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 "AliAnalysisManager.h"
33 #include "AliMCEventHandler.h"
34 #include "AliHeader.h"
37 #include <TParticle.h>
39 #include <TParameter.h>
41 //====================================================================
42 AliFMDMCEventInspector::AliFMDMCEventInspector()
43 : AliFMDEventInspector(),
60 //____________________________________________________________________
61 AliFMDMCEventInspector::AliFMDMCEventInspector(const char* /* name */)
62 : AliFMDEventInspector("fmdEventInspector"),
78 // name Name of object
82 //____________________________________________________________________
83 AliFMDMCEventInspector::AliFMDMCEventInspector(const AliFMDMCEventInspector& o)
84 : AliFMDEventInspector(o),
100 // o Object to copy from
104 //____________________________________________________________________
105 AliFMDMCEventInspector::~AliFMDMCEventInspector()
111 //____________________________________________________________________
112 AliFMDMCEventInspector&
113 AliFMDMCEventInspector::operator=(const AliFMDMCEventInspector& o)
116 // Assignement operator
119 // o Object to assign from
122 // Reference to this object
124 AliFMDEventInspector::operator=(o);
128 //____________________________________________________________________
130 AliFMDMCEventInspector::Init(const TAxis& vtxAxis)
133 // Initialize the object
136 // vtxAxis Vertex axis in use
138 AliFMDEventInspector::Init(vtxAxis);
143 Int_t nVtx = vtxAxis.GetNbins();
144 Double_t lVtx = vtxAxis.GetXmin();
145 Double_t hVtx = vtxAxis.GetXmax();
146 fHVertex = new TH1F("vertex", "True vertex distribution", nVtx, lVtx, hVtx);
147 fHVertex->SetXTitle("v_{z} [cm]");
148 fHVertex->SetYTitle("# of events");
149 fHVertex->SetFillColor(kGreen+1);
150 fHVertex->SetFillStyle(3001);
151 fHVertex->SetDirectory(0);
152 // fHVertex->Sumw2();
153 fList->Add(fHVertex);
155 fHPhiR = new TH1F("phiR", "Event plane", 120, 0, 2*TMath::Pi());
156 fHPhiR->SetXTitle("#Phi_{R} [radians]");
157 fHPhiR->SetYTitle("# of events");
158 fHPhiR->SetFillColor(kGreen+1);
159 fHPhiR->SetFillStyle(3001);
160 fHPhiR->SetDirectory(0);
163 fHB = new TH1F("b", "Impact parameter", 5*maxB, 0, maxB);
164 fHB->SetXTitle("b [fm]");
165 fHB->SetYTitle("# of events");
166 fHB->SetFillColor(kGreen+1);
167 fHB->SetFillStyle(3001);
168 fHB->SetDirectory(0);
171 fHBvsPart = new TH2F("bVsParticipants", "Impact parameter vs Participants",
172 5*maxB, 0, maxB, maxPart, -.5, maxPart-.5);
173 fHBvsPart->SetXTitle("b [fm]");
174 fHBvsPart->SetYTitle("# of participants");
175 fHBvsPart->SetZTitle("Events");
176 fHBvsPart->SetDirectory(0);
177 fList->Add(fHBvsPart);
179 fHBvsBin = new TH2F("bVsBinary", "Impact parameter vs Binary Collisions",
180 5*maxB, 0, maxB, maxBin, -.5, maxBin-.5);
181 fHBvsBin->SetXTitle("b [fm]");
182 fHBvsBin->SetYTitle("# of binary collisions");
183 fHBvsBin->SetZTitle("Events");
184 fHBvsBin->SetDirectory(0);
185 fList->Add(fHBvsBin);
187 fHBvsCent = new TH2F("bVsCentrality", "Impact parameter vs Centrality",
188 5*maxB, 0, maxB, fCentAxis->GetNbins(),
189 fCentAxis->GetXbins()->GetArray());
190 fHBvsCent->SetXTitle("b [fm]");
191 fHBvsCent->SetYTitle("Centrality [%]");
192 fHBvsCent->SetZTitle("Event");
193 fHBvsCent->SetDirectory(0);
194 fList->Add(fHBvsCent);
197 fHVzComp = new TH2F("vzComparison", "v_{z} truth vs reconstructed",
198 10*nVtx, lVtx, hVtx, 10*nVtx, lVtx, hVtx);
199 fHVzComp->SetXTitle("True v_{z} [cm]");
200 fHVzComp->SetYTitle("Reconstructed v_{z} [cm]");
201 fHVzComp->SetZTitle("Events");
202 fHVzComp->SetDirectory(0);
203 fList->Add(fHVzComp);
205 fHCentVsPart = new TH2F("centralityVsParticipans",
206 "# of participants vs Centrality",
207 maxPart, -.5, maxPart-.5, fCentAxis->GetNbins(),
208 fCentAxis->GetXbins()->GetArray());
209 fHCentVsPart->SetXTitle("Participants");
210 fHCentVsPart->SetYTitle("Centrality [%]");
211 fHCentVsPart->SetZTitle("Event");
212 fHCentVsPart->SetDirectory(0);
213 fList->Add(fHCentVsPart);
215 fHCentVsBin = new TH2F("centralityVsBinary",
216 "# of binary collisions vs Centrality",
217 maxBin, -.5, maxBin-.5, fCentAxis->GetNbins(),
218 fCentAxis->GetXbins()->GetArray());
219 fHCentVsBin->SetXTitle("Binary collisions");
220 fHCentVsBin->SetYTitle("Centrality [%]");
221 fHCentVsBin->SetZTitle("Event");
222 fHCentVsBin->SetDirectory(0);
223 fList->Add(fHCentVsBin);
226 //____________________________________________________________________
228 AliFMDMCEventInspector::StoreInformation(Int_t runNo)
230 // Store information about running conditions in the output list
232 AliFMDEventInspector::StoreInformation(runNo);
233 TParameter<bool>* mc = new TParameter<bool>("mc",true); // , fProduction.Data());
240 TString& AppendField(TString& s, bool test, const char* f)
243 if (!s.IsNull()) s.Append(",");
249 //____________________________________________________________________
251 AliFMDMCEventInspector::ReadProductionDetails(AliMCEvent* 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 AppendField(fProduction, colGeometry, "Geometry");
274 AppendField(fProduction, pythiaHeader, "Pythia");
275 AppendField(fProduction, dpmHeader, "DPM");
276 AppendField(fProduction, gevHeader, "GevSim");
277 AppendField(fProduction, herwigHeader, "Herwig");
278 AppendField(fProduction, hijingHeader, "Hijing");
279 // AppendField(fProduction, hydjetHeader, "Hydjet");
280 AppendField(fProduction, eposHeader, "EPOS");
283 //____________________________________________________________________
285 AliFMDMCEventInspector::ProcessMC(AliMCEvent* event,
300 // triggers On return, the triggers fired
301 // ivz On return, the found vertex bin (1-based). A zero
302 // means outside of the defined vertex range
303 // vz On return, the z position of the interaction
304 // b On return, the impact parameter - < 0 if not available
305 // c On return, centrality estimate - < 0 if not available
306 // phiR On return, the event plane angle - < 0 if not available
309 // 0 (or kOk) on success, otherwise a bit mask of error codes
312 // Check that we have an event
314 AliWarning("No MC event found for input event");
318 //Assign MC only triggers : True NSD etc.
319 AliHeader* header = event->Header();
320 AliGenEventHeader* genHeader = header->GenEventHeader();
321 AliCollisionGeometry* colGeometry =
322 dynamic_cast<AliCollisionGeometry*>(genHeader);
323 AliGenPythiaEventHeader* pythiaHeader =
324 dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
325 AliGenDPMjetEventHeader* dpmHeader =
326 dynamic_cast<AliGenDPMjetEventHeader*>(genHeader);
327 AliGenGeVSimEventHeader* gevHeader =
328 dynamic_cast<AliGenGeVSimEventHeader*>(genHeader);
329 AliGenHerwigEventHeader* herwigHeader =
330 dynamic_cast<AliGenHerwigEventHeader*>(genHeader);
331 // AliGenHijingEventHeader* hijingHeader =
332 // dynamic_cast<AliGenHijingEventHeader*>(genHeader);
333 // AliGenHydjetEventHeader* hydjetHeader =
334 // dynamic_cast<AliGenHydjetEventHeader*>(genHeader);
335 // AliGenEposEventHeader* eposHeader =
336 // dynamic_cast<AliGenEposEventHeader*>(genHeader);
338 // Check if this is a single diffractive event
340 Double_t phi = -1111;
347 b = colGeometry->ImpactParameter();
348 phi = colGeometry->ReactionPlaneAngle();
349 npart = (colGeometry->ProjectileParticipants() +
350 colGeometry->TargetParticipants());
351 nbin = colGeometry->NN();
353 if (fDebug && !colGeometry) {
354 AliWarningF("Collision header of class %s is not a CollisionHeader",
355 genHeader->ClassName());
359 Int_t pythiaType = pythiaHeader->ProcessType();
362 if (pythiaType==92 || pythiaType==93) sd = kTRUE;
363 b = pythiaHeader->GetImpactParameter();
364 npart = 2; // Always 2 protons
365 nbin = 1; // Always 1 binary collision
368 if (b < 3.5) c = 2.5; //0-5%
369 else if (b < 4.95) c = 7.5; //5-10%
370 else if (b < 6.98) c = 15; //10-20%
371 else if (b < 8.55) c = 25; //20-30%
372 else if (b < 9.88) c = 35; //30-40%
373 else if (b < 11.04) c = 45; //40-50%
374 else c = 55; //50-60%
376 if(dpmHeader) { // Also an AliCollisionGeometry
377 Int_t processType = dpmHeader->ProcessType();
381 if (processType == 5 || processType == 6) sd = kTRUE;
384 phi = gevHeader->GetEventPlane();
387 Int_t processType = herwigHeader->ProcessType();
389 if (processType == 5 || processType == 6) sd = kTRUE;
390 npart = 2; // Always 2 protons
391 nbin = 1; // Always 1 binary collision
393 // if (hijingHeader) {
394 // b = hijingHeader->ImpactParameter();
395 // phi = hijingHeader->ReactionPlaneAngle();
397 // if (hydjetHeader) {
398 // b = hydjetHeader->ImpactParameter();
399 // phi = hydjetHeader->ReactionPlaneAngle();
402 // b = eposHeader->ImpactParameter();
403 // phi = eposHeader->ReactionPlaneAngle();
406 // Normalize event plane angle to [0,2pi]
407 if (phi <= -1111) phiR = -1;
410 if (phi < 0) phi += 2*TMath::Pi();
411 else if (phi > 2*TMath::Pi()) phi -= 2*TMath::Pi();
417 // Do a check on particles
418 sd = IsSingleDiffractive(event->Stack());
422 triggers |= AliAODForwardMult::kMCNSD;
423 fHTriggers->Fill(kMCNSD+0.5);
426 // Get the primary vertex from EG
428 genHeader->PrimaryVertex(vtx);
431 DMSG(fDebug, 2, "vz=%f, phiR=%f, b=%f, npart=%d, nbin=%d",
432 vz, phiR, b, npart, nbin);
437 fHBvsPart->Fill(b, npart);
438 fHBvsBin->Fill(b, nbin);
440 if(fUseDisplacedVertices) {
441 // Put the vertex at fixed locations
443 Double_t ratio = zvtx/37.5;
444 if(ratio > 0) ratio = ratio + 0.5;
445 if(ratio < 0) ratio = ratio - 0.5;
446 Int_t ratioInt = Int_t(ratio);
447 zvtx = 37.5*((Double_t)ratioInt);
448 if(TMath::Abs(zvtx) > 999)
452 // Check for the vertex bin
453 ivz = fVtxAxis.FindBin(vz);
454 if (ivz <= 0 || ivz > fHEventsTr->GetXaxis()->GetNbins()) {
456 AliWarning(Form("Vertex @ %f outside of range [%f,%f]",
457 vz, fVtxAxis.GetXmin(), fVtxAxis.GetXmax())); }
466 //____________________________________________________________________
468 Double_t rapidity(TParticle* p, Double_t mass)
470 Double_t pt = p->Pt();
471 Double_t pz = p->Pz();
472 Double_t ee = TMath::Sqrt(pt*pt+pz*pz+mass*mass);
473 if (TMath::Abs(ee - TMath::Abs(pz)) < 1e-9) return TMath::Sign(1e30, pz);
474 return .5 * TMath::Log((ee + pz) / (ee - pz));
478 //____________________________________________________________________
480 AliFMDMCEventInspector::IsSingleDiffractive(AliStack* stack,
482 Double_t xiMax) const
484 // Re-implementation of AliPWG0Helper::IsHadronLevelSingleDiffrative
486 // This is re-implemented here to be indendent of the PWG0 library.
487 TParticle* p1 = 0; // Particle with least y
488 TParticle* p2 = 0; // Particle with largest y
489 Double_t y1 = 1e10; // y of p1
490 Double_t y2 = -1e10; // y of p2
492 // Loop over primaries
493 for (Int_t i = 0; i < stack->GetNprimary(); i++) {
494 TParticle* p = stack->Particle(i);
497 Int_t pdg = TMath::Abs(p->GetPdgCode());
498 Int_t c1 = p->GetFirstDaughter();
499 Int_t s = p->GetStatusCode();
500 Int_t mfl = Int_t(pdg/TMath::Power(10,Int_t(TMath::Log10(pdg))));
502 // Select final state charm and beauty
503 if (c1 > -1 || s != 1) mfl = 0;
505 // Check if this is a primary, pi0, Sigma0, ???, or most
506 // significant digit is larger than or equal to 4
507 if (!(stack->IsPhysicalPrimary(i) ||
513 Int_t m1 = p->GetFirstMother();
515 TParticle* pm1 = stack->Particle(m1);
516 Int_t mpdg = TMath::Abs(pm1->GetPdgCode());
517 // Check if mother is a p0, Simga0, or ???
518 if (mpdg == 111 || mpdg == 3124 || mpdg == 3212) continue;
521 // Calculate the rapidity of the particle
522 Double_t mm = (pdg != 3124 ? p->GetMass() : 1.5195);
523 Double_t yy = rapidity(p, mm);
525 // Check if the rapidity of this particle is further out than any
526 // of the preceding particles
536 if (!p1 || !p2) return false;
538 // Calculate rapidities assuming protons
539 y1 = TMath::Abs(rapidity(p1, 0.938));
540 y2 = TMath::Abs(rapidity(p2, 0.938));
542 // Check if both or just one is a proton
543 Int_t pdg1 = p1->GetPdgCode();
544 Int_t pdg2 = p2->GetPdgCode();
546 if (pdg1 == 2212 && pdg2 == 2212)
547 arm = (y1 > y2 ? 0 : 1);
548 else if (pdg1 == 2212)
550 else if (pdg2 == 2212)
556 Double_t m02s = (fEnergy > 0 ? 1 - 2 * p1->Energy() / fEnergy : 0);
557 Double_t m12s = (fEnergy > 0 ? 1 - 2 * p2->Energy() / fEnergy : 0);
559 if (arm == 0 && m02s > xiMin && m02s < xiMax) return true;
560 if (arm == 1 && m12s > xiMin && m12s < xiMax) return true;
565 //____________________________________________________________________
567 AliFMDMCEventInspector::CompareResults(Double_t vz, Double_t trueVz,
568 Double_t cent, Double_t b,
569 Int_t npart, Int_t nbin)
571 fHVzComp->Fill(trueVz, vz);
572 fHBvsCent->Fill(b, cent);
573 fHCentVsPart->Fill(npart, cent);
574 fHCentVsBin->Fill(nbin, cent);