1 #include "AliAnalysisMuMuNch.h"
5 * \ingroup pwg-muon-mumu
7 * \class AliAnalysisMuMuNch
9 * SPD tracklet to Nch analysis
11 * The idea is that this sub-analysis is used first (within the AliAnalysisTaskMuMu sub-framework)
12 * in order to compute the number of charged particles within an event, so that information
13 * can be used in subsequent sub-analysis, like the invariant mass or mean pt ones.
17 #include "AliInputEventHandler.h"
18 #include "AliMultiplicity.h"
19 #include "AliAODTracklets.h"
20 #include "AliAnalysisMuonUtility.h"
22 #include "AliAODEvent.h"
23 #include "AliESDEvent.h"
24 #include "AliESDUtils.h"
26 #include "AliAnalysisMuMuCutRegistry.h"
27 #include "AliAnalysisMuMuEventCutter.h"
28 #include "AliAnalysisMuMuCutElement.h"
29 #include "AliAnalysisMuMuBinning.h"
30 #include "Riostream.h"
31 #include "TParameter.h"
34 #include "AliMergeableCollection.h"
35 #include "AliMCEvent.h"
36 #include "AliAODMCParticle.h"
42 #include "TObjString.h"
45 #include "AliAODMCHeader.h"
46 #include "AliGenEventHeader.h"
47 #include "AliGenHijingEventHeader.h"
48 #include "AliGenDPMjetEventHeader.h"
49 #include "AliGenPythiaEventHeader.h"
50 #include "AliGenCocktailEventHeader.h"
55 Double_t SPDgeomR(Double_t* x,Double_t* par) // Eta position of the SPD right edge eta as "seen" from a z vertex position
57 // par[0] = radius of SPD layer
66 theta = TMath::ATan(par[0]/z);
69 else if( d > 14.09999 )
72 theta = TMath::Pi() - TMath::ATan(par[0]/z);
75 return -TMath::Log(TMath::Tan(theta/2.));
78 Double_t SPDgeomL(Double_t* x,Double_t* par) // Eta position of the SPD left edge eta as "seen" from a z vertex position
80 // par[0] = radius of SPD layer
89 theta = TMath::Pi() - TMath::ATan(par[0]/z);
95 theta = TMath::ATan(par[0]/z);
98 return -TMath::Log(TMath::Tan(theta/2.));
103 ////_____________________________________________________________________________
104 //AliAnalysisMuMuNch::AliAnalysisMuMuNch(TH2* spdCorrection, Double_t etaMin, Double_t etaMax
105 // , Double_t zMin, Double_t zMax,Bool_t disableHistos, Bool_t computeResolution)
106 //: AliAnalysisMuMuBase(),
107 //fSPDCorrection(0x0),
108 //fEtaAxis(new TAxis(TMath::Nint(10./0.1),-5.,5.)),
109 //fZAxis(new TAxis(TMath::Nint(80/0.25),-40.,40.)),
110 //fCurrentEvent(0x0),
115 //fResolution(computeResolution)
117 // if ( spdCorrection )
119 // fSPDCorrection = static_cast<TH2F*>(spdCorrection->Clone());
120 // fSPDCorrection->SetDirectory(0);
122 // DefineSPDAcceptance();
124 // if ( disableHistos )
126 // DisableHistograms("*");
130 //FIXME: First and second constructor may be ambiguous if we do not set all the arguments
132 //_____________________________________________________________________________
133 AliAnalysisMuMuNch::AliAnalysisMuMuNch(TH2F* spdCorrection, TProfile* spdMeanCorrection, Double_t meanTrRef, Double_t etaMin, Double_t etaMax
134 , Double_t zMin, Double_t zMax, Bool_t disableHistos, Bool_t computeResolution)
135 : AliAnalysisMuMuBase(),
136 fSPDOneOverAccxEff(0x0),
137 fSPDCorrectionMap(0x0),
138 fSPDCorrectionList(0x0),
139 fSPDMeanTracklets(0x0),
140 fSPDMeanTrackletsCorrToCompare(0x0),
141 fEtaAxis(new TAxis(TMath::Nint(10./0.1),-5.,5.)),
142 fZAxis(new TAxis(TMath::Nint(80/0.25),-40.,40.)),
144 fMeanTrRef(meanTrRef),
147 fEtaMinToCompare(0.),
148 fEtaMaxToCompare(0.),
152 fResolution(computeResolution),
154 fGeneratorHeaderClass(new TString("AliGenDPMjetEventHeader"))
156 //FIXME: Add a protection to avoid an etamin or etamax non multiple of the eta bin size
158 //FIXME: Add fluctuations to the SPD AccxEff correction method
160 if ( spdCorrection && spdMeanCorrection )
162 AliWarning("Two methods used to correct tracklets: Data-driven and SPDAccxEff corrected tracklets will be available in the event list, but the histograms in this class will be filled just with the AccxEff corrected values");
163 // AliFatal("Cannot use 2 different methods for tracklets correction");
165 // else if ( spdCorrection )
168 AliWarning("SPD AccxEff correction method not ready to be used, fluctuations are missing. Do not trust the results");
170 if ( fMeanTrRef > 0. && !spdMeanCorrection ) AliWarning("Reference mean nof tracklets argument will not be used: SPD AccxEff correction method in use");
172 fSPDOneOverAccxEff = static_cast<TH2F*>(spdCorrection->Clone());
173 fSPDOneOverAccxEff->SetDirectory(0);
175 // else if ( spdMeanCorrection )
176 if ( spdMeanCorrection )
178 if ( fMeanTrRef < 0. ) AliWarning("Reference mean nof tracklets argument set to -1: Maximum of the spdMeanCorrection will be used");
179 else AliWarning(Form("Using %f as reference mean nof tracklets for correction",fMeanTrRef));
181 frand = new TRandom3();
182 fSPDMeanTracklets = static_cast<TProfile*>(spdMeanCorrection->Clone());
183 fSPDMeanTracklets->SetDirectory(0);
186 DefineSPDAcceptance();
188 if ( disableHistos ) // FIXME: Is this really useful? it breaks when setting to ktrue due to non existence of histos in SetEvent(). Answer: It is useful, it will speed up the task when we want to execute only SetEvent and not fill all the multiplicity histos (i.e. doing J/psi vs multiplicity analysis). The problem is that disabling the histos the method CreateHisto() does not create histosm thats why the task breaks in SetEvent, so fix this
190 DisableHistograms("*");
194 //_____________________________________________________________________________
195 AliAnalysisMuMuNch::AliAnalysisMuMuNch(TProfile* spdMeanCorrection, TProfile* spdMeanCorrectionToCompare, Double_t meanTrRef, Double_t etaMin,
196 Double_t etaMax, Double_t zMin, Double_t zMax, Double_t etaMinToCompare, Double_t etaMaxToCompare,Bool_t disableHistos, Bool_t computeResolution)
197 : AliAnalysisMuMuBase(),
198 fSPDOneOverAccxEff(0x0),
199 fSPDCorrectionMap(0x0),
200 fSPDCorrectionList(0x0),
201 fSPDMeanTracklets(0x0),
202 fSPDMeanTrackletsCorrToCompare(0x0),
203 fEtaAxis(new TAxis(TMath::Nint(10./0.1),-5.,5.)),
204 fZAxis(new TAxis(TMath::Nint(80/0.25),-40.,40.)),
206 fMeanTrRef(meanTrRef),
209 fEtaMinToCompare(etaMinToCompare),
210 fEtaMaxToCompare(etaMaxToCompare),
214 fResolution(computeResolution),
216 fGeneratorHeaderClass(new TString("AliGenDPMjetEventHeader"))
218 //FIXME: Add a protection to avoid an etamin or etamax non multiple of the eta bin size
220 /// This construction is designed to compute everything in etaMin < eta < etaMax and correct with spdMeanCorrection (main eta tange and correction), but when filling the histos in FillHistosForEvent is able to compute the number of tracklets in etaMinToCompare < eta < etaMaxToCompare and correct them with spdMeanCorrectionToCompare (secondary eta range and correction) in order to compare N_{tr}^{|eta|< etaMax} vs N_{tr}^{|eta|< etaMaxToCompare}
222 if ( !spdMeanCorrection || !spdMeanCorrectionToCompare )
224 AliFatal("Need the two corrections to compare. Maybe you are using the wrong constructor");
226 if ( fEtaMinToCompare < fEtaMin || fEtaMaxToCompare > fEtaMax )
228 AliFatal("Cannot select a eta range to compare wider than the main eta range");
231 if ( fMeanTrRef < 0. ) AliWarning("Reference mean nof tracklets argument set to -1: Maximum of the spdMeanCorrection will be used");
232 else AliWarning(Form("Using %f as reference mean nof tracklets for correction",fMeanTrRef));
234 frand = new TRandom3();
235 fSPDMeanTracklets = static_cast<TProfile*>(spdMeanCorrection->Clone());
236 fSPDMeanTracklets->SetDirectory(0);
238 fSPDMeanTrackletsCorrToCompare = static_cast<TProfile*>(spdMeanCorrectionToCompare->Clone());
239 fSPDMeanTrackletsCorrToCompare->SetDirectory(0);
241 DefineSPDAcceptance();
243 if ( disableHistos ) // FIXME: Is this really useful? it breaks when setting to ktrue due to non existence of histos in SetEvent()
245 DisableHistograms("*");
249 //_____________________________________________________________________________
250 AliAnalysisMuMuNch::AliAnalysisMuMuNch(TObjArray* spdCorrectionList, Double_t meanTrRef, Double_t etaMin, Double_t etaMax
251 , Double_t zMin, Double_t zMax,Bool_t disableHistos, Bool_t computeResolution)
252 : AliAnalysisMuMuBase(),
253 fSPDOneOverAccxEff(0x0),
254 fSPDCorrectionMap(0x0),
255 fSPDCorrectionList(0x0),
256 fSPDMeanTracklets(0x0),
257 fSPDMeanTrackletsCorrToCompare(0x0),
258 fEtaAxis(new TAxis(TMath::Nint(10./0.1),-5.,5.)),
259 fZAxis(new TAxis(TMath::Nint(80/0.25),-40.,40.)),
261 fMeanTrRef(meanTrRef),
264 fEtaMinToCompare(0.),
265 fEtaMaxToCompare(0.),
269 fResolution(computeResolution),
271 fGeneratorHeaderClass(new TString("AliGenDPMjetEventHeader"))
273 //FIXME: Add a protection to avoid an etamin or etamax non multiple of the eta bin size
275 // Uses a different correction for each group of runs (both SPD AccxEff OR mean tracklets are supported)
277 if ( spdCorrectionList ) DefineSPDCorrectionMap(spdCorrectionList);
278 else AliFatal("No SPD correction list provided");
280 if ( fMeanTrRef < 0. ) AliWarning("Reference mean nof tracklets argument set to -1: Maximum of the spdMeanCorrection will be used");
281 else AliWarning(Form("Using %f as reference mean nof tracklets for correction",fMeanTrRef));
283 frand = new TRandom3();
285 DefineSPDAcceptance();
287 if ( disableHistos ) // FIXME: Is this really useful? it breaks when setting to ktrue due to non existence of histos in SetEvent()
289 DisableHistograms("*");
293 //_____________________________________________________________________________
294 AliAnalysisMuMuNch::~AliAnalysisMuMuNch()
296 delete fSPDOneOverAccxEff;
297 delete fSPDCorrectionMap;
298 delete fSPDCorrectionList;
299 delete fSPDMeanTracklets;
300 delete fSPDMeanTrackletsCorrToCompare;
308 delete fGeneratorHeaderClass;
311 //_____________________________________________________________________________
312 void AliAnalysisMuMuNch::DefineGeneratorName(const char* genName)
314 // TString sgenName(genName);
315 // if ( sgenNam.Contains("pythia") ) fGeneratorHeaderClass = "AliGenPythiaEventHeader";
316 // else if ( sgenNam.Contains("dpmjet") ) fGeneratorHeaderClass = "AliGenDPMjetEventHeader";
317 // else if ( sgenNam.Contains("dpmjet") ) fGeneratorHeaderClass = "AliGenHijingEventHeader";
319 fGeneratorHeaderClass->Form("%s",genName);
321 std::cout << " Will use " << fGeneratorHeaderClass->Data() << " tracks" << std::endl;
324 //_____________________________________________________________________________
325 void AliAnalysisMuMuNch::DefineHistogramCollection(const char* eventSelection,
326 const char* triggerClassName,
327 const char* centrality)
329 // Define multiplicity histos
331 if ( Histo(eventSelection,triggerClassName,centrality,"AliAnalysisMuMuNch") )
336 // dummy histogram to signal that we already defined all our histograms (see above)
337 CreateEventHistos(kHistoForData | kHistoForMCInput,eventSelection,triggerClassName,centrality,"AliAnalysisMuMuNch","Dummy semaphore",1,0,1);
339 Double_t multMin = -0.5; //Tracklets multiplicity range
340 Double_t multMax = 500.5;
341 Int_t nbinsMult = GetNbins(multMin,multMax,1.);
343 Double_t phimin = 0.; //Phi range
344 Double_t phimax = 2*TMath::Pi();
345 Int_t nphibins = GetNbins(phimin,phimax,0.05);
347 if ( !fSPDMeanTracklets && !fSPDOneOverAccxEff && fResolution ) // Resolution histos
349 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"EtaRes","#eta resolution;#eta_{Reco} - #eta_{MC};Counts",(fEtaAxis->GetNbins())*2,fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
351 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"PhiRes","#phi resolution;#phi_{Reco} - #phi_{MC};Counts",nphibins*2,-phimax,phimax);
353 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"PhiResShifted","#phi resolution;#phi_{Reco} - #phi_{MC};Counts",nphibins*4,-phimax/4,phimax/4);
355 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"EtaResVsZ","#eta resolution vs MC Zvertex;ZVertex (cm);#eta_{Reco} - #eta_{MC}",(fZAxis->GetNbins())*20,fZAxis->GetXmin(),fZAxis->GetXmax(),(fEtaAxis->GetNbins())*8,fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
357 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"PhiResVsZ","#phi resolution vs MC Zvertex;ZVertex (cm);#phi_{Reco} - #phi_{MC}",(fZAxis->GetNbins())*20,fZAxis->GetXmin(),fZAxis->GetXmax(),nphibins*4,-phimax/4,phimax/4);
359 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"EtaResVsnC","#eta resolution vs Nof contributors to SPD vertex;NofContributors;#eta_{Reco} - #eta_{MC}",200,0,200,(fEtaAxis->GetNbins())*8,fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
361 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"PhiResVsnC","#phi resolution vs Nof contributors to SPD vertex;NofContributors;#phi_{Reco} - #phi_{MC}",200,0,200,nphibins*4,-phimax/4,phimax/4);
363 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"SPDZvResVsnC","SPD Zvertex resolution vs Nof contributors;NofContributors;Zvertex_{Reco} - Zvertex_{MC} (cm)",200,0,200,(fZAxis->GetNbins())*20,fZAxis->GetXmin(),fZAxis->GetXmax());
365 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"SPDZvResVsMCz","SPD Zvertex resolution vs MC z vertex;MC Zvertex (cm);Zvertex_{Reco} - Zvertex_{MC} (cm)",(fZAxis->GetNbins())*20,fZAxis->GetXmin(),fZAxis->GetXmax(),(fZAxis->GetNbins())*10,fZAxis->GetXmin(),fZAxis->GetXmax());
367 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"Phi","Reco #phi distribution;#phi;Counts",nphibins,phimin,phimax);
369 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"MCPhi","MC #phi distribution;#phi;Counts",nphibins,phimin,phimax);
371 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"Eta","Reco #eta distribution;#phi;Counts",(fEtaAxis->GetNbins())*2,fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
373 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"MCEta","MC #eta distribution;#phi;Counts",(fEtaAxis->GetNbins())*2,fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
375 return; // When computing resolutions we don't want to create the rest of histos
378 TString TrackletsCorrectedName("");
379 TString TrackletsCorrectedAxisName("");
380 if ( fSPDMeanTracklets && !fSPDOneOverAccxEff )
382 TrackletsCorrectedName = "Number of corrected tracklets";
383 TrackletsCorrectedAxisName = "N_{tr}^{corr}";
385 else if( fSPDOneOverAccxEff )
387 TrackletsCorrectedName = "Number of charged particles";
388 TrackletsCorrectedAxisName = "N_{ch}";
391 CreateEventHistos(kHistoForData | kHistoForMCInput,eventSelection,triggerClassName,centrality,"TrackletsVsZVertexVsPhi","Number of tracklets vs Z vertex vs #phi;Z vertex;#phi",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),nphibins,phimin,phimax);
393 CreateEventHistos(kHistoForData | kHistoForMCInput,eventSelection,triggerClassName,centrality,"TrackletsVsZVertexVsEta","Number of tracklets vs ZVertex vs #eta;ZVertex;#eta",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
394 AttachSPDAcceptance(kHistoForData | kHistoForMCInput,eventSelection,triggerClassName,centrality,"TrackletsVsZVertexVsEta");
396 CreateEventHistos(kHistoForData | kHistoForMCInput,eventSelection,triggerClassName,centrality,"Tracklets",Form("Number of tracklets in |#eta| < %1.1f distribution;N_{Tracklets};N_{events}",fEtaMax),nbinsMult,multMin,multMax);
398 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"NBkgTrackletsVsZVertexVsEta","Number of background tracklets vs ZVertex vs #eta;ZVertex;#eta",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
399 AttachSPDAcceptance(kHistoForMCInput,eventSelection,triggerClassName,centrality,"NBkgTrackletsVsZVertexVsEta");
401 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"NchVsZVertexVsEta","Number of charged particles vs ZVertex vs #eta;ZVertex;#eta",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
402 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"NchVsRecoZVertexVsEta","Number of gen. charged particles vs reco. ZVertex vs gen. #eta;ZVertex;#eta",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
403 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"NchVsZVertexVsEta",Form("%s vs ZVertex vs #eta;ZVertex;#eta",TrackletsCorrectedName.Data()),fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
404 AttachSPDAcceptance(kHistoForData | kHistoForMCInput,eventSelection,triggerClassName,centrality,"NchVsZVertexVsEta");
405 AttachSPDAcceptance(kHistoForMCInput,eventSelection,triggerClassName,centrality,"NchVsRecoZVertexVsEta");
407 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"NchVsZVertexVsPhi","Number of charged particles vs ZVertex vs #phi;ZVertex;#phi",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),nphibins,phimin,phimax);
409 CreateEventHistos(kHistoForData | kHistoForMCInput,eventSelection,triggerClassName,centrality,"EventsVsZVertexVsEta","Effective number of events vs ZVertex vs #eta;ZVertex;#eta",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax()); // Fill 1 unit in each "touched" eta bin per event (represents the eta bins in which each event contributes)
410 AttachSPDAcceptance(kHistoForData | kHistoForMCInput,eventSelection,triggerClassName,centrality,"EventsVsZVertexVsEta");
412 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"Nch",Form("Number of charged particles in |#eta| < %1.1f distribution;N_{ch};N_{events}",fEtaMax),nbinsMult,multMin,multMax);
413 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"Nch",Form("%s in |#eta| < %1.1f distribution;%s;N_{events}",TrackletsCorrectedName.Data(),fEtaMax,TrackletsCorrectedAxisName.Data()),nbinsMult,multMin,multMax);
415 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"dNchdEta",Form("<dNchd#eta> in |#eta| < %1.1f distribution;dN_{ch}/d#eta;N_{events}",fEtaMax),nbinsMult,multMin,multMax);
416 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"dNchdEta",Form("<d%sd#eta> in |#eta| < %1.1f distribution;d%s/d#eta;N_{events}",TrackletsCorrectedAxisName.Data(),fEtaMax,TrackletsCorrectedAxisName.Data()),nbinsMult,multMin,multMax);
418 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"TrackletsVsNch",Form("Number of tracklets vs number of generated charged particles in |#eta| < %1.1f;N_{ch};N_{tracklets}",fEtaMax),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax); //Response matrix
419 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"TrackletsVsNch",Form("Number of tracklets vs %s in |#eta| < %1.1f;%s;N_{tracklets}",TrackletsCorrectedName.Data(),fEtaMax,TrackletsCorrectedAxisName.Data()),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
421 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"dNchdetaVsMCdNchdeta",Form("Corrected dN_{ch}/d#eta vs MC dN_{ch}/d#eta in |#eta| < %1.1f;(dN_{ch}/d#eta)_{MC};dN_{ch}/d#eta",fEtaMax),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
423 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"V0AMultVsNch",Form("V0A multiplicity vs number of generated charged particles in |#eta| < %1.1f;N_{ch};V0A Mult",fEtaMax),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
424 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"V0AMultVsNch",Form("V0A multiplicity vs %s in |#eta| < %1.1f;%s;V0A Mult",TrackletsCorrectedName.Data(),fEtaMax,TrackletsCorrectedAxisName.Data()),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
426 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"V0CMultVsNch",Form("V0C multiplicity vs number of generated charged particles in |#eta| < %1.1f;N_{ch};V0C Mult",fEtaMax),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
427 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"V0CMultVsNch",Form("V0C multiplicity vs %s in |#eta| < %1.1f;%s;V0A Mult",TrackletsCorrectedName.Data(),fEtaMax,TrackletsCorrectedAxisName.Data()),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
429 // CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"NchVsTracklets","Number of generated charged particles vs reco tracklets;N_{tracklets};N_{ch}",nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
431 if ( fSPDMeanTrackletsCorrToCompare )
433 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"CorrTrackletsEtaSecVsCorrTrackletsEtaPrim",Form("N_{tr}^{corr} in |#eta|< %1.1f vs N_{tr}^{corr} in |#eta|< %1.1f;N_{tracklets}^{|#eta|<%1.1f};N_{tracklets}^{|#eta|<%1.1f}",fEtaMaxToCompare,fEtaMax,fEtaMax,fEtaMaxToCompare),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
434 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"MeanNchEtaSecVsZVertex",Form("Mean number of corrected tracklets in |#eta| < %1.1f vs Z vertex;Z vertex;<N_{tr}^{corr}>",fEtaMaxToCompare),fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),0);
435 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"MeanTrackletsEtaSecVsZVertex",Form("Mean number of tracklets in |#eta| < %1.1f vs Z vertex;Z vertex;<N_{tr}^{corr}>",fEtaMaxToCompare),fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),0);
436 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"TrackletsSecVsZVertexVsEta","Number of tracklets vs ZVertex vs #eta;ZVertex;#eta",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
439 if ( fSPDMeanTracklets && fSPDOneOverAccxEff )
441 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"dNchdetaComparison2Corrections","dN_{ch}/d#eta comparison with SPD AccxEff and data-driven corrections;dN_{ch}/d#eta;A*N^{corr}_{Tracklets}",151,multMin,150.5,151,multMin,150.5);
442 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"DispersiondNchdetaComparison2Corrections","dN_{ch}/d#eta dispersion with SPD AccxEff and data-driven corrections;(dN_{ch}/d#eta - A*N^{corr}_{Tracklets}) /dN_{ch}/d#eta;N_{events}",201,-1.005,1.005);
443 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"CheckMeanNtrCorrVsZVertex","Check for NtrCorr",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),0);
444 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"CheckNtrCorr","Check for NtrCorr distribution;N^{corr}_{tr};N_{events}",nbinsMult,multMin,multMax);
447 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"RelDispersiondNchdetaFromNtrCorrVsdNchdEtaMC",Form("Relative dispersion of dN_{ch}/d#eta from N_{tr}^{corr} vs MC dN_{ch}/d#eta in |#eta| < %1.1f;((dN_{ch}/d#eta)_{gen} - A*N^{corr}_{Tracklets}) /(dN_{ch}/d#eta)_{gen}",fEtaMax),201,-1.005,1.005);
448 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"DispersiondNchdetaFromNtrCorrVsdNchdEtaMC",Form("Dispersion of dN_{ch}/d#eta from N_{tr}^{corr} vs MC dN_{ch}/d#eta in |#eta| < %1.1f;(dN_{ch}/d#eta)_{gen} - A*N^{corr}_{Tracklets}",fEtaMax),402,-100.5,100.5);
449 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"dNchdetaFromNtrCorrVsdNchdEtaMC",Form("dN_{ch}/d#eta from N_{tr}^{corr} vs MC dN_{ch}/d#eta in |#eta| < %1.1f;(dN_{ch}/d#eta)_{gen};dN_{ch}/d#eta",fEtaMax),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
451 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"RelDispersiondNchdetaFromAccEffVsdNchdEtaMC",Form("Relative dispersion of dN_{ch}/d#eta from N_{tr}^{AccxEff} vs MC dN_{ch}/d#eta in |#eta| < %1.1f;((dN_{ch}/d#eta)_{gen} - dN_{ch}/d#eta) /(dN_{ch}/d#eta)_{gen};N_{events}",fEtaMax),201,-1.005,1.005);
452 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"DispersiondNchdetaFromAccEffVsdNchdEtaMC",Form("Dispersion of dN_{ch}/d#eta from N_{tr}^{AccxEff} vs MC dN_{ch}/d#eta in |#eta| < %1.1f;(dN_{ch}/d#eta)_{gen} - dN_{ch}/d#eta;N_{events}",fEtaMax),402,-100.5,100.5);
453 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"dNchdetaFromAccEffVsdNchdEtaMC",Form("dN_{ch}/d#eta from N_{tr}^{AccxEff} vs MC dN_{ch}/d#eta in |#eta| < %1.1f;(dN_{ch}/d#eta)_{gen};dN_{ch}/d#eta",fEtaMax),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
456 // CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"CorrTrackletsVsNch","Reco tracklets corrected vs number of generated charged particles;N_{ch};N_{tracklets}^{corr}",nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
457 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"CorrTrackletsVsNch",Form("%s vs number of generated charged particles in |#eta| < %1.1f;N_{ch};%s",TrackletsCorrectedName.Data(),fEtaMax,TrackletsCorrectedAxisName.Data()),nbinsMult,multMin,multMax,nbinsMult,multMin,multMax);
459 // profile histograms
460 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"MeanTrackletsVsEta","Mean number of tracklets vs #eta;#eta;<N_{Tracklets}>",fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax(),0);
461 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"MeandNchdEtaVsEta","Mean dN_{ch}/d#eta vs #eta;#eta;<dN_{ch}/d#eta>",fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax(),0);
463 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"MeanTrackletsVsZVertex",Form("Mean number of tracklets in |#eta| < %1.1f vs Z vertex;Z vertex;<N_{Tracklets}>",fEtaMax),fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),0);
465 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"MeanNchVsEta","Mean number of generated charged particles vs #eta;#eta;<N_{ch}>",fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax(),0); // Each bin has to be divided by the binwidth to became dNch/dEta (Done in the terminate and stored in MeandNchdEta histo)
466 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"MeanNchVsEta",Form("Mean %s vs #eta;#eta;<%s>",TrackletsCorrectedName.Data(),TrackletsCorrectedAxisName.Data()),fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax(),0); // Each bin has to be divided by the binwidth to became dNch/dEta (Done in the terminate and stored in MeandNchdEta histo)
468 CreateEventHistos(kHistoForMCInput,eventSelection,triggerClassName,centrality,"MeanNchVsZVertex",Form("Mean number of generated charged particles in |#eta| < %1.1f vs Z vertex;Z vertex;<N_{ch}>",fEtaMax),fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),0);
469 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"MeanNchVsZVertex",Form("Mean %s in |#eta| < %1.1f vs Z vertex;Z vertex;<%s>",TrackletsCorrectedName.Data(),fEtaMax,TrackletsCorrectedAxisName.Data()),fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),0);
470 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,"MeandNchdEtaVsZVertex",Form("Mean d%s/d#eta in |#eta| < %1.1f vs Z vertex;Z vertex;<%s>",TrackletsCorrectedAxisName.Data(),fEtaMax,TrackletsCorrectedAxisName.Data()),fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),0);
473 TObjArray* bins = Binning()->CreateBinObjArray("psi","dnchdeta","");
475 AliAnalysisMuMuBinning::Range* r;
477 while ( ( r = static_cast<AliAnalysisMuMuBinning::Range*>(nextBin()) ) )
479 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,Form("EventsIn%s",r->AsString().Data()),Form("Number of %s events in %s bin",triggerClassName,r->AsString().Data()),1,0.,2);
484 TObjArray* binsntr = Binning()->CreateBinObjArray("psi","ntrcorr","");
485 TIter nextBinNtr(binsntr);
486 AliAnalysisMuMuBinning::Range* rNtr;
488 while ( ( rNtr = static_cast<AliAnalysisMuMuBinning::Range*>(nextBinNtr()) ) )
490 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,Form("MeanNchVsZVertex%s",rNtr->AsString().Data()),Form("Mean %s in |#eta| < %1.1f vs Z vertex in bin %s;Z vertex;<%s>",TrackletsCorrectedName.Data(),fEtaMax,rNtr->AsString().Data(),TrackletsCorrectedAxisName.Data()),fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),0);
492 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,Form("MeanTrackletsVsZVertex%s",rNtr->AsString().Data()),Form("Mean number of tracklets in |#eta| < %1.1f vs Z vertex in bin %s;Z vertex;<N_{Tracklets}>",fEtaMax,rNtr->AsString().Data()),fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),0);
497 TObjArray* binsRel = Binning()->CreateBinObjArray("psi","relntrcorr","");
498 TIter nextBinRel(binsRel);
499 AliAnalysisMuMuBinning::Range* rRel;
501 while ( ( rRel = static_cast<AliAnalysisMuMuBinning::Range*>(nextBinRel()) ) )
503 CreateEventHistos(kHistoForData,eventSelection,triggerClassName,centrality,Form("EventsIn%s",rRel->AsString().Data()),Form("Number of %s events in %s bin",triggerClassName,rRel->AsString().Data()),1,0.,2);
510 //_____________________________________________________________________________
511 void AliAnalysisMuMuNch::DefineSPDAcceptance()
513 // Defines the functions ( eta = f(z) ) of the edges (right/left) of the inner and outer SPD layers
514 // R_in = 3.9 cm ; R_out = 7.6 cm
516 fSPD1LR = new TF1("fSPD1LR",SPDgeomR,-40,40,1);
517 fSPD1LR->SetParameter(0,3.9);
518 fSPD1LL = new TF1("fSPD1LL",SPDgeomL,-40,40,1);
519 fSPD1LL->SetParameter(0,3.9);
520 fSPD2LR = new TF1("fSPD2LR",SPDgeomR,-40,40,1);
521 fSPD2LR->SetParameter(0,7.6);
522 fSPD2LL = new TF1("fSPD2LL",SPDgeomL,-40,40,1);
523 fSPD2LL->SetParameter(0,7.6);
527 //_____________________________________________________________________________
528 void AliAnalysisMuMuNch::DefineSPDCorrectionMap(TObjArray* spdCorrectionList)
530 // Defines a TMap of the SPD periods and the corresponding correction
531 // Each SPD correction in the list must contain in the name the 1st run for which is valid and respect the naming convention:
532 // (SPDCorrection_1stValidRunNumber_lastValidRunNumber).
533 // The list must be ordered from smaller to bigger run number
534 // This is usable with both types of corrections
536 if ( !fSPDCorrectionMap ) // Creates a TMap for the run->Correction correspondance
538 fSPDCorrectionMap = new TMap;
539 fSPDCorrectionMap->SetOwnerKeyValue(kTRUE,kTRUE);
542 TIter next(spdCorrectionList);
543 TH1* SPDCorrection(0x0);
545 Int_t i(0); // SPDCorrection index in the list
546 while ( (SPDCorrection = static_cast<TH1*>(next())) ) // Checks if the correction list format is ok and if it is ordered
548 if ( static_cast<TH1*>(SPDCorrection)->IsA() != TH2::Class() && static_cast<TH1*>(SPDCorrection)->IsA() != TProfile::Class() )
550 AliFatal("Unrecognized SPD correction Class");
553 TString name = SPDCorrection->GetName();
554 if ( !name.BeginsWith("SPDCorrection_") ) AliFatal(Form("Incorrect SPD correction at %d format: Objects in list must named as 'SPDCorrection_1stValidRunNumber_lastValidRunNumber'",i));
556 name.Remove(0,name.First("_") + 1);
557 TString nameLast = name;
558 name.Remove(name.First("_"),name.Length());
559 nameLast.Remove(0,nameLast.First("_") + 1);
560 if ( !name.IsDigit() ) AliFatal(Form("Incorrect SPD correction at %d format: Impossible to retrieve first valid run number",i));
561 if ( !nameLast.IsDigit() ) AliFatal(Form("Incorrect SPD correction at %d format: Impossible to retrieve last valid run number",i));
563 Int_t runLow = name.Atoi();
564 Int_t runHigh = nameLast.Atoi();
565 if ( runHigh < runLow ) AliFatal(Form("SPD correction at %d validity range not valid",i));
566 if ( runLow <= runRef ) AliFatal("SPD correction list not in correct order. Should be ordered from smaller to bigger run number");
567 else runRef = runHigh;
569 for ( Int_t j = runLow ; j <= runHigh ; j++ )
571 fSPDCorrectionMap->Add(new TObjString(Form("%d",j)),new TObjString(Form("%d",i))); // The mapping is done between the runs and the index of the correction in the spdCorrection List
577 fSPDCorrectionList = static_cast<TObjArray*>(spdCorrectionList->Clone());
580 //_____________________________________________________________________________
581 void AliAnalysisMuMuNch::AddHisto(const char* eventSelection,
582 const char* triggerClassName,
583 const char* centrality,
584 const char* histoname,
588 // Adds the content of a 1D histo to a 2D histo a the z position
590 Int_t zbin = fZAxis->FindBin(z);
592 if (isMC) h2 = static_cast<TH2F*>(MCHisto(eventSelection,triggerClassName,centrality,histoname));
593 else h2 = static_cast<TH2F*>(Histo(eventSelection,triggerClassName,centrality,histoname));
595 for ( Int_t i = 1; i <= h->GetXaxis()->GetNbins(); ++i )
597 Double_t content = h2->GetCellContent(zbin,i);
599 if ( h->GetBinContent(i) > 0 )
601 h2->SetCellContent(zbin,i,content + h->GetBinContent(i));
605 h2->SetEntries(h2->GetSumOfWeights());
609 //_____________________________________________________________________________
610 void AliAnalysisMuMuNch::AttachSPDAcceptance(UInt_t dataType,
611 const char* eventSelection,
612 const char* triggerClassName,
613 const char* centrality,const char* histoname)
615 // Attachs AccxEff curves to the histogram
617 if ( dataType & kHistoForData )
619 if( !Histo(eventSelection,triggerClassName,centrality,histoname) )
621 AliError(Form("ERROR: SPD Acceptance curves attach failed. Histo /%s/%s/%s/%s not found",eventSelection,triggerClassName,centrality,histoname));
625 Histo(eventSelection,triggerClassName,centrality,histoname)->GetListOfFunctions()->Add(fSPD1LR->Clone());
626 Histo(eventSelection,triggerClassName,centrality,histoname)->GetListOfFunctions()->Add(fSPD1LL->Clone());
627 Histo(eventSelection,triggerClassName,centrality,histoname)->GetListOfFunctions()->Add(fSPD2LR->Clone());
628 Histo(eventSelection,triggerClassName,centrality,histoname)->GetListOfFunctions()->Add(fSPD2LL->Clone());
630 if ( (dataType & kHistoForMCInput) && HasMC() )
632 if( !MCHisto(eventSelection,triggerClassName,centrality,histoname) )
634 AliError(Form("ERROR: SPD Acceptance curves attach failed. MC Histo /%s/%s/%s/%s not found",eventSelection,triggerClassName,centrality,histoname));
638 MCHisto(eventSelection,triggerClassName,centrality,histoname)->GetListOfFunctions()->Add(fSPD1LR->Clone());
639 MCHisto(eventSelection,triggerClassName,centrality,histoname)->GetListOfFunctions()->Add(fSPD1LL->Clone());
640 MCHisto(eventSelection,triggerClassName,centrality,histoname)->GetListOfFunctions()->Add(fSPD2LR->Clone());
641 MCHisto(eventSelection,triggerClassName,centrality,histoname)->GetListOfFunctions()->Add(fSPD2LL->Clone());
648 //_____________________________________________________________________________
649 void AliAnalysisMuMuNch::FillHistosForEvent(const char* eventSelection,
650 const char* triggerClassName,
651 const char* centrality)
653 // Fills the data (or reco if simu) multiplicity histos
655 if ( IsHistogrammingDisabled() ) return;
657 if ( fResolution ) return; //When computing resolutions we skip this method
659 // if ( !AliAnalysisMuonUtility::IsAODEvent(Event()) )
661 // AliError("Don't know how to deal with ESDs...");
665 // if ( HasMC() && !fSPDOneOverAccxEff && !fSPDMeanTracklets ) // We have MC but no correction (SPD correction computation mode)so we skip the method
670 // AliAODEvent* aod = static_cast<AliAODEvent*>(Event());
672 // AliVVertex* vertex = aod->GetPrimaryVertexSPD();
674 AliVVertex* vertex = AliAnalysisMuonUtility::GetVertexSPD(Event());
676 TList* nchList = static_cast<TList*>(Event()->FindListObject("NCH"));
678 if (!nchList || nchList->IsEmpty() ) // Empty NCH means that there is no SPD vertex ( see SetEvent() ) when runing on data.
680 AliError("Empty Nch list in event");
686 if ( !vertex || vertex->GetZ() == 0.0 ) // Running in Simu the spdZ == 0 means no SPD info. In data, avoid breaks in events w/o SPD vertex
690 else SPDZv = vertex->GetZ();
692 TH1* hSPDcorrectionVsEta = static_cast<TH1*>(nchList->FindObject("SPDcorrectionVsEta"));
693 TH1* hNTrackletVsEta = static_cast<TH1*>(nchList->FindObject("NTrackletVsEta"));
694 TH1* hNTrackletVsPhi = static_cast<TH1*>(nchList->FindObject("NTrackletVsPhi"));
696 TH1* hNTrackletSecVsEta(0x0);
697 if ( fSPDMeanTrackletsCorrToCompare ) // In case we have a secondary eta range we clone the tracklets vs eta histo
699 hNTrackletSecVsEta = static_cast<TH1*>(hNTrackletVsEta->Clone());
700 hNTrackletSecVsEta->Reset();
703 TH1* hNchVsEta = static_cast<TH1*>(hNTrackletVsEta->Clone("NchVsEta"));
705 TProfile* hMeanTrackletsVsEta = static_cast<TProfile*>(Histo(eventSelection,triggerClassName,centrality,"MeanTrackletsVsEta"));
706 TProfile* hMeanNchVsEta = static_cast<TProfile*>(Histo(eventSelection,triggerClassName,centrality,"MeanNchVsEta"));
707 TProfile* hMeandNchdEtaVsEta = static_cast<TProfile*>(Histo(eventSelection,triggerClassName,centrality,"MeandNchdEtaVsEta"));
709 TH2* hEventsVsZVertexVsEta = static_cast<TH2*>(Histo(eventSelection,triggerClassName,centrality,"EventsVsZVertexVsEta"));
713 Int_t nTracklets[2] = {0,0}; // {nTracklets_Eta_fetaRange,nTracklets_Eta_fetaRangeComp} The first component is the number of tracklets in the primary eta range and the second is the number of tracklets in the secondary eta range
714 Double_t nch[2] = {0.,0.}; // {nCorrTracklets_Eta_fetaRange,nCorrTracklets_Eta_fetaRangeComp} The first component is the corrected(with the primary correction) number of tracklets in the primary eta range and the second is the number of corrected(with the secondary correction) tracklets in the secondary eta range
716 Int_t etaBinMin[2] = {fEtaAxis->FindBin(fetaRange[0]),fEtaAxis->FindBin(fEtaMinToCompare)}; // Primary and secondary (if any) eta ranges
717 Int_t etaBinMax[2] = {fEtaAxis->FindBin(fetaRange[1]),fEtaAxis->FindBin(fEtaMaxToCompare)-1}; // Note that the binMax is the bin-1 because the upper extreme of a bin belongs to the next bin (i.e. the bin containing -0.5 has as center -0.45, the bin is [-0.5,-0.4) but the bin containing 0.5 has as center 1.05, the bin is [0.5,1.1) so we have to take the previous bin [0.4,0.5)) This is already taken into account in the GetEtaRangeSPD method
719 for (Int_t j = etaBinMin[0] ; j <= etaBinMax[0] ; j++) // Loop over eta bins.
721 Double_t correction = hSPDcorrectionVsEta->GetBinContent(j);
723 Double_t eta = fEtaAxis->GetBinCenter(j);
725 if ( correction < 0 ) continue;
726 else if ( correction == 0.0 ) // No tracklets found in this eta bin.
728 correction = GetSPDCorrection(SPDZv,eta); //FIXME: Here eta is the bincenter not the exact one, will be a problem if the SPD AccxEff binning is not the same as the fEtaAxis one
730 if ( correction == 0. || correction > 2.5) continue; // We need to know if the eta bin is in a region we want to take into account to count or not the zero
733 Int_t ntr = hNTrackletVsEta->GetBinContent(j); // Tracklets in eta bin
734 nTracklets[0] += ntr;
735 if ( j >= etaBinMin[1] && j <= etaBinMax[1] )
737 nTracklets[1] += ntr; // number of tracklets in the secondary eta range
738 hNTrackletSecVsEta->SetBinContent(j,ntr);
741 hMeanTrackletsVsEta->Fill(eta,ntr); // Fill the number of tracklets of each eta bin in the profile
743 if ( fSPDOneOverAccxEff )
745 nch[0] += ntr * correction; // Number of charged particles (SPD AccxEff corrected tracklets)
746 hMeanNchVsEta->Fill(eta,ntr*correction);
747 hMeandNchdEtaVsEta->Fill(eta,ntr*correction/fEtaAxis->GetBinWidth(5));
748 hNchVsEta->SetBinContent(j,hNchVsEta->GetBinContent(j) * correction ); // Fill the number of charged particles of each eta bin in the profile
751 ++nBins; // We sum up the number of bins entering in the computation
753 hEventsVsZVertexVsEta->Fill(SPDZv,eta,1.0); // Fill 1 count each eta bin where the events contributes
756 AddHisto(eventSelection,triggerClassName,centrality,"TrackletsVsZVertexVsPhi",SPDZv,hNTrackletVsPhi);
757 AddHisto(eventSelection,triggerClassName,centrality,"TrackletsVsZVertexVsEta",SPDZv,hNTrackletVsEta);
759 AddHisto(eventSelection,triggerClassName,centrality,"NchVsZVertexVsEta",SPDZv,hNchVsEta);
761 Histo(eventSelection,triggerClassName,centrality,"Tracklets")->Fill(nTracklets[0]);
762 Histo(eventSelection,triggerClassName,centrality,"MeanTrackletsVsZVertex")->Fill(SPDZv,nTracklets[0]);
765 if ( fSPDMeanTracklets && !fSPDOneOverAccxEff ) // Just correct by SPDMeanTracklets method if there is no SPD AccxEff correction
767 Double_t SPDr = GetTrackletsMeanCorrection(SPDZv,nTracklets[0]); // Get 'mean correction' for the zvtx
769 if ( SPDr < -999.) nch[0] = -1;
770 else nch[0] = nTracklets[0] + SPDr; // In case of 'mean correction' nch has not be filled in the eta bins loop
772 if ( fSPDMeanTrackletsCorrToCompare ) // Comparison of corrected tracklets in the primary and secondary eta ranges
774 AddHisto(eventSelection,triggerClassName,centrality,"TrackletsSecVsZVertexVsEta",SPDZv,hNTrackletSecVsEta);
776 Double_t SPDrEtaComp = GetTrackletsMeanCorrection(SPDZv,nTracklets[1],kTRUE); // Get secondary 'mean correction' for the zvtx
778 if ( SPDrEtaComp < -999.) nch[1] = -1;
779 else nch[1] = nTracklets[1] + SPDrEtaComp; // In case of 'mean correction' nch has not be filled in the eta bins loop
781 Histo(eventSelection,triggerClassName,centrality,"CorrTrackletsEtaSecVsCorrTrackletsEtaPrim")->Fill(nch[0],nch[1]);
782 Histo(eventSelection,triggerClassName,centrality,"MeanNchEtaSecVsZVertex")->Fill(SPDZv,nch[1]); // Control plot to check if the secondary correction is applied correctly
783 Histo(eventSelection,triggerClassName,centrality,"MeanTrackletsEtaSecVsZVertex")->Fill(SPDZv,nTracklets[1]);
787 else if ( fSPDMeanTracklets && fSPDOneOverAccxEff ) // Here we compare the Corrected tracklets with the two correction methods
790 Bool_t parFound1(kFALSE),parFound2(kFALSE);
791 Double_t NtrCorr(0.),dNchdeta(0.);
792 while ( i < nchList->GetEntries() - 1 && !(parFound1 && parFound2) )
795 while ( nchList->At(i)->IsA() != TParameter<Double_t>::Class() && i < nchList->GetEntries() - 1 ) // In case there is a diferent object, just to skip it
800 TParameter<Double_t>* p = static_cast<TParameter<Double_t>*>(nchList->At(i));
802 if ( TString(p->GetName()).Contains("NtrCorr") )
805 NtrCorr = p->GetVal();
807 else if ( TString(p->GetName()).Contains("MeandNchdEta") )
810 dNchdeta = p->GetVal();
814 if ( parFound1 && parFound2 )
816 // Double_t dNchdetaPubli = 17.35; //FIXME: hardcoded (pPb value)
817 Double_t ctToNch = 1.11; //FIXME: hardcoded (value for Nch vs NtrCorr(eta<0.5) in pPb)
819 Histo(eventSelection,triggerClassName,centrality,"dNchdetaComparison2Corrections")->Fill(dNchdeta,ctToNch*NtrCorr/(2*fEtaMax));
820 Histo(eventSelection,triggerClassName,centrality,"CheckMeanNtrCorrVsZVertex")->Fill(SPDZv,NtrCorr);
823 Histo(eventSelection,triggerClassName,centrality,"DispersiondNchdetaComparison2Corrections")->Fill((dNchdeta - ctToNch*NtrCorr/(2*fEtaMax)) / dNchdeta);
826 Histo(eventSelection,triggerClassName,centrality,"CheckNtrCorr")->Fill(NtrCorr);
832 Histo(eventSelection,triggerClassName,centrality,"TrackletsVsNch")->Fill(nch[0],nTracklets[0]);
833 Histo(eventSelection,triggerClassName,centrality,"Nch")->Fill(nch[0]);
834 Histo(eventSelection,triggerClassName,centrality,"MeanNchVsZVertex")->Fill(SPDZv,nch[0]);
837 Double_t V0AMult = 0.;
838 Double_t V0CMult = 0.;
840 // AliVVZERO* vzero = aod->GetVZEROData();
841 AliVVZERO* vzero = Event()->GetVZEROData();
844 Double_t multV0A = vzero->GetMTotV0A();
845 V0AMult = AliESDUtils::GetCorrV0A(multV0A,SPDZv);
846 Double_t multV0C = vzero->GetMTotV0C();
847 V0CMult = AliESDUtils::GetCorrV0C(multV0C,SPDZv);
849 Histo(eventSelection,triggerClassName,centrality,"V0AMultVsNch")->Fill(V0AMult,nch[0]);
850 Histo(eventSelection,triggerClassName,centrality,"V0CMultVsNch")->Fill(V0CMult,nch[0]);
857 // Mean dNch/dEta computation. In case the correction is the 'mean' one, this is not really dNch/deta, we have to multiply it by a factor <Nch>/<Ntrkls_corr> (we get <Nch> from a MC)
858 Double_t meandNchdEta(0.);
862 if ( fSPDOneOverAccxEff ) meandNchdEta = nch[0] / (nBins*fEtaAxis->GetBinWidth(5)); // Divide by nBins to get the mean and by the binWidht to get the d/dEta
863 else if ( fSPDMeanTracklets ) meandNchdEta = nch[0] / (2.*fEtaMax); //fEtaAxis->GetBinWidth(5);
866 Histo(eventSelection,triggerClassName,centrality,"dNchdEta")->Fill(meandNchdEta);
867 Histo(eventSelection,triggerClassName,centrality,"MeandNchdEtaVsZVertex")->Fill(SPDZv,meandNchdEta);
870 //_____________These were tests //FIXME: Check if this tests are still neccesary_____________
871 TObjArray* bins = Binning()->CreateBinObjArray("psi","dnchdeta","");
873 AliAnalysisMuMuBinning::Range* r;
875 while ( ( r = static_cast<AliAnalysisMuMuBinning::Range*>(nextBin()) ) )
878 if ( r->Quantity() == "DNCHDETA" )
880 ok = r->IsInRange(meandNchdEta);
885 Histo(eventSelection,triggerClassName,centrality,Form("EventsIn%s",r->AsString().Data()))->Fill(1.);
892 TObjArray* binsNtrRaw = Binning()->CreateBinObjArray("psi","ntrraw","");
893 TIter nextBinNtrRaw(binsNtrRaw);
894 AliAnalysisMuMuBinning::Range* rNtrRaw;
896 while ( ( rNtrRaw = static_cast<AliAnalysisMuMuBinning::Range*>(nextBinNtrRaw()) ) )
899 if ( rNtrRaw->Quantity() == "NTRRAW" )
901 ok = rNtrRaw->IsInRange(nTracklets[0]);
906 Histo(eventSelection,triggerClassName,centrality,Form("MeanTrackletsVsZVertex%s",rNtrRaw->AsString().Data()))->Fill(SPDZv,nTracklets[0]);
913 TObjArray* binsNtr = Binning()->CreateBinObjArray("psi","ntrcorr","");
914 TIter nextBinNtr(binsNtr);
915 AliAnalysisMuMuBinning::Range* rNtr;
917 while ( ( rNtr = static_cast<AliAnalysisMuMuBinning::Range*>(nextBinNtr()) ) )
920 if ( rNtr->Quantity() == "NTRCORR" )
922 ok = rNtr->IsInRange(nch[0]);
927 Histo(eventSelection,triggerClassName,centrality,Form("MeanNchVsZVertex%s",rNtr->AsString().Data()))->Fill(SPDZv,nch[0]);
934 TObjArray* binsRel = Binning()->CreateBinObjArray("psi","relntrcorr","");
935 TIter nextBinRel(binsRel);
936 AliAnalysisMuMuBinning::Range* rRel;
937 while ( ( rRel = static_cast<AliAnalysisMuMuBinning::Range*>(nextBinRel()) ) )
940 if ( rRel->Quantity() == "RELNTRCORR" )
942 ok = rRel->IsInRange(nch[0]/fMeanTrRef);
947 Histo(eventSelection,triggerClassName,centrality,Form("EventsIn%s",rRel->AsString().Data()))->Fill(1.);
952 //_________________________________________________________________________________________
956 //_____________________________________________________________________________
957 void AliAnalysisMuMuNch::FillHistosForMCEvent(const char* eventSelection,const char* triggerClassName,const char* centrality)
959 /// Fill input MC multiplicity histos
961 if ( IsHistogrammingDisabled() ) return;
963 TList* nchList = static_cast<TList*>(Event()->FindListObject("NCH"));
965 if (!nchList || nchList->IsEmpty())
967 AliError("Empty Nch list in event");
971 Double_t MCZv = AliAnalysisMuonUtility::GetMCVertexZ(Event(),MCEvent()); // Definition of MC generated z vertex
972 // AliVVertex* vertex = static_cast<AliAODEvent*>(Event())->GetPrimaryVertexSPD();
973 AliVVertex* vertex = AliAnalysisMuonUtility::GetVertexSPD(Event());
976 TParameter<Double_t>* p(0x0);
978 //____Resolution Histos___
979 if ( !fSPDOneOverAccxEff && !fSPDMeanTracklets && fResolution )
981 Int_t nContributors(0);
984 nContributors = vertex->GetNContributors();
985 SPDZv = vertex->GetZ();
987 MCHisto(eventSelection,triggerClassName,centrality,"SPDZvResVsnC")->Fill(nContributors,SPDZv - MCZv);
988 MCHisto(eventSelection,triggerClassName,centrality,"SPDZvResVsMCz")->Fill(MCZv,SPDZv - MCZv);
990 Double_t EtaReco(0.),EtaMC(0.),PhiReco(0.),PhiMC(0.);
991 Int_t i(-1),labelEtaReco(-1),labelEtaMC(-1),labelPhiReco(-1),labelPhiMC(-1);
993 while ( i < nchList->GetEntries() - 1 )
996 while ( nchList->At(i)->IsA() != TParameter<Double_t>::Class() ) // In case there is a diferent object, just to skip it
1001 p = static_cast<TParameter<Double_t>*>(nchList->At(i));
1005 if ( TString(p->GetName()).Contains("EtaReco") ) // We take the reco eta
1007 sscanf(p->GetName(),"EtaReco%d",&labelEtaReco);
1008 EtaReco = p->GetVal();
1009 MCHisto(eventSelection,triggerClassName,centrality,"Eta")->Fill(EtaReco);
1011 else if ( TString(p->GetName()).Contains("EtaMC") ) // We take the generated eta
1013 sscanf(p->GetName(),"EtaMC%d",&labelEtaMC);
1014 EtaMC = p->GetVal();
1015 MCHisto(eventSelection,triggerClassName,centrality,"MCEta")->Fill(EtaMC);
1017 if ( labelEtaReco > 0 && labelEtaReco == labelEtaMC ) // To be sure we compute the difference for the same particle
1019 labelEtaReco = -1; // Restart of the label value to avoid double count the eta difference when computing the phi one
1020 Double_t EtaDif = EtaReco - EtaMC;
1021 MCHisto(eventSelection,triggerClassName,centrality,"EtaRes")->Fill(EtaDif);
1022 MCHisto(eventSelection,triggerClassName,centrality,"EtaResVsZ")->Fill(MCZv,EtaDif);
1023 MCHisto(eventSelection,triggerClassName,centrality,"EtaResVsnC")->Fill(nContributors,EtaDif);
1027 else if ( TString(p->GetName()).Contains("PhiReco") ) // We take the reco phi
1029 sscanf(p->GetName(),"PhiReco%d",&labelPhiReco);
1030 PhiReco = p->GetVal();
1031 MCHisto(eventSelection,triggerClassName,centrality,"Phi")->Fill(PhiReco);
1033 else if ( TString(p->GetName()).Contains("PhiMC") ) // We take the generated phi
1035 sscanf(p->GetName(),"PhiMC%d",&labelPhiMC);
1036 PhiMC = p->GetVal();
1037 MCHisto(eventSelection,triggerClassName,centrality,"MCPhi")->Fill(PhiMC);
1040 if ( labelPhiReco > 0 && labelPhiReco == labelPhiMC ) // To be sure we compute the difference for the same particle
1042 labelPhiReco = -1; // Restart of the label value to avoid double count the phi difference when computing the eta one
1043 Double_t PhiDif = PhiReco - PhiMC;
1044 MCHisto(eventSelection,triggerClassName,centrality,"PhiRes")->Fill(PhiDif);
1046 //___With the following algorithm we refer the differences to the interval [-Pi/2,Pi/2]
1047 if ( PhiDif < -TMath::PiOver2() && PhiDif > -TMath::Pi() )
1049 PhiDif = -TMath::Pi() - PhiDif;
1051 else if ( PhiDif < -TMath::Pi() )
1053 PhiDif = -2.*TMath::Pi() - PhiDif;
1054 if ( PhiDif < -TMath::PiOver2() )
1056 PhiDif = -TMath::Pi() - PhiDif;
1060 else if ( PhiDif > TMath::PiOver2() && PhiDif < TMath::Pi() )
1062 PhiDif = TMath::Pi() - PhiDif;
1064 else if ( PhiDif > TMath::Pi() )
1066 PhiDif = 2.*TMath::Pi() - PhiDif;
1067 if ( PhiDif > TMath::PiOver2() )
1069 PhiDif = TMath::Pi() - PhiDif;
1074 MCHisto(eventSelection,triggerClassName,centrality,"PhiResVsZ")->Fill(MCZv,PhiDif);
1075 MCHisto(eventSelection,triggerClassName,centrality,"PhiResShifted")->Fill(PhiDif);
1076 MCHisto(eventSelection,triggerClassName,centrality,"PhiResVsnC")->Fill(nContributors,PhiDif);
1080 return; // When computing resolutions we skip the rest of the method
1084 //___Multiplicity histos (just when not computing resolutions)___
1085 TH1* hSPDcorrectionVsEta = static_cast<TH1*>(nchList->FindObject("MCSPDcorrectionVsEta"));
1086 TH1* hNBkgTrackletsVSEta = static_cast<TH1*>(nchList->FindObject("NBkgTrackletsVSEta"));
1087 TH1* hNchVsPhi = static_cast<TH1*>(nchList->FindObject("MCNchVsPhi"));
1088 TH1* hNchVsEta = static_cast<TH1*>(nchList->FindObject("MCNchVsEta"));
1089 TH1* hNTrackletVsEta = static_cast<TH1*>(nchList->FindObject("MCNTrackletVsEta"));
1090 TH1* hNTrackletVsPhi = static_cast<TH1*>(nchList->FindObject("MCNTrackletVsPhi"));
1092 TProfile* hMeanNchVsEta = static_cast<TProfile*>(MCHisto(eventSelection,triggerClassName,centrality,"MeanNchVsEta"));
1094 TH2* hEventsVsZVertexVsEta = static_cast<TH2*>(MCHisto(eventSelection,triggerClassName,centrality,"EventsVsZVertexVsEta"));
1098 Double_t nchSum(0.),nTracklets(0.);
1099 for (Int_t j = 1 ; j <= fEtaAxis->GetNbins() ; j++) //Loop over all eta bins
1101 Double_t correction = hSPDcorrectionVsEta->GetBinContent(j);
1103 if ( correction < 0 ) continue; // We count just the particles in the SPD acceptance. (MCSPDcorrectionVsEta is filled to -1 in SetEvent() for those bins out of range)
1105 nTracklets += hNTrackletVsEta->GetBinContent(j); // Reco tracklets
1107 ++nBins; // We sum up the number of bins entering in the computation
1109 Double_t eta = fEtaAxis->GetBinCenter(j);
1110 Double_t nch = hNchVsEta->GetBinContent(j); // Generated particles
1114 hMeanNchVsEta->Fill(eta,nch); // Fill the number of charged particles of each eta bin in the profile
1116 hEventsVsZVertexVsEta->Fill(MCZv,eta,1.0); // Fill 1 count each eta bin where the events contributes
1119 MCHisto(eventSelection,triggerClassName,centrality,"Tracklets")->Fill(nTracklets); // Note that these are NOT the same tracklets as in the FillHistosForEvent() since here the SPD "dead" zones (the ones where correction > threshold) are not rejected
1123 SPDZv = vertex->GetZ();
1126 Bool_t isMChisto = kTRUE; // Used to get the MC histos in the Add method
1128 AddHisto(eventSelection,triggerClassName,centrality,"NBkgTrackletsVsZVertexVsEta",SPDZv,hNBkgTrackletsVSEta,isMChisto);
1129 AddHisto(eventSelection,triggerClassName,centrality,"NchVsZVertexVsPhi",MCZv,hNchVsPhi,isMChisto);
1130 AddHisto(eventSelection,triggerClassName,centrality,"NchVsZVertexVsEta",MCZv,hNchVsEta,isMChisto);
1131 AddHisto(eventSelection,triggerClassName,centrality,"NchVsRecoZVertexVsEta",SPDZv,hNchVsEta,isMChisto);
1132 AddHisto(eventSelection,triggerClassName,centrality,"TrackletsVsZVertexVsEta",SPDZv,hNTrackletVsEta,isMChisto);
1133 AddHisto(eventSelection,triggerClassName,centrality,"TrackletsVsZVertexVsPhi",SPDZv,hNTrackletVsPhi,isMChisto);
1135 MCHisto(eventSelection,triggerClassName,centrality,"MeanNchVsZVertex")->Fill(MCZv,nchSum);
1136 MCHisto(eventSelection,triggerClassName,centrality,"Nch")->Fill(nchSum);
1139 // Mean dNch/dEta computation
1140 Double_t meandNchdEta(0.);
1143 meandNchdEta = nchSum / (nBins*fEtaAxis->GetBinWidth(5)); // Divide by nBins to get the mean and by the binWidht to get the d/dEta
1146 MCHisto(eventSelection,triggerClassName,centrality,"dNchdEta")->Fill(meandNchdEta);
1151 Double_t nTrCorr(0.);
1152 Double_t dNchdetaReco(0.);
1153 Double_t ctToNch = 1.11; //FIXME: hardcoded (value for Nch vs NtrCorr(eta<0.5) in pPb)
1154 while ( i < nchList->GetEntries() - 1 )
1157 while ( nchList->At(i)->IsA() != TParameter<Double_t>::Class() && i < nchList->GetEntries() - 1 ) // In case there is a diferent object, just to skip it
1162 p = static_cast<TParameter<Double_t>*>(nchList->At(i));
1164 if ( ( TString(p->GetName()).Contains("NtrCorr") || TString(p->GetName()).BeginsWith("Nch") ) && ( (fSPDMeanTracklets && !fSPDOneOverAccxEff) || (!fSPDMeanTracklets && fSPDOneOverAccxEff) ))
1166 MCHisto(eventSelection,triggerClassName,centrality,"CorrTrackletsVsNch")->Fill(nchSum,p->GetVal());
1168 else if ( TString(p->GetName()).Contains("NtrCorr") )
1170 nTrCorr = p->GetVal();
1171 MCHisto(eventSelection,triggerClassName,centrality,"dNchdetaFromNtrCorrVsdNchdEtaMC")->Fill(meandNchdEta,ctToNch*nTrCorr/(2*fEtaMax));
1172 MCHisto(eventSelection,triggerClassName,centrality,"RelDispersiondNchdetaFromNtrCorrVsdNchdEtaMC")->Fill((meandNchdEta - ctToNch*nTrCorr/(2*fEtaMax)) / meandNchdEta);
1173 MCHisto(eventSelection,triggerClassName,centrality,"DispersiondNchdetaFromNtrCorrVsdNchdEtaMC")->Fill((meandNchdEta - ctToNch*nTrCorr/(2*fEtaMax)));
1175 else if ( TString(p->GetName()).Contains("Ntr") && !TString(p->GetName()).Contains("SPDOk") && !TString(p->GetName()).Contains("Corr"))
1177 MCHisto(eventSelection,triggerClassName,centrality,"TrackletsVsNch")->Fill(nchSum,p->GetVal());
1179 else if ( TString(p->GetName()).Contains("MeandNchdEta") )
1181 dNchdetaReco = p->GetVal();
1182 MCHisto(eventSelection,triggerClassName,centrality,"dNchdetaVsMCdNchdeta")->Fill(meandNchdEta,dNchdetaReco);
1183 MCHisto(eventSelection,triggerClassName,centrality,"dNchdetaFromAccEffVsdNchdEtaMC")->Fill(meandNchdEta,dNchdetaReco);
1184 MCHisto(eventSelection,triggerClassName,centrality,"RelDispersiondNchdetaFromAccEffVsdNchdEtaMC")->Fill((meandNchdEta - dNchdetaReco) / meandNchdEta);
1185 MCHisto(eventSelection,triggerClassName,centrality,"DispersiondNchdetaFromAccEffVsdNchdEtaMC")->Fill((meandNchdEta - dNchdetaReco));
1189 Double_t V0AMult = 0.;
1190 Double_t V0CMult = 0.;
1192 AliVVZERO* vzero = Event()->GetVZEROData();
1195 Double_t multV0A = vzero->GetMTotV0A();
1196 V0AMult = AliESDUtils::GetCorrV0A(multV0A,MCZv);
1197 Double_t multV0C = vzero->GetMTotV0C();
1198 V0CMult = AliESDUtils::GetCorrV0C(multV0C,MCZv);
1200 MCHisto(eventSelection,triggerClassName,centrality,"V0AMultVsNch")->Fill(V0AMult,nchSum);
1201 MCHisto(eventSelection,triggerClassName,centrality,"V0CMultVsNch")->Fill(V0CMult,nchSum);
1208 //_____________________________________________________________________________
1209 Bool_t AliAnalysisMuMuNch::GetEtaRangeSPD(Double_t spdZVertex, Double_t etaRange[])
1211 // Fill the SPD eta range for a given z vertex and returns whether the range is valid or not.
1213 if ( fSPDMeanTracklets || (!fSPDMeanTracklets && !fSPDOneOverAccxEff) )
1215 // If we are using the mean correction or we want the raw distributions we should not apply the algorithm to restric the eta range, in order to avoid the effect of the eta-Zv bins on the distributions ( the algorithm makes that when an eta bin is partially out of the SPD acceptance we remove it. This makes that the mean raw tracklets distribution is not smooth for Zv in which the eta range is partially out of the SPD )
1217 //FIXME: Implement something to warning or reject events for which the selected eta range is completely out of the SPD acceptance
1218 etaRange[0] = fEtaMin;
1219 etaRange[1] = fEtaMax - 1E-6;
1224 Double_t etaMax(fEtaMax),etaMin(fEtaMin);
1226 Double_t vf1LR = fSPD1LR->Eval(spdZVertex); //Eta values for the z vertex over the SPD acceptance curves
1227 Double_t vf2LR = fSPD2LR->Eval(spdZVertex);
1228 Double_t vf1LL = fSPD1LL->Eval(spdZVertex);
1229 Double_t vf2LL = fSPD2LL->Eval(spdZVertex);
1231 //____We start by asigning the eta range as the eta values in the SPD acceptance curve
1232 if ( spdZVertex < 0. )
1235 etaMin = TMath::Max(vf1LL,vf2LL);
1239 etaMax = TMath::Min(vf1LR,vf2LR);
1245 //____Algorithm to avoid taking bins which are crossed by the SPD acceptance curves
1246 Int_t binYMin = fEtaAxis->FindBin(etaMin); // Find the corresponding bins for eta max & min and z vertex
1247 Int_t binYMax = fEtaAxis->FindBin(etaMax);
1248 Int_t binX = fZAxis->FindBin(spdZVertex);
1250 // Define the values for the relevant edges of the eta and z bins
1251 Double_t upEdge = fEtaAxis->GetBinUpEdge(binYMax); // up edge of the top eta bin
1252 Double_t lowEdge = fEtaAxis->GetBinLowEdge(binYMin); // low edge of the bottom eta bin
1253 Double_t leftEdge = fZAxis->GetBinLowEdge(binX); // left edge of the z bin
1254 Double_t rightEdge = fZAxis->GetBinUpEdge(binX); // right edge of the z bin
1256 Double_t etaMaxTemp(0.),etaMinTemp(0.);
1257 if ( spdZVertex < 0. )
1259 etaMaxTemp = fSPD2LR->Eval(rightEdge); // Define the temporary eta max as the value of the curve int the righ edge of the bin
1260 etaMinTemp = TMath::Max(fSPD1LL->Eval(leftEdge),fSPD2LL->Eval(leftEdge));
1264 etaMaxTemp = TMath::Min(fSPD1LR->Eval(rightEdge),fSPD2LR->Eval(rightEdge));
1265 etaMinTemp = fSPD2LL->Eval(leftEdge);
1268 while ( upEdge > etaMaxTemp ) //We take eta max as the up edge of the 1st bin which is inside the SPD acceptance but not crossed by the curve
1270 binYMax = binYMax - 1; // Since the up edge of the current bin is bigger than the SPD acc curve we move 1 bin below
1271 upEdge = fEtaAxis->GetBinUpEdge(binYMax); // Take the up edge of the new bin
1272 etaMax = upEdge - 1E-6; // We substract 1E-6 cause the up edge of the a bin belongs to the bin+1
1276 //We take eta min as the low edge of the 1st bin which is inside the SPD acceptance but not crossed by the curve
1277 while ( lowEdge < etaMinTemp )
1279 binYMin = binYMin + 1; // Since the low edge of the current bin is smaller than the SPD acc curve we move 1 bin above
1280 lowEdge = fEtaAxis->GetBinLowEdge(binYMin); // Take the low edge of the new bin
1281 etaMin = lowEdge + 1E-6;
1285 // In case the eta range we want (given in the constructor) is smaller than the one found by the algorithm (max range) we redefine the values
1286 if ( etaMin < fEtaMin ) etaMin = fEtaMin + 1E-6;
1287 if ( etaMax > fEtaMax ) etaMax = fEtaMax - 1E-6;
1289 if ( etaMin > etaMax ) // If this happens, the event is not able to cover the desired eta range, so we set an invalid range
1292 etaRange[1] = -999.;
1294 return kFALSE; //FIXME: Shall we add something to invalidate this event in SetEvent to dont count it in AliAnalysisTaskMuMu::FillCounters?
1298 etaRange[0] = etaMin;
1299 etaRange[1] = etaMax;
1305 //_____________________________________________________________________________
1306 Double_t AliAnalysisMuMuNch::GetSPDCorrection(Double_t zvert, Double_t eta) const
1308 if ( !fSPDOneOverAccxEff )
1310 return 1.; // Like this we will simply compute the raw tracklets or if we are correctiong by the mean tracklets the eta bin will be counted as valid
1314 Int_t bin =fSPDOneOverAccxEff->FindBin(zvert,eta);
1315 return fSPDOneOverAccxEff->GetBinContent(bin);// Like this we will compute Nch from the SPD AccxEFf
1319 //_____________________________________________________________________________
1320 Double_t AliAnalysisMuMuNch::GetTrackletsMeanCorrection(Double_t zvert, Int_t nTracklets, Bool_t corrToCompare) const
1322 if ( !fSPDMeanTracklets )
1324 AliFatal("ERROR: No tracklets mean correction");
1330 if ( corrToCompare && fSPDMeanTrackletsCorrToCompare ) h = static_cast<TProfile*>(fSPDMeanTrackletsCorrToCompare);
1331 else h = static_cast<TProfile*>(fSPDMeanTracklets);
1333 Int_t bin = h->FindBin(zvert);
1334 Double_t mNTtklsZ = h->GetBinContent(bin);
1336 Double_t mNTtklsZref(0.);
1337 if ( fSPDMeanTrackletsCorrToCompare )
1339 if ( corrToCompare ) mNTtklsZref = h->GetMaximum();
1342 if ( fMeanTrRef > 0. ) mNTtklsZref = fMeanTrRef;
1343 else mNTtklsZref = h->GetMaximum();
1348 if ( fMeanTrRef > 0. ) mNTtklsZref = fMeanTrRef;
1349 else mNTtklsZref = h->GetMaximum();
1353 if ( mNTtklsZ == 0. ) deltaN = -1000.; // If the zvertex is out of the correction range the correction is < -999 (non valid)
1357 if ( mNTtklsZref < mNTtklsZ ) coef = -1.;
1359 Double_t meanPoiss = nTracklets*(mNTtklsZref - mNTtklsZ)/mNTtklsZ;
1360 deltaN = coef*frand->PoissonD(TMath::Abs(meanPoiss));
1367 //_____________________________________________________________________________
1368 AliAODTracklets* AliAnalysisMuMuNch::GetTracklets(AliVEvent* event)
1370 /// Return AliAODTracklets if the event is an AOD event. If event is ESD event creates AliAODTracklets object from ESD AliMultiplicity and returns it
1372 AliAODTracklets* tracklets(0x0);
1374 if ( event->IsA() == AliAODEvent::Class() )
1376 tracklets = static_cast<const AliAODEvent*>(Event())->GetTracklets(); // Tracklets object
1378 else if ( event->IsA() == AliESDEvent::Class() )
1380 const AliMultiplicity* mult = static_cast<const AliESDEvent*>(Event())->GetMultiplicity();
1384 tracklets = new AliAODTracklets();
1386 if ( mult->GetNumberOfTracklets() > 0 )
1388 tracklets->CreateContainer(mult->GetNumberOfTracklets());
1389 for (Int_t n = 0 ; n < mult->GetNumberOfTracklets() ; n++)
1391 tracklets->SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n, 0),mult->GetLabel(n, 1));
1396 else AliFatal("Unrecognized Event Type");
1402 //==============================These methods are useless here, anyway they should go in the EventCutterClass=================
1403 //_____________________________________________________________________________
1404 Bool_t AliAnalysisMuMuNch::HasAtLeastNTrackletsInEtaRange(const AliVEvent& event, Int_t n, Double_t& etaMin, Double_t& etaMax) const
1406 if ( event.IsA() != AliAODEvent::Class() )
1411 AliAODTracklets* tracklets = static_cast<const AliAODEvent&>(event).GetTracklets();
1418 Int_t nTrackletsInRange(0);
1420 Int_t nTracklets = tracklets->GetNumberOfTracklets();
1422 for (Int_t i = 0 ; i < nTracklets && nTrackletsInRange < n; i++)
1424 Double_t eta = -TMath::Log(TMath::Tan(tracklets->GetTheta(i)/2.0));
1426 if ( eta > etaMin && eta < etaMax )
1428 ++nTrackletsInRange;
1432 return (nTrackletsInRange>=n);
1435 //_____________________________________________________________________________
1436 void AliAnalysisMuMuNch::NameOfHasAtLeastNTrackletsInEtaRange(TString& name, Int_t n, Double_t& etaMin, Double_t& etaMax) const
1438 if ( TMath::AreEqualAbs(TMath::Abs(etaMin),TMath::Abs(etaMax),1E-9 ) )
1440 name.Form("ATLEAST%dTRKLINABSETALT%3.1f",n,TMath::Abs(etaMin));
1444 name.Form("ATLEAST%dTRKLINETA%3.1f-%3.1f",n,etaMin,etaMax);
1447 //=======================================================================================
1449 //_____________________________________________________________________________
1450 Bool_t AliAnalysisMuMuNch::IsMCtrackFromGenerator(Int_t indexMC) const
1452 ///Checks if the MC particle corresponding to a track has been generated with a given generator.
1456 AliWarning("There is no MC information in the event");
1460 if ( indexMC >= MCEvent()->GetNumberOfTracks() )
1462 AliWarning("This MC track does not exist. Index out of range");
1466 //______________"MANUAL" METHOD___________//
1467 //It does not work since NProduced gives just the stable dpmjet produced particles. See AliMCEvent::GetGenerator
1468 // Int_t labelTemp(labelMC);
1469 // while ( labelTemp != -1 )
1471 // AODpartMCTemp = static_cast<AliAODMCParticle*>(MCEvent()->GetTrack(labelMC));
1472 // labelTemp = AODpartMCTemp->GetMother();
1473 // if ( labelTemp != -1 ) labelMC = labelTemp;
1474 // std::cout << labelTemp << " ===>" << labelMC <<std::endl;
1477 // AliAODMCHeader* mcHeader = static_cast<AliAODMCHeader*>(Event()->FindListObject(AliAODMCHeader::StdBranchName()));
1480 // TList* lheaders = mcHeader->GetCocktailHeaders();
1481 // lheaders->Print();
1483 // AliGenEventHeader* mcGenH(0x0);
1484 // TIter next(lheaders); // Get the iterator on the list of cocktail headers
1485 // Int_t nProduced(0);
1486 // while ( labelMC >= nProduced ) // Loop over the cocktail headers
1488 // mcGenH = static_cast<AliGenEventHeader*>(next());
1491 // std::cout << "Generator header not found" << std::endl;
1494 // else nProduced += mcGenH->NProduced();
1497 // TString genName(mcGenH->GetName());
1498 // return genName.Contains("dpmjet_0");
1499 //_________________________________________
1502 if ( !MCEvent()->GetCocktailGenerator(indexMC,genName) )
1504 AliWarning("No cocktail generator found for this event");
1507 // std::cout << genName.Data() << std::endl;
1508 return genName.Contains(fGeneratorHeaderClass->Data());
1511 //==============================This method is not used=====================
1512 //_____________________________________________________________________________
1513 Double_t AliAnalysisMuMuNch::NumberOfTrackletsInEtaRange(const AliVEvent& event, Double_t& etaMin, Double_t& etaMax, Bool_t /*corrected*/) const
1515 if ( event.IsA() != AliAODEvent::Class() )
1517 AliError("Not working for ESDs...");
1521 AliAODTracklets* tracklets = static_cast<const AliAODEvent&>(event).GetTracklets();
1528 Double_t nTrackletsInRange(0);
1530 Int_t nTracklets = tracklets->GetNumberOfTracklets();
1532 for (Int_t i = 0 ; i < nTracklets ; i++)
1534 Double_t thetaTracklet = tracklets->GetTheta(i);
1535 Double_t etaTracklet = -TMath::Log(TMath::Tan(thetaTracklet/2.));
1537 if ( etaTracklet > etaMin && etaTracklet < etaMax )
1539 nTrackletsInRange += 1.0;
1543 return nTrackletsInRange;
1545 //==============================
1548 //_____________________________________________________________________________
1549 void AliAnalysisMuMuNch::SetEvent(AliVEvent* event, AliMCEvent* mcEvent)
1551 /// Set the event, compute multiplicities and add them as a list to the event
1553 // if ( event->IsA() != AliAODEvent::Class() )
1555 // AliError("Only working for AODs for the moment.");
1559 AliAnalysisMuMuBase::SetEvent(event,mcEvent); // To have Event() and MCEvent() method working
1561 TList* nchList = static_cast<TList*>(event->FindListObject("NCH")); // Define the list with the NCH info for each event
1564 nchList = new TList;
1565 nchList->SetOwner(kTRUE);
1566 nchList->SetName("NCH");
1567 event->AddObject(nchList);
1570 nchList->Clear(); // We clear the NCH list for this new event
1573 Bool_t vertexSPDFound(kFALSE);
1574 // AliAODTracklets* tracklets(0x0);
1576 AliVVertex* vertexSPD = AliAnalysisMuonUtility::GetVertexSPD(event);
1579 vertexSPDFound = kTRUE;
1580 SPDZv = vertexSPD->GetZ();
1581 if ( SPDZv == 0. ) SPDZv = -40.; // If SPDZv = 0. means that there is no reconstructed vertex. Setting the vertex to -40 allow us to get an invalid correction
1584 AliAODTracklets* tracklets = GetTracklets(event);
1586 // if ( event->IsA() == AliAODEvent::Class() )
1588 // const AliAODVertex* vertexSPD = static_cast<const AliAODEvent*>(Event())->GetPrimaryVertexSPD(); // SPD vertex object
1591 // vertexSPDFound = kTRUE;
1592 // SPDZv = vertexSPD->GetZ();
1593 // if ( SPDZv == 0. ) SPDZv = -40.; // If SPDZv = 0. means that there is no reconstructed vertex. Setting the vertex to -40 allow us to get an invalid correction
1597 // tracklets = static_cast<const AliAODEvent*>(Event())->GetTracklets(); // Tracklets object
1600 // else if ( event->IsA() == AliESDEvent::Class() )
1602 // const AliESDVertex* vertexSPD = static_cast<const AliESDEvent*>(Event())->GetPrimaryVertexSPD(); // SPD vertex object
1605 // vertexSPDFound = kTRUE;
1606 // SPDZv = vertexSPD->GetZ();
1610 // tracklets = new AliAODTracklets();
1611 // const AliMultiplicity* mult = static_cast<const AliESDEvent*>(Event())->GetMultiplicity();
1615 // if (mult->GetNumberOfTracklets()>0)
1617 // tracklets->CreateContainer(mult->GetNumberOfTracklets());
1618 // for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++)
1622 //// fMChandler->SelectParticle(mult->GetLabel(n, 0));
1623 //// fMChandler->SelectParticle(mult->GetLabel(n, 1));
1625 // tracklets->SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n, 0),mult->GetLabel(n, 1));
1630 // else AliFatal("Unrecognized Event Type");
1632 TH1* hSPDcorrectionVsEta(0x0); // Pointers for the individual event histos
1633 TH1* hNchVsEta(0x0);
1634 TH1* hNTrackletVsEta(0x0);
1635 TH1* hNTrackletVsPhi(0x0);
1637 // Variables we will use in the multiplicity computation
1638 Int_t binMin,binMax;
1639 Int_t nTracklets(0);
1640 Double_t thetaTracklet(0.),phiTracklet(0.),etaTracklet(0.);
1642 Int_t nTrackletsInRange(0);
1643 Int_t nTrackletsInRangeSPDOk(0);
1647 Bool_t isEtaRangeValid = GetEtaRangeSPD(SPDZv,fetaRange);
1649 //____Data (or reco) multiplicity computation ___
1650 if ( !fResolution ) // When computing resolutions we dont do anything else
1652 //_______Create once the histos with the individual event "properties" (cleared at the beginning of each new event)_______
1653 if ( !Histo("AliAnalysisMuMuNch","SPDcorrectionVsEta") )
1655 CreateEventHistos(kHistoForData | kHistoForMCInput,"AliAnalysisMuMuNch","SPDcorrectionVsEta","SPD correction-like vs #eta;#eta",fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
1657 CreateEventHistos(kHistoForMCInput,"AliAnalysisMuMuNch","NchVsEta","Nch vs #eta;#eta",fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
1659 CreateEventHistos(kHistoForData | kHistoForMCInput,"AliAnalysisMuMuNch","NTrackletVsEta","Ntracklet vs #eta;#eta",fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
1661 CreateEventHistos(kHistoForData,"AliAnalysisMuMuNch","NBkgTrackletsVSEta","NBkg Tracklets vs #eta;#eta",fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
1663 Double_t phimin = 0.; //Phi range
1664 Double_t phimax = 2*TMath::Pi();
1665 Int_t nphibins = GetNbins(phimin,phimax,0.05);
1667 CreateEventHistos(kHistoForData | kHistoForMCInput,"AliAnalysisMuMuNch","NTrackletVsPhi","Ntracklet vs #phi;#phi",nphibins,phimin,phimax);
1669 CreateEventHistos(kHistoForMCInput,"AliAnalysisMuMuNch","NchVsPhi","Nch vs #phi;#phi",nphibins,phimin,phimax);
1671 CreateEventHistos(kHistoForData | kHistoForMCInput,"AliAnalysisMuMuNch","test","test",fZAxis->GetNbins(),fZAxis->GetXmin(),fZAxis->GetXmax(),fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
1673 Histo("AliAnalysisMuMuNch","test")->GetListOfFunctions()->Add(fSPD1LR->Clone());
1674 Histo("AliAnalysisMuMuNch","test")->GetListOfFunctions()->Add(fSPD1LL->Clone());
1675 Histo("AliAnalysisMuMuNch","test")->GetListOfFunctions()->Add(fSPD2LR->Clone());
1676 Histo("AliAnalysisMuMuNch","test")->GetListOfFunctions()->Add(fSPD2LL->Clone());
1680 hSPDcorrectionVsEta = Histo("AliAnalysisMuMuNch","SPDcorrectionVsEta"); // Set the individual event histos
1681 hNTrackletVsEta = Histo("AliAnalysisMuMuNch","NTrackletVsEta");
1682 hNTrackletVsPhi = Histo("AliAnalysisMuMuNch","NTrackletVsPhi");
1684 hSPDcorrectionVsEta->Reset(); // Reset of the individual event histos
1685 hNTrackletVsEta->Reset();
1686 hNTrackletVsPhi->Reset();
1688 //____Data (or Reco if simu) tracklets computation___
1689 if ( tracklets && vertexSPDFound && isEtaRangeValid )
1692 Histo("AliAnalysisMuMuNch","test")->Fill(SPDZv,fetaRange[1]);
1693 Histo("AliAnalysisMuMuNch","test")->Fill(SPDZv,fetaRange[0]);
1695 nTracklets = tracklets->GetNumberOfTracklets();
1697 Double_t SPDr; // SPD efficiency (If we use the 'mean correction' or no correction it will be always 1)
1698 for (Int_t i = 0 ; i < nTracklets ; i++)
1700 thetaTracklet = tracklets->GetTheta(i);
1701 etaTracklet = -TMath::Log(TMath::Tan(thetaTracklet/2.));
1702 if ( etaTracklet < fetaRange[0] || etaTracklet > fetaRange[1] ) continue; // Avoid tracklets out of the eta SPD acceptance or out of the eta cut
1704 SPDr = GetSPDCorrection(SPDZv,etaTracklet); // Get SPD AccxEff for the corresponding [zvtx,eta] bin (If we use the 'mean correction' or no correction it will be always 1)
1706 Int_t bin = fEtaAxis->FindBin(etaTracklet);
1708 nTrackletsInRange++;
1709 if ( SPDr!=0. && SPDr <= 2.5) // Threshold to reduce border effects
1711 hSPDcorrectionVsEta->SetBinContent(bin,SPDr);
1712 hNTrackletVsEta->Fill(etaTracklet);
1713 hNTrackletVsPhi->Fill(tracklets->GetPhi(i));
1715 nTrackletsInRangeSPDOk++;
1717 else // If the correction is above the threshold we store a -1 in the correction to skip this eta bin int the fill method (can just happen using SPD AccxEff correction)
1719 hSPDcorrectionVsEta->SetBinContent(bin,-1.0);
1723 nchList->Add(new TParameter<Double_t>("Ntr",nTrackletsInRange));
1724 nchList->Add(new TParameter<Double_t>("NtrSPDOk",nTrackletsInRangeSPDOk)); // if there is not SPD AccxEff correction this will be equal to Ntr
1726 //___ Fill the out-of-eta-range bins with -1.0
1728 binMin = fEtaAxis->FindBin(fetaRange[0]);
1729 binMax = fEtaAxis->FindBin(fetaRange[1]);
1731 for ( Int_t i = 1; i < binMin; ++i )
1733 hSPDcorrectionVsEta->SetBinContent(i,-1.0);
1735 for ( Int_t i = binMax + 1 ; i <= fEtaAxis->GetNbins(); ++i )
1737 hSPDcorrectionVsEta->SetBinContent(i,-1.0);
1740 if ( fSPDOneOverAccxEff || fSPDMeanTracklets ) // Here we correct the raw tracklets
1742 if ( fSPDOneOverAccxEff ) // In this case the correction is the SPD accxEff
1745 //----- Mean dNchdEta computation to set it into the event
1746 for (Int_t j = binMin/*1*/ ; j <= binMax/*fEtaAxis->GetNbins()*/ ; j++) // Loop over eta bins
1748 Double_t correction = hSPDcorrectionVsEta->GetBinContent(j);
1750 Double_t eta = fEtaAxis->GetBinCenter(j);
1752 if ( correction < 0 ) continue; // If the correction is < 0 we skip that eta bin
1753 else if ( correction == 0.0 ) // If the correction is 0 we have no tracklets in that eta bin
1755 Double_t spdCorr = GetSPDCorrection(SPDZv,eta);
1756 if ( spdCorr == 0. || spdCorr > 2.5) continue; // If the correction in the eta bin is not within the threshold we do not count the "0"(that eta bin will not count for nBins)
1759 nch += hNTrackletVsEta->GetBinContent(j) * correction; // Number of charged particles (tracklets*(1/SPDAccxEff))
1761 ++nBins; // We sum up the number of bins entering in the computation
1764 nchList->Add(new TParameter<Double_t>("Nch",nch));
1766 Double_t meandNchdEta(0.);// We compute the mean dNch/dEta in the event
1769 meandNchdEta = nch / (nBins*fEtaAxis->GetBinWidth(5));
1772 nchList->Add(new TParameter<Double_t>("MeandNchdEta",meandNchdEta)); // We add the mean dNch/dEta to the event. It will serve us as a multiplicity estimator.
1774 // else if( fSPDMeanTracklets ) // In this case the correction is the 'mean correction'
1775 if( fSPDMeanTracklets ) // In this case the correction is the 'mean correction'
1777 SPDr = GetTrackletsMeanCorrection(SPDZv,nTrackletsInRange); // Get 'mean correction' for the zvtx
1779 if ( SPDr < -999.) nch = -1;
1780 else nch = nTrackletsInRange + SPDr;
1782 nchList->Add(new TParameter<Double_t>("NtrCorr",nch));// We add the corrected number of tracklets to the event. It will serve us as a multiplicity estimator.
1784 // else AliFatal("Unknown tracklets correction class");
1788 else // If there is no tracklets or vertex object or the eta range is not valid everything is invalidated
1790 for ( Int_t i = 1 ; i <= hSPDcorrectionVsEta->GetNbinsX() ; ++i )
1792 hSPDcorrectionVsEta->SetBinContent(i,-1.0);
1795 nchList->Add(new TParameter<Double_t>("Ntr",-1)); //We set an invalid Ntracklets
1797 if ( fSPDOneOverAccxEff ) // In this case the correction is the SPD accxEff
1799 nchList->Add(new TParameter<Double_t>("MeandNchdEta",-1)); //We set an invalid dNch/deta
1801 else if( fSPDMeanTracklets ) // In this case the correction is the 'mean correction'
1803 nchList->Add(new TParameter<Double_t>("NtrCorr",-1)); //We set an invalid Ntracklets corrected
1808 //____ We add the tracklets histos to the event
1809 nchList->Add(hSPDcorrectionVsEta->Clone());
1810 nchList->Add(hNTrackletVsEta->Clone());
1811 nchList->Add(hNTrackletVsPhi->Clone());
1816 //____Input MC multiplicity computation ___
1819 Double_t etaRange[2];
1820 if ( !fResolution ) //When computing resolutions we dont do anything else
1822 Double_t MCZv = AliAnalysisMuonUtility::GetMCVertexZ(Event(),MCEvent());
1823 GetEtaRangeSPD(MCZv,etaRange);
1825 hNchVsEta = MCHisto("AliAnalysisMuMuNch","NchVsEta");
1826 hSPDcorrectionVsEta = MCHisto("AliAnalysisMuMuNch","SPDcorrectionVsEta");
1827 TH1* hNchVsPhi = MCHisto("AliAnalysisMuMuNch","NchVsPhi");
1828 hNTrackletVsEta = MCHisto("AliAnalysisMuMuNch","NTrackletVsEta");
1829 hNTrackletVsPhi = MCHisto("AliAnalysisMuMuNch","NTrackletVsPhi");
1831 hNTrackletVsEta->Reset();
1834 hSPDcorrectionVsEta->Reset();
1835 hNTrackletVsPhi->Reset();
1837 //___ Fill the out-of-eta-range bins with -1.0
1838 binMin = fEtaAxis->FindBin(etaRange[0]);
1839 binMax = fEtaAxis->FindBin(etaRange[1]);
1841 for ( Int_t i = 1; i < binMin; ++i )
1843 hSPDcorrectionVsEta->SetBinContent(i,-1.0);
1845 for ( Int_t i = binMax + 1 ; i <= fEtaAxis->GetNbins(); ++i )
1847 hSPDcorrectionVsEta->SetBinContent(i,-1.0);
1849 for ( Int_t i = binMin; i <= binMax; ++i ) // Fill the bins inside the eta range with +1
1851 hSPDcorrectionVsEta->SetBinContent(i,1.0); // FIXME: Do we really want all the tracklets to be counted for MC purposes? or we want to count only those in active regions of the SPD as for Data computations?
1855 Int_t nMCTracks = MCEvent()->GetNumberOfTracks(); // number of MC tracks
1857 for ( Int_t i = 0; i < nMCTracks ; ++i ) //Loop over generated tracks
1859 // AliAODMCParticle* AODpart = static_cast<AliAODMCParticle*>(mcEvent->GetTrack(i));
1860 AliMCParticle* MCpart = static_cast<AliMCParticle*>(mcEvent->GetTrack(i));
1862 Bool_t isPP(kFALSE);
1863 Int_t nGentorDex(-2); //Generator Index: -1 as default;
1865 // 1, 2 ... are for other generators
1867 if ( static_cast<const AliVEvent*>(event)->IsA() == AliAODEvent::Class() )
1869 AliAODMCParticle* AODpart = static_cast<AliAODMCParticle*>(mcEvent->GetTrack(i));
1870 isPP = AODpart->IsPhysicalPrimary();
1871 nGentorDex = AODpart->GetGeneratorIndex();
1873 else if ( static_cast<const AliVEvent*>(event)->IsA() == AliESDEvent::Class() )
1875 isPP = MCEvent()->IsPhysicalPrimary(i);
1876 nGentorDex = MCpart->GetGeneratorIndex();
1880 // if ( AODpart->IsPhysicalPrimary() ) // We take only particles produced in the collision (Particles produced in the collision including products of strong and electromagnetic decay and excluding feed-down from weak decays of strange particles)
1881 if ( isPP && nGentorDex==0 )
1883 // if ( !IsMCtrackFromGenerator(i) ) continue; // Select only the particles generated by the desired generator
1885 if ( MCpart->Charge()!=0 ) // We take only charged particles
1887 hNchVsEta->Fill(MCpart->Eta());
1888 hNchVsPhi->Fill(MCpart->Phi());
1894 nchList->Add(hNchVsEta->Clone("MCNchVsEta"));
1895 nchList->Add(hNchVsPhi->Clone("MCNchVsPhi"));
1896 nchList->Add(hSPDcorrectionVsEta->Clone("MCSPDcorrectionVsEta"));
1898 //__Bkg tracklets and Resolution estimation __
1899 if ( tracklets ) // We can compute the Bkg tracklets and resolution only if we have the tracklets object in the event
1901 TH1* hNBkgTrackletsVSEta(0x0); // Pointer for the Bkg histo
1904 hNBkgTrackletsVSEta = Histo("AliAnalysisMuMuNch","NBkgTrackletsVSEta");
1906 hNBkgTrackletsVSEta->Reset();
1909 nTracklets = tracklets->GetNumberOfTracklets();
1911 for (Int_t i = 0 ; i < nTracklets ; i++) // Loop over tracklets to check if they come or not from the same MC particle
1913 Int_t label1 = tracklets->GetLabel(i,0);
1914 Int_t label2 = tracklets->GetLabel(i,1);
1916 // if ( !IsMCtrackFromGenerator(label1) || !IsMCtrackFromGenerator(label2) ) continue; // Select only the particles generated by the desired generator
1918 thetaTracklet = tracklets->GetTheta(i);
1919 etaTracklet = -TMath::Log(TMath::Tan(thetaTracklet/2.));
1920 phiTracklet = tracklets->GetPhi(i);
1924 hNTrackletVsEta->Fill(etaTracklet);
1925 hNTrackletVsPhi->Fill(phiTracklet);
1928 if ( label1 != label2 && !fResolution ) hNBkgTrackletsVSEta->Fill(etaTracklet); // Tracklets not comming from the same MC particle are Bkg
1929 else if ( !fSPDOneOverAccxEff && !fSPDMeanTracklets && fResolution ) // Compute the resolutions with the tracklets comming from the same MC particle
1931 // AliAODMCParticle* AODpartMC = static_cast<AliAODMCParticle*>(MCEvent()->GetTrack(label1));
1932 AliMCParticle* partMC = static_cast<AliMCParticle*>(MCEvent()->GetTrack(label1));
1933 Double_t etaTrackletMC = partMC->Eta();
1934 Double_t phiTrackletMC = partMC->Phi();
1936 // Resolution variables
1937 nchList->Add(new TParameter<Double_t>(Form("EtaReco%d",label1),etaTracklet));
1938 nchList->Add(new TParameter<Double_t>(Form("EtaMC%d",label1),etaTrackletMC));
1940 nchList->Add(new TParameter<Double_t>(Form("PhiReco%d",label1),phiTracklet));
1941 nchList->Add(new TParameter<Double_t>(Form("PhiMC%d",label1),phiTrackletMC));
1948 nchList->Add(hNTrackletVsEta->Clone("MCNTrackletVsEta"));
1949 nchList->Add(hNTrackletVsPhi->Clone("MCNTrackletVsPhi"));
1950 nchList->Add(hNBkgTrackletsVSEta->Clone());
1960 //_____________________________________________________________________________
1961 void AliAnalysisMuMuNch::SetRun(const AliInputEventHandler* eventHandler)
1963 // For each new run this method sets the corresponding SPD correction from SPDCorrection list using the SPDCorrection map
1965 if ( !fSPDCorrectionList ) return;
1967 // AliAODEvent* event = static_cast<AliAODEvent*>(eventHandler->GetEvent());
1968 AliVEvent* event = static_cast<AliVEvent*>(eventHandler->GetEvent());
1970 TString run(Form("%d",event->GetRunNumber())); // Get the run number
1971 TObjString* SPDCorrectionKey = static_cast<TObjString*>(fSPDCorrectionMap->GetValue(run)); // Get the corresponding SPDCorrection map key for the run
1973 Int_t SPDCorrectionIndex(0);
1974 if ( SPDCorrectionKey ) SPDCorrectionIndex = SPDCorrectionKey->String().Atoi(); // Converts the key into Int, if found
1975 else AliFatal(Form("No SPD correction found for run %d",run.Atoi()));
1977 TH1* hSPDCorrection = static_cast<TH1*>(fSPDCorrectionList->At(SPDCorrectionIndex)); // Gets the SPD correction at key position from the list
1979 if ( static_cast<TH1*>(hSPDCorrection)->IsA() == TH2::Class() ) fSPDOneOverAccxEff = static_cast<TH2F*>(hSPDCorrection); // Sets the corresponding correction data member
1980 else if ( static_cast<TH1*>(hSPDCorrection)->IsA() == TProfile::Class() ) fSPDMeanTracklets = static_cast<TProfile*>(hSPDCorrection);
1981 else AliFatal("Unrecognized correction class");
1983 AliInfo(Form("Using correction %s for run %s",hSPDCorrection->GetName(),run.Data()));
1987 //_____________________________________________________________________________
1988 void AliAnalysisMuMuNch::Terminate(Option_t *)
1990 /// Called once at the end of the query
1991 if ( !HistogramCollection() ) return;
1993 if ( HistogramCollection()->FindObject(Form("/%s/AliAnalysisMuMuNch/NTrackletVsEta",MCInputPrefix())) )
1995 HistogramCollection()->Remove(Form("/%s/AliAnalysisMuMuNch/NTrackletVsEta",MCInputPrefix()));
1996 HistogramCollection()->Remove(Form("/%s/AliAnalysisMuMuNch/NTrackletVsPhi",MCInputPrefix()));
1997 HistogramCollection()->Remove(Form("/%s/AliAnalysisMuMuNch/NchVsEta",MCInputPrefix()));
1998 HistogramCollection()->Remove(Form("/%s/AliAnalysisMuMuNch/NchVsPhi",MCInputPrefix()));
1999 HistogramCollection()->Remove(Form("/%s/AliAnalysisMuMuNch/SPDcorrectionVsEta",MCInputPrefix()));
2000 HistogramCollection()->Remove("/AliAnalysisMuMuNch/NBkgTrackletsVSEta");
2003 if ( HistogramCollection()->FindObject("/AliAnalysisMuMuNch/NTrackletVsEta") )
2005 HistogramCollection()->Remove("/AliAnalysisMuMuNch/NTrackletVsEta");
2006 HistogramCollection()->Remove("/AliAnalysisMuMuNch/test");
2007 HistogramCollection()->Remove("/AliAnalysisMuMuNch/NTrackletVsPhi");
2008 HistogramCollection()->Remove("/AliAnalysisMuMuNch/SPDcorrectionVsEta");
2010 //____ Compute dNchdEta histo
2011 TObjArray* idArr = HistogramCollection()->SortAllIdentifiers();
2016 while ( (id = static_cast<TObjString*>(next())) )
2018 TProfile* p = static_cast<TProfile*>(HistogramCollection()->FindObject(Form("%s%s",id->GetName(),"MeanNchVsEta")));
2022 TH1* h = new TH1F("MeandNchdEta","Event averaged dN_{ch}/d#eta ;#eta;<dN_{ch}/d#eta>",fEtaAxis->GetNbins(),fEtaAxis->GetXmin(),fEtaAxis->GetXmax());
2024 if ( p->GetNbinsX() != h->GetNbinsX() || p->GetXaxis()->GetXmin() != h->GetXaxis()->GetXmin() || p->GetXaxis()->GetXmax() != h->GetXaxis()->GetXmax() )
2026 AliError("ERROR: Cannot compute MeandNchdEta since the binning doesn't match with MeanNchVsEta histo");
2030 for ( Int_t i = 1 ; i < h->GetNbinsX() ; i++ )
2032 h->SetBinContent(i,p->GetBinContent(i)/p->GetBinWidth(i));
2033 h->SetBinError(i,p->GetBinError(i)/p->GetBinWidth(i));
2034 h->SetEntries(p->GetEntries());
2037 HistogramCollection()->Adopt(Form("%s",id->GetName()),h);