]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG2/FORWARD/analysis2/AliFMDMCEventInspector.cxx
Mega commit.
[u/mrichter/AliRoot.git] / PWG2 / FORWARD / analysis2 / AliFMDMCEventInspector.cxx
index 74a9b0119b843f1a7543c4fe67e4804fc6f7d44c..e933a92d9eb2b28b1fd2c68e2060507e73542c42 100644 (file)
@@ -21,6 +21,7 @@
 #include "AliCentrality.h"
 #include "AliESDEvent.h"
 #include "AliMCEvent.h"
+#include "AliStack.h"
 #include "AliGenPythiaEventHeader.h"
 #include "AliGenDPMjetEventHeader.h"
 #include "AliGenHijingEventHeader.h"
 #include "AliGenGeVSimEventHeader.h"
 #include "AliHeader.h"
 #include <TList.h>
+#include <TH2F.h>
+#include <TParticle.h>
+#include <TMath.h>
+
 //====================================================================
 AliFMDMCEventInspector::AliFMDMCEventInspector()
   : AliFMDEventInspector(), 
     fHVertex(0),
     fHPhiR(0), 
-    fHB(0)
+    fHB(0),
+    fHBvsPart(0),
+    fHBvsBin(0),
+    fHBvsCent(0),
+    fHVzComp(0),
+    fHCentVsPart(0),
+    fHCentVsBin(0)
 {
   // 
   // Constructor 
@@ -47,7 +58,13 @@ AliFMDMCEventInspector::AliFMDMCEventInspector(const char* /* name */)
   : AliFMDEventInspector("fmdEventInspector"), 
     fHVertex(0),
     fHPhiR(0), 
-    fHB(0)
+    fHB(0),
+    fHBvsPart(0),
+    fHBvsBin(0),
+    fHBvsCent(0),
+    fHVzComp(0),
+    fHCentVsPart(0),
+    fHCentVsBin(0)
 {
   // 
   // Constructor 
@@ -62,7 +79,13 @@ AliFMDMCEventInspector::AliFMDMCEventInspector(const AliFMDMCEventInspector& o)
   : AliFMDEventInspector(o), 
     fHVertex(0),
     fHPhiR(0), 
-    fHB(0)
+    fHB(0),
+    fHBvsPart(0),
+    fHBvsBin(0),
+    fHBvsCent(0),
+    fHVzComp(0),
+    fHCentVsPart(0),
+    fHCentVsBin(0)
 {
   // 
   // Copy constructor 
@@ -108,10 +131,13 @@ AliFMDMCEventInspector::Init(const TAxis& vtxAxis)
   //
   AliFMDEventInspector::Init(vtxAxis);
 
-  fHVertex = new TH1F("vertex", "True vertex distribution", 
-                     vtxAxis.GetNbins(), 
-                     vtxAxis.GetXmin(), 
-                     vtxAxis.GetXmax());
+  Int_t    maxPart = 450;
+  Int_t    maxBin  = 225;
+  Int_t    maxB    = 25;
+  Int_t    nVtx = vtxAxis.GetNbins();
+  Double_t lVtx = vtxAxis.GetXmin();
+  Double_t hVtx = vtxAxis.GetXmax();
+  fHVertex = new TH1F("vertex", "True vertex distribution", nVtx, lVtx, hVtx);
   fHVertex->SetXTitle("v_{z} [cm]");
   fHVertex->SetYTitle("# of events");
   fHVertex->SetFillColor(kGreen+1);
@@ -128,14 +154,67 @@ AliFMDMCEventInspector::Init(const TAxis& vtxAxis)
   fHPhiR->SetDirectory(0);
   fList->Add(fHPhiR);
 
-  fHB = new TH1F("b", "Impact parameter", 125, 0, 25);
+  fHB = new TH1F("b", "Impact parameter", 5*maxB, 0, maxB);
   fHB->SetXTitle("b [fm]");
   fHB->SetYTitle("# of events");
   fHB->SetFillColor(kGreen+1);
   fHB->SetFillStyle(3001);
   fHB->SetDirectory(0);
   fList->Add(fHB);
+
+  fHBvsPart = new TH2F("bVsParticipants", "Impact parameter vs Participants",
+                      5*maxB, 0, maxB, maxPart, -.5, maxPart-.5);
+  fHBvsPart->SetXTitle("b [fm]");
+  fHBvsPart->SetYTitle("# of participants");
+  fHBvsPart->SetZTitle("Events");
+  fHBvsPart->SetDirectory(0);
+  fList->Add(fHBvsPart);
+
+  fHBvsBin = new TH2F("bVsBinary", "Impact parameter vs Binary Collisions",
+                      5*maxB, 0, maxB, maxBin, -.5, maxBin-.5);
+  fHBvsBin->SetXTitle("b [fm]");
+  fHBvsBin->SetYTitle("# of binary collisions");
+  fHBvsBin->SetZTitle("Events");
+  fHBvsBin->SetDirectory(0);
+  fList->Add(fHBvsBin);
   
+  fHBvsCent = new TH2F("bVsCentrality", "Impact parameter vs Centrality",
+                      5*maxB, 0, maxB, fCentAxis->GetNbins(), 
+                      fCentAxis->GetXbins()->GetArray());
+  fHBvsCent->SetXTitle("b [fm]");
+  fHBvsCent->SetYTitle("Centrality [%]");
+  fHBvsCent->SetZTitle("Event");
+  fHBvsCent->SetDirectory(0);
+  fList->Add(fHBvsCent);
+  
+  
+  fHVzComp = new TH2F("vzComparison", "v_{z} truth vs reconstructed",
+                     10*nVtx, lVtx, hVtx, 10*nVtx, lVtx, hVtx);
+  fHVzComp->SetXTitle("True v_{z} [cm]");
+  fHVzComp->SetYTitle("Reconstructed v_{z} [cm]");
+  fHVzComp->SetZTitle("Events");
+  fHVzComp->SetDirectory(0);
+  fList->Add(fHVzComp);
+
+  fHCentVsPart = new TH2F("centralityVsParticipans", 
+                         "# of participants vs Centrality",
+                         maxPart, -.5, maxPart-.5, fCentAxis->GetNbins(), 
+                         fCentAxis->GetXbins()->GetArray());
+  fHCentVsPart->SetXTitle("Participants");
+  fHCentVsPart->SetYTitle("Centrality [%]");
+  fHCentVsPart->SetZTitle("Event");
+  fHCentVsPart->SetDirectory(0);
+  fList->Add(fHCentVsPart);
+
+  fHCentVsBin = new TH2F("centralityVsBinary", 
+                        "# of binary collisions vs Centrality",
+                        maxBin, -.5, maxBin-.5, fCentAxis->GetNbins(), 
+                        fCentAxis->GetXbins()->GetArray());
+  fHCentVsBin->SetXTitle("Binary collisions");
+  fHCentVsBin->SetYTitle("Centrality [%]");
+  fHCentVsBin->SetZTitle("Event");
+  fHCentVsBin->SetDirectory(0);
+  fList->Add(fHCentVsBin);
 }
 
 //____________________________________________________________________
@@ -145,6 +224,8 @@ AliFMDMCEventInspector::ProcessMC(AliMCEvent*       event,
                                  UShort_t&         ivz, 
                                  Double_t&         vz,
                                  Double_t&         b,
+                                 Int_t&            npart, 
+                                 Int_t&            nbin,
                                  Double_t&         phiR)
 {
   // 
@@ -172,57 +253,74 @@ AliFMDMCEventInspector::ProcessMC(AliMCEvent*       event,
   //Assign MC only triggers : True NSD etc.
   AliHeader*               header          = event->Header();
   AliGenEventHeader*       genHeader       = header->GenEventHeader();
+  AliCollisionGeometry*    colGeometry     = 
+    dynamic_cast<AliCollisionGeometry*>(genHeader);
   AliGenPythiaEventHeader* pythiaHeader    = 
     dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
   AliGenDPMjetEventHeader* dpmHeader       = 
     dynamic_cast<AliGenDPMjetEventHeader*>(genHeader);
   AliGenGeVSimEventHeader* gevHeader       = 
     dynamic_cast<AliGenGeVSimEventHeader*>(genHeader);
-  AliGenHijingEventHeader* hijingHeader    = 
-    dynamic_cast<AliGenHijingEventHeader*>(genHeader);
   AliGenHerwigEventHeader* herwigHeader    = 
     dynamic_cast<AliGenHerwigEventHeader*>(genHeader);
+  // AliGenHijingEventHeader* hijingHeader    = 
+  //   dynamic_cast<AliGenHijingEventHeader*>(genHeader);
   // AliGenHydjetEventHeader* hydjetHeader    = 
   //   dynamic_cast<AliGenHydjetEventHeader*>(genHeader);
-  AliGenEposEventHeader*   eposHeader      = 
-    dynamic_cast<AliGenEposEventHeader*>(genHeader);
+  // AliGenEposEventHeader*   eposHeader      = 
+  //   dynamic_cast<AliGenEposEventHeader*>(genHeader);
   
   // Check if this is a single diffractive event 
-  Bool_t   sd = kFALSE;
-  Double_t phi = -1111;
-  b            = -1;
+  Bool_t   sd    = kFALSE;
+  Double_t phi   = -1111;
+  npart          = 0;
+  nbin           = 0;
+  b              = -1;
+  if (colGeometry) { 
+    b     = colGeometry->ImpactParameter();
+    phi   = colGeometry->ReactionPlaneAngle();
+    npart = (colGeometry->ProjectileParticipants() + 
+            colGeometry->TargetParticipants());
+    nbin  = colGeometry->NN();
+  }
   if(pythiaHeader) {
     Int_t pythiaType = pythiaHeader->ProcessType();
+    // 92 and 93 are SD 
+    // 94 is DD 
     if (pythiaType==92 || pythiaType==93) sd = kTRUE;
-    b = pythiaHeader->GetImpactParameter();
+    b     = pythiaHeader->GetImpactParameter();
+    npart = 2; // Always 2 protons
+    nbin  = 1; // Always 1 binary collision 
   }
-  if(dpmHeader) {
+  if(dpmHeader) { // Also an AliCollisionGeometry 
     Int_t processType = dpmHeader->ProcessType();
+    // 1 & 4 are ND 
+    // 5 & 6 are SD 
+    // 7 is DD 
     if (processType == 5 || processType == 6)  sd = kTRUE;
-    b    = dpmHeader->ImpactParameter();
-    phi  = dpmHeader->ReactionPlaneAngle();
-
   }
   if (gevHeader) { 
     phi  = gevHeader->GetEventPlane();
   }
-  if (hijingHeader) { 
-    b    = hijingHeader->ImpactParameter();
-    phi  = hijingHeader->ReactionPlaneAngle();
-  }
   if (herwigHeader) {
     Int_t processType = herwigHeader->ProcessType();
     // This is a guess 
     if (processType == 5 || processType == 6)  sd = kTRUE;
+    npart = 2; // Always 2 protons
+    nbin  = 1; // Always 1 binary collision 
   }
+  // if (hijingHeader) { 
+  // b    = hijingHeader->ImpactParameter();
+  // phi  = hijingHeader->ReactionPlaneAngle();
+  // }
   // if (hydjetHeader) {
   //   b    = hydjetHeader->ImpactParameter();
   //   phi  = hydjetHeader->ReactionPlaneAngle();
   // }
-  if (eposHeader) {
-    b    = eposHeader->ImpactParameter();
-    phi  = eposHeader->ReactionPlaneAngle();
-  }
+  // if (eposHeader) {
+  //   b    = eposHeader->ImpactParameter();
+  // phi  = eposHeader->ReactionPlaneAngle();
+  // }
 
   // Normalize event plane angle to [0,2pi]
   if (phi <= -1111) phiR = -1;
@@ -234,6 +332,9 @@ AliFMDMCEventInspector::ProcessMC(AliMCEvent*       event,
     }
   }
 
+  // Do a check on particles
+  sd = IsSingleDiffractive(event->Stack());
+
   // Set NSD flag
   if(!sd) {
     triggers |= AliAODForwardMult::kMCNSD;
@@ -248,6 +349,8 @@ AliFMDMCEventInspector::ProcessMC(AliMCEvent*       event,
   fHVertex->Fill(vz);
   fHPhiR->Fill(phiR);
   fHB->Fill(b);
+  fHBvsPart->Fill(b, npart);
+  fHBvsBin->Fill(b, nbin);
 
   // Check for the vertex bin 
   ivz = fHEventsTr->GetXaxis()->FindBin(vz);
@@ -263,9 +366,110 @@ AliFMDMCEventInspector::ProcessMC(AliMCEvent*       event,
   
   return kOk;
 }
+
+//____________________________________________________________________
+namespace {
+  Double_t rapidity(TParticle* p, Double_t mass)
+  {
+    Double_t pt = p->Pt();
+    Double_t pz = p->Pz();
+    Double_t ee = TMath::Sqrt(pt*pt+pz*pz+mass*mass);
+    if (TMath::Abs(ee - TMath::Abs(pz)) < 1e-9) return TMath::Sign(1e30, pz);
+    return .5 * TMath::Log((ee + pz) / (ee - pz)); 
+  }
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDMCEventInspector::IsSingleDiffractive(AliStack* stack,
+                                           Double_t xiMin, 
+                                           Double_t xiMax) const
+{
+  // Re-implementation of AliPWG0Helper::IsHadronLevelSingleDiffrative
+  // 
+  // This is re-implemented here to be indendent of the PWG0 library. 
+  TParticle* p1 = 0;     // Particle with least y 
+  TParticle* p2 = 0;     // Particle with largest y 
+  Double_t   y1 =  1e10; // y of p1 
+  Double_t   y2 = -1e10; // y of p2 
+  
+  // Loop over primaries 
+  for (Int_t i = 0; i < stack->GetNprimary(); i++) { 
+    TParticle* p = stack->Particle(i);
+    if (!p) continue;
+    
+    Int_t pdg = TMath::Abs(p->GetPdgCode());
+    Int_t c1  = p->GetFirstDaughter();
+    Int_t s   = p->GetStatusCode();
+    Int_t mfl = Int_t(pdg/TMath::Power(10,Int_t(TMath::Log10(pdg))));
+
+    // Select final state charm and beauty 
+    if (c1 > -1 || s != 1) mfl = 0; 
+
+    // Check if this is a primary, pi0, Sigma0, ???, or most
+    // significant digit is larger than or equal to 4
+    if (!(stack->IsPhysicalPrimary(i) || 
+         pdg == 111  || 
+         pdg == 3212 || 
+         pdg == 3124 || 
+         mfl >= 4)) continue;
+
+    Int_t m1 = p->GetFirstMother();
+    if (m1 > 0) { 
+      TParticle* pm1  = stack->Particle(m1);
+      Int_t      mpdg = TMath::Abs(pm1->GetPdgCode());
+      // Check if mother is a p0, Simga0, or ???
+      if (mpdg == 111 || mpdg == 3124 || mpdg == 3212) continue;
+    }
+    
+    // Calculate the rapidity of the particle 
+    Double_t mm = (pdg != 3124 ? p->GetMass() : 1.5195);
+    Double_t yy = rapidity(p, mm);
+    
+    // Check if the rapidity of this particle is further out than any
+    // of the preceding particles
+    if (yy < y1) { 
+      y1 = yy;
+      p1 = p;
+    }
+    if (yy > y2) { 
+      y2 = yy;
+      p2 = p;
+    }
+  }
+  if (!p1 || !p2) return false;
+  
+  // Calculate rapidities assuming protons 
+  y1            = TMath::Abs(rapidity(p1, 0.938));
+  y2            = TMath::Abs(rapidity(p2, 0.938));
+
+  // Check if both or just one is a proton
+  Int_t    pdg1 = p1->GetPdgCode();
+  Int_t    pdg2 = p2->GetPdgCode();
+  Int_t    arm  = -99999;
+  if (pdg1 == 2212 && pdg2 == 2212) 
+    arm = (y1 > y2 ? 0 : 1);
+  else if (pdg1 == 2212) 
+    arm = 0;
+  else if (pdg2 == 2212) 
+    arm = 1;
+  else 
+    return false;
+  
+  // Rapidity shift
+  Double_t m02s = 1 - 2 * p1->Energy() / fEnergy; 
+  Double_t m12s = 1 - 2 * p2->Energy() / fEnergy;
+  
+  if (arm == 0 && m02s > xiMin && m02s < xiMax) return true;
+  if (arm == 1 && m12s > xiMin && m12s < xiMax) return true;
+    
+  return false;
+}
 //____________________________________________________________________
 Bool_t
-AliFMDMCEventInspector::ReadCentrality(const AliESDEvent* esd, Double_t& cent)
+AliFMDMCEventInspector::ReadCentrality(const AliESDEvent* esd, 
+                                      Double_t& cent, 
+                                      UShort_t& qual) const
 {
   // 
   // Read centrality from event 
@@ -277,23 +481,33 @@ AliFMDMCEventInspector::ReadCentrality(const AliESDEvent* esd, Double_t& cent)
   // Return:
   //    False on error, true otherwise 
   //
+  cent = -1;
+  qual = 0;
   AliCentrality* centObj = const_cast<AliESDEvent*>(esd)->GetCentrality();
-  if (centObj) {
-    // AliInfo(Form("Got centrality object %p with quality %d", 
-    //              centObj, centObj->GetQuality()));
-    // centObj->Print();
-    if (centObj->GetQuality() == 0x8) 
-      cent = centObj->GetCentralityPercentileUnchecked("V0M");  
-    else
-      cent = centObj->GetCentralityPercentile("V0M");        
-  }
-  // AliInfo(Form("Centrality is %f", cent));
-  fHCent->Fill(cent);
+  if (!centObj) return true;
+
+  qual = centObj->GetQuality();
+  if (qual == 0x8) // Ignore ZDC outliers 
+    cent = centObj->GetCentralityPercentileUnchecked("V0M");  
+  else
+    cent = centObj->GetCentralityPercentile("V0M");        
 
   return true;
 }
 
-  
+//____________________________________________________________________
+Bool_t
+AliFMDMCEventInspector::CompareResults(Double_t vz,    Double_t trueVz, 
+                                      Double_t cent,  Double_t b,
+                                      Int_t    npart, Int_t    nbin)
+{
+  fHVzComp->Fill(trueVz, vz);
+  fHBvsCent->Fill(b, cent);
+  fHCentVsPart->Fill(npart, cent);
+  fHCentVsBin->Fill(nbin, cent);
+
+  return true;
+}  
 //
 // EOF
 //