21 saw 1.1 *
22 * Revision 1.5 1995/04/10 15:52:52 saw
23 * No defined gethit blocks is not an error in thExecuteGethits
24 *
25 * Revision 1.4 1995/01/13 16:26:01 saw
26 * Add missing return(S_SUCCESS) calls to various routines
27 *
28 * Revision 1.3 1994/09/27 19:26:21 saw
29 * Remove linux dependencies
30 *
31 * Revision 1.2 1994/08/26 12:30:23 saw
32 * Register result and test variables as needed
33 *
34 * Revision 1.1 1994/07/21 18:48:12 saw
35 * Initial revision
36 *
37 */
38 /*
39 Any gethit block can only operate on one "data structure".
40
41 begin gethit wc
42 saw 1.1 missing_value=-1 ! Value to give when hit not found
43 hitcount=numhits ! Pointer to word holding hit count
44 matchlist=plane ! First array to match with
45 matchlist=counter! Second array to match with
46 valuelist=data ! Default list containing data values
47
48 xsin1,txsin1:,1,4 ! Use default array !Makes hit.xscin1, and test.txsin1
49 xsin2,txsin2:data2,1,5
50 end gethist wc
51 */
52 #include <stdio.h>
53 #include <string.h>
54 #include "daVar.h"
55 #include "th.h"
56 #include "thInternal.h"
57 #include "thUtils.h"
58 #include "cfortran.h"
59
60 struct thGethitList {
61 struct thGethitList *next;
62 daVarStruct *src; /* Array to get data from when hit is found */
63 saw 1.1 DAINT *coord; /* Coordinate values to match*/
64 daVarStruct *dest,*test; /* Variable to put value of hit detector
65 and a flag for hit found/not found */
66 int destindex, testindex;
67 };
68 typedef struct thGethitList thGethitList;
69
70 struct thGethitOpaque {
71 DAINT *vnhits; /* CTP variable with number of hits */
72 int ncoord; /* Number of coordinates that must match */
73 DAINT **coord_array; /* Point to list of arrays containing hit
74 coordinates */
75 thGethitList *hlisthead; /* List of gethit definitions */
76 daVarStruct *srcdefault; /* Default data array */
77 DADOUBLE default_real; /* Default value to give when hit not found */
78 DAINT default_int; /* Int of default_real */
79 };
80
81 typedef struct thGethitOpaque thGethitOpaque;
82
83 struct thGBlockList {
84 saw 1.1 struct thGBlockList *next;
85 char *blockname; /* Block name without the block.gethit */
86 daVarStruct *var; /* Pointer to variable that describes block */
87 };
88 typedef struct thGBlockList thGBlockList;
89
90 thGBlockList *thGBlockListP = NULL;
91 char *hitsourceclasslist[]={EVENTSTR,0};
92
93 /* Function prototypes */
94 thStatus thGethitPreamble(char *line, thGethitOpaque *opqptr,int *icoord);
95 char *thGetline(char *lines,char **lcopy);
96 thStatus thBookaGethit(char *line, thGethitOpaque *opqptr
97 ,thGethitList **thGethitNext);
98 thStatus thExecuteaGethitBlock(daVarStruct *var);
99 thStatus thExecuteaGethit(thGBlockList *block);
100
101 thStatus thBookGethits(daVarStruct *var)
102 {
103 char *lines,*eol,*lcopy;
104 thGethitOpaque *opqptr;
105 saw 1.1 thGethitList **thGethitNext;
106 int ncoord,icoord;
107 int line_count,mode;
108 char *blockname;
109
110 blockname = var->name; /* If name doesn't fit pattern, use whole */
111 /* printf("Booking gethit block %s\n",blockname);*/
112 if(strcasestr(var->name,BLOCKSTR)==var->name){
113 int i;
114 i = strlen(BLOCKSTR) + 1;
115 if(strcasestr((var->name + i),GETHITSTR)==(var->name + i)){
116 i += strlen(GETHITSTR);
117 if(*(var->name + i) == '.'){
118 blockname += i + 1;
119 }
120 }
121 }
122
123 if(var->opaque == 0) {
124 opqptr = (thGethitOpaque *) malloc(sizeof(thGethitOpaque));
125 var->opaque = (void *) opqptr;
126 saw 1.1 } else {
127 daVarStructList *next,*this;
128
129 opqptr = (thGethitOpaque *) var->opaque;
130 free(opqptr->coord_array);
131 /* Walk down optptr->hlisthead freeing the individual gethit structures */
132 }
133 /* Initialize/Clear the Gethit structure */
134 opqptr->vnhits = (DAINT *) 0;
135 opqptr->ncoord = 0;
136 opqptr->coord_array = (DAINT **) 0;
137 opqptr->srcdefault = (daVarStruct *) 0;
138 opqptr->hlisthead = (thGethitList *) 0;
139 opqptr->default_real = opqptr->default_int = 0;
140
141 lines = var->title;
142 line_count = 0;
143 ncoord=0;
144
145 while(*lines) { /* First Pass */
146 /* Count the number of arrays to match */
147 saw 1.1
148 line_count++;
149 lines = thGetline(lines,&lcopy);
150 if(!thCleanLine(lcopy)){
151 if(strcasestr(lcopy,"matchlist") && strchr(lcopy,'=')) {
152 ncoord++;
153 }
154 if(strchr(lcopy,':')) { /* First gethit definition */
155 break;
156 }
157 }
158 }
159 opqptr->ncoord = ncoord;
160 opqptr->coord_array = (DAINT **) malloc(ncoord*sizeof(DAINT *));
161
162 mode = 0; /* setup mode */
163 thGethitNext = (thGethitList **) &opqptr->hlisthead;
164 line_count = 0;
165 icoord = 0;
166
167 lines = var->title;
168 saw 1.1 while(*lines) { /* Second Pass */
169 line_count++;
170 lines = thGetline(lines,&lcopy);
171 if(!thCleanLine(lcopy)){
172 if(strchr(lcopy,':'))
173 mode = 1;
174 if(mode) { /* Defining the individual gethits */
175 if(thBookaGethit(lcopy,opqptr,thGethitNext)==S_SUCCESS){
176 thGethitNext = &((*thGethitNext)->next);
177 } else {
178 fprintf(STDERR,"Gethit booking error in line %d\n",line_count);
179 }
180 } else { /* Preamble */
181 if(thGethitPreamble(lcopy,opqptr,&icoord)!=S_SUCCESS){
182 fprintf(STDERR,"Gethit booking error in line %d\n",line_count);
183 }
184 }
185 }
186 }
187 /* Update internal table of gethit blocks */
188 {
189 saw 1.1 thGBlockList *thisblock,*nextblock,**lastblockp;
190 nextblock = thGBlockListP;
191 lastblockp = &thGBlockListP;
192 thisblock = thGBlockListP;
193 while(thisblock){
194 if((strcasecmp(thisblock->var->name,var->name)) == 0){
195 /* Replacing a block with a new definition */
196 fprintf(stderr,"Replacing %s with new definition\n",var->name);
197 if(thisblock->var != var){
198 fprintf(stderr,"ERR: Same name, different var pointer\n");
199 }
200 break;
201 }
202 lastblockp = &thisblock->next;
203 thisblock = thisblock->next;
204 }
205 if(!thisblock){ /* Create entry for New block */
206 *lastblockp = thisblock = (thGBlockList *) malloc(sizeof(thGBlockList));
207 thisblock->var = var;
208 thisblock->next = (thGBlockList *) NULL;
209 thisblock->blockname = (char *) malloc(strlen(blockname) + 1);
210 saw 1.1 strcpy(thisblock->blockname,blockname);
211 }
212 }
213 /* printf("Returning from booking Gethit's\n");*/
214 return(S_SUCCESS);
215 }
216 char *thGetline(char *lines,char **lcopy)
217 /* Pull out the characters from lines up to a newline and copy them into
218 a new array. Return the pointer to that array. If a line is missing
219 a newline, return an error. */
220 {
221 static char *line_copy=0;
222 static line_copy_size=0;
223 char *next;
224 int len;
225 char *eol;
226
227 eol = strchr(lines,'\n');
228 if(!eol) {
229 len = strlen(lines);
230 next = lines + len;
231 saw 1.1 } else {
232 len = (eol-lines);
233 next = eol+1;
234 }
235 if(!line_copy) {
236 line_copy = (char *) malloc(len+1);
237 line_copy_size = len+1;
238 } else {
239 if(len >= line_copy_size) {
240 line_copy = (char *) realloc(line_copy,len+1);
241 line_copy_size = len+1;
242 }
243 }
244 strncpy(line_copy,lines,len);
245 line_copy[len] = '\0';
246 *lcopy = line_copy;
247 return(next);
248 }
249 thStatus thGethitPreamble(char *line, thGethitOpaque *opqptr,int *icoord){
250 char *equal;
251 char *arg;
252 saw 1.1
253 /* printf("Processing preamble line %x %s\n",line,line);*/
254 if(!(equal=strchr(line,'=')))
255 return(S_SUCCESS);
256 arg = equal + 1;
257 *equal = 0;
258 arg = thSpaceStrip(arg);
259 /* printf("line=%s,arg=%s\n",line,arg); */
260 if(strcasestr(line,"missing_value")) {
261 opqptr->default_real = atof(arg);
262 opqptr->default_int = floatToLong(opqptr->default_real);
263 } else {
264 daVarStruct *varp;
265 /* printf("line=%s,arg=%x %s\n",line,arg,arg);*/
266 if(daVarLookupPWithClass(arg,hitsourceclasslist,&varp)!=S_SUCCESS){
267 fprintf(STDERR,"(thGethitPreamble )Variable %s not found\n",arg);
268 return(S_FAILURE); /* Variable not found */
269 }
270 /* printf("line=%s,arg=%x %s\n",line,arg,arg);*/
271 /* printf("Searching for keyword in %s\n",line);*/
272 if(strcasestr(line,"valuelist")) {
273 saw 1.1 opqptr->srcdefault = varp;
274 } else {
275 if(varp->type != DAVARINT) {
276 return(S_FAILURE); /* Not an integer array */
277 }
278 if(strcasestr(line,"hitcount")) {
279 opqptr->vnhits = (DAINT *) varp->varptr;
280 /* printf("Setting vnhits to %s\n",varp->name);*/
281 } else if(strcasestr(line,"matchlist")) {
282 /* printf("Coordinate %d=%s\n",*icoord,varp->name);*/
283 opqptr->coord_array[(*icoord)++] = (DAINT *) varp->varptr;
284 } else {
285 return(S_FAILURE);
286 }
287 }
288 }
289 return(S_SUCCESS);
290 }
291 thStatus thBookaGethit(char *line, thGethitOpaque *opqptr, thGethitList **thGethitNext)
292 {
293 char *colon;
294 saw 1.1 int ndestarg; /* Number of destination args */
295 char *destargs[20];
296 int nsrcarg; /* Number of destination args */
297 char *srcargs[20];
298 daVarStruct *destp, *testp;
299 int destind,testind; /* Indexes into destination and test arrays */
300 daVarStruct *source;
301 DAINT *coord;
302 int icoord;
303 thGethitList *Gethit;
304 thStatus status;
305
306 if(!(colon=strchr(line,':'))) {
307 return(S_SUCCESS);
308 }
309
310 *colon = '\0';
311 colon++;
312
313 ndestarg = thCommas(line,destargs);
314 nsrcarg = thCommas(colon,srcargs);
315 saw 1.1
316 /* Parse the source side first so that we know the data type of the
317 source in case we need to register the destination */
318
319 /* printf("%s found as %s at %x\n",destargs[0],destp->name,destp->varptr);*/
320 if(nsrcarg < opqptr->ncoord+1) {
321 fprintf(STDERR,"Insufficient arguments after :\n");
322 return(S_FAILURE);
323 }
324 srcargs[0] = thSpaceStrip(srcargs[0]);
325 if(strlen(srcargs[0]) == 0) {
326 source = opqptr->srcdefault;
327 } else {
328 if(daVarLookupPWithClass(srcargs[0],hitsourceclasslist,*source)
329 != S_SUCCESS) {
330 fprintf(STDERR,"%s not registered\n",srcargs[0]);
331 return(S_FAILURE); /* Destination not registered */
332 }
333 }
334
335 destargs[0] = thSpaceStrip(destargs[0]);
336 saw 1.1 if((status=thVarResolve(destargs[0],&destp,&destind,2,source->type)) != S_SUCCESS){
337 return(S_FAILURE);
338 /* ASAP we must change this to register variables as they are needed */
339 /* If the variable exists, then we also must check to make sure that
340 the requested index does not exceed the size of the array.
341 a new thVarResolve should also increase the size of the array if
342 it was created by CTP */
343 }
344 if(ndestarg > 1){
345 destargs[1] = thSpaceStrip(destargs[1]);
346 if(thVarResolve(destargs[1],&testp,&testind,3,DAVARINT) != S_SUCCESS){
347 return(S_FAILURE); /* Test flag not registered */
348 /* ASAP we must change this to register variables as they are needed */
349 /* If the variable exists, then we also must check to make sure that
350 the requested index does not exceed the size of the array.
351 a new thVarResolve should also increase the size of the array if
352 it was created by CTP */
353
354 }
355 } else {
356 testp = 0;
357 saw 1.1 testind = 0;
358 }
359
360 coord = (DAINT *) malloc(opqptr->ncoord*sizeof(DAINT));
361 for(icoord=0;icoord<opqptr->ncoord;icoord++) {
362 srcargs[icoord+1] = thSpaceStrip(srcargs[icoord+1]);
363 if(thEvalImed(srcargs[icoord+1],0,&coord[icoord]) != S_SUCCESS) {
364 fprintf(STDERR,"Error evaluating %s\n",srcargs[icoord+1]);
365 free(coord);
366 return(S_FAILURE);
367 }
368 }
369 /* Everything obtained from line now */
370 Gethit = *thGethitNext = (thGethitList *) malloc(sizeof(thGethitList));
371 Gethit->next = (thGethitList *) NULL;
372 Gethit->src = source;
373 Gethit->coord = coord;
374 Gethit->dest = destp;
375 Gethit->destindex = destind;
376 Gethit->test = testp;
377 Gethit->testindex = testind;
378 saw 1.1
379 return(S_SUCCESS);
380 }
381 thStatus thExecuteGethits(char *block_name){
382 thGBlockList *thisblock;
383
384
385 if(block_name) if(*block_name=='\0') block_name = 0;
386
387 if(thGBlockListP == 0){
388 return(S_SUCCESS); /* No gethits defined */
389 } else {
390 thisblock = thGBlockListP;
391 while(thisblock){
392 if(block_name)
393 if(strcasecmp(block_name,thisblock->blockname)!=0){
394 thisblock = thisblock->next;
395 continue;
396 }
397 thExecuteaGethitBlock(thisblock->var);
398 (*((DAINT *)thisblock->var->varptr))++; /* Increment block counter */
399 saw 1.1 if(block_name)
400 if(strcasecmp(block_name,thisblock->blockname)==0) return(S_SUCCESS);
401 thisblock = thisblock->next;
402 }
403 }
404 return(S_SUCCESS);
405 }
406
407 thStatus thExecuteaGethitBlock(daVarStruct *var)
408 /* Execute a gethit block */
409 {
410 thGethitOpaque *opqptr;
411 thGethitList *thisgethit;
412 int nhits;
413 int ihit;
414 int icoord,ncoord;
415 DAINT **coord_array;
416 double dval;
417 int ival;
418
419 /* opqptr = block->var->opaque;*/ /* Structure that describes the gethits */
420 saw 1.1 opqptr = var->opaque;
421 /* printf("opqptr=%x\n",opqptr);*/
422 nhits = *(opqptr->vnhits);
423 ncoord = opqptr->ncoord;
424 coord_array = opqptr->coord_array;
425
426 thisgethit = opqptr->hlisthead;
427 /* printf("%d hits this event\n",nhits);*/
428 while(thisgethit){ /* Inefficient algorithm */
429 /* printf("Getting %s\n",thisgethit->dest->name);*/
430 if(thisgethit->test) {
431 /* Assume that test is integer */
432 *((DAINT *) thisgethit->test->varptr + thisgethit->testindex) = FALSE;
433 }
434 for(ihit=0;ihit<nhits;ihit++){
435 for(icoord=0;icoord<ncoord;icoord++){
436 /* printf("Hit=%d, Coord=%d %d %d\n",ihit,icoord
437 ,coord_array[icoord][ihit],thisgethit->coord[icoord]);*/
438 if((coord_array[icoord])[ihit] != thisgethit->coord[icoord]) break;
439 }
440 if(icoord >= ncoord){ /* All coordinates matched */
441 saw 1.1 int srctype;
442 /* printf("Matched at hit %d, %d %d\n",ihit,icoord,ncoord);*/
443 if(thisgethit->test)
444 *((DAINT *) thisgethit->test->varptr + thisgethit->testindex) = TRUE;
445 /* Need to grab the data value, stuff it into variable */
446 srctype = thisgethit->src->type;
447 switch(srctype)
448 {
449 case DAVARINT:
450 ival = ((DAINT *)thisgethit->src->varptr)[ihit];
451 switch(thisgethit->dest->type)
452 {
453 case DAVARINT:
454 ((DAINT *)thisgethit->dest->varptr)[thisgethit->destindex] =
455 ival;
456 break;
457 case DAVARFLOAT:
458 ((DAFLOAT *)thisgethit->dest->varptr)[thisgethit->destindex] =
459 ival;
460 break;
461 case DAVARDOUBLE:
462 saw 1.1 ((DADOUBLE *)thisgethit->dest->varptr)[thisgethit->destindex]
463 = ival;
464 break;
465 }
466 break;
467 case DAVARFLOAT:
468 case DAVARDOUBLE:
469 if(srctype == DAVARFLOAT)
470 dval = ((DAFLOAT *)thisgethit->src->varptr)[ihit];
471 else
472 dval = ((DADOUBLE *)thisgethit->src->varptr)[ihit];
473 switch(thisgethit->dest->type)
474 {
475 case DAVARINT:
476 ((DAINT *)thisgethit->dest->varptr)[thisgethit->destindex] =
477 floatToLong(dval);
478 break;
479 case DAVARFLOAT:
480 ((DAFLOAT *)thisgethit->dest->varptr)[thisgethit->destindex] =
481 dval;
482 break;
483 saw 1.1 case DAVARDOUBLE:
484 ((DADOUBLE *)thisgethit->dest->varptr)[thisgethit->destindex]
485 = dval;
486 break;
487 }
488 break;
489 }
490 break; /* Only match one hit for now */
491 }
492 }
493 thisgethit = thisgethit->next;
494 }
495 return(S_SUCCESS);
496 }
|