/[ascend]/trunk/models/johnpye/datareader/datareader.c
ViewVC logotype

Annotation of /trunk/models/johnpye/datareader/datareader.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3291 - (hide annotations) (download) (as text)
Sat Dec 2 12:41:27 2017 UTC (2 years, 10 months ago) by jpye
File MIME type: text/x-csrc
File size: 8941 byte(s)
adding test case for tmy3 datareader (no assertions made yet!)

1 johnpye 801 /* ASCEND modelling environment
2 jpye 3291 Copyright (C) 2017 John Pye
3 johnpye 801 Copyright (C) 2006 Carnegie Mellon University
4    
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2, or (at your option)
8     any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16 jpye 2649 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 johnpye 801 */
18    
19     #include <stdio.h>
20 jose 2071 #include <string.h>
21 johnpye 801
22 jpye 2323 #include <ascend/general/platform.h>
23     #include <ascend/general/panic.h>
24 jpye 2018 #include <ascend/utilities/error.h>
25 johnpye 801
26 johnpye 1211
27 jpye 2018 #include <ascend/compiler/child.h>
28     #include <ascend/general/list.h>
29     #include <ascend/compiler/module.h>
30     #include <ascend/compiler/childinfo.h>
31     #include <ascend/compiler/parentchild.h>
32     #include <ascend/compiler/slist.h>
33     #include <ascend/compiler/type_desc.h>
34     #include <ascend/compiler/packages.h>
35     #include <ascend/compiler/symtab.h>
36     #include <ascend/compiler/instquery.h>
37     #include <ascend/compiler/instmacro.h>
38     #include <ascend/compiler/instance_types.h>
39 johnpye 801
40 jpye 2018 #include <ascend/compiler/extfunc.h>
41 johnpye 908
42 johnpye 811 #include "dr.h"
43 johnpye 801
44 jpye 3283 //#define DATAREADER_DEBUG
45 jpye 2779 #ifdef DATAREADER_DEBUG
46     # define MSG CONSOLE_DEBUG
47     #else
48     # define MSG(ARGS...) ((void)0)
49     #endif
50 jpye 1775
51 johnpye 801 /*------------------------------------------------------------------------------
52 johnpye 811 GLOBALS
53     */
54    
55 jose 2071 static symchar *dr_symbols[3];
56 johnpye 811 #define FILENAME_SYM dr_symbols[0]
57 johnpye 812 #define FORMAT_SYM dr_symbols[1]
58 jose 2071 #define PARAM_SYM dr_symbols[2]
59 johnpye 811
60     /*------------------------------------------------------------------------------
61 johnpye 801 BINDINGS FOR THE DATA READER TO THE ASCEND EXTERNAL FUNCTIONS API
62     */
63    
64 johnpye 908 ExtBBoxInitFunc asc_datareader_prepare;
65     ExtBBoxFunc asc_datareader_calc;
66     ExtBBoxFinalFunc asc_datareader_close;
67 johnpye 801
68     #ifndef ASC_EXPORT
69     # error "Where is ASC_EXPORT?"
70     #endif
71    
72 johnpye 812 /**
73     This is the function called from "IMPORT datareader"
74    
75     It sets up the functions in this external function library and tells ASCEND
76     how many inputs and outputs it needs.
77     */
78 johnpye 801 extern
79 johnpye 1063 ASC_EXPORT int datareader_register(){
80 johnpye 811 const char *help = "The is the ASCEND Data Reader, for pulling in"
81 johnpye 801 " time-series data such as weather readings for use in simulations.";
82    
83     int result = 0;
84    
85 jpye 3258 //ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Initialising data reader...\n");
86 johnpye 801
87 jpye 2779 MSG("EVALUATION FUNCTION AT %p",asc_datareader_calc);
88 johnpye 801
89 johnpye 812 result += CreateUserFunctionBlackBox("datareader"
90 johnpye 801 , asc_datareader_prepare
91     , asc_datareader_calc /* value */
92     , asc_datareader_calc /* deriv */
93     , NULL /* deriv2 */
94     , asc_datareader_close /* final */
95 johnpye 819 , 1,5 /* inputs, outputs */
96 johnpye 811 , help
97 johnpye 908 , 0.0
98 johnpye 801 ); /* returns 0 on success */
99    
100     if(result){
101     ERROR_REPORTER_HERE(ASC_PROG_NOTE,"CreateUserFunction result = %d\n",result);
102     }
103     return result;
104     }
105    
106 johnpye 812 /**
107     This function prepares the data that we will use before starting the solver
108     process.
109     */
110 johnpye 908 int asc_datareader_prepare(struct BBoxInterp *slv_interp,
111 johnpye 801 struct Instance *data,
112     struct gl_list_t *arglist
113     ){
114 jose 2071 struct Instance *fninst, *fmtinst, *parinst;
115     const char *fn, *fmt, *par;
116 johnpye 801 DataReader *d;
117 jpye 3258 //char *partok = NULL; //token parser string for initialising datareader
118 jose 2071 int noutputs; //number of outputs as per the arg file
119 johnpye 801
120 johnpye 811 dr_symbols[0] = AddSymbol("filename");
121 johnpye 812 dr_symbols[1] = AddSymbol("format");
122 jose 2071 dr_symbols[2] = AddSymbol("parameters");
123 jpye 2649
124 jose 2071 /* get the data file name (we will look for this file in the ASCENDLIBRARY path) */
125 johnpye 811 fninst = ChildByChar(data,FILENAME_SYM);
126 johnpye 801 if(!fninst){
127     ERROR_REPORTER_HERE(ASC_USER_ERROR
128     ,"Couldn't locate 'filename', please check Data Reader usage."
129     );
130     return 1;
131     }
132     if(InstanceKind(fninst)!=SYMBOL_CONSTANT_INST){
133 johnpye 812 ERROR_REPORTER_HERE(ASC_USER_ERROR,"'filename' must be a symbol_constant");
134 johnpye 801 return 1;
135     }
136     fn = SCP(SYMC_INST(fninst)->value);
137 jpye 2779 MSG("FILENAME: %s",fn);
138 johnpye 801 if(fn==NULL || strlen(fn)==0){
139     ERROR_REPORTER_HERE(ASC_USER_ERROR,"'filename' is NULL or empty");
140     return 1;
141     }
142    
143 johnpye 812 /* get the data reader format *//**
144     This is the function called from "IMPORT extfntest"
145    
146     It sets up the functions in this external function library
147     */
148    
149     fmtinst = ChildByChar(data,FORMAT_SYM);
150     if(!fmtinst){
151     ERROR_REPORTER_HERE(ASC_USER_ERROR
152     ,"Couldn't locate 'format', please check Data Reader usage."
153     );
154     return 1;
155     }
156     if(InstanceKind(fmtinst)!=SYMBOL_CONSTANT_INST){
157     ERROR_REPORTER_HERE(ASC_USER_ERROR,"'format' must be a symbol_constant");
158     return 1;
159     }
160     fmt = SCP(SYMC_INST(fmtinst)->value);
161 jpye 2779 MSG("FORMAT: %s",fmt);
162 johnpye 812 if(fmt==NULL || strlen(fmt)==0){
163     ERROR_REPORTER_HERE(ASC_USER_ERROR,"'format' is NULL or empty");
164     return 1;
165     }
166 jose 2071 /* get the datareader parameters. Ascend syntax is
167     parameters :== 'col1:interp1,col2,interp2,..,coln:interpn';
168     where coln is the data file column assigned to corresponding variable
169     interpn is the algorithm used to interpret that data column
170     */
171     parinst = ChildByChar(data,PARAM_SYM);
172     if(!fninst){
173     ERROR_REPORTER_HERE(ASC_USER_ERROR
174     ,"Couldn't locate 'parameters', please check Data Reader usage."
175     );
176     return 1;
177     }
178     if(InstanceKind(parinst)!=SYMBOL_CONSTANT_INST){
179     ERROR_REPORTER_HERE(ASC_USER_ERROR,"'parameters' must be a symbol_constant");
180     return 1;
181     }
182     par = SCP(SYMC_INST(parinst)->value);
183     if(par==NULL || strlen(par)==0){
184     ERROR_REPORTER_HERE(ASC_USER_ERROR,"'parameters' is NULL or empty");
185     return 1;
186     }
187 jpye 2649
188 jose 2071 /* obtain number of outputs from the paramater statement */
189     /* this enables to create a datareader object with the right size parameter tokens */
190     /*
191     note: the reason for this string manipulations is that par is pointing directly
192     to the instance of the model parinst->value. Any string operations that are not
193     read only will affect this address, potentially leaving a NULL pointer in the
194     instance, or the datareader structure. even if passed down it wont be passed
195     by value, but by pointer, so other functions (such as datareader_set_parameters)
196     might affect this address, potentially causing a seg fault.
197 jpye 2649
198 jose 2071 */
199 jpye 3258 char *par2 = ASC_NEW_ARRAY(char,strlen(par)+1);
200     strncpy(par2,par,strlen(par)+1);
201 jpye 2649
202     /*datareader only! in rigour nouputs has to be derived by more
203 jose 2071 explicit methods, such as parsing or argument passing*/
204 jpye 2649 noutputs = gl_length(arglist)-1;
205    
206 jose 2071 /* create the data reader: tell it the filename and nouputs */
207     d = datareader_new(fn,noutputs);
208     //set datareader file format
209 johnpye 812 if(fmt!=NULL){
210     if(datareader_set_format(d,fmt)){
211     CONSOLE_DEBUG("Invalid 'format'");
212     return 1;
213 johnpye 908 }
214 johnpye 812 }
215 jose 2071 //initialise datareader object
216 johnpye 801 if(datareader_init(d)){
217     CONSOLE_DEBUG("Error initialising data reader");
218     return 1;
219     }
220 jose 2071 //asign user defined parameters
221 jpye 3258 if(datareader_set_parameters(d,par2)){
222 jose 2071 CONSOLE_DEBUG("failed to set parameters");
223 jpye 3258 ASC_FREE(par2);
224 jose 2071 return 1;
225     }
226 jpye 2649
227 jpye 2797 MSG("Created data reader at %p...",d);
228 jpye 2649 /*assign the succesfully created datareader object to the
229 jose 2071 BlackBox Cache of the relation */
230     slv_interp->user_data = (void *)d; //BROKEN AT THE MOMENT
231 jpye 3258 ASC_FREE(par2);
232 johnpye 801 return 0;
233     }
234    
235     /* return 0 on success */
236 johnpye 908 int asc_datareader_calc(struct BBoxInterp *slv_interp,
237 johnpye 801 int ninputs, int noutputs,
238     double *inputs, double *outputs,
239     double *jacobian
240     ){
241     DataReader *d;
242     d = (DataReader *)slv_interp->user_data;
243 johnpye 819 if(!d){
244     ERROR_REPORTER_HERE(ASC_USER_ERROR
245     ,"Datareader was not initialised successfully"
246     );
247     return 1;
248     }
249 johnpye 801
250     if(ninputs!=datareader_num_inputs(d)){
251     ERROR_REPORTER_HERE(ASC_USER_ERROR
252     ,"Invalid number of inputs, expected %d but received %d"
253     ,datareader_num_inputs(d), ninputs
254     );
255     return 1;
256     }
257    
258 johnpye 819 if(noutputs!=datareader_num_outputs(d)){
259 johnpye 801 ERROR_REPORTER_HERE(ASC_USER_ERROR
260     ,"Invalid number of outputs, expected <=%d but received %d"
261     ,datareader_num_outputs(d), noutputs
262     );
263 jose 2071 //return 1; warn about incompatibility but keep going ...JZap
264 johnpye 801 }
265    
266 jpye 2779 #ifdef DATAREADER_DEBUG
267 jpye 3281 int i;
268 johnpye 801 for(i=0; i< ninputs; ++i){
269 jpye 2779 MSG("inputs[%d] = %f", i, inputs[i]);
270 johnpye 801 }
271 jpye 1775 #endif
272 johnpye 801
273 johnpye 811 switch(slv_interp->task){
274 johnpye 801 case bb_func_eval:
275 jpye 2779 MSG("DATA READER EVALUATION");
276 johnpye 801 if(datareader_func(d,inputs,outputs)){
277     CONSOLE_DEBUG("Datareader evaluation error");
278     return 1;
279     }
280 jpye 2779 #ifdef DATAREADER_DEBUG
281 johnpye 819 for(i=0; i< noutputs; ++i){
282 jpye 2779 MSG("outputs[%d] = %f", i, outputs[i]);
283 johnpye 819 }
284 jpye 1775 #endif
285 johnpye 801 return 0; /* success */
286     case bb_deriv_eval:
287 jpye 2779 MSG("DATA READER DERIVATIVE");
288 johnpye 801 if(datareader_deriv(d,inputs,outputs)){
289 jpye 2779 MSG("Datareader derivative evaluation error");
290 johnpye 801 return 1;
291     }
292     return 0; /* success */
293 johnpye 811 default:
294     CONSOLE_DEBUG("UNHANDLED REQUEST");
295     return 1;
296 johnpye 801 }
297     }
298 johnpye 811
299 johnpye 908 void asc_datareader_close(struct BBoxInterp *slv_interp){
300 jpye 3281 DataReader *d;
301     d = (DataReader *)slv_interp->user_data;
302     if(!d){
303     ERROR_REPORTER_HERE(ASC_USER_ERROR
304     ,"Attempted to close a null datareader"
305     );
306     return;
307     }
308 jpye 3284 #if 1
309 jpye 3281 MSG("CLOSING DATAREADER");
310     datareader_free(d);
311     #else
312     MSG("NOT IMPLEMENTED");
313     #endif
314 johnpye 811 }
315 jpye 2779

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22