]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG3/muondep/AliAnalysisTaskMuonResolution.cxx
Coverity
[u/mrichter/AliRoot.git] / PWG3 / muondep / AliAnalysisTaskMuonResolution.cxx
CommitLineData
7cbb1928 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// ROOT includes
17#include <TFile.h>
18#include <TTree.h>
19#include <TH1F.h>
20#include <TH2F.h>
21#include <TMultiGraph.h>
22#include <TGraphErrors.h>
23#include <TCanvas.h>
24#include <TLegend.h>
25#include <Riostream.h>
26#include <TString.h>
27#include <TGeoManager.h>
00612ffc 28#include <TList.h>
29#include <TObjString.h>
30#include <TRegexp.h>
7cbb1928 31
32// STEER includes
33#include "AliESDEvent.h"
34#include "AliESDMuonTrack.h"
35#include "AliCDBManager.h"
36#include "AliCDBStorage.h"
37#include "AliGeomManager.h"
38
39// ANALYSIS includes
7cbb1928 40#include "AliAnalysisDataSlot.h"
41#include "AliAnalysisManager.h"
42#include "AliInputEventHandler.h"
43#include "AliAnalysisTaskMuonResolution.h"
44
45// MUON includes
46#include "AliMUONCDB.h"
47#include "AliMUONRecoParam.h"
48#include "AliMUONESDInterface.h"
49#include "AliMUONVTrackReconstructor.h"
50#include "AliMUONTrack.h"
51#include "AliMUONTrackParam.h"
52#include "AliMUONTrackExtrap.h"
53#include "AliMUONVCluster.h"
54#include "AliMUONGeometryTransformer.h"
55#include "AliMUONGeometryModuleTransformer.h"
56#include "AliMUONGeometryDetElement.h"
57#include "AliMpDEIterator.h"
58
59#ifndef SafeDelete
60#define SafeDelete(x) if (x != NULL) { delete x; x = NULL; }
61#endif
62
63ClassImp(AliAnalysisTaskMuonResolution)
64
65const Int_t AliAnalysisTaskMuonResolution::fgkMinEntries = 10;
66
67//________________________________________________________________________
68AliAnalysisTaskMuonResolution::AliAnalysisTaskMuonResolution() :
69 AliAnalysisTaskSE(),
70 fResiduals(NULL),
71 fResidualsVsP(NULL),
72 fLocalChi2(NULL),
73 fChamberRes(NULL),
74 fTrackRes(NULL),
75 fCanvases(NULL),
00612ffc 76 fDefaultStorage(""),
7cbb1928 77 fNEvents(0),
00612ffc 78 fShowProgressBar(kFALSE),
79 fPrintClResPerCh(kFALSE),
80 fPrintClResPerDE(kFALSE),
81 fGaus(NULL),
7cbb1928 82 fMinMomentum(0.),
83 fSelectPhysics(kFALSE),
84 fMatchTrig(kFALSE),
00612ffc 85 fApplyAccCut(kFALSE),
86 fSelectTrigger(kFALSE),
87 fTriggerMask(0),
7cbb1928 88 fExtrapMode(1),
89 fCorrectForSystematics(kTRUE),
90 fOCDBLoaded(kFALSE),
91 fNDE(0),
92 fReAlign(kFALSE),
93 fOldAlignStorage(""),
94 fNewAlignStorage(""),
95 fOldGeoTransformer(NULL),
00612ffc 96 fNewGeoTransformer(NULL),
97 fSelectTriggerClass(NULL)
7cbb1928 98{
99 /// Default constructor
100}
101
102//________________________________________________________________________
103AliAnalysisTaskMuonResolution::AliAnalysisTaskMuonResolution(const char *name) :
104 AliAnalysisTaskSE(name),
105 fResiduals(NULL),
106 fResidualsVsP(NULL),
107 fLocalChi2(NULL),
108 fChamberRes(NULL),
109 fTrackRes(NULL),
110 fCanvases(NULL),
00612ffc 111 fDefaultStorage("raw://"),
7cbb1928 112 fNEvents(0),
00612ffc 113 fShowProgressBar(kFALSE),
114 fPrintClResPerCh(kFALSE),
115 fPrintClResPerDE(kFALSE),
116 fGaus(NULL),
7cbb1928 117 fMinMomentum(0.),
118 fSelectPhysics(kFALSE),
119 fMatchTrig(kFALSE),
00612ffc 120 fApplyAccCut(kFALSE),
121 fSelectTrigger(kFALSE),
122 fTriggerMask(0),
7cbb1928 123 fExtrapMode(1),
124 fCorrectForSystematics(kTRUE),
125 fOCDBLoaded(kFALSE),
126 fNDE(0),
127 fReAlign(kFALSE),
128 fOldAlignStorage(""),
129 fNewAlignStorage(""),
130 fOldGeoTransformer(NULL),
00612ffc 131 fNewGeoTransformer(NULL),
132 fSelectTriggerClass(NULL)
7cbb1928 133{
134 /// Constructor
135
136 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) SetStartingResolution(i, -1., -1.);
137
00612ffc 138 FitResiduals();
139
7cbb1928 140 // Output slot #1 writes into a TObjArray container
141 DefineOutput(1,TObjArray::Class());
142 // Output slot #2 writes into a TObjArray container
143 DefineOutput(2,TObjArray::Class());
144 // Output slot #3 writes into a TObjArray container
145 DefineOutput(3,TObjArray::Class());
146 // Output slot #4 writes into a TObjArray container
147 DefineOutput(4,TObjArray::Class());
148 // Output slot #5 writes into a TObjArray container
149 DefineOutput(5,TObjArray::Class());
150}
151
152//________________________________________________________________________
153AliAnalysisTaskMuonResolution::~AliAnalysisTaskMuonResolution()
154{
155 /// Destructor
00612ffc 156 if (!AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
157 SafeDelete(fResiduals);
158 SafeDelete(fResidualsVsP);
159 SafeDelete(fTrackRes);
160 }
7cbb1928 161 SafeDelete(fChamberRes);
7cbb1928 162 SafeDelete(fCanvases);
00612ffc 163 SafeDelete(fGaus);
7cbb1928 164 SafeDelete(fOldGeoTransformer);
165 SafeDelete(fNewGeoTransformer);
00612ffc 166 SafeDelete(fSelectTriggerClass);
7cbb1928 167}
168
169//___________________________________________________________________________
170void AliAnalysisTaskMuonResolution::UserCreateOutputObjects()
171{
172 /// Create histograms
173
174 // do it once the OCDB has been loaded (i.e. from NotifyRun())
175 if (!fOCDBLoaded) return;
176
00612ffc 177 // set the list of trigger classes that can be selected to fill histograms (in case the physics selection is not used)
178 fSelectTriggerClass = new TList();
179 fSelectTriggerClass->SetOwner();
180 fSelectTriggerClass->AddLast(new TObjString(" CINT1B-ABCE-NOPF-ALL ")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
181 fSelectTriggerClass->AddLast(new TObjString(" CMUS1B-ABCE-NOPF-MUON ")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUON);
182 fSelectTriggerClass->AddLast(new TObjString(" CINT1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
183 fSelectTriggerClass->AddLast(new TObjString(" CMUS1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUON);
184 fSelectTriggerClass->AddLast(new TObjString(" CSH1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kHighMult);
185
7cbb1928 186 fResiduals = new TObjArray(1000);
187 fResiduals->SetOwner();
188 fResidualsVsP = new TObjArray(1000);
189 fResidualsVsP->SetOwner();
190 fTrackRes = new TObjArray(1000);
191 fTrackRes->SetOwner();
192 TH2F* h2;
193
194 // find the highest chamber resolution and set histogram bins
195 const AliMUONRecoParam* recoParam = AliMUONESDInterface::GetTracker()->GetRecoParam();
196 Double_t maxSigma[2] = {-1., -1.};
197 for (Int_t i = 0; i < 10; i++) {
198 if (recoParam->GetDefaultNonBendingReso(i) > maxSigma[0]) maxSigma[0] = recoParam->GetDefaultNonBendingReso(i);
199 if (recoParam->GetDefaultBendingReso(i) > maxSigma[1]) maxSigma[1] = recoParam->GetDefaultBendingReso(i);
200 }
201 const char* axes[2] = {"X", "Y"};
00612ffc 202 const Int_t nBins = 5000;
7cbb1928 203 const Int_t nSigma = 10;
204 const Int_t pNBins = 20;
205 const Double_t pEdges[2] = {0., 50.};
206
207 for (Int_t ia = 0; ia < 2; ia++) {
208
209 Double_t maxRes = nSigma*maxSigma[ia];
210
211 // List of residual histos
212 h2 = new TH2F(Form("hResidual%sPerCh_ClusterIn",axes[ia]), Form("cluster-track residual-%s distribution per chamber (cluster attached to the track);chamber ID;#Delta_{%s} (cm)",axes[ia],axes[ia]), 10, 0.5, 10.5, nBins, -maxRes, maxRes);
f4d9245c 213 fResiduals->AddAtAndExpand(h2, kResidualPerChClusterIn+ia);
7cbb1928 214 h2 = new TH2F(Form("hResidual%sPerCh_ClusterOut",axes[ia]), Form("cluster-track residual-%s distribution per chamber (cluster not attached to the track);chamber ID;#Delta_{%s} (cm)",axes[ia],axes[ia]), 10, 0.5, 10.5, nBins, -2.*maxRes, 2.*maxRes);
f4d9245c 215 fResiduals->AddAtAndExpand(h2, kResidualPerChClusterOut+ia);
7cbb1928 216
217 h2 = new TH2F(Form("hResidual%sPerHalfCh_ClusterIn",axes[ia]), Form("cluster-track residual-%s distribution per half chamber (cluster attached to the track);half chamber ID;#Delta_{%s} (cm)",axes[ia],axes[ia]), 20, 0.5, 20.5, nBins, -maxRes, maxRes);
f4d9245c 218 fResiduals->AddAtAndExpand(h2, kResidualPerHalfChClusterIn+ia);
7cbb1928 219 h2 = new TH2F(Form("hResidual%sPerHalfCh_ClusterOut",axes[ia]), Form("cluster-track residual-%s distribution per half chamber (cluster not attached to the track);half chamber ID;#Delta_{%s} (cm)",axes[ia],axes[ia]), 20, 0.5, 20.5, nBins, -2.*maxRes, 2.*maxRes);
f4d9245c 220 fResiduals->AddAtAndExpand(h2, kResidualPerHalfChClusterOut+ia);
7cbb1928 221
222 h2 = new TH2F(Form("hResidual%sPerDE_ClusterIn",axes[ia]), Form("cluster-track residual-%s distribution per DE (cluster not attached to the track);DE ID;#Delta_{%s} (cm)",axes[ia],axes[ia]), fNDE, 0.5, fNDE+0.5, nBins, -maxRes, maxRes);
223 for (Int_t i = 1; i <= fNDE; i++) h2->GetXaxis()->SetBinLabel(i, Form("%d",fDEIds[i]));
f4d9245c 224 fResiduals->AddAtAndExpand(h2, kResidualPerDEClusterIn+ia);
7cbb1928 225 h2 = new TH2F(Form("hResidual%sPerDE_ClusterOut",axes[ia]), Form("cluster-track residual-%s distribution per DE (cluster not attached to the track);DE ID;#Delta_{%s} (cm)",axes[ia],axes[ia]), fNDE, 0.5, fNDE+0.5, nBins, -2.*maxRes, 2.*maxRes);
226 for (Int_t i = 1; i <= fNDE; i++) h2->GetXaxis()->SetBinLabel(i, Form("%d",fDEIds[i]));
f4d9245c 227 fResiduals->AddAtAndExpand(h2, kResidualPerDEClusterOut+ia);
7cbb1928 228
229 h2 = new TH2F(Form("hTrackRes%sPerCh",axes[ia]), Form("track #sigma_{%s} per Ch;chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]), 10, 0.5, 10.5, nBins, 0., maxRes);
230 fResiduals->AddAtAndExpand(h2, kTrackResPerCh+ia);
231 h2 = new TH2F(Form("hTrackRes%sPerHalfCh",axes[ia]), Form("track #sigma_{%s} per half Ch;half chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]), 20, 0.5, 20.5, nBins, 0., maxRes);
232 fResiduals->AddAtAndExpand(h2, kTrackResPerHalfCh+ia);
233 h2 = new TH2F(Form("hTrackRes%sPerDE",axes[ia]), Form("track #sigma_{%s} per DE;DE ID;#sigma_{%s} (cm)",axes[ia],axes[ia]), fNDE, 0.5, fNDE+0.5, nBins, 0., maxRes);
234 for (Int_t i = 1; i <= fNDE; i++) h2->GetXaxis()->SetBinLabel(i, Form("%d",fDEIds[i]));
235 fResiduals->AddAtAndExpand(h2, kTrackResPerDE+ia);
236
237 h2 = new TH2F(Form("hMCS%sPerCh",axes[ia]), Form("MCS %s-dispersion of extrapolated track per Ch;chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]), 10, 0.5, 10.5, nBins, 0., 0.2);
238 fResiduals->AddAtAndExpand(h2, kMCSPerCh+ia);
239 h2 = new TH2F(Form("hMCS%sPerHalfCh",axes[ia]), Form("MCS %s-dispersion of extrapolated track per half Ch;half chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]), 20, 0.5, 20.5, nBins, 0., 0.2);
240 fResiduals->AddAtAndExpand(h2, kMCSPerHalfCh+ia);
241 h2 = new TH2F(Form("hMCS%sPerDE",axes[ia]), Form("MCS %s-dispersion of extrapolated track per DE;DE ID;#sigma_{%s} (cm)",axes[ia],axes[ia]), fNDE, 0.5, fNDE+0.5, nBins, 0., 0.2);
242 for (Int_t i = 1; i <= fNDE; i++) h2->GetXaxis()->SetBinLabel(i, Form("%d",fDEIds[i]));
243 fResiduals->AddAtAndExpand(h2, kMCSPerDE+ia);
244
245 h2 = new TH2F(Form("hClusterRes2%sPerCh",axes[ia]), Form("cluster #sigma_{%s}^{2} per Ch;chamber ID;#sigma_{%s}^{2} (cm^{2})",axes[ia],axes[ia]), 10, 0.5, 10.5, nSigma*nBins, -0.1*maxRes*maxRes, maxRes*maxRes);
246 fResiduals->AddAtAndExpand(h2, kClusterRes2PerCh+ia);
247
248 // List of residual vs. p histos
249 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
250 h2 = new TH2F(Form("hResidual%sInCh%dVsP_ClusterIn",axes[ia],i+1), Form("cluster-track residual-%s distribution in chamber %d versus momentum (cluster attached to the track);p (GeV/c^{2});#Delta_{%s} (cm)",axes[ia],i+1,axes[ia]), pNBins, pEdges[0], pEdges[1], nBins, -maxRes, maxRes);
f4d9245c 251 fResidualsVsP->AddAtAndExpand(h2, kResidualInChVsPClusterIn+10*ia+i);
7cbb1928 252 h2 = new TH2F(Form("hResidual%sInCh%dVsP_ClusterOut",axes[ia],i+1), Form("cluster-track residual-%s distribution in chamber %d versus momentum (cluster not attached to the track);p (GeV/c^{2});#Delta_{%s} (cm)",axes[ia],i+1,axes[ia]), pNBins, pEdges[0], pEdges[1], nBins, -2.*maxRes, 2.*maxRes);
f4d9245c 253 fResidualsVsP->AddAtAndExpand(h2, kResidualInChVsPClusterOut+10*ia+i);
7cbb1928 254 }
255
256 // local chi2
257 h2 = new TH2F(Form("hLocalChi2%sPerCh",axes[ia]), Form("local chi2-%s distribution per chamber;chamber ID;local #chi^{2}_{%s}", axes[ia], axes[ia]), 10, 0.5, 10.5, 1000, 0., 25.);
258 fResiduals->AddAtAndExpand(h2, kLocalChi2PerCh+ia);
259 h2 = new TH2F(Form("hLocalChi2%sPerDE",axes[ia]), Form("local chi2-%s distribution per DE;DE ID;local #chi^{2}_{%s}", axes[ia], axes[ia]), fNDE, 0.5, fNDE+0.5, 1000, 0., 25.);
260 for (Int_t i = 1; i <= fNDE; i++) h2->GetXaxis()->SetBinLabel(i, Form("%d",fDEIds[i]));
261 fResiduals->AddAtAndExpand(h2, kLocalChi2PerDE+ia);
262
263 // track resolution
264 h2 = new TH2F(Form("hUncorrSlope%sRes",axes[ia]), Form("muon slope_{%s} reconstructed resolution at first cluster vs p;p (GeV/c); #sigma_{slope_{%s}}", axes[ia], axes[ia]), 300, 0., 300., 1000, 0., 0.003);
265 fTrackRes->AddAtAndExpand(h2, kUncorrSlopeRes+ia);
266 h2 = new TH2F(Form("hSlope%sRes",axes[ia]), Form("muon slope_{%s} reconstructed resolution at vertex vs p;p (GeV/c); #sigma_{slope_{%s}}", axes[ia], axes[ia]), 300, 0., 300., 1000, 0., 0.02);
267 fTrackRes->AddAtAndExpand(h2, kSlopeRes+ia);
268 }
269
270 // local chi2 X+Y
271 h2 = new TH2F("hLocalChi2PerCh", "local chi2 (~0.5*(#chi^{2}_{X}+#chi^{2}_{Y})) distribution per chamber;chamber ID;local #chi^{2}", 10, 0.5, 10.5, 1000, 0., 25.);
272 fResiduals->AddAtAndExpand(h2, kLocalChi2PerCh+2);
273 h2 = new TH2F("hLocalChi2PerDE", "local chi2 (~0.5*(#chi^{2}_{X}+#chi^{2}_{Y})) distribution per chamber;DE ID;local #chi^{2}", fNDE, 0.5, fNDE+0.5, 1000, 0., 25.);
274 for (Int_t i = 1; i <= fNDE; i++) h2->GetXaxis()->SetBinLabel(i, Form("%d",fDEIds[i]));
275 fResiduals->AddAtAndExpand(h2, kLocalChi2PerDE+2);
276
277 // track resolution
278 h2 = new TH2F("hUncorrPRes", "muon momentum reconstructed resolution at first cluster vs p;p (GeV/c); #sigma_{p}/p (%)", 300, 0., 300., 1000, 0., 10.);
279 fTrackRes->AddAtAndExpand(h2, kUncorrPRes);
280 h2 = new TH2F("hPRes", "muon momentum reconstructed resolution at vertex vs p;p (GeV/c); #sigma_{p}/p (%)", 300, 0., 300., 1000, 0., 10.);
281 fTrackRes->AddAtAndExpand(h2, kPRes);
282 h2 = new TH2F("hUncorrPtRes", "muon transverse momentum reconstructed resolution at first cluster vs p_{t};p_{t} (GeV/c); #sigma_{p_{t}}/p_{t} (%)", 300, 0., 30., 300, 0., 30.);
283 fTrackRes->AddAtAndExpand(h2, kUncorrPtRes);
284 h2 = new TH2F("hPtRes", "muon transverse momentum reconstructed resolution at vertex vs p_{t};p_{t} (GeV/c); #sigma_{p_{t}}/p_{t} (%)", 300, 0., 30., 300, 0., 30.);
285 fTrackRes->AddAtAndExpand(h2, kPtRes);
286
287 // Post data at least once per task to ensure data synchronisation (required for merging)
288 PostData(1, fResiduals);
289 PostData(2, fResidualsVsP);
290 PostData(5, fTrackRes);
291}
292
293//________________________________________________________________________
294void AliAnalysisTaskMuonResolution::UserExec(Option_t *)
295{
296 /// Main event loop
297
298 // check if OCDB properly loaded
299 if (!fOCDBLoaded) return;
300
301 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
302 if (!esd) return;
303
00612ffc 304 if (fShowProgressBar && (++fNEvents)%100 == 0) cout<<"\rEvent processing... "<<fNEvents<<"\r"<<flush;
305
306 // skip events that do not pass the physics selection if required
307 UInt_t triggerWord = (fInputHandler) ? fInputHandler->IsEventSelected() : 0;
308 if (fSelectPhysics && triggerWord == 0) return;
309
310 // skip events that do not pass the trigger selection if required
f4d9245c 311 TString firedTriggerClasses = esd->GetFiredTriggerClasses();
312 if (!fSelectPhysics) triggerWord = BuildTriggerWord(firedTriggerClasses);
00612ffc 313 if (fSelectTrigger && (triggerWord & fTriggerMask) == 0) return;
7cbb1928 314
315 // get tracker to refit
316 AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
317
318 // loop over tracks
319 Int_t nTracks = (Int_t) esd->GetNumberOfMuonTracks();
320 for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack) {
321
322 // get the ESD track
323 AliESDMuonTrack* esdTrack = esd->GetMuonTrack(iTrack);
324
325 // skip ghost tracks
326 if (!esdTrack->ContainTrackerData()) continue;
327
7cbb1928 328 // skip tracks not matched with trigger if required
329 if (fMatchTrig && !esdTrack->ContainTriggerData()) continue;
330
00612ffc 331 // skip tracks that do not pass the acceptance cuts if required
332 Double_t thetaAbs = TMath::ATan(esdTrack->GetRAtAbsorberEnd()/505.) * TMath::RadToDeg();
333 Double_t eta = esdTrack->Eta();
334 if (fApplyAccCut && (thetaAbs < 2. || thetaAbs > 9. || eta < -4. || eta > -2.5)) continue;
335
7cbb1928 336 // skip low momentum tracks
337 if (esdTrack->PUncorrected() < fMinMomentum) continue;
338
339 // get the corresponding MUON track
340 AliMUONTrack track;
341 AliMUONESDInterface::ESDToMUON(*esdTrack, track, kFALSE);
342
343 // change the cluster resolution (and position)
344 ModifyClusters(track);
345
346 // refit the track
347 if (!tracker->RefitTrack(track, kFALSE)) break;
348
349 // save track unchanged
350 AliMUONTrack referenceTrack(track);
351
352 // get track param at first cluster and add MCS in first chamber
353 AliMUONTrackParam trackParamAtFirstCluster(*(static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->First())));
354 Int_t firstCh = 0; while (firstCh < 10 && !esdTrack->IsInMuonClusterMap(firstCh)) firstCh++;
355 AliMUONTrackExtrap::AddMCSEffect(&trackParamAtFirstCluster, AliMUONConstants::ChamberThicknessInX0(firstCh)/2., -1.);
356
357 // fill momentum error at first cluster
358 Double_t pXUncorr = trackParamAtFirstCluster.Px();
359 Double_t pYUncorr = trackParamAtFirstCluster.Py();
360 Double_t pZUncorr = trackParamAtFirstCluster.Pz();
361 Double_t pUncorr = trackParamAtFirstCluster.P();
362 TMatrixD covUncorr(5,5);
363 Cov2CovP(trackParamAtFirstCluster,covUncorr);
364 Double_t sigmaPUncorr = TMath::Sqrt(pXUncorr * (pXUncorr*covUncorr(2,2) + pYUncorr*covUncorr(2,3) + pZUncorr*covUncorr(2,4)) +
365 pYUncorr * (pXUncorr*covUncorr(3,2) + pYUncorr*covUncorr(3,3) + pZUncorr*covUncorr(3,4)) +
366 pZUncorr * (pXUncorr*covUncorr(4,2) + pYUncorr*covUncorr(4,3) + pZUncorr*covUncorr(4,4))) / pUncorr;
367 ((TH2F*)fTrackRes->UncheckedAt(kUncorrPRes))->Fill(pUncorr,100.*sigmaPUncorr/pUncorr);
368
369 // fill transverse momentum error at first cluster
370 Double_t ptUncorr = TMath::Sqrt(pXUncorr*pXUncorr + pYUncorr*pYUncorr);
371 Double_t sigmaPtUncorr = TMath::Sqrt(pXUncorr * (pXUncorr*covUncorr(2,2) + pYUncorr*covUncorr(2,3)) + pYUncorr * (pXUncorr*covUncorr(3,2) + pYUncorr*covUncorr(3,3))) / ptUncorr;
372 ((TH2F*)fTrackRes->UncheckedAt(kUncorrPtRes))->Fill(ptUncorr,100.*sigmaPtUncorr/ptUncorr);
373
374 // fill slopeX-Y error at first cluster
375 ((TH2F*)fTrackRes->UncheckedAt(kUncorrSlopeRes))->Fill(pUncorr,TMath::Sqrt(trackParamAtFirstCluster.GetCovariances()(1,1)));
376 ((TH2F*)fTrackRes->UncheckedAt(kUncorrSlopeRes+1))->Fill(pUncorr,TMath::Sqrt(trackParamAtFirstCluster.GetCovariances()(3,3)));
377
378 // fill momentum error at vertex
379 AliMUONTrackParam trackParamAtVtx(trackParamAtFirstCluster);
380 AliMUONTrackExtrap::ExtrapToVertex(&trackParamAtVtx, esdTrack->GetNonBendingCoor(), esdTrack->GetBendingCoor(), esdTrack->GetZ(), 0., 0.);
381 Double_t pXVtx = trackParamAtVtx.Px();
382 Double_t pYVtx = trackParamAtVtx.Py();
383 Double_t pZVtx = trackParamAtVtx.Pz();
384 Double_t pVtx = trackParamAtVtx.P();
385 TMatrixD covVtx(5,5);
386 Cov2CovP(trackParamAtVtx,covVtx);
387 Double_t sigmaPVtx = TMath::Sqrt(pXVtx * (pXVtx*covVtx(2,2) + pYVtx*covVtx(2,3) + pZVtx*covVtx(2,4)) +
388 pYVtx * (pXVtx*covVtx(3,2) + pYVtx*covVtx(3,3) + pZVtx*covVtx(3,4)) +
389 pZVtx * (pXVtx*covVtx(4,2) + pYVtx*covVtx(4,3) + pZVtx*covVtx(4,4))) / pVtx;
390 ((TH2F*)fTrackRes->UncheckedAt(kPRes))->Fill(pVtx,100.*sigmaPVtx/pVtx);
391
392 // fill transverse momentum error at vertex
393 Double_t ptVtx = TMath::Sqrt(pXVtx*pXVtx + pYVtx*pYVtx);
394 Double_t sigmaPtVtx = TMath::Sqrt(pXVtx * (pXVtx*covVtx(2,2) + pYVtx*covVtx(2,3)) + pYVtx * (pXVtx*covVtx(3,2) + pYVtx*covVtx(3,3))) / ptVtx;
395 ((TH2F*)fTrackRes->UncheckedAt(kPtRes))->Fill(ptVtx,100.*sigmaPtVtx/ptVtx);
396
397 // fill slopeX-Y error at vertex
398 ((TH2F*)fTrackRes->UncheckedAt(kSlopeRes))->Fill(pVtx,TMath::Sqrt(trackParamAtVtx.GetCovariances()(1,1)));
399 ((TH2F*)fTrackRes->UncheckedAt(kSlopeRes+1))->Fill(pVtx,TMath::Sqrt(trackParamAtVtx.GetCovariances()(3,3)));
400
401 // loop over clusters
402 Int_t nClusters = track.GetNClusters();
403 for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
404
405 // Get current, previous and next trackParams
406 AliMUONTrackParam* trackParam = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->UncheckedAt(iCluster));
407 AliMUONTrackParam* previousTrackParam = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->Before(trackParam));
408 AliMUONTrackParam* nextTrackParam = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->After(trackParam));
409
410 // save current trackParam and remove it from the track
411 AliMUONTrackParam currentTrackParam(*trackParam);
412 track.RemoveTrackParamAtCluster(trackParam);
413
414 // get cluster info
415 AliMUONVCluster* cluster = currentTrackParam.GetClusterPtr();
416 Int_t chId = cluster->GetChamberId();
417 Int_t halfChId = (cluster->GetX() > 0) ? 2*chId : 2*chId+1;
418 Int_t deId = cluster->GetDetElemId();
419
420 // compute residuals with cluster still attached to the track
421 AliMUONTrackParam* referenceTrackParam = static_cast<AliMUONTrackParam*>(referenceTrack.GetTrackParamAtCluster()->UncheckedAt(iCluster));
422 Double_t deltaX = cluster->GetX() - referenceTrackParam->GetNonBendingCoor();
423 Double_t deltaY = cluster->GetY() - referenceTrackParam->GetBendingCoor();
424
425 // compute local chi2
426 Double_t sigmaDeltaX2 = cluster->GetErrX2() - referenceTrackParam->GetCovariances()(0,0);
427 Double_t sigmaDeltaY2 = cluster->GetErrY2() - referenceTrackParam->GetCovariances()(2,2);
428 Double_t localChi2X = (sigmaDeltaX2 > 0.) ? deltaX*deltaX/sigmaDeltaX2 : 0.;
429 Double_t localChi2Y = (sigmaDeltaY2 > 0.) ? deltaY*deltaY/sigmaDeltaY2 : 0.;
430 Double_t localChi2 = 0.5 * referenceTrackParam->GetLocalChi2();
431
432 // fill local chi2 info at every clusters
433 ((TH2F*)fResiduals->UncheckedAt(kLocalChi2PerCh))->Fill(chId+1, localChi2X);
434 ((TH2F*)fResiduals->UncheckedAt(kLocalChi2PerCh+1))->Fill(chId+1, localChi2Y);
435 ((TH2F*)fResiduals->UncheckedAt(kLocalChi2PerCh+2))->Fill(chId+1, localChi2);
436 ((TH2F*)fResiduals->UncheckedAt(kLocalChi2PerDE))->Fill(fDEIndices[deId], localChi2X);
437 ((TH2F*)fResiduals->UncheckedAt(kLocalChi2PerDE+1))->Fill(fDEIndices[deId], localChi2Y);
438 ((TH2F*)fResiduals->UncheckedAt(kLocalChi2PerDE+2))->Fill(fDEIndices[deId], localChi2);
439
440 // make sure the track has another cluster in the same station and can still be refitted
441 Bool_t refit = track.IsValid( 1 << (chId/2) );
442 if (refit) {
443
444 // refit the track and proceed if everything goes fine
445 if (tracker->RefitTrack(track, kFALSE)) {
446
447 // fill histograms of residuals with cluster still attached to the track
f4d9245c 448 ((TH2F*)fResiduals->UncheckedAt(kResidualPerChClusterIn))->Fill(chId+1, deltaX);
449 ((TH2F*)fResiduals->UncheckedAt(kResidualPerChClusterIn+1))->Fill(chId+1, deltaY);
450 ((TH2F*)fResiduals->UncheckedAt(kResidualPerHalfChClusterIn))->Fill(halfChId+1, deltaX);
451 ((TH2F*)fResiduals->UncheckedAt(kResidualPerHalfChClusterIn+1))->Fill(halfChId+1, deltaY);
452 ((TH2F*)fResiduals->UncheckedAt(kResidualPerDEClusterIn))->Fill(fDEIndices[deId], deltaX);
453 ((TH2F*)fResiduals->UncheckedAt(kResidualPerDEClusterIn+1))->Fill(fDEIndices[deId], deltaY);
454 ((TH2F*)fResidualsVsP->UncheckedAt(kResidualInChVsPClusterIn+chId))->Fill(pUncorr, deltaX);
455 ((TH2F*)fResidualsVsP->UncheckedAt(kResidualInChVsPClusterIn+10+chId))->Fill(pUncorr, deltaY);
7cbb1928 456
457 // find the track parameters closest to the current cluster position
458 Double_t dZWithPrevious = (previousTrackParam) ? TMath::Abs(previousTrackParam->GetClusterPtr()->GetZ() - cluster->GetZ()) : FLT_MAX;
459 Int_t previousChId = (previousTrackParam) ? previousTrackParam->GetClusterPtr()->GetChamberId() : -1;
460 Double_t dZWithNext = (nextTrackParam) ? TMath::Abs(nextTrackParam->GetClusterPtr()->GetZ() - cluster->GetZ()) : FLT_MAX;
461 AliMUONTrackParam* startingTrackParam = 0x0;
462 if ((fExtrapMode == 0 && dZWithPrevious < dZWithNext) ||
463 (fExtrapMode == 1 && previousTrackParam && !(chId/2 == 2 && previousChId/2 == 1) &&
464 !(chId/2 == 3 && previousChId/2 == 2))) startingTrackParam = previousTrackParam;
465 else startingTrackParam = nextTrackParam;
466
467 // reset current parameters
468 currentTrackParam.SetParameters(startingTrackParam->GetParameters());
469 currentTrackParam.SetZ(startingTrackParam->GetZ());
470 currentTrackParam.SetCovariances(startingTrackParam->GetCovariances());
471 currentTrackParam.ResetPropagator();
472
473 // extrapolate to the current cluster position and fill histograms of residuals if everything goes fine
474 if (AliMUONTrackExtrap::ExtrapToZCov(&currentTrackParam, currentTrackParam.GetClusterPtr()->GetZ(), kTRUE)) {
475
476 // compute MCS dispersion on the first chamber
477 TMatrixD mcsCov(5,5);
478 if (startingTrackParam == nextTrackParam && chId == 0) {
479 AliMUONTrackParam trackParamForMCS;
480 trackParamForMCS.SetParameters(nextTrackParam->GetParameters());
481 AliMUONTrackExtrap::AddMCSEffect(&trackParamForMCS,AliMUONConstants::ChamberThicknessInX0(nextTrackParam->GetClusterPtr()->GetChamberId()),-1.);
482 const TMatrixD &propagator = currentTrackParam.GetPropagator();
483 TMatrixD tmp(trackParamForMCS.GetCovariances(),TMatrixD::kMultTranspose,propagator);
484 mcsCov.Mult(propagator,tmp);
485 } else mcsCov.Zero();
486
487 // compute residuals
488 Double_t trackResX2 = currentTrackParam.GetCovariances()(0,0) + mcsCov(0,0);
489 Double_t trackResY2 = currentTrackParam.GetCovariances()(2,2) + mcsCov(2,2);
490 deltaX = cluster->GetX() - currentTrackParam.GetNonBendingCoor();
491 deltaY = cluster->GetY() - currentTrackParam.GetBendingCoor();
492
493 // fill histograms with cluster not attached to the track
f4d9245c 494 ((TH2F*)fResiduals->UncheckedAt(kResidualPerChClusterOut))->Fill(chId+1, deltaX);
495 ((TH2F*)fResiduals->UncheckedAt(kResidualPerChClusterOut+1))->Fill(chId+1, deltaY);
496 ((TH2F*)fResiduals->UncheckedAt(kResidualPerHalfChClusterOut))->Fill(halfChId+1, deltaX);
497 ((TH2F*)fResiduals->UncheckedAt(kResidualPerHalfChClusterOut+1))->Fill(halfChId+1, deltaY);
498 ((TH2F*)fResiduals->UncheckedAt(kResidualPerDEClusterOut))->Fill(fDEIndices[deId], deltaX);
499 ((TH2F*)fResiduals->UncheckedAt(kResidualPerDEClusterOut+1))->Fill(fDEIndices[deId], deltaY);
500 ((TH2F*)fResidualsVsP->UncheckedAt(kResidualInChVsPClusterOut+chId))->Fill(pUncorr, deltaX);
501 ((TH2F*)fResidualsVsP->UncheckedAt(kResidualInChVsPClusterOut+10+chId))->Fill(pUncorr, deltaY);
7cbb1928 502 ((TH2F*)fResiduals->UncheckedAt(kTrackResPerCh))->Fill(chId+1, TMath::Sqrt(trackResX2));
503 ((TH2F*)fResiduals->UncheckedAt(kTrackResPerCh+1))->Fill(chId+1, TMath::Sqrt(trackResY2));
504 ((TH2F*)fResiduals->UncheckedAt(kTrackResPerHalfCh))->Fill(halfChId+1, TMath::Sqrt(trackResX2));
505 ((TH2F*)fResiduals->UncheckedAt(kTrackResPerHalfCh+1))->Fill(halfChId+1, TMath::Sqrt(trackResY2));
506 ((TH2F*)fResiduals->UncheckedAt(kTrackResPerDE))->Fill(fDEIndices[deId], TMath::Sqrt(trackResX2));
507 ((TH2F*)fResiduals->UncheckedAt(kTrackResPerDE+1))->Fill(fDEIndices[deId], TMath::Sqrt(trackResY2));
508 ((TH2F*)fResiduals->UncheckedAt(kMCSPerCh))->Fill(chId+1, TMath::Sqrt(mcsCov(0,0)));
509 ((TH2F*)fResiduals->UncheckedAt(kMCSPerCh+1))->Fill(chId+1, TMath::Sqrt(mcsCov(2,2)));
510 ((TH2F*)fResiduals->UncheckedAt(kMCSPerHalfCh))->Fill(halfChId+1, TMath::Sqrt(mcsCov(0,0)));
511 ((TH2F*)fResiduals->UncheckedAt(kMCSPerHalfCh+1))->Fill(halfChId+1, TMath::Sqrt(mcsCov(2,2)));
512 ((TH2F*)fResiduals->UncheckedAt(kMCSPerDE))->Fill(fDEIndices[deId], TMath::Sqrt(mcsCov(0,0)));
513 ((TH2F*)fResiduals->UncheckedAt(kMCSPerDE+1))->Fill(fDEIndices[deId], TMath::Sqrt(mcsCov(2,2)));
514 ((TH2F*)fResiduals->UncheckedAt(kClusterRes2PerCh))->Fill(chId+1, deltaX*deltaX - trackResX2);
515 ((TH2F*)fResiduals->UncheckedAt(kClusterRes2PerCh+1))->Fill(chId+1, deltaY*deltaY - trackResY2);
516 }
517
518 }
519
520 }
521
522 // restore the track
523 track.AddTrackParamAtCluster(currentTrackParam, *(currentTrackParam.GetClusterPtr()), kTRUE);
524
525 }
526
527 }
528
529 // Post final data. It will be written to a file with option "RECREATE"
530 PostData(1, fResiduals);
531 PostData(2, fResidualsVsP);
532 PostData(5, fTrackRes);
533}
534
535//________________________________________________________________________
536void AliAnalysisTaskMuonResolution::NotifyRun()
537{
538 /// load necessary data from OCDB corresponding to the first run number and initialize analysis
539
540 if (fOCDBLoaded) return;
541
542 AliCDBManager* cdbm = AliCDBManager::Instance();
00612ffc 543 cdbm->SetDefaultStorage(fDefaultStorage.Data());
7cbb1928 544 cdbm->SetRun(fCurrentRunNumber);
545
546 if (!AliMUONCDB::LoadField()) return;
547
548 if (!AliMUONCDB::LoadMapping()) return;
549
550 AliMUONRecoParam* recoParam = AliMUONCDB::LoadRecoParam();
551 if (!recoParam) return;
552
7cbb1928 553 AliMUONESDInterface::ResetTracker(recoParam);
554
555 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
556
557 // set the cluster resolution to default if not already set and create output objects
558 if (fClusterResNB[i] < 0.) fClusterResNB[i] = recoParam->GetDefaultNonBendingReso(i);
559 if (fClusterResB[i] < 0.) fClusterResB[i] = recoParam->GetDefaultBendingReso(i);
560
561 // fill correspondence between DEId and indices for histo (starting from 1)
562 AliMpDEIterator it;
563 it.First(i);
564 while (!it.IsDone()) {
565 fNDE++;
566 fDEIndices[it.CurrentDEId()] = fNDE;
567 fDEIds[fNDE] = it.CurrentDEId();
568 it.Next();
569 }
570
571 }
572
573 if (fReAlign) {
574
00612ffc 575 // recover default storage full name (raw:// cannot be used to set specific storage)
7cbb1928 576 TString defaultStorage(cdbm->GetDefaultStorage()->GetType());
577 if (defaultStorage == "alien") defaultStorage += Form("://folder=%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
578 else defaultStorage += Form("://%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
579
580 // reset existing geometry/alignment if any
581 if (cdbm->GetEntryCache()->Contains("GRP/Geometry/Data")) cdbm->UnloadFromCache("GRP/Geometry/Data");
582 if (cdbm->GetEntryCache()->Contains("MUON/Align/Data")) cdbm->UnloadFromCache("MUON/Align/Data");
583 if (AliGeomManager::GetGeometry()) AliGeomManager::GetGeometry()->UnlockGeometry();
584
585 // get original geometry transformer
586 AliGeomManager::LoadGeometry();
587 if (!AliGeomManager::GetGeometry()) return;
588 if (fOldAlignStorage != "none") {
589 if (!fOldAlignStorage.IsNull()) cdbm->SetSpecificStorage("MUON/Align/Data",fOldAlignStorage.Data());
590 else cdbm->SetSpecificStorage("MUON/Align/Data",defaultStorage.Data());
591 AliGeomManager::ApplyAlignObjsFromCDB("MUON");
592 }
593 fOldGeoTransformer = new AliMUONGeometryTransformer();
594 fOldGeoTransformer->LoadGeometryData();
595
596 // get new geometry transformer
597 cdbm->UnloadFromCache("GRP/Geometry/Data");
598 if (fOldAlignStorage != "none") cdbm->UnloadFromCache("MUON/Align/Data");
599 AliGeomManager::GetGeometry()->UnlockGeometry();
600 AliGeomManager::LoadGeometry();
601 if (!AliGeomManager::GetGeometry()) return;
602 if (!fNewAlignStorage.IsNull()) cdbm->SetSpecificStorage("MUON/Align/Data",fNewAlignStorage.Data());
603 else cdbm->SetSpecificStorage("MUON/Align/Data",defaultStorage.Data());
604 AliGeomManager::ApplyAlignObjsFromCDB("MUON");
605 fNewGeoTransformer = new AliMUONGeometryTransformer();
606 fNewGeoTransformer->LoadGeometryData();
607
608 } else {
609
610 // load geometry for track extrapolation to vertex
611 if (cdbm->GetEntryCache()->Contains("GRP/Geometry/Data")) cdbm->UnloadFromCache("GRP/Geometry/Data");
612 if (AliGeomManager::GetGeometry()) AliGeomManager::GetGeometry()->UnlockGeometry();
613 AliGeomManager::LoadGeometry();
614 if (!AliGeomManager::GetGeometry()) return;
615
616 }
617
00612ffc 618 // print starting chamber resolution if required
619 if (fPrintClResPerCh) {
620 printf("\nstarting chamber resolution:\n");
621 printf(" - non-bending:");
622 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) printf((i==0)?" %5.3f":", %5.3f",fClusterResNB[i]);
623 printf("\n - bending:");
624 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) printf((i==0)?" %6.4f":", %6.4f",fClusterResB[i]);
625 printf("\n\n");
626 }
627
628 fOCDBLoaded = kTRUE;
7cbb1928 629
630 UserCreateOutputObjects();
631
632}
633
634//________________________________________________________________________
635void AliAnalysisTaskMuonResolution::Terminate(Option_t *)
636{
637 /// compute final results
638
639 // recover output objects
640 fResiduals = static_cast<TObjArray*> (GetOutputData(1));
641 fResidualsVsP = static_cast<TObjArray*> (GetOutputData(2));
642 fTrackRes = static_cast<TObjArray*> (GetOutputData(5));
643 if (!fResiduals || !fResidualsVsP || !fTrackRes) return;
644
645 // summary graphs
646 fLocalChi2 = new TObjArray(1000);
647 fLocalChi2->SetOwner();
648 fChamberRes = new TObjArray(1000);
649 fChamberRes->SetOwner();
650 TGraphErrors* g;
651 TMultiGraph* mg;
652
653 const char* axes[2] = {"X", "Y"};
654 Double_t newClusterRes[2][10], newClusterResErr[2][10];
f4d9245c 655 fNDE = ((TH2F*)fResiduals->UncheckedAt(kResidualPerDEClusterIn))->GetXaxis()->GetNbins();
7cbb1928 656
657 for (Int_t ia = 0; ia < 2; ia++) {
658
659 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
660 g->SetName(Form("gResidual%sPerChMean_ClusterIn",axes[ia]));
661 g->SetTitle(Form("cluster-track residual-%s per Ch: mean (cluster in);chamber ID;<#Delta_{%s}> (cm)",axes[ia],axes[ia]));
662 g->SetMarkerStyle(kFullDotLarge);
f4d9245c 663 fChamberRes->AddAtAndExpand(g, kResidualPerChMeanClusterIn+ia);
7cbb1928 664 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
665 g->SetName(Form("gResidual%sPerChMean_ClusterOut",axes[ia]));
666 g->SetTitle(Form("cluster-track residual-%s per Ch: mean (cluster out);chamber ID;<#Delta_{%s}> (cm)",axes[ia],axes[ia]));
667 g->SetMarkerStyle(kFullDotLarge);
f4d9245c 668 fChamberRes->AddAtAndExpand(g, kResidualPerChMeanClusterOut+ia);
7cbb1928 669
670 g = new TGraphErrors(2*AliMUONConstants::NTrackingCh());
671 g->SetName(Form("gResidual%sPerHalfChMean_ClusterIn",axes[ia]));
672 g->SetTitle(Form("cluster-track residual-%s per half Ch: mean (cluster in);half chamber ID;<#Delta_{%s}> (cm)",axes[ia],axes[ia]));
673 g->SetMarkerStyle(kFullDotLarge);
f4d9245c 674 fChamberRes->AddAtAndExpand(g, kResidualPerHalfChMeanClusterIn+ia);
7cbb1928 675 g = new TGraphErrors(2*AliMUONConstants::NTrackingCh());
676 g->SetName(Form("gResidual%sPerHalfChMean_ClusterOut",axes[ia]));
677 g->SetTitle(Form("cluster-track residual-%s per half Ch: mean (cluster out);half chamber ID;<#Delta_{%s}> (cm)",axes[ia],axes[ia]));
678 g->SetMarkerStyle(kFullDotLarge);
f4d9245c 679 fChamberRes->AddAtAndExpand(g, kResidualPerHalfChMeanClusterOut+ia);
7cbb1928 680
681 g = new TGraphErrors(fNDE);
682 g->SetName(Form("gResidual%sPerDEMean_ClusterIn",axes[ia]));
683 g->SetTitle(Form("cluster-track residual-%s per DE: mean (cluster in);DE ID;<#Delta_{%s}> (cm)",axes[ia],axes[ia]));
684 g->SetMarkerStyle(kFullDotLarge);
f4d9245c 685 fChamberRes->AddAtAndExpand(g, kResidualPerDEMeanClusterIn+ia);
7cbb1928 686 g = new TGraphErrors(fNDE);
687 g->SetName(Form("gResidual%sPerDEMean_ClusterOut",axes[ia]));
688 g->SetTitle(Form("cluster-track residual-%s per DE: mean (cluster out);DE ID;<#Delta_{%s}> (cm)",axes[ia],axes[ia]));
689 g->SetMarkerStyle(kFullDotLarge);
f4d9245c 690 fChamberRes->AddAtAndExpand(g, kResidualPerDEMeanClusterOut+ia);
7cbb1928 691
692 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
693 g->SetName(Form("gResidual%sPerChSigma_ClusterIn",axes[ia]));
694 g->SetTitle(Form("cluster-track residual-%s per Ch: sigma (cluster in);chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
695 g->SetMarkerStyle(kFullDotLarge);
f4d9245c 696 fChamberRes->AddAtAndExpand(g, kResidualPerChSigmaClusterIn+ia);
7cbb1928 697 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
698 g->SetName(Form("gResidual%sPerChSigma_ClusterOut",axes[ia]));
699 g->SetTitle(Form("cluster-track residual-%s per Ch: sigma (cluster out);chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
700 g->SetMarkerStyle(kFullDotLarge);
f4d9245c 701 fChamberRes->AddAtAndExpand(g, kResidualPerChSigmaClusterOut+ia);
7cbb1928 702
703 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
704 g->SetName(Form("gResidual%sPerChDispersion_ClusterOut",axes[ia]));
705 g->SetTitle(Form("cluster-track residual-%s per Ch: dispersion (cluster out);chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
706 g->SetMarkerStyle(kFullDotLarge);
f4d9245c 707 fChamberRes->AddAtAndExpand(g, kResidualPerChDispersionClusterOut+ia);
7cbb1928 708
709 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
710 g->SetName(Form("gCombinedResidual%sPerChSigma",axes[ia]));
711 g->SetTitle(Form("combined cluster-track residual-%s per Ch: sigma;chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
712 g->SetMarkerStyle(kFullDotLarge);
713 fChamberRes->AddAtAndExpand(g, kCombinedResidualPerChSigma+ia);
714
715 g = new TGraphErrors(2*AliMUONConstants::NTrackingCh());
716 g->SetName(Form("gCombinedResidual%sPerHalfChSigma",axes[ia]));
717 g->SetTitle(Form("combined cluster-track residual-%s per half Ch: sigma;half chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
718 g->SetMarkerStyle(kFullDotLarge);
719 fChamberRes->AddAtAndExpand(g, kCombinedResidualPerHalfChSigma+ia);
720
721 g = new TGraphErrors(fNDE);
722 g->SetName(Form("gCombinedResidual%sPerDESigma",axes[ia]));
723 g->SetTitle(Form("combined cluster-track residual-%s per DE: sigma;DE ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
724 g->SetMarkerStyle(kFullDotLarge);
725 fChamberRes->AddAtAndExpand(g, kCombinedResidualPerDESigma+ia);
726
727 mg = new TMultiGraph(Form("mgCombinedResidual%sSigmaVsP",axes[ia]),Form("cluster %s-resolution per chamber versus momentum;p (GeV/c^{2});#sigma_{%s} (cm)",axes[ia],axes[ia]));
728 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
f4d9245c 729 g = new TGraphErrors(((TH2F*)fResidualsVsP->UncheckedAt(kResidualInChVsPClusterIn+10*ia+i))->GetNbinsX());
7cbb1928 730 g->SetName(Form("gRes%sVsP_ch%d",axes[ia],i+1));
731 g->SetMarkerStyle(kFullDotMedium);
732 g->SetMarkerColor(i+1+i/9);
733 mg->Add(g,"p");
734 }
735 fChamberRes->AddAtAndExpand(mg, kCombinedResidualSigmaVsP+ia);
736
737 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
738 g->SetName(Form("gTrackRes%sPerCh",axes[ia]));
739 g->SetTitle(Form("track <#sigma_{%s}> per Ch;chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
740 g->SetMarkerStyle(kFullDotLarge);
741 fChamberRes->AddAtAndExpand(g, kTrackResPerChMean+ia);
742
743 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
744 g->SetName(Form("gMCS%sPerCh",axes[ia]));
745 g->SetTitle(Form("MCS %s-dispersion of extrapolated track per Ch;chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
746 g->SetMarkerStyle(kFullDotLarge);
747 fChamberRes->AddAtAndExpand(g, kMCSPerChMean+ia);
748
749 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
750 g->SetName(Form("gClusterRes%sPerCh",axes[ia]));
751 g->SetTitle(Form("cluster <#sigma_{%s}> per Ch;chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
752 g->SetMarkerStyle(kFullDotLarge);
753 fChamberRes->AddAtAndExpand(g, kClusterResPerCh+ia);
754
755 g = new TGraphErrors(2*AliMUONConstants::NTrackingCh());
756 g->SetName(Form("gClusterRes%sPerHalfCh",axes[ia]));
757 g->SetTitle(Form("cluster <#sigma_{%s}> per half Ch;half chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
758 g->SetMarkerStyle(kFullDotLarge);
759 fChamberRes->AddAtAndExpand(g, kClusterResPerHalfCh+ia);
760
761 g = new TGraphErrors(fNDE);
762 g->SetName(Form("gClusterRes%sPerDE",axes[ia]));
763 g->SetTitle(Form("cluster <#sigma_{%s}> per DE;DE ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
764 g->SetMarkerStyle(kFullDotLarge);
765 fChamberRes->AddAtAndExpand(g, kClusterResPerDE+ia);
766
767 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
768 g->SetName(Form("gCalcClusterRes%sPerCh",axes[ia]));
769 g->SetTitle(Form("calculated cluster <#sigma_{%s}> per Ch;chamber ID;#sigma_{%s} (cm)",axes[ia],axes[ia]));
770 g->SetMarkerStyle(kFullDotLarge);
771 fChamberRes->AddAtAndExpand(g, kCalcClusterResPerCh+ia);
772
773 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
774 g->SetName(Form("gLocalChi2%sPerChMean",axes[ia]));
775 g->SetTitle(Form("local chi2-%s per Ch: mean;chamber ID;<local #chi^{2}_{%s}>",axes[ia],axes[ia]));
776 g->SetMarkerStyle(kFullDotLarge);
777 fLocalChi2->AddAtAndExpand(g, kLocalChi2PerChMean+ia);
778
779 g = new TGraphErrors(fNDE);
780 g->SetName(Form("gLocalChi2%sPerDEMean",axes[ia]));
781 g->SetTitle(Form("local chi2-%s per DE: mean;DE ID;<local #chi^{2}_{%s}>",axes[ia],axes[ia]));
782 g->SetMarkerStyle(kFullDotLarge);
783 fLocalChi2->AddAtAndExpand(g, kLocalChi2PerDEMean+ia);
784
785 // compute residual mean and dispersion and averaged local chi2 per chamber and half chamber
00612ffc 786 Double_t meanIn, meanInErr, meanOut, meanOutErr, sigma, sigmaIn, sigmaInErr, sigmaOut, sigmaOutErr;
7cbb1928 787 Double_t sigmaTrack, sigmaTrackErr, sigmaMCS, sigmaMCSErr, clusterRes, clusterResErr, sigmaCluster, sigmaClusterErr;
788 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
789
790 // method 1
f4d9245c 791 TH1D *tmp = ((TH2F*)fResiduals->UncheckedAt(kResidualPerChClusterIn+ia))->ProjectionY("tmp",i+1,i+1,"e");
792 GetMean(tmp, meanIn, meanInErr, (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChMeanClusterIn+ia), i, i+1);
793 GetRMS(tmp, sigmaIn, sigmaInErr, (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChSigmaClusterIn+ia), i, i+1);
7cbb1928 794 delete tmp;
795
f4d9245c 796 tmp = ((TH2F*)fResiduals->UncheckedAt(kResidualPerChClusterOut+ia))->ProjectionY("tmp",i+1,i+1,"e");
797 GetMean(tmp, meanOut, meanOutErr, (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChMeanClusterOut+ia), i, i+1);
798 GetRMS(tmp, sigmaOut, sigmaOutErr, (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChSigmaClusterOut+ia), i, i+1);
7cbb1928 799 delete tmp;
800
801 if (fCorrectForSystematics) {
00612ffc 802 sigma = TMath::Sqrt(sigmaIn*sigmaIn + meanIn*meanIn);
803 sigmaInErr = (sigma>0) ? TMath::Sqrt(sigmaIn*sigmaIn*sigmaInErr*sigmaInErr + meanIn*meanIn*meanInErr*meanInErr) / sigma : 0.;
804 sigmaIn = sigma;
805 sigma = TMath::Sqrt(sigmaOut*sigmaOut + meanOut*meanOut);
806 sigmaOutErr = (sigma>0) ? TMath::Sqrt(sigmaOut*sigmaOut*sigmaOutErr*sigmaOutErr + meanOut*meanOut*meanOutErr*meanOutErr) / sigma : 0.;
807 sigmaOut = sigma;
7cbb1928 808 }
f4d9245c 809 ((TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChDispersionClusterOut+ia))->SetPoint(i, i+1, sigmaOut);
810 ((TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChDispersionClusterOut+ia))->SetPointError(i, 0., sigmaOutErr);
7cbb1928 811
812 clusterRes = TMath::Sqrt(sigmaIn*sigmaOut);
813 // clusterResErr = (clusterRes > 0.) ? 0.5 * TMath::Sqrt(sigmaInErr*sigmaInErr*sigmaOut*sigmaOut + sigmaIn*sigmaIn*sigmaOutErr*sigmaOutErr) / clusterRes : 0.;
814 clusterResErr = TMath::Sqrt(sigmaInErr*sigmaOutErr);
815 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerChSigma+ia))->SetPoint(i, i+1, clusterRes);
816 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerChSigma+ia))->SetPointError(i, 0., clusterResErr);
817 newClusterRes[ia][i] = clusterRes;
818 newClusterResErr[ia][i] = clusterResErr;
819
820 // method 2
821 tmp = ((TH2F*)fResiduals->UncheckedAt(kTrackResPerCh+ia))->ProjectionY("tmp",i+1,i+1,"e");
00612ffc 822 GetMean(tmp, sigmaTrack, sigmaTrackErr, (TGraphErrors*)fChamberRes->UncheckedAt(kTrackResPerChMean+ia), i, i+1, kFALSE, kFALSE);
7cbb1928 823 delete tmp;
824
825 tmp = ((TH2F*)fResiduals->UncheckedAt(kMCSPerCh+ia))->ProjectionY("tmp",i+1,i+1,"e");
00612ffc 826 GetMean(tmp, sigmaMCS, sigmaMCSErr, (TGraphErrors*)fChamberRes->UncheckedAt(kMCSPerChMean+ia), i, i+1, kFALSE, kFALSE);
7cbb1928 827 delete tmp;
828
829 sigmaCluster = sigmaOut*sigmaOut - sigmaTrack*sigmaTrack;
830 if (sigmaCluster > 0.) {
831 sigmaCluster = TMath::Sqrt(sigmaCluster);
832 sigmaClusterErr = TMath::Sqrt(sigmaOut*sigmaOut*sigmaOutErr*sigmaOutErr + sigmaTrack*sigmaTrack*sigmaTrackErr*sigmaTrackErr) / sigmaCluster;
833 } else {
834 sigmaCluster = 0.;
835 sigmaClusterErr = 0.;
836 }
837 ((TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerCh+ia))->SetPoint(i, i+1, sigmaCluster);
838 ((TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerCh+ia))->SetPointError(i, 0., sigmaClusterErr);
839
840 // method 3
841 tmp = ((TH2F*)fResiduals->UncheckedAt(kClusterRes2PerCh+ia))->ProjectionY("tmp",i+1,i+1,"e");
842 ZoomRight(tmp);
843 clusterRes = tmp->GetMean();
844 if (clusterRes > 0.) {
845 ((TGraphErrors*)fChamberRes->UncheckedAt(kCalcClusterResPerCh+ia))->SetPoint(i, i+1, TMath::Sqrt(clusterRes));
846 ((TGraphErrors*)fChamberRes->UncheckedAt(kCalcClusterResPerCh+ia))->SetPointError(i, 0., 0.5 * tmp->GetMeanError() / TMath::Sqrt(clusterRes));
847 } else {
848 ((TGraphErrors*)fChamberRes->UncheckedAt(kCalcClusterResPerCh+ia))->SetPoint(i, i+1, 0.);
849 ((TGraphErrors*)fChamberRes->UncheckedAt(kCalcClusterResPerCh+ia))->SetPointError(i, 0., 0.);
850 }
851 delete tmp;
852
853 // method 1 versus p
f4d9245c 854 FillSigmaClusterVsP((TH2F*)fResidualsVsP->UncheckedAt(kResidualInChVsPClusterIn+10*ia+i),
855 (TH2F*)fResidualsVsP->UncheckedAt(kResidualInChVsPClusterOut+10*ia+i),
7cbb1928 856 (TGraphErrors*)((TMultiGraph*)fChamberRes->UncheckedAt(kCombinedResidualSigmaVsP+ia))->GetListOfGraphs()->FindObject(Form("gRes%sVsP_ch%d",axes[ia],i+1)));
857
858 // compute residual mean and dispersion per half chamber
859 for (Int_t j = 0; j < 2; j++) {
860 Int_t k = 2*i+j;
861
862 // method 1
f4d9245c 863 tmp = ((TH2F*)fResiduals->UncheckedAt(kResidualPerHalfChClusterIn+ia))->ProjectionY("tmp",k+1,k+1,"e");
864 GetMean(tmp, meanIn, meanInErr, (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerHalfChMeanClusterIn+ia), k, k+1);
7cbb1928 865 GetRMS(tmp, sigmaIn, sigmaInErr);
866 delete tmp;
867
f4d9245c 868 tmp = ((TH2F*)fResiduals->UncheckedAt(kResidualPerHalfChClusterOut+ia))->ProjectionY("tmp",k+1,k+1,"e");
869 GetMean(tmp, meanOut, meanOutErr, (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerHalfChMeanClusterOut+ia), k, k+1);
7cbb1928 870 GetRMS(tmp, sigmaOut, sigmaOutErr);
871 delete tmp;
872
873 if (fCorrectForSystematics) {
00612ffc 874 sigma = TMath::Sqrt(sigmaIn*sigmaIn + meanIn*meanIn);
875 sigmaInErr = (sigma>0) ? TMath::Sqrt(sigmaIn*sigmaIn*sigmaInErr*sigmaInErr + meanIn*meanIn*meanInErr*meanInErr) / sigma : 0.;
876 sigmaIn = sigma;
877 sigma = TMath::Sqrt(sigmaOut*sigmaOut + meanOut*meanOut);
878 sigmaOutErr = (sigma>0) ? TMath::Sqrt(sigmaOut*sigmaOut*sigmaOutErr*sigmaOutErr + meanOut*meanOut*meanOutErr*meanOutErr) / sigma : 0.;
879 sigmaOut = sigma;
7cbb1928 880 }
881
882 clusterRes = TMath::Sqrt(sigmaIn*sigmaOut);
883 // clusterResErr = (clusterRes > 0.) ? 0.5 * TMath::Sqrt(sigmaInErr*sigmaInErr*sigmaOut*sigmaOut + sigmaIn*sigmaIn*sigmaOutErr*sigmaOutErr) / clusterRes : 0.;
884 clusterResErr = TMath::Sqrt(sigmaInErr*sigmaOutErr);
885 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerHalfChSigma+ia))->SetPoint(k, k+1, clusterRes);
886 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerHalfChSigma+ia))->SetPointError(k, 0., clusterResErr);
887
888 // method 2
889 tmp = ((TH2F*)fResiduals->UncheckedAt(kTrackResPerHalfCh+ia))->ProjectionY("tmp",k+1,k+1,"e");
00612ffc 890 GetMean(tmp, sigmaTrack, sigmaTrackErr, 0x0, 0, 0, kFALSE, kFALSE);
7cbb1928 891 delete tmp;
892
893 tmp = ((TH2F*)fResiduals->UncheckedAt(kMCSPerHalfCh+ia))->ProjectionY("tmp",k+1,k+1,"e");
00612ffc 894 GetMean(tmp, sigmaMCS, sigmaMCSErr, 0x0, 0, 0, kFALSE, kFALSE);
7cbb1928 895 delete tmp;
896
897 sigmaCluster = sigmaOut*sigmaOut - sigmaTrack*sigmaTrack;
898 if (sigmaCluster > 0.) {
899 sigmaCluster = TMath::Sqrt(sigmaCluster);
900 sigmaClusterErr = TMath::Sqrt(sigmaOut*sigmaOut*sigmaOutErr*sigmaOutErr + sigmaTrack*sigmaTrack*sigmaTrackErr*sigmaTrackErr) / sigmaCluster;
901 } else {
902 sigmaCluster = 0.;
903 sigmaClusterErr = 0.;
904 }
905 ((TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerHalfCh+ia))->SetPoint(k, k+1, sigmaCluster);
906 ((TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerHalfCh+ia))->SetPointError(k, 0., sigmaClusterErr);
907
908 }
909
910 // compute averaged local chi2
911 tmp = ((TH2F*)fResiduals->UncheckedAt(kLocalChi2PerCh+ia))->ProjectionY("tmp",i+1,i+1,"e");
912 ((TGraphErrors*)fLocalChi2->UncheckedAt(kLocalChi2PerChMean+ia))->SetPoint(i, i+1, tmp->GetMean());
913 ((TGraphErrors*)fLocalChi2->UncheckedAt(kLocalChi2PerChMean+ia))->SetPointError(i, 0., tmp->GetMeanError());
914 delete tmp;
915
916 }
917
918 // compute residual mean and dispersion per DE
919 for (Int_t i = 0; i < fNDE; i++) {
920
921 // method 1
f4d9245c 922 TH1D *tmp = ((TH2F*)fResiduals->UncheckedAt(kResidualPerDEClusterIn+ia))->ProjectionY("tmp",i+1,i+1,"e");
923 GetMean(tmp, meanIn, meanInErr, (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerDEMeanClusterIn+ia), i, i+1);
7cbb1928 924 GetRMS(tmp, sigmaIn, sigmaInErr);
925 delete tmp;
926
f4d9245c 927 tmp = ((TH2F*)fResiduals->UncheckedAt(kResidualPerDEClusterOut+ia))->ProjectionY("tmp",i+1,i+1,"e");
928 GetMean(tmp, meanOut, meanOutErr, (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerDEMeanClusterOut+ia), i, i+1);
7cbb1928 929 GetRMS(tmp, sigmaOut, sigmaOutErr);
930 delete tmp;
931
932 if (fCorrectForSystematics) {
00612ffc 933 sigma = TMath::Sqrt(sigmaIn*sigmaIn + meanIn*meanIn);
934 sigmaInErr = (sigma>0) ? TMath::Sqrt(sigmaIn*sigmaIn*sigmaInErr*sigmaInErr + meanIn*meanIn*meanInErr*meanInErr) / sigma : 0.;
935 sigmaIn = sigma;
936 sigma = TMath::Sqrt(sigmaOut*sigmaOut + meanOut*meanOut);
937 sigmaOutErr = (sigma>0) ? TMath::Sqrt(sigmaOut*sigmaOut*sigmaOutErr*sigmaOutErr + meanOut*meanOut*meanOutErr*meanOutErr) / sigma : 0.;
938 sigmaOut = sigma;
7cbb1928 939 }
940
941 clusterRes = TMath::Sqrt(sigmaIn*sigmaOut);
942 // clusterResErr = (clusterRes > 0.) ? 0.5 * TMath::Sqrt(sigmaInErr*sigmaInErr*sigmaOut*sigmaOut + sigmaIn*sigmaIn*sigmaOutErr*sigmaOutErr) / clusterRes : 0.;
943 clusterResErr = TMath::Sqrt(sigmaInErr*sigmaOutErr);
944 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerDESigma+ia))->SetPoint(i, i+1, clusterRes);
945 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerDESigma+ia))->SetPointError(i, 0., clusterResErr);
946
947 // method 2
948 tmp = ((TH2F*)fResiduals->UncheckedAt(kTrackResPerDE+ia))->ProjectionY("tmp",i+1,i+1,"e");
00612ffc 949 GetMean(tmp, sigmaTrack, sigmaTrackErr, 0x0, 0, 0, kFALSE, kFALSE);
7cbb1928 950 delete tmp;
951
952 tmp = ((TH2F*)fResiduals->UncheckedAt(kMCSPerDE+ia))->ProjectionY("tmp",i+1,i+1,"e");
00612ffc 953 GetMean(tmp, sigmaMCS, sigmaMCSErr, 0x0, 0, 0, kFALSE, kFALSE);
7cbb1928 954 delete tmp;
955
956 sigmaCluster = sigmaOut*sigmaOut - sigmaTrack*sigmaTrack;
957 if (sigmaCluster > 0.) {
958 sigmaCluster = TMath::Sqrt(sigmaCluster);
959 sigmaClusterErr = TMath::Sqrt(sigmaOut*sigmaOut*sigmaOutErr*sigmaOutErr + sigmaTrack*sigmaTrack*sigmaTrackErr*sigmaTrackErr) / sigmaCluster;
960 } else {
961 sigmaCluster = 0.;
962 sigmaClusterErr = 0.;
963 }
964 ((TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerDE+ia))->SetPoint(i, i+1, sigmaCluster);
965 ((TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerDE+ia))->SetPointError(i, 0., sigmaClusterErr);
966
967 // compute averaged local chi2
968 tmp = ((TH2F*)fResiduals->UncheckedAt(kLocalChi2PerDE+ia))->ProjectionY("tmp",i+1,i+1,"e");
969 ((TGraphErrors*)fLocalChi2->UncheckedAt(kLocalChi2PerDEMean+ia))->SetPoint(i, i+1, tmp->GetMean());
970 ((TGraphErrors*)fLocalChi2->UncheckedAt(kLocalChi2PerDEMean+ia))->SetPointError(i, 0., tmp->GetMeanError());
971 delete tmp;
972
973 }
974
975 // set graph labels
f4d9245c 976 TAxis* xAxis = ((TH2F*)fResiduals->UncheckedAt(kResidualPerDEClusterOut+ia))->GetXaxis();
977 ((TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerDEMeanClusterIn+ia))->GetXaxis()->Set(fNDE, 0.5, fNDE+0.5);
978 ((TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerDEMeanClusterOut+ia))->GetXaxis()->Set(fNDE, 0.5, fNDE+0.5);
7cbb1928 979 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerDESigma+ia))->GetXaxis()->Set(fNDE, 0.5, fNDE+0.5);
980 ((TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerDE+ia))->GetXaxis()->Set(fNDE, 0.5, fNDE+0.5);
981 ((TGraphErrors*)fLocalChi2->UncheckedAt(kLocalChi2PerDEMean+ia))->GetXaxis()->Set(fNDE, 0.5, fNDE+0.5);
982 for (Int_t i = 1; i <= fNDE; i++) {
983 const char* label = xAxis->GetBinLabel(i);
f4d9245c 984 ((TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerDEMeanClusterIn+ia))->GetXaxis()->SetBinLabel(i, label);
985 ((TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerDEMeanClusterOut+ia))->GetXaxis()->SetBinLabel(i, label);
7cbb1928 986 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerDESigma+ia))->GetXaxis()->SetBinLabel(i, label);
987 ((TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerDE+ia))->GetXaxis()->SetBinLabel(i, label);
988 ((TGraphErrors*)fLocalChi2->UncheckedAt(kLocalChi2PerDEMean+ia))->GetXaxis()->SetBinLabel(i, label);
989 }
990
991 }
992
993 // compute averaged local chi2 per chamber (X+Y)
994 TH2F* h2 = (TH2F*)fResiduals->UncheckedAt(kLocalChi2PerCh+2);
995 g = new TGraphErrors(AliMUONConstants::NTrackingCh());
996 g->SetName("gLocalChi2PerChMean");
997 g->SetTitle("local chi2 per Ch: mean;chamber ID;<local #chi^{2}>");
998 g->SetMarkerStyle(kFullDotLarge);
999 fLocalChi2->AddAtAndExpand(g, kLocalChi2PerChMean+2);
1000 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
1001 TH1D* tmp = h2->ProjectionY("tmp",i+1,i+1,"e");
1002 g->SetPoint(i, i+1, tmp->GetMean());
1003 g->SetPointError(i, 0., tmp->GetMeanError());
1004 delete tmp;
1005 }
1006
1007 // compute averaged local chi2 per DE (X+Y)
1008 h2 = (TH2F*)fResiduals->UncheckedAt(kLocalChi2PerDE+2);
1009 g = new TGraphErrors(fNDE);
1010 g->SetName("gLocalChi2PerDEMean");
1011 g->SetTitle("local chi2 per DE: mean;DE ID;<local #chi^{2}>");
1012 g->SetMarkerStyle(kFullDotLarge);
1013 fLocalChi2->AddAtAndExpand(g, kLocalChi2PerDEMean+2);
1014 for (Int_t i = 0; i < fNDE; i++) {
1015 TH1D* tmp = h2->ProjectionY("tmp",i+1,i+1,"e");
1016 g->SetPoint(i, i+1, tmp->GetMean());
1017 g->SetPointError(i, 0., tmp->GetMeanError());
1018 delete tmp;
1019 }
1020
1021 // set graph labels
1022 g->GetXaxis()->Set(fNDE, 0.5, fNDE+0.5);
1023 for (Int_t i = 1; i <= fNDE; i++) {
1024 const char* label = h2->GetXaxis()->GetBinLabel(i);
1025 g->GetXaxis()->SetBinLabel(i, label);
1026 }
1027
1028 // display
1029 fCanvases = new TObjArray(1000);
1030 fCanvases->SetOwner();
1031
1032 TLegend *lResPerChMean = new TLegend(0.75,0.85,0.99,0.99);
1033 TLegend *lResPerChSigma1 = new TLegend(0.75,0.85,0.99,0.99);
1034 TLegend *lResPerChSigma2 = new TLegend(0.75,0.85,0.99,0.99);
1035 TLegend *lResPerChSigma3 = new TLegend(0.75,0.85,0.99,0.99);
1036
1037 TCanvas* cResPerCh = new TCanvas("cResPerCh","cResPerCh",1200,500);
1038 cResPerCh->Divide(4,2);
1039 for (Int_t ia = 0; ia < 2; ia++) {
1040 cResPerCh->cd(1+4*ia);
f4d9245c 1041 g = (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChMeanClusterOut+ia);
7cbb1928 1042 g->Draw("ap");
1043 g->SetMarkerColor(2);
1044 g->SetLineColor(2);
1045 if (ia == 0) lResPerChMean->AddEntry(g,"cluster out","PL");
f4d9245c 1046 g = (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChMeanClusterIn+ia);
7cbb1928 1047 g->Draw("p");
1048 g->SetMarkerColor(4);
1049 g->SetLineColor(4);
1050 if (ia == 0) lResPerChMean->AddEntry(g,"cluster in","PL");
1051 if (ia == 0) lResPerChMean->Draw();
1052 else lResPerChMean->DrawClone();
1053 cResPerCh->cd(2+4*ia);
f4d9245c 1054 g = (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChSigmaClusterOut+ia);
7cbb1928 1055 g->Draw("ap");
1056 g->SetMinimum(0.);
1057 g->SetMarkerColor(2);
1058 g->SetLineColor(2);
1059 if (ia == 0) lResPerChSigma1->AddEntry(g,"cluster out","PL");
f4d9245c 1060 g = (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChSigmaClusterIn+ia);
7cbb1928 1061 g->Draw("p");
1062 g->SetMarkerColor(4);
1063 g->SetLineColor(4);
1064 if (ia == 0) lResPerChSigma1->AddEntry(g,"cluster in","PL");
1065 g = (TGraphErrors*)fChamberRes->UncheckedAt(kMCSPerChMean+ia);
1066 g->Draw("p");
1067 g->SetMarkerColor(5);
1068 g->SetLineColor(5);
1069 if (ia == 0) lResPerChSigma1->AddEntry(g,"MCS","PL");
1070 g = (TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerChSigma+ia);
1071 g->Draw("p");
1072 g->SetMarkerColor(3);
1073 g->SetLineColor(3);
1074 if (ia == 0) lResPerChSigma1->AddEntry(g,"combined 1","PL");
1075 if (ia == 0) lResPerChSigma1->Draw();
1076 else lResPerChSigma1->DrawClone();
1077 cResPerCh->cd(3+4*ia);
f4d9245c 1078 g = (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerChDispersionClusterOut+ia);
7cbb1928 1079 g->Draw("ap");
1080 g->SetMinimum(0.);
1081 g->SetMarkerColor(2);
1082 g->SetLineColor(2);
1083 if (ia == 0) lResPerChSigma2->AddEntry(g,"cluster out","PL");
1084 g = (TGraphErrors*)fChamberRes->UncheckedAt(kMCSPerChMean+ia);
1085 g->Draw("p");
1086 if (ia == 0) lResPerChSigma2->AddEntry(g,"MCS","PL");
1087 g = (TGraphErrors*)fChamberRes->UncheckedAt(kTrackResPerChMean+ia);
1088 g->Draw("p");
1089 g->SetMarkerColor(4);
1090 g->SetLineColor(4);
1091 if (ia == 0) lResPerChSigma2->AddEntry(g,"track res.","PL");
1092 g = (TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerCh+ia);
1093 g->Draw("p");
1094 if (ia == 0) lResPerChSigma2->AddEntry(g,"combined 2","PL");
1095 if (ia == 0) lResPerChSigma2->Draw();
1096 else lResPerChSigma2->DrawClone();
1097 cResPerCh->cd(4+4*ia);
1098 g = (TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerChSigma+ia);
1099 g->Draw("ap");
1100 g->SetMinimum(0.);
1101 if (ia == 0) lResPerChSigma3->AddEntry(g,"combined 1","PL");
1102 g = (TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerCh+ia);
1103 g->Draw("p");
1104 if (ia == 0) lResPerChSigma3->AddEntry(g,"combined 2","PL");
1105 if (ia == 0) lResPerChSigma3->Draw();
1106 else lResPerChSigma3->DrawClone();
1107 }
1108 fCanvases->AddAtAndExpand(cResPerCh, kResPerCh);
1109
1110 TCanvas* cResPerHalfCh = new TCanvas("cResPerHalfCh","cResPerHalfCh",1200,500);
1111 cResPerHalfCh->Divide(2,2);
1112 for (Int_t ia = 0; ia < 2; ia++) {
1113 cResPerHalfCh->cd(1+2*ia);
f4d9245c 1114 g = (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerHalfChMeanClusterOut+ia);
7cbb1928 1115 g->Draw("ap");
1116 g->SetMarkerColor(2);
1117 g->SetLineColor(2);
f4d9245c 1118 g = (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerHalfChMeanClusterIn+ia);
7cbb1928 1119 g->Draw("p");
1120 g->SetMarkerColor(4);
1121 g->SetLineColor(4);
1122 lResPerChMean->DrawClone();
1123 cResPerHalfCh->cd(2+2*ia);
1124 g = (TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerHalfChSigma+ia);
1125 g->Draw("ap");
1126 g->SetMinimum(0.);
1127 g->SetMarkerColor(3);
1128 g->SetLineColor(3);
1129 g = (TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerHalfCh+ia);
1130 g->Draw("p");
1131 lResPerChSigma3->DrawClone();
1132 }
1133 fCanvases->AddAtAndExpand(cResPerHalfCh, kResPerHalfCh);
1134
1135 TCanvas* cResPerDE = new TCanvas("cResPerDE","cResPerDE",1200,800);
1136 cResPerDE->Divide(1,4);
1137 for (Int_t ia = 0; ia < 2; ia++) {
1138 cResPerDE->cd(1+ia);
f4d9245c 1139 g = (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerDEMeanClusterOut+ia);
7cbb1928 1140 g->Draw("ap");
1141 g->SetMarkerColor(2);
1142 g->SetLineColor(2);
f4d9245c 1143 g = (TGraphErrors*)fChamberRes->UncheckedAt(kResidualPerDEMeanClusterIn+ia);
7cbb1928 1144 g->Draw("p");
1145 g->SetMarkerColor(4);
1146 g->SetLineColor(4);
1147 lResPerChMean->DrawClone();
1148 cResPerDE->cd(3+ia);
1149 g = (TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerDESigma+ia);
1150 g->Draw("ap");
1151 g->SetMinimum(0.);
1152 g->SetMarkerColor(3);
1153 g->SetLineColor(3);
1154 g = (TGraphErrors*)fChamberRes->UncheckedAt(kClusterResPerDE+ia);
1155 g->Draw("p");
1156 lResPerChSigma3->DrawClone();
1157 }
1158 fCanvases->AddAtAndExpand(cResPerDE, kResPerDE);
1159
1160 TCanvas* cResPerChVsP = new TCanvas("cResPerChVsP","cResPerChVsP");
1161 cResPerChVsP->Divide(1,2);
1162 for (Int_t ia = 0; ia < 2; ia++) {
1163 cResPerChVsP->cd(1+ia);
1164 mg = (TMultiGraph*)fChamberRes->UncheckedAt(kCombinedResidualSigmaVsP+ia);
1165 mg->Draw("ap");
1166 }
1167 fCanvases->AddAtAndExpand(cResPerChVsP, kResPerChVsP);
1168
1169 // print results
00612ffc 1170 if (fPrintClResPerCh) {
1171 printf("\nchamber resolution:\n");
1172 printf(" - non-bending:");
1173 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) printf((i==0)?" %5.3f":", %5.3f",newClusterRes[0][i]);
1174 printf("\n - bending:");
1175 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) printf((i==0)?" %6.4f":", %6.4f",newClusterRes[1][i]);
1176 printf("\n\n");
1177 }
1178
1179 if (fPrintClResPerDE) {
1180 Double_t iDE, clRes;
1181 printf("\nDE resolution:\n");
1182 printf(" - non-bending:");
1183 for (Int_t i = 0; i < fNDE; i++) {
1184 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerDESigma))->GetPoint(i, iDE, clRes);
1185 printf((i==0)?" %5.3f":", %5.3f", clRes);
1186 }
1187 printf("\n - bending:");
1188 for (Int_t i = 0; i < fNDE; i++) {
1189 ((TGraphErrors*)fChamberRes->UncheckedAt(kCombinedResidualPerDESigma+1))->GetPoint(i, iDE, clRes);
1190 printf((i==0)?" %6.4f":", %6.4f", clRes);
1191 }
1192 printf("\n\n");
1193 }
7cbb1928 1194
1195 // Post final data.
1196 PostData(3, fLocalChi2);
1197 PostData(4, fChamberRes);
1198}
1199
1200//________________________________________________________________________
1201void AliAnalysisTaskMuonResolution::ModifyClusters(AliMUONTrack& track)
1202{
1203 /// Reset the clusters resolution from the ones given to the task and change
1204 /// the cluster position according to the new alignment parameters if required
1205
1206 Double_t gX,gY,gZ,lX,lY,lZ;
1207
1208 // loop over clusters
1209 Int_t nClusters = track.GetNClusters();
1210 for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
1211
1212 AliMUONVCluster* cl = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
1213
1214 // change their resolution
1215 cl->SetErrXY(fClusterResNB[cl->GetChamberId()], fClusterResB[cl->GetChamberId()]);
1216
1217 // change their position
1218 if (fReAlign) {
1219 gX = cl->GetX();
1220 gY = cl->GetY();
1221 gZ = cl->GetZ();
1222 fOldGeoTransformer->Global2Local(cl->GetDetElemId(),gX,gY,gZ,lX,lY,lZ);
1223 fNewGeoTransformer->Local2Global(cl->GetDetElemId(),lX,lY,lZ,gX,gY,gZ);
1224 cl->SetXYZ(gX,gY,gZ);
1225 }
1226
1227 }
1228
1229}
1230
1231//________________________________________________________________________
1232void AliAnalysisTaskMuonResolution::Zoom(TH1* h, Double_t fractionCut)
1233{
1234 /// Reduce the range of the histogram by removing a given fration of the statistic at each edge
1235 ZoomLeft(h, fractionCut);
1236 ZoomRight(h, fractionCut);
1237}
1238
1239//________________________________________________________________________
1240void AliAnalysisTaskMuonResolution::ZoomLeft(TH1* h, Double_t fractionCut)
1241{
1242 /// Reduce the range of the histogram by removing a given fration of the statistic on the left side
1243 Int_t maxEventsCut = (Int_t) (fractionCut * h->GetEntries());
1244 Int_t nBins = h->GetNbinsX();
1245
1246 // set low edge
1247 Int_t minBin;
1248 Int_t eventsCut = 0;
1249 for (minBin = 1; minBin <= nBins; minBin++) {
1250 eventsCut += (Int_t) h->GetBinContent(minBin);
1251 if (eventsCut > maxEventsCut) break;
1252 }
1253
1254 // set new axis range
1255 h->GetXaxis()->SetRange(--minBin, h->GetXaxis()->GetLast());
1256}
1257
1258//________________________________________________________________________
1259void AliAnalysisTaskMuonResolution::ZoomRight(TH1* h, Double_t fractionCut)
1260{
1261 /// Reduce the range of the histogram by removing a given fration of the statistic on the right side
1262 Int_t maxEventsCut = (Int_t) (fractionCut * h->GetEntries());
1263 Int_t nBins = h->GetNbinsX();
1264
1265 // set high edge
1266 Int_t maxBin;
1267 Int_t eventsCut = 0;
1268 for (maxBin = nBins; maxBin >= 1; maxBin--) {
1269 eventsCut += (Int_t) h->GetBinContent(maxBin);
1270 if (eventsCut > maxEventsCut) break;
1271 }
1272
1273 // set new axis range
1274 h->GetXaxis()->SetRange(h->GetXaxis()->GetFirst(), ++maxBin);
1275}
1276
1277//________________________________________________________________________
00612ffc 1278void AliAnalysisTaskMuonResolution::GetMean(TH1* h, Double_t& mean, Double_t& meanErr, TGraphErrors* g, Int_t i, Double_t x, Bool_t zoom, Bool_t enableFit)
7cbb1928 1279{
00612ffc 1280 /// Fill graph with the mean value and the corresponding error (zooming if required)
1281
1282 if (h->GetEntries() < fgkMinEntries) { // not enough entries
1283
1284 mean = 0.;
1285 meanErr = 0.;
1286
1287 } else if (enableFit && fGaus) { // take the mean of a gaussian fit
1288
1289 fGaus->SetParameters(h->GetEntries(), 0., 0.1);
1290
1291 h->Fit("fGaus", "WWNQ");
1292
1293 mean = fGaus->GetParameter(1);
1294 meanErr = fGaus->GetParError(1);
1295
1296 } else { // take the mean of the distribution
1297
1298 Int_t firstBin = h->GetXaxis()->GetFirst();
1299 Int_t lastBin = h->GetXaxis()->GetLast();
1300
1301 if (zoom) Zoom(h);
1302
1303 mean = h->GetMean();
1304 meanErr = h->GetMeanError();
1305
1306 if (zoom) h->GetXaxis()->SetRange(firstBin,lastBin);
1307
1308 }
1309
1310 // fill graph if required
7cbb1928 1311 if (g) {
1312 g->SetPoint(i, x, mean);
1313 g->SetPointError(i, 0., meanErr);
1314 }
00612ffc 1315
7cbb1928 1316}
1317
1318//________________________________________________________________________
1319void AliAnalysisTaskMuonResolution::GetRMS(TH1* h, Double_t& rms, Double_t& rmsErr, TGraphErrors* g, Int_t i, Double_t x, Bool_t zoom)
1320{
00612ffc 1321 /// Return the dispersion value and the corresponding error (zooming if required) and fill graph if !=0x0
1322
1323 if (h->GetEntries() < fgkMinEntries) { // not enough entries
1324
1325 rms = 0.;
1326 rmsErr = 0.;
1327
1328 } else if (fGaus) { // take the sigma of a gaussian fit
1329
1330 fGaus->SetParameters(h->GetEntries(), 0., 0.1);
1331
1332 h->Fit("fGaus", "WWNQ");
1333
1334 rms = fGaus->GetParameter(2);
1335 rmsErr = fGaus->GetParError(2);
1336
1337 } else { // take the RMS of the distribution
1338
1339 Int_t firstBin = h->GetXaxis()->GetFirst();
1340 Int_t lastBin = h->GetXaxis()->GetLast();
1341
1342 if (zoom) Zoom(h);
1343
1344 rms = h->GetRMS();
1345 rmsErr = h->GetRMSError();
1346
1347 if (zoom) h->GetXaxis()->SetRange(firstBin,lastBin);
1348
1349 }
1350
1351 // fill graph if required
7cbb1928 1352 if (g) {
1353 g->SetPoint(i, x, rms);
1354 g->SetPointError(i, 0., rmsErr);
1355 }
00612ffc 1356
7cbb1928 1357}
1358
1359//________________________________________________________________________
f4d9245c 1360void AliAnalysisTaskMuonResolution::FillSigmaClusterVsP(const TH2* hIn, const TH2* hOut, TGraphErrors* g, Bool_t zoom)
7cbb1928 1361{
1362 /// Fill graph with cluster resolution from combined residuals with cluster in/out (zooming if required)
1363 Double_t sigmaIn, sigmaInErr, sigmaOut, sigmaOutErr, clusterRes, clusterResErr;
1364 for (Int_t j = 1; j <= hIn->GetNbinsX(); j++) {
1365 TH1D* tmp = hIn->ProjectionY("tmp",j,j,"e");
1366 GetRMS(tmp, sigmaIn, sigmaInErr, 0x0, 0, 0., zoom);
1367 delete tmp;
1368 tmp = hOut->ProjectionY("tmp",j,j,"e");
1369 GetRMS(tmp, sigmaOut, sigmaOutErr, 0x0, 0, 0., zoom);
1370 delete tmp;
1371 Double_t p = 0.5 * (hIn->GetBinLowEdge(j) + hIn->GetBinLowEdge(j+1));
1372 Double_t pErr = p - hIn->GetBinLowEdge(j);
1373 clusterRes = TMath::Sqrt(sigmaIn*sigmaOut);
00612ffc 1374 //clusterResErr = (clusterRes > 0.) ? 0.5 * TMath::Sqrt(sigmaInErr*sigmaInErr*sigmaOut*sigmaOut + sigmaIn*sigmaIn*sigmaOutErr*sigmaOutErr) / clusterRes : 0.;
1375 clusterResErr = TMath::Sqrt(sigmaInErr*sigmaOutErr);
7cbb1928 1376 g->SetPoint(j, p, clusterRes);
1377 g->SetPointError(j, pErr, clusterResErr);
1378 }
1379}
1380
1381//__________________________________________________________________________
1382void AliAnalysisTaskMuonResolution::Cov2CovP(const AliMUONTrackParam &param, TMatrixD &covP)
1383{
1384 /// change coordinate system: (X, SlopeX, Y, SlopeY, q/Pyz) -> (X, Y, pX, pY, pZ)
1385 /// parameters (param) are given in the (X, SlopeX, Y, SlopeY, q/Pyz) coordinate system
1386
1387 // Get useful parameters
1388 Double_t slopeX = param.GetNonBendingSlope();
1389 Double_t slopeY = param.GetBendingSlope();
1390 Double_t qOverPYZ = param.GetInverseBendingMomentum();
1391 Double_t pZ = param.Pz();
1392
1393 // compute Jacobian to change the coordinate system from (X,SlopeX,Y,SlopeY,c/pYZ) to (X,Y,pX,pY,pZ)
1394 Double_t dpZdSlopeY = - qOverPYZ * qOverPYZ * pZ * pZ * pZ * slopeY;
1395 Double_t dpZdQOverPYZ = (qOverPYZ != 0.) ? - pZ / qOverPYZ : - FLT_MAX;
1396 TMatrixD jacob(5,5);
1397 jacob.Zero();
1398 jacob(0,0) = 1.;
1399 jacob(1,2) = 1.;
1400 jacob(2,1) = pZ;
1401 jacob(2,3) = slopeX * dpZdSlopeY;
1402 jacob(2,4) = slopeX * dpZdQOverPYZ;
1403 jacob(3,3) = pZ + slopeY * dpZdSlopeY;
1404 jacob(3,4) = slopeY * dpZdQOverPYZ;
1405 jacob(4,3) = dpZdSlopeY;
1406 jacob(4,4) = dpZdQOverPYZ;
1407
1408 // compute covariances in new coordinate system
1409 TMatrixD tmp(param.GetCovariances(),TMatrixD::kMultTranspose,jacob);
1410 covP.Mult(jacob,tmp);
1411}
1412
00612ffc 1413//__________________________________________________________________________
f4d9245c 1414UInt_t AliAnalysisTaskMuonResolution::BuildTriggerWord(const TString& firedTriggerClasses)
00612ffc 1415{
1416 /// build the trigger word from the fired trigger classes and the list of selectable trigger
1417
1418 UInt_t word = 0;
1419
1420 TObjString* trigClasseName = 0x0;
1421 TIter nextTrigger(fSelectTriggerClass);
1422 while ((trigClasseName = static_cast<TObjString*>(nextTrigger()))) {
1423
1424 TRegexp GenericTriggerClasseName(trigClasseName->String());
f4d9245c 1425 if (firedTriggerClasses.Contains(GenericTriggerClasseName)) word |= trigClasseName->GetUniqueID();
00612ffc 1426
1427 }
1428
1429 return word;
1430}
1431