617fa7867ba4ff77d1d0b45997d323a107a0175c
[u/mrichter/AliRoot.git] / MUON / AliMUONQADataMakerRec.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 // $Id$
17
18 // --- MUON header files ---
19 #include "AliMUONQADataMakerRec.h"
20
21 #include "AliMUON2DMap.h"
22 #include "AliMUONCluster.h"  
23 #include "AliMUONConstants.h"  
24 #include "AliMUONDDLTrigger.h"
25 #include "AliMUONDarcHeader.h"
26 #include "AliMUONDigitMaker.h"
27 #include "AliMUONLocalStruct.h"
28 #include "AliMUONLocalTrigger.h"
29 #include "AliMUONRawStreamTracker.h"
30 #include "AliMUONRawStreamTrigger.h"
31 #include "AliMUONRegHeader.h"
32 #include "AliMUONTrackerCalibratedDataMaker.h"
33 #include "AliMUONTriggerDisplay.h"
34 #include "AliMUONVCluster.h"
35 #include "AliMUONVClusterStore.h"
36 #include "AliMUONVDigit.h"
37 #include "AliMUONVDigitStore.h"
38 #include "AliMUONVTrackerData.h"
39 #include "AliMUONVTriggerStore.h"
40 #include "AliMUONTrack.h"
41 #include "AliMUONTrackParam.h"
42 #include "AliMUONESDInterface.h"
43 #include "AliMpBusPatch.h"
44 #include "AliMpCDB.h"
45 #include "AliMpConstants.h"
46 #include "AliMpDDLStore.h"
47 #include "AliMpDEIterator.h"
48 #include "AliMpDEManager.h"
49 #include "AliMpLocalBoard.h"
50 #include "AliMpStationType.h"
51 #include "AliMpTriggerCrate.h"
52 #include "AliRawEventHeaderBase.h"
53
54 // --- AliRoot header files ---
55 #include "AliCDBManager.h"
56 #include "AliCDBStorage.h"
57 #include "AliESDEvent.h"
58 #include "AliESDMuonTrack.h"
59 #include "AliESDMuonCluster.h"
60 #include "AliLog.h"
61 #include "AliRawReader.h"
62 #include "AliQAChecker.h"
63 #include "AliCodeTimer.h"
64
65 // --- ROOT system ---
66 #include <TClonesArray.h>
67 #include <TFile.h> 
68 #include <TH1F.h> 
69 #include <TH1I.h> 
70 #include <TH2F.h>
71 #include <TH3F.h> 
72 #include <Riostream.h>
73
74 //-----------------------------------------------------------------------------
75 /// \class AliMUONQADataMakerRec
76 ///
77 /// MUON base class for quality assurance data (histo) maker
78 ///
79 /// \author C. Finck, D. Stocco, L. Aphecetche
80
81 /// \cond CLASSIMP
82 ClassImp(AliMUONQADataMakerRec)
83 /// \endcond
84            
85 //____________________________________________________________________________ 
86 AliMUONQADataMakerRec::AliMUONQADataMakerRec() : 
87 AliQADataMakerRec(AliQA::GetDetName(AliQA::kMUON), "MUON Quality Assurance Data Maker"),
88 fIsInitRaws(kFALSE),
89 fIsInitRecPointsTracker(kFALSE),
90 fIsInitRecPointsTrigger(kFALSE),
91 fIsInitESDs(kFALSE),
92 fDigitStore(0x0),
93 fTriggerStore(0x0),
94 fDigitMaker(0x0),
95 fClusterStore(0x0),
96 fTrackerDataMaker(0x0)
97 {
98     /// ctor
99         
100         Ctor();
101 }
102
103 //____________________________________________________________________________ 
104 void
105 AliMUONQADataMakerRec::Ctor()
106 {
107         /// Init some members
108         fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV1");
109         fDigitMaker = new AliMUONDigitMaker(kTRUE);
110 }
111
112 //____________________________________________________________________________ 
113 AliMUONQADataMakerRec::AliMUONQADataMakerRec(const AliMUONQADataMakerRec& qadm) :
114 AliQADataMakerRec(qadm),
115 fIsInitRaws(kFALSE),
116 fIsInitRecPointsTracker(kFALSE),
117 fIsInitRecPointsTrigger(kFALSE),
118 fIsInitESDs(kFALSE),
119 fDigitStore(0x0),
120 fTriggerStore(0x0),
121 fDigitMaker(0x0),
122 fClusterStore(0x0),
123 fTrackerDataMaker(0x0)
124 {
125     ///copy ctor 
126     SetName((const char*)qadm.GetName()) ; 
127     SetTitle((const char*)qadm.GetTitle()); 
128
129         // Do not copy the digit store and digit maker, but create its own ones
130         
131         Ctor();
132         
133 }
134
135 //__________________________________________________________________
136 AliMUONQADataMakerRec& AliMUONQADataMakerRec::operator = (const AliMUONQADataMakerRec& qadm )
137 {
138   /// Assignment operator
139
140   // check assignment to self
141   if (this == &qadm) return *this;
142
143   this->~AliMUONQADataMakerRec();
144   new(this) AliMUONQADataMakerRec(qadm);
145   return *this;
146 }
147
148 //__________________________________________________________________
149 AliMUONQADataMakerRec::~AliMUONQADataMakerRec()
150 {
151     /// dtor
152   
153   AliCodeTimerAuto("");
154   
155   delete fDigitStore;
156   delete fTriggerStore;
157   delete fDigitMaker;
158   delete fClusterStore;
159   delete fTrackerDataMaker;
160 }
161
162 //____________________________________________________________________________ 
163 void AliMUONQADataMakerRec::EndOfDetectorCycle(AliQA::TASKINDEX_t task, TObjArray* list)
164 {
165   ///Detector specific actions at end of cycle
166   
167   AliCodeTimerAuto("");
168   
169   // Display trigger histos in a more user friendly way
170   DisplayTriggerInfo(task);
171   
172   if ( task == AliQA::kRAWS && fTrackerDataMaker ) 
173   {
174     TIter next(list);
175     TObject* o;
176     Bool_t alreadyThere(kFALSE);
177     while ( ( o = next() ) && !alreadyThere )
178     {
179       TString classname(o->ClassName());
180       if ( classname.Contains("TrackerData") ) alreadyThere = kTRUE;
181     }
182     if (!alreadyThere && fTrackerDataMaker) 
183     {
184       AliInfo("Adding fTrackerDataMaker to the list of qa objects");
185       list->AddAt(fTrackerDataMaker->Data(),(Int_t)kTrackerData);
186     }
187     if ( fTrackerDataMaker ) 
188     {
189       TH1* hbp = GetRawsData(kTrackerBusPatchOccupancy);
190       hbp->Reset();
191       TIter nextBP(AliMpDDLStore::Instance()->CreateBusPatchIterator());
192       AliMpBusPatch* bp(0x0);
193       AliMUONVTrackerData* data = fTrackerDataMaker->Data();
194       Int_t occDim = 2;
195       
196       while ( ( bp = static_cast<AliMpBusPatch*>(nextBP())) )
197       {
198         Int_t busPatchId = bp->GetId();
199         Int_t bin = hbp->FindBin(busPatchId);
200         hbp->SetBinContent(bin,data->BusPatch(busPatchId,occDim));
201       }
202     }
203   }
204   
205   if ( task == AliQA::kESDS ) {
206   // Normalize ESD histos
207     TH1* h;
208     Int_t bin;
209     AliMpDEIterator it;
210     it.First();
211     while ( !it.IsDone()) {
212     
213       Int_t detElemId = it.CurrentDEId();
214     
215       if ( AliMpDEManager::GetStationType(detElemId) != AliMp::kStationTrigger ) {
216       
217         h = GetESDsData(kESDnClustersPerDE);
218         Double_t nClusters = h->GetBinContent(h->GetXaxis()->FindFixBin((Double_t)detElemId));
219       
220         if (nClusters > 0) {
221         
222           h = GetESDsData(kESDClusterChargePerDE);
223           bin = h->GetXaxis()->FindFixBin((Double_t)detElemId);
224           h->SetBinContent(bin, h->GetBinContent(bin)/nClusters);
225         
226           h = GetESDsData(kESDClusterMultPerDE);
227           bin = h->GetXaxis()->FindFixBin((Double_t)detElemId);
228           h->SetBinContent(bin, h->GetBinContent(bin)/nClusters);
229         
230           h = GetESDsData(kESDResidualXPerDEMean);
231           bin = h->GetXaxis()->FindFixBin((Double_t)detElemId);
232           Double_t meanResX = h->GetBinContent(bin)/nClusters;
233           h->SetBinContent(bin, meanResX);
234         
235           h = GetESDsData(kESDResidualYPerDEMean);
236           bin = h->GetXaxis()->FindFixBin((Double_t)detElemId);
237           Double_t meanResY = h->GetBinContent(bin)/nClusters;
238           h->SetBinContent(bin, meanResY);
239         
240           h = GetESDsData(kESDResidualXPerDESigma);
241           bin = h->GetXaxis()->FindFixBin((Double_t)detElemId);
242           if (nClusters > 1) h->SetBinContent(bin, TMath::Sqrt(h->GetBinContent(bin)/nClusters - meanResX*meanResX));
243           else h->SetBinContent(bin, 0.);
244         
245           h = GetESDsData(kESDResidualYPerDESigma);
246           bin = h->GetXaxis()->FindFixBin((Double_t)detElemId);
247           if (nClusters > 1) h->SetBinContent(bin, TMath::Sqrt(h->GetBinContent(bin)/nClusters - meanResY*meanResY));
248           else h->SetBinContent(bin, 0.);
249         
250         }
251       
252       }
253     
254       it.Next();
255     }
256   
257     Double_t nTracks = GetESDsData(kESDnClustersPerTrack)->GetEntries();
258     if (nTracks > 0) {
259       GetESDsData(kESDnClustersPerCh)->Scale(1./nTracks);
260       GetESDsData(kESDnClustersPerDE)->Scale(1./nTracks);
261     }
262   }
263   
264   // do the QA checking
265   AliQAChecker::Instance()->Run(AliQA::kMUON, task, list) ;
266 }
267
268 //____________________________________________________________________________ 
269 void AliMUONQADataMakerRec::InitRaws()
270 {
271     /// create Raws histograms in Raws subdir
272         
273   AliCodeTimerAuto("");
274   
275   Bool_t forExpert(kTRUE);
276   
277         if ( ! AliCDBManager::Instance()->GetDefaultStorage() )
278         {
279                 AliError("CDB default storage not set. Cannot work.");
280                 fIsInitRaws=kFALSE;
281         }
282         
283         TH3F* h3 = new TH3F("hTriggerScalersBendPlane", "Trigger scalers in bending plane",
284                                                                                         4, 10.5, 14.5,
285                                                                                         234, 0.5, 234.5,
286                                                                                         16, -0.5, 15.5);
287         h3->GetXaxis()->SetTitle("Chamber");
288         h3->GetYaxis()->SetTitle("Board");
289         h3->GetZaxis()->SetTitle("Strip");
290         Add2RawsList(h3, kTriggerScalersBP,forExpert);
291         
292         TH3F* h4 = new TH3F("hTriggerScalersNonBendPlane", "Trigger scalers in non-bending plane",
293                                                                                         4, 10.5, 14.5,
294                                                                                         234, 0.5, 234.5,
295                                                                                         16, -0.5, 15.5);
296         h4->GetXaxis()->SetTitle("Chamber");
297         h4->GetYaxis()->SetTitle("Board");
298         h4->GetZaxis()->SetTitle("Strip");
299         Add2RawsList(h4, kTriggerScalersNBP,forExpert);
300         
301         AliMUONTriggerDisplay triggerDisplay;
302         TString histoName, histoTitle;
303         for(Int_t iCath=0; iCath<AliMpConstants::NofCathodes(); iCath++){
304                 TString cathName = ( iCath==0 ) ? "BendPlane" : "NonBendPlane";
305                 for(Int_t iChamber=0; iChamber<AliMpConstants::NofTriggerChambers(); iChamber++){
306                         histoName = Form("hScalers%sChamber%i", cathName.Data(), 11+iChamber);
307                         histoTitle = Form("Chamber %i: Scalers %s", 11+iChamber, cathName.Data());
308                         TH2F* h5 = (TH2F*)triggerDisplay.GetEmptyDisplayHisto(histoName, AliMUONTriggerDisplay::kDisplayStrips, 
309                                                                               iCath, iChamber, histoTitle);
310                         Add2RawsList(h5, kTriggerScalersDisplay + AliMpConstants::NofTriggerChambers()*iCath + iChamber,forExpert);
311                 }
312         }
313         
314   Int_t nbp(0);
315   TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
316   while (next())
317   {
318     ++nbp;
319   }
320   
321   TH1* hbp = new TH1F("hTrackerBusPatchOccupancy","Occupancy of bus patches",
322                       nbp,-0.5,nbp-0.5);
323   
324   Add2RawsList(hbp,kTrackerBusPatchOccupancy,!forExpert);
325   
326         fIsInitRaws = kTRUE;
327 }
328
329 //____________________________________________________________________________ 
330 void AliMUONQADataMakerRec::InitRecPoints()
331 {
332         /// create Reconstructed Points histograms in RecPoints subdir
333   
334   AliCodeTimerAuto("");
335   
336         InitRecPointsTrigger();
337         InitRecPointsTracker();
338 }
339
340 //____________________________________________________________________________ 
341 void AliMUONQADataMakerRec::InitRecPointsTracker()
342 {
343         /// create Reconstructed Points histograms in RecPoints subdir for the
344         /// MUON tracker subsystem.
345
346   AliCodeTimerAuto("");
347   
348   Bool_t forExpert(kTRUE);
349   
350         AliMpDEIterator it;
351         
352         it.First();
353         
354         Int_t ndes(0);
355         
356         while ( !it.IsDone())
357         {
358                 Int_t detElemId = it.CurrentDEId();
359                 
360                 it.Next();
361
362                 if ( AliMpDEManager::GetStationType(detElemId) != AliMp::kStationTrigger )
363                 {
364                         ndes = TMath::Max(ndes,detElemId);
365
366                         TH1* h = new TH1I(Form("hTrackerClusterMultiplicityForDE%04d",detElemId),
367                                           Form("Multiplicity of the clusters in detection element %d",detElemId),
368                                           100,0,100);
369                         
370                         h->GetXaxis()->SetTitle("Detection Element Id");
371                         
372                         Add2RecPointsList(h,kTrackerClusterMultiplicityPerDE+detElemId,forExpert);
373                         
374                         h =  new TH1I(Form("hTrackerClusterChargeForDE%04d",detElemId),
375                                       Form("Charge of the clusters in detection element %d",detElemId),
376                                       100,0,1000);
377
378                         h->GetXaxis()->SetTitle("Detection Element Id");
379
380                         Add2RecPointsList(h,kTrackerClusterChargePerDE+detElemId,forExpert);
381
382                 }
383
384         }
385
386         TH1* h = new TH1I("hTrackerNumberOfClustersPerDE","Number of clusters per detection element",
387                                                                                 ndes, 0.5, ndes + 0.5);
388
389         h->GetXaxis()->SetTitle("Detection Element Id");
390
391         Add2RecPointsList(h, kTrackerNumberOfClustersPerDE,!forExpert);
392
393         for ( Int_t i = 0; i < AliMpConstants::NofTrackingChambers(); ++i ) 
394         {
395                 TH1* h1 = new TH1I("hTrackerNumberOfClustersPerChamber","Number of clusters per chamber",
396                                    AliMpConstants::NofTrackingChambers(),-0.5,AliMpConstants::NofTrackingChambers()-0.5);
397                 Add2RecPointsList(h1,kTrackerNumberOfClustersPerChamber,forExpert);
398                 h1 = new TH1I(Form("hTrackerClusterMultiplicityForChamber%d",i),
399                               Form("Cluster multiplicity for chamber %d",i),
400                               100,0,100);
401                 Add2RecPointsList(h1,kTrackerClusterMultiplicityPerChamber+i,forExpert);
402                 h1 = new TH1I(Form("hTrackerClusterChargeForChamber%d",i),
403                               Form("Cluster charge for chamber %d",i),
404                               100,0,1000);
405                 Add2RecPointsList(h1,kTrackerClusterChargePerChamber+i,forExpert);
406         }
407         
408         fIsInitRecPointsTracker=kTRUE;
409 }
410
411 //____________________________________________________________________________ 
412 void AliMUONQADataMakerRec::InitRecPointsTrigger()
413 {
414         /// create Reconstructed Points histograms in RecPoints subdir for the
415         /// MUON Trigger subsystem.
416         
417   Bool_t forExpert(kTRUE);
418   
419     TH3F* h0 = new TH3F("hTriggerDigitsBendPlane", "Trigger digits in bending plane",
420                         4, 10.5, 14.5,
421                         234, 0.5, 234.5,
422                         16, -0.5, 15.5);
423     h0->GetXaxis()->SetTitle("Chamber");
424     h0->GetYaxis()->SetTitle("Board");
425     h0->GetZaxis()->SetTitle("Strip");
426     Add2RecPointsList(h0, kTriggerDigitsBendPlane,forExpert);
427
428     TH3F* h1 = new TH3F("hTriggerDigitsNonBendPlane", "Trigger digits in non-bending plane",
429                         4, 10.5, 14.5,
430                         234, 0.5, 234.5,
431                         16, -0.5, 15.5);
432     h1->GetXaxis()->SetTitle("Chamber");
433     h1->GetYaxis()->SetTitle("Board");
434     h1->GetZaxis()->SetTitle("Strip");
435     Add2RecPointsList(h1, kTriggerDigitsNonBendPlane,forExpert);
436
437     TH1F* h2 = new TH1F("hTriggeredBoards", "Triggered boards", 234, 0.5, 234.5);
438     Add2RecPointsList(h2, kTriggeredBoards,forExpert);
439
440     AliMUONTriggerDisplay triggerDisplay;
441     TString histoName, histoTitle;
442     for(Int_t iCath=0; iCath<AliMpConstants::NofCathodes(); iCath++){
443       TString cathName = ( iCath==0 ) ? "BendPlane" : "NonBendPlane";
444       for(Int_t iChamber=0; iChamber<AliMpConstants::NofTriggerChambers(); iChamber++){
445         histoName = Form("hTriggerDigits%sChamber%i", cathName.Data(), 11+iChamber);
446         histoTitle = Form("Chamber %i: Fired pads %s", 11+iChamber, cathName.Data());
447         TH2F* h3 = (TH2F*)triggerDisplay.GetEmptyDisplayHisto(histoName, AliMUONTriggerDisplay::kDisplayStrips, 
448                                                               iCath, iChamber, histoTitle);
449         Add2RecPointsList(h3, kTriggerDigitsDisplay + AliMpConstants::NofTriggerChambers()*iCath + iChamber,forExpert);
450       }
451     }
452
453     TH2F* h4 = (TH2F*)triggerDisplay.GetEmptyDisplayHisto("hFiredBoardsDisplay", AliMUONTriggerDisplay::kDisplayBoards,
454                                                           0, 0, "Fired boards");
455     Add2RecPointsList(h4, kTriggerBoardsDisplay,forExpert);
456         
457         fIsInitRecPointsTrigger = kTRUE;
458 }
459
460
461 //____________________________________________________________________________ 
462 void AliMUONQADataMakerRec::InitESDs()
463 {
464   ///create ESDs histograms in ESDs subdir
465   
466   Bool_t forExpert(kTRUE);
467   
468   Int_t nCh = AliMUONConstants::NTrackingCh();
469   Int_t nDE = 1100;
470   
471   // track info
472   TH1F* hESDnTracks = new TH1F("hESDnTracks", "number of tracks", 20, 0., 20.);
473   Add2ESDsList(hESDnTracks, kESDnTracks,!forExpert);
474
475   TH1F* hESDMatchTrig = new TH1F("hESDMatchTrig", "number of tracks matched with trigger", 20, 0., 20.);
476   Add2ESDsList(hESDMatchTrig, kESDMatchTrig,!forExpert);
477   
478   TH1F* hESDMomentum = new TH1F("hESDMomentum", "P distribution", 300, 0., 300);
479   Add2ESDsList(hESDMomentum, kESDMomentum,forExpert);
480
481   TH1F* hESDPt = new TH1F("hESDPt", "Pt distribution", 200, 0., 50);
482   Add2ESDsList(hESDPt, kESDPt,forExpert);
483
484   TH1F* hESDRapidity = new TH1F("hESDRapidity", "rapidity distribution", 200, -4.5, -2.);
485   Add2ESDsList(hESDRapidity, kESDRapidity,forExpert);
486
487   TH1F* hESDChi2 = new TH1F("hESDChi2", "normalized chi2 distribution", 500, 0., 50.);
488   Add2ESDsList(hESDChi2, kESDChi2,forExpert);
489   
490   // cluster info
491   for (Int_t i = 0; i < nCh; i++) {
492     Float_t rMax = AliMUONConstants::Rmax(i/2);
493     TH2F* hESDClusterHitMap = new TH2F(Form("hESDClusterHitMap%d",i+1), Form("cluster position distribution in chamber %d",i+1),
494                                        100, -rMax, rMax, 100, -rMax, rMax);
495     Add2ESDsList(hESDClusterHitMap, kESDClusterHitMap+i,forExpert);
496   }
497   
498   TH1F* hESDnClustersPerTrack = new TH1F("hESDnClustersPerTrack", "number of clusters per track", 20, 0., 20.);
499   Add2ESDsList(hESDnClustersPerTrack, kESDnClustersPerTrack,!forExpert);
500   
501   TH1F* hESDnClustersPerCh = new TH1F("hESDnClustersPerCh", "number of clusters per chamber per track;chamber ID", nCh, 0, nCh);
502   hESDnClustersPerCh->SetFillColor(kRed);
503   Add2ESDsList(hESDnClustersPerCh, kESDnClustersPerCh,forExpert);
504   
505   TH1F* hESDnClustersPerDE = new TH1F("hESDnClustersPerDE", "number of clusters per DE per track;DetElem ID", nDE, 0, nDE);
506   hESDnClustersPerDE->SetFillColor(kRed);
507   Add2ESDsList(hESDnClustersPerDE, kESDnClustersPerDE,forExpert);
508   
509   TH1F* hESDClusterCharge = new TH1F("hESDClusterCharge", "cluster charge distribution", 500, 0., 5000.);
510   Add2ESDsList(hESDClusterCharge, kESDClusterCharge,forExpert);
511   
512   for (Int_t i = 0; i < nCh; i++) {
513     TH1F* hESDClusterChargeInCh = new TH1F(Form("hESDClusterChargeInCh%d",i+1), Form("cluster charge distribution in chamber %d",i+1), 500, 0., 5000.);
514     Add2ESDsList(hESDClusterChargeInCh, kESDClusterChargeInCh+i,forExpert);
515   }
516   
517   TH1F* hESDClusterChargePerDE = new TH1F("hESDClusterChargePerDE", "cluster mean charge per DE;DetElem ID", nDE, 0, nDE);
518   hESDClusterChargePerDE->SetOption("P");
519   hESDClusterChargePerDE->SetMarkerStyle(kFullDotMedium);
520   hESDClusterChargePerDE->SetMarkerColor(kRed);
521   Add2ESDsList(hESDClusterChargePerDE, kESDClusterChargePerDE,forExpert);
522   
523   TH1F* hESDClusterMult = new TH1F("hESDClusterMult", "cluster multiplicity distribution", 200, 0., 200.);
524   Add2ESDsList(hESDClusterMult, kESDClusterMult,forExpert);
525   
526   for (Int_t i = 0; i < nCh; i++) {
527     TH1F* hESDClusterMultInCh = new TH1F(Form("hESDClusterMultInCh%d",i+1), Form("cluster multiplicity distribution in chamber %d",i+1), 200, 0., 200.);
528     Add2ESDsList(hESDClusterMultInCh, kESDClusterMultInCh+i,forExpert);
529   }
530   
531   TH1F* hESDClusterMultPerDE = new TH1F("hESDClusterMultPerDE", "cluster mean multiplicity per DE;DetElem ID", nDE, 0, nDE);
532   hESDClusterMultPerDE->SetOption("P");
533   hESDClusterMultPerDE->SetMarkerStyle(kFullDotMedium);
534   hESDClusterMultPerDE->SetMarkerColor(kRed);
535   Add2ESDsList(hESDClusterMultPerDE, kESDClusterMultPerDE,forExpert);
536   
537   // cluster - track info
538   TH1F* hESDResidualX = new TH1F("hESDResidualX", "cluster-track residual-X distribution", 1000, -5., 5.);
539   Add2ESDsList(hESDResidualX, kESDResidualX,forExpert);
540   
541   TH1F* hESDResidualY = new TH1F("hESDResidualY", "cluster-track residual-Y distribution", 1000, -1., 1.);
542   Add2ESDsList(hESDResidualY, kESDResidualY,forExpert);
543   
544   for (Int_t i = 0; i < nCh; i++) {
545     TH1F* hESDResidualXInCh = new TH1F(Form("hESDResidualXInCh%d",i+1), Form("cluster-track residual-X distribution in chamber %d",i+1), 1000, -5., 5.);
546     Add2ESDsList(hESDResidualXInCh, kESDResidualXInCh+i,forExpert);
547     
548     TH1F* hESDResidualYInCh = new TH1F(Form("hESDResidualYInCh%d",i+1), Form("cluster-track residual-Y distribution in chamber %d",i+1), 1000, -1., 1.);
549     Add2ESDsList(hESDResidualYInCh, kESDResidualYInCh+i,forExpert);
550   }
551   
552   TH1F* hESDResidualXPerDEMean = new TH1F("hESDResidualXPerDEMean", "cluster-track residual-X per DE: mean;DetElem ID", nDE, 0, nDE);
553   hESDResidualXPerDEMean->SetOption("P");
554   hESDResidualXPerDEMean->SetMarkerStyle(kFullDotMedium);
555   hESDResidualXPerDEMean->SetMarkerColor(kRed);
556   Add2ESDsList(hESDResidualXPerDEMean, kESDResidualXPerDEMean,forExpert);
557   
558   TH1F* hESDResidualYPerDEMean = new TH1F("hESDResidualYPerDEMean", "cluster-track residual-Y per DE: mean;DetElem ID", nDE, 0, nDE);
559   hESDResidualYPerDEMean->SetOption("P");
560   hESDResidualYPerDEMean->SetMarkerStyle(kFullDotMedium);
561   hESDResidualYPerDEMean->SetMarkerColor(kRed);
562   Add2ESDsList(hESDResidualYPerDEMean, kESDResidualYPerDEMean,forExpert);
563   
564   TH1F* hESDResidualXPerDESigma = new TH1F("hESDResidualXPerDESigma", "cluster-track residual-X per DE: sigma;DetElem ID", nDE, 0, nDE);
565   hESDResidualXPerDESigma->SetOption("P");
566   hESDResidualXPerDESigma->SetMarkerStyle(kFullDotMedium);
567   hESDResidualXPerDESigma->SetMarkerColor(kRed);
568   Add2ESDsList(hESDResidualXPerDESigma, kESDResidualXPerDESigma,forExpert);
569   
570   TH1F* hESDResidualYPerDESigma = new TH1F("hESDResidualYPerDESigma", "cluster-track residual-Y per DE: sigma;DetElem ID", nDE, 0, nDE);
571   hESDResidualYPerDESigma->SetOption("P");
572   hESDResidualYPerDESigma->SetMarkerStyle(kFullDotMedium);
573   hESDResidualYPerDESigma->SetMarkerColor(kRed);
574   Add2ESDsList(hESDResidualYPerDESigma, kESDResidualYPerDESigma,forExpert);
575   
576   fIsInitESDs =  kTRUE;
577 }
578
579 //____________________________________________________________________________
580 void AliMUONQADataMakerRec::MakeRaws(AliRawReader* rawReader)
581 {
582     /// make QA for rawdata
583
584     if ( ! fIsInitRaws ) {
585       AliWarningStream() 
586         << "Skipping function due to a failure in Init" << endl;
587       return;
588     }    
589
590   if ( rawReader->GetType() == AliRawEventHeaderBase::kPhysicsEvent ) 
591   {
592     rawReader->Reset();
593     MakeRawsTracker(rawReader);
594   }
595   
596   rawReader->Reset();    
597   MakeRawsTrigger(rawReader);
598 }
599
600 //____________________________________________________________________________
601 void AliMUONQADataMakerRec::MakeRawsTracker(AliRawReader* rawReader)
602 {
603         /// make QA for rawdata tracker
604   
605         if (!fTrackerDataMaker) 
606         {
607                 const Bool_t histogram(kFALSE);
608                 const Bool_t fastDecoder(kTRUE);
609     
610 //    fTrackerDataMaker = new AliMUONTrackerRawDataMaker(rawReader,histogram,fastDecoder,takeRawReaderOwnership);
611
612                 fTrackerDataMaker = new AliMUONTrackerCalibratedDataMaker(GetRecoParam(),
613                                                                           AliCDBManager::Instance()->GetRun(),
614                                                                           rawReader,
615                                                                           AliCDBManager::Instance()->GetDefaultStorage()->GetURI(),
616                                                                           "NOGAIN",
617                                                                           histogram,
618                                                                           0.0,0.0,
619                                                                           fastDecoder);
620                 
621                 fTrackerDataMaker->Data()->DisableChannelLevel(); // to save up disk space, we only store starting at the manu level
622                 
623                 fTrackerDataMaker->SetRunning(kTRUE);
624         }
625         
626         ((AliMUONTrackerCalibratedDataMaker*)fTrackerDataMaker)->SetRawReader(rawReader);
627         
628         fTrackerDataMaker->ProcessEvent();
629 }
630
631 //____________________________________________________________________________
632 void AliMUONQADataMakerRec::MakeRawsTrigger(AliRawReader* rawReader)
633 {
634         /// make QA for rawdata trigger
635         
636     // Get trigger scalers
637
638     Int_t loCircuit=0;
639     AliMpCDB::LoadDDLStore();
640
641     AliMUONRawStreamTrigger rawStreamTrig(rawReader);
642     while (rawStreamTrig.NextDDL()) 
643     {
644       // If not a scaler event, do nothing
645       Bool_t scalerEvent =  rawReader->GetDataHeader()->GetL1TriggerMessage() & 0x1;
646       if(!scalerEvent) break;
647
648       AliMUONDDLTrigger* ddlTrigger = rawStreamTrig.GetDDLTrigger();
649       AliMUONDarcHeader* darcHeader = ddlTrigger->GetDarcHeader();
650
651       Int_t nReg = darcHeader->GetRegHeaderEntries();
652     
653       for(Int_t iReg = 0; iReg < nReg ;iReg++)
654       {   //reg loop
655
656         // crate info  
657         AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
658           GetTriggerCrate(rawStreamTrig.GetDDL(), iReg);
659
660         AliMUONRegHeader* regHeader =  darcHeader->GetRegHeaderEntry(iReg);
661
662         // loop over local structures
663         Int_t nLocal = regHeader->GetLocalEntries();
664         for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) 
665         {
666           AliMUONLocalStruct* localStruct = regHeader->GetLocalEntry(iLocal);
667         
668           // if card exist
669           if (!localStruct) continue;
670           
671           loCircuit = crate->GetLocalBoardId(localStruct->GetId());
672
673           if ( !loCircuit ) continue; // empty slot
674
675           AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, false);
676
677           // skip copy cards
678           if( !localBoard->IsNotified()) 
679             continue;
680
681           Int_t cathode = localStruct->GetComptXY()%2;
682
683           ERaw hindex = (cathode==0) ? kTriggerScalersBP : kTriggerScalersNBP;
684
685           // loop over strips
686           for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
687             if(localStruct->GetXY1(ibitxy) > 0)
688               ((TH3F*)GetRawsData(hindex))->Fill(11+0, loCircuit, ibitxy, 2*localStruct->GetXY1(ibitxy));
689             if(localStruct->GetXY2(ibitxy) > 0)
690               ((TH3F*)GetRawsData(hindex))->Fill(11+1, loCircuit, ibitxy, 2*localStruct->GetXY2(ibitxy));
691             if(localStruct->GetXY3(ibitxy) > 0)
692               ((TH3F*)GetRawsData(hindex))->Fill(11+2, loCircuit, ibitxy, 2*localStruct->GetXY3(ibitxy));
693             if(localStruct->GetXY4(ibitxy) > 0)
694               ((TH3F*)GetRawsData(hindex))->Fill(11+3, loCircuit, ibitxy, 2*localStruct->GetXY4(ibitxy));
695           } // loop on strips
696         } // iLocal
697       } // iReg
698     } // NextDDL
699 }
700
701 //____________________________________________________________________________
702 void AliMUONQADataMakerRec::MakeRecPoints(TTree* clustersTree)
703 {
704         /// Fill histograms from treeR
705         
706         if (fIsInitRecPointsTracker) MakeRecPointsTracker(clustersTree);
707         if (fIsInitRecPointsTrigger) MakeRecPointsTrigger(clustersTree);
708 }
709
710 //____________________________________________________________________________
711 void AliMUONQADataMakerRec::MakeRecPointsTracker(TTree* clustersTree)
712 {
713         /// Fill histograms related to tracker clusters 
714         
715         // First things first : do we have clusters in the TreeR ?
716         // In "normal" production mode, it should be perfectly normal
717         // *not* to have them.
718         // But if for some reason we de-activated the combined tracking,
719         // then we have clusters in TreeR, so let's take that opportunity
720         // to QA them...
721         
722         if (!fClusterStore)
723         {
724                 AliCodeTimerAuto("ClusterStore creation");
725                 fClusterStore = AliMUONVClusterStore::Create(*clustersTree);
726                 if (!fClusterStore) 
727                 {
728                         fIsInitRecPointsTracker = kFALSE;
729                         return;
730                 }
731         }
732         
733         AliCodeTimerAuto("");
734         
735         fClusterStore->Connect(*clustersTree,kFALSE);
736         clustersTree->GetEvent(0);
737
738         TIter next(fClusterStore->CreateIterator());
739         AliMUONVCluster* cluster;
740         
741         while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) )
742         {
743                 Int_t detElemId = cluster->GetDetElemId();
744                 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
745                 
746                 GetRecPointsData(kTrackerNumberOfClustersPerDE)->Fill(detElemId);
747                 GetRecPointsData(kTrackerClusterChargePerDE+detElemId)->Fill(cluster->GetCharge());
748                 GetRecPointsData(kTrackerClusterMultiplicityPerDE+detElemId)->Fill(cluster->GetNDigits());
749
750                 GetRecPointsData(kTrackerNumberOfClustersPerChamber)->Fill(chamberId);
751                 GetRecPointsData(kTrackerClusterChargePerChamber+chamberId)->Fill(cluster->GetCharge());
752                 GetRecPointsData(kTrackerClusterMultiplicityPerChamber+chamberId)->Fill(cluster->GetNDigits());
753                 
754         }
755         
756         fClusterStore->Clear();
757 }
758
759 //____________________________________________________________________________
760 void AliMUONQADataMakerRec::MakeRecPointsTrigger(TTree* clustersTree)
761 {
762         /// makes data from trigger response
763       
764     // Fired pads info
765     fDigitStore->Clear();
766
767     if (!fTriggerStore) fTriggerStore = AliMUONVTriggerStore::Create(*clustersTree);
768     fTriggerStore->Clear();
769     fTriggerStore->Connect(*clustersTree, false);
770     clustersTree->GetEvent(0);
771
772     AliMUONLocalTrigger* locTrg;
773     TIter nextLoc(fTriggerStore->CreateLocalIterator());
774
775     while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(nextLoc()) ) ) 
776     {
777       if (locTrg->IsNull()) continue;
778    
779       TArrayS xyPattern[2];
780       locTrg->GetXPattern(xyPattern[0]);
781       locTrg->GetYPattern(xyPattern[1]);
782
783       Int_t nBoard = locTrg->LoCircuit();
784
785       Bool_t xTrig=locTrg->IsTrigX();
786       Bool_t yTrig=locTrg->IsTrigY();
787     
788       if (xTrig && yTrig)
789         ((TH1F*)GetRecPointsData(kTriggeredBoards))->Fill(nBoard);
790
791       fDigitMaker->TriggerDigits(nBoard, xyPattern, *fDigitStore);
792     }
793
794     TIter nextDigit(fDigitStore->CreateIterator());
795     AliMUONVDigit* mDigit;
796     while ( ( mDigit = static_cast<AliMUONVDigit*>(nextDigit()) ) )
797     {
798       Int_t detElemId = mDigit->DetElemId();
799       Int_t ch = detElemId/100;
800       Int_t localBoard = mDigit->ManuId();
801       Int_t channel = mDigit->ManuChannel();
802       Int_t cathode = mDigit->Cathode();
803       ERecPoints hindex 
804         = ( cathode == 0 ) ? kTriggerDigitsBendPlane : kTriggerDigitsNonBendPlane;
805       
806       ((TH3F*)GetRecPointsData(hindex))->Fill(ch, localBoard, channel);
807     }
808 }
809
810 //____________________________________________________________________________
811 void AliMUONQADataMakerRec::MakeESDs(AliESDEvent* esd)
812 {
813   /// make QA data from ESDs
814   
815   if ( ! fIsInitESDs ) {
816     AliWarningStream() 
817     << "Skipping function due to a failure in Init" << endl;
818     return;
819   }    
820   
821   // load ESD event in the interface
822   AliMUONESDInterface esdInterface;
823   if (GetRecoParam()) AliMUONESDInterface::ResetTracker(GetRecoParam());
824   else AliError("Unable to get recoParam: use default ones for residual calculation");
825   esdInterface.LoadEvent(*esd);
826   
827   GetESDsData(kESDnTracks)->Fill(esdInterface.GetNTracks());
828   
829   Int_t nTrackMatchTrig = 0;
830   
831   // loop over tracks
832   Int_t nTracks = (Int_t) esd->GetNumberOfMuonTracks(); 
833   for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack) {
834     
835     // get the ESD track and skip "ghosts"
836     AliESDMuonTrack* esdTrack = esd->GetMuonTrack(iTrack);
837     if (!esdTrack->ContainTrackerData()) continue;
838     
839     // get corresponding MUON track
840     AliMUONTrack* track = esdInterface.FindTrack(esdTrack->GetUniqueID());
841     
842     if (esdTrack->ContainTriggerData()) nTrackMatchTrig++;
843     
844     GetESDsData(kESDMomentum)->Fill(esdTrack->P());
845     GetESDsData(kESDPt)->Fill(esdTrack->Pt());
846     GetESDsData(kESDRapidity)->Fill(esdTrack->Y());
847     GetESDsData(kESDChi2)->Fill(track->GetNormalizedChi2());
848     GetESDsData(kESDnClustersPerTrack)->Fill(track->GetNClusters());
849     
850     // loop over clusters
851     AliMUONTrackParam* trackParam = static_cast<AliMUONTrackParam*>(track->GetTrackParamAtCluster()->First());
852     while (trackParam) {
853       
854       AliMUONVCluster* cluster = trackParam->GetClusterPtr();
855       Int_t chId = cluster->GetChamberId();
856       Int_t deID = cluster->GetDetElemId();
857       Double_t residualX = cluster->GetX() - trackParam->GetNonBendingCoor();
858       Double_t residualY = cluster->GetY() - trackParam->GetBendingCoor();
859       
860       GetESDsData(kESDClusterHitMap+chId)->Fill(cluster->GetX(), cluster->GetY());
861       
862       GetESDsData(kESDnClustersPerCh)->Fill(chId);
863       GetESDsData(kESDnClustersPerDE)->Fill(deID);
864       
865       GetESDsData(kESDClusterCharge)->Fill(cluster->GetCharge());
866       GetESDsData(kESDClusterChargeInCh+chId)->Fill(cluster->GetCharge());
867       GetESDsData(kESDClusterChargePerDE)->Fill(deID, cluster->GetCharge());
868       
869       if (cluster->GetNDigits() > 0) { // discard clusters with pad not stored in ESD
870         GetESDsData(kESDClusterMult)->Fill(cluster->GetNDigits());
871         GetESDsData(kESDClusterMultInCh+chId)->Fill(cluster->GetNDigits());
872         GetESDsData(kESDClusterMultPerDE)->Fill(deID, cluster->GetNDigits());
873       }
874       
875       GetESDsData(kESDResidualX)->Fill(residualX);
876       GetESDsData(kESDResidualY)->Fill(residualY);
877       GetESDsData(kESDResidualXInCh+chId)->Fill(residualX);
878       GetESDsData(kESDResidualYInCh+chId)->Fill(residualY);
879       GetESDsData(kESDResidualXPerDEMean)->Fill(deID, residualX);
880       GetESDsData(kESDResidualYPerDEMean)->Fill(deID, residualY);
881       GetESDsData(kESDResidualXPerDESigma)->Fill(deID, residualX*residualX);
882       GetESDsData(kESDResidualYPerDESigma)->Fill(deID, residualY*residualY);
883       
884       trackParam = static_cast<AliMUONTrackParam*>(track->GetTrackParamAtCluster()->After(trackParam));
885     }
886     
887   }
888   
889   GetESDsData(kESDMatchTrig)->Fill(nTrackMatchTrig);
890   
891 }
892
893 //____________________________________________________________________________ 
894 void AliMUONQADataMakerRec::StartOfDetectorCycle()
895 {
896     /// Detector specific actions at start of cycle
897   
898 }
899
900 //____________________________________________________________________________ 
901 void AliMUONQADataMakerRec::DisplayTriggerInfo(AliQA::TASKINDEX_t task)
902 {
903   //
904   /// Display trigger information in a user-friendly way:
905   /// from local board and strip numbers to their position on chambers
906   //
907   if(task!=AliQA::kRECPOINTS && task!=AliQA::kRAWS) return;
908
909   AliMUONTriggerDisplay triggerDisplay;
910   
911   TH3F* histoStrips=0x0;
912   TH2F* histoDisplayStrips=0x0;
913
914   for (Int_t iCath = 0; iCath < AliMpConstants::NofCathodes(); iCath++)
915   {
916     if(task==AliQA::kRECPOINTS){
917       ERecPoints hindex 
918         = ( iCath == 0 ) ? kTriggerDigitsBendPlane : kTriggerDigitsNonBendPlane;
919       histoStrips = (TH3F*)GetRecPointsData(hindex);
920     }
921     else if(task==AliQA::kRAWS){
922       ERaw hindex 
923         = ( iCath == 0 ) ? kTriggerScalersBP : kTriggerScalersNBP;
924       histoStrips = (TH3F*)GetRawsData(hindex);
925       if(histoStrips->GetEntries()==0) return; // No scalers found
926     }
927     
928     for (Int_t iChamber = 0; iChamber < AliMpConstants::NofTriggerChambers(); iChamber++)
929     {
930       if(task==AliQA::kRECPOINTS){
931         histoDisplayStrips = (TH2F*)GetRecPointsData(kTriggerDigitsDisplay + AliMpConstants::NofTriggerChambers()*iCath + iChamber);
932       }
933       else if(task==AliQA::kRAWS){
934         histoDisplayStrips = (TH2F*)GetRawsData(kTriggerScalersDisplay + AliMpConstants::NofTriggerChambers()*iCath + iChamber);
935       }
936       Int_t bin = histoStrips->GetXaxis()->FindBin(11+iChamber);
937       histoStrips->GetXaxis()->SetRange(bin,bin);
938       TH2F* inputHisto = (TH2F*)histoStrips->Project3D("zy");
939       triggerDisplay.FillDisplayHistogram(inputHisto, histoDisplayStrips, AliMUONTriggerDisplay::kDisplayStrips, iCath, iChamber);
940     } // iChamber
941   } // iCath
942
943   if(task!=AliQA::kRECPOINTS) return;
944   TH1F* histoBoards = (TH1F*)GetRecPointsData(kTriggeredBoards);
945   TH2F* histoDisplayBoards = (TH2F*)GetRecPointsData(kTriggerBoardsDisplay);
946   triggerDisplay.FillDisplayHistogram(histoBoards, histoDisplayBoards, AliMUONTriggerDisplay::kDisplayBoards, 0, 0);
947 }