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