1 //====================================================================
3 // Base class for classes that calculate the multiplicity in the
4 // central region event-by-event
10 // - AliAODCentralMult
15 #include "AliCentralMultiplicityTask.h"
16 #include "AliAODForwardMult.h"
17 #include "AliForwardUtil.h"
19 #include "AliAODHandler.h"
20 #include "AliAnalysisManager.h"
21 #include "AliESDEvent.h"
22 #include "AliMultiplicity.h"
30 //====================================================================
31 AliCentralMultiplicityTask::AliCentralMultiplicityTask(const char* name)
32 : AliAnalysisTaskSE(name),
33 fInspector("centralEventInspector"),
40 fFirstEventSeen(false),
43 fClusterPerTracklet(0),
52 DefineOutput(1, TList::Class());
54 "ESD:AliESDRun.,AliESDHeader.,AliMultiplicity.,"
55 "SPDVertex.,PrimaryVertex.";
57 //____________________________________________________________________
58 AliCentralMultiplicityTask::AliCentralMultiplicityTask()
59 : AliAnalysisTaskSE(),
67 fFirstEventSeen(false),
70 fClusterPerTracklet(0),
80 //____________________________________________________________________
81 AliCentralMultiplicityTask::AliCentralMultiplicityTask(const AliCentralMultiplicityTask& o)
82 : AliAnalysisTaskSE(o),
83 fInspector(o.fInspector),
86 fAODCentral(o.fAODCentral),
88 fUseSecondary(o.fUseSecondary),
89 fUseAcceptance(o.fUseAcceptance),
90 fFirstEventSeen(o.fFirstEventSeen),
92 fNClusterTracklet(o.fNClusterTracklet),
93 fClusterPerTracklet(o.fClusterPerTracklet),
94 fNCluster(o.fNCluster),
95 fNTracklet(o.fNTracklet),
103 //____________________________________________________________________
104 AliCentralMultiplicityTask&
105 AliCentralMultiplicityTask::operator=(const AliCentralMultiplicityTask& o)
108 // Assignment operator
110 if (&o == this) return *this;
111 fInspector = o.fInspector;
114 fAODCentral = o.fAODCentral;
115 fManager = o.fManager;
116 fUseSecondary = o.fUseSecondary;
117 fUseAcceptance = o.fUseAcceptance;
118 fFirstEventSeen = o.fFirstEventSeen;
120 fNClusterTracklet = o.fNClusterTracklet;
121 fClusterPerTracklet= o.fClusterPerTracklet;
122 fNCluster = o.fNCluster;
123 fNTracklet = o.fNTracklet;
128 //____________________________________________________________________
129 void AliCentralMultiplicityTask::UserCreateOutputObjects()
132 // Create output objects
136 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
138 dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
139 if (!ah) AliFatal("No AOD output handler set in analysis manager");
142 TObject* obj = &fAODCentral;
143 ah->AddBranch("AliAODCentralMult", &obj);
150 fInspector.DefineOutput(fList);
155 //____________________________________________________________________
157 AliCentralMultiplicityTask::GetESDEvent()
160 // Get the ESD event. IF this is the first event, initialise
162 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
164 AliWarning("No ESD event found for input event");
168 // IF we've read the first event already, just return the event
169 if (fFirstEventSeen) return esd;
171 // Read the details of the rung
172 fInspector.ReadRunDetails(esd);
174 // If we weren't initialised before (i.e., in the setup), do so now.
175 if (!GetManager().IsInit()) {
176 GetManager().Init(fInspector.GetCollisionSystem(),
177 fInspector.GetEnergy(),
178 fInspector.GetField());
179 AliInfo("Manager of corrections in AliCentralMultiplicityTask init");
181 if (!GetManager().HasSecondaryCorrection())
182 AliFatal("No secondary correction defined!");
183 if (!GetManager().HasAcceptanceCorrection())
184 AliFatal("No acceptance correction defined!");
187 // Check for existence and get secondary map
188 AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
189 const TAxis& vaxis = secMap->GetVertexAxis();
193 fNClusterTracklet = new TH2D("nClusterVsnTracklet",
194 "Total number of cluster vs number of tracklets",
195 100, 0, 10000, 100, 0, 10000);
196 fNClusterTracklet->SetDirectory(0);
197 fNClusterTracklet->SetXTitle("# of free clusters");
198 fNClusterTracklet->SetYTitle("# of tracklets");
199 fNClusterTracklet->SetStats(0);
200 fList->Add(fNClusterTracklet);
204 fClusterPerTracklet = new TH2D("clusterPerTracklet",
205 "N_{free cluster}/N_{tracklet} vs. #eta",
206 nEta,-lEta,lEta, 101, -.05, 10.05);
207 fClusterPerTracklet->SetDirectory(0);
208 fClusterPerTracklet->SetXTitle("#eta");
209 fClusterPerTracklet->SetYTitle("N_{free cluster}/N_{tracklet}");
210 fClusterPerTracklet->SetStats(0);
211 fList->Add(fClusterPerTracklet);
214 fNCluster = new TH1D("cacheCluster", "", nEta,-lEta,lEta);
215 fNCluster->SetDirectory(0);
218 fNTracklet = new TH1D("cacheTracklet", "", nEta,-lEta,lEta);
219 fNTracklet->SetDirectory(0);
222 // Initialize the inspecto
223 fInspector.Init(vaxis);
224 fFirstEventSeen = kTRUE;
226 // Print some information
231 //____________________________________________________________________
233 AliCentralMultiplicityTask::MarkEventForStore() const
235 // Make sure the AOD tree is filled
236 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
238 dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
240 AliFatal("No AOD output handler set in analysis manager");
242 ah->SetFillAOD(kTRUE);
245 //____________________________________________________________________
246 void AliCentralMultiplicityTask::FindEtaLimits()
248 AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
250 const TAxis& vaxis = secMap->GetVertexAxis();
252 fEtaMin.Set(vaxis.GetNbins());
253 fEtaMax.Set(vaxis.GetNbins());
255 TList* hits = new TList;
257 hits->SetName("hitMaps");
260 TList* secs = new TList;
262 secs->SetName("secondaryMaps");
264 TH2D* hCoverage = new TH2D("coverage", "#eta coverage per v_{z}",
265 secMap->GetCorrection(UShort_t(1))->GetXaxis()->GetNbins(),
266 secMap->GetCorrection(UShort_t(1))->GetXaxis()->GetXmin(),
267 secMap->GetCorrection(UShort_t(1))->GetXaxis()->GetXmax(),
268 vaxis.GetNbins(),vaxis.GetXmin(),vaxis.GetXmax());
269 hCoverage->SetDirectory(0);
270 hCoverage->SetXTitle("#eta");
271 hCoverage->SetYTitle("v_{z} [cm]");
272 hCoverage->SetZTitle("n_{bins}");
273 fList->Add(hCoverage);
275 for (Int_t v = 1; v <= vaxis.GetNbins(); v++) {
276 TH2D* corr = secMap->GetCorrection(UShort_t(v));
277 TH1D* proj = corr->ProjectionX(Form("secCor%02d", v));
278 proj->Scale(1. / corr->GetNbinsY());
279 proj->SetTitle(Form("Projection of secondary correction "
280 "for %+5.1f<v_{z}<%+5.1f",
281 vaxis.GetBinLowEdge(v), vaxis.GetBinUpEdge(v)));
282 proj->SetYTitle("#LT 2^{nd} correction#GT");
283 proj->SetDirectory(0);
284 proj->SetMarkerStyle(20);
285 proj->SetMarkerColor(kBlue+1);
288 TH2D* obg = static_cast<TH2D*>(corr->Clone(Form("secCor2DFiducial%02d",v)));
289 obg->SetDirectory(0);
292 TH1D* after = static_cast<TH1D*>(proj->Clone(Form("secCorFiducial%02d",v)));
293 after->SetDirectory(0);
294 after->SetMarkerColor(kRed+1);
297 TH2D* data = static_cast<TH2D*>(corr->Clone(Form("hitMap%02d",v)));
298 //d->SetTitle(Form("hitMap%02d",v));
299 data->SetTitle(Form("d^{2}N/d#eta d#phi "
300 "for %+5.1f<v_{z}<%+5.1f",
301 vaxis.GetBinLowEdge(v), vaxis.GetBinUpEdge(v)));
302 data->GetZaxis()->SetTitle("");
303 data->SetMarkerColor(kBlack);
304 data->SetMarkerStyle(1);
307 TH1D* hAcceptance = fManager.GetAcceptanceCorrection(v);
308 TH1D* accClone = static_cast<TH1D*>(hAcceptance->Clone(Form("acceptance%02d",v)));
311 // Double_t prev = 0;
312 for (Int_t e = 1; e <= proj->GetNbinsX(); e++) {
313 Double_t c = proj->GetBinContent(e);
314 if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
319 after->SetBinContent(e, 0);
320 after->SetBinError(e, 0);
321 for(Int_t nn =1; nn <=obg->GetNbinsY();nn++)
322 obg->SetBinContent(e,nn,0);
325 for (Int_t e = proj->GetNbinsX(); e >= 1; e--) {
326 Double_t c = proj->GetBinContent(e);
327 if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
332 after->SetBinContent(e, 0);
333 after->SetBinError(e, 0);
334 for(Int_t nn =1; nn <=obg->GetNbinsY();nn++)
335 obg->SetBinContent(e,nn,0);
339 for (Int_t nn = fEtaMin[v-1]; nn<=fEtaMax[v-1]; nn++) {
340 hCoverage->SetBinContent(nn,v,1);
346 //____________________________________________________________________
347 void AliCentralMultiplicityTask::UserExec(Option_t* /*option*/)
350 // Process each event
355 fAODCentral.Clear("");
358 AliESDEvent* esd = GetESDEvent();
360 Bool_t lowFlux = kFALSE;
365 UShort_t nClusters = 0;
366 UInt_t found = fInspector.Process(esd, triggers, lowFlux,
367 ivz, vz, cent, nClusters);
369 // No event or no trigger
370 if (found & AliFMDEventInspector::kNoEvent) return;
371 if (found & AliFMDEventInspector::kNoTriggers) return;
373 // Make sure AOD is filled
376 if (found == AliFMDEventInspector::kNoSPD) return;
377 if (found == AliFMDEventInspector::kNoVertex) return;
378 if (triggers & AliAODForwardMult::kPileUp) return;
379 if (found == AliFMDEventInspector::kBadVertex) return; // Out of range
383 const AliMultiplicity* spdmult = esd->GetMultiplicity();
385 TH2D& aodHist = fAODCentral.GetHistogram();
387 ProcessESD(aodHist, spdmult);
388 CorrectData(aodHist, ivz);
390 TList* hitList = static_cast<TList*>(fList->FindObject("hitMaps"));
393 data = static_cast<TH2D*>(hitList->At(ivz-1));
399 //____________________________________________________________________
401 AliCentralMultiplicityTask::ProcessESD(TH2D& aodHist,
402 const AliMultiplicity* spdmult) const
407 //Filling clusters in layer 1 used for tracklets...
408 for(Int_t j = 0; j< spdmult->GetNumberOfTracklets();j++) {
409 Double_t eta = spdmult->GetEta(j);
410 fNTracklet->Fill(eta);
411 aodHist.Fill(eta,spdmult->GetPhi(j));
414 //...and then the unused ones in layer 1
415 for(Int_t j = 0; j< spdmult->GetNumberOfSingleClusters();j++) {
416 Double_t eta = -TMath::Log(TMath::Tan(spdmult->GetThetaSingle(j)/2.));
417 fNCluster->Fill(eta);
418 aodHist.Fill(eta, spdmult->GetPhiSingle(j));
420 fNClusterTracklet->Fill(fNCluster->GetEntries(),
421 fNTracklet->GetEntries());
423 fNCluster->Divide(fNTracklet);
424 for (Int_t j = 1; j <= fNCluster->GetNbinsX(); j++)
425 fClusterPerTracklet->Fill(fNCluster->GetXaxis()->GetBinCenter(j),
426 fNCluster->GetBinContent(j));
430 //____________________________________________________________________
432 AliCentralMultiplicityTask::CorrectData(TH2D& aodHist, UShort_t vtxbin) const
435 TH1D* hAcceptance = fManager.GetAcceptanceCorrection(vtxbin);
436 TH2D* hSecMap = fManager.GetSecMapCorrection(vtxbin);
438 if (!hSecMap) AliFatal("No secondary map!");
439 if (!hAcceptance) AliFatal("No acceptance!");
441 if (fUseSecondary && hSecMap) aodHist.Divide(hSecMap);
443 for(Int_t nx = 1; nx <= aodHist.GetNbinsX(); nx++) {
444 Float_t accCor = hAcceptance->GetBinContent(nx);
445 Float_t accErr = hAcceptance->GetBinError(nx);
447 Bool_t fiducial = true;
448 if (nx < fEtaMin[vtxbin-1] || nx > fEtaMax[vtxbin-1])
450 // Bool_t etabinSeen = kFALSE;
451 for(Int_t ny = 1; ny <= aodHist.GetNbinsY(); ny++) {
454 aodHist.SetBinContent(nx, ny, 0);
455 aodHist.SetBinError(nx, ny, 0);
459 // Get currrent value
460 Float_t aodValue = aodHist.GetBinContent(nx,ny);
461 Float_t aodErr = aodHist.GetBinError(nx,ny);
463 #if 0 // This is done once in the FindEtaBins function
466 if(hSecMap) secCor = hSecMap->GetBinContent(nx,ny);
467 if (secCor > 0.5) etabinSeen = kTRUE;
469 if (aodValue < 0.000001) {
470 aodHist.SetBinContent(nx,ny, 0);
471 aodHist.SetBinError(nx,ny, 0);
474 if (!fUseAcceptance) continue;
476 // Acceptance correction
477 if (accCor < 0.000001) accCor = 1;
478 Float_t aodNew = aodValue / accCor ;
479 Float_t error = aodNew*TMath::Sqrt(TMath::Power(aodErr/aodValue,2) +
480 TMath::Power(accErr/accCor,2) );
481 aodHist.SetBinContent(nx,ny, aodNew);
483 aodHist.SetBinError(nx,ny,error);
484 aodHist.SetBinError(nx,ny,aodErr);
486 //Filling underflow bin if we eta bin is in range
487 if (fiducial) aodHist.SetBinContent(nx,0, 1.);
488 // if (etabinSeen) aodHist.SetBinContent(nx,0, 1.);
492 //____________________________________________________________________
493 void AliCentralMultiplicityTask::Terminate(Option_t* /*option*/)
502 //____________________________________________________________________
504 AliCentralMultiplicityTask::Print(Option_t* option) const
512 std::cout << ClassName() << ": " << GetName() << "\n"
514 << " Use secondary correction: " << fUseSecondary << '\n'
515 << " Use acceptance correction: " << fUseAcceptance << '\n'
516 << " Off-line trigger mask: 0x"
517 << std::hex << std::setfill('0')
518 << std::setw (8) << fOfflineTriggerMask
519 << std::dec << std::setfill (' ')
520 << std::noboolalpha << std::endl;
521 AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
523 const TAxis& vaxis = secMap->GetVertexAxis();
524 std::cout << " Eta ranges:\n"
525 << " Vertex | Eta bins\n"
527 << " ----------------+-----------" << std::endl;
528 for (Int_t v = 1; v <= vaxis.GetNbins(); v++) {
529 std::cout << " " << std::setw(2) << v << " "
530 << std::setw(5) << vaxis.GetBinLowEdge(v) << "-"
531 << std::setw(5) << vaxis.GetBinUpEdge(v) << " | "
532 << std::setw(3) << fEtaMin[v-1] << "-"
533 << std::setw(3) << fEtaMax[v-1] << std::endl;
537 gROOT->IncreaseDirLevel();
538 fManager.Print(option);
539 fInspector.Print(option);
540 gROOT->DecreaseDirLevel();
543 //====================================================================
544 AliCentralMultiplicityTask::Manager::Manager() :
545 fAcceptancePath("$ALICE_ROOT/PWGLF/FORWARD/corrections/CentralAcceptance"),
546 fSecMapPath("$ALICE_ROOT/PWGLF/FORWARD/corrections/CentralSecMap"),
549 fAcceptanceName("centralacceptance"),
550 fSecMapName("centralsecmap"),
557 //____________________________________________________________________
558 AliCentralMultiplicityTask::Manager::Manager(const Manager& o)
559 :fAcceptancePath(o.fAcceptancePath),
560 fSecMapPath(o.fSecMapPath),
561 fAcceptance(o.fAcceptance),
563 fAcceptanceName(o.fAcceptanceName),
564 fSecMapName(o.fSecMapName),
571 //____________________________________________________________________
572 AliCentralMultiplicityTask::Manager&
573 AliCentralMultiplicityTask::Manager::operator=(const Manager& o)
576 // Assignment operator
578 if (&o == this) return *this;
579 fAcceptancePath = o.fAcceptancePath;
580 fSecMapPath = o.fSecMapPath;
581 fAcceptance = o.fAcceptance;
583 fAcceptanceName = o.fAcceptanceName;
584 fSecMapName = o.fSecMapName;
589 //____________________________________________________________________
591 AliCentralMultiplicityTask::Manager::GetFullFileName(UShort_t what,
597 // Get full path name to object file
601 // sys Collision system
602 // sNN Center of mass energy
603 // field Magnetic field
609 what == 0 ? GetSecMapPath() : GetAcceptancePath(),
610 GetFileName(what, sys, sNN, field));
613 //____________________________________________________________________
615 AliCentralMultiplicityTask::Manager::GetFileName(UShort_t what ,
621 // Get the full path name
625 // sys Collision system
626 // sNN Center of mass energy
627 // field Magnetic field
632 // Must be static - otherwise the data may disappear on return from
633 // this member function
634 static TString fname = "";
637 case 0: fname = fSecMapName; break;
638 case 1: fname = fAcceptanceName; break;
640 ::Error("GetFileName",
641 "Invalid indentifier %d for central object, must be 0 or 1!", what);
644 fname.Append(Form("_%s_%04dGeV_%c%1dkG.root",
645 AliForwardUtil::CollisionSystemString(sys),
646 sNN, (field < 0 ? 'm' : 'p'), TMath::Abs(field)));
651 //____________________________________________________________________
653 AliCentralMultiplicityTask::Manager::GetSecMapCorrection(UShort_t vtxbin) const
656 // Get the secondary map
665 ::Warning("GetSecMapCorrection","No secondary map defined");
668 return fSecmap->GetCorrection(vtxbin);
670 //____________________________________________________________________
672 AliCentralMultiplicityTask::Manager::GetAcceptanceCorrection(UShort_t vtxbin)
676 // Get the acceptance correction
685 ::Warning("GetAcceptanceCorrection","No acceptance map defined");
688 return fAcceptance->GetCorrection(vtxbin);
691 //____________________________________________________________________
693 AliCentralMultiplicityTask::Manager::Init(UShort_t sys,
701 // sys Collision system (1: pp, 2: PbPb, 3: pPb)
702 // sNN Center of mass energy per nucleon pair [GeV]
703 // field Magnetic field [kG]
705 if(fIsInit) ::Warning("Init","Already initialised - overriding...");
707 TFile fsec(GetFullFileName(0,sys,sNN,field));
709 dynamic_cast<AliCentralCorrSecondaryMap*>(fsec.Get(fSecMapName.Data()));
711 ::Error("Init", "no central Secondary Map found!") ;
714 TFile facc(GetFullFileName(1,sys,sNN,field));
716 dynamic_cast<AliCentralCorrAcceptance*>(facc.Get(fAcceptanceName.Data()));
718 ::Error("Init", "no central Acceptance found!") ;
722 if(fSecmap && fAcceptance) {
725 "Central Manager initialised for %s, energy %dGeV, field %dkG",
726 sys == 1 ? "pp" : sys == 2 ? "PbPb" : sys == 3 ? "pPb" : "unknown", sNN,field);
729 //____________________________________________________________________
731 AliCentralMultiplicityTask::Manager::WriteFile(UShort_t what,
739 // Write correction output to (a temporary) file
742 // What What to write
743 // sys Collision system (1: pp, 2: PbPb, 3: pPb)
744 // sNN Center of mass energy per nucleon (GeV)
746 // obj Object to write
747 // full if true, write to full path, otherwise locally
753 ofName = GetFileName(what, sys, sNN, fld);
755 ofName = GetFullFileName(what, sys, sNN, fld);
756 if (ofName.IsNull()) {
757 AliErrorGeneral("Manager",Form("Unknown object type %d", what));
760 TFile* output = TFile::Open(ofName, "RECREATE");
762 AliErrorGeneral("Manager",Form("Failed to open file %s", ofName.Data()));
766 TString oName(GetObjectName(what));
767 Int_t ret = obj->Write(oName);
769 AliErrorGeneral("Manager",Form("Failed to write %p to %s/%s (%d)",
770 obj, ofName.Data(), oName.Data(), ret));
774 ret = output->Write();
776 AliErrorGeneral("Manager",
777 Form("Failed to write %s to disk (%d)", ofName.Data(),ret));
783 TString cName(obj->IsA()->GetName());
784 AliInfoGeneral("Manager",
785 Form("Wrote %s object %s to %s\n",
786 cName.Data(),oName.Data(), ofName.Data()));
788 TString dName(GetFileDir(what));
789 AliInfoGeneral("Manager",
790 Form("%s should be copied to %s\n"
792 "aliroot $ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/"
793 "MoveCorrections.C\\(%d\\)\nor\n\t"
795 ofName.Data(),dName.Data(),
797 gSystem->ExpandPathName(dName.Data())));
804 //____________________________________________________________________
806 AliCentralMultiplicityTask::Manager::Print(Option_t* option) const
809 // Print information to standard output
811 std::cout << " AliCentralMultiplicityTask::Manager\n"
813 << " Initialized: " << fIsInit << '\n'
814 << " Acceptance path: " << fAcceptancePath << '\n'
815 << " Acceptance name: " << fAcceptanceName << '\n'
816 << " Acceptance: " << fAcceptance << '\n'
817 << " Secondary path: " << fSecMapPath << '\n'
818 << " Secondary name: " << fSecMapName << '\n'
819 << " Secondary map: " << fSecmap
820 << std::noboolalpha << std::endl;
821 if (fAcceptance) fAcceptance->Print(option);
822 if (fSecmap) fSecmap->Print(option);