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