1 /**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 /// \class AliTPCQADataMakerRec
17 /// \brief Produces the data needed to calculate the quality assurance.
19 /// Based on AliPHOSQADataMaker
20 /// All data must be mergeable objects.
22 /// Updated July 2011:
23 /// ==================
25 /// Major changes to accomodate updates of general DQM/QA changes to have per
26 /// trigger histograms (for a given event specie).
28 /// 1) One instance of AliTPCdataQA only. (This also solves some old wishes by
29 /// offline team to use less memory because event the 2d arrays for this object
30 /// is not used). This now has a new flag for only keeping DQM info event by
31 /// event! For this reason there is no need for a special DQM reset any more
34 /// 2) Fill the histogram for each event. The histograms are no longer filled
35 /// from the AliTPCdataQA but per event.
37 /// 3) Use profiles for the RAW info. By adding the profiles event by event we
38 /// get the correct event averages WITHOUT having to normalize in the end!
39 /// Results should therefore also be directly mergable when that feature will
40 /// come. (none of the other histograms are merged).
42 /// This means that from the DQM/QA point of view the TPC DQM is now fully
43 /// standard and should ease future developments.
45 /// Updated June 2010:
46 /// ==================
48 /// The "beautification" of the online DQM histograms have been moved to
51 /// The per event RAW histograms have been modified in AliTPCdataQA and
52 /// the copies have therefore also been modified here.
54 /// The AliTPCdataQA can now be configured a bit from here: time bin
55 /// range (extended default range to 1-1000, event range at start:
56 /// 0-100000, 1000 events per bin). (At least the parameters are not
62 /// For the QA of the RAW data we use the class, AliTPCdataQA, from the
63 /// existing TPC Calibration framework (which is more advanced than the
64 /// standard QA framework) and extract the histograms at the end. The
65 /// Analyse method of the AliTPCdataQA class is called in the method,
66 /// EndOfDetectorCycle, and there also: 1d histogram(s) are projected
67 /// and added to the QA list.
69 /// \author P. Christiansen, Lund
70 /// \date January 2008
72 #include "AliTPCQADataMakerRec.h"
74 // --- ROOT system ---
75 #include <TClonesArray.h>
83 #include <TProfile2D.h>
85 // --- Standard library ---
87 // --- AliRoot header files ---
88 #include "AliQAChecker.h"
89 #include "AliESDEvent.h"
90 #include "AliESDtrack.h"
92 #include "AliTPCCalPad.h"
93 #include "AliTPCCalROC.h"
94 #include "AliTPCClustersRow.h"
95 #include "AliTPCclusterMI.h"
96 #include "AliSimDigits.h"
97 #include <AliDetectorRecoParam.h>
101 ClassImp(AliTPCQADataMakerRec)
104 //____________________________________________________________________________
105 AliTPCQADataMakerRec::AliTPCQADataMakerRec() :
106 AliQADataMakerRec(AliQAv1::GetDetName(AliQAv1::kTPC),
107 "TPC Rec Quality Assurance Data Maker"),
110 fRawLastTimeBin(1000)
114 for(Int_t i = 0; i < 6; i++)
118 //____________________________________________________________________________
119 AliTPCQADataMakerRec::AliTPCQADataMakerRec(const AliTPCQADataMakerRec& qadm) :
122 fRawFirstTimeBin(qadm.GetRawFirstTimeBin()),
123 fRawLastTimeBin(qadm.GetRawLastTimeBin())
126 /// Does not copy the calibration object, instead InitRaws have to be
129 SetName((const char*)qadm.GetName()) ;
130 SetTitle((const char*)qadm.GetTitle());
132 for(Int_t i = 0; i < 6; i++)
136 //__________________________________________________________________
137 AliTPCQADataMakerRec& AliTPCQADataMakerRec::operator = (const AliTPCQADataMakerRec& qadm )
141 this->~AliTPCQADataMakerRec();
142 new(this) AliTPCQADataMakerRec(qadm);
146 //__________________________________________________________________
147 AliTPCQADataMakerRec::~AliTPCQADataMakerRec()
153 for(Int_t i = 0; i < 6; i++)
157 //____________________________________________________________________________
158 void AliTPCQADataMakerRec::EndOfDetectorCycle(AliQAv1::TASKINDEX_t task, TObjArray ** list)
160 /// Detector specific actions at end of cycle
162 ResetEventTrigClasses();
164 AliQAChecker::Instance()->Run(AliQAv1::kTPC, task, list) ;
168 //____________________________________________________________________________
169 void AliTPCQADataMakerRec::InitESDs()
171 /// create ESDs histograms in ESDs subdir
173 const Bool_t expert = kTRUE ;
174 const Bool_t image = kTRUE ;
176 TH1F * histESDclusters =
177 new TH1F("hESDclusters", "N TPC clusters per track; N clusters; Counts",
179 histESDclusters->Sumw2();
180 Add2ESDsList(histESDclusters, kClusters, !expert, image);
182 TH1F * histESDratio =
183 new TH1F("hESDratio", "Ratio: TPC clusters / findable; Ratio: cluster/findable; Counts",
185 histESDratio->Sumw2();
186 Add2ESDsList(histESDratio, kRatio, !expert, image);
189 new TH1F("hESDpt", "P_{T} distribution; p_{T} [GeV/c]; Counts",
192 Add2ESDsList(histESDpt, kPt, !expert, image);
194 ClonePerTrigClass(AliQAv1::kESDS); // this should be the last line
197 //____________________________________________________________________________
198 void AliTPCQADataMakerRec::InitRaws()
202 // Modified: 7/7 - 2008
203 // Laurent Aphecetche pointed out that the mapping was read from file
204 // for each event, so now we read in the map here and set if for
206 const Bool_t expert = kTRUE ;
207 const Bool_t saveCorr = kTRUE ;
208 const Bool_t image = kTRUE ;
210 // It might happen that we will be in this method a few times
211 // (we create the dataQA at the first call to this method)
213 fTPCdataQA = new AliTPCdataQA();
214 LoadMaps(); // Load Altro maps
215 fTPCdataQA->SetAltroMapping(fMapping); // set Altro mapping
216 fTPCdataQA->SetRangeTime(fRawFirstTimeBin, fRawLastTimeBin); // set time bin interval
217 fTPCdataQA->SetIsDQM(kTRUE);
220 TProfile * histRawsOccupancyVsSector =
221 new TProfile("hRawsOccupancyVsSector", "Occupancy vs sector; Sector; Occupancy",
223 histRawsOccupancyVsSector->SetMarkerStyle(20);
224 histRawsOccupancyVsSector->SetOption("P");
225 histRawsOccupancyVsSector->SetStats(kFALSE);
226 if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib )
227 Add2RawsList(histRawsOccupancyVsSector, kRawsOccupancyVsSector, expert, image, !saveCorr);
229 Add2RawsList(histRawsOccupancyVsSector, kRawsOccupancyVsSector, !expert, image, !saveCorr);
231 TProfile * histRawsQVsSector =
232 new TProfile("hRawsQVsSector", "<Q> vs sector; Sector; <Q>",
234 Add2RawsList(histRawsQVsSector, kRawsQVsSector, expert, !image, !saveCorr);
236 TProfile * histRawsQmaxVsSector =
237 new TProfile("hRawsQmaxVsSector", "<Qmax> vs sector; Sector; <Qmax>",
239 histRawsQmaxVsSector->SetMarkerStyle(20);
240 histRawsQmaxVsSector->SetOption("P");
241 histRawsQmaxVsSector->SetStats(kFALSE);
242 if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib )
243 Add2RawsList(histRawsQmaxVsSector, kRawsQmaxVsSector, expert, image, !saveCorr);
245 Add2RawsList(histRawsQmaxVsSector, kRawsQmaxVsSector, !expert, image, !saveCorr);
247 TProfile2D * histRawsOccupancy2dVsSector =
248 new TProfile2D("hRawsOccupancy2dVsSector", "Occupancy vs sector; Sector; Patch",
250 histRawsOccupancy2dVsSector->SetOption("COLZ");
251 histRawsOccupancy2dVsSector->SetStats(kFALSE);
252 if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib )
253 Add2RawsList(histRawsOccupancy2dVsSector, kRawsOccupancy2dVsSector, expert, image, !saveCorr);
255 Add2RawsList(histRawsOccupancy2dVsSector, kRawsOccupancy2dVsSector, !expert, image, !saveCorr);
258 ClonePerTrigClass(AliQAv1::kRAWS); // this should be the last line
261 //____________________________________________________________________________
262 void AliTPCQADataMakerRec::InitDigits()
264 const Bool_t expert = kTRUE ;
265 const Bool_t image = kTRUE ;
266 TH1F * histDigitsADC =
267 new TH1F("hDigitsADC", "Digit ADC distribution; ADC; Counts",
269 histDigitsADC->Sumw2();
270 Add2DigitsList(histDigitsADC, kDigitsADC, !expert, image);
272 ClonePerTrigClass(AliQAv1::kDIGITS); // this should be the last line
275 //____________________________________________________________________________
276 void AliTPCQADataMakerRec::InitRecPoints()
278 const Bool_t expert = kTRUE ;
279 const Bool_t image = kTRUE ;
281 TH1F * histRecPointsQmaxShort =
282 new TH1F("hRecPointsQmaxShort", "Qmax distrbution (short pads); Qmax; Counts",
284 histRecPointsQmaxShort->Sumw2();
285 Add2RecPointsList(histRecPointsQmaxShort, kQmaxShort, !expert, image);
287 TH1F * histRecPointsQmaxMedium =
288 new TH1F("hRecPointsQmaxMedium", "Qmax distrbution (medium pads); Qmax; Counts",
290 histRecPointsQmaxMedium->Sumw2();
291 Add2RecPointsList(histRecPointsQmaxMedium, kQmaxMedium, !expert, image);
293 TH1F * histRecPointsQmaxLong =
294 new TH1F("hRecPointsQmaxLong", "Qmax distrbution (long pads); Qmax; Counts",
296 histRecPointsQmaxLong->Sumw2();
297 Add2RecPointsList(histRecPointsQmaxLong, kQmaxLong, !expert, image);
299 TH1F * histRecPointsQShort =
300 new TH1F("hRecPointsQShort", "Q distrbution (short pads); Q; Counts",
302 histRecPointsQShort->Sumw2();
303 Add2RecPointsList(histRecPointsQShort, kQShort, !expert, image);
305 TH1F * histRecPointsQMedium =
306 new TH1F("hRecPointsQMedium", "Q distrbution (medium pads); Q; Counts",
308 histRecPointsQMedium->Sumw2();
309 Add2RecPointsList(histRecPointsQMedium, kQMedium, !expert, image);
311 TH1F * histRecPointsQLong =
312 new TH1F("hRecPointsQLong", "Q distrbution (long pads); Q; Counts",
314 histRecPointsQLong->Sumw2();
315 Add2RecPointsList(histRecPointsQLong, kQLong, !expert, image);
317 TH1F * histRecPointsRow =
318 new TH1F("hRecPointsRow", "Clusters per row; Row; Counts",
320 histRecPointsRow->Sumw2();
321 Add2RecPointsList(histRecPointsRow, kRow, !expert, image);
323 ClonePerTrigClass(AliQAv1::kRECPOINTS); // this should be the last line
326 //____________________________________________________________________________
327 void AliTPCQADataMakerRec::MakeESDs(AliESDEvent * esd)
329 /// make QA data from ESDs
331 const Int_t nESDTracks = esd->GetNumberOfTracks();
332 Int_t nTPCtracks = 0;
333 for(Int_t i = 0; i < nESDTracks; i++) {
335 AliESDtrack * track = esd->GetTrack(i);
337 if ((track->GetStatus() & AliESDtrack::kTPCrefit)==0)
342 Int_t nTPCclusters = track->GetTPCNcls();
343 Int_t nTPCclustersFindable = track->GetTPCNclsF();
344 if ( nTPCclustersFindable<=0) continue;
345 FillESDsData(kClusters,nTPCclusters);
346 FillESDsData(kRatio,Float_t(nTPCclusters)/Float_t(nTPCclustersFindable));
347 FillESDsData(kPt,track->Pt());
350 IncEvCountCycleESDs();
351 IncEvCountTotalESDs();
355 //____________________________________________________________________________
356 void AliTPCQADataMakerRec::MakeRaws(AliRawReader* rawReader)
358 /// To make QA for the RAW data we use the TPC Calibration framework
359 /// to handle the data and then in the end extract the data
361 GetRawsData(0); // dummy call to init raw data
365 AliError("No TPC data QA (no call to InitRaws?)!!!!") ;
368 if(fTPCdataQA->GetIsDQM() == kFALSE)
369 AliError("Data QA has to be initialized as DQM!!!!") ;
372 fTPCdataQA->ResetProfiles();
374 if(fTPCdataQA->ProcessEvent(rawReader)) { // means that TPC data was processed
376 fTPCdataQA->FillOccupancyProfile();
379 TObjArray *arrRW = GetMatchingRawsData(kRawsOccupancyVsSector); // all kRawsOccupancyVsSector clones matching to triggers
380 for (int ih=arrRW->GetEntriesFast();ih--;) {
381 TProfile* hRawsOccupancyVsSector = dynamic_cast<TProfile*>(arrRW->At(ih));
382 if (hRawsOccupancyVsSector) hRawsOccupancyVsSector->Add(fTPCdataQA->GetHistOccVsSector());
384 arrRW = GetMatchingRawsData(kRawsOccupancy2dVsSector);
385 for (int ih=arrRW->GetEntriesFast();ih--;) {
386 TProfile2D* hRawsOccupancy2dVsSector = dynamic_cast<TProfile2D*>(arrRW->At(ih));
387 if (hRawsOccupancy2dVsSector) hRawsOccupancy2dVsSector->Add(fTPCdataQA->GetHistOcc2dVsSector());
389 arrRW = GetMatchingRawsData(kRawsQVsSector);
390 for (int ih=arrRW->GetEntriesFast();ih--;) {
391 TProfile* hRawsQVsSector = dynamic_cast<TProfile*>(arrRW->At(ih));
392 if (hRawsQVsSector) hRawsQVsSector->Add(fTPCdataQA->GetHistQVsSector());
394 arrRW = GetMatchingRawsData(kRawsQmaxVsSector);
395 for (int ih=arrRW->GetEntriesFast();ih--;) {
396 TProfile* hRawsQmaxVsSector = dynamic_cast<TProfile*>(arrRW->At(ih));
397 if (hRawsQmaxVsSector) hRawsQmaxVsSector->Add(fTPCdataQA->GetHistQmaxVsSector());
400 IncEvCountCycleRaws();
401 IncEvCountTotalRaws();
407 //____________________________________________________________________________
408 void AliTPCQADataMakerRec::MakeDigits(TTree* digitTree)
411 TBranch* branch = digitTree->GetBranch("Segment");
412 AliSimDigits* digArray = 0;
413 branch->SetAddress(&digArray);
415 Int_t nEntries = Int_t(digitTree->GetEntries());
417 for (Int_t n = 0; n < nEntries; n++) {
419 digitTree->GetEvent(n);
421 if (digArray->First())
423 Float_t dig = digArray->CurrentDigit();
425 FillDigitsData(kDigitsADC,dig);
426 } while (digArray->Next());
429 IncEvCountCycleDigits();
430 IncEvCountTotalDigits();
434 //____________________________________________________________________________
435 void AliTPCQADataMakerRec::MakeRecPoints(TTree* recTree)
438 AliTPCClustersRow* clrow = 0x0;
439 TBranch* branch = recTree->GetBranch("Segment");
440 branch->SetAddress(&clrow);
441 TClonesArray * clarray = 0x0;
443 const Int_t nEntries = Int_t(recTree->GetEntries());
444 for (Int_t i = 0; i < nEntries; i++) {
448 clarray = clrow->GetArray();
450 if (!clarray) continue;
452 const Int_t nClusters = clarray->GetEntriesFast();
453 for (Int_t icl=0; icl < nClusters; icl++){
455 AliTPCclusterMI* cluster =
456 (AliTPCclusterMI*)clarray->At(icl);
458 Float_t Qmax = cluster->GetMax();
459 Float_t Q = cluster->GetQ();
460 Int_t row = cluster->GetRow();
462 if(cluster->GetDetector()<36) { // IROC (short pads)
464 FillRecPointsData(kQmaxShort,Qmax);
465 FillRecPointsData(kQShort,Q);
466 } else { // OROC (medium and long pads)
468 if(cluster->GetRow()<64) { // medium pads
470 FillRecPointsData(kQmaxMedium,Qmax);
471 FillRecPointsData(kQMedium,Q);
472 } else { // long pads
474 FillRecPointsData(kQmaxLong,Qmax);
475 FillRecPointsData(kQLong,Q);
479 FillRecPointsData(kRow,row);
480 } // end loop over clusters
481 } // end loop over tree
483 IncEvCountCycleRecPoints();
484 IncEvCountTotalRecPoints();
488 //____________________________________________________________________________
489 void AliTPCQADataMakerRec::LoadMaps()
491 TString path = gSystem->Getenv("ALICE_ROOT");
492 path += "/TPC/mapping/Patch";
494 for(Int_t i = 0; i < 6; i++) {
496 if(fMapping[i]!=0) // mapping already loaded
498 TString path2 = path;
501 fMapping[i] = new AliTPCAltroMapping(path2.Data());