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