TPC DQM update (Ruben, Peter C.)
[u/mrichter/AliRoot.git] / TPC / AliTPCQADataMakerRec.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, 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 /* $Id: $ */
18
19 /*
20   Based on AliPHOSQADataMaker
21   Produces the data needed to calculate the quality assurance. 
22   All data must be mergeable objects.
23   P. Christiansen, Lund, January 2008
24
25   Updated July 2011:
26   ==================
27
28   Major changes to accomodate updates of general DQM/QA changes to have per
29   trigger histograms (for a given event specie).
30
31   1) One instance of AliTPCdataQA only. (This also solves some old wishes by
32   offline team to use less memory because event the 2d arrays for this object
33   is not used). This now has a new flag for only keeping DQM info event by
34   event! For this reason there is no need for a special DQM reset any more
35   between runs!
36
37   2) Fill the histogram for each event. The histograms are no longer filled
38   from the AliTPCdataQA but per event.
39
40   3) Use profiles for the RAW info. By adding the profiles event by event we
41   get the correct event averages WITHOUT having to normalize in the end!
42   Results should therefore also be directly mergable when that feature will
43   come. (none of the other histograms are merged).
44
45   This means that from the DQM/QA point of view the TPC DQM is now fully
46   standard and should ease future developments.
47
48   Updated June 2010:
49   ==================
50
51   The "beautification" of the online DQM histograms have been moved to
52   an amore macro.  
53
54   The per event RAW histograms have been modified in AliTPCdataQA and
55   the copies have therefore also been modified here.
56
57   The AliTPCdataQA can now be configured a bit from here: time bin
58   range (extended default range to 1-1000, event range at start:
59   0-100000, 1000 events per bin). (At least the parameters are not
60   hardcoded:-)
61
62   Implementation:
63   ===============
64
65   For the QA of the RAW data we use the class, AliTPCdataQA, from the
66   existing TPC Calibration framework (which is more advanced than the
67   standard QA framework) and extract the histograms at the end. The
68   Analyse method of the AliTPCdataQA class is called in the method,
69   EndOfDetectorCycle, and there also: 1d histogram(s) are projected
70   and added to the QA list.
71 */
72
73 #include "AliTPCQADataMakerRec.h"
74
75 // --- ROOT system ---
76 #include <TClonesArray.h>
77 #include <TString.h>
78 #include <TSystem.h>
79 #include <TBox.h>
80 #include <TLine.h>
81 #include <TAxis.h>
82
83 // --- Standard library ---
84
85 // --- AliRoot header files ---
86 #include "AliQAChecker.h"
87 #include "AliESDEvent.h"
88 #include "AliESDtrack.h"
89 #include "AliLog.h"
90 #include "AliTPCCalPad.h"
91 #include "AliTPCCalROC.h"
92 #include "AliTPCClustersRow.h"
93 #include "AliTPCclusterMI.h"
94 #include "AliSimDigits.h"
95
96
97 ClassImp(AliTPCQADataMakerRec)
98
99 //____________________________________________________________________________ 
100 AliTPCQADataMakerRec::AliTPCQADataMakerRec() : 
101 AliQADataMakerRec(AliQAv1::GetDetName(AliQAv1::kTPC), 
102                   "TPC Rec Quality Assurance Data Maker"),
103 fTPCdataQA(NULL),
104 fRawFirstTimeBin(1),
105 fRawLastTimeBin(1000)
106 {
107   // ctor
108   
109   for(Int_t i = 0; i < 6; i++)
110     fMapping[i] = 0;
111 }
112
113 //____________________________________________________________________________ 
114 AliTPCQADataMakerRec::AliTPCQADataMakerRec(const AliTPCQADataMakerRec& qadm) :
115   AliQADataMakerRec(),
116   fTPCdataQA(NULL),
117   fRawFirstTimeBin(qadm.GetRawFirstTimeBin()),
118   fRawLastTimeBin(qadm.GetRawLastTimeBin())
119 {
120   //copy ctor 
121   // Does not copy the calibration object, instead InitRaws have to be
122   // called again
123   SetName((const char*)qadm.GetName()) ; 
124   SetTitle((const char*)qadm.GetTitle()); 
125
126   for(Int_t i = 0; i < 6; i++)
127     fMapping[i] = 0;
128 }
129
130 //__________________________________________________________________
131 AliTPCQADataMakerRec& AliTPCQADataMakerRec::operator = (const AliTPCQADataMakerRec& qadm )
132 {
133   // Equal operator.
134   this->~AliTPCQADataMakerRec();
135   new(this) AliTPCQADataMakerRec(qadm);
136   return *this;
137 }
138
139 //__________________________________________________________________
140 AliTPCQADataMakerRec::~AliTPCQADataMakerRec()
141 {
142   // Destructor
143   delete fTPCdataQA; 
144
145   for(Int_t i = 0; i < 6; i++) 
146     delete fMapping[i];
147 }
148  
149 //____________________________________________________________________________ 
150 void AliTPCQADataMakerRec::EndOfDetectorCycle(AliQAv1::TASKINDEX_t task, TObjArray ** list)
151 {
152   //Detector specific actions at end of cycle
153   ResetEventTrigClasses();
154
155   AliQAChecker::Instance()->Run(AliQAv1::kTPC, task, list) ;  
156 }
157
158
159 //____________________________________________________________________________ 
160 void AliTPCQADataMakerRec::InitESDs()
161 {
162   //create ESDs histograms in ESDs subdir  
163   const Bool_t expert   = kTRUE ; 
164   const Bool_t image    = kTRUE ; 
165   
166   TH1F * histESDclusters = 
167     new TH1F("hESDclusters", "N TPC clusters per track; N clusters; Counts",
168              160, 0, 160);
169   histESDclusters->Sumw2();
170   Add2ESDsList(histESDclusters, kClusters, !expert, image);
171
172   TH1F * histESDratio = 
173     new TH1F("hESDratio", "Ratio: TPC clusters / findable; Ratio: cluster/findable; Counts",
174              100, 0, 1);
175   histESDratio->Sumw2();
176   Add2ESDsList(histESDratio, kRatio, !expert, image);
177   
178   TH1F * histESDpt = 
179     new TH1F("hESDpt", "P_{T} distribution; p_{T} [GeV/c]; Counts",
180              50, 0, 5);
181   histESDpt->Sumw2();
182   Add2ESDsList(histESDpt, kPt, !expert, image);
183   //
184   ClonePerTrigClass(AliQAv1::kESDS); // this should be the last line
185 }
186
187 //____________________________________________________________________________ 
188 void AliTPCQADataMakerRec::InitRaws()
189 {
190   //
191   // Adding the raw 
192   //  
193
194   // Modified: 7/7 - 2008
195   // Laurent Aphecetche pointed out that the mapping was read from file
196   // for each event, so now we read in the map here and set if for 
197   // the raw data qa
198   const Bool_t expert   = kTRUE ; 
199   const Bool_t saveCorr = kTRUE ; 
200   const Bool_t image    = kTRUE ; 
201   
202   fTPCdataQA = new AliTPCdataQA();
203   LoadMaps(); // Load Altro maps
204   fTPCdataQA->SetAltroMapping(fMapping); // set Altro mapping
205   fTPCdataQA->SetRangeTime(fRawFirstTimeBin, fRawLastTimeBin); // set time bin interval 
206   fTPCdataQA->SetIsDQM(kTRUE);
207   
208   TProfile * histRawsOccupancyVsSector = 
209     new TProfile("hRawsOccupancyVsSector", "Occupancy vs sector; Sector; Occupancy",
210              72, 0, 72);
211   histRawsOccupancyVsSector->SetMarkerStyle(20);
212   histRawsOccupancyVsSector->SetOption("P");
213   histRawsOccupancyVsSector->SetStats(kFALSE);
214   Add2RawsList(histRawsOccupancyVsSector, kRawsOccupancyVsSector, !expert, image, !saveCorr);
215   
216   TProfile * histRawsQVsSector = 
217     new TProfile("hRawsQVsSector", "<Q> vs sector; Sector; <Q>",
218              72, 0, 72);
219   Add2RawsList(histRawsQVsSector, kRawsQVsSector, expert, !image, !saveCorr);
220
221   TProfile * histRawsQmaxVsSector = 
222     new TProfile("hRawsQmaxVsSector", "<Qmax> vs sector; Sector; <Qmax>",
223              72, 0, 72);
224   histRawsQmaxVsSector->SetMarkerStyle(20);
225   histRawsQmaxVsSector->SetOption("P");
226   histRawsQmaxVsSector->SetStats(kFALSE);
227   Add2RawsList(histRawsQmaxVsSector, kRawsQmaxVsSector, !expert, image, !saveCorr);
228   //
229   ClonePerTrigClass(AliQAv1::kRAWS); // this should be the last line
230 }
231
232 //____________________________________________________________________________ 
233 void AliTPCQADataMakerRec::InitDigits()
234 {
235   const Bool_t expert   = kTRUE ; 
236   const Bool_t image    = kTRUE ; 
237   TH1F * histDigitsADC = 
238     new TH1F("hDigitsADC", "Digit ADC distribution; ADC; Counts",
239              1000, 0, 1000);
240   histDigitsADC->Sumw2();
241   Add2DigitsList(histDigitsADC, kDigitsADC, !expert, image);
242   //
243   ClonePerTrigClass(AliQAv1::kDIGITS); // this should be the last line
244 }
245
246 //____________________________________________________________________________ 
247 void AliTPCQADataMakerRec::InitRecPoints()
248 {
249   const Bool_t expert   = kTRUE ; 
250   const Bool_t image    = kTRUE ; 
251   
252   TH1F * histRecPointsQmaxShort = 
253     new TH1F("hRecPointsQmaxShort", "Qmax distrbution (short pads); Qmax; Counts",
254              100, 0, 300);
255   histRecPointsQmaxShort->Sumw2();
256   Add2RecPointsList(histRecPointsQmaxShort, kQmaxShort, !expert, image);
257
258   TH1F * histRecPointsQmaxMedium = 
259     new TH1F("hRecPointsQmaxMedium", "Qmax distrbution (medium pads); Qmax; Counts",
260              100, 0, 300);
261   histRecPointsQmaxMedium->Sumw2();
262   Add2RecPointsList(histRecPointsQmaxMedium, kQmaxMedium, !expert, image);
263
264   TH1F * histRecPointsQmaxLong = 
265     new TH1F("hRecPointsQmaxLong", "Qmax distrbution (long pads); Qmax; Counts",
266              100, 0, 300);
267   histRecPointsQmaxLong->Sumw2();
268   Add2RecPointsList(histRecPointsQmaxLong, kQmaxLong, !expert, image);
269
270   TH1F * histRecPointsQShort = 
271     new TH1F("hRecPointsQShort", "Q distrbution (short pads); Q; Counts",
272              100, 0, 2000);
273   histRecPointsQShort->Sumw2();
274   Add2RecPointsList(histRecPointsQShort, kQShort, !expert, image);
275
276   TH1F * histRecPointsQMedium = 
277     new TH1F("hRecPointsQMedium", "Q distrbution (medium pads); Q; Counts",
278              100, 0, 2000);
279   histRecPointsQMedium->Sumw2();
280   Add2RecPointsList(histRecPointsQMedium, kQMedium, !expert, image);
281
282   TH1F * histRecPointsQLong = 
283     new TH1F("hRecPointsQLong", "Q distrbution (long pads); Q; Counts",
284              100, 0, 2000);
285   histRecPointsQLong->Sumw2();
286   Add2RecPointsList(histRecPointsQLong, kQLong, !expert, image);
287
288   TH1F * histRecPointsRow = 
289     new TH1F("hRecPointsRow", "Clusters per row; Row; Counts",
290              159, 0, 159);
291   histRecPointsRow->Sumw2();
292   Add2RecPointsList(histRecPointsRow, kRow, !expert, image);
293   //
294   ClonePerTrigClass(AliQAv1::kRECPOINTS); // this should be the last line
295 }
296
297 //____________________________________________________________________________
298 void AliTPCQADataMakerRec::MakeESDs(AliESDEvent * esd)
299 {
300   // make QA data from ESDs
301  
302   const Int_t nESDTracks = esd->GetNumberOfTracks();
303   Int_t nTPCtracks = 0; 
304   for(Int_t i = 0; i < nESDTracks; i++) {
305     
306     AliESDtrack * track = esd->GetTrack(i);
307     
308     if ((track->GetStatus() & AliESDtrack::kTPCrefit)==0)
309       continue;
310     
311     nTPCtracks++;
312     
313     Int_t nTPCclusters         = track->GetTPCNcls();
314     Int_t nTPCclustersFindable = track->GetTPCNclsF();
315     if ( nTPCclustersFindable<=0) continue;
316     FillESDsData(kClusters,nTPCclusters);
317     FillESDsData(kRatio,Float_t(nTPCclusters)/Float_t(nTPCclustersFindable));
318     FillESDsData(kPt,track->Pt()); 
319   }
320   //
321   IncEvCountCycleESDs();
322   IncEvCountTotalESDs();
323   //
324 }
325
326 //____________________________________________________________________________
327 void AliTPCQADataMakerRec::MakeRaws(AliRawReader* rawReader)
328 {
329   //
330   // To make QA for the RAW data we use the TPC Calibration framework 
331   // to handle the data and then in the end extract the data
332   //
333   
334   GetRawsData(0); // dummy call to init raw data
335   rawReader->Reset() ; 
336   if (! fTPCdataQA ) {
337
338     AliError("No TPC data QA (no call to InitRaws?)!!!!") ; 
339   } else {  
340
341     if(fTPCdataQA->GetIsDQM() == kFALSE)
342       AliError("Data QA has to be initialized as DQM!!!!") ; 
343
344     // Fill profile data
345     fTPCdataQA->ResetProfiles();
346     
347     if(fTPCdataQA->ProcessEvent(rawReader)) { // means that TPC data was processed  
348
349       fTPCdataQA->FillOccupancyProfile();
350       
351       // Fill histograms    
352       TObjArray *arrRW = GetMatchingRawsData(kRawsOccupancyVsSector); // all kRawsOccupancyVsSector clones matching to triggers
353       for (int ih=arrRW->GetEntriesFast();ih--;) {
354         TProfile* hRawsOccupancyVsSector = dynamic_cast<TProfile*>(arrRW->At(ih));
355         if (hRawsOccupancyVsSector) hRawsOccupancyVsSector->Add(fTPCdataQA->GetHistOccVsSector());
356       }
357       arrRW = GetMatchingRawsData(kRawsQVsSector);
358       for (int ih=arrRW->GetEntriesFast();ih--;) {
359         TProfile* hRawsQVsSector = dynamic_cast<TProfile*>(arrRW->At(ih));
360         if (hRawsQVsSector) hRawsQVsSector->Add(fTPCdataQA->GetHistQVsSector());
361       }
362       arrRW = GetMatchingRawsData(kRawsQmaxVsSector);
363       for (int ih=arrRW->GetEntriesFast();ih--;) {
364         TProfile* hRawsQmaxVsSector = dynamic_cast<TProfile*>(arrRW->At(ih));
365         if (hRawsQmaxVsSector) hRawsQmaxVsSector->Add(fTPCdataQA->GetHistQmaxVsSector());
366       }
367       //
368       IncEvCountCycleRaws();
369       IncEvCountTotalRaws();
370       //
371     }
372   }
373 }
374
375 //____________________________________________________________________________
376 void AliTPCQADataMakerRec::MakeDigits(TTree* digitTree)
377 {
378  
379   TBranch* branch = digitTree->GetBranch("Segment");
380   AliSimDigits* digArray = 0;
381   branch->SetAddress(&digArray);
382   
383   Int_t nEntries = Int_t(digitTree->GetEntries());
384   
385   for (Int_t n = 0; n < nEntries; n++) {
386     
387     digitTree->GetEvent(n);
388     
389     if (digArray->First())
390       do {
391         Float_t dig = digArray->CurrentDigit();
392         
393         FillDigitsData(kDigitsADC,dig);
394       } while (digArray->Next());    
395   }
396   //
397   IncEvCountCycleDigits();
398   IncEvCountTotalDigits();
399   //
400 }
401
402 //____________________________________________________________________________
403 void AliTPCQADataMakerRec::MakeRecPoints(TTree* recTree)
404 {
405   
406   AliTPCClustersRow* clrow = 0x0;
407   TBranch* branch = recTree->GetBranch("Segment");  
408   branch->SetAddress(&clrow);
409   TClonesArray * clarray = 0x0;
410
411   const Int_t nEntries = Int_t(recTree->GetEntries());
412   for (Int_t i = 0; i < nEntries; i++) {
413     
414     branch->GetEntry(i);
415
416     clarray = clrow->GetArray();
417
418     if (!clarray) continue;
419
420     const Int_t nClusters = clarray->GetEntriesFast();
421     for (Int_t icl=0; icl < nClusters; icl++){
422       
423       AliTPCclusterMI* cluster = 
424         (AliTPCclusterMI*)clarray->At(icl);
425       
426       Float_t Qmax = cluster->GetMax();
427       Float_t Q    = cluster->GetQ();
428       Int_t   row  = cluster->GetRow();
429
430       if(cluster->GetDetector()<36) { // IROC (short pads)
431
432         FillRecPointsData(kQmaxShort,Qmax);
433         FillRecPointsData(kQShort,Q);
434       } else { // OROC (medium and long pads)
435         row += 63;
436         if(cluster->GetRow()<64) { // medium pads
437
438           FillRecPointsData(kQmaxMedium,Qmax);
439           FillRecPointsData(kQMedium,Q);
440         } else { // long pads
441
442           FillRecPointsData(kQmaxLong,Qmax);
443           FillRecPointsData(kQLong,Q);
444         }
445       }
446       
447       FillRecPointsData(kRow,row);
448     } // end loop over clusters
449   } // end loop over tree
450   //
451   IncEvCountCycleRecPoints();
452   IncEvCountTotalRecPoints();
453   //
454 }
455
456 //____________________________________________________________________________
457 void AliTPCQADataMakerRec::LoadMaps()
458 {
459   TString path = gSystem->Getenv("ALICE_ROOT");
460   path += "/TPC/mapping/Patch";
461
462   for(Int_t i = 0; i < 6; i++) {
463
464     if(fMapping[i]!=0) // mapping already loaded
465       continue;
466     TString path2 = path;
467     path2 += i;
468     path2 += ".data";
469     fMapping[i] = new AliTPCAltroMapping(path2.Data());
470   }
471 }
472