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