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

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