pythonforecast.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002   file : $URL: https://frepple.svn.sourceforge.net/svnroot/frepple/trunk/modules/forecast/pythonforecast.cpp $
00003   version : $LastChangedRevision: 1315 $  $LastChangedBy: jdetaeye $
00004   date : $LastChangedDate: 2010-07-17 18:08:53 +0200 (Sat, 17 Jul 2010) $
00005  ***************************************************************************/
00006 
00007 /***************************************************************************
00008  *                                                                         *
00009  * Copyright (C) 2007-2010 by Johan De Taeye                               *
00010  *                                                                         *
00011  * This library is free software; you can redistribute it and/or modify it *
00012  * under the terms of the GNU Lesser General Public License as published   *
00013  * by the Free Software Foundation; either version 2.1 of the License, or  *
00014  * (at your option) any later version.                                     *
00015  *                                                                         *
00016  * This library is distributed in the hope that it will be useful,         *
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
00019  * General Public License for more details.                                *
00020  *                                                                         *
00021  * You should have received a copy of the GNU Lesser General Public        *
00022  * License along with this library; if not, write to the Free Software     *
00023  * Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 *
00024  * USA                                                                     *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 #include "forecast.h"
00029 
00030 namespace module_forecast
00031 {
00032 
00033 
00034 PyObject* Forecast::getattro(const Attribute& attr)
00035 {
00036   if (attr.isA(Tags::tag_calendar))
00037     return PythonObject(getCalendar());
00038   else if (attr.isA(Tags::tag_discrete))
00039     return PythonObject(getDiscrete());
00040   return Demand::getattro(attr);
00041 }
00042 
00043 
00044 int Forecast::setattro(const Attribute& attr, const PythonObject& field)
00045 {
00046   if (attr.isA(Tags::tag_calendar))
00047   {
00048     if (!field.check(Calendar::metadata))
00049     {
00050       PyErr_SetString(PythonDataException, "forecast calendar must be of type calendar");
00051       return -1;
00052     }
00053     Calendar* y = static_cast<Calendar*>(static_cast<PyObject*>(field));
00054     setCalendar(y);
00055   }
00056   else if (attr.isA(Tags::tag_discrete))
00057     setDiscrete(field.getBool());
00058   else
00059     return Demand::setattro(attr, field);
00060   return 0; // OK
00061 }
00062 
00063 
00064 extern "C" PyObject* Forecast::timeseries(PyObject *self, PyObject *args)
00065 {
00066   // Get the forecast model
00067   Forecast* forecast = static_cast<Forecast*>(self);
00068 
00069   // Parse the Python arguments
00070   PyObject* history;
00071   PyObject* buckets = NULL;
00072   int ok = PyArg_ParseTuple(args, "O|O", &history, &buckets);
00073   if (!ok) return NULL;
00074 
00075   // Verify we can iterate over the arguments
00076   PyObject *historyiterator = PyObject_GetIter(history);
00077   PyObject *bucketiterator = NULL;
00078   if (!historyiterator)
00079   {
00080     PyErr_Format(PyExc_AttributeError,"Invalid type for time series");
00081     return NULL;
00082   }
00083   if (buckets) bucketiterator = PyObject_GetIter(buckets);
00084   if (!bucketiterator)
00085   {
00086     PyErr_Format(PyExc_AttributeError,"Invalid type for time series");
00087     return NULL;
00088   }
00089 
00090   // Copy the history data into a C++ data structure
00091   double data[300];
00092   unsigned int historycount = 0;
00093   PyObject *item;
00094   while ((item = PyIter_Next(historyiterator)))
00095   {
00096     data[historycount++] = PyFloat_AsDouble(item);
00097     Py_DECREF(item);
00098     if (historycount>=300) break;
00099   }
00100   Py_DECREF(historyiterator);
00101 
00102   // Copy the bucket data into a C++ data structure
00103   Date bucketdata[300];
00104   unsigned int bucketcount = 0;
00105   while ((item = PyIter_Next(bucketiterator)))
00106   {
00107     bucketdata[bucketcount++] = PythonObject(item).getDate();
00108     Py_DECREF(item);
00109     if (bucketcount>=300) break;
00110   }
00111   Py_DECREF(bucketiterator);
00112 
00113   Py_BEGIN_ALLOW_THREADS  // Free the Python interpreter for other threads
00114   try {
00115     // Generate the forecast
00116     forecast->generateFutureValues
00117       (data, historycount, bucketdata, bucketcount, true);
00118   }
00119   catch (...)
00120   {
00121     Py_BLOCK_THREADS;
00122     PythonType::evalException();
00123     return NULL;
00124   }
00125   Py_END_ALLOW_THREADS   // Release the Python interpreter
00126   return Py_BuildValue("");
00127 }
00128 
00129 
00130 PyObject* ForecastBucket::getattro(const Attribute& attr)
00131 {
00132   if (attr.isA(Tags::tag_startdate))
00133     return PythonObject(getDueRange().getStart());
00134   if (attr.isA(Tags::tag_enddate))
00135     return PythonObject(getDueRange().getEnd());
00136   if (attr.isA(Forecast::tag_total))
00137     return PythonObject(getTotal());
00138   if (attr.isA(Forecast::tag_consumed))
00139     return PythonObject(getConsumed());
00140   if (attr.isA(Tags::tag_weight))
00141     return PythonObject(getWeight());
00142   return Demand::getattro(attr);
00143 }
00144 
00145 
00146 int ForecastBucket::setattro(const Attribute& attr, const PythonObject& field)
00147 {
00148   if (attr.isA(Forecast::tag_total))
00149     setTotal(field.getDouble());
00150   else if (attr.isA(Forecast::tag_consumed))
00151     setConsumed(field.getDouble());
00152   else if (attr.isA(Tags::tag_weight))
00153     setWeight(field.getDouble());
00154   else
00155     return Demand::setattro(attr, field);
00156   return 0;  // OK
00157 }
00158 
00159 
00160 } // end namespace

Documentation generated for frePPLe by  doxygen