2 // This class inspects the event
5 // - AliESDFMD object possibly corrected for sharing
8 // - A histogram of v_z of events with triggers.
9 // - A histogram of v_z of events with vertex and triggers
10 // - A histogram of trigger counters
12 // Note, that these are added to the master output list
17 #include "AliFMDMCEventInspector.h"
19 #include "AliAODForwardMult.h"
20 #include "AliForwardUtil.h"
21 #include "AliCentrality.h"
22 #include "AliESDEvent.h"
23 #include "AliMCEvent.h"
25 #include "AliGenPythiaEventHeader.h"
26 #include "AliGenDPMjetEventHeader.h"
27 #include "AliGenHijingEventHeader.h"
28 // #include "AliGenHydjetEventHeader.h"
29 #include "AliGenEposEventHeader.h"
30 #include "AliGenHerwigEventHeader.h"
31 #include "AliGenGeVSimEventHeader.h"
32 #include "AliHeader.h"
35 #include <TParticle.h>
38 //====================================================================
39 AliFMDMCEventInspector::AliFMDMCEventInspector()
40 : AliFMDEventInspector(),
56 //____________________________________________________________________
57 AliFMDMCEventInspector::AliFMDMCEventInspector(const char* /* name */)
58 : AliFMDEventInspector("fmdEventInspector"),
73 // name Name of object
77 //____________________________________________________________________
78 AliFMDMCEventInspector::AliFMDMCEventInspector(const AliFMDMCEventInspector& o)
79 : AliFMDEventInspector(o),
94 // o Object to copy from
98 //____________________________________________________________________
99 AliFMDMCEventInspector::~AliFMDMCEventInspector()
105 //____________________________________________________________________
106 AliFMDMCEventInspector&
107 AliFMDMCEventInspector::operator=(const AliFMDMCEventInspector& o)
110 // Assignement operator
113 // o Object to assign from
116 // Reference to this object
118 AliFMDEventInspector::operator=(o);
122 //____________________________________________________________________
124 AliFMDMCEventInspector::Init(const TAxis& vtxAxis)
127 // Initialize the object
130 // vtxAxis Vertex axis in use
132 AliFMDEventInspector::Init(vtxAxis);
137 Int_t nVtx = vtxAxis.GetNbins();
138 Double_t lVtx = vtxAxis.GetXmin();
139 Double_t hVtx = vtxAxis.GetXmax();
140 fHVertex = new TH1F("vertex", "True vertex distribution", nVtx, lVtx, hVtx);
141 fHVertex->SetXTitle("v_{z} [cm]");
142 fHVertex->SetYTitle("# of events");
143 fHVertex->SetFillColor(kGreen+1);
144 fHVertex->SetFillStyle(3001);
145 fHVertex->SetDirectory(0);
146 // fHVertex->Sumw2();
147 fList->Add(fHVertex);
149 fHPhiR = new TH1F("phiR", "Event plane", 120, 0, 2*TMath::Pi());
150 fHPhiR->SetXTitle("#Phi_{R} [radians]");
151 fHPhiR->SetYTitle("# of events");
152 fHPhiR->SetFillColor(kGreen+1);
153 fHPhiR->SetFillStyle(3001);
154 fHPhiR->SetDirectory(0);
157 fHB = new TH1F("b", "Impact parameter", 5*maxB, 0, maxB);
158 fHB->SetXTitle("b [fm]");
159 fHB->SetYTitle("# of events");
160 fHB->SetFillColor(kGreen+1);
161 fHB->SetFillStyle(3001);
162 fHB->SetDirectory(0);
165 fHBvsPart = new TH2F("bVsParticipants", "Impact parameter vs Participants",
166 5*maxB, 0, maxB, maxPart, -.5, maxPart-.5);
167 fHBvsPart->SetXTitle("b [fm]");
168 fHBvsPart->SetYTitle("# of participants");
169 fHBvsPart->SetZTitle("Events");
170 fHBvsPart->SetDirectory(0);
171 fList->Add(fHBvsPart);
173 fHBvsBin = new TH2F("bVsBinary", "Impact parameter vs Binary Collisions",
174 5*maxB, 0, maxB, maxBin, -.5, maxBin-.5);
175 fHBvsBin->SetXTitle("b [fm]");
176 fHBvsBin->SetYTitle("# of binary collisions");
177 fHBvsBin->SetZTitle("Events");
178 fHBvsBin->SetDirectory(0);
179 fList->Add(fHBvsBin);
181 fHBvsCent = new TH2F("bVsCentrality", "Impact parameter vs Centrality",
182 5*maxB, 0, maxB, fCentAxis->GetNbins(),
183 fCentAxis->GetXbins()->GetArray());
184 fHBvsCent->SetXTitle("b [fm]");
185 fHBvsCent->SetYTitle("Centrality [%]");
186 fHBvsCent->SetZTitle("Event");
187 fHBvsCent->SetDirectory(0);
188 fList->Add(fHBvsCent);
191 fHVzComp = new TH2F("vzComparison", "v_{z} truth vs reconstructed",
192 10*nVtx, lVtx, hVtx, 10*nVtx, lVtx, hVtx);
193 fHVzComp->SetXTitle("True v_{z} [cm]");
194 fHVzComp->SetYTitle("Reconstructed v_{z} [cm]");
195 fHVzComp->SetZTitle("Events");
196 fHVzComp->SetDirectory(0);
197 fList->Add(fHVzComp);
199 fHCentVsPart = new TH2F("centralityVsParticipans",
200 "# of participants vs Centrality",
201 maxPart, -.5, maxPart-.5, fCentAxis->GetNbins(),
202 fCentAxis->GetXbins()->GetArray());
203 fHCentVsPart->SetXTitle("Participants");
204 fHCentVsPart->SetYTitle("Centrality [%]");
205 fHCentVsPart->SetZTitle("Event");
206 fHCentVsPart->SetDirectory(0);
207 fList->Add(fHCentVsPart);
209 fHCentVsBin = new TH2F("centralityVsBinary",
210 "# of binary collisions vs Centrality",
211 maxBin, -.5, maxBin-.5, fCentAxis->GetNbins(),
212 fCentAxis->GetXbins()->GetArray());
213 fHCentVsBin->SetXTitle("Binary collisions");
214 fHCentVsBin->SetYTitle("Centrality [%]");
215 fHCentVsBin->SetZTitle("Event");
216 fHCentVsBin->SetDirectory(0);
217 fList->Add(fHCentVsBin);
220 //____________________________________________________________________
222 AliFMDMCEventInspector::ProcessMC(AliMCEvent* event,
236 // triggers On return, the triggers fired
237 // ivz On return, the found vertex bin (1-based). A zero
238 // means outside of the defined vertex range
239 // vz On return, the z position of the interaction
240 // b On return, the impact parameter - < 0 if not available
241 // phiR On return, the event plane angle - < 0 if not available
244 // 0 (or kOk) on success, otherwise a bit mask of error codes
247 // Check that we have an event
249 AliWarning("No MC event found for input event");
253 //Assign MC only triggers : True NSD etc.
254 AliHeader* header = event->Header();
255 AliGenEventHeader* genHeader = header->GenEventHeader();
256 AliCollisionGeometry* colGeometry =
257 dynamic_cast<AliCollisionGeometry*>(genHeader);
258 AliGenPythiaEventHeader* pythiaHeader =
259 dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
260 AliGenDPMjetEventHeader* dpmHeader =
261 dynamic_cast<AliGenDPMjetEventHeader*>(genHeader);
262 AliGenGeVSimEventHeader* gevHeader =
263 dynamic_cast<AliGenGeVSimEventHeader*>(genHeader);
264 AliGenHerwigEventHeader* herwigHeader =
265 dynamic_cast<AliGenHerwigEventHeader*>(genHeader);
266 // AliGenHijingEventHeader* hijingHeader =
267 // dynamic_cast<AliGenHijingEventHeader*>(genHeader);
268 // AliGenHydjetEventHeader* hydjetHeader =
269 // dynamic_cast<AliGenHydjetEventHeader*>(genHeader);
270 // AliGenEposEventHeader* eposHeader =
271 // dynamic_cast<AliGenEposEventHeader*>(genHeader);
273 // Check if this is a single diffractive event
275 Double_t phi = -1111;
280 b = colGeometry->ImpactParameter();
281 phi = colGeometry->ReactionPlaneAngle();
282 npart = (colGeometry->ProjectileParticipants() +
283 colGeometry->TargetParticipants());
284 nbin = colGeometry->NN();
287 Int_t pythiaType = pythiaHeader->ProcessType();
290 if (pythiaType==92 || pythiaType==93) sd = kTRUE;
291 b = pythiaHeader->GetImpactParameter();
292 npart = 2; // Always 2 protons
293 nbin = 1; // Always 1 binary collision
295 if(dpmHeader) { // Also an AliCollisionGeometry
296 Int_t processType = dpmHeader->ProcessType();
300 if (processType == 5 || processType == 6) sd = kTRUE;
303 phi = gevHeader->GetEventPlane();
306 Int_t processType = herwigHeader->ProcessType();
308 if (processType == 5 || processType == 6) sd = kTRUE;
309 npart = 2; // Always 2 protons
310 nbin = 1; // Always 1 binary collision
312 // if (hijingHeader) {
313 // b = hijingHeader->ImpactParameter();
314 // phi = hijingHeader->ReactionPlaneAngle();
316 // if (hydjetHeader) {
317 // b = hydjetHeader->ImpactParameter();
318 // phi = hydjetHeader->ReactionPlaneAngle();
321 // b = eposHeader->ImpactParameter();
322 // phi = eposHeader->ReactionPlaneAngle();
325 // Normalize event plane angle to [0,2pi]
326 if (phi <= -1111) phiR = -1;
329 if (phi < 0) phi += 2*TMath::Pi();
330 else if (phi > 2*TMath::Pi()) phi -= 2*TMath::Pi();
335 // Do a check on particles
336 sd = IsSingleDiffractive(event->Stack());
340 triggers |= AliAODForwardMult::kMCNSD;
341 fHTriggers->Fill(kMCNSD+0.5);
344 // Get the primary vertex from EG
346 genHeader->PrimaryVertex(vtx);
352 fHBvsPart->Fill(b, npart);
353 fHBvsBin->Fill(b, nbin);
355 // Check for the vertex bin
356 ivz = fHEventsTr->GetXaxis()->FindBin(vz);
357 if (ivz <= 0 || ivz > fHEventsTr->GetXaxis()->GetNbins()) {
359 AliWarning(Form("Vertex @ %f outside of range [%f,%f]",
360 vz, fHEventsTr->GetXaxis()->GetXmin(),
361 fHEventsTr->GetXaxis()->GetXmax())); }
370 //____________________________________________________________________
372 Double_t rapidity(TParticle* p, Double_t mass)
374 Double_t pt = p->Pt();
375 Double_t pz = p->Pz();
376 Double_t ee = TMath::Sqrt(pt*pt+pz*pz+mass*mass);
377 if (TMath::Abs(ee - TMath::Abs(pz)) < 1e-9) return TMath::Sign(1e30, pz);
378 return .5 * TMath::Log((ee + pz) / (ee - pz));
382 //____________________________________________________________________
384 AliFMDMCEventInspector::IsSingleDiffractive(AliStack* stack,
386 Double_t xiMax) const
388 // Re-implementation of AliPWG0Helper::IsHadronLevelSingleDiffrative
390 // This is re-implemented here to be indendent of the PWG0 library.
391 TParticle* p1 = 0; // Particle with least y
392 TParticle* p2 = 0; // Particle with largest y
393 Double_t y1 = 1e10; // y of p1
394 Double_t y2 = -1e10; // y of p2
396 // Loop over primaries
397 for (Int_t i = 0; i < stack->GetNprimary(); i++) {
398 TParticle* p = stack->Particle(i);
401 Int_t pdg = TMath::Abs(p->GetPdgCode());
402 Int_t c1 = p->GetFirstDaughter();
403 Int_t s = p->GetStatusCode();
404 Int_t mfl = Int_t(pdg/TMath::Power(10,Int_t(TMath::Log10(pdg))));
406 // Select final state charm and beauty
407 if (c1 > -1 || s != 1) mfl = 0;
409 // Check if this is a primary, pi0, Sigma0, ???, or most
410 // significant digit is larger than or equal to 4
411 if (!(stack->IsPhysicalPrimary(i) ||
417 Int_t m1 = p->GetFirstMother();
419 TParticle* pm1 = stack->Particle(m1);
420 Int_t mpdg = TMath::Abs(pm1->GetPdgCode());
421 // Check if mother is a p0, Simga0, or ???
422 if (mpdg == 111 || mpdg == 3124 || mpdg == 3212) continue;
425 // Calculate the rapidity of the particle
426 Double_t mm = (pdg != 3124 ? p->GetMass() : 1.5195);
427 Double_t yy = rapidity(p, mm);
429 // Check if the rapidity of this particle is further out than any
430 // of the preceding particles
440 if (!p1 || !p2) return false;
442 // Calculate rapidities assuming protons
443 y1 = TMath::Abs(rapidity(p1, 0.938));
444 y2 = TMath::Abs(rapidity(p2, 0.938));
446 // Check if both or just one is a proton
447 Int_t pdg1 = p1->GetPdgCode();
448 Int_t pdg2 = p2->GetPdgCode();
450 if (pdg1 == 2212 && pdg2 == 2212)
451 arm = (y1 > y2 ? 0 : 1);
452 else if (pdg1 == 2212)
454 else if (pdg2 == 2212)
460 Double_t m02s = 1 - 2 * p1->Energy() / fEnergy;
461 Double_t m12s = 1 - 2 * p2->Energy() / fEnergy;
463 if (arm == 0 && m02s > xiMin && m02s < xiMax) return true;
464 if (arm == 1 && m12s > xiMin && m12s < xiMax) return true;
468 //____________________________________________________________________
470 AliFMDMCEventInspector::ReadCentrality(const AliESDEvent* esd,
472 UShort_t& qual) const
475 // Read centrality from event
479 // cent On return, the centrality or negative if not found
482 // False on error, true otherwise
486 AliCentrality* centObj = const_cast<AliESDEvent*>(esd)->GetCentrality();
487 if (!centObj) return true;
489 qual = centObj->GetQuality();
490 if (qual == 0x8) // Ignore ZDC outliers
491 cent = centObj->GetCentralityPercentileUnchecked("V0M");
493 cent = centObj->GetCentralityPercentile("V0M");
498 //____________________________________________________________________
500 AliFMDMCEventInspector::CompareResults(Double_t vz, Double_t trueVz,
501 Double_t cent, Double_t b,
502 Int_t npart, Int_t nbin)
504 fHVzComp->Fill(trueVz, vz);
505 fHBvsCent->Fill(b, cent);
506 fHCentVsPart->Fill(npart, cent);
507 fHCentVsBin->Fill(nbin, cent);