]>
Commit | Line | Data |
---|---|---|
ffab0c37 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | /* | |
17 | marian.ivanov@cern.ch | |
18 | ||
19 | //TOOLKIT for chain manipulation: | |
20 | //Example usage: | |
21 | // | |
22 | // 1. Check the list of files | |
23 | AliXRDPROOFtoolkit toolkit; | |
24 | AliXRDPROOFtoolkit::FilterList("pp.txt","AliESDs.root esdTree AliESDfriends.root * Kinematics.root *",0) | |
25 | AliXRDPROOFtoolkit::FilterList("pp.txt","AliESDs.root esdTree AliESDfriends.root * Kinematics.root *",1) | |
26 | // | |
27 | //2. make a chain or random chain form the list of files | |
28 | TChain * chain = toolkit.MakeChain("esd.txt","esdTree",0,10) | |
29 | TChain * chainRandom = toolkit.MakeChainrandom("esd.txt","esdTree",0,10) | |
30 | chain->Draw("fTPCnclsF"); | |
31 | ||
32 | ||
33 | */ | |
34 | #include <TTree.h> | |
35 | #include <TEnv.h> | |
36 | #include <TString.h> | |
37 | #include <TObjArray.h> | |
38 | #include <TObjString.h> | |
39 | #include <TTree.h> | |
40 | #include <TFile.h> | |
41 | #include <TChain.h> | |
42 | #include <TDSet.h> | |
43 | #include <TH1.h> | |
44 | #include <TGraph.h> | |
45 | #include <TMath.h> | |
46 | #include <TPad.h> | |
47 | #include <exception> | |
48 | #include <fstream> | |
49 | #include <TRandom.h> | |
50 | #include <AliXRDPROOFtoolkit.h> | |
51 | ||
52 | ||
53 | ClassImp(AliXRDPROOFtoolkit) | |
54 | ||
55 | ||
56 | ||
57 | //______________________________________________________________________________ | |
58 | AliXRDPROOFtoolkit::AliXRDPROOFtoolkit () : | |
59 | TObject () , | |
60 | fVerbose(kFALSE), // verbso mode - print command | |
61 | fUserName(""), // user name | |
62 | fUserGroup(0) // user group info | |
63 | { | |
64 | // | |
65 | // | |
66 | // | |
67 | fUserGroup = gSystem->GetUserInfo(); | |
68 | fUserName = fUserGroup->fUser; | |
69 | fVerbose=1; | |
70 | } | |
71 | ||
72 | ||
73 | ||
74 | ||
75 | ||
76 | TChain* AliXRDPROOFtoolkit::MakeChain(const char*fileIn, const char * treeName, const char *fName, Int_t maxFiles, Int_t startFile) | |
77 | { | |
78 | // | |
79 | // Create the chain | |
80 | // | |
81 | TChain* chain = new TChain(treeName); | |
82 | ||
83 | // Open the input stream | |
84 | ifstream in; | |
85 | in.open(fileIn); | |
86 | ||
87 | // Read the input list of files and add them to the chain | |
88 | TString currentFile; | |
89 | Int_t counter=0; | |
90 | while(in.good()) { | |
91 | in >> currentFile; | |
92 | if (fName) { | |
93 | currentFile+="#"; | |
94 | currentFile+=fName; | |
95 | } | |
96 | if (!currentFile.Contains("root")) continue; // protection | |
97 | counter++; | |
98 | if (counter<startFile) continue; | |
99 | if (counter>maxFiles+startFile) break; | |
0f923679 | 100 | TFile * f = TFile::Open(currentFile.Data()); |
101 | if (f){ | |
102 | chain->Add(currentFile.Data()); | |
103 | } | |
104 | delete f; | |
ffab0c37 | 105 | } |
106 | ||
107 | in.close(); | |
108 | ||
109 | return chain; | |
110 | } | |
111 | ||
112 | TChain* AliXRDPROOFtoolkit::MakeChainRandom(const char*fileIn, const char * treeName,const char *fName, Int_t maxFiles, Int_t startFile) | |
113 | { | |
114 | // | |
115 | // Create a TDSet - files are in random order | |
116 | // | |
117 | // filein - input list text file | |
118 | // treename - containg tree | |
119 | // maxFiles - maximum number of files included | |
120 | ||
121 | TObjArray array(10000); | |
122 | ||
123 | TChain* chain = new TChain(treeName); | |
124 | ||
125 | // Open the input stream | |
126 | ifstream in; | |
127 | in.open(fileIn); | |
128 | ||
129 | // Read the input list of files and add them to the chain | |
130 | TString currentFile; | |
131 | Int_t counter=0; | |
132 | while(in.good()) { | |
133 | in >> currentFile; | |
134 | if (fName) { | |
135 | currentFile+="#"; | |
136 | currentFile+=fName; | |
137 | } | |
138 | if (!currentFile.Contains("root")) continue; // protection | |
139 | counter++; | |
140 | // chain->Add(currentFile.Data()); | |
141 | array.AddLast(new TObjString(currentFile)); | |
142 | } | |
143 | in.close(); | |
144 | Int_t entries = array.GetEntries(); | |
145 | printf("Number of entries\t%d\n",entries); | |
146 | // | |
147 | // | |
148 | // | |
149 | Double_t *randomI = new Double_t[entries]; | |
150 | Int_t *indexes = new Int_t[entries]; | |
151 | for (Int_t i=0;i<entries; i++) randomI[i]=gRandom->Rndm(); | |
152 | TMath::Sort(entries,randomI,indexes); | |
153 | ||
154 | for (Int_t i=startFile; (i<startFile+maxFiles) && (i<entries); i++){ | |
155 | Int_t ifile = indexes[i]; | |
156 | if (ifile<entries && (array.At(ifile)) && array.At(ifile)->TestBit(TObject::kCannotPick)==kFALSE){ | |
157 | printf("%d\t%d\t%s\n",i, ifile, array.At(ifile)->GetName()); | |
158 | chain->Add(array.At(ifile)->GetName()); | |
159 | array.At(ifile)->SetBit(TObject::kCannotPick); | |
160 | } | |
161 | } | |
162 | return chain; | |
163 | } | |
164 | ||
165 | ||
166 | ||
167 | TDSet* AliXRDPROOFtoolkit::MakeSet(const char*fileIn, const char * treeName, const char *fName, Int_t maxFiles) | |
168 | { | |
169 | // | |
170 | // Create the TDSet out of list | |
171 | // filein - input list text file | |
172 | // treename - containg tree | |
173 | // maxFiles - maximum number of files included | |
174 | ||
175 | TDSet* chain = new TDSet(treeName); | |
176 | ||
177 | // Open the input stream | |
178 | ifstream in; | |
179 | in.open(fileIn); | |
180 | ||
181 | // Read the input list of files and add them to the chain | |
182 | TString currentFile; | |
183 | Int_t counter=0; | |
184 | while(in.good()) { | |
185 | in >> currentFile; | |
186 | if (fName) { | |
187 | currentFile+="#"; | |
188 | currentFile+=fName; | |
189 | } | |
190 | if (!currentFile.Contains("root")) continue; // protection | |
191 | counter++; | |
192 | if (maxFiles>0 && counter>maxFiles) break; | |
193 | chain->Add(currentFile.Data()); | |
194 | } | |
195 | ||
196 | in.close(); | |
197 | chain->Validate(); | |
198 | return chain; | |
199 | } | |
200 | ||
201 | ||
202 | TDSet* AliXRDPROOFtoolkit::MakeSetRandom(const char*fileIn, const char * treeName, const char *fName, Int_t maxFiles) | |
203 | { | |
204 | // | |
205 | // Create a TDSet - files are in random order | |
206 | // | |
207 | // filein - input list text file | |
208 | // treename - containg tree | |
209 | // maxFiles - maximum number of files included | |
210 | ||
211 | TObjArray array(10000); | |
212 | ||
213 | TDSet* chain = new TDSet(treeName); | |
214 | ||
215 | // Open the input stream | |
216 | ifstream in; | |
217 | in.open(fileIn); | |
218 | ||
219 | // Read the input list of files and add them to the chain | |
220 | TString currentFile; | |
221 | Int_t counter=0; | |
222 | while(in.good()) { | |
223 | in >> currentFile; | |
224 | if (fName) { | |
225 | currentFile+="#"; | |
226 | currentFile+=fName; | |
227 | } | |
228 | if (!currentFile.Contains("root")) continue; // protection | |
229 | counter++; | |
230 | // chain->Add(currentFile.Data()); | |
231 | array.AddLast(new TObjString(currentFile)); | |
232 | } | |
233 | in.close(); | |
234 | Int_t entries = array.GetEntries(); | |
235 | printf("Number of entries\t%d",entries); | |
236 | if (maxFiles<0) maxFiles=entries; | |
237 | if (maxFiles>entries) maxFiles=entries; | |
238 | for (Int_t i=0; i<maxFiles; i++){ | |
239 | Int_t ifile = TMath::Nint(gRandom->Rndm()*Float_t(entries)); | |
240 | if (ifile<entries && (array.At(ifile)) && array.At(ifile)->TestBit(TObject::kCannotPick)==kFALSE){ | |
241 | printf("%d\t%d\t%s\n",i, ifile, array.At(ifile)->GetName()); | |
242 | chain->Add(array.At(ifile)->GetName()); | |
243 | array.At(ifile)->SetBit(TObject::kCannotPick); | |
244 | } | |
245 | } | |
246 | ||
247 | ||
248 | chain->Validate(); | |
249 | return chain; | |
250 | } | |
251 | ||
252 | ||
253 | ||
254 | ||
255 | ||
256 | ||
ffab0c37 | 257 | |
258 | Int_t AliXRDPROOFtoolkit::CheckTreeInFile(const char*fileName,const char*treeName, Int_t debugLevel, const char *branchName){ | |
259 | // | |
260 | // Check the tree in file | |
261 | // fileName - the name of the file with tree | |
262 | // treeName - the name of file | |
263 | // debugLevel - 0 check the existance of the file - 1 make loop over entries | |
264 | // branchName - if debugLevel>0 the branch is chcecked | |
265 | // if brnachName =0 the content of full tree is chcecked | |
266 | // return value = 0 - Check things OK | |
267 | // -1 - file not exist or not accesible | |
268 | // -2 - file is zombie | |
269 | // -3 - tree not present | |
270 | // -4 - branch not present | |
271 | TFile * file = TFile::Open(fileName); | |
272 | if (!file) { return -1;} | |
273 | if (file->IsZombie()) {file->Close(); delete file; return -2;}; | |
274 | ||
275 | TString TrName(treeName); | |
276 | if (TrName=="*") { | |
277 | //cout <<" treename ==== *"<<endl;; | |
278 | file->Close(); delete file; | |
279 | return 0; | |
280 | } | |
281 | TTree * tree = (TTree*)file->Get(treeName); | |
282 | if (!tree) {file->Close(); delete file; return -3;} | |
283 | TBranch * branch = 0; | |
284 | if (branchName) { | |
285 | branch = tree->GetBranch(branchName); | |
286 | if (!branch) {file->Close(); delete file; return -4;} | |
287 | } | |
288 | // | |
289 | if (debugLevel==1 && tree->GetEntries()==0 ) return 1; //empty | |
290 | ||
291 | tree->SetBranchStatus("*",1); | |
292 | try { | |
293 | if (debugLevel>1){ | |
294 | Int_t entries = tree->GetEntries(); | |
295 | for (Int_t i=0;i<entries; i++){ | |
296 | if (branch) branch->GetEntry(i); | |
297 | else tree->GetEntry(); | |
298 | } | |
299 | } | |
300 | }catch ( ... ) { | |
301 | printf("PROBLEM\n"); | |
302 | // never catched - as there is no exception in the ROOT IO | |
303 | file->Close(); delete file; | |
304 | return 1 ; | |
305 | } | |
306 | ||
307 | file->Close(); delete file; | |
308 | return 0; | |
309 | } | |
310 | ||
311 | ||
312 | Bool_t AliXRDPROOFtoolkit::FilterList(const char*inputList, const char*fileList, Int_t checkLevel){ | |
313 | // | |
314 | // Filter the list | |
315 | // inputList - list of original file names | |
316 | // fileList - list of file to be checked | |
317 | // - 0 - fileName | |
318 | // - 1 - treeName (if * not checked) | |
319 | // - 2 - fileName | |
320 | // .... | |
321 | // checkLevel - 0 - check only existance of the files and tree's + | |
322 | // simple file corruption | |
323 | // > 1 - check the content of the tree - | |
324 | // (can crash as there do not exest exception handling in ROOT) | |
325 | // Output - two streams are created - file with good entries | |
326 | // "%s.Good a,d file with bad entries %s.Bad | |
327 | //EXAMPLE: | |
328 | // AliXRDPROOFtoolkit::FilterList("ppgrid2.txt","AliESDs.root esdTree AliESDfriends.root * Kinematics.root *",1) | |
329 | gEnv->SetValue("TFile.Recover", 0); | |
330 | // | |
331 | fstream finput; | |
332 | finput.open(inputList, ios_base::in); | |
333 | fstream focGood; | |
334 | fstream focBad; | |
335 | focGood.open(Form("%s.Good",inputList), ios_base::out|ios_base::trunc); | |
336 | focBad.open(Form("%s.Bad",inputList), ios_base::out|ios_base::trunc); | |
337 | // | |
338 | if(!finput.is_open()) { | |
339 | cout<<"Can't open file "<<inputList<<endl; | |
340 | return kFALSE; | |
341 | } | |
342 | // | |
343 | // Read the input list of files and add them to the chain | |
344 | // | |
345 | TObjArray *array = (TString(fileList)).Tokenize(" "); | |
346 | TString currentFile; | |
347 | Int_t counter=0; | |
348 | while(finput.good()) { | |
349 | finput >> currentFile; | |
350 | if (!currentFile.Contains("root")) continue; // protection | |
351 | if (currentFile.Contains("alien://")){ | |
352 | focGood<<currentFile<<endl; | |
353 | continue; | |
354 | } | |
355 | Bool_t isZip = currentFile.Contains("#"); | |
356 | const char * dirname = gSystem->DirName(currentFile.Data()); | |
357 | Int_t status = 0; | |
358 | // | |
359 | for (Int_t i=0; i<array->GetEntries(); i+=2){ | |
360 | char fname[1000]; | |
361 | if (!isZip){ | |
472f0066 | 362 | snprintf(fname,1000, "%s/%s",dirname,array->At(i)->GetName()); |
ffab0c37 | 363 | if (((TObjString*)array->At(i))->String().Contains("*")){ |
472f0066 | 364 | snprintf(fname,1000, "%s", currentFile.Data()); |
ffab0c37 | 365 | } |
366 | } | |
367 | if (isZip) { | |
368 | const char * fileName = gSystem->BaseName(currentFile.Data()); | |
369 | TString fstring=fileName; | |
370 | fstring[fstring.First("#")]=0; | |
472f0066 | 371 | snprintf(fname,1000, "%s/%s#%s",dirname,fstring.Data(),array->At(i)->GetName()); |
ffab0c37 | 372 | printf(fname, "To check %s%s#%s\n",dirname,fstring.Data(),array->At(i)->GetName()); |
373 | } | |
374 | ||
375 | printf("\nFile to be checked %s\n",fname); | |
376 | //cout <<"\n arguments: "<< array->At(i+1)->GetName()<<" "<<checkLevel<<endl; | |
377 | Int_t cstatus = CheckTreeInFile(fname, array->At(i+1)->GetName(), checkLevel,0); | |
378 | //printf(" CheckTreeInFile returns %d",cstatus); | |
379 | if (cstatus!=0) { | |
380 | status = cstatus; | |
381 | break; | |
382 | } | |
383 | } | |
384 | if (status==0){ | |
385 | focGood<<currentFile<<endl; | |
386 | }else{ | |
387 | focBad<<currentFile<<endl; | |
388 | } | |
389 | counter++; | |
390 | } | |
391 | finput.close(); | |
392 | return kTRUE; | |
393 | } | |
394 | ||
395 | ||
396 | Bool_t AliXRDPROOFtoolkit::FilterListZip(const char*inputList, const char*fileList, Int_t checkLevel){ | |
397 | // | |
398 | // Filter the list | |
399 | // inputList - list of original file names | |
400 | // fileList - list of file to be checked | |
401 | // - 0 - fileName | |
402 | // - 1 - treeName (if * not checked) | |
403 | // - 2 - fileName | |
404 | // .... | |
405 | // checkLevel - 0 - check only existance of the files and tree's + | |
406 | // simple file corruption | |
407 | // > 1 - check the content of the tree - | |
408 | // (can crash as there do not exest exception handling in ROOT) | |
409 | // Output - two streams are created - file with good entries | |
410 | // "%s.Good a,d file with bad entries %s.Bad | |
411 | //EXAMPLE: | |
412 | // AliXRDPROOFtoolkit::FilterList("ppgrid2.txt","AliESDs.root esdTree AliESDfriends.root * Kinematics.root *",1) | |
413 | ||
414 | fstream finput; | |
415 | finput.open(inputList, ios_base::in); | |
416 | fstream focGood; | |
417 | fstream focBad; | |
418 | focGood.open(Form("%s.Good",inputList), ios_base::out|ios_base::trunc); | |
419 | focBad.open(Form("%s.Bad",inputList), ios_base::out|ios_base::trunc); | |
420 | // | |
421 | if(!finput.is_open()) { | |
422 | cout<<"Can't open file "<<inputList<<endl; | |
423 | return kFALSE; | |
424 | } | |
425 | // | |
426 | // Read the input list of files and add them to the chain | |
427 | // | |
428 | TObjArray *array = (TString(fileList)).Tokenize(" "); | |
429 | TString currentFile; | |
430 | Int_t counter=0; | |
431 | while(finput.good()) { | |
432 | finput >> currentFile; | |
433 | if (!currentFile.Contains("root")) continue; // protection | |
434 | if (currentFile.Contains("alien://")){ | |
435 | focGood<<currentFile<<endl; | |
436 | continue; | |
437 | } | |
438 | //Bool_t isZip = currentFile.Contains("#"); | |
439 | const char * dirname = gSystem->DirName(currentFile.Data()); | |
440 | const char * fileName = gSystem->BaseName(currentFile.Data()); | |
441 | TString fstring=fileName; | |
442 | fstring[fstring.First("#")]=0; | |
443 | Int_t status = 0; | |
444 | for (Int_t i=0; i<array->GetEntries(); i+=2){ | |
445 | char fname[1000]; | |
446 | //if (isZip) sprintf(fname, | |
472f0066 | 447 | snprintf(fname,1000, "%s/%s#%s",dirname,fstring.Data(),array->At(i)->GetName()); |
ffab0c37 | 448 | printf(fname, "To check %s%s#%s\n",dirname,fstring.Data(),array->At(i)->GetName()); |
449 | //cout <<"\n arguments: "<< array->At(i+1)->GetName()<<" "<<checkLevel<<endl; | |
450 | Int_t cstatus = CheckTreeInFile(fname, array->At(i+1)->GetName(), checkLevel,0); | |
451 | //printf(" CheckTreeInFile returns %d",cstatus); | |
452 | if (cstatus!=0) { | |
453 | status = cstatus; | |
454 | break; | |
455 | } | |
456 | } | |
457 | if (status==0){ | |
458 | focGood<<currentFile<<endl; | |
459 | }else{ | |
460 | focBad<<currentFile<<endl; | |
461 | } | |
462 | counter++; | |
463 | } | |
464 | finput.close(); | |
465 | return kTRUE; | |
466 | } | |
467 | ||
468 | ||
469 | ||
470 | ||
471 | ||
472 | Bool_t AliXRDPROOFtoolkit::XRDCopyDir(const char * idir, const char * files, const char *odir, Bool_t /*zip*/){ | |
473 | // | |
474 | // idir - input directory | |
475 | // odir - output directory | |
476 | // files - the list of files to be coppied | |
477 | // zip - not supported yet | |
478 | // | |
479 | // Example : | |
480 | // | |
481 | // idir ="root://gsiaf.gsi.de:1094//sma/sim/v4-05-Rev-03/pp/0000"; | |
482 | // odir ="root://lxgrid2.gsi.de:1094//miranov/test/pp/0000"; | |
483 | // char *files="AliESDs.root AliESDfriend.root Kinematics.root"; | |
484 | TString str(files); | |
485 | TObjArray * array = str.Tokenize(" "); | |
486 | Int_t nfiles = array->GetEntries(); | |
487 | char infile[1000]; | |
488 | char outfile[1000]; | |
489 | Bool_t succes=kTRUE; | |
490 | for (Int_t ifile =0; ifile<nfiles; ifile++){ | |
472f0066 | 491 | snprintf(infile,1000,"%s/%s", idir, array->At(ifile)->GetName()); |
492 | snprintf(outfile,1000,"%s/%s", odir, array->At(ifile)->GetName()); | |
ffab0c37 | 493 | printf("%s - %s\n",infile, outfile); |
494 | Bool_t result = TFile::Cp(infile,outfile); | |
495 | succes &= result; | |
496 | } | |
497 | return succes; | |
498 | } | |
499 | ||
500 | ||
501 | ||
e87bf665 | 502 | void AliXRDPROOFtoolkit::JoinTreesIndex(const char * outputFile, const char * outputTree, const char *indexName, const char *inputTrees, Int_t debugLevel){ |
503 | // | |
504 | // Join together several tree according to the index | |
505 | // | |
506 | // Parameters: | |
507 | // Output: | |
508 | // outputFile : name of the output file | |
509 | // outputTree : name of the output Tree | |
510 | // indexName : name of the branch to be used as an index | |
511 | // Input: | |
512 | // inputTrees : decription of the input trees setup | |
513 | /* | |
514 | Example usage: | |
515 | ||
516 | AliXRDPROOFtoolkit::JoinTreesIndex("outAll.root","joinAll","run","1#CPass1#run#tpcQA#TPCCPass1.root+1#VPass1#run#tpcQA#TPCVPass1.root+1#Pass1#run#tpcQA#TPCPass1.root+0#DAQ#run#joinTree#fproductionJoin.root+0#C#run#dcs#OCDBscan.root+0#CE#run#Fits#CEtrend.root"); | |
517 | ==> | |
518 | Combine information form the Cpass1,VPass, and Pass1QA, calibration tree, DAQ information, trigger information | |
519 | Make a File "outAll.root", with tree "joinAll", index of tree with name "run" | |
520 | // | |
521 | // Input tree configuration string: | |
522 | // | |
523 | const char *inputTrees="1#CPass1#run#tpcQA#TPCCPass1.root+1#VPass1#run#tpcQA#TPCVPass1.root+1#Pass1#run#tpcQA#TPCPass1.root+0#DAQ#run#joinTree#/home/miranov/test/dbQueries/fproductionJoin.root+0#C#run#dcs#OCDBscan.root+0#CE#run#Fits#CEtrend.root" | |
524 | Describe 6 trees to be merged (string separated be +): | |
525 | TObjArray *arrayInput = TString(inputTrees).Tokenize("+"); | |
526 | TObjString = 1#CPass1#run#tpcQA#TPCCPass1.root | |
527 | TObjString = 1#VPass1#run#tpcQA#TPCVPass1.root | |
528 | TObjString = 1#Pass1#run#tpcQA#TPCPass1.root | |
529 | TObjString = 0#DAQ#run#joinTree#/home/miranov/test/dbQueries/fproductionJoin.root | |
530 | TObjString = 0#C#run#dcs#OCDBscan.root | |
531 | TObjString = 0#CE#run#Fits#CEtrend.root | |
532 | // | |
533 | Each tree is characterize by 5 parameters - separate by # | |
534 | description="1#CPass1#run#tpcQA#TPCCPass1.root" | |
535 | TString(description)->Tokenize("#").Print() | |
536 | Collection name='TObjArray', class='TObjArray', size=16 | |
537 | TObjString = 1 ==> (0/1) index is used | |
538 | TObjString = CPass1 ==> name of output branch in output tree | |
539 | TObjString = run ==> name of the index | |
540 | TObjString = tpcQA ==> name of the input tree in the input file | |
541 | TObjString = TPCCPass1.root ==> name of the input file | |
542 | */ | |
543 | // | |
544 | // | |
545 | // | |
546 | ||
547 | TFile * fout = new TFile(outputFile,"recreate"); | |
548 | fout->cd(); | |
549 | TTree *joinTree=new TTree(outputTree,outputTree); | |
550 | // | |
551 | // 1. Define setup. parse definition string | |
552 | // | |
553 | TObjArray *arrayInput = TString(inputTrees).Tokenize("+"); | |
554 | Int_t nTrees = arrayInput->GetEntries(); | |
555 | TObjArray * arrayFile = new TObjArray(nTrees); // array of TFiles with trees | |
556 | TObjArray * arrayTrees = new TObjArray(nTrees); // array of trees | |
557 | TObjArray * arrayNames = new TObjArray(nTrees); // name of tree | |
558 | TObjArray * arrayRunID = new TObjArray(nTrees); // name of tree | |
559 | TArrayI arrayEnableTree(nTrees); | |
560 | for (Int_t i=0; i<2; i++) printf("\n"); | |
561 | printf("Joing query\n"); | |
562 | arrayInput->Print(); | |
563 | for (Int_t i=0; i<2; i++) printf("\n"); | |
564 | {for (Int_t itree=0; itree<nTrees; itree++){ | |
565 | // | |
566 | TObjArray *description = TString(arrayInput->At(itree)->GetName()).Tokenize("#"); | |
567 | if (description->GetEntries()<4) { | |
568 | printf("Fatal: Invalid description: %s\n", arrayInput->At(itree)->GetName()); | |
569 | continue; | |
570 | } | |
571 | TFile * f = TFile::Open(description->At(4)->GetName()); | |
572 | if (!f){ | |
573 | printf("Fatal: Invalid description: fileName %s\n", description->At(4)->GetName()); | |
574 | return; | |
575 | } | |
576 | arrayFile->AddAt(f,itree); | |
577 | TTree * tree = (TTree*)f->Get(description->At(3)->GetName()); | |
578 | if (!tree){ | |
579 | printf("Fatal: Invalid description. Tree name\t%s\n", description->At(3)->GetName()); | |
580 | return; | |
581 | } | |
582 | tree->SetCacheSize(400000000); | |
583 | // | |
584 | arrayTrees->AddAt(tree,itree); | |
585 | // | |
586 | arrayRunID->AddAt(new TObjString(description->At(2)->GetName()),itree); | |
587 | arrayNames->AddAt(new TObjString(description->At(1)->GetName()),itree); | |
588 | arrayEnableTree[itree]=atoi(description->At(0)->GetName()); | |
589 | ||
590 | }} | |
591 | // | |
592 | // 2. Make the run list | |
593 | // | |
594 | // | |
595 | map<int, int> runMap; | |
063feb04 | 596 | map<int, int> *runMapTree = new map<int, int>[nTrees]; |
597 | //map<int, int> runMapTree[nTrees]; | |
e87bf665 | 598 | {for (Int_t itree=0; itree<nTrees; itree++){ |
599 | TTree * tree = (TTree*)arrayTrees->At(itree); | |
600 | Int_t entries=tree->GetEntries(); | |
601 | char query[2000]; | |
602 | snprintf(query,2000,"%s:Entry$", arrayRunID->At(itree)->GetName()); | |
603 | entries = tree->Draw(query,"","goff"); | |
604 | for (Int_t ientry=0;ientry<entries; ientry++){ | |
605 | Int_t irun=Int_t(tree->GetV1()[ientry]); | |
606 | // Int_t entryNr=Int_t(tree->GetV2()[ientry]); | |
607 | if (arrayEnableTree[itree]>0) runMap[irun]+=1; | |
608 | runMapTree[itree][irun]=ientry; | |
609 | if (debugLevel>0) printf("%s\t%d\t%d\n",tree->GetName(), irun, runMapTree[itree][irun]); | |
610 | } | |
611 | } | |
612 | } | |
613 | // | |
614 | // 3. Make join tree | |
615 | // | |
616 | Int_t jrun=0; | |
617 | joinTree->Branch(indexName, &jrun,Form("%s/I",indexName)); | |
618 | Int_t *status=new Int_t[nTrees]; | |
619 | char *brName = new char[10000]; | |
620 | char *brTitle= new char[10000]; | |
621 | // | |
622 | ||
623 | {for (Int_t itree=0; itree<nTrees; itree++){ | |
624 | TTree * tree = (TTree*)arrayTrees->At(itree); | |
625 | tree->GetEntry(1); | |
063feb04 | 626 | TString treeName=arrayNames->At(itree)->GetName(); |
627 | if (treeName.Length()>0){ | |
628 | joinTree->Branch(Form("%s.status",treeName.Data()), &status[itree],Form("%s.status/I",treeName.Data())); | |
629 | }else{ | |
630 | joinTree->Branch("status", &status[itree],"status/I"); | |
631 | } | |
e87bf665 | 632 | // |
633 | Int_t nbranches= tree->GetListOfBranches()->GetEntries(); | |
634 | for (Int_t ibr=0; ibr<nbranches; ibr++){ | |
635 | TBranch * br = (TBranch*)(tree->GetListOfBranches()->At(ibr)); | |
063feb04 | 636 | if (treeName.Length()>0){ |
637 | sprintf(brName,"%s.%s",treeName.Data(), br->GetName()); | |
638 | sprintf(brTitle,"%s.%s",treeName.Data(), br->GetTitle()); | |
639 | }else{ | |
640 | sprintf(brName,"%s",br->GetName()); | |
641 | sprintf(brTitle,"%s",br->GetTitle()); | |
642 | } | |
e87bf665 | 643 | void* addr = 0; |
644 | TString className=br->GetClassName(); | |
645 | if (className.Length()==0){ | |
646 | TString str(br->GetTitle()); | |
647 | if (str[str.Length()-1]=='I') addr=new Int_t; | |
648 | if (str[str.Length()-1]=='F') addr=new Float_t; | |
649 | if (str[str.Length()-1]=='D') addr=new Double_t; | |
650 | if (str[str.Length()-1]=='C') addr=new Char_t[10000]; | |
651 | if (addr) joinTree->Branch(brName, addr, brTitle); | |
652 | br->SetAddress(addr); | |
653 | }else{ | |
654 | TClass cclass(className); | |
655 | TObject **addrClass = new TObject *; | |
656 | (*addrClass)=0; | |
657 | printf("%s\t%s\n",br->GetName(), className.Data()); | |
658 | br->SetAddress(addrClass); | |
659 | br->GetEntry(0); | |
660 | joinTree->Branch(brName,addrClass); | |
661 | } | |
662 | } | |
663 | } | |
664 | } | |
665 | joinTree->Write(); | |
666 | // | |
667 | // 4. Fill the trees | |
668 | // | |
669 | map<int, int>::iterator riter; | |
670 | {for (riter=runMap.begin(); riter != runMap.end(); ++riter){ | |
671 | printf("%d\t%d\t", riter->first, riter->second); | |
672 | jrun=riter->first; | |
673 | for (Int_t itree=0; itree<nTrees; itree++){ | |
674 | TTree * tree = (TTree*)arrayTrees->At(itree); | |
675 | Int_t entry= runMapTree[itree][jrun]; | |
676 | status[itree]=(entry>0)?1:0; | |
677 | if (entry>=0) tree->GetEntry(entry); | |
678 | printf("%d\t",entry); | |
679 | // | |
680 | } | |
681 | joinTree->Fill(); | |
682 | printf("\n"); | |
683 | }} | |
684 | joinTree->Write("joinTree"); | |
685 | fout->Close(); | |
686 | ||
687 | } | |
688 | ||
ffab0c37 | 689 |