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
