add libPWGmuon.so
[u/mrichter/AliRoot.git] / MONITOR / AliQAHistNavigator.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 //  support classes for the QA histogram viewer
18 //  
19 //  origin: Mikolaj Krzewicki, Nikhef, Mikolaj.Krzewicki@cern.ch
20 //
21 ///////////////////////////////////////////////////////////////////////////
22
23 #include <list>
24 #include <string>
25 #include <Riostream.h>
26 #include <TSystem.h>
27 #include <TH1.h>
28 #include <TList.h>
29 #include <TNamed.h>
30 #include <TObjString.h>
31 #include <TString.h>
32 #include <TFile.h>
33 #include <TPRegexp.h>
34 #include <TKey.h>
35 #include "AliQAHistNavigator.h"
36
37 ClassImp(AliQAHistNavigator)
38
39 //_________________________________________________________________________
40 AliQAHistNavigator::AliQAHistNavigator(Int_t run):
41     fPFile( NULL ),
42     fPCORRFile( NULL ),
43     fPQAResultFile( NULL ),
44     fRun( run ),
45     fPCurrFile( NULL ),
46     fPCurrDetector( NULL ),
47     fPCurrLevel( NULL ),
48     fPCurrItem( NULL ),
49     fPListOfFiles( new AliQADirList() ),
50     fLoopAllFiles(kTRUE),
51     fLoopAllDetectors(kTRUE),
52     fLoopAllLevels(kTRUE),
53     fInitOK(kFALSE),
54     fExpertMode(kFALSE),
55     fExpertDirName("Expert"),
56     fPEmptyList(new TList())
57 {
58     //ctor
59     fPEmptyList->AddLast(new AliQADirListItem(""));
60     ReReadFiles();
61 }
62
63 //_________________________________________________________________________
64 AliQAHistNavigator::~AliQAHistNavigator()
65 {
66     //dtor
67 }
68
69 //_________________________________________________________________________
70 Bool_t AliQAHistNavigator::GetHistogram(TH1*& hist)
71 {
72     //get histogram from file
73     TString file = GetFileName();
74     TString dir = GetDirName();
75     TString histname = GetItemName();
76     cout<<"GetHistogram: "<<file<<":"<<dir<<"/"<<histname<<endl;
77     if (file==""||dir==""||histname=="") 
78     {
79         printf("GetItem: nothing to fetch...\n");
80         return kFALSE;
81     }
82     if (!OpenCurrentDirectory()) return kFALSE;
83     hist = dynamic_cast<TH1*>( gDirectory->FindKey(histname)->ReadObj() );
84     if (!hist)
85     {
86         printf("GetItem: null pointer returned by gDirectory\n");
87         return kFALSE;
88     }
89     return kTRUE;
90 }
91
92 //_________________________________________________________________________
93 Bool_t AliQAHistNavigator::Next()
94 {
95     //move to the next histogram
96     if (!fPCurrFile||!fPCurrDetector||!fPCurrLevel) return kFALSE;
97     if (!(fPCurrItem=(AliQADirListItem*)GetItemList()->After(fPCurrItem)))
98     {
99         if (!(fPCurrLevel=(AliQADirList*)fPCurrDetector->GetDirs()->After(fPCurrLevel)))
100         {
101             if (!(fPCurrDetector=(AliQADirList*)fPCurrFile->GetDirs()->After(fPCurrDetector)))
102             {
103                 if (!(fPCurrFile=(AliQADirList*)fPListOfFiles->GetDirs()->After(fPCurrFile)))
104                 {
105                     //we're at the end of everything
106                     if (fLoopAllFiles)
107                     {
108                         //rewind to the beginning
109                         fPCurrFile = (AliQADirList*)fPListOfFiles->GetDirs()->First();
110                         fPCurrDetector = (AliQADirList*)fPCurrFile->GetDirs()->First();
111                         fPCurrLevel = (AliQADirList*) fPCurrDetector->GetDirs()->First();
112                         fPCurrItem = (AliQADirListItem*)GetItemList()->First();
113                         OpenCurrentFile();
114                         OpenCurrentDirectory();
115                         printf("----------------back at the beginning!\n");
116                     } else return kFALSE; //no rewind, we finish
117                 } else //if there is a next file
118                 {
119                     fPCurrDetector = (AliQADirList*)fPCurrFile->GetDirs()->First();
120                     fPCurrLevel=(AliQADirList*)fPCurrDetector->GetDirs()->First();
121                     fPCurrItem=(AliQADirListItem*)GetItemList()->First();
122                     OpenCurrentFile();
123                     OpenCurrentDirectory();
124                 }
125             } else //if there is a next detector
126             {
127                 fPCurrLevel=(AliQADirList*)fPCurrDetector->GetDirs()->First();
128                 fPCurrItem=(AliQADirListItem*)GetItemList()->First();
129                 OpenCurrentDirectory();
130             }
131         } else //if there is a next level
132         {
133             fPCurrItem=(AliQADirListItem*)GetItemList()->First();
134             OpenCurrentDirectory();
135         }
136     } else //if there is a next histgram
137     {
138     }
139     return kTRUE;
140 }
141
142 //_________________________________________________________________________
143 Bool_t AliQAHistNavigator::Prev()
144 {
145     //move to the previous histrogram
146     if (!fPCurrLevel||!fPCurrDetector||!fPCurrFile) return kFALSE;
147     if (!(fPCurrItem=(AliQADirListItem*)GetItemList()->Before(fPCurrItem)))
148     {
149         if (!(fPCurrLevel=(AliQADirList*)fPCurrDetector->GetDirs()->Before(fPCurrLevel)))
150         {
151             if (!(fPCurrDetector=(AliQADirList*)fPCurrFile->GetDirs()->Before(fPCurrDetector)))
152             {
153                 if (!(fPCurrFile=(AliQADirList*)fPListOfFiles->GetDirs()->Before(fPCurrFile)))
154                 {
155                     //we're at the end of everything
156                     if (fLoopAllFiles)
157                     {
158                         //rewind to the beginning
159                         fPCurrFile = (AliQADirList*)fPListOfFiles->GetDirs()->Last();
160                         fPCurrDetector = (AliQADirList*)fPCurrFile->GetDirs()->Last();
161                         fPCurrLevel = (AliQADirList*) fPCurrDetector->GetDirs()->Last();
162                         fPCurrItem = (AliQADirListItem*)GetItemList()->Last();
163                         OpenCurrentFile();
164                         OpenCurrentDirectory();
165                         printf("----------------back at the end!\n");
166                     } else return kFALSE; //no rewind, we finish
167                 } else //if there is a next file
168                 {
169                     fPCurrDetector = (AliQADirList*)fPCurrFile->GetDirs()->Last();
170                     fPCurrLevel=(AliQADirList*)fPCurrDetector->GetDirs()->Last();
171                     fPCurrItem=(AliQADirListItem*)GetItemList()->Last();
172                     OpenCurrentFile();
173                     OpenCurrentDirectory();
174                 }
175             } else //if there is a next detector
176             {
177                 fPCurrLevel=(AliQADirList*)fPCurrDetector->GetDirs()->Last();
178                 fPCurrItem=(AliQADirListItem*)GetItemList()->Last();
179                 OpenCurrentDirectory();
180             }
181         } else //if there is a next level
182         {
183             fPCurrItem=(AliQADirListItem*)GetItemList()->Last();
184             OpenCurrentDirectory();
185         }
186     } else //if there is a next histgram
187     {
188     }
189     return kTRUE;
190 }
191
192 //_________________________________________________________________________
193 void AliQAHistNavigator::SetExpertMode(Bool_t mode)
194 {
195     //sets the expert mode
196     Bool_t oldmode = fExpertMode;
197     fExpertMode = mode;
198     if (fExpertMode!=oldmode) fPCurrItem = (AliQADirListItem*)GetItemList()->First();
199     
200 }
201
202 //_________________________________________________________________________
203 Bool_t AliQAHistNavigator::OpenCurrentFile()
204 {
205     //open current file
206     if (fPFile) fPFile->Close();
207     if (!(fPFile->Open(GetFileName(),"READ")))
208     {
209         cout<<"There is no file: "<<GetFileName()<<endl;
210         return kFALSE;
211     }
212     return kTRUE;
213 }
214
215 //_________________________________________________________________________
216 Bool_t AliQAHistNavigator::OpenCurrentDirectory()
217 {
218     //Open current directory
219     if (!gDirectory->cd(GetDirName())) return kFALSE;
220     return kTRUE;
221 }
222
223 //_________________________________________________________________________
224 Bool_t AliQAHistNavigator::SetFile( TString file )
225 {
226     //Set a new file to read from
227     AliQADirList* tmp = (AliQADirList*)fPListOfFiles->GetDirs()->FindObject ( file.Data() );
228     if (!tmp) return kFALSE;
229     fPCurrFile = tmp;
230     OpenCurrentFile();
231     fPCurrDetector = (AliQADirList*)fPCurrFile->GetDirs()->First();
232     fPCurrLevel = (AliQADirList*)fPCurrDetector->GetDirs()->First();
233     fPCurrItem = (AliQADirListItem*)GetItemList()->First();
234     return kTRUE;
235 }
236
237 //_________________________________________________________________________
238 Bool_t AliQAHistNavigator::SetFile( Int_t file )
239 {
240     //Set a new file to read from
241     printf("AliQAHistNavigator::SetFile(%i)\n",file);
242     AliQADirList* tmp = (AliQADirList*)fPListOfFiles->GetDirs()->At(file);
243     if (!tmp) return kFALSE;
244     fPCurrFile = tmp;
245     OpenCurrentFile();
246     fPCurrDetector = (AliQADirList*)fPCurrFile->GetDirs()->First();
247     fPCurrLevel = (AliQADirList*)fPCurrDetector->GetDirs()->First();
248     fPCurrItem = (AliQADirListItem*)GetItemList()->First();
249     OpenCurrentDirectory();
250     return kTRUE;
251 }
252
253 //_________________________________________________________________________
254 Bool_t AliQAHistNavigator::SetDetector( TString det )
255 {
256     //Set a new detector
257     AliQADirList* tmp = (AliQADirList*)fPCurrFile->GetDirs()->FindObject( det.Data() );
258     if (!tmp) return kFALSE;
259     fPCurrDetector = tmp;
260     fPCurrLevel = (AliQADirList*)fPCurrDetector->GetDirs()->First();
261     fPCurrItem = (AliQADirListItem*)GetItemList()->First();
262     OpenCurrentDirectory();
263     return kTRUE;
264 }
265
266 //_________________________________________________________________________
267 Bool_t AliQAHistNavigator::SetDetector( Int_t det )
268 {
269     //Set a new detector
270     printf("AliQAHistNavigator::SetDetector(%i)\n",det);
271     AliQADirList* tmp = (AliQADirList*)fPCurrFile->GetDirs()->At( det );
272     if (!tmp) return kFALSE;
273     fPCurrDetector = tmp;
274     fPCurrLevel = (AliQADirList*)fPCurrDetector->GetDirs()->First();
275     fPCurrItem = (AliQADirListItem*)GetItemList()->First();
276     OpenCurrentDirectory();
277     return kTRUE;
278 }
279
280 //_________________________________________________________________________
281 Bool_t AliQAHistNavigator::SetLevel( TString level )
282 {
283     //Set a new level
284     AliQADirList* tmp = (AliQADirList*)fPCurrDetector->GetDirs()->FindObject( level.Data() );
285     if (!tmp) return kFALSE;
286     fPCurrLevel = tmp;
287     fPCurrItem = (AliQADirListItem*)GetItemList()->First();
288     OpenCurrentDirectory();
289     return kTRUE;
290 }
291
292 //_________________________________________________________________________
293 Bool_t AliQAHistNavigator::SetLevel( Int_t level )
294 {
295     //Set a new level
296     AliQADirList* tmp = (AliQADirList*)fPCurrDetector->GetDirs()->At( level );
297     if (!tmp) return kFALSE;
298     fPCurrLevel = tmp;
299     fPCurrItem = (AliQADirListItem*)GetItemList()->First();
300     OpenCurrentDirectory();
301     return kTRUE;
302 }
303
304 //_________________________________________________________________________
305 Bool_t AliQAHistNavigator::SetItem( TString hist )
306 {
307     //set the new item
308     AliQADirListItem* tmp = (AliQADirListItem*)GetItemList()->FindObject( hist.Data() );
309     if (!tmp) return kFALSE;
310     fPCurrItem = tmp;
311     return kTRUE;
312 }
313
314 //_________________________________________________________________________
315 Bool_t AliQAHistNavigator::SetItem( Int_t hist )
316 {
317     //set the new item
318     AliQADirListItem* tmp = (AliQADirListItem*)GetItemList()->At( hist );
319     if (!tmp) return kFALSE;
320     fPCurrItem = tmp;
321     return kTRUE;
322 }
323
324 //_________________________________________________________________________
325 TList* AliQAHistNavigator::GetItemList()
326 {
327     //returns the current list of histograms, if none, returns empty list
328     TList* itemlist=NULL;
329     if (fExpertMode)
330     {
331         AliQADirList* expertlist = (AliQADirList*)fPCurrLevel->GetDirs()->FindObject(fExpertDirName);
332         if (expertlist) itemlist = expertlist->GetItems();
333         else
334         {
335             //this is a bit of a hack, but it will always return something sensible
336             AliQADirListItem* it = (AliQADirListItem*)fPEmptyList->First();
337             it->SetParent(fPCurrLevel);
338             itemlist = fPEmptyList;
339         }
340     } else
341     {
342         itemlist = fPCurrLevel->GetItems();
343     }
344     return itemlist;
345 }
346
347 //_________________________________________________________________________
348 TString AliQAHistNavigator::GetDetectorName()
349 {
350     //Get name of current detector
351     if (!fPCurrDetector) return "";
352     TString name = fPCurrDetector->GetName();
353     return name;
354 }
355
356 //_________________________________________________________________________
357 TString AliQAHistNavigator::GetLevelName()
358 {
359     //Get name of current leve
360     if (!fPCurrLevel) return "";
361     TString name = fPCurrLevel->GetName();
362     return name;
363 }
364
365 //_________________________________________________________________________
366 TString AliQAHistNavigator::GetFileName()
367 {
368     //Get name of current file
369     if (!fPCurrFile) return "";
370     TString file = fPCurrFile->GetName();
371     return file;
372 }
373
374 //_________________________________________________________________________
375 TString AliQAHistNavigator::GetDirName()
376 {
377     //get the name of dir containing current item
378     if (!fPCurrItem) return "";
379     AliQADirList* d=(AliQADirList*)fPCurrItem->GetParent();
380     TString path;
381     do
382     {
383         path = d->GetName() + path;
384         path = "/" + path;
385         d=d->GetParent();
386     }
387     while (d->GetParent());
388     return path;
389 }
390
391 //_________________________________________________________________________
392 TString AliQAHistNavigator::GetPath(AliQADirListItem* const item)
393 {
394     //Get the full path to teh directory containing item
395     AliQADirList* d=item->GetParent();
396     TString path = "";//item->GetString();
397     do
398     {
399         TString sep = (d->GetParent()) ? "/" : ":/" ;
400         path = d->GetName() + sep + path;
401     }
402     while ((d=d->GetParent()));
403     return path;
404 }
405
406 //_________________________________________________________________________
407 TString AliQAHistNavigator::GetItemName()
408 {
409     //Get name of current item
410     if (!fPCurrItem) return "";
411     return fPCurrItem->GetString();
412 }
413
414 //_________________________________________________________________________
415 Bool_t AliQAHistNavigator::GetListOfFiles()
416 {
417     //scan directory for QA files
418     delete fPListOfFiles;
419     fPListOfFiles = new AliQADirList();
420
421     TString fileNameCORR;
422     TString fileNameQAResult;
423
424     TString macdir(".");
425     gSystem->ExpandPathName(macdir);
426
427     void* dirhandle = gSystem->OpenDirectory(macdir.Data());
428     if(dirhandle != 0)
429     {
430         const char* filename;
431         TString runstr = "";
432         TString revstr = "";
433         runstr += fRun;
434         TString reg;
435         reg+= ".*QA\\.";
436         reg+= (fRun==0) ? "[0-9].*" : revstr.Data();
437         reg+= "\\.root$";
438         TPRegexp reHist(reg);
439         TPRegexp reMerged("Merged.QA.Data.[0-9]*.root");
440         TPRegexp reCORR("CORR.QA.[0-9]*.root");
441         TPRegexp reQA("QA.root");
442         std::list<string> names;
443         while((filename = gSystem->GetDirEntry(dirhandle)) != 0)
444         {
445             if (reCORR.Match(filename))
446             {
447                 fileNameCORR = filename;
448                 continue;
449             }
450             if (reQA.Match(filename))
451             {
452                 fileNameQAResult = filename;
453                 continue;
454             }
455             if (reMerged.Match(filename))
456             {
457                 names.clear();
458                 names.push_back(filename);
459                 break;
460             }
461             if (reHist.Match(filename))
462             {
463                 names.push_back(filename);
464             }
465         }
466         if (!fPCORRFile) fPCORRFile = new TFile(fileNameCORR,"READ");
467         if (!fPQAResultFile) fPQAResultFile = new TFile(fileNameQAResult,"READ");
468         if (names.empty())
469         {
470             printf("GetListOfFiles: no files matching...\n");
471             return kFALSE;
472         }
473         names.sort();
474         char fullName[1000];
475         for (std::list<string>::iterator si=names.begin(); si!=names.end(); ++si)
476         {
477           snprintf(fullName,sizeof(fullName),"%s", si->c_str());
478           AliQADirList* f = new AliQADirList();
479           f->SetName(fullName);
480           fPListOfFiles->GetDirs()->AddLast(f);
481         }
482     }
483     else
484     {
485         gSystem->FreeDirectory(dirhandle);
486         return kFALSE;
487     }
488     return kTRUE;
489 }
490
491 //_________________________________________________________________________
492 Bool_t AliQAHistNavigator::CloneDirStructure()
493 {
494     //scan all files
495     if (!GetListOfFiles()) return kFALSE;
496     if (fPListOfFiles->GetDirs()->GetEntries()==0) return kFALSE;
497     TIter fileiter(fPListOfFiles->GetDirs());
498     AliQADirList* f;
499     while ((f = (AliQADirList*)fileiter.Next()))
500     {
501         TString filename = f->GetName();
502         TFile file(filename);
503         if (!Crawl(f)) continue;
504     }
505     return kTRUE;
506 }
507
508 //_________________________________________________________________________
509 Bool_t AliQAHistNavigator::Crawl(AliQADirList* dir)
510 {
511     //scans the current directory and puts result in dir
512     //returns false if dir in file empty
513     TString oldkeyname;
514     TString keyname;
515     TString pwd = gDirectory->GetPath();
516     TList* keys = gDirectory->GetListOfKeys();
517     if (!keys) return kFALSE;
518     if (keys->GetEntries()==0) return kFALSE;
519     TIter keyiter(keys);
520     TKey* key;
521     while ((key = dynamic_cast <TKey* > (keyiter.Next()) ))
522     {
523         keyname = key->GetName();
524         if (keyname==oldkeyname) continue; //do not copy cycles
525         oldkeyname = keyname;
526         TString classname=key->GetClassName();
527         if (!classname) return kFALSE;
528         if (classname=="TDirectoryFile")
529         {
530             gDirectory->cd(key->GetName());
531             AliQADirList* newdir = new AliQADirList();
532             if (!Crawl(newdir))
533             {
534                 gDirectory->cd(pwd);
535                 continue;
536             }
537             gDirectory->cd(pwd);
538
539             newdir->SetName(keyname);
540             newdir->SetParent(dir);
541             dir->GetDirs()->AddLast(newdir);
542         }
543         else
544         {
545             AliQADirListItem* item = new AliQADirListItem(keyname);
546             item->SetParent(dir);
547             dir->GetItems()->AddLast(item);
548         }
549     }
550     return kTRUE;
551 }
552
553 //_________________________________________________________________________
554 Bool_t AliQAHistNavigator::ReReadFiles()
555 {
556     //close, open and rescan the files
557     if (!CloneDirStructure())
558     {
559         printf("AliQAHistNavigator::AliQAHistNavigator(): error reading files\n");
560         return kFALSE;
561     }
562     fPCurrFile = (AliQADirList*)fPListOfFiles->GetDirs()->First();
563     if (fPCurrFile)
564     {
565         fPCurrDetector = (AliQADirList*)fPCurrFile->GetDirs()->First();
566         if (fPCurrDetector)
567         {
568             fPCurrLevel = (AliQADirList*) fPCurrDetector->GetDirs()->First();
569             if (fPCurrLevel)
570             {
571                 fPCurrItem = (AliQADirListItem*) GetItemList()->First();
572                 if (fPCurrItem)
573                 {
574                     fInitOK = kTRUE;
575                     OpenCurrentFile();
576                     OpenCurrentDirectory();
577                 }
578             }
579         }
580     }
581     return kTRUE;
582 }
583
584 //_________________________________________________________________________
585 //_________________________________________________________________________
586 ClassImp(AliQADirList)
587 //_________________________________________________________________________
588 AliQADirList::AliQADirList():
589     TNamed(),
590     fPParent(NULL),
591     fPItems(new TList()),
592     fPDirs(new TList())
593 {
594     //ctor
595 }
596
597 //_________________________________________________________________________
598 AliQADirList::~AliQADirList()
599 {
600     //dtor
601     if (fPParent) delete fPParent;
602     delete fPItems;
603     delete fPDirs;
604 }
605
606 //_________________________________________________________________________
607 ClassImp(AliQADirListItem)
608 //_________________________________________________________________________
609 AliQADirListItem::AliQADirListItem(const char* s):
610     TObjString(s),
611     fPParent(NULL)
612 {
613     //ctor
614 }
615
616 //_________________________________________________________________________
617 AliQADirListItem::~AliQADirListItem()
618 {
619     //dtor
620     if (fPParent) delete fPParent;
621 }
622