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 fInspector = o.fInspector;
113 fAODCentral = o.fAODCentral;
114 fManager = o.fManager;
115 fUseSecondary = o.fUseSecondary;
116 fUseAcceptance = o.fUseAcceptance;
117 fFirstEventSeen = o.fFirstEventSeen;
119 fNClusterTracklet = o.fNClusterTracklet;
120 fClusterPerTracklet= o.fClusterPerTracklet;
121 fNCluster = o.fNCluster;
122 fNTracklet = o.fNTracklet;
127 //____________________________________________________________________
128 void AliCentralMultiplicityTask::UserCreateOutputObjects()
131 // Create output objects
135 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
137 dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
138 if (!ah) AliFatal("No AOD output handler set in analysis manager");
141 TObject* obj = &fAODCentral;
142 ah->AddBranch("AliAODCentralMult", &obj);
149 fInspector.DefineOutput(fList);
154 //____________________________________________________________________
156 AliCentralMultiplicityTask::GetESDEvent()
159 // Get the ESD event. IF this is the first event, initialise
161 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
163 AliWarning("No ESD event found for input event");
167 // IF we've read the first event already, just return the event
168 if (fFirstEventSeen) return esd;
170 // Read the details of the rung
171 fInspector.ReadRunDetails(esd);
173 // If we weren't initialised before (i.e., in the setup), do so now.
174 if (!GetManager().IsInit()) {
175 GetManager().Init(fInspector.GetCollisionSystem(),
176 fInspector.GetEnergy(),
177 fInspector.GetField());
178 AliInfo("Manager of corrections in AliCentralMultiplicityTask init");
181 // Check for existence and get secondary map
182 AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
183 if (!secMap) AliFatal("No secondary map defined!");
184 const TAxis& vaxis = secMap->GetVertexAxis();
188 fNClusterTracklet = new TH2D("nClusterVsnTracklet",
189 "Total number of cluster vs number of tracklets",
190 100, 0, 100, 100, 0, 100);
191 fNClusterTracklet->SetDirectory(0);
192 fNClusterTracklet->SetXTitle("# of free clusters");
193 fNClusterTracklet->SetYTitle("# of tracklets");
194 fNClusterTracklet->SetStats(0);
195 fList->Add(fNClusterTracklet);
199 fClusterPerTracklet = new TH2D("clusterPerTracklet",
200 "N_{free cluster}/N_{tracklet} vs. #eta",
201 nEta,-lEta,lEta, 101, -.05, 10.05);
202 fClusterPerTracklet->SetDirectory(0);
203 fClusterPerTracklet->SetXTitle("#eta");
204 fClusterPerTracklet->SetYTitle("N_{free cluster}/N_{tracklet}");
205 fClusterPerTracklet->SetStats(0);
206 fList->Add(fClusterPerTracklet);
209 fNCluster = new TH1D("cacheCluster", "", nEta,-lEta,lEta);
210 fNCluster->SetDirectory(0);
213 fNTracklet = new TH1D("cacheTracklet", "", nEta,-lEta,lEta);
214 fNTracklet->SetDirectory(0);
217 // Initialize the inspecto
218 fInspector.Init(vaxis);
219 fFirstEventSeen = kTRUE;
221 // Print some information
226 //____________________________________________________________________
228 AliCentralMultiplicityTask::MarkEventForStore() const
230 // Make sure the AOD tree is filled
231 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
233 dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
235 AliFatal("No AOD output handler set in analysis manager");
237 ah->SetFillAOD(kTRUE);
240 //____________________________________________________________________
241 void AliCentralMultiplicityTask::FindEtaLimits()
243 AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
245 const TAxis& vaxis = secMap->GetVertexAxis();
247 fEtaMin.Set(vaxis.GetNbins());
248 fEtaMax.Set(vaxis.GetNbins());
250 TList* hits = new TList;
252 hits->SetName("hitMaps");
255 TList* secs = new TList;
257 secs->SetName("secondaryMaps");
259 TH2D* hCoverage = new TH2D("coverage", "#eta coverage per v_{z}",
260 secMap->GetCorrection(UShort_t(1))->GetXaxis()->GetNbins(),
261 secMap->GetCorrection(UShort_t(1))->GetXaxis()->GetXmin(),
262 secMap->GetCorrection(UShort_t(1))->GetXaxis()->GetXmax(),
263 vaxis.GetNbins(),vaxis.GetXmin(),vaxis.GetXmax());
264 hCoverage->SetDirectory(0);
265 hCoverage->SetXTitle("#eta");
266 hCoverage->SetYTitle("v_{z} [cm]");
267 hCoverage->SetZTitle("n_{bins}");
268 fList->Add(hCoverage);
270 for (Int_t v = 1; v <= vaxis.GetNbins(); v++) {
271 TH2D* corr = secMap->GetCorrection(UShort_t(v));
272 TH1D* proj = corr->ProjectionX(Form("secCor%02d", v));
273 proj->Scale(1. / corr->GetNbinsY());
274 proj->SetTitle(Form("Projection of secondary correction "
275 "for %+5.1f<v_{z}<%+5.1f",
276 vaxis.GetBinLowEdge(v), vaxis.GetBinUpEdge(v)));
277 proj->SetYTitle("#LT 2^{nd} correction#GT");
278 proj->SetDirectory(0);
279 proj->SetMarkerStyle(20);
280 proj->SetMarkerColor(kBlue+1);
283 TH2D* obg = static_cast<TH2D*>(corr->Clone(Form("secCor2DFiducial%02d",v)));
284 obg->SetDirectory(0);
287 TH1D* after = static_cast<TH1D*>(proj->Clone(Form("secCorFiducial%02d",v)));
288 after->SetDirectory(0);
289 after->SetMarkerColor(kRed+1);
292 TH2D* data = static_cast<TH2D*>(corr->Clone(Form("hitMap%02d",v)));
293 //d->SetTitle(Form("hitMap%02d",v));
294 data->SetTitle(Form("d^{2}N/d#eta d#phi "
295 "for %+5.1f<v_{z}<%+5.1f",
296 vaxis.GetBinLowEdge(v), vaxis.GetBinUpEdge(v)));
297 data->GetZaxis()->SetTitle("");
298 data->SetMarkerColor(kBlack);
299 data->SetMarkerStyle(1);
302 TH1D* hAcceptance = fManager.GetAcceptanceCorrection(v);
303 TH1D* accClone = static_cast<TH1D*>(hAcceptance->Clone(Form("acceptance%02d",v)));
307 for (Int_t e = 1; e <= proj->GetNbinsX(); e++) {
308 Double_t c = proj->GetBinContent(e);
309 if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
314 after->SetBinContent(e, 0);
315 after->SetBinError(e, 0);
316 for(Int_t nn =1; nn <=obg->GetNbinsY();nn++)
317 obg->SetBinContent(e,nn,0);
320 for (Int_t e = proj->GetNbinsX(); e >= 1; e--) {
321 Double_t c = proj->GetBinContent(e);
322 if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
327 after->SetBinContent(e, 0);
328 after->SetBinError(e, 0);
329 for(Int_t nn =1; nn <=obg->GetNbinsY();nn++)
330 obg->SetBinContent(e,nn,0);
334 for (Int_t nn = fEtaMin[v-1]; nn<=fEtaMax[v-1]; nn++) {
335 hCoverage->SetBinContent(nn,v,1);
341 //____________________________________________________________________
342 void AliCentralMultiplicityTask::UserExec(Option_t* /*option*/)
345 // Process each event
350 fAODCentral.Clear("");
353 AliESDEvent* esd = GetESDEvent();
355 Bool_t lowFlux = kFALSE;
360 UShort_t nClusters = 0;
361 UInt_t found = fInspector.Process(esd, triggers, lowFlux,
362 ivz, vz, cent, nClusters);
364 // No event or no trigger
365 if (found & AliFMDEventInspector::kNoEvent) return;
366 if (found & AliFMDEventInspector::kNoTriggers) return;
368 // Make sure AOD is filled
371 if (found == AliFMDEventInspector::kNoSPD) return;
372 if (found == AliFMDEventInspector::kNoVertex) return;
373 if (triggers & AliAODForwardMult::kPileUp) return;
374 if (found == AliFMDEventInspector::kBadVertex) return; // Out of range
378 const AliMultiplicity* spdmult = esd->GetMultiplicity();
380 TH2D& aodHist = fAODCentral.GetHistogram();
382 ProcessESD(aodHist, spdmult);
383 CorrectData(aodHist, ivz);
385 TList* hitList = static_cast<TList*>(fList->FindObject("hitMaps"));
388 data = static_cast<TH2D*>(hitList->At(ivz-1));
394 //____________________________________________________________________
396 AliCentralMultiplicityTask::ProcessESD(TH2D& aodHist,
397 const AliMultiplicity* spdmult) const
402 //Filling clusters in layer 1 used for tracklets...
403 for(Int_t j = 0; j< spdmult->GetNumberOfTracklets();j++) {
404 Double_t eta = spdmult->GetEta(j);
405 fNTracklet->Fill(eta);
406 aodHist.Fill(eta,spdmult->GetPhi(j));
409 //...and then the unused ones in layer 1
410 for(Int_t j = 0; j< spdmult->GetNumberOfSingleClusters();j++) {
411 Double_t eta = -TMath::Log(TMath::Tan(spdmult->GetThetaSingle(j)/2.));
412 fNCluster->Fill(eta);
413 aodHist.Fill(eta, spdmult->GetPhiSingle(j));
415 fNClusterTracklet->Fill(fNCluster->GetEntries(),
416 fNTracklet->GetEntries());
418 fNCluster->Divide(fNTracklet);
419 for (Int_t j = 1; j <= fNCluster->GetNbinsX(); j++)
420 fClusterPerTracklet->Fill(fNCluster->GetXaxis()->GetBinCenter(j),
421 fNCluster->GetBinContent(j));
425 //____________________________________________________________________
427 AliCentralMultiplicityTask::CorrectData(TH2D& aodHist, UShort_t vtxbin) const
430 TH1D* hAcceptance = fManager.GetAcceptanceCorrection(vtxbin);
431 TH2D* hSecMap = fManager.GetSecMapCorrection(vtxbin);
433 if (!hSecMap) AliFatal("No secondary map!");
434 if (!hAcceptance) AliFatal("No acceptance!");
436 if (fUseSecondary && hSecMap) aodHist.Divide(hSecMap);
438 for(Int_t nx = 1; nx <= aodHist.GetNbinsX(); nx++) {
439 Float_t accCor = hAcceptance->GetBinContent(nx);
440 Float_t accErr = hAcceptance->GetBinError(nx);
442 Bool_t fiducial = true;
443 if (nx < fEtaMin[vtxbin-1] || nx > fEtaMax[vtxbin-1])
445 // Bool_t etabinSeen = kFALSE;
446 for(Int_t ny = 1; ny <= aodHist.GetNbinsY(); ny++) {
449 aodHist.SetBinContent(nx, ny, 0);
450 aodHist.SetBinError(nx, ny, 0);
454 // Get currrent value
455 Float_t aodValue = aodHist.GetBinContent(nx,ny);
456 Float_t aodErr = aodHist.GetBinError(nx,ny);
458 #if 0 // This is done once in the FindEtaBins function
461 if(hSecMap) secCor = hSecMap->GetBinContent(nx,ny);
462 if (secCor > 0.5) etabinSeen = kTRUE;
464 if (aodValue < 0.000001) {
465 aodHist.SetBinContent(nx,ny, 0);
466 aodHist.SetBinError(nx,ny, 0);
469 if (!fUseAcceptance) continue;
471 // Acceptance correction
472 if (accCor < 0.000001) accCor = 1;
473 Float_t aodNew = aodValue / accCor ;
474 Float_t error = aodNew*TMath::Sqrt(TMath::Power(aodErr/aodValue,2) +
475 TMath::Power(accErr/accCor,2) );
476 aodHist.SetBinContent(nx,ny, aodNew);
478 aodHist.SetBinError(nx,ny,error);
479 aodHist.SetBinError(nx,ny,aodErr);
481 //Filling underflow bin if we eta bin is in range
482 if (fiducial) aodHist.SetBinContent(nx,0, 1.);
483 // if (etabinSeen) aodHist.SetBinContent(nx,0, 1.);
487 //____________________________________________________________________
488 void AliCentralMultiplicityTask::Terminate(Option_t* /*option*/)
497 //____________________________________________________________________
499 AliCentralMultiplicityTask::Print(Option_t* option) const
507 std::cout << ClassName() << ": " << GetName() << "\n"
509 << " Use secondary correction: " << fUseSecondary << '\n'
510 << " Use acceptance correction: " << fUseAcceptance << '\n'
511 << " Off-line trigger mask: 0x"
512 << std::hex << std::setfill('0')
513 << std::setw (8) << fOfflineTriggerMask
514 << std::dec << std::setfill (' ')
515 << std::noboolalpha << std::endl;
516 AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
518 const TAxis& vaxis = secMap->GetVertexAxis();
519 std::cout << " Eta ranges:\n"
520 << " Vertex | Eta bins\n"
522 << " ----------------+-----------" << std::endl;
523 for (Int_t v = 1; v <= vaxis.GetNbins(); v++) {
524 std::cout << " " << std::setw(2) << v << " "
525 << std::setw(5) << vaxis.GetBinLowEdge(v) << "-"
526 << std::setw(5) << vaxis.GetBinUpEdge(v) << " | "
527 << std::setw(3) << fEtaMin[v-1] << "-"
528 << std::setw(3) << fEtaMax[v-1] << std::endl;
532 gROOT->IncreaseDirLevel();
533 fManager.Print(option);
534 fInspector.Print(option);
535 gROOT->DecreaseDirLevel();
538 //====================================================================
539 AliCentralMultiplicityTask::Manager::Manager() :
540 fAcceptancePath("$ALICE_ROOT/PWG2/FORWARD/corrections/CentralAcceptance"),
541 fSecMapPath("$ALICE_ROOT/PWG2/FORWARD/corrections/CentralSecMap"),
544 fAcceptanceName("centralacceptance"),
545 fSecMapName("centralsecmap"),
552 //____________________________________________________________________
553 AliCentralMultiplicityTask::Manager::Manager(const Manager& o)
554 :fAcceptancePath(o.fAcceptancePath),
555 fSecMapPath(o.fSecMapPath),
556 fAcceptance(o.fAcceptance),
558 fAcceptanceName(o.fAcceptanceName),
559 fSecMapName(o.fSecMapName),
566 //____________________________________________________________________
567 AliCentralMultiplicityTask::Manager&
568 AliCentralMultiplicityTask::Manager::operator=(const Manager& o)
571 // Assignment operator
573 fAcceptancePath = o.fAcceptancePath;
574 fSecMapPath = o.fSecMapPath;
575 fAcceptance = o.fAcceptance;
577 fAcceptanceName = o.fAcceptanceName;
578 fSecMapName = o.fSecMapName;
583 //____________________________________________________________________
585 AliCentralMultiplicityTask::Manager::GetFullFileName(UShort_t what,
591 // Get full path name to object file
595 // sys Collision system
596 // sNN Center of mass energy
597 // field Magnetic field
603 what == 0 ? GetSecMapPath() : GetAcceptancePath(),
604 GetFileName(what, sys, sNN, field));
607 //____________________________________________________________________
609 AliCentralMultiplicityTask::Manager::GetFileName(UShort_t what ,
615 // Get the full path name
619 // sys Collision system
620 // sNN Center of mass energy
621 // field Magnetic field
626 // Must be static - otherwise the data may disappear on return from
627 // this member function
628 static TString fname = "";
631 case 0: fname = fSecMapName; break;
632 case 1: fname = fAcceptanceName; break;
634 ::Error("GetFileName",
635 "Invalid indentifier %d for central object, must be 0 or 1!", what);
638 fname.Append(Form("_%s_%04dGeV_%c%1dkG.root",
639 AliForwardUtil::CollisionSystemString(sys),
640 sNN, (field < 0 ? 'm' : 'p'), TMath::Abs(field)));
645 //____________________________________________________________________
647 AliCentralMultiplicityTask::Manager::GetSecMapCorrection(UShort_t vtxbin) const
650 // Get the secondary map
659 ::Warning("GetSecMapCorrection","No secondary map defined");
662 return fSecmap->GetCorrection(vtxbin);
664 //____________________________________________________________________
666 AliCentralMultiplicityTask::Manager::GetAcceptanceCorrection(UShort_t vtxbin)
670 // Get the acceptance correction
679 ::Warning("GetAcceptanceCorrection","No acceptance map defined");
682 return fAcceptance->GetCorrection(vtxbin);
685 //____________________________________________________________________
687 AliCentralMultiplicityTask::Manager::Init(UShort_t sys,
695 // sys Collision system (1: pp, 2: PbPb)
696 // sNN Center of mass energy per nucleon pair [GeV]
697 // field Magnetic field [kG]
699 if(fIsInit) ::Warning("Init","Already initialised - overriding...");
701 TFile fsec(GetFullFileName(0,sys,sNN,field));
703 dynamic_cast<AliCentralCorrSecondaryMap*>(fsec.Get(fSecMapName.Data()));
705 ::Error("Init", "no central Secondary Map found!") ;
708 TFile facc(GetFullFileName(1,sys,sNN,field));
710 dynamic_cast<AliCentralCorrAcceptance*>(facc.Get(fAcceptanceName.Data()));
712 ::Error("Init", "no central Acceptance found!") ;
716 if(fSecmap && fAcceptance) {
719 "Central Manager initialised for %s, energy %dGeV, field %dkG",
720 sys == 1 ? "pp" : sys == 2 ? "PbPb" : "unknown", sNN,field);
723 //____________________________________________________________________
725 AliCentralMultiplicityTask::Manager::WriteFile(UShort_t what,
733 // Write correction output to (a temporary) file
736 // What What to write
737 // sys Collision system (1: pp, 2: PbPb)
738 // sNN Center of mass energy per nucleon (GeV)
740 // obj Object to write
741 // full if true, write to full path, otherwise locally
747 ofName = GetFileName(what, sys, sNN, fld);
749 ofName = GetFullFileName(what, sys, sNN, fld);
750 if (ofName.IsNull()) {
751 AliErrorGeneral("Manager",Form("Unknown object type %d", what));
754 TFile* output = TFile::Open(ofName, "RECREATE");
756 AliErrorGeneral("Manager",Form("Failed to open file %s", ofName.Data()));
760 TString oName(GetObjectName(what));
761 Int_t ret = obj->Write(oName);
763 AliErrorGeneral("Manager",Form("Failed to write %p to %s/%s (%d)",
764 obj, ofName.Data(), oName.Data(), ret));
768 ret = output->Write();
770 AliErrorGeneral("Manager",
771 Form("Failed to write %s to disk (%d)", ofName.Data(),ret));
777 TString cName(obj->IsA()->GetName());
778 AliInfoGeneral("Manager",
779 Form("Wrote %s object %s to %s\n",
780 cName.Data(),oName.Data(), ofName.Data()));
782 TString dName(GetFileDir(what));
783 AliInfoGeneral("Manager",
784 Form("%s should be copied to %s\n"
786 "aliroot $ALICE_ROOT/PWG2/FORWARD/analysis2/scripts/"
787 "MoveCorrections.C\\(%d\\)\nor\n\t"
789 ofName.Data(),dName.Data(),
791 gSystem->ExpandPathName(dName.Data())));
798 //____________________________________________________________________
800 AliCentralMultiplicityTask::Manager::Print(Option_t* option) const
803 // Print information to standard output
805 std::cout << " AliCentralMultiplicityTask::Manager\n"
807 << " Initialized: " << fIsInit << '\n'
808 << " Acceptance path: " << fAcceptancePath << '\n'
809 << " Acceptance name: " << fAcceptanceName << '\n'
810 << " Acceptance: " << fAcceptance << '\n'
811 << " Secondary path: " << fSecMapPath << '\n'
812 << " Secondary name: " << fSecMapName << '\n'
813 << " Secondary map: " << fSecmap
814 << std::noboolalpha << std::endl;
815 if (fAcceptance) fAcceptance->Print(option);
816 if (fSecmap) fSecmap->Print(option);