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