DQM histogram ranges updated. Added new methods. More details in class description...
[u/mrichter/AliRoot.git] / MUON / MUONRecoCheck.C
CommitLineData
b8dc484b 1/**************************************************************************
48217459 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**************************************************************************/
b8dc484b 15
e54bf126 16// $Id$
17
18/// \ingroup macros
19/// \file MUONRecoCheck.C
20/// \brief Utility macro to check the muon reconstruction.
21///
22/// Reconstructed tracks are compared to reference tracks. The reference tracks
23/// are built from AliTrackReference for the hit in chamber (0..9) and from
24/// kinematics (TreeK) for the vertex parameters.
25///
c687aa97 26/// \author Jean-Pierre Cussonneau, Philippe Pillot, Subatech
e54bf126 27
b8dc484b 28// ROOT includes
f202486b 29#include "TMath.h"
b8dc484b 30#include "TClonesArray.h"
31#include "TH1.h"
f202486b 32#include "TH2.h"
c687aa97 33#include "TH3.h"
f202486b 34#include "TGraphErrors.h"
35#include "TF1.h"
b8dc484b 36#include "TFile.h"
c687aa97 37#include "TCanvas.h"
38#include "TLegend.h"
b8dc484b 39
40// STEER includes
a99c3449 41#include "AliCDBManager.h"
c687aa97 42#include "AliLog.h"
b8dc484b 43
44// MUON includes
a99c3449 45#include "AliMUONCDB.h"
b8dc484b 46#include "AliMUONConstants.h"
47#include "AliMUONTrack.h"
48#include "AliMUONRecoCheck.h"
49#include "AliMUONTrackParam.h"
a99c3449 50#include "AliMUONRecoParam.h"
48217459 51#include "AliMUONVTrackStore.h"
f202486b 52#include "AliMUONVCluster.h"
c687aa97 53#include "AliMUONTrackExtrap.h"
b8dc484b 54
c687aa97 55Double_t langaufun(Double_t *x, Double_t *par);
56
57//------------------------------------------------------------------------------------
58void MUONRecoCheck (Int_t nEvent = -1, const char* pathSim="./generated/", const char* esdFileName="AliESDs.root",
f202486b 59 const char* ocdbPath = "local://$ALICE_ROOT/OCDB")
e54bf126 60{
b8dc484b 61
c687aa97 62 AliLog::SetClassDebugLevel("AliMCEvent",-1);
63
64 // ###################################### define histograms ###################################### //
b8dc484b 65 // File for histograms and histogram booking
66 TFile *histoFile = new TFile("MUONRecoCheck.root", "RECREATE");
48217459 67
b8dc484b 68 TH1F *hReconstructible = new TH1F("hReconstructible"," Nb of reconstructible tracks ",15,-0.5,14.5);
69 TH1F *hReco = new TH1F("hReco"," Nb of reconstructed tracks / evt",15,-0.5,14.5);
96ebe67e 70 TH1F *hNClusterComp = new TH1F("hNClusterComp"," Nb of compatible clusters / track ",15,-0.5,14.5);
b8dc484b 71 TH1F *hTrackRefID = new TH1F("hTrackRefID"," track reference ID ",100,-0.5,99.5);
72
c687aa97 73 // momentum resolution at vertex
74 histoFile->mkdir("momentumAtVertex","momentumAtVertex");
75 histoFile->cd("momentumAtVertex");
76
77 const Int_t pNBins = 30;
78 const Double_t pEdges[2] = {0., 300.};
79 const Int_t deltaPAtVtxNBins = 250;
80 const Double_t deltaPAtVtxEdges[2] = {-35., 15.};
81
82 TH1F *hResMomVertex = new TH1F("hResMomVertex"," delta P at vertex;#Delta_{p} (GeV/c)",deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
83
84 TH2D *hResMomVertexVsMom = new TH2D("hResMomVertexVsMom","#Delta_{p} at vertex versus p;p (GeV/c);#Delta_{p} (GeV/c)",2*pNBins,pEdges[0],pEdges[1],deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
85 TH2D *hResMomVertexVsMom_2_3_Deg = new TH2D("hResMomVertexVsMom_2_3_Deg","#Delta_{p} at vertex versus p for tracks between 2 and 3 degrees at absorber end;p (GeV/c);#Delta_{p} (GeV/c)",2*pNBins,pEdges[0],pEdges[1],deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
86 TH2D *hResMomVertexVsMom_3_10_Deg = new TH2D("hResMomVertexVsMom_3_10_Deg","#Delta_{p} at vertex versus p for tracks between 3 and 10 degrees at absorber end;p (GeV/c);#Delta_{p} (GeV/c)",2*pNBins,pEdges[0],pEdges[1],deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
87 TH2D *hResMomVertexVsMom_0_2_DegMC = new TH2D("hResMomVertexVsMom_0_2_DegMC","#Delta_{p} at vertex versus p for tracks with MC angle below 2 degrees;p (GeV/c);#Delta_{p} (GeV/c)",2*pNBins,pEdges[0],pEdges[1],deltaPAtVtxNBins/10,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
88
89 TH2D *hResMomVertexVsPosAbsEnd_0_2_DegMC = new TH2D("hResMomVertexVsPosAbsEnd_0_2_DegMC","#Delta_{p} at vertex versus track position at absorber end for tracks with MC angle < 2 degrees;position (cm);#Delta_{p} (GeV/c)",100,0.,100.,deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
90 TH2D *hResMomVertexVsPosAbsEnd_2_3_DegMC = new TH2D("hResMomVertexVsPosAbsEnd_2_3_DegMC","#Delta_{p} at vertex versus track position at absorber end for tracks with MC angle in [2,3[ degrees;position (cm);#Delta_{p} (GeV/c)",100,0.,100.,deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
91 TH2D *hResMomVertexVsPosAbsEnd_3_10_DegMC = new TH2D("hResMomVertexVsPosAbsEnd_3_10_DegMC","#Delta_{p} at vertex versus track position at absorber end for tracks with MC angle in [3,10[ degrees;position (cm);#Delta_{p} (GeV/c)",100,0.,100.,deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
92
93 TH2D *hResMomVertexVsAngle = new TH2D("hResMomVertexVsAngle","#Delta_{p} at vertex versus track position at absorber end converted to degrees;angle (Deg);#Delta_{p} (GeV/c)",10,0.,10.,deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
94 TH2D *hResMomVertexVsMCAngle = new TH2D("hResMomVertexVsMCAngle","#Delta_{p} at vertex versus MC angle;MC angle (Deg);#Delta_{p} (GeV/c)",10,0.,10.,deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
95 TH3D *hResMomVertexVsAngleVsMom = new TH3D("hResMomVertexVsAngleVsMom","#Delta_{p} at vertex versus track position at absorber end converted to degrees versus momentum;p (GeV/c);angle (Deg);#Delta_{p} (GeV/c)",2*pNBins,pEdges[0],pEdges[1],100,0.,10.,deltaPAtVtxNBins,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1]);
96
97 TGraphErrors* gMeanResMomVertexVsMom = new TGraphErrors(pNBins);
98 gMeanResMomVertexVsMom->SetName("gMeanResMomVertexVsMom");
99 gMeanResMomVertexVsMom->SetTitle("<#Delta_{p}> at vertex versus p;p (GeV/c);<#Delta_{p}> (GeV/c)");
100 TGraphErrors* gMostProbResMomVertexVsMom = new TGraphErrors(pNBins);
101 gMostProbResMomVertexVsMom->SetName("gMostProbResMomVertexVsMom");
102 gMostProbResMomVertexVsMom->SetTitle("Most probable #Delta_{p} at vertex versus p;p (GeV/c);Most prob. #Delta_{p} (GeV/c)");
103 TGraphErrors* gSigmaResMomVertexVsMom = new TGraphErrors(pNBins);
104 gSigmaResMomVertexVsMom->SetName("gSigmaResMomVertexVsMom");
105 gSigmaResMomVertexVsMom->SetTitle("#Delta_{p}/p at vertex versus p;p (GeV/c);#sigma_{p}/p (%)");
106 TF1 *f2 = new TF1("f2",langaufun,deltaPAtVtxEdges[0],deltaPAtVtxEdges[1],4);
107
108 // momentum resolution at first cluster
109 histoFile->mkdir("momentumAtFirstCluster","momentumAtFirstCluster");
110 histoFile->cd("momentumAtFirstCluster");
111
112 const Int_t deltaPAtFirstClNBins = 500;
113 const Double_t deltaPAtFirstClEdges[2] = {-25., 25.};
114
115 TH1F *hResMomFirstCluster = new TH1F("hResMomFirstCluster"," delta P at first cluster;#Delta_{p} (GeV/c)",deltaPAtFirstClNBins,deltaPAtFirstClEdges[0],deltaPAtFirstClEdges[1]);
116 TH2D *hResMomFirstClusterVsMom = new TH2D("hResMomFirstClusterVsMom","#Delta_{p} at first cluster versus p;p (GeV/c);#Delta_{p} (GeV/c)",2*pNBins,pEdges[0],pEdges[1],deltaPAtFirstClNBins,deltaPAtFirstClEdges[0],deltaPAtFirstClEdges[1]);
117
118 TGraphErrors* gMeanResMomFirstClusterVsMom = new TGraphErrors(pNBins);
119 gMeanResMomFirstClusterVsMom->SetName("gMeanResMomFirstClusterVsMom");
120 gMeanResMomFirstClusterVsMom->SetTitle("<#Delta_{p}> at first cluster versus p;p (GeV/c);<#Delta_{p}> (GeV/c)");
121 TGraphErrors* gSigmaResMomFirstClusterVsMom = new TGraphErrors(pNBins);
122 gSigmaResMomFirstClusterVsMom->SetName("gSigmaResMomFirstClusterVsMom");
123 gSigmaResMomFirstClusterVsMom->SetTitle("#Delta_{p}/p at first cluster versus p;p (GeV/c);#sigma_{p}/p (%)");
124 TF1* f = new TF1("f","gausn");
125
126 // cluster resolution
127 histoFile->mkdir("clusters","clusters");
128 histoFile->cd("clusters");
129
f202486b 130 TH1F* hResidualXInCh[AliMUONConstants::NTrackingCh()];
131 TH1F* hResidualYInCh[AliMUONConstants::NTrackingCh()];
132 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
133 hResidualXInCh[i] = new TH1F(Form("hResidualXInCh%d",i+1), Form("cluster-track residual-X distribution in chamber %d;#Delta_{X} (cm)",i+1), 1000, -1., 1.);
134 hResidualYInCh[i] = new TH1F(Form("hResidualYInCh%d",i+1), Form("cluster-track residual-Y distribution in chamber %d;#Delta_{Y} (cm)",i+1), 1000, -0.5, 0.5);
135 }
c687aa97 136
f202486b 137 TGraphErrors* gResidualXPerChMean = new TGraphErrors(AliMUONConstants::NTrackingCh());
138 gResidualXPerChMean->SetName("gResidualXPerChMean");
c687aa97 139 gResidualXPerChMean->SetTitle("cluster-track residual-X per Ch: mean;chamber ID;<#Delta_{X}> (cm)");
f202486b 140 gResidualXPerChMean->SetMarkerStyle(kFullDotLarge);
141 TGraphErrors* gResidualYPerChMean = new TGraphErrors(AliMUONConstants::NTrackingCh());
142 gResidualYPerChMean->SetName("gResidualYPerChMean");
143 gResidualYPerChMean->SetTitle("cluster-track residual-Y per Ch: mean;chamber ID;<#Delta_{Y}> (cm)");
144 gResidualYPerChMean->SetMarkerStyle(kFullDotLarge);
145 TGraphErrors* gResidualXPerChSigma = new TGraphErrors(AliMUONConstants::NTrackingCh());
146 gResidualXPerChSigma->SetName("gResidualXPerChSigma");
147 gResidualXPerChSigma->SetTitle("cluster-track residual-X per Ch: sigma;chamber ID;#sigma_{X} (cm)");
148 gResidualXPerChSigma->SetMarkerStyle(kFullDotLarge);
149 TGraphErrors* gResidualYPerChSigma = new TGraphErrors(AliMUONConstants::NTrackingCh());
150 gResidualYPerChSigma->SetName("gResidualYPerChSigma");
c687aa97 151 gResidualYPerChSigma->SetTitle("cluster-track residual-Y per Ch: sigma;chamber ID;#sigma_{Y} (cm)");
f202486b 152 gResidualYPerChSigma->SetMarkerStyle(kFullDotLarge);
48217459 153
c687aa97 154 // ###################################### initialize ###################################### //
a99c3449 155 AliMUONRecoCheck rc(esdFileName, pathSim);
156
157 // load necessary data from OCDB
158 AliCDBManager::Instance()->SetDefaultStorage(ocdbPath);
159 AliCDBManager::Instance()->SetRun(rc.GetRunNumber());
c687aa97 160 if (!AliMUONCDB::LoadField()) return;
161 AliMUONTrackExtrap::SetField();
a99c3449 162 AliMUONRecoParam* recoParam = AliMUONCDB::LoadRecoParam();
163 if (!recoParam) return;
a0bfad0e 164
f202486b 165 // get sigma cut from recoParam to associate clusters with TrackRefs in case the label are not used
a99c3449 166 Double_t sigmaCut = (recoParam->ImproveTracks()) ? recoParam->GetSigmaCutForImprovement() : recoParam->GetSigmaCutForTracking();
f202486b 167 // compute the mask of requested stations from recoParam
168 UInt_t requestedStationMask = 0;
169 for (Int_t i = 0; i < 5; i++) if (recoParam->RequestStation(i)) requestedStationMask |= ( 1 << i );
170 // get from recoParam whether a track need 2 chambers hit in the same station (4 or 5) or not to be reconstructible
171 Bool_t request2ChInSameSt45 = !recoParam->MakeMoreTrackCandidates();
48217459 172
173 Int_t nevents = rc.NumberOfEvents();
b8dc484b 174
edcc5b56 175 if (nevents < nEvent || nEvent < 0) nEvent = nevents;
b8dc484b 176
177 Int_t ievent;
178 Int_t nReconstructibleTracks = 0;
179 Int_t nReconstructedTracks = 0;
180 Int_t nReconstructibleTracksCheck = 0;
f202486b 181 AliMUONTrackParam *trackParam;
182 Double_t x1,y1,z1,pX1,pY1,pZ1,p1,pT1;
183 Double_t x2,y2,z2,pX2,pY2,pZ2,p2,pT2;
c687aa97 184 Double_t xAbs,yAbs,dAbs,aAbs,aMC;
48217459 185
c687aa97 186 // ###################################### fill histograms ###################################### //
48217459 187 for (ievent=0; ievent<nEvent; ievent++)
188 {
c687aa97 189 if ((ievent+1)%100 == 0) cout<<"\rEvent processing... "<<ievent+1<<flush;
b8dc484b 190
a99c3449 191 AliMUONVTrackStore* trackStore = rc.ReconstructedTracks(ievent, kFALSE);
f202486b 192 AliMUONVTrackStore* trackRefStore = rc.ReconstructibleTracks(ievent, requestedStationMask, request2ChInSameSt45);
b8dc484b 193
48217459 194 hReconstructible->Fill(trackRefStore->GetSize());
195 hReco->Fill(trackStore->GetSize());
196
197 nReconstructibleTracks += trackRefStore->GetSize();
198 nReconstructedTracks += trackStore->GetSize();
199
f202486b 200 // loop over trackRef
48217459 201 TIter next(trackRefStore->CreateIterator());
202 AliMUONTrack* trackRef;
48217459 203 while ( ( trackRef = static_cast<AliMUONTrack*>(next()) ) )
204 {
48217459 205
f202486b 206 hTrackRefID->Fill(trackRef->GetMCLabel());
207
208 AliMUONTrack* trackMatched = 0x0;
209 Int_t nMatchClusters = 0;
210
211 // loop over trackReco and look for compatible track
48217459 212 TIter next2(trackStore->CreateIterator());
213 AliMUONTrack* trackReco;
48217459 214 while ( ( trackReco = static_cast<AliMUONTrack*>(next2()) ) )
215 {
f202486b 216
217 // check if trackReco is compatible with trackRef
218 Int_t n = 0;
219 if (trackReco->Match(*trackRef, sigmaCut, nMatchClusters)) {
220 trackMatched = trackReco;
221 nMatchClusters = n;
222 break;
61fed964 223 }
f202486b 224
48217459 225 }
226
f202486b 227 if (trackMatched) { // tracking requirements verified, track is found
48217459 228 nReconstructibleTracksCheck++;
f202486b 229 hNClusterComp->Fill(nMatchClusters);
c687aa97 230
231 // compute track position at the end of the absorber
232 AliMUONTrackParam trackParamAtAbsEnd(*((AliMUONTrackParam*)trackMatched->GetTrackParamAtCluster()->First()));
233 AliMUONTrackExtrap::ExtrapToZ(&trackParamAtAbsEnd, AliMUONConstants::AbsZEnd());
234 xAbs = trackParamAtAbsEnd.GetNonBendingCoor();
235 yAbs = trackParamAtAbsEnd.GetBendingCoor();
236 dAbs = TMath::Sqrt(xAbs*xAbs + yAbs*yAbs);
237 aAbs = TMath::ATan(-dAbs/AliMUONConstants::AbsZEnd()) * TMath::RadToDeg();
238
48217459 239 trackParam = trackRef->GetTrackParamAtVertex();
240 x1 = trackParam->GetNonBendingCoor();
241 y1 = trackParam->GetBendingCoor();
242 z1 = trackParam->GetZ();
243 pX1 = trackParam->Px();
244 pY1 = trackParam->Py();
245 pZ1 = trackParam->Pz();
246 p1 = trackParam->P();
f202486b 247 pT1 = TMath::Sqrt(pX1*pX1 + pY1*pY1);
c687aa97 248 aMC = TMath::ATan(-pT1/pZ1) * TMath::RadToDeg();
249
f202486b 250 trackParam = trackMatched->GetTrackParamAtVertex();
48217459 251 x2 = trackParam->GetNonBendingCoor();
252 y2 = trackParam->GetBendingCoor();
253 z2 = trackParam->GetZ();
254 pX2 = trackParam->Px();
255 pY2 = trackParam->Py();
256 pZ2 = trackParam->Pz();
257 p2 = trackParam->P();
f202486b 258 pT2 = TMath::Sqrt(pX2*pX2 + pY2*pY2);
48217459 259
260 hResMomVertex->Fill(p2-p1);
f202486b 261 hResMomVertexVsMom->Fill(p1,p2-p1);
c687aa97 262 hResMomVertexVsAngleVsMom->Fill(p1,aAbs,p2-p1);
263 if (aAbs > 2. && aAbs < 3.) hResMomVertexVsMom_2_3_Deg->Fill(p1,p2-p1);
264 else if (aAbs >= 3. && aAbs < 10.) hResMomVertexVsMom_3_10_Deg->Fill(p1,p2-p1);
265 if (aMC < 2.) {
266 hResMomVertexVsMom_0_2_DegMC->Fill(p1,p2-p1);
267 hResMomVertexVsPosAbsEnd_0_2_DegMC->Fill(dAbs,p2-p1);
268 }
269 else if (aMC >= 2. && aMC < 3) hResMomVertexVsPosAbsEnd_2_3_DegMC->Fill(dAbs,p2-p1);
270 else if (aMC >= 3. && aMC < 10.) hResMomVertexVsPosAbsEnd_3_10_DegMC->Fill(dAbs,p2-p1);
271 hResMomVertexVsAngle->Fill(aAbs,p2-p1);
272 hResMomVertexVsMCAngle->Fill(aMC,p2-p1);
f202486b 273
96ebe67e 274 trackParam = (AliMUONTrackParam*) trackRef->GetTrackParamAtCluster()->First();
48217459 275 x1 = trackParam->GetNonBendingCoor();
276 y1 = trackParam->GetBendingCoor();
277 z1 = trackParam->GetZ();
278 pX1 = trackParam->Px();
279 pY1 = trackParam->Py();
280 pZ1 = trackParam->Pz();
281 p1 = trackParam->P();
f202486b 282 pT1 = TMath::Sqrt(pX1*pX1 + pY1*pY1);
283
f202486b 284 trackParam = (AliMUONTrackParam*) trackMatched->GetTrackParamAtCluster()->First();
48217459 285 x2 = trackParam->GetNonBendingCoor();
286 y2 = trackParam->GetBendingCoor();
287 z2 = trackParam->GetZ();
288 pX2 = trackParam->Px();
289 pY2 = trackParam->Py();
290 pZ2 = trackParam->Pz();
291 p2 = trackParam->P();
f202486b 292 pT2 = TMath::Sqrt(pX2*pX2 + pY2*pY2);
48217459 293
96ebe67e 294 hResMomFirstCluster->Fill(p2-p1);
f202486b 295 hResMomFirstClusterVsMom->Fill(p1,p2-p1);
296
297 // Fill residuals
298 // Loop over clusters of first track
299 AliMUONTrackParam* trackParamAtCluster1 = (AliMUONTrackParam*) trackMatched->GetTrackParamAtCluster()->First();
300 while (trackParamAtCluster1) {
301 AliMUONVCluster* cluster1 = trackParamAtCluster1->GetClusterPtr();
302 AliMUONTrackParam* trackParamAtCluster2 = (AliMUONTrackParam*) trackRef->GetTrackParamAtCluster()->First();
303 while (trackParamAtCluster2) {
304 AliMUONVCluster* cluster2 = trackParamAtCluster2->GetClusterPtr();
305 if (cluster1->GetDetElemId() == cluster2->GetDetElemId()) {
306 hResidualXInCh[cluster1->GetChamberId()]->Fill(cluster1->GetX() - cluster2->GetX());
307 hResidualYInCh[cluster1->GetChamberId()]->Fill(cluster1->GetY() - cluster2->GetY());
308 break;
309 }
310 trackParamAtCluster2 = (AliMUONTrackParam*) trackRef->GetTrackParamAtCluster()->After(trackParamAtCluster2);
311 }
312 trackParamAtCluster1 = (AliMUONTrackParam*) trackMatched->GetTrackParamAtCluster()->After(trackParamAtCluster1);
313 }
314
b8dc484b 315 }
f202486b 316
b8dc484b 317 } // end loop track ref.
b8dc484b 318
48217459 319 } // end loop on event
c687aa97 320 cout<<"\rEvent processing... "<<nevents<<" done"<<endl;
48217459 321
c687aa97 322 // ###################################### compute stuff ###################################### //
323 // compute momentum resolution at vertex versus p
324 Int_t rebinFactorX = TMath::Max(hResMomVertexVsMom->GetNbinsX()/pNBins, 1);
325 for (Int_t i = rebinFactorX; i <= hResMomVertexVsMom->GetNbinsX(); i+=rebinFactorX) {
326 cout<<"\rFitting momentum residuals at vertex... "<<i/rebinFactorX<<"/"<<pNBins<<flush;
327 TH1D *tmp = hResMomVertexVsMom->ProjectionY("tmp",i-rebinFactorX+1,i,"e");
328 Double_t p = 0.5 * (hResMomVertexVsMom->GetBinLowEdge(i-rebinFactorX+1) + hResMomVertexVsMom->GetBinLowEdge(i+1));
329 f2->SetParameters(0.2,0.,(Double_t)tmp->GetEntries(),1.);
330 tmp->Fit("f2","WWNQ");
331 Double_t fwhm = f2->GetParameter(0);
332 Double_t sigma = f2->GetParameter(3);
333 Double_t sigmaP = TMath::Sqrt(sigma*sigma + fwhm*fwhm/(8.*log(2.)));
334 Int_t rebin = TMath::Max(Int_t(0.5*sigmaP/tmp->GetBinWidth(1)),1);
335 while (deltaPAtVtxNBins%rebin!=0) rebin--;
336 tmp->Rebin(rebin);
337 tmp->Fit("f2","NQ");
338 fwhm = f2->GetParameter(0);
339 sigma = f2->GetParameter(3);
340 sigmaP = TMath::Sqrt(sigma*sigma + fwhm*fwhm/(8.*log(2.)));
341 Double_t fwhmErr = f2->GetParError(0);
342 Double_t sigmaErr = f2->GetParError(3);
343 Double_t sigmaPErr = TMath::Sqrt(sigma*sigma*sigmaErr*sigmaErr + fwhm*fwhm*fwhmErr*fwhmErr/(64.*log(2.)*log(2.))) / sigmaP;
344 gMeanResMomVertexVsMom->SetPoint(i/rebinFactorX-1,p,tmp->GetMean());
345 gMeanResMomVertexVsMom->SetPointError(i/rebinFactorX-1,hResMomVertexVsMom->GetBinWidth(i),tmp->GetMeanError());
346 gMostProbResMomVertexVsMom->SetPoint(i/rebinFactorX-1,p,-f2->GetParameter(1));
347 gMostProbResMomVertexVsMom->SetPointError(i/rebinFactorX-1,hResMomVertexVsMom->GetBinWidth(i),f2->GetParError(1));
348 gSigmaResMomVertexVsMom->SetPoint(i/rebinFactorX-1,p,100.*sigmaP/p);
349 gSigmaResMomVertexVsMom->SetPointError(i/rebinFactorX-1,hResMomVertexVsMom->GetBinWidth(i),100.*sigmaPErr/p);
f202486b 350 delete tmp;
351 }
c687aa97 352 cout<<"\rFitting momentum residuals at vertex... "<<pNBins<<"/"<<pNBins<<endl;
353
354 // compute momentum resolution at first cluster versus p
355 rebinFactorX = TMath::Max(hResMomFirstClusterVsMom->GetNbinsX()/pNBins, 1);
356 for (Int_t i = rebinFactorX; i <= hResMomFirstClusterVsMom->GetNbinsX(); i+=rebinFactorX) {
357 cout<<"\rFitting momentum residuals at first cluster... "<<i/rebinFactorX<<"/"<<pNBins<<flush;
358 TH1D *tmp = hResMomFirstClusterVsMom->ProjectionY("tmp",i-rebinFactorX+1,i,"e");
359 Double_t p = 0.5 * (hResMomFirstClusterVsMom->GetBinLowEdge(i-rebinFactorX+1) + hResMomFirstClusterVsMom->GetBinLowEdge(i+1));
360 f->SetParameters(tmp->GetEntries(),0.,1.);
361 tmp->Fit("f","WWNQ");
362 Int_t rebin = TMath::Max(Int_t(0.5*f->GetParameter(2)/tmp->GetBinWidth(1)),1);
363 while (deltaPAtFirstClNBins%rebin!=0) rebin--;
364 tmp->Rebin(rebin);
365 tmp->Fit("f","NQ");
366 gMeanResMomFirstClusterVsMom->SetPoint(i/rebinFactorX-1,p,f->GetParameter(1));
367 gMeanResMomFirstClusterVsMom->SetPointError(i/rebinFactorX-1,hResMomFirstClusterVsMom->GetBinWidth(i),f->GetParError(1));
368 gSigmaResMomFirstClusterVsMom->SetPoint(i/rebinFactorX-1,p,100.*f->GetParameter(2)/p);
369 gSigmaResMomFirstClusterVsMom->SetPointError(i/rebinFactorX-1,hResMomFirstClusterVsMom->GetBinWidth(i),100.*f->GetParError(2)/p);
f202486b 370 delete tmp;
371 }
c687aa97 372 cout<<"\rFitting momentum residuals at first cluster... "<<pNBins<<"/"<<pNBins<<endl;
f202486b 373
374 // compute residual mean and dispersion
375 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
376 hResidualXInCh[i]->GetXaxis()->SetRangeUser(-3.*hResidualXInCh[i]->GetRMS(), 3.*hResidualXInCh[i]->GetRMS());
377 gResidualXPerChMean->SetPoint(i, i+1, hResidualXInCh[i]->GetMean());
378 gResidualXPerChMean->SetPointError(i, 0., hResidualXInCh[i]->GetMeanError());
379 gResidualXPerChSigma->SetPoint(i, i+1, hResidualXInCh[i]->GetRMS());
380 gResidualXPerChSigma->SetPointError(i, 0., hResidualXInCh[i]->GetRMSError());
381 hResidualXInCh[i]->GetXaxis()->SetRange(0,0);
382 hResidualYInCh[i]->GetXaxis()->SetRangeUser(-3.*hResidualYInCh[i]->GetRMS(), 3.*hResidualYInCh[i]->GetRMS());
383 gResidualYPerChMean->SetPoint(i, i+1, hResidualYInCh[i]->GetMean());
384 gResidualYPerChMean->SetPointError(i, 0., hResidualYInCh[i]->GetMeanError());
385 gResidualYPerChSigma->SetPoint(i, i+1, hResidualYInCh[i]->GetRMS());
386 gResidualYPerChSigma->SetPointError(i, 0., hResidualYInCh[i]->GetRMSError());
387 hResidualYInCh[i]->GetXaxis()->SetRange(0,0);
388 }
389
c687aa97 390 // ###################################### display histograms ###################################### //
391 // diplay momentum residual for different angular region
392 TCanvas cResMom("cResMom", "momentum residual at vertex in 3 angular regions");
393 cResMom.cd();
394 hResMomVertex->Draw();
395 TH1D *hResMomVertex_0_2_Deg = hResMomVertexVsAngle->ProjectionY("hResMomVertex_0_2_Deg",1,2);
396 hResMomVertex_0_2_Deg->Draw("sames");
397 hResMomVertex_0_2_Deg->SetLineColor(2);
398 TH1D *hResMomVertex_2_3_Deg = hResMomVertexVsAngle->ProjectionY("hResMomVertex_2_3_Deg",3,3);
399 hResMomVertex_2_3_Deg->Draw("sames");
400 hResMomVertex_2_3_Deg->SetLineColor(4);
401 TH1D *hResMomVertex_3_10_Deg = hResMomVertexVsAngle->ProjectionY("hResMomVertex_3_10_Deg",4,10);
402 hResMomVertex_3_10_Deg->Draw("sames");
403 hResMomVertex_3_10_Deg->SetLineColor(3);
404
405 // diplay momentum residual for different angular region
406 TCanvas cResMomMC("cResMomMC", "momentum residual at vertex in 3 MC angular regions");
407 cResMomMC.cd();
408 hResMomVertex->Draw();
409 TH1D *hResMomVertex_0_2_DegMC = hResMomVertexVsMCAngle->ProjectionY("hResMomVertex_0_2_DegMC",1,2);
410 hResMomVertex_0_2_DegMC->Draw("sames");
411 hResMomVertex_0_2_DegMC->SetLineColor(2);
412 TH1D *hResMomVertex_2_3_DegMC = hResMomVertexVsMCAngle->ProjectionY("hResMomVertex_2_3_DegMC",3,3);
413 hResMomVertex_2_3_DegMC->Draw("sames");
414 hResMomVertex_2_3_DegMC->SetLineColor(4);
415 TH1D *hResMomVertex_3_10_DegMC = hResMomVertexVsMCAngle->ProjectionY("hResMomVertex_3_10_DegMC",4,10);
416 hResMomVertex_3_10_DegMC->Draw("sames");
417 hResMomVertex_3_10_DegMC->SetLineColor(3);
418
419 // diplay momentum residual versus position at absorber end for different MC angular region
420 TCanvas cResMomVsPos("cResMomVsPos", "momentum residual at vertex versus position at absorber end in 3 MC angular regions");
421 cResMomVsPos.cd();
422 hResMomVertexVsPosAbsEnd_0_2_DegMC->Draw();
423 hResMomVertexVsPosAbsEnd_0_2_DegMC->SetMarkerColor(2);
424 hResMomVertexVsPosAbsEnd_2_3_DegMC->Draw("sames");
425 hResMomVertexVsPosAbsEnd_2_3_DegMC->SetMarkerColor(4);
426 hResMomVertexVsPosAbsEnd_3_10_DegMC->Draw("sames");
427 hResMomVertexVsPosAbsEnd_3_10_DegMC->SetMarkerColor(3);
428
429 // diplay momentum residual of tracks between 2 and 3 deg. for different momentum values
430 Int_t pNBinsShown = 10;
431 TLegend lResMom_2_3_Deg(0.15,0.25,0.3,0.85);
432 TCanvas cResMom_2_3_Deg("cResMom_2_3_Deg", "momentum residual for tracks between 2 and 3 degrees");
433 cResMom_2_3_Deg.cd();
434 TH1D* proj = 0x0;
435 hResMomVertexVsMom_2_3_Deg->Sumw2();
436 rebinFactorX = TMath::Max(hResMomVertexVsMom_2_3_Deg->GetNbinsX()/pNBinsShown, 1);
437 for (Int_t i = rebinFactorX; i <= hResMomVertexVsMom_2_3_Deg->GetNbinsX(); i+=rebinFactorX) {
438 cout<<"\rFitting momentum residuals at vertex (tracks in [2,3] deg.)... "<<i/rebinFactorX<<"/"<<pNBinsShown<<flush;
439 proj = hResMomVertexVsMom_2_3_Deg->ProjectionY(Form("hRes23_%d",i/rebinFactorX),i-rebinFactorX+1,i);
440 if (proj->GetEntries() > 0) proj->Scale(1./proj->GetEntries());
441 proj->Draw((i==rebinFactorX)?"hist":"histsames");
442 proj->SetLineColor(i/rebinFactorX);
443 f2->SetParameters(0.2,0.,1.,1.);
444 f2->SetLineColor(i/rebinFactorX);
445 proj->Fit("f2","WWNQ","sames");
446 Double_t fwhm = f2->GetParameter(0);
447 Double_t sigma = f2->GetParameter(3);
448 Double_t sigmaP = TMath::Sqrt(sigma*sigma + fwhm*fwhm/(8.*log(2.)));
449 Int_t rebin = TMath::Max(Int_t(0.5*sigmaP/proj->GetBinWidth(1)),1);
450 while (deltaPAtVtxNBins%rebin!=0) rebin--;
451 proj->Rebin(rebin);
452 proj->Scale(1./rebin);
453 proj->Fit("f2","Q","sames");
454 Double_t p = 0.5 * (hResMomVertexVsMom_2_3_Deg->GetBinLowEdge(i-rebinFactorX+1) + hResMomVertexVsMom_2_3_Deg->GetBinLowEdge(i+1));
455 lResMom_2_3_Deg.AddEntry(proj,Form("%5.1f GeV",p));
456 }
457 cout<<"\rFitting momentum residuals at vertex (tracks in [2,3] deg.)... "<<pNBinsShown<<"/"<<pNBinsShown<<endl;
458 lResMom_2_3_Deg.Draw("same");
b8dc484b 459
c687aa97 460 // diplay momentum residual of tracks between 3 and 10 deg. for different momentum values
461 pNBinsShown = 10;
462 TLegend lResMom_3_10_Deg(0.15,0.25,0.3,0.85);
463 TCanvas cResMom_3_10_Deg("cResMom_3_10_Deg", "momentum residual for tracks between 3 and 10 degrees");
464 cResMom_3_10_Deg.cd();
465 proj = 0x0;
466 hResMomVertexVsMom_3_10_Deg->Sumw2();
467 rebinFactorX = TMath::Max(hResMomVertexVsMom_3_10_Deg->GetNbinsX()/pNBinsShown, 1);
468 for (Int_t i = rebinFactorX; i <= hResMomVertexVsMom_3_10_Deg->GetNbinsX(); i+=rebinFactorX) {
469 cout<<"\rFitting momentum residuals at vertex (tracks in [3,10] deg.)... "<<i/rebinFactorX<<"/"<<pNBinsShown<<flush;
470 proj = hResMomVertexVsMom_3_10_Deg->ProjectionY(Form("hRes310_%d",i/rebinFactorX),i-rebinFactorX+1,i);
471 if (proj->GetEntries() > 0) proj->Scale(1./proj->GetEntries());
472 proj->Draw((i==rebinFactorX)?"hist":"histsames");
473 proj->SetLineColor(i/rebinFactorX);
474 f2->SetParameters(0.2,0.,1.,1.);
475 f2->SetLineColor(i/rebinFactorX);
476 proj->Fit("f2","WWNQ","sames");
477 Double_t fwhm = f2->GetParameter(0);
478 Double_t sigma = f2->GetParameter(3);
479 Double_t sigmaP = TMath::Sqrt(sigma*sigma + fwhm*fwhm/(8.*log(2.)));
480 Int_t rebin = TMath::Max(Int_t(0.5*sigmaP/proj->GetBinWidth(1)),1);
481 while (deltaPAtVtxNBins%rebin!=0) rebin--;
482 proj->Rebin(rebin);
483 proj->Scale(1./rebin);
484 proj->Fit("f2","Q","sames");
485 Double_t p = 0.5 * (hResMomVertexVsMom_3_10_Deg->GetBinLowEdge(i-rebinFactorX+1) + hResMomVertexVsMom_3_10_Deg->GetBinLowEdge(i+1));
486 lResMom_3_10_Deg.AddEntry(proj,Form("%5.1f GeV",p));
487 }
488 cout<<"\rFitting momentum residuals at vertex (tracks in [3,10] deg.)... "<<pNBinsShown<<"/"<<pNBinsShown<<endl;
489 lResMom_3_10_Deg.Draw("same");
490
491 // diplay momentum residuals of tracks with MC angle < 2 deg. for different momentum values
492 pNBinsShown = 5;
493 TLegend lResMom_0_2_DegMC(0.15,0.25,0.3,0.85);
494 TCanvas cResMom_0_2_DegMC("cResMom_0_2_DegMC", "momentum residuals for tracks with MC angle < 2 degrees");
495 cResMom_0_2_DegMC.cd();
496 proj = 0x0;
497 hResMomVertexVsMom_0_2_DegMC->Sumw2();
498 rebinFactorX = TMath::Max(hResMomVertexVsMom_0_2_DegMC->GetNbinsX()/pNBinsShown, 1);
499 for (Int_t i = rebinFactorX; i <= hResMomVertexVsMom_0_2_DegMC->GetNbinsX(); i+=rebinFactorX) {
500 proj = hResMomVertexVsMom_0_2_DegMC->ProjectionY(Form("hRes02_%d",i/rebinFactorX),i-rebinFactorX+1,i);
501 if (proj->GetEntries() > 0) proj->Scale(1./proj->GetEntries());
502 proj->Draw((i==rebinFactorX)?"hist":"histsames");
503 proj->SetLineColor(i/rebinFactorX);
504 proj->SetLineWidth(2);
505 Double_t p = 0.5 * (hResMomVertexVsMom_0_2_DegMC->GetBinLowEdge(i-rebinFactorX+1) + hResMomVertexVsMom_0_2_DegMC->GetBinLowEdge(i+1));
506 lResMom_0_2_DegMC.AddEntry(proj,Form("%5.1f GeV",p));
507 }
508 lResMom_0_2_DegMC.Draw("same");
509
510 // ###################################### save histogram ###################################### //
b8dc484b 511 histoFile->Write();
c687aa97 512
513 histoFile->cd("momentumAtVertex");
514 gMeanResMomVertexVsMom->Write();
515 gMostProbResMomVertexVsMom->Write();
516 gSigmaResMomVertexVsMom->Write();
517 cResMom.Write();
518 cResMomMC.Write();
519 cResMomVsPos.Write();
520 cResMom_2_3_Deg.Write();
521 cResMom_3_10_Deg.Write();
522 cResMom_0_2_DegMC.Write();
523
524 histoFile->cd("momentumAtFirstCluster");
525 gMeanResMomFirstClusterVsMom->Write();
526 gSigmaResMomFirstClusterVsMom->Write();
527
528 histoFile->cd("clusters");
f202486b 529 gResidualXPerChMean->Write();
530 gResidualXPerChSigma->Write();
531 gResidualYPerChMean->Write();
532 gResidualYPerChSigma->Write();
c687aa97 533
b8dc484b 534 histoFile->Close();
c687aa97 535
536 printf(" nb of reconstructible tracks: %d \n", nReconstructibleTracks);
537 printf(" nb of reconstructed tracks: %d \n", nReconstructedTracks);
538 printf(" nb of reconstructible tracks which are reconstructed: %d \n", nReconstructibleTracksCheck);
539
540}
541
542//------------------------------------------------------------------------------------
543Double_t langaufun(Double_t *x, Double_t *par) {
544
545 //Fit parameters:
546 //par[0]=Width (scale) parameter of Landau density
547 //par[1]=Most Probable (MP, location) parameter of Landau density
548 //par[2]=Total area (integral -inf to inf, normalization constant)
549 //par[3]=Width (sigma) of convoluted Gaussian function
550 //
551 //In the Landau distribution (represented by the CERNLIB approximation),
552 //the maximum is located at x=-0.22278298 with the location parameter=0.
553 //This shift is corrected within this function, so that the actual
554 //maximum is identical to the MP parameter.
555
556 // Numeric constants
557 Double_t invsq2pi = 0.3989422804014; // (2 pi)^(-1/2)
558 Double_t mpshift = -0.22278298; // Landau maximum location
559
560 // Control constants
561 Double_t np = 100.0; // number of convolution steps
562 Double_t sc = 5.0; // convolution extends to +-sc Gaussian sigmas
563
564 // Variables
565 Double_t xx;
566 Double_t mpc;
567 Double_t fland;
568 Double_t sum = 0.0;
569 Double_t xlow,xupp;
570 Double_t step;
571 Double_t i;
572
573
574 // MP shift correction
575 mpc = par[1] - mpshift * par[0];
576
577 // Range of convolution integral
578 xlow = x[0] - sc * par[3];
579 xupp = x[0] + sc * par[3];
580
581 step = (xupp-xlow) / np;
582
583 // Convolution integral of Landau and Gaussian by sum
584 for(i=1.0; i<=np/2; i++) {
585 xx = xlow + (i-.5) * step;
586 //change x -> -x because the tail of the Landau is at the left here...
587 fland = TMath::Landau(-xx,mpc,par[0]) / par[0];
588 sum += fland * TMath::Gaus(x[0],xx,par[3]);
589
590 //change x -> -x because the tail of the Landau is at the left here...
591 xx = xupp - (i-.5) * step;
592 fland = TMath::Landau(-xx,mpc,par[0]) / par[0];
593 sum += fland * TMath::Gaus(x[0],xx,par[3]);
594 }
595
596 return (par[2] * step * sum * invsq2pi / par[3]);
b8dc484b 597}
598