]>
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> | |
d4e3890b | 50 | #include <TTimeStamp.h> |
ffab0c37 | 51 | #include <AliXRDPROOFtoolkit.h> |
52 | ||
53 | ||
54 | ClassImp(AliXRDPROOFtoolkit) | |
55 | ||
56 | ||
57 | ||
58 | //______________________________________________________________________________ | |
59 | AliXRDPROOFtoolkit::AliXRDPROOFtoolkit () : | |
60 | TObject () , | |
61 | fVerbose(kFALSE), // verbso mode - print command | |
62 | fUserName(""), // user name | |
63 | fUserGroup(0) // user group info | |
64 | { | |
65 | // | |
66 | // | |
67 | // | |
68 | fUserGroup = gSystem->GetUserInfo(); | |
69 | fUserName = fUserGroup->fUser; | |
70 | fVerbose=1; | |
71 | } | |
72 | ||
73 | ||
74 | ||
75 | ||
76 | ||
77 | TChain* AliXRDPROOFtoolkit::MakeChain(const char*fileIn, const char * treeName, const char *fName, Int_t maxFiles, Int_t startFile) | |
78 | { | |
79 | // | |
80 | // Create the chain | |
81 | // | |
82 | TChain* chain = new TChain(treeName); | |
83 | ||
84 | // Open the input stream | |
85 | ifstream in; | |
86 | in.open(fileIn); | |
87 | ||
88 | // Read the input list of files and add them to the chain | |
89 | TString currentFile; | |
90 | Int_t counter=0; | |
91 | while(in.good()) { | |
92 | in >> currentFile; | |
93 | if (fName) { | |
94 | currentFile+="#"; | |
95 | currentFile+=fName; | |
96 | } | |
97 | if (!currentFile.Contains("root")) continue; // protection | |
98 | counter++; | |
99 | if (counter<startFile) continue; | |
100 | if (counter>maxFiles+startFile) break; | |
0f923679 | 101 | TFile * f = TFile::Open(currentFile.Data()); |
102 | if (f){ | |
103 | chain->Add(currentFile.Data()); | |
104 | } | |
105 | delete f; | |
ffab0c37 | 106 | } |
107 | ||
108 | in.close(); | |
109 | ||
110 | return chain; | |
111 | } | |
112 | ||
113 | TChain* AliXRDPROOFtoolkit::MakeChainRandom(const char*fileIn, const char * treeName,const char *fName, Int_t maxFiles, Int_t startFile) | |
114 | { | |
115 | // | |
116 | // Create a TDSet - files are in random order | |
117 | // | |
118 | // filein - input list text file | |
119 | // treename - containg tree | |
120 | // maxFiles - maximum number of files included | |
121 | ||
122 | TObjArray array(10000); | |
123 | ||
124 | TChain* chain = new TChain(treeName); | |
125 | ||
126 | // Open the input stream | |
127 | ifstream in; | |
128 | in.open(fileIn); | |
129 | ||
130 | // Read the input list of files and add them to the chain | |
131 | TString currentFile; | |
132 | Int_t counter=0; | |
133 | while(in.good()) { | |
134 | in >> currentFile; | |
135 | if (fName) { | |
136 | currentFile+="#"; | |
137 | currentFile+=fName; | |
138 | } | |
139 | if (!currentFile.Contains("root")) continue; // protection | |
140 | counter++; | |
141 | // chain->Add(currentFile.Data()); | |
142 | array.AddLast(new TObjString(currentFile)); | |
143 | } | |
144 | in.close(); | |
145 | Int_t entries = array.GetEntries(); | |
146 | printf("Number of entries\t%d\n",entries); | |
147 | // | |
148 | // | |
149 | // | |
150 | Double_t *randomI = new Double_t[entries]; | |
151 | Int_t *indexes = new Int_t[entries]; | |
152 | for (Int_t i=0;i<entries; i++) randomI[i]=gRandom->Rndm(); | |
153 | TMath::Sort(entries,randomI,indexes); | |
154 | ||
155 | for (Int_t i=startFile; (i<startFile+maxFiles) && (i<entries); i++){ | |
156 | Int_t ifile = indexes[i]; | |
157 | if (ifile<entries && (array.At(ifile)) && array.At(ifile)->TestBit(TObject::kCannotPick)==kFALSE){ | |
158 | printf("%d\t%d\t%s\n",i, ifile, array.At(ifile)->GetName()); | |
159 | chain->Add(array.At(ifile)->GetName()); | |
160 | array.At(ifile)->SetBit(TObject::kCannotPick); | |
161 | } | |
162 | } | |
163 | return chain; | |
164 | } | |
165 | ||
166 | ||
167 | ||
168 | TDSet* AliXRDPROOFtoolkit::MakeSet(const char*fileIn, const char * treeName, const char *fName, Int_t maxFiles) | |
169 | { | |
170 | // | |
171 | // Create the TDSet out of list | |
172 | // filein - input list text file | |
173 | // treename - containg tree | |
174 | // maxFiles - maximum number of files included | |
175 | ||
176 | TDSet* chain = new TDSet(treeName); | |
177 | ||
178 | // Open the input stream | |
179 | ifstream in; | |
180 | in.open(fileIn); | |
181 | ||
182 | // Read the input list of files and add them to the chain | |
183 | TString currentFile; | |
184 | Int_t counter=0; | |
185 | while(in.good()) { | |
186 | in >> currentFile; | |
187 | if (fName) { | |
188 | currentFile+="#"; | |
189 | currentFile+=fName; | |
190 | } | |
191 | if (!currentFile.Contains("root")) continue; // protection | |
192 | counter++; | |
193 | if (maxFiles>0 && counter>maxFiles) break; | |
194 | chain->Add(currentFile.Data()); | |
195 | } | |
196 | ||
197 | in.close(); | |
198 | chain->Validate(); | |
199 | return chain; | |
200 | } | |
201 | ||
202 | ||
203 | TDSet* AliXRDPROOFtoolkit::MakeSetRandom(const char*fileIn, const char * treeName, const char *fName, Int_t maxFiles) | |
204 | { | |
205 | // | |
206 | // Create a TDSet - files are in random order | |
207 | // | |
208 | // filein - input list text file | |
209 | // treename - containg tree | |
210 | // maxFiles - maximum number of files included | |
211 | ||
212 | TObjArray array(10000); | |
213 | ||
214 | TDSet* chain = new TDSet(treeName); | |
215 | ||
216 | // Open the input stream | |
217 | ifstream in; | |
218 | in.open(fileIn); | |
219 | ||
220 | // Read the input list of files and add them to the chain | |
221 | TString currentFile; | |
222 | Int_t counter=0; | |
223 | while(in.good()) { | |
224 | in >> currentFile; | |
225 | if (fName) { | |
226 | currentFile+="#"; | |
227 | currentFile+=fName; | |
228 | } | |
229 | if (!currentFile.Contains("root")) continue; // protection | |
230 | counter++; | |
231 | // chain->Add(currentFile.Data()); | |
232 | array.AddLast(new TObjString(currentFile)); | |
233 | } | |
234 | in.close(); | |
235 | Int_t entries = array.GetEntries(); | |
236 | printf("Number of entries\t%d",entries); | |
237 | if (maxFiles<0) maxFiles=entries; | |
238 | if (maxFiles>entries) maxFiles=entries; | |
239 | for (Int_t i=0; i<maxFiles; i++){ | |
240 | Int_t ifile = TMath::Nint(gRandom->Rndm()*Float_t(entries)); | |
241 | if (ifile<entries && (array.At(ifile)) && array.At(ifile)->TestBit(TObject::kCannotPick)==kFALSE){ | |
242 | printf("%d\t%d\t%s\n",i, ifile, array.At(ifile)->GetName()); | |
243 | chain->Add(array.At(ifile)->GetName()); | |
244 | array.At(ifile)->SetBit(TObject::kCannotPick); | |
245 | } | |
246 | } | |
247 | ||
248 | ||
249 | chain->Validate(); | |
250 | return chain; | |
251 | } | |
252 | ||
253 | ||
254 | ||
255 | ||
256 | ||
257 | ||
ffab0c37 | 258 | |
259 | Int_t AliXRDPROOFtoolkit::CheckTreeInFile(const char*fileName,const char*treeName, Int_t debugLevel, const char *branchName){ | |
260 | // | |
261 | // Check the tree in file | |
262 | // fileName - the name of the file with tree | |
263 | // treeName - the name of file | |
264 | // debugLevel - 0 check the existance of the file - 1 make loop over entries | |
265 | // branchName - if debugLevel>0 the branch is chcecked | |
266 | // if brnachName =0 the content of full tree is chcecked | |
267 | // return value = 0 - Check things OK | |
268 | // -1 - file not exist or not accesible | |
269 | // -2 - file is zombie | |
270 | // -3 - tree not present | |
271 | // -4 - branch not present | |
272 | TFile * file = TFile::Open(fileName); | |
273 | if (!file) { return -1;} | |
274 | if (file->IsZombie()) {file->Close(); delete file; return -2;}; | |
275 | ||
276 | TString TrName(treeName); | |
277 | if (TrName=="*") { | |
278 | //cout <<" treename ==== *"<<endl;; | |
279 | file->Close(); delete file; | |
280 | return 0; | |
281 | } | |
282 | TTree * tree = (TTree*)file->Get(treeName); | |
283 | if (!tree) {file->Close(); delete file; return -3;} | |
284 | TBranch * branch = 0; | |
285 | if (branchName) { | |
286 | branch = tree->GetBranch(branchName); | |
287 | if (!branch) {file->Close(); delete file; return -4;} | |
288 | } | |
289 | // | |
290 | if (debugLevel==1 && tree->GetEntries()==0 ) return 1; //empty | |
291 | ||
292 | tree->SetBranchStatus("*",1); | |
293 | try { | |
294 | if (debugLevel>1){ | |
295 | Int_t entries = tree->GetEntries(); | |
296 | for (Int_t i=0;i<entries; i++){ | |
297 | if (branch) branch->GetEntry(i); | |
298 | else tree->GetEntry(); | |
299 | } | |
300 | } | |
301 | }catch ( ... ) { | |
302 | printf("PROBLEM\n"); | |
303 | // never catched - as there is no exception in the ROOT IO | |
304 | file->Close(); delete file; | |
305 | return 1 ; | |
306 | } | |
307 | ||
308 | file->Close(); delete file; | |
309 | return 0; | |
310 | } | |
311 | ||
312 | ||
313 | Bool_t AliXRDPROOFtoolkit::FilterList(const char*inputList, const char*fileList, Int_t checkLevel){ | |
314 | // | |
315 | // Filter the list | |
316 | // inputList - list of original file names | |
317 | // fileList - list of file to be checked | |
318 | // - 0 - fileName | |
319 | // - 1 - treeName (if * not checked) | |
320 | // - 2 - fileName | |
321 | // .... | |
322 | // checkLevel - 0 - check only existance of the files and tree's + | |
323 | // simple file corruption | |
324 | // > 1 - check the content of the tree - | |
325 | // (can crash as there do not exest exception handling in ROOT) | |
326 | // Output - two streams are created - file with good entries | |
327 | // "%s.Good a,d file with bad entries %s.Bad | |
328 | //EXAMPLE: | |
329 | // AliXRDPROOFtoolkit::FilterList("ppgrid2.txt","AliESDs.root esdTree AliESDfriends.root * Kinematics.root *",1) | |
330 | gEnv->SetValue("TFile.Recover", 0); | |
331 | // | |
332 | fstream finput; | |
333 | finput.open(inputList, ios_base::in); | |
334 | fstream focGood; | |
335 | fstream focBad; | |
336 | focGood.open(Form("%s.Good",inputList), ios_base::out|ios_base::trunc); | |
337 | focBad.open(Form("%s.Bad",inputList), ios_base::out|ios_base::trunc); | |
338 | // | |
339 | if(!finput.is_open()) { | |
340 | cout<<"Can't open file "<<inputList<<endl; | |
341 | return kFALSE; | |
342 | } | |
343 | // | |
344 | // Read the input list of files and add them to the chain | |
345 | // | |
346 | TObjArray *array = (TString(fileList)).Tokenize(" "); | |
347 | TString currentFile; | |
348 | Int_t counter=0; | |
349 | while(finput.good()) { | |
350 | finput >> currentFile; | |
351 | if (!currentFile.Contains("root")) continue; // protection | |
352 | if (currentFile.Contains("alien://")){ | |
353 | focGood<<currentFile<<endl; | |
354 | continue; | |
355 | } | |
356 | Bool_t isZip = currentFile.Contains("#"); | |
357 | const char * dirname = gSystem->DirName(currentFile.Data()); | |
358 | Int_t status = 0; | |
359 | // | |
360 | for (Int_t i=0; i<array->GetEntries(); i+=2){ | |
361 | char fname[1000]; | |
362 | if (!isZip){ | |
472f0066 | 363 | snprintf(fname,1000, "%s/%s",dirname,array->At(i)->GetName()); |
ffab0c37 | 364 | if (((TObjString*)array->At(i))->String().Contains("*")){ |
472f0066 | 365 | snprintf(fname,1000, "%s", currentFile.Data()); |
ffab0c37 | 366 | } |
367 | } | |
368 | if (isZip) { | |
369 | const char * fileName = gSystem->BaseName(currentFile.Data()); | |
370 | TString fstring=fileName; | |
371 | fstring[fstring.First("#")]=0; | |
472f0066 | 372 | snprintf(fname,1000, "%s/%s#%s",dirname,fstring.Data(),array->At(i)->GetName()); |
ffab0c37 | 373 | printf(fname, "To check %s%s#%s\n",dirname,fstring.Data(),array->At(i)->GetName()); |
374 | } | |
375 | ||
376 | printf("\nFile to be checked %s\n",fname); | |
377 | //cout <<"\n arguments: "<< array->At(i+1)->GetName()<<" "<<checkLevel<<endl; | |
378 | Int_t cstatus = CheckTreeInFile(fname, array->At(i+1)->GetName(), checkLevel,0); | |
379 | //printf(" CheckTreeInFile returns %d",cstatus); | |
380 | if (cstatus!=0) { | |
381 | status = cstatus; | |
382 | break; | |
383 | } | |
384 | } | |
385 | if (status==0){ | |
386 | focGood<<currentFile<<endl; | |
387 | }else{ | |
388 | focBad<<currentFile<<endl; | |
389 | } | |
390 | counter++; | |
391 | } | |
392 | finput.close(); | |
09d5920f | 393 | delete array; |
ffab0c37 | 394 | return kTRUE; |
395 | } | |
396 | ||
397 | ||
398 | Bool_t AliXRDPROOFtoolkit::FilterListZip(const char*inputList, const char*fileList, Int_t checkLevel){ | |
399 | // | |
400 | // Filter the list | |
401 | // inputList - list of original file names | |
402 | // fileList - list of file to be checked | |
403 | // - 0 - fileName | |
404 | // - 1 - treeName (if * not checked) | |
405 | // - 2 - fileName | |
406 | // .... | |
407 | // checkLevel - 0 - check only existance of the files and tree's + | |
408 | // simple file corruption | |
409 | // > 1 - check the content of the tree - | |
410 | // (can crash as there do not exest exception handling in ROOT) | |
411 | // Output - two streams are created - file with good entries | |
412 | // "%s.Good a,d file with bad entries %s.Bad | |
413 | //EXAMPLE: | |
414 | // AliXRDPROOFtoolkit::FilterList("ppgrid2.txt","AliESDs.root esdTree AliESDfriends.root * Kinematics.root *",1) | |
415 | ||
416 | fstream finput; | |
417 | finput.open(inputList, ios_base::in); | |
418 | fstream focGood; | |
419 | fstream focBad; | |
420 | focGood.open(Form("%s.Good",inputList), ios_base::out|ios_base::trunc); | |
421 | focBad.open(Form("%s.Bad",inputList), ios_base::out|ios_base::trunc); | |
422 | // | |
423 | if(!finput.is_open()) { | |
424 | cout<<"Can't open file "<<inputList<<endl; | |
425 | return kFALSE; | |
426 | } | |
427 | // | |
428 | // Read the input list of files and add them to the chain | |
429 | // | |
430 | TObjArray *array = (TString(fileList)).Tokenize(" "); | |
431 | TString currentFile; | |
432 | Int_t counter=0; | |
433 | while(finput.good()) { | |
434 | finput >> currentFile; | |
435 | if (!currentFile.Contains("root")) continue; // protection | |
436 | if (currentFile.Contains("alien://")){ | |
437 | focGood<<currentFile<<endl; | |
438 | continue; | |
439 | } | |
440 | //Bool_t isZip = currentFile.Contains("#"); | |
441 | const char * dirname = gSystem->DirName(currentFile.Data()); | |
442 | const char * fileName = gSystem->BaseName(currentFile.Data()); | |
443 | TString fstring=fileName; | |
444 | fstring[fstring.First("#")]=0; | |
445 | Int_t status = 0; | |
446 | for (Int_t i=0; i<array->GetEntries(); i+=2){ | |
447 | char fname[1000]; | |
448 | //if (isZip) sprintf(fname, | |
472f0066 | 449 | snprintf(fname,1000, "%s/%s#%s",dirname,fstring.Data(),array->At(i)->GetName()); |
ffab0c37 | 450 | printf(fname, "To check %s%s#%s\n",dirname,fstring.Data(),array->At(i)->GetName()); |
451 | //cout <<"\n arguments: "<< array->At(i+1)->GetName()<<" "<<checkLevel<<endl; | |
452 | Int_t cstatus = CheckTreeInFile(fname, array->At(i+1)->GetName(), checkLevel,0); | |
453 | //printf(" CheckTreeInFile returns %d",cstatus); | |
454 | if (cstatus!=0) { | |
455 | status = cstatus; | |
456 | break; | |
457 | } | |
458 | } | |
459 | if (status==0){ | |
460 | focGood<<currentFile<<endl; | |
461 | }else{ | |
462 | focBad<<currentFile<<endl; | |
463 | } | |
464 | counter++; | |
465 | } | |
466 | finput.close(); | |
467 | return kTRUE; | |
468 | } | |
469 | ||
470 | ||
471 | ||
472 | ||
473 | ||
474 | Bool_t AliXRDPROOFtoolkit::XRDCopyDir(const char * idir, const char * files, const char *odir, Bool_t /*zip*/){ | |
475 | // | |
476 | // idir - input directory | |
477 | // odir - output directory | |
478 | // files - the list of files to be coppied | |
479 | // zip - not supported yet | |
480 | // | |
481 | // Example : | |
482 | // | |
483 | // idir ="root://gsiaf.gsi.de:1094//sma/sim/v4-05-Rev-03/pp/0000"; | |
484 | // odir ="root://lxgrid2.gsi.de:1094//miranov/test/pp/0000"; | |
485 | // char *files="AliESDs.root AliESDfriend.root Kinematics.root"; | |
486 | TString str(files); | |
487 | TObjArray * array = str.Tokenize(" "); | |
488 | Int_t nfiles = array->GetEntries(); | |
489 | char infile[1000]; | |
490 | char outfile[1000]; | |
491 | Bool_t succes=kTRUE; | |
492 | for (Int_t ifile =0; ifile<nfiles; ifile++){ | |
472f0066 | 493 | snprintf(infile,1000,"%s/%s", idir, array->At(ifile)->GetName()); |
494 | snprintf(outfile,1000,"%s/%s", odir, array->At(ifile)->GetName()); | |
ffab0c37 | 495 | printf("%s - %s\n",infile, outfile); |
496 | Bool_t result = TFile::Cp(infile,outfile); | |
497 | succes &= result; | |
498 | } | |
09d5920f | 499 | delete array; |
ffab0c37 | 500 | return succes; |
501 | } | |
502 | ||
503 | ||
504 | ||
e87bf665 | 505 | void AliXRDPROOFtoolkit::JoinTreesIndex(const char * outputFile, const char * outputTree, const char *indexName, const char *inputTrees, Int_t debugLevel){ |
506 | // | |
507 | // Join together several tree according to the index | |
508 | // | |
509 | // Parameters: | |
510 | // Output: | |
511 | // outputFile : name of the output file | |
512 | // outputTree : name of the output Tree | |
513 | // indexName : name of the branch to be used as an index | |
514 | // Input: | |
515 | // inputTrees : decription of the input trees setup | |
516 | /* | |
517 | Example usage: | |
518 | ||
519 | 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"); | |
520 | ==> | |
521 | Combine information form the Cpass1,VPass, and Pass1QA, calibration tree, DAQ information, trigger information | |
522 | Make a File "outAll.root", with tree "joinAll", index of tree with name "run" | |
523 | // | |
524 | // Input tree configuration string: | |
525 | // | |
526 | 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" | |
527 | Describe 6 trees to be merged (string separated be +): | |
528 | TObjArray *arrayInput = TString(inputTrees).Tokenize("+"); | |
529 | TObjString = 1#CPass1#run#tpcQA#TPCCPass1.root | |
530 | TObjString = 1#VPass1#run#tpcQA#TPCVPass1.root | |
531 | TObjString = 1#Pass1#run#tpcQA#TPCPass1.root | |
532 | TObjString = 0#DAQ#run#joinTree#/home/miranov/test/dbQueries/fproductionJoin.root | |
533 | TObjString = 0#C#run#dcs#OCDBscan.root | |
534 | TObjString = 0#CE#run#Fits#CEtrend.root | |
535 | // | |
536 | Each tree is characterize by 5 parameters - separate by # | |
537 | description="1#CPass1#run#tpcQA#TPCCPass1.root" | |
538 | TString(description)->Tokenize("#").Print() | |
539 | Collection name='TObjArray', class='TObjArray', size=16 | |
540 | TObjString = 1 ==> (0/1) index is used | |
541 | TObjString = CPass1 ==> name of output branch in output tree | |
542 | TObjString = run ==> name of the index | |
543 | TObjString = tpcQA ==> name of the input tree in the input file | |
544 | TObjString = TPCCPass1.root ==> name of the input file | |
545 | */ | |
546 | // | |
547 | // | |
548 | // | |
549 | ||
550 | TFile * fout = new TFile(outputFile,"recreate"); | |
551 | fout->cd(); | |
552 | TTree *joinTree=new TTree(outputTree,outputTree); | |
553 | // | |
554 | // 1. Define setup. parse definition string | |
555 | // | |
556 | TObjArray *arrayInput = TString(inputTrees).Tokenize("+"); | |
557 | Int_t nTrees = arrayInput->GetEntries(); | |
558 | TObjArray * arrayFile = new TObjArray(nTrees); // array of TFiles with trees | |
559 | TObjArray * arrayTrees = new TObjArray(nTrees); // array of trees | |
560 | TObjArray * arrayNames = new TObjArray(nTrees); // name of tree | |
561 | TObjArray * arrayRunID = new TObjArray(nTrees); // name of tree | |
562 | TArrayI arrayEnableTree(nTrees); | |
563 | for (Int_t i=0; i<2; i++) printf("\n"); | |
564 | printf("Joing query\n"); | |
565 | arrayInput->Print(); | |
566 | for (Int_t i=0; i<2; i++) printf("\n"); | |
567 | {for (Int_t itree=0; itree<nTrees; itree++){ | |
568 | // | |
569 | TObjArray *description = TString(arrayInput->At(itree)->GetName()).Tokenize("#"); | |
570 | if (description->GetEntries()<4) { | |
571 | printf("Fatal: Invalid description: %s\n", arrayInput->At(itree)->GetName()); | |
572 | continue; | |
573 | } | |
574 | TFile * f = TFile::Open(description->At(4)->GetName()); | |
575 | if (!f){ | |
576 | printf("Fatal: Invalid description: fileName %s\n", description->At(4)->GetName()); | |
09d5920f | 577 | delete arrayInput; |
e87bf665 | 578 | return; |
579 | } | |
580 | arrayFile->AddAt(f,itree); | |
581 | TTree * tree = (TTree*)f->Get(description->At(3)->GetName()); | |
582 | if (!tree){ | |
583 | printf("Fatal: Invalid description. Tree name\t%s\n", description->At(3)->GetName()); | |
09d5920f | 584 | delete arrayInput; |
e87bf665 | 585 | return; |
586 | } | |
587 | tree->SetCacheSize(400000000); | |
588 | // | |
589 | arrayTrees->AddAt(tree,itree); | |
590 | // | |
591 | arrayRunID->AddAt(new TObjString(description->At(2)->GetName()),itree); | |
592 | arrayNames->AddAt(new TObjString(description->At(1)->GetName()),itree); | |
593 | arrayEnableTree[itree]=atoi(description->At(0)->GetName()); | |
594 | ||
595 | }} | |
596 | // | |
09d5920f | 597 | delete arrayInput; |
e87bf665 | 598 | // 2. Make the run list |
599 | // | |
600 | // | |
601 | map<int, int> runMap; | |
063feb04 | 602 | map<int, int> *runMapTree = new map<int, int>[nTrees]; |
603 | //map<int, int> runMapTree[nTrees]; | |
e87bf665 | 604 | {for (Int_t itree=0; itree<nTrees; itree++){ |
605 | TTree * tree = (TTree*)arrayTrees->At(itree); | |
606 | Int_t entries=tree->GetEntries(); | |
607 | char query[2000]; | |
608 | snprintf(query,2000,"%s:Entry$", arrayRunID->At(itree)->GetName()); | |
609 | entries = tree->Draw(query,"","goff"); | |
610 | for (Int_t ientry=0;ientry<entries; ientry++){ | |
611 | Int_t irun=Int_t(tree->GetV1()[ientry]); | |
612 | // Int_t entryNr=Int_t(tree->GetV2()[ientry]); | |
613 | if (arrayEnableTree[itree]>0) runMap[irun]+=1; | |
614 | runMapTree[itree][irun]=ientry; | |
615 | if (debugLevel>0) printf("%s\t%d\t%d\n",tree->GetName(), irun, runMapTree[itree][irun]); | |
616 | } | |
617 | } | |
618 | } | |
619 | // | |
620 | // 3. Make join tree | |
621 | // | |
622 | Int_t jrun=0; | |
d4e3890b | 623 | fout->cd(); |
e87bf665 | 624 | joinTree->Branch(indexName, &jrun,Form("%s/I",indexName)); |
625 | Int_t *status=new Int_t[nTrees]; | |
626 | char *brName = new char[10000]; | |
627 | char *brTitle= new char[10000]; | |
628 | // | |
629 | ||
630 | {for (Int_t itree=0; itree<nTrees; itree++){ | |
631 | TTree * tree = (TTree*)arrayTrees->At(itree); | |
632 | tree->GetEntry(1); | |
063feb04 | 633 | TString treeName=arrayNames->At(itree)->GetName(); |
634 | if (treeName.Length()>0){ | |
635 | joinTree->Branch(Form("%s.status",treeName.Data()), &status[itree],Form("%s.status/I",treeName.Data())); | |
636 | }else{ | |
637 | joinTree->Branch("status", &status[itree],"status/I"); | |
638 | } | |
e87bf665 | 639 | // |
640 | Int_t nbranches= tree->GetListOfBranches()->GetEntries(); | |
641 | for (Int_t ibr=0; ibr<nbranches; ibr++){ | |
642 | TBranch * br = (TBranch*)(tree->GetListOfBranches()->At(ibr)); | |
063feb04 | 643 | if (treeName.Length()>0){ |
644 | sprintf(brName,"%s.%s",treeName.Data(), br->GetName()); | |
645 | sprintf(brTitle,"%s.%s",treeName.Data(), br->GetTitle()); | |
646 | }else{ | |
647 | sprintf(brName,"%s",br->GetName()); | |
648 | sprintf(brTitle,"%s",br->GetTitle()); | |
649 | } | |
e87bf665 | 650 | void* addr = 0; |
651 | TString className=br->GetClassName(); | |
652 | if (className.Length()==0){ | |
653 | TString str(br->GetTitle()); | |
654 | if (str[str.Length()-1]=='I') addr=new Int_t; | |
655 | if (str[str.Length()-1]=='F') addr=new Float_t; | |
656 | if (str[str.Length()-1]=='D') addr=new Double_t; | |
657 | if (str[str.Length()-1]=='C') addr=new Char_t[10000]; | |
658 | if (addr) joinTree->Branch(brName, addr, brTitle); | |
659 | br->SetAddress(addr); | |
660 | }else{ | |
661 | TClass cclass(className); | |
662 | TObject **addrClass = new TObject *; | |
663 | (*addrClass)=0; | |
664 | printf("%s\t%s\n",br->GetName(), className.Data()); | |
665 | br->SetAddress(addrClass); | |
666 | br->GetEntry(0); | |
667 | joinTree->Branch(brName,addrClass); | |
668 | } | |
669 | } | |
670 | } | |
671 | } | |
672 | joinTree->Write(); | |
673 | // | |
674 | // 4. Fill the trees | |
675 | // | |
676 | map<int, int>::iterator riter; | |
677 | {for (riter=runMap.begin(); riter != runMap.end(); ++riter){ | |
678 | printf("%d\t%d\t", riter->first, riter->second); | |
679 | jrun=riter->first; | |
680 | for (Int_t itree=0; itree<nTrees; itree++){ | |
681 | TTree * tree = (TTree*)arrayTrees->At(itree); | |
682 | Int_t entry= runMapTree[itree][jrun]; | |
683 | status[itree]=(entry>0)?1:0; | |
684 | if (entry>=0) tree->GetEntry(entry); | |
685 | printf("%d\t",entry); | |
686 | // | |
687 | } | |
688 | joinTree->Fill(); | |
689 | printf("\n"); | |
690 | }} | |
d4e3890b | 691 | fout->cd(); |
692 | joinTree->Write(outputTree); | |
e87bf665 | 693 | fout->Close(); |
694 | ||
695 | } | |
696 | ||
ffab0c37 | 697 | |
d4e3890b | 698 | |
699 | void AliXRDPROOFtoolkit::CacheFileList(const char * fileIn, const char* cachePrefix){ | |
700 | // | |
701 | // cache the list of file locally, cache valeus are stored in the location | |
702 | // specified by optional argumen prefix | |
703 | // 2 new files are created | |
704 | // <fileIn>.cache - file with the location of cahe files | |
705 | // <fileIn>.cacheLog - log file +list of files which can not be cached | |
706 | // | |
707 | /* | |
708 | fileIn = "TPCCPass1.list"; | |
709 | cachePrefix = ""; | |
710 | */ | |
711 | ifstream fin; | |
712 | fin.open(fileIn); | |
713 | ofstream fout; | |
714 | fout.open(Form("%s.cache",fileIn)); | |
715 | ofstream foutLog; | |
716 | foutLog.open(Form("%s.cacheLog",fileIn)); | |
717 | // Read the input list of files and add them to the chain | |
718 | TString currentFile; | |
719 | TString cacheFile; | |
720 | Int_t counter=0; | |
721 | {while(fin.good()) { | |
722 | TTimeStamp s; | |
723 | TString fname; | |
724 | fin >> currentFile; | |
725 | fname=currentFile; | |
726 | fname.ReplaceAll("-","_"); | |
727 | fname.ReplaceAll("/","_"); | |
728 | fname.ReplaceAll(":","_"); | |
844f84d2 | 729 | fname.ReplaceAll("~","_"); |
d4e3890b | 730 | cacheFile=cachePrefix; |
731 | cacheFile+=fname; | |
732 | printf("%s\t%s\n",currentFile.Data(),cacheFile.Data()); | |
733 | if (TFile::Cp(currentFile.Data(),cacheFile.Data())){ | |
734 | fout<<cacheFile.Data()<<"\n"; | |
735 | foutLog<<s.AsString(); | |
736 | foutLog<<cacheFile.Data()<<"n"; | |
737 | }else{ | |
738 | foutLog<<"Copy failed"<<currentFile.Data()<<cacheFile.Data()<<"\n"; | |
739 | } | |
740 | }} | |
741 | fout.close(); | |
742 | foutLog.close(); | |
743 | } | |
744 | ||
745 | ||
746 | ||
747 | void AliXRDPROOFtoolkit::MakeTreeFromList(const char *fout, const char * treeOut, const char * treeIn, const char * flist, Bool_t debug){ | |
748 | // | |
749 | // join trees from the list and make a common tree - stored in the file | |
750 | // | |
751 | /* | |
752 | Example: | |
753 | const char * fout="TPCCpass1.root"; | |
754 | const char *treeOut="tpcQA" | |
755 | const char *treeIn="tpcQA" | |
756 | const char * flist="TPCCPass1.list" | |
757 | */ | |
758 | if (debug>0){ | |
759 | printf("MakeTreeFromList\n"); | |
760 | printf("fout=%s\n",fout); | |
761 | printf("treeOut=%s\n",treeOut); | |
762 | printf("treeIn=%s\n",treeIn); | |
763 | printf("fileList=%s\n",flist); | |
764 | } | |
765 | ifstream fin; | |
766 | fin.open(flist); | |
767 | ofstream foutLog; | |
768 | foutLog.open(Form("%s.chainLog",flist)); | |
769 | // Read the input list of files and add them to the chain | |
770 | TString currentFile; | |
771 | Int_t counter=0; | |
772 | Int_t nbranches=0; | |
773 | {while(fin.good()) { | |
774 | fin >> currentFile; | |
775 | TFile * f = TFile::Open(currentFile.Data()); | |
776 | foutLog<<"Opening file"<<currentFile.Data(); | |
777 | if (!f) { | |
778 | foutLog<<"Error opening file\t"<<currentFile<<"\n"; | |
779 | cout<<"Error opening file\t"<<currentFile<<"\n"; | |
780 | continue; | |
781 | } | |
782 | TTree * tree = (TTree*)f->Get(treeIn); | |
783 | if (!tree) { | |
784 | foutLog<<"Error opening tree\t"<<currentFile<<treeIn<<"\n"; | |
785 | cout<<"Error opening tree\t"<<currentFile<<treeIn<<"\n"; | |
786 | f->ls(); | |
787 | continue; | |
788 | } | |
789 | if (tree->GetListOfBranches()==0){ | |
790 | foutLog<<"Error opening tree\t"<<currentFile<<treeIn<<"\n"; | |
791 | cout<<"Error opening tree\t"<<currentFile<<treeIn<<"\n"; | |
792 | continue; | |
793 | } | |
794 | Int_t nbranchesCurrent = tree->GetListOfBranches()->GetEntries(); | |
795 | if ( nbranches ==0 ) nbranches=nbranchesCurrent; | |
796 | if ( nbranches!=nbranchesCurrent){ | |
844f84d2 | 797 | foutLog<<"Error tree layout\t"<<currentFile<<" \t"<<treeIn<<" \t"<<nbranches<<" \t"<<nbranchesCurrent<<"\n"; |
798 | cout<<"Error tree layout\t" <<currentFile<<" \t"<<treeIn<<" \t"<<nbranches<<" \t"<<nbranchesCurrent<<"\n"; | |
d4e3890b | 799 | } |
800 | counter++; | |
801 | } | |
802 | } | |
803 | foutLog<<"Number of files"<<counter<<"\n"; | |
804 | cout<< "Number of files"<<counter<<"\n"; | |
805 | // | |
806 | ||
807 | TChain * chain = AliXRDPROOFtoolkit::MakeChain(flist,treeIn,0,1000000000,0); | |
808 | Bool_t status=kTRUE; | |
809 | if (!chain) status=kFALSE; | |
810 | if (chain->GetEntries()==0) status=kFALSE; | |
811 | if (!status){ | |
812 | printf("Incorrect list (%s) or trees (%s)", flist,treeIn); | |
813 | return; | |
814 | } | |
815 | TFile *fileOut= TFile::Open(fout, "recreate"); | |
816 | TTree * tree = chain->CopyTree("1"); | |
817 | fileOut->cd(); | |
818 | tree->Write(treeOut); | |
844f84d2 | 819 | delete tree; |
d4e3890b | 820 | fileOut->Close(); |
844f84d2 | 821 | delete fileOut; |
d4e3890b | 822 | } |