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