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