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