/[ascend]/branches/ksenija2/models/johnpye/datareader/datareader.c
ViewVC logotype

Contents of /branches/ksenija2/models/johnpye/datareader/datareader.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2857 - (show annotations) (download) (as text)
Sat Mar 21 13:13:27 2015 UTC (7 years, 3 months ago) by jpye
File MIME type: text/x-csrc
File size: 8809 byte(s)
rearranging the idaanaylse file top-down, functions in the order called.
minor changes elsehwere to debug output, commenting.

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

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