(file) Return to thTree.c CVS log (file) (dir) Up to [HallC] / Analyzer / CTP

  1 saw   1.1 /*-----------------------------------------------------------------------------
  2            * Copyright (c) 1999      Thomas Jefferson National Accelerator Facility
  3            *
  4            * This software was developed under a United States Government license
  5            * described in the NOTICE file included as part of this distribution.
  6            *
  7            * Stephen A. Wood, 12000 Jefferson Ave., Newport News, VA 23606
  8            * Email: saw@jlab.org  Tel: (758) 269-7367  Fax: (757) 269-5235
  9            *-----------------------------------------------------------------------------
 10            * 
 11            * Description:
 12            *  Book ROOT trees.
 13            *	
 14            * Author:  Stephen Wood, CEBAF Hall C
 15            *
 16            * Revision History:
 17            *   $Log: thTree.c,v $
 18 saw   1.5  *
 19            *   Revision 1.1.16.2  2004/07/09 20:41:50  saw
 20            *   Can now put a test on a tree block
 21            *
 22            *   Revision 1.1.16.1  2004/07/09 14:12:11  saw
 23            *   Add ability for CTP to make ROOT Trees
 24            *
 25            *   Revision 1.4  2004/07/08 20:07:00  saw
 26            *   Supply dummy routines when ROOTSYS not defined
 27            *
 28 saw   1.4  *   Revision 1.3  2004/07/07 18:16:30  saw
 29            *   Use properly exported names from thRootStuff.cpp
 30            *
 31 saw   1.3  *   Revision 1.2  2004/07/02 18:46:29  saw
 32            *   Update ugly cpp routine for gcc 3.2.3.  Need to find a better way to
 33            *   reference C++ routines.
 34            *
 35 saw   1.2  *   Revision 1.1  2002/07/31 20:07:48  saw
 36            *   Add files for ROOT Trees
 37            *
 38 saw   1.1  *   Revision 1.1  1999/08/25 13:16:07  saw
 39            *   *** empty log message ***
 40            *
 41            */
 42           
 43           #include <stdio.h>
 44           #include <stdlib.h>
 45           #include <string.h>
 46           #include <math.h>
 47           #include "daVar.h"
 48           #include "th.h"
 49           #include "thInternal.h"
 50           #include "thUtils.h"
 51           
 52 saw   1.4 #ifdef ROOTTREE
 53 saw   1.1 extern daVarStatus thTreeRHandler();
 54           
 55           struct thLeafList {		/* Variable and index list */
 56             struct thLeafList *next;
 57             char *name;
 58             int leafsize;			/* Number of bytes in leaf */
 59             char leaftype;		/* Single letter with leaf type */
 60             daVarStruct *varp; int index;
 61           };
 62           typedef struct thLeafList thLeafList;
 63           
 64           struct thTreeBranchList {
 65             struct thTreeBranchList *next;
 66             char *branchname;		/* Block name without the "block.hist" */
 67             void *evstruct;		/* Event structure to fill with data */
 68             struct thLeafList *leaflistp;
 69           };
 70           typedef struct thTreeBranchList thTreeBranchList;
 71           
 72           struct thTreeOpaque {		/* Opaque structure for histogram definition */
 73             void *file;
 74 saw   1.1   /*  void *file Need to point to structure that has file info.  File structures will also
 75             be on a linked list so that we a new file is opened, you can see if it exists.  Wait, we
 76           should just use davars.  Make a new class for files? ? 
 77            */
 78             void *treeptr;		/* Pointer to tree object */
 79             daVarStruct *test; int testindex;
 80             thTreeBranchList *branchlistP;
 81           };
 82           typedef struct thTreeOpaque thTreeOpaque;
 83           
 84           struct thRBlockList {
 85             struct thRBlockList *next;
 86             char *blockname;		/* Block name without the "block.tree" */
 87             daVarStruct *var;		/* Varptr points to # times called
 88           				   Title is code from file.
 89           				   opaque is pointer to hist speclist */
 90           };
 91           typedef struct thRBlockList thRBlockList;
 92           
 93           thRBlockList *thRBlockListP;	/* Pointer to list of tree blocks */
 94           
 95 saw   1.1 thStatus thBookaBranch(thTreeOpaque *tree, char *line, thTreeBranchList **thBranchNext);
 96                /*thStatus thExecuteaHist(thHistSpecList *Hist);*/
 97           thStatus thRemoveTree(char *block_name);
 98           
 99           thStatus thBookTree(daVarStruct *var)
100           {
101             char *lines,*eol;
102             int line_count;
103             thTreeBranchList **thBranchNext;
104             char *blockname;
105             thTreeOpaque *treedef;
106             int i;
107             int isopen;
108             char *lbuf=0;
109           
110             /*  thHistZeroLastId(); */
111             
112 saw   1.3   /* printf("In booktrees\n");*/
113 saw   1.1   /* Get the name without the block.test on it */
114             blockname = var->name;	/* If name doesn't fit pattern, use whole */
115             if(strcasestr(var->name,BLOCKSTR)==var->name){
116               i = strlen(BLOCKSTR) + 1;
117               if(strcasestr((var->name + i),TREESTR)==(var->name + i)){
118                 i += strlen(TREESTR);
119                 if(*(var->name + i) == '.'){
120           	blockname += i + 1;
121                 }
122               }
123             }
124           
125 saw   1.3   /*printf("Booking tree %s\n",blockname);*/
126 saw   1.1 
127             if(var->opaque) thRemoveTree(blockname);
128           
129             /* We assume for now that thRemoveTree completely removed the opaque definition)
130              */
131             treedef = var->opaque = (thTreeOpaque *) malloc(sizeof(thTreeOpaque));
132             thBranchNext = (thTreeBranchList **) &treedef->branchlistP;
133             
134             lines = var->title;
135             line_count = 0;
136             isopen = 0;
137             while(*lines){
138               char *lcopy;
139           
140               line_count++;
141               eol = strchr(lines,'\n');
142               if(!eol) {
143                 fprintf(stderr,"L %d: Last line of hist block %s has no newline\n"
144           	      ,line_count,var->name);
145                 break;
146               }
147 saw   1.1     if(*(eol+1)=='\0'){		/* This is the last line */
148                 if(strcasestr(lines,ENDSTR) == 0)
149           	fprintf(stderr,"L %d: Last line of tree block %s is not an END\n"
150           		,line_count,var->name);
151                 break;
152               }
153               if(line_count == 1) {
154                 char *fname=0;
155                 if(strcasestr(lines,BEGINSTR) !=0) {
156           	char *p;
157           	if(p = strcasestr(lines,"file=")) {
158           	  p += 5;
159           	  /* If " or ', grab to next matching char */
160           	  /* other interpret as variable.  But interpret as file if variable not found */
161           	  if(*p == QUOTECHAR1 || *p == QUOTECHAR2) {
162           	    char *s; int len;
163           	    s = p+1;
164           	    while(*s && *s != *p && *s !='\n') s++;
165           	    len = (s - p) - 1;
166           	    fname = malloc(len+1);
167           	    strncpy(fname,p+1,len);
168 saw   1.1 	    fname[len] = '\0';
169           	  } else {		/* Probably a variable */
170           	    char *varname=0; char *s; int len; int index;
171           	    daVarStruct *varp;
172           	    s = p;
173           	    while(*s && !isspace(*s) && *s !='\n') s++;
174           	    len = (s-p);
175           	    varname = malloc(len+1);
176           	    strncpy(varname,p,len);
177           	    varname[len] = '\0';
178           	    if(thVarResolve(varname,&varp,&index,1,0)==S_SUCCESS) {
179           	      printf("%s,type=%d, size=%d\n",varp->name,varp->type,varp->size);
180           	      printf("%s\n",(char *) varp->varptr);
181           	      if(varp->type == DAVARSTRING) {
182           		fname = malloc(strlen((char *)varp->varptr)+1);
183           		strcpy(fname,(char *)varp->varptr);
184           	      } else if(varp->type == DAVARFSTRING) {
185           		fname = malloc(varp->size+1);
186           		strncpy(fname,(char *)varp->varptr,varp->size);
187           		fname[varp->size] = '\0';
188           		p = fname;
189 saw   1.1 		while(*p && !isspace(*p)) p++;
190           		*p = '\0';	/* Null terminate at first blank */
191           	      }
192           	    }
193           	    if(!fname) {
194           	      fname = malloc(len+1);
195           	      strncpy(fname,p,len);
196           	      fname[len] = '\0';
197           	    }
198           	  }
199           	}
200 saw   1.5 	if(p = strcasestr(lines,"test=")) {
201           	  /* RHS must be a variable */
202           	  char *varname=0; char *s; int len, testindex;
203           	  daVarStruct *testp;
204           	  p += 5;
205           	  s = p;
206           	  while(*s && !isspace(*s) && *s !='\n') s++;
207           	  len = (s-p);
208           	  varname = (char *) malloc(len+1);
209           	  strncpy(varname,p,len);
210           	  varname[len] = '\0';
211           	  if(thVarResolve(varname,&testp,&testindex,1,0) != S_SUCCESS) {
212           	    return(S_FAILURE); /* Test flag not registered */
213                 /* ASAP we must change this to register variables as they are needed */
214                 /* If the variable exists, then we also must check to make sure that
215           	 the requested index does not exceed the size of the array.
216           	 a new thVarResolve should also increase the size of the array if
217           	 it was created by CTP */
218           	  }
219           	  treedef->test = testp;
220           	  treedef->testindex = testindex;
221 saw   1.5 	} else {
222           	  treedef->test = 0; /* No test, always true */
223           	}
224 saw   1.1       }
225                 
226                 if(fname) {
227           	/*printf("Opening Root file %s\n",fname);*/
228 saw   1.3 	treedef->file = (void *) thRoot_TFile(fname);
229 saw   1.1 	free(fname);
230                 } else {
231           	/*printf("Opening Root file %s\n","ctp.tree");*/
232 saw   1.3 	treedef->file = (void *) thRoot_TFile("ctp.root");
233 saw   1.1       }
234               
235                 /*printf("Call to TTree(\"%s\",\"title\") goes here\n",blockname);*/
236 saw   1.3       treedef->treeptr = (void *) thRoot_TTree(blockname);
237 saw   1.1 
238                 if(strcasestr(lines,BEGINSTR) != 0){
239           	/*	printf("Is a begin\n");*/
240           	lines = eol + 1;
241           	continue;
242                 } else
243           	fprintf(stderr,"First line of tree block %s is not a BEGIN\n",var->name);
244               }
245               /* Ready to book the line, Add continuation lines later */
246               lcopy = (char *) malloc(eol-lines+1);
247               strncpy(lcopy,lines,(eol-lines));
248               *(lcopy + (eol-lines)) = '\0';
249               if(!thCleanLine(lcopy)){
250                 if(strchr(lcopy,'=')) {	/* Start of a new branch */
251           	if(lbuf) {		/* Do we have a pending branch */
252           	  /*printf("Passing 1 |%s|\n",lbuf);*/
253           	  if(thBookaBranch(treedef,lbuf,thBranchNext)==S_SUCCESS){
254           	    thBranchNext = &((*thBranchNext)->next);
255           	  } else {
256           	    fprintf(stderr,"(%s): Tree booking error in line %d\n",var->name,line_count);
257           	  }
258 saw   1.1 	  free(lbuf);
259           	  lbuf = 0;
260           	}
261                 }
262                 if(lbuf) {		/* Append */
263           	char *lastcomma;
264           	char *firstcomma;
265           	int addcomma=0; 
266           	lastcomma = lbuf + strlen(lbuf) - 1;
267           	while(*lastcomma == ' ') lastcomma--;
268           	if(*lastcomma != ',' && *lastcomma != '=') lastcomma = 0;
269           	firstcomma = lcopy;
270           	while(*firstcomma == ' ') firstcomma++;
271           	if(*firstcomma != ',') firstcomma = 0;
272           	if(firstcomma && lastcomma) {
273           	  *firstcomma = ' ';
274           	} else if (!firstcomma && !lastcomma) {
275           	  addcomma = 1;
276           	}
277           	lbuf = realloc(lbuf,strlen(lbuf) + strlen(lcopy) + 2);
278           	if(addcomma) strcat(lbuf,",");
279 saw   1.1 	strcat(lbuf,lcopy);
280                 } else {			/* Make new lbuf */
281           	lbuf = malloc(strlen(lcopy)+1);
282           	strcpy(lbuf,lcopy);
283                 }
284               }
285               free(lcopy);
286               lines = eol+1;
287             }
288             if(lbuf) {			/* Do the last branch we were building */
289               /*printf("Passing 2 |%s|\n",lbuf);*/
290               if(thBookaBranch(treedef,lbuf,thBranchNext)==S_SUCCESS){
291                 thBranchNext = &((*thBranchNext)->next);
292               } else {
293                 fprintf(stderr,"(%s): Tree booking error in line %d\n",var->name,line_count);
294               }
295               free(lbuf);
296             }
297             /* Update internal table of trees. */
298             {
299               thRBlockList *thisblock,*nextblock,**lastblockp;
300 saw   1.1     nextblock = thRBlockListP;
301               lastblockp = &thRBlockListP;
302               thisblock = thRBlockListP;
303               while(thisblock){
304                 if((strcasecmp(thisblock->var->name,var->name)) == 0){
305           	/* Replacing a block with a new definition */
306           	fprintf(stderr,"Replacing %s with new definition\n",var->name);
307           	if(thisblock->var != var){
308           	  fprintf(stderr,"ERR: Same name, different var pointer\n");
309           	}
310           	break;
311                 }
312                 lastblockp = &thisblock->next;
313                 thisblock = thisblock->next;
314               }
315               if(!thisblock){		/* Create entry for New block */
316                 *lastblockp = thisblock = (thRBlockList *) malloc(sizeof(thRBlockList));
317                 thisblock->var = var;
318                 thisblock->next = (thRBlockList *) NULL;
319                 thisblock->blockname = (char *) malloc(strlen(blockname) + 1);
320                 strcpy(thisblock->blockname,blockname);
321 saw   1.1     }
322             }
323 saw   1.3   /*printf("Returning from booking a tree\n");*/
324 saw   1.1   return(S_SUCCESS);
325           }
326           
327           thStatus thBookaBranch(thTreeOpaque *treedef, char *line, thTreeBranchList **thBranchNext)
328                /* Interpret a branch def of the form branch=leaf1,leaf2,leaf3,... */
329                /* For now require the "branch=" part */
330           {
331           
332             /*  char *long_title;*/
333             int n,nleafs;
334             int lenbrancharg;
335             char *brancharg;
336             char *sleafs,*branchname;
337             thTreeBranchList *Branch;
338             thLeafList **LeafNext;
339             thLeafList *thisleaf;
340             daVarStruct *varp;
341             int vind;
342             char *args[100];
343           
344             /*printf("In thBookaBranch\n");*/
345 saw   1.1   if(!(sleafs = strchr(line,'='))) {
346               return(S_FAILURE);
347             }    
348             *sleafs=0;
349             sleafs++;			/* Pointer to list of leaves */
350             nleafs = thCommas(sleafs,args);
351             if(nleafs <=0) {
352               return(S_FAILURE);
353             }
354             Branch = *thBranchNext = (thTreeBranchList *) malloc(sizeof(thTreeBranchList));
355             Branch->next = (thTreeBranchList *) NULL;
356             branchname = thSpaceStrip(line);
357             Branch->branchname = malloc(strlen(branchname)+1);
358             LeafNext = (thLeafList **) &Branch->leaflistp;
359             strcpy(Branch->branchname,branchname);
360             lenbrancharg = 0;
361             for(n=0;n<nleafs;n++) {
362               char *nameptr;
363               /* Need to look for $name here.  name will be the name given to root */
364               args[n] = thSpaceStrip(args[n]);
365               /*printf("Leaf %s\n",args[n]);*/
366 saw   1.1     if(nameptr=strchr(args[n],'$')) *nameptr++=0;
367               if(thVarResolve(args[n],&varp,&vind,0,0) == S_SUCCESS) {
368                 char *p, snum[25];
369                 /*printf("Index=%d\n",vind);*/
370                 thisleaf = *LeafNext = (thLeafList *) malloc(sizeof(thLeafList));
371                 /*printf("thisleaf = %x\n",thisleaf);*/
372                 thisleaf->next = (thLeafList *) NULL;
373                 thisleaf->varp = varp;
374                 thisleaf->index = vind;
375                 /* Pick a good name */
376                 if(nameptr) {
377           	thisleaf->name = (char *) malloc(strlen(nameptr)+1);
378           	strcpy(thisleaf->name,nameptr);
379                 } else {
380           	if(p=strpbrk(args[n],"()[]")) {
381           	  sprintf(snum,"%d",vind+1);
382           	  thisleaf->name = (char *) malloc(strlen(args[n])+strlen(snum)+2);
383           	  strncpy(thisleaf->name,args[n],p-args[n]);
384           	  thisleaf->name[p-args[n]] = '\0';
385           	  strcat(thisleaf->name,"_");
386           	  strcat(thisleaf->name,snum);
387 saw   1.1 	} else {
388           	  thisleaf->name = (char *) malloc(strlen(args[n])+1);
389           	  strcpy(thisleaf->name,args[n]);
390           	}
391                 }
392                 LeafNext = &((*LeafNext)->next);
393                 lenbrancharg += strlen(args[n]) + 3;
394               }	else {
395                 fprintf(stderr,"Bad variable %s\n",args[n]);
396               }
397             }
398             /* Walk down the leaf list and build the Branch call argument */
399             /* What do I do about leaf names with subscripts? */
400             thisleaf = Branch->leaflistp;
401             brancharg = malloc(lenbrancharg+10);
402             brancharg[0] = '\0';
403             while(thisleaf) {
404 saw   1.3     /*printf("thisleaf = %x\n",thisleaf);
405                 printf("Adding %s to branchlist\n",thisleaf->name);*/
406 saw   1.1     strcat(brancharg,thisleaf->name);
407               if(thisleaf->varp->type == DAVARINT) {
408                 strcat(brancharg,"/I");
409                 thisleaf->leafsize=4;
410               } else if(thisleaf->varp->type == DAVARFLOAT) {
411                 strcat(brancharg,"/F");
412                 thisleaf->leafsize=4;
413               } else if(thisleaf->varp->type == DAVARDOUBLE) {
414                 strcat(brancharg,"/D");
415                 thisleaf->leafsize=8;
416               } else {
417                 fprintf(stderr,"Variable %s has unknown type\n");
418               }
419           
420               if(thisleaf->next) {
421                 strcat(brancharg,":");
422               }
423               thisleaf = thisleaf->next;
424             }
425           
426             /* Reserve enough space as if they were all double */
427 saw   1.1   Branch->evstruct = (void *) malloc(lenbrancharg*sizeof(double));
428           
429             /*
430                  * leaflist is the concatenation of all the variable names and types
431                    separated by a colon character :
432                    The variable name and the variable type are separated by a slash (/).
433                    The variable type may be 0,1 or 2 characters. If no type is given,
434                    the type of the variable is assumed to be the same as the previous
435                    variable. If the first variable does not have a type, it is assumed
436                    of type F by default. The list of currently supported types is given below:
437                       - C : a character string terminated by the 0 character
438                       - B : an 8 bit signed integer (Char_t)
439                       - b : an 8 bit unsigned integer (UChar_t)
440                       - S : a 16 bit signed integer (Short_t)
441                       - s : a 16 bit unsigned integer (UShort_t)
442                       - I : a 32 bit signed integer (Int_t)
443                       - i : a 32 bit unsigned integer (UInt_t)
444                       - F : a 32 bit floating point (Float_t)
445                       - D : a 64 bit floating point (Double_t)
446             */
447           
448 saw   1.3   printf("Branch=%s  Leafs=%s\n",Branch->branchname,brancharg);
449             thRoot_Branch(treedef->treeptr,Branch->branchname,(Branch->evstruct),brancharg);
450 saw   1.1 
451             free(brancharg);
452 saw   1.3   printf("Exiting book a branch\n");
453 saw   1.1   return(S_SUCCESS);
454           }
455             
456           thStatus thFillTreeV(daVarStruct *var){
457             thTreeOpaque *treedef;
458             thTreeBranchList *thisbranch;
459             thLeafList *thisleaf;
460             void *structp;
461 saw   1.3   /* printf("Executing Tree %s\n",var->name);*/
462 saw   1.1   treedef = ((thTreeOpaque *)(var->opaque));
463             thisbranch = treedef->branchlistP;
464 saw   1.5   if(! (treedef->test ? *((DAINT *) treedef->test->varptr
465           			  + treedef->testindex) : 1)) {
466               return(S_SUCCESS);  /* Test was false */
467             }
468 saw   1.1   while(thisbranch) {
469               structp = thisbranch->evstruct;
470               /*    printf("Filling branch %s at %x\n",thisbranch->branchname,structp);*/
471               thisleaf = thisbranch->leaflistp;
472               while(thisleaf) {
473                 if(thisleaf->varp->type == DAVARINT) {
474           	*((DAINT *)(structp))++ = *((DAINT *)thisleaf->varp->varptr
475           				    + thisleaf->index);
476           	/*	printf("   %s=%d\n",thisleaf->name,*((DAINT *)thisleaf->varp->varptr
477           		+ thisleaf->index));*/
478                 } else if(thisleaf->varp->type == DAVARFLOAT) {
479           	*((DAFLOAT *)(structp))++ = *((DAFLOAT *)thisleaf->varp->varptr
480           				    + thisleaf->index);
481           	/*	printf("   %s=%f\n",thisleaf->name,*((DAFLOAT *)thisleaf->varp->varptr
482           		+ thisleaf->index));*/
483                 } else if(thisleaf->varp->type == DAVARDOUBLE) {
484           	*((DADOUBLE *)(structp))++ = *((DADOUBLE *)thisleaf->varp->varptr
485           				    + thisleaf->index);
486           	/*	printf("   %s=%lf\n",thisleaf->name,*((DADOUBLE *)thisleaf->varp->varptr
487           		+ thisleaf->index));*/
488                 }
489 saw   1.1       thisleaf = thisleaf->next;
490               }
491               thisbranch = thisbranch->next;
492             }
493 saw   1.3   thRoot_Fill(treedef->treeptr);
494 saw   1.1 
495             (*((DAINT *)var->varptr))++; /* Increment block counter */
496             return(S_SUCCESS);
497           }
498           thStatus thClearTreeV(daVarStruct *var){
499             
500 saw   1.3   /* printf("Clearing Tree %s\n",var->name); */
501 saw   1.1 
502             (*((DAINT *)var->varptr)) = 0; /* Increment block counter */
503             return(S_SUCCESS);
504           }
505           thStatus thWriteTreeV(daVarStruct *var){
506             
507 saw   1.3   /* printf("Writing Tree %s\n",var->name); */
508             thRoot_Write(((thTreeOpaque *)(var->opaque))->file);
509 saw   1.1 
510             (*((DAINT *)var->varptr)) = 0; /* Increment block counter */
511             return(S_SUCCESS);
512           }
513           thStatus thCloseTreeV(daVarStruct *var){
514             
515 saw   1.3   /*printf("Closing Tree %s\n",var->name);*/
516             thRoot_Close(((thTreeOpaque *)(var->opaque))->file);
517 saw   1.1 
518             (*((DAINT *)var->varptr)) = 0; /* Increment block counter */
519             return(S_SUCCESS);
520           }
521           
522           thStatus thRemoveTree(char *treename) {
523             printf("Dummy routine to remove tree %s\n",treename);
524             return(S_SUCCESS);
525           }
526           
527           /*
528           int thtreewrite_()
529           {
530 saw   1.3   thRoot_Write();
531 saw   1.1 }
532           */
533 saw   1.4 
534           #else
535           
536           thStatus thBookTree(daVarStruct *var) {
537             return(S_SUCCESS);
538           }
539           
540           thStatus thFillTreeV(daVarStruct *var) {
541             return(S_SUCCESS);
542           }
543           thStatus thClearTreeV(daVarStruct *var) {
544             return(S_SUCCESS);
545           }
546           thStatus thWriteTreeV(daVarStruct *var) {
547             return(S_SUCCESS);
548           }
549           thStatus thCloseTreeV(daVarStruct *var) {
550             return(S_SUCCESS);
551           }
552 saw   1.1 
553           #endif

Analyzer/Replay: Mark Jones, Documents: Stephen Wood
Powered by
ViewCVS 0.9.2-cvsgraph-1.4.0