In AliMUONQADataMakerRec:
[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 "AliMUONCalibrationData.h"
44 #include "AliMpBusPatch.h"
45 #include "AliMpCDB.h"
46 #include "AliMpConstants.h"
47 #include "AliMpDDLStore.h"
48 #include "AliMpDEIterator.h"
49 #include "AliMpDEManager.h"
50 #include "AliMpLocalBoard.h"
51 #include "AliMpStationType.h"
52 #include "AliMpTriggerCrate.h"
53 #include "AliMpDCSNamer.h"
54 #include "AliRawEventHeaderBase.h"
55
56 // --- AliRoot header files ---
57 #include "AliCDBManager.h"
58 #include "AliCDBStorage.h"
59 #include "AliESDEvent.h"
60 #include "AliESDMuonTrack.h"
61 #include "AliESDMuonCluster.h"
62 #include "AliLog.h"
63 #include "AliRawReader.h"
64 #include "AliQAChecker.h"
65 #include "AliCodeTimer.h"
66 #include "AliDCSValue.h"
67
68 // --- ROOT system ---
69 #include <TClonesArray.h>
70 #include <TFile.h> 
71 #include <TH1F.h> 
72 #include <TH1I.h> 
73 #include <TH2F.h>
74 #include <TH3F.h> 
75 #include <Riostream.h>
76
77 //-----------------------------------------------------------------------------
78 /// \class AliMUONQADataMakerRec
79 ///
80 /// MUON base class for quality assurance data (histo) maker
81 ///
82 /// \author C. Finck, D. Stocco, L. Aphecetche
83
84 /// \cond CLASSIMP
85 ClassImp(AliMUONQADataMakerRec)
86 /// \endcond
87            
88 //____________________________________________________________________________ 
89 AliMUONQADataMakerRec::AliMUONQADataMakerRec() : 
90 AliQADataMakerRec(AliQA::GetDetName(AliQA::kMUON), "MUON Quality Assurance Data Maker"),
91 fIsInitRaws(kFALSE),
92 fIsInitRecPointsTracker(kFALSE),
93 fIsInitRecPointsTrigger(kFALSE),
94 fIsInitESDs(kFALSE),
95 fDigitStore(0x0),
96 fTriggerStore(0x0),
97 fDigitMaker(0x0),
98 fClusterStore(0x0),
99 fTrackerDataMaker(0x0),
100 fhESDnTotClustersPerCh(0x0),
101 fhESDnTotClustersPerDE(0x0),
102 fhESDnTotFullClustersPerDE(0x0),
103 fhESDSumClusterChargePerDE(0x0),
104 fhESDSumClusterSizePerDE(0x0),
105 fhESDSumResidualXPerDE(0x0),
106 fhESDSumResidualYPerDE(0x0),
107 fhESDSumResidualX2PerDE(0x0),
108 fhESDSumResidualY2PerDE(0x0),
109 fhESDSumLocalChi2XPerDE(0x0),
110 fhESDSumLocalChi2YPerDE(0x0)
111 {
112     /// ctor
113         
114   AliDebug(1,"");
115
116         Ctor();
117 }
118
119 //____________________________________________________________________________ 
120 void
121 AliMUONQADataMakerRec::Ctor()
122 {
123         /// Init some members
124         fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV1");
125         fDigitMaker = new AliMUONDigitMaker(kTRUE);
126 }
127
128 //____________________________________________________________________________ 
129 AliMUONQADataMakerRec::AliMUONQADataMakerRec(const AliMUONQADataMakerRec& qadm) :
130 AliQADataMakerRec(qadm),
131 fIsInitRaws(kFALSE),
132 fIsInitRecPointsTracker(kFALSE),
133 fIsInitRecPointsTrigger(kFALSE),
134 fIsInitESDs(kFALSE),
135 fDigitStore(0x0),
136 fTriggerStore(0x0),
137 fDigitMaker(0x0),
138 fClusterStore(0x0),
139 fTrackerDataMaker(0x0),
140 fhESDnTotClustersPerCh(0x0),
141 fhESDnTotClustersPerDE(0x0),
142 fhESDnTotFullClustersPerDE(0x0),
143 fhESDSumClusterChargePerDE(0x0),
144 fhESDSumClusterSizePerDE(0x0),
145 fhESDSumResidualXPerDE(0x0),
146 fhESDSumResidualYPerDE(0x0),
147 fhESDSumResidualX2PerDE(0x0),
148 fhESDSumResidualY2PerDE(0x0),
149 fhESDSumLocalChi2XPerDE(0x0),
150 fhESDSumLocalChi2YPerDE(0x0)
151 {
152     ///copy ctor 
153
154     AliDebug(1,"");
155
156
157     SetName((const char*)qadm.GetName()) ; 
158     SetTitle((const char*)qadm.GetTitle()); 
159
160         // Do not copy the digit store and digit maker, but create its own ones
161         
162         Ctor();
163         
164 }
165
166 //__________________________________________________________________
167 AliMUONQADataMakerRec& AliMUONQADataMakerRec::operator = (const AliMUONQADataMakerRec& qadm )
168 {
169   /// Assignment operator
170
171   AliDebug(1,"");
172
173   // check assignment to self
174   if (this == &qadm) return *this;
175
176   this->~AliMUONQADataMakerRec();
177   new(this) AliMUONQADataMakerRec(qadm);
178   return *this;
179 }
180
181 //__________________________________________________________________
182 AliMUONQADataMakerRec::~AliMUONQADataMakerRec()
183 {
184     /// dtor
185   
186   AliDebug(1,"");
187
188   AliCodeTimerAuto("");
189   
190   delete fDigitStore;
191   delete fTriggerStore;
192   delete fDigitMaker;
193   delete fClusterStore;
194   delete fTrackerDataMaker;
195   delete fhESDnTotClustersPerCh;
196   delete fhESDnTotClustersPerDE;
197   delete fhESDnTotFullClustersPerDE;
198   delete fhESDSumClusterChargePerDE;
199   delete fhESDSumClusterSizePerDE;
200   delete fhESDSumResidualXPerDE;
201   delete fhESDSumResidualYPerDE;
202   delete fhESDSumResidualX2PerDE;
203   delete fhESDSumResidualY2PerDE;
204   delete fhESDSumLocalChi2XPerDE;
205   delete fhESDSumLocalChi2YPerDE;
206 }
207
208 //____________________________________________________________________________ 
209 void AliMUONQADataMakerRec::EndOfDetectorCycle(AliQA::TASKINDEX_t task, TObjArray** list)
210 {
211   ///Detector specific actions at end of cycle
212   
213   AliCodeTimerAuto("");
214   
215   // Display trigger histos in a more user friendly way
216   DisplayTriggerInfo(task);
217   
218   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
219     SetEventSpecie(specie) ; 
220     if ( task == AliQA::kRAWS && fTrackerDataMaker ) 
221       {
222         TIter next(list[specie]);
223         TObject* o;
224         Bool_t alreadyThere(kFALSE);
225         while ( ( o = next() ) && !alreadyThere )
226           {
227             TString classname(o->ClassName());
228             if ( classname.Contains("TrackerData") ) alreadyThere = kTRUE;
229           }
230         if (!alreadyThere && fTrackerDataMaker) 
231           {
232             AliInfo("Adding fTrackerDataMaker to the list of qa objects");
233             list[specie]->AddAt(fTrackerDataMaker->Data(),(Int_t)kTrackerData);
234           }
235           if ( fTrackerDataMaker ) 
236             {
237               TH1* hbp = GetRawsData(kTrackerBusPatchOccupancy);
238               hbp->Reset();
239               TIter nextBP(AliMpDDLStore::Instance()->CreateBusPatchIterator());
240               AliMpBusPatch* bp(0x0);
241               AliMUONVTrackerData* data = fTrackerDataMaker->Data();
242               Int_t occDim = 2;
243       
244               while ( ( bp = static_cast<AliMpBusPatch*>(nextBP())) )
245                 {
246                   Int_t busPatchId = bp->GetId();
247                   Int_t bin = hbp->FindBin(busPatchId);
248                   hbp->SetBinContent(bin,data->BusPatch(busPatchId,occDim));
249                 }
250             }
251       }
252   
253     // Normalize ESD histos
254     if ( task == AliQA::kESDS ) {
255       
256       Double_t nTracks = GetESDsData(kESDnClustersPerTrack)->GetEntries();
257       if (nTracks <= 0) continue;
258       
259       TH1* hESDnClustersPerCh = GetESDsData(kESDnClustersPerCh);
260       TH1* hESDnClustersPerDE = GetESDsData(kESDnClustersPerDE);
261       TH1* hESDClusterChargePerChMean = GetESDsData(kESDClusterChargePerChMean);
262       TH1* hESDClusterChargePerChSigma = GetESDsData(kESDClusterChargePerChSigma);
263       TH1* hESDClusterSizePerChMean = GetESDsData(kESDClusterSizePerChMean);
264       TH1* hESDClusterSizePerChSigma = GetESDsData(kESDClusterSizePerChSigma);
265       TH1* hESDResidualXPerChMean = GetESDsData(kESDResidualXPerChMean);
266       TH1* hESDResidualXPerChSigma = GetESDsData(kESDResidualXPerChSigma);
267       TH1* hESDResidualYPerChMean = GetESDsData(kESDResidualYPerChMean);
268       TH1* hESDResidualYPerChSigma = GetESDsData(kESDResidualYPerChSigma);
269       TH1* hESDLocalChi2XPerChMean = GetESDsData(kESDLocalChi2XPerChMean);
270       TH1* hESDLocalChi2YPerChMean = GetESDsData(kESDLocalChi2YPerChMean);
271       TH1* hESDClusterChargePerDE = GetESDsData(kESDClusterChargePerDE);
272       TH1* hESDClusterSizePerDE = GetESDsData(kESDClusterSizePerDE);
273       TH1* hESDResidualXPerDEMean = GetESDsData(kESDResidualXPerDEMean);
274       TH1* hESDResidualXPerDESigma = GetESDsData(kESDResidualXPerDESigma);
275       TH1* hESDResidualYPerDEMean = GetESDsData(kESDResidualYPerDEMean);
276       TH1* hESDResidualYPerDESigma = GetESDsData(kESDResidualYPerDESigma);
277       TH1* hESDLocalChi2XPerDEMean = GetESDsData(kESDLocalChi2XPerDEMean);
278       TH1* hESDLocalChi2YPerDEMean = GetESDsData(kESDLocalChi2YPerDEMean);
279       
280       hESDnClustersPerCh->Reset();
281       hESDnClustersPerDE->Reset();
282       hESDnClustersPerCh->Add(fhESDnTotClustersPerCh, 1./nTracks);
283       hESDnClustersPerDE->Add(fhESDnTotClustersPerDE, 1./nTracks);
284       
285       // loop over chambers
286       for (Int_t iCh = 0; iCh < AliMUONConstants::NTrackingCh(); iCh++) {
287         
288         TH1* hESDClusterChargeInCh = GetESDsData(kESDClusterChargeInCh+iCh);
289         Double_t sigmaCharge = hESDClusterChargeInCh->GetRMS();
290         hESDClusterChargePerChMean->SetBinContent(iCh+1, hESDClusterChargeInCh->GetMean());
291         hESDClusterChargePerChMean->SetBinError(iCh+1, hESDClusterChargeInCh->GetMeanError());
292         hESDClusterChargePerChSigma->SetBinContent(iCh+1, sigmaCharge);
293         hESDClusterChargePerChSigma->SetBinError(iCh+1, hESDClusterChargeInCh->GetRMSError());
294         
295         TH1* hESDClusterSizeInCh = GetESDsData(kESDClusterSizeInCh+iCh);
296         Double_t sigmaSize = hESDClusterSizeInCh->GetRMS();
297         hESDClusterSizePerChMean->SetBinContent(iCh+1, hESDClusterSizeInCh->GetMean());
298         hESDClusterSizePerChMean->SetBinError(iCh+1, hESDClusterSizeInCh->GetMeanError());
299         hESDClusterSizePerChSigma->SetBinContent(iCh+1, sigmaSize);
300         hESDClusterSizePerChSigma->SetBinError(iCh+1, hESDClusterSizeInCh->GetRMSError());
301         
302         TH1* hESDResidualXInCh = GetESDsData(kESDResidualXInCh+iCh);
303         Double_t sigmaResidualX = hESDResidualXInCh->GetRMS();
304         hESDResidualXPerChMean->SetBinContent(iCh+1, hESDResidualXInCh->GetMean());
305         hESDResidualXPerChMean->SetBinError(iCh+1, hESDResidualXInCh->GetMeanError());
306         hESDResidualXPerChSigma->SetBinContent(iCh+1, sigmaResidualX);
307         hESDResidualXPerChSigma->SetBinError(iCh+1, hESDResidualXInCh->GetRMSError());
308         
309         TH1* hESDResidualYInCh = GetESDsData(kESDResidualYInCh+iCh);
310         Double_t sigmaResidualY = hESDResidualYInCh->GetRMS();
311         hESDResidualYPerChMean->SetBinContent(iCh+1, hESDResidualYInCh->GetMean());
312         hESDResidualYPerChMean->SetBinError(iCh+1, hESDResidualYInCh->GetMeanError());
313         hESDResidualYPerChSigma->SetBinContent(iCh+1, sigmaResidualY);
314         hESDResidualYPerChSigma->SetBinError(iCh+1, hESDResidualYInCh->GetRMSError());
315         
316         TH1* hESDLocalChi2XInCh = GetESDsData(kESDLocalChi2XInCh+iCh);
317         Double_t sigmaLocalChi2X = hESDLocalChi2XInCh->GetRMS();
318         hESDLocalChi2XPerChMean->SetBinContent(iCh+1, hESDLocalChi2XInCh->GetMean());
319         hESDLocalChi2XPerChMean->SetBinError(iCh+1, hESDLocalChi2XInCh->GetMeanError());
320         
321         TH1* hESDLocalChi2YInCh = GetESDsData(kESDLocalChi2YInCh+iCh);
322         Double_t sigmaLocalChi2Y = hESDLocalChi2YInCh->GetRMS();
323         hESDLocalChi2YPerChMean->SetBinContent(iCh+1, hESDLocalChi2YInCh->GetMean());
324         hESDLocalChi2YPerChMean->SetBinError(iCh+1, hESDLocalChi2YInCh->GetMeanError());
325         
326         // loop over DE into chamber iCh
327         AliMpDEIterator it;
328         it.First(iCh);
329         while ( !it.IsDone()) {
330           
331           Int_t iDE = it.CurrentDEId();
332           
333           Double_t nClusters = fhESDnTotClustersPerDE->GetBinContent(iDE+1);
334           if (nClusters > 1) {
335             
336             hESDClusterChargePerDE->SetBinContent(iDE+1, fhESDSumClusterChargePerDE->GetBinContent(iDE+1)/nClusters);
337             hESDClusterChargePerDE->SetBinError(iDE+1, sigmaCharge/TMath::Sqrt(nClusters));
338             
339             Double_t meanResX = fhESDSumResidualXPerDE->GetBinContent(iDE+1)/nClusters;
340             hESDResidualXPerDEMean->SetBinContent(iDE+1, meanResX);
341             hESDResidualXPerDEMean->SetBinError(iDE+1, sigmaResidualX/TMath::Sqrt(nClusters));
342             hESDResidualXPerDESigma->SetBinContent(iDE+1, TMath::Sqrt(fhESDSumResidualX2PerDE->GetBinContent(iDE+1)/nClusters - meanResX*meanResX));
343             hESDResidualXPerDESigma->SetBinError(iDE+1, sigmaResidualX/TMath::Sqrt(2.*nClusters));
344             
345             Double_t meanResY = fhESDSumResidualYPerDE->GetBinContent(iDE+1)/nClusters;
346             hESDResidualYPerDEMean->SetBinContent(iDE+1, meanResY);
347             hESDResidualYPerDEMean->SetBinError(iDE+1, sigmaResidualY/TMath::Sqrt(nClusters));
348             hESDResidualYPerDESigma->SetBinContent(iDE+1, TMath::Sqrt(fhESDSumResidualY2PerDE->GetBinContent(iDE+1)/nClusters - meanResY*meanResY));
349             hESDResidualYPerDESigma->SetBinError(iDE+1, sigmaResidualY/TMath::Sqrt(2.*nClusters));
350             
351             hESDLocalChi2XPerDEMean->SetBinContent(iDE+1, fhESDSumLocalChi2XPerDE->GetBinContent(iDE+1)/nClusters);
352             hESDLocalChi2XPerDEMean->SetBinError(iDE+1, sigmaLocalChi2X/TMath::Sqrt(nClusters));
353             
354             hESDLocalChi2YPerDEMean->SetBinContent(iDE+1, fhESDSumLocalChi2YPerDE->GetBinContent(iDE+1)/nClusters);
355             hESDLocalChi2YPerDEMean->SetBinError(iDE+1, sigmaLocalChi2Y/TMath::Sqrt(nClusters));
356             
357           } else {
358             
359             hESDClusterChargePerDE->SetBinContent(iDE+1, fhESDSumClusterChargePerDE->GetBinContent(iDE+1));
360             hESDClusterChargePerDE->SetBinError(iDE+1, hESDClusterChargeInCh->GetXaxis()->GetXmax());
361             
362             hESDResidualXPerDEMean->SetBinContent(iDE+1, fhESDSumResidualXPerDE->GetBinContent(iDE+1));
363             hESDResidualXPerDEMean->SetBinError(iDE+1, hESDResidualXInCh->GetXaxis()->GetXmax());
364             hESDResidualXPerDESigma->SetBinContent(iDE+1, 0.);
365             hESDResidualXPerDESigma->SetBinError(iDE+1, hESDResidualXInCh->GetXaxis()->GetXmax());
366             
367             hESDResidualYPerDEMean->SetBinContent(iDE+1, fhESDSumResidualYPerDE->GetBinContent(iDE+1));
368             hESDResidualYPerDEMean->SetBinError(iDE+1, hESDResidualYInCh->GetXaxis()->GetXmax());
369             hESDResidualYPerDESigma->SetBinContent(iDE+1, 0.);
370             hESDResidualYPerDESigma->SetBinError(iDE+1, hESDResidualYInCh->GetXaxis()->GetXmax());
371             
372             hESDLocalChi2XPerDEMean->SetBinContent(iDE+1, fhESDSumLocalChi2XPerDE->GetBinContent(iDE+1));
373             hESDLocalChi2XPerDEMean->SetBinError(iDE+1, hESDLocalChi2XInCh->GetXaxis()->GetXmax());
374             
375             hESDLocalChi2YPerDEMean->SetBinContent(iDE+1, fhESDSumLocalChi2YPerDE->GetBinContent(iDE+1));
376             hESDLocalChi2YPerDEMean->SetBinError(iDE+1, hESDLocalChi2YInCh->GetXaxis()->GetXmax());
377             
378           }
379           
380           Double_t nFullClusters = fhESDnTotFullClustersPerDE->GetBinContent(iDE+1);
381           if (nFullClusters > 1) {
382             
383             hESDClusterSizePerDE->SetBinContent(iDE+1, fhESDSumClusterSizePerDE->GetBinContent(iDE+1)/nFullClusters);
384             hESDClusterSizePerDE->SetBinError(iDE+1, sigmaSize/TMath::Sqrt(nFullClusters));
385             
386           } else {
387             
388             hESDClusterSizePerDE->SetBinContent(iDE+1, fhESDSumClusterSizePerDE->GetBinContent(iDE+1));
389             hESDClusterSizePerDE->SetBinError(iDE+1, hESDClusterSizeInCh->GetXaxis()->GetXmax());
390             
391           }
392           
393           it.Next();
394         }
395         
396       }
397       
398     }
399     
400   }
401   
402   // do the QA checking
403   AliQAChecker::Instance()->Run(AliQA::kMUON, task, list) ;
404 }
405
406 //____________________________________________________________________________ 
407 void AliMUONQADataMakerRec::InitRaws()
408 {
409     /// create Raws histograms in Raws subdir
410         
411   AliCodeTimerAuto("");
412   
413   Bool_t forExpert(kTRUE);
414   
415         if ( ! AliCDBManager::Instance()->GetDefaultStorage() )
416         {
417                 AliError("CDB default storage not set. Cannot work.");
418                 fIsInitRaws=kFALSE;
419         }
420         
421         TH3F* h3 = new TH3F("hTriggerScalersBendPlane", "Trigger scalers in bending plane",
422                                                                                         4, 10.5, 14.5,
423                                                                                         234, 0.5, 234.5,
424                                                                                         16, -0.5, 15.5);
425         h3->GetXaxis()->SetTitle("Chamber");
426         h3->GetYaxis()->SetTitle("Board");
427         h3->GetZaxis()->SetTitle("Strip");
428         Add2RawsList(h3, kTriggerScalersBP,forExpert);
429         
430         TH3F* h4 = new TH3F("hTriggerScalersNonBendPlane", "Trigger scalers in non-bending plane",
431                                                                                         4, 10.5, 14.5,
432                                                                                         234, 0.5, 234.5,
433                                                                                         16, -0.5, 15.5);
434         h4->GetXaxis()->SetTitle("Chamber");
435         h4->GetYaxis()->SetTitle("Board");
436         h4->GetZaxis()->SetTitle("Strip");
437         Add2RawsList(h4, kTriggerScalersNBP,forExpert);
438         
439         AliMUONTriggerDisplay triggerDisplay;
440         TString histoName, histoTitle;
441         for(Int_t iCath=0; iCath<AliMpConstants::NofCathodes(); iCath++){
442                 TString cathName = ( iCath==0 ) ? "BendPlane" : "NonBendPlane";
443                 for(Int_t iChamber=0; iChamber<AliMpConstants::NofTriggerChambers(); iChamber++){
444                         histoName = Form("hScalers%sChamber%i", cathName.Data(), 11+iChamber);
445                         histoTitle = Form("Chamber %i: Scalers %s", 11+iChamber, cathName.Data());
446                         TH2F* h5 = (TH2F*)triggerDisplay.GetEmptyDisplayHisto(histoName, AliMUONTriggerDisplay::kDisplayStrips, 
447                                                                               iCath, iChamber, histoTitle);
448                         Add2RawsList(h5, kTriggerScalersDisplay + AliMpConstants::NofTriggerChambers()*iCath + iChamber,!forExpert);
449                 }
450         }
451
452         TH2F* h6 = new TH2F("hTriggerRPCI", "Trigger RPC currents",
453                             4, 10.5, 14.5,
454                             18, -0.5, 17.5);
455         h6->GetXaxis()->SetTitle("Chamber");
456         h6->GetYaxis()->SetTitle("RPC");
457         Add2RawsList(h6, kTriggerRPCi, forExpert);
458
459         TH2F* h7 = new TH2F("hTriggerRPCHV", "Trigger RPC HV",
460                             4, 10.5, 14.5,
461                             18, -0.5, 17.5);
462         h7->GetXaxis()->SetTitle("Chamber");
463         h7->GetYaxis()->SetTitle("RPC");
464         Add2RawsList(h7, kTriggerRPChv, forExpert);
465         
466         for(Int_t iChamber=0; iChamber<AliMpConstants::NofTriggerChambers(); iChamber++){
467           histoName = Form("hRPCIChamber%i", 11+iChamber);
468           histoTitle = Form("Chamber %i: RPC Currents (#muA)", 11+iChamber);
469           TH2F* h8 = (TH2F*)triggerDisplay.GetEmptyDisplayHisto(histoName, AliMUONTriggerDisplay::kDisplaySlats, 
470                                                                 0, iChamber, histoTitle);
471           Add2RawsList(h8, kTriggerIDisplay + iChamber, !forExpert);
472         }
473
474         for(Int_t iChamber=0; iChamber<AliMpConstants::NofTriggerChambers(); iChamber++){
475           histoName = Form("hRPCHVChamber%i", 11+iChamber);
476           histoTitle = Form("Chamber %i: RPC HV (V)", 11+iChamber);
477           TH2F* h9 = (TH2F*)triggerDisplay.GetEmptyDisplayHisto(histoName, AliMUONTriggerDisplay::kDisplaySlats, 
478                                                                 0, iChamber, histoTitle);
479           Add2RawsList(h9, kTriggerHVDisplay + iChamber, !forExpert);
480         }
481
482         
483   Int_t nbp(0);
484   TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
485   while (next())
486   {
487     ++nbp;
488   }
489   
490   TH1* hbp = new TH1F("hTrackerBusPatchOccupancy","Occupancy of bus patches",
491                       nbp,-0.5,nbp-0.5);
492   
493   Add2RawsList(hbp,kTrackerBusPatchOccupancy,!forExpert);
494
495   const Bool_t histogram(kFALSE);
496   const Bool_t fastDecoder(kTRUE);
497
498   fTrackerDataMaker = new AliMUONTrackerCalibratedDataMaker(GetRecoParam(),
499                                                             AliCDBManager::Instance()->GetRun(),
500                                                             0x0,
501                                                             AliCDBManager::Instance()->GetDefaultStorage()->GetURI(),
502                                                             "NOGAIN",
503                                                             histogram,
504                                                             0.0,0.0,
505                                                             fastDecoder);
506                 
507   fTrackerDataMaker->Data()->DisableChannelLevel(); // to save up disk space, we only store starting at the manu level
508         
509   fTrackerDataMaker->SetRunning(kTRUE);
510   
511         fIsInitRaws = kTRUE;
512 }
513
514 //____________________________________________________________________________ 
515 void AliMUONQADataMakerRec::InitRecPoints()
516 {
517         /// create Reconstructed Points histograms in RecPoints subdir
518   
519   AliCodeTimerAuto("");
520   
521         InitRecPointsTrigger();
522         InitRecPointsTracker();
523 }
524
525 //____________________________________________________________________________ 
526 void AliMUONQADataMakerRec::InitRecPointsTracker()
527 {
528         /// create Reconstructed Points histograms in RecPoints subdir for the
529         /// MUON tracker subsystem.
530
531   AliCodeTimerAuto("");
532   
533   Bool_t forExpert(kTRUE);
534   
535         AliMpDEIterator it;
536         
537         it.First();
538         
539         Int_t ndes(0);
540         
541         while ( !it.IsDone())
542         {
543                 Int_t detElemId = it.CurrentDEId();
544                 
545                 it.Next();
546
547                 if ( AliMpDEManager::GetStationType(detElemId) != AliMp::kStationTrigger )
548                 {
549                         ndes = TMath::Max(ndes,detElemId);
550
551                         TH1* h = new TH1I(Form("hTrackerClusterMultiplicityForDE%04d",detElemId),
552                                           Form("Multiplicity of the clusters in detection element %d",detElemId),
553                                           100,0,100);
554                         
555                         h->GetXaxis()->SetTitle("Detection Element Id");
556                         
557                         Add2RecPointsList(h,kTrackerClusterMultiplicityPerDE+detElemId,forExpert);
558                         
559                         h =  new TH1I(Form("hTrackerClusterChargeForDE%04d",detElemId),
560                                       Form("Charge of the clusters in detection element %d",detElemId),
561                                       100,0,1000);
562
563                         h->GetXaxis()->SetTitle("Detection Element Id");
564
565                         Add2RecPointsList(h,kTrackerClusterChargePerDE+detElemId,forExpert);
566
567                 }
568
569         }
570
571         TH1* h = new TH1I("hTrackerNumberOfClustersPerDE","Number of clusters per detection element",
572                                                                                 ndes, 0.5, ndes + 0.5);
573
574         h->GetXaxis()->SetTitle("Detection Element Id");
575
576         Add2RecPointsList(h, kTrackerNumberOfClustersPerDE,!forExpert);
577
578         for ( Int_t i = 0; i < AliMpConstants::NofTrackingChambers(); ++i ) 
579         {
580                 TH1* h1 = new TH1I("hTrackerNumberOfClustersPerChamber","Number of clusters per chamber",
581                                    AliMpConstants::NofTrackingChambers(),-0.5,AliMpConstants::NofTrackingChambers()-0.5);
582                 Add2RecPointsList(h1,kTrackerNumberOfClustersPerChamber,forExpert);
583                 h1 = new TH1I(Form("hTrackerClusterMultiplicityForChamber%d",i),
584                               Form("Cluster multiplicity for chamber %d",i),
585                               100,0,100);
586                 Add2RecPointsList(h1,kTrackerClusterMultiplicityPerChamber+i,forExpert);
587                 h1 = new TH1I(Form("hTrackerClusterChargeForChamber%d",i),
588                               Form("Cluster charge for chamber %d",i),
589                               100,0,1000);
590                 Add2RecPointsList(h1,kTrackerClusterChargePerChamber+i,forExpert);
591         }
592         
593         fIsInitRecPointsTracker=kTRUE;
594 }
595
596 //____________________________________________________________________________ 
597 void AliMUONQADataMakerRec::InitRecPointsTrigger()
598 {
599         /// create Reconstructed Points histograms in RecPoints subdir for the
600         /// MUON Trigger subsystem.
601         
602   Bool_t forExpert(kTRUE);
603   
604     TH3F* h0 = new TH3F("hTriggerDigitsBendPlane", "Trigger digits in bending plane",
605                         4, 10.5, 14.5,
606                         234, 0.5, 234.5,
607                         16, -0.5, 15.5);
608     h0->GetXaxis()->SetTitle("Chamber");
609     h0->GetYaxis()->SetTitle("Board");
610     h0->GetZaxis()->SetTitle("Strip");
611     Add2RecPointsList(h0, kTriggerDigitsBendPlane,forExpert);
612
613     TH3F* h1 = new TH3F("hTriggerDigitsNonBendPlane", "Trigger digits in non-bending plane",
614                         4, 10.5, 14.5,
615                         234, 0.5, 234.5,
616                         16, -0.5, 15.5);
617     h1->GetXaxis()->SetTitle("Chamber");
618     h1->GetYaxis()->SetTitle("Board");
619     h1->GetZaxis()->SetTitle("Strip");
620     Add2RecPointsList(h1, kTriggerDigitsNonBendPlane,forExpert);
621
622     TH1F* h2 = new TH1F("hTriggeredBoards", "Triggered boards", 234, 0.5, 234.5);
623     Add2RecPointsList(h2, kTriggeredBoards,forExpert);
624
625     AliMUONTriggerDisplay triggerDisplay;
626     TString histoName, histoTitle;
627     for(Int_t iCath=0; iCath<AliMpConstants::NofCathodes(); iCath++){
628       TString cathName = ( iCath==0 ) ? "BendPlane" : "NonBendPlane";
629       for(Int_t iChamber=0; iChamber<AliMpConstants::NofTriggerChambers(); iChamber++){
630         histoName = Form("hTriggerDigits%sChamber%i", cathName.Data(), 11+iChamber);
631         histoTitle = Form("Chamber %i: Fired pads %s", 11+iChamber, cathName.Data());
632         TH2F* h3 = (TH2F*)triggerDisplay.GetEmptyDisplayHisto(histoName, AliMUONTriggerDisplay::kDisplayStrips, 
633                                                               iCath, iChamber, histoTitle);
634         Add2RecPointsList(h3, kTriggerDigitsDisplay + AliMpConstants::NofTriggerChambers()*iCath + iChamber,!forExpert);
635       }
636     }
637
638     TH2F* h4 = (TH2F*)triggerDisplay.GetEmptyDisplayHisto("hFiredBoardsDisplay", AliMUONTriggerDisplay::kDisplayBoards,
639                                                           0, 0, "Fired boards");
640     Add2RecPointsList(h4, kTriggerBoardsDisplay,!forExpert);
641         
642         fIsInitRecPointsTrigger = kTRUE;
643 }
644
645
646 //____________________________________________________________________________ 
647 void AliMUONQADataMakerRec::InitESDs()
648 {
649   ///create ESDs histograms in ESDs subdir
650   
651   Bool_t forExpert(kTRUE);
652   
653   Int_t nCh = AliMUONConstants::NTrackingCh();
654   Int_t nDE = 1100;
655   
656   // track info
657   TH1F* hESDnTracks = new TH1F("hESDnTracks", "number of tracks;n_{tracks}", 20, 0., 20.);
658   Add2ESDsList(hESDnTracks, kESDnTracks,!forExpert);
659
660   TH1F* hESDMatchTrig = new TH1F("hESDMatchTrig", "number of tracks matched with trigger;n_{tracks}", 20, 0., 20.);
661   Add2ESDsList(hESDMatchTrig, kESDMatchTrig,!forExpert);
662   
663   TH1F* hESDMomentum = new TH1F("hESDMomentum", "momentum distribution;p (GeV/c)", 300, 0., 300);
664   Add2ESDsList(hESDMomentum, kESDMomentum,forExpert);
665
666   TH1F* hESDPt = new TH1F("hESDPt", "transverse momentum distribution;p_{t} (GeV/c)", 200, 0., 50);
667   Add2ESDsList(hESDPt, kESDPt,forExpert);
668
669   TH1F* hESDRapidity = new TH1F("hESDRapidity", "rapidity distribution;rapidity", 200, -4.5, -2.);
670   Add2ESDsList(hESDRapidity, kESDRapidity,forExpert);
671
672   TH1F* hESDChi2 = new TH1F("hESDChi2", "normalized #chi^{2} distribution;#chi^{2} / ndf", 500, 0., 50.);
673   Add2ESDsList(hESDChi2, kESDChi2,forExpert);
674   
675   TH1F* hESDProbChi2 = new TH1F("hESDProbChi2", "distribution of probability of #chi^{2};prob(#chi^{2})", 100, 0., 1.);
676   Add2ESDsList(hESDProbChi2, kESDProbChi2,forExpert);
677   
678   // cluster info
679   for (Int_t i = 0; i < nCh; i++) {
680     Float_t rMax = AliMUONConstants::Rmax(i/2);
681     TH2F* hESDClusterHitMap = new TH2F(Form("hESDClusterHitMap%d",i+1), Form("cluster position distribution in chamber %d;X (cm);Y (cm)",i+1),
682                                        100, -rMax, rMax, 100, -rMax, rMax);
683     Add2ESDsList(hESDClusterHitMap, kESDClusterHitMap+i,forExpert);
684   }
685   
686   TH1F* hESDnClustersPerTrack = new TH1F("hESDnClustersPerTrack", "number of associated clusters per track;n_{clusters}", 20, 0., 20.);
687   Add2ESDsList(hESDnClustersPerTrack, kESDnClustersPerTrack,!forExpert);
688   
689   TH1F* hESDnClustersPerCh = new TH1F("hESDnClustersPerCh", "averaged number of clusters per chamber per track;chamber ID;<n_{clusters}>", nCh, 0, nCh);
690   hESDnClustersPerCh->SetFillColor(kRed);
691   Add2ESDsList(hESDnClustersPerCh, kESDnClustersPerCh,forExpert);
692   
693   TH1F* hESDnClustersPerDE = new TH1F("hESDnClustersPerDE", "averaged number of clusters per DE per track;DetElem ID;<n_{clusters}>", nDE, 0, nDE);
694   hESDnClustersPerDE->SetFillColor(kRed);
695   Add2ESDsList(hESDnClustersPerDE, kESDnClustersPerDE,forExpert);
696   
697   for (Int_t i = 0; i < nCh; i++) {
698     TH1F* hESDClusterChargeInCh = new TH1F(Form("hESDClusterChargeInCh%d",i+1), Form("cluster charge distribution in chamber %d;charge (ADC counts)",i+1), 500, 0., 5000.);
699     Add2ESDsList(hESDClusterChargeInCh, kESDClusterChargeInCh+i,forExpert);
700   }
701   
702   TH1F* hESDClusterChargePerChMean = new TH1F("hESDClusterChargePerChMean", "cluster mean charge per chamber;chamber ID;<charge> (ADC counts)", nCh, 0, nCh);
703   hESDClusterChargePerChMean->SetOption("P");
704   hESDClusterChargePerChMean->SetMarkerStyle(kFullDotMedium);
705   hESDClusterChargePerChMean->SetMarkerColor(kRed);
706   Add2ESDsList(hESDClusterChargePerChMean, kESDClusterChargePerChMean,forExpert);
707   
708   TH1F* hESDClusterChargePerChSigma = new TH1F("hESDClusterChargePerChSigma", "cluster charge dispersion per chamber;chamber ID;#sigma_{charge} (ADC counts)", nCh, 0, nCh);
709   hESDClusterChargePerChSigma->SetOption("P");
710   hESDClusterChargePerChSigma->SetMarkerStyle(kFullDotMedium);
711   hESDClusterChargePerChSigma->SetMarkerColor(kRed);
712   Add2ESDsList(hESDClusterChargePerChSigma, kESDClusterChargePerChSigma,forExpert);
713   
714   TH1F* hESDClusterChargePerDE = new TH1F("hESDClusterChargePerDE", "cluster mean charge per DE;DetElem ID;<charge> (ADC counts)", nDE, 0, nDE);
715   hESDClusterChargePerDE->SetOption("P");
716   hESDClusterChargePerDE->SetMarkerStyle(kFullDotMedium);
717   hESDClusterChargePerDE->SetMarkerColor(kRed);
718   Add2ESDsList(hESDClusterChargePerDE, kESDClusterChargePerDE,forExpert);
719   
720   for (Int_t i = 0; i < nCh; i++) {
721     TH1F* hESDClusterSizeInCh = new TH1F(Form("hESDClusterSizeInCh%d",i+1), Form("cluster size distribution in chamber %d;size (n_{pads})",i+1), 200, 0., 200.);
722     Add2ESDsList(hESDClusterSizeInCh, kESDClusterSizeInCh+i,forExpert);
723   }
724   
725   TH1F* hESDClusterSizePerChMean = new TH1F("hESDClusterSizePerChMean", "cluster mean size per chamber;chamber ID;<size> (n_{pads})", nCh, 0, nCh);
726   hESDClusterSizePerChMean->SetOption("P");
727   hESDClusterSizePerChMean->SetMarkerStyle(kFullDotMedium);
728   hESDClusterSizePerChMean->SetMarkerColor(kRed);
729   Add2ESDsList(hESDClusterSizePerChMean, kESDClusterSizePerChMean,forExpert);
730   
731   TH1F* hESDClusterSizePerChSigma = new TH1F("hESDClusterSizePerChSigma", "cluster size dispersion per chamber;chamber ID;#sigma_{size} (n_{pads})", nCh, 0, nCh);
732   hESDClusterSizePerChSigma->SetOption("P");
733   hESDClusterSizePerChSigma->SetMarkerStyle(kFullDotMedium);
734   hESDClusterSizePerChSigma->SetMarkerColor(kRed);
735   Add2ESDsList(hESDClusterSizePerChSigma, kESDClusterSizePerChSigma,forExpert);
736   
737   TH1F* hESDClusterSizePerDE = new TH1F("hESDClusterSizePerDE", "cluster mean size per DE;DetElem ID;<size> (n_{pads})", nDE, 0, nDE);
738   hESDClusterSizePerDE->SetOption("P");
739   hESDClusterSizePerDE->SetMarkerStyle(kFullDotMedium);
740   hESDClusterSizePerDE->SetMarkerColor(kRed);
741   Add2ESDsList(hESDClusterSizePerDE, kESDClusterSizePerDE,forExpert);
742   
743   // cluster - track info
744   for (Int_t i = 0; i < nCh; i++) {
745     TH1F* hESDResidualXInCh = new TH1F(Form("hESDResidualXInCh%d",i+1), Form("cluster-track residual-X distribution in chamber %d;#Delta_{X} (cm)",i+1), 1000, -5., 5.);
746     Add2ESDsList(hESDResidualXInCh, kESDResidualXInCh+i,forExpert);
747     
748     TH1F* hESDResidualYInCh = new TH1F(Form("hESDResidualYInCh%d",i+1), Form("cluster-track residual-Y distribution in chamber %d;#Delta_{Y} (cm)",i+1), 1000, -1., 1.);
749     Add2ESDsList(hESDResidualYInCh, kESDResidualYInCh+i,forExpert);
750     
751     TH1F* hESDLocalChi2XInCh = new TH1F(Form("hESDLocalChi2XInCh%d",i+1), Form("local chi2-X distribution in chamber %d;local #chi^{2}_{X}",i+1), 1000, 0., 25);
752     Add2ESDsList(hESDLocalChi2XInCh, kESDLocalChi2XInCh+i,forExpert);
753     
754     TH1F* hESDLocalChi2YInCh = new TH1F(Form("hESDLocalChi2YInCh%d",i+1), Form("local chi2-Y distribution in chamber %d;local #chi^{2}_{Y}",i+1), 1000, 0., 25);
755     Add2ESDsList(hESDLocalChi2YInCh, kESDLocalChi2YInCh+i,forExpert);
756   }
757   
758   TH1F* hESDResidualXPerChMean = new TH1F("hESDResidualXPerChMean", "cluster-track residual-X per Ch: mean;chamber ID;<#Delta_{X}> (cm)", nCh, 0, nCh);
759   hESDResidualXPerChMean->SetOption("P");
760   hESDResidualXPerChMean->SetMarkerStyle(kFullDotMedium);
761   hESDResidualXPerChMean->SetMarkerColor(kRed);
762   Add2ESDsList(hESDResidualXPerChMean, kESDResidualXPerChMean,forExpert);
763   
764   TH1F* hESDResidualYPerChMean = new TH1F("hESDResidualYPerChMean", "cluster-track residual-Y per Ch: mean;chamber ID;<#Delta_{Y}> (cm)", nCh, 0, nCh);
765   hESDResidualYPerChMean->SetOption("P");
766   hESDResidualYPerChMean->SetMarkerStyle(kFullDotMedium);
767   hESDResidualYPerChMean->SetMarkerColor(kRed);
768   Add2ESDsList(hESDResidualYPerChMean, kESDResidualYPerChMean,forExpert);
769   
770   TH1F* hESDResidualXPerChSigma = new TH1F("hESDResidualXPerChSigma", "cluster-track residual-X per Ch: sigma;chamber ID;#sigma_{X} (cm)", nCh, 0, nCh);
771   hESDResidualXPerChSigma->SetOption("P");
772   hESDResidualXPerChSigma->SetMarkerStyle(kFullDotMedium);
773   hESDResidualXPerChSigma->SetMarkerColor(kRed);
774   Add2ESDsList(hESDResidualXPerChSigma, kESDResidualXPerChSigma,forExpert);
775   
776   TH1F* hESDResidualYPerChSigma = new TH1F("hESDResidualYPerChSigma", "cluster-track residual-Y per Ch: sigma;chamber ID;#sigma_{Y} (cm)", nCh, 0, nCh);
777   hESDResidualYPerChSigma->SetOption("P");
778   hESDResidualYPerChSigma->SetMarkerStyle(kFullDotMedium);
779   hESDResidualYPerChSigma->SetMarkerColor(kRed);
780   Add2ESDsList(hESDResidualYPerChSigma, kESDResidualYPerChSigma,forExpert);
781   
782   TH1F* hESDLocalChi2XPerChMean = new TH1F("hESDLocalChi2XPerChMean", "local chi2-X per Ch: mean;chamber ID;<local #chi^{2}_{X}>", nCh, 0, nCh);
783   hESDLocalChi2XPerChMean->SetOption("P");
784   hESDLocalChi2XPerChMean->SetMarkerStyle(kFullDotMedium);
785   hESDLocalChi2XPerChMean->SetMarkerColor(kRed);
786   Add2ESDsList(hESDLocalChi2XPerChMean, kESDLocalChi2XPerChMean,forExpert);
787   
788   TH1F* hESDLocalChi2YPerChMean = new TH1F("hESDLocalChi2YPerChMean", "local chi2-Y per Ch: mean;chamber ID;<local #chi^{2}_{Y}>", nCh, 0, nCh);
789   hESDLocalChi2YPerChMean->SetOption("P");
790   hESDLocalChi2YPerChMean->SetMarkerStyle(kFullDotMedium);
791   hESDLocalChi2YPerChMean->SetMarkerColor(kRed);
792   Add2ESDsList(hESDLocalChi2YPerChMean, kESDLocalChi2YPerChMean,forExpert);
793   
794   TH1F* hESDResidualXPerDEMean = new TH1F("hESDResidualXPerDEMean", "cluster-track residual-X per DE: mean;DetElem ID;<#Delta_{X}> (cm)", nDE, 0, nDE);
795   hESDResidualXPerDEMean->SetOption("P");
796   hESDResidualXPerDEMean->SetMarkerStyle(kFullDotMedium);
797   hESDResidualXPerDEMean->SetMarkerColor(kRed);
798   Add2ESDsList(hESDResidualXPerDEMean, kESDResidualXPerDEMean,forExpert);
799   
800   TH1F* hESDResidualYPerDEMean = new TH1F("hESDResidualYPerDEMean", "cluster-track residual-Y per DE: mean;DetElem ID;<#Delta_{Y}> (cm)", nDE, 0, nDE);
801   hESDResidualYPerDEMean->SetOption("P");
802   hESDResidualYPerDEMean->SetMarkerStyle(kFullDotMedium);
803   hESDResidualYPerDEMean->SetMarkerColor(kRed);
804   Add2ESDsList(hESDResidualYPerDEMean, kESDResidualYPerDEMean,forExpert);
805   
806   TH1F* hESDResidualXPerDESigma = new TH1F("hESDResidualXPerDESigma", "cluster-track residual-X per DE: sigma;DetElem ID;#sigma_{X} (cm)", nDE, 0, nDE);
807   hESDResidualXPerDESigma->SetOption("P");
808   hESDResidualXPerDESigma->SetMarkerStyle(kFullDotMedium);
809   hESDResidualXPerDESigma->SetMarkerColor(kRed);
810   Add2ESDsList(hESDResidualXPerDESigma, kESDResidualXPerDESigma,forExpert);
811   
812   TH1F* hESDResidualYPerDESigma = new TH1F("hESDResidualYPerDESigma", "cluster-track residual-Y per DE: sigma;DetElem ID;#sigma_{Y} (cm)", nDE, 0, nDE);
813   hESDResidualYPerDESigma->SetOption("P");
814   hESDResidualYPerDESigma->SetMarkerStyle(kFullDotMedium);
815   hESDResidualYPerDESigma->SetMarkerColor(kRed);
816   Add2ESDsList(hESDResidualYPerDESigma, kESDResidualYPerDESigma,forExpert);
817   
818   TH1F* hESDLocalChi2XPerDEMean = new TH1F("hESDLocalChi2XPerDEMean", "local chi2-X per DE: mean;DetElem ID;<local #chi^{2}_{X}>", nDE, 0, nDE);
819   hESDLocalChi2XPerDEMean->SetOption("P");
820   hESDLocalChi2XPerDEMean->SetMarkerStyle(kFullDotMedium);
821   hESDLocalChi2XPerDEMean->SetMarkerColor(kRed);
822   Add2ESDsList(hESDLocalChi2XPerDEMean, kESDLocalChi2XPerDEMean,forExpert);
823   
824   TH1F* hESDLocalChi2YPerDEMean = new TH1F("hESDLocalChi2YPerDEMean", "local chi2-Y per DE: mean;DetElem ID;<local #chi^{2}_{Y}>", nDE, 0, nDE);
825   hESDLocalChi2YPerDEMean->SetOption("P");
826   hESDLocalChi2YPerDEMean->SetMarkerStyle(kFullDotMedium);
827   hESDLocalChi2YPerDEMean->SetMarkerColor(kRed);
828   Add2ESDsList(hESDLocalChi2YPerDEMean, kESDLocalChi2YPerDEMean,forExpert);
829   
830   // temporary histograms
831   fhESDnTotClustersPerCh = new TH1F("fhESDnTotClustersPerCh", "total number of associated clusters per chamber;chamber ID", nCh, 0, nCh);
832   fhESDnTotClustersPerCh->SetDirectory(0);
833   fhESDnTotClustersPerDE = new TH1F("fhESDnTotClustersPerDE", "total number of associated clusters per DE;DetElem ID", nDE, 0, nDE);
834   fhESDnTotClustersPerDE->SetDirectory(0);
835   fhESDnTotFullClustersPerDE = new TH1F("fhESDnTotFullClustersPerDE", "total number of associated clusters containing pad info per DE;DetElem ID", nDE, 0, nDE);
836   fhESDnTotFullClustersPerDE->SetDirectory(0);
837   fhESDSumClusterChargePerDE = new TH1F("fhESDSumClusterChargePerDE", "sum of cluster charge per DE;DetElem ID;ADC counts", nDE, 0, nDE);
838   fhESDSumClusterChargePerDE->SetDirectory(0);
839   fhESDSumClusterSizePerDE = new TH1F("fhESDSumClusterSizePerDE", "sum of cluster size per DE;DetElem ID;averaged number of associated pads", nDE, 0, nDE);
840   fhESDSumClusterSizePerDE->SetDirectory(0);
841   fhESDSumResidualXPerDE = new TH1F("fhESDSumResidualXPerDE", "sum of cluster-track residual-X per DE;DetElem ID", nDE, 0, nDE);
842   fhESDSumResidualXPerDE->SetDirectory(0);
843   fhESDSumResidualYPerDE = new TH1F("fhESDSumResidualYPerDE", "sum of cluster-track residual-Y per DE;DetElem ID", nDE, 0, nDE);
844   fhESDSumResidualYPerDE->SetDirectory(0);
845   fhESDSumResidualX2PerDE = new TH1F("fhESDSumResidualX2PerDE", "sum of cluster-track residual-X**2 per DE;DetElem ID", nDE, 0, nDE);
846   fhESDSumResidualX2PerDE->SetDirectory(0);
847   fhESDSumResidualY2PerDE = new TH1F("fhESDSumResidualY2PerDE", "sum of cluster-track residual-Y**2 per DE;DetElem ID", nDE, 0, nDE);
848   fhESDSumResidualY2PerDE->SetDirectory(0);
849   fhESDSumLocalChi2XPerDE = new TH1F("fhESDSumLocalChi2XPerDE", "sum of local chi2-X per DE;DetElem ID", nDE, 0, nDE);
850   fhESDSumLocalChi2XPerDE->SetDirectory(0);
851   fhESDSumLocalChi2YPerDE = new TH1F("fhESDSumLocalChi2YPerDE", "sum of local chi2-Y per DE;DetElem ID", nDE, 0, nDE);
852   fhESDSumLocalChi2YPerDE->SetDirectory(0);
853   
854   fIsInitESDs =  kTRUE;
855 }
856
857 //____________________________________________________________________________
858 void AliMUONQADataMakerRec::MakeRaws(AliRawReader* rawReader)
859 {
860     /// make QA for rawdata
861
862     if ( ! fIsInitRaws ) {
863       AliWarningStream() 
864         << "Skipping function due to a failure in Init" << endl;
865       return;
866     }    
867
868   if ( rawReader->GetType() == AliRawEventHeaderBase::kPhysicsEvent ) 
869   {
870     rawReader->Reset();
871     MakeRawsTracker(rawReader);
872   }
873   
874   rawReader->Reset();    
875   MakeRawsTrigger(rawReader);
876 }
877
878 //____________________________________________________________________________
879 void AliMUONQADataMakerRec::MakeRawsTracker(AliRawReader* rawReader)
880 {
881         /// make QA for rawdata tracker
882         
883         ((AliMUONTrackerCalibratedDataMaker*)fTrackerDataMaker)->SetRawReader(rawReader);
884         
885         fTrackerDataMaker->ProcessEvent();
886 }
887
888 //____________________________________________________________________________
889 void AliMUONQADataMakerRec::MakeRawsTrigger(AliRawReader* rawReader)
890 {
891         /// make QA for rawdata trigger
892         
893     // Get trigger scalers
894
895     Int_t loCircuit=0;
896     AliMpCDB::LoadDDLStore();
897
898     AliMUONRawStreamTrigger rawStreamTrig(rawReader);
899     while (rawStreamTrig.NextDDL()) 
900     {
901       // If not a scaler event, do nothing
902       Bool_t scalerEvent =  rawReader->GetDataHeader()->GetL1TriggerMessage() & 0x1;
903       if(!scalerEvent) break;
904
905       AliMUONDDLTrigger* ddlTrigger = rawStreamTrig.GetDDLTrigger();
906       AliMUONDarcHeader* darcHeader = ddlTrigger->GetDarcHeader();
907
908       Int_t nReg = darcHeader->GetRegHeaderEntries();
909     
910       for(Int_t iReg = 0; iReg < nReg ;iReg++)
911       {   //reg loop
912
913         // crate info  
914         AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->
915           GetTriggerCrate(rawStreamTrig.GetDDL(), iReg);
916
917         AliMUONRegHeader* regHeader =  darcHeader->GetRegHeaderEntry(iReg);
918
919         // loop over local structures
920         Int_t nLocal = regHeader->GetLocalEntries();
921         for(Int_t iLocal = 0; iLocal < nLocal; iLocal++) 
922         {
923           AliMUONLocalStruct* localStruct = regHeader->GetLocalEntry(iLocal);
924         
925           // if card exist
926           if (!localStruct) continue;
927           
928           loCircuit = crate->GetLocalBoardId(localStruct->GetId());
929
930           if ( !loCircuit ) continue; // empty slot
931
932           AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(loCircuit, false);
933
934           // skip copy cards
935           if( !localBoard->IsNotified()) 
936             continue;
937
938           Int_t cathode = localStruct->GetComptXY()%2;
939
940           ERaw hindex = (cathode==0) ? kTriggerScalersBP : kTriggerScalersNBP;
941
942           // loop over strips
943           for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
944             if(localStruct->GetXY1(ibitxy) > 0)
945               ((TH3F*)GetRawsData(hindex))->Fill(11+0, loCircuit, ibitxy, 2*localStruct->GetXY1(ibitxy));
946             if(localStruct->GetXY2(ibitxy) > 0)
947               ((TH3F*)GetRawsData(hindex))->Fill(11+1, loCircuit, ibitxy, 2*localStruct->GetXY2(ibitxy));
948             if(localStruct->GetXY3(ibitxy) > 0)
949               ((TH3F*)GetRawsData(hindex))->Fill(11+2, loCircuit, ibitxy, 2*localStruct->GetXY3(ibitxy));
950             if(localStruct->GetXY4(ibitxy) > 0)
951               ((TH3F*)GetRawsData(hindex))->Fill(11+3, loCircuit, ibitxy, 2*localStruct->GetXY4(ibitxy));
952           } // loop on strips
953         } // iLocal
954       } // iReg
955     } // NextDDL
956 }
957
958 //____________________________________________________________________________
959 void AliMUONQADataMakerRec::MakeRecPoints(TTree* clustersTree)
960 {
961         /// Fill histograms from treeR
962         
963         if (fIsInitRecPointsTracker) MakeRecPointsTracker(clustersTree);
964         if (fIsInitRecPointsTrigger) MakeRecPointsTrigger(clustersTree);
965 }
966
967 //____________________________________________________________________________
968 void AliMUONQADataMakerRec::MakeRecPointsTracker(TTree* clustersTree)
969 {
970         /// Fill histograms related to tracker clusters 
971         
972         // First things first : do we have clusters in the TreeR ?
973         // In "normal" production mode, it should be perfectly normal
974         // *not* to have them.
975         // But if for some reason we de-activated the combined tracking,
976         // then we have clusters in TreeR, so let's take that opportunity
977         // to QA them...
978         
979         if (!fClusterStore)
980         {
981                 AliCodeTimerAuto("ClusterStore creation");
982                 fClusterStore = AliMUONVClusterStore::Create(*clustersTree);
983                 if (!fClusterStore) 
984                 {
985                         fIsInitRecPointsTracker = kFALSE;
986                         return;
987                 }
988         }
989         
990         AliCodeTimerAuto("");
991         
992         fClusterStore->Connect(*clustersTree,kFALSE);
993         clustersTree->GetEvent(0);
994
995         TIter next(fClusterStore->CreateIterator());
996         AliMUONVCluster* cluster;
997         
998         while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) )
999         {
1000                 Int_t detElemId = cluster->GetDetElemId();
1001                 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1002                 
1003                 GetRecPointsData(kTrackerNumberOfClustersPerDE)->Fill(detElemId);
1004                 GetRecPointsData(kTrackerClusterChargePerDE+detElemId)->Fill(cluster->GetCharge());
1005                 GetRecPointsData(kTrackerClusterMultiplicityPerDE+detElemId)->Fill(cluster->GetNDigits());
1006
1007                 GetRecPointsData(kTrackerNumberOfClustersPerChamber)->Fill(chamberId);
1008                 GetRecPointsData(kTrackerClusterChargePerChamber+chamberId)->Fill(cluster->GetCharge());
1009                 GetRecPointsData(kTrackerClusterMultiplicityPerChamber+chamberId)->Fill(cluster->GetNDigits());
1010                 
1011         }
1012         
1013         fClusterStore->Clear();
1014 }
1015
1016 //____________________________________________________________________________
1017 void AliMUONQADataMakerRec::MakeRecPointsTrigger(TTree* clustersTree)
1018 {
1019         /// makes data from trigger response
1020       
1021     // Fired pads info
1022     fDigitStore->Clear();
1023
1024     if (!fTriggerStore) fTriggerStore = AliMUONVTriggerStore::Create(*clustersTree);
1025     fTriggerStore->Clear();
1026     fTriggerStore->Connect(*clustersTree, false);
1027     clustersTree->GetEvent(0);
1028
1029     AliMUONLocalTrigger* locTrg;
1030     TIter nextLoc(fTriggerStore->CreateLocalIterator());
1031
1032     while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(nextLoc()) ) ) 
1033     {
1034       if (locTrg->IsNull()) continue;
1035    
1036       TArrayS xyPattern[2];
1037       locTrg->GetXPattern(xyPattern[0]);
1038       locTrg->GetYPattern(xyPattern[1]);
1039
1040       Int_t nBoard = locTrg->LoCircuit();
1041
1042       Bool_t xTrig=locTrg->IsTrigX();
1043       Bool_t yTrig=locTrg->IsTrigY();
1044     
1045       if (xTrig && yTrig)
1046         ((TH1F*)GetRecPointsData(kTriggeredBoards))->Fill(nBoard);
1047
1048       fDigitMaker->TriggerDigits(nBoard, xyPattern, *fDigitStore);
1049     }
1050
1051     TIter nextDigit(fDigitStore->CreateIterator());
1052     AliMUONVDigit* mDigit;
1053     while ( ( mDigit = static_cast<AliMUONVDigit*>(nextDigit()) ) )
1054     {
1055       Int_t detElemId = mDigit->DetElemId();
1056       Int_t ch = detElemId/100;
1057       Int_t localBoard = mDigit->ManuId();
1058       Int_t channel = mDigit->ManuChannel();
1059       Int_t cathode = mDigit->Cathode();
1060       ERecPoints hindex 
1061         = ( cathode == 0 ) ? kTriggerDigitsBendPlane : kTriggerDigitsNonBendPlane;
1062       
1063       ((TH3F*)GetRecPointsData(hindex))->Fill(ch, localBoard, channel);
1064     }
1065 }
1066
1067 //____________________________________________________________________________
1068 void AliMUONQADataMakerRec::MakeESDs(AliESDEvent* esd)
1069 {
1070   /// make QA data from ESDs
1071   
1072   if ( ! fIsInitESDs ) {
1073     AliWarningStream() 
1074     << "Skipping function due to a failure in Init" << endl;
1075     return;
1076   }    
1077   
1078   // use event specie from RecoParam
1079   AliRecoParam::EventSpecie_t savedEventSpecie = fEventSpecie;
1080   if (GetRecoParam()) SetEventSpecie(static_cast<AliRecoParam::EventSpecie_t>(GetRecoParam()->GetEventSpecie()));
1081   
1082   // load ESD event in the interface
1083   AliMUONESDInterface esdInterface;
1084   if (GetRecoParam()) AliMUONESDInterface::ResetTracker(GetRecoParam());
1085   else AliError("Unable to get recoParam: use default ones for residual calculation");
1086   esdInterface.LoadEvent(*esd);
1087   
1088   GetESDsData(kESDnTracks)->Fill(esdInterface.GetNTracks());
1089   
1090   Int_t nTrackMatchTrig = 0;
1091   
1092   // loop over tracks
1093   Int_t nTracks = (Int_t) esd->GetNumberOfMuonTracks(); 
1094   for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack) {
1095     
1096     // get the ESD track and skip "ghosts"
1097     AliESDMuonTrack* esdTrack = esd->GetMuonTrack(iTrack);
1098     if (!esdTrack->ContainTrackerData()) continue;
1099     
1100     // get corresponding MUON track
1101     AliMUONTrack* track = esdInterface.FindTrack(esdTrack->GetUniqueID());
1102     
1103     if (esdTrack->ContainTriggerData()) nTrackMatchTrig++;
1104     
1105     GetESDsData(kESDMomentum)->Fill(esdTrack->P());
1106     GetESDsData(kESDPt)->Fill(esdTrack->Pt());
1107     GetESDsData(kESDRapidity)->Fill(esdTrack->Y());
1108     GetESDsData(kESDChi2)->Fill(track->GetNormalizedChi2());
1109     GetESDsData(kESDProbChi2)->Fill(TMath::Prob(track->GetGlobalChi2(),track->GetNDF()));
1110     GetESDsData(kESDnClustersPerTrack)->Fill(track->GetNClusters());
1111     
1112     // loop over clusters
1113     AliMUONTrackParam* trackParam = static_cast<AliMUONTrackParam*>(track->GetTrackParamAtCluster()->First());
1114     while (trackParam) {
1115       
1116       AliMUONVCluster* cluster = trackParam->GetClusterPtr();
1117       Int_t chId = cluster->GetChamberId();
1118       Int_t deID = cluster->GetDetElemId();
1119       Double_t residualX = cluster->GetX() - trackParam->GetNonBendingCoor();
1120       Double_t residualY = cluster->GetY() - trackParam->GetBendingCoor();
1121       Double_t localChi2X = (cluster->GetErrX2() > 0.) ? residualX*residualX/cluster->GetErrX2() : 0.;
1122       Double_t localChi2Y = (cluster->GetErrY2() > 0.) ? residualY*residualY/cluster->GetErrY2() : 0.;
1123       
1124       GetESDsData(kESDClusterHitMap+chId)->Fill(cluster->GetX(), cluster->GetY());
1125       
1126       fhESDnTotClustersPerCh->Fill(chId);
1127       fhESDnTotClustersPerDE->Fill(deID);
1128       
1129       GetESDsData(kESDClusterChargeInCh+chId)->Fill(cluster->GetCharge());
1130       fhESDSumClusterChargePerDE->Fill(deID, cluster->GetCharge());
1131       
1132       if (cluster->GetNDigits() > 0) { // discard clusters with pad not stored in ESD
1133         fhESDnTotFullClustersPerDE->Fill(deID);
1134         GetESDsData(kESDClusterSizeInCh+chId)->Fill(cluster->GetNDigits());
1135         fhESDSumClusterSizePerDE->Fill(deID, cluster->GetNDigits());
1136       }
1137       
1138       GetESDsData(kESDResidualXInCh+chId)->Fill(residualX);
1139       GetESDsData(kESDResidualYInCh+chId)->Fill(residualY);
1140       fhESDSumResidualXPerDE->Fill(deID, residualX);
1141       fhESDSumResidualYPerDE->Fill(deID, residualY);
1142       fhESDSumResidualX2PerDE->Fill(deID, residualX*residualX);
1143       fhESDSumResidualY2PerDE->Fill(deID, residualY*residualY);
1144       
1145       GetESDsData(kESDLocalChi2XInCh+chId)->Fill(localChi2X);
1146       GetESDsData(kESDLocalChi2YInCh+chId)->Fill(localChi2Y);
1147       fhESDSumLocalChi2XPerDE->Fill(deID, localChi2X);
1148       fhESDSumLocalChi2YPerDE->Fill(deID, localChi2Y);
1149       
1150       trackParam = static_cast<AliMUONTrackParam*>(track->GetTrackParamAtCluster()->After(trackParam));
1151     }
1152     
1153   }
1154   
1155   GetESDsData(kESDMatchTrig)->Fill(nTrackMatchTrig);
1156   
1157   // restore event specie
1158   SetEventSpecie(savedEventSpecie);
1159   
1160 }
1161
1162 //____________________________________________________________________________ 
1163 void AliMUONQADataMakerRec::StartOfDetectorCycle()
1164 {
1165     /// Detector specific actions at start of cycle
1166   
1167 }
1168
1169 //____________________________________________________________________________ 
1170 void AliMUONQADataMakerRec::DisplayTriggerInfo(AliQA::TASKINDEX_t task)
1171 {
1172   //
1173   /// Display trigger information in a user-friendly way:
1174   /// from local board and strip numbers to their position on chambers
1175   //
1176
1177   if(task!=AliQA::kRECPOINTS && task!=AliQA::kRAWS) return;
1178
1179   AliMUONTriggerDisplay triggerDisplay;
1180   
1181   TH3F* histoStrips=0x0;
1182   TH2F* histoDisplayStrips=0x0;
1183
1184   for (Int_t iCath = 0; iCath < AliMpConstants::NofCathodes(); iCath++)
1185   {
1186     if(task==AliQA::kRECPOINTS){
1187       ERecPoints hindex 
1188         = ( iCath == 0 ) ? kTriggerDigitsBendPlane : kTriggerDigitsNonBendPlane;
1189       histoStrips = (TH3F*)GetRecPointsData(hindex);
1190     }
1191     else if(task==AliQA::kRAWS){
1192       ERaw hindex 
1193         = ( iCath == 0 ) ? kTriggerScalersBP : kTriggerScalersNBP;
1194       histoStrips = (TH3F*)GetRawsData(hindex);
1195       if(histoStrips->GetEntries()==0) continue; // No scalers found
1196     }
1197     
1198     for (Int_t iChamber = 0; iChamber < AliMpConstants::NofTriggerChambers(); iChamber++)
1199     {
1200       if(task==AliQA::kRECPOINTS){
1201         histoDisplayStrips = (TH2F*)GetRecPointsData(kTriggerDigitsDisplay + AliMpConstants::NofTriggerChambers()*iCath + iChamber);
1202       }
1203       else if(task==AliQA::kRAWS){
1204         histoDisplayStrips = (TH2F*)GetRawsData(kTriggerScalersDisplay + AliMpConstants::NofTriggerChambers()*iCath + iChamber);
1205       }
1206       Int_t bin = histoStrips->GetXaxis()->FindBin(11+iChamber);
1207       histoStrips->GetXaxis()->SetRange(bin,bin);
1208       TH2F* inputHisto = (TH2F*)histoStrips->Project3D("zy");
1209       triggerDisplay.FillDisplayHistogram(inputHisto, histoDisplayStrips, AliMUONTriggerDisplay::kDisplayStrips, iCath, iChamber);
1210     } // iChamber
1211   } // iCath
1212
1213   if(task==AliQA::kRAWS){    
1214     TH2F* histoI  = (TH2F*) GetRawsData(kTriggerRPCi);
1215     TH2F* histoHV = (TH2F*) GetRawsData(kTriggerRPChv);
1216     FillTriggerDCSHistos();
1217     for (Int_t iChamber = 0; iChamber < AliMpConstants::NofTriggerChambers(); iChamber++) {
1218       Int_t bin = histoI->GetXaxis()->FindBin(11+iChamber);
1219       TH2F* histoDisplayI = (TH2F*)GetRawsData(kTriggerIDisplay + iChamber);
1220       triggerDisplay.FillDisplayHistogram(histoI->ProjectionY("_px", bin, bin), histoDisplayI, AliMUONTriggerDisplay::kDisplaySlats, 0, iChamber);
1221       TH2F* histoDisplayHV = (TH2F*)GetRawsData(kTriggerHVDisplay + iChamber);
1222       bin = histoHV->GetXaxis()->FindBin(11+iChamber);
1223       triggerDisplay.FillDisplayHistogram(histoHV->ProjectionY("_px", bin, bin), histoDisplayHV, AliMUONTriggerDisplay::kDisplaySlats, 0, iChamber);
1224     }
1225   }
1226
1227   if(task==AliQA::kRECPOINTS){
1228     TH1F* histoBoards = (TH1F*)GetRecPointsData(kTriggeredBoards);
1229     TH2F* histoDisplayBoards = (TH2F*)GetRecPointsData(kTriggerBoardsDisplay);
1230     triggerDisplay.FillDisplayHistogram(histoBoards, histoDisplayBoards, AliMUONTriggerDisplay::kDisplayBoards, 0, 0);
1231   }
1232 }
1233
1234
1235 //_____________________________________________________________________________
1236 Bool_t 
1237 AliMUONQADataMakerRec::FillTriggerDCSHistos()
1238 {
1239   /// Get HV and currents values for one trigger chamber
1240   
1241   AliCodeTimerAuto("");
1242
1243   AliMpDEIterator deIt;
1244
1245   deIt.First();
1246
1247   AliMUONCalibrationData calibrationData(AliCDBManager::Instance()->GetRun());
1248
1249   TMap* triggerDcsMap = calibrationData.TriggerDCS();
1250
1251   AliMpDCSNamer triggerDcsNamer("TRIGGER");
1252
1253   TH2* currHisto = 0x0;
1254
1255   Bool_t error = kFALSE;
1256   
1257   while ( !deIt.IsDone() )
1258   {
1259     Int_t detElemId = deIt.CurrentDEId();
1260     
1261     if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStationTrigger) {
1262
1263       Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
1264       Int_t slat = detElemId%100;
1265
1266       for(Int_t iMeas=0; iMeas<AliMpDCSNamer::kNDCSMeas; iMeas++){
1267         TString currAlias = triggerDcsNamer.DCSChannelName(detElemId, 0, iMeas);
1268
1269         AliDebug(2, Form("\nDetElemId %i   dcsAlias %s", detElemId, currAlias.Data()));
1270
1271         TPair* triggerDcsPair = static_cast<TPair*>(triggerDcsMap->FindObject(currAlias.Data()));
1272
1273         if (!triggerDcsPair)
1274         {
1275           AliError(Form("Did not find expected alias (%s) for DE %d",
1276                         currAlias.Data(),detElemId));  
1277           error = kTRUE;
1278         }
1279         else
1280         {
1281           TObjArray* values = static_cast<TObjArray*>(triggerDcsPair->Value());
1282           if (!values)
1283           {
1284             AliError(Form("Could not get values for alias %s",currAlias.Data()));
1285             error = kTRUE;
1286           }
1287           else
1288           {
1289             TIter next(values);
1290             AliDCSValue* val;
1291
1292             while ( ( val = static_cast<AliDCSValue*>(next()) ) )
1293             {
1294               Float_t hvi = val->GetFloat();
1295
1296               AliDebug(2, Form("Value %f", hvi));
1297
1298               switch(iMeas){
1299               case AliMpDCSNamer::kDCSI:
1300                 currHisto = (TH2F*) GetRawsData(kTriggerRPCi);
1301                 break;
1302               case AliMpDCSNamer::kDCSHV:
1303                 currHisto = (TH2F*) GetRawsData(kTriggerRPChv);
1304                 break;
1305               } 
1306               Int_t binX = currHisto->GetXaxis()->FindBin(iChamber+1);
1307               Int_t binY = currHisto->GetYaxis()->FindBin(slat);
1308               currHisto->SetBinContent(binX, binY, hvi);
1309             } // loop on values
1310           } // if (!values)
1311         } // if (!triggerDcsPair)
1312       } // loop on measured types (HV and currents)
1313     } // if (stationType == kStationTrigger)
1314
1315     deIt.Next();
1316   }
1317   return error;
1318 }
1319
1320 //____________________________________________________________________________ 
1321 AliMUONVTrackerData* AliMUONQADataMakerRec::GetTrackerData() const
1322
1323   
1324   return fTrackerDataMaker->Data(); 
1325   
1326 }