]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG2/RESONANCES/AliRsnLoopPair.cxx
Fixed all fixable coding conventions violations
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnLoopPair.cxx
index 995a88cbc0b30ef49d873bc06fac6d03fd4be13e..a1106471d61995ea3316c2f531a033175ac6b4ff 100644 (file)
@@ -18,6 +18,8 @@
 
 #include "AliLog.h"
 
+#include "AliRsnEvent.h"
+#include "AliRsnPairDef.h"
 #include "AliRsnMother.h"
 #include "AliRsnCutSet.h"
 #include "AliRsnDaughterSelector.h"
@@ -29,8 +31,10 @@ ClassImp(AliRsnLoopPair)
 //_____________________________________________________________________________
 AliRsnLoopPair::AliRsnLoopPair(const char *name, AliRsnPairDef *def, Bool_t isMixed) :
    AliRsnLoop(name, isMixed),
+   fTrueMC(kFALSE),
    fOnlyTrue(kFALSE),
    fCheckDecay(kFALSE),
+   fRangeY(1E20),
    fPairDef(def),
    fPairCuts(0x0),
    fMother()
@@ -46,8 +50,10 @@ AliRsnLoopPair::AliRsnLoopPair(const char *name, AliRsnPairDef *def, Bool_t isMi
 //_____________________________________________________________________________
 AliRsnLoopPair::AliRsnLoopPair(const AliRsnLoopPair& copy) :
    AliRsnLoop(copy),
+   fTrueMC(copy.fTrueMC),
    fOnlyTrue(copy.fOnlyTrue),
    fCheckDecay(copy.fCheckDecay),
+   fRangeY(copy.fRangeY),
    fPairDef(copy.fPairDef),
    fPairCuts(copy.fPairCuts),
    fMother(copy.fMother)
@@ -63,10 +69,16 @@ AliRsnLoopPair::AliRsnLoopPair(const AliRsnLoopPair& copy) :
 //_____________________________________________________________________________
 AliRsnLoopPair& AliRsnLoopPair::operator=(const AliRsnLoopPair& copy)
 {
+//
+// Assignment operator
+//
+
    AliRsnLoop::operator=(copy);
    
+   fTrueMC = copy.fTrueMC;
    fOnlyTrue = copy.fOnlyTrue;
    fCheckDecay = copy.fCheckDecay;
+   fRangeY = copy.fRangeY;
    fPairDef = copy.fPairDef;
    fPairCuts = copy.fPairCuts;
    fMother = copy.fMother;
@@ -126,13 +138,13 @@ Int_t AliRsnLoopPair::DoLoop
 //
 
    if (fIsMixed) {
-      AliDebugClass(1, Form("[%s]: event-mixing loop", GetName()));
+      AliDebugClass(3, Form("[%s]: event-mixing loop", GetName()));
       if (!evMix || !selMix) {
          AliError(Form("[%s] NULL mixed event when mixing is required: cannot process", GetName()));
          return 0;
       }
    } else {
-      AliDebugClass(1, Form("[%s]: single-event loop", GetName()));
+      AliDebugClass(3, Form("[%s]: single-event loop", GetName()));
       evMix = evMain;
       selMix = selMain;
    }
@@ -140,14 +152,17 @@ Int_t AliRsnLoopPair::DoLoop
    
    // check cuts
    if (!OkEvent(evMain)) {
-      AliDebugClass(1, Form("[%s]: main event not accepted", GetName()));
+      AliDebugClass(3, Form("[%s]: main event not accepted", GetName()));
       return 0;
    }
    if (!OkEvent(evMix)) {
-      AliDebugClass(1, Form("[%s]: mixed event not accepted", GetName()));
+      AliDebugClass(3, Form("[%s]: mixed event not accepted", GetName()));
       return 0;
    }
    
+   // if it is required to loop over True MC, do this here and skip the rest of the method
+   if (fTrueMC) return LoopTrueMC(evMain);
+   
    Int_t i0, i1, start, npairs = 0;
    
    TEntryList *list0 = selMain->GetSelected(fListID[0], fPairDef->GetDef1().GetChargeC());
@@ -156,9 +171,9 @@ Int_t AliRsnLoopPair::DoLoop
       AliError("Can't process NULL lists");
       return 0;
    }
-   AliDebugClass(2, Form("[%s]: list counts: %d, %d", GetName(), (Int_t)list0->GetN(), (Int_t)list1->GetN()));
+   AliDebugClass(3, Form("[%s]: list counts: %d, %d", GetName(), (Int_t)list0->GetN(), (Int_t)list1->GetN()));
    if (!list0->GetN() || !list1->GetN()) {
-      AliDebugClass(2, Form("[%s]: at least one list is empty", GetName()));
+      AliDebugClass(3, Form("[%s]: at least one list is empty", GetName()));
       return 0;
    }
    
@@ -178,12 +193,10 @@ Int_t AliRsnLoopPair::DoLoop
          fMother.Sum(1) = fDaughter[0].Psim() + fDaughter[1].Psim();
          fMother.Ref(0).SetXYZM(fMother.Sum(0).X(), fMother.Sum(0).Y(), fMother.Sum(0).Z(), fPairDef->GetMotherMass());
          fMother.Ref(1).SetXYZM(fMother.Sum(1).X(), fMother.Sum(1).Y(), fMother.Sum(1).Z(), fPairDef->GetMotherMass());
-         // check cuts
-         if (fPairCuts) {
-            if (!fPairCuts->IsSelected(&fMother)) {
-               AliDebugClass(2, Form("[%s]: candidate mother didn't pass the cuts", GetName()));
-               continue;
-            }
+         // check rapidity range
+         if (TMath::Abs(fMother.Rapidity(0)) > fRangeY) {
+            AliDebugClass(2, Form("[%s]: Outside rapidity range", GetName()));
+            continue;
          }
          // check mother
          if (fOnlyTrue) {
@@ -192,6 +205,13 @@ Int_t AliRsnLoopPair::DoLoop
                continue;
             }
          }
+         // check cuts
+         if (fPairCuts) {
+            if (!fPairCuts->IsSelected(&fMother)) {
+               AliDebugClass(2, Form("[%s]: candidate mother didn't pass the cuts", GetName()));
+               continue;
+            }
+         }
          // fill outputs
          next.Reset();
          while ( (out = (AliRsnListOutput*)next()) ) {
@@ -216,7 +236,7 @@ Bool_t AliRsnLoopPair::IsTrueMother()
    // daughters have same mother with the right PDG code
    Int_t commonPDG = fMother.CommonMother();
    if (commonPDG != fPairDef->GetMotherPDG()) return kFALSE;
-   AliDebugClass(4, "Found a true mother");
+   AliDebugClass(1, "Found a true mother");
    
    // check #2:
    // checks if daughter have the right particle type
@@ -227,7 +247,259 @@ Bool_t AliRsnLoopPair::IsTrueMother()
       if (!def1.MatchesPID(&fDaughter[0])) return kFALSE;
       if (!def2.MatchesPID(&fDaughter[1])) return kFALSE;
    }
-   AliDebugClass(4, "Decay products match");
+   AliDebugClass(1, "Decay products match");
    
    return kTRUE;
 }
+
+//__________________________________________________________________________________________________
+Bool_t AliRsnLoopPair::AssignMotherAndDaughters(AliRsnEvent *rsnEvent, Int_t ipart)
+{
+//
+// Calls the appropriate assignment method
+//
+
+   // setup pointers
+   fMother.SetDaughter(0, &fDaughter[0]);
+   fMother.SetDaughter(1, &fDaughter[1]);
+   fMother.SetRefEvent(rsnEvent);
+   fDaughter[0].SetOwnerEvent(rsnEvent);
+   fDaughter[1].SetOwnerEvent(rsnEvent);
+
+   if (rsnEvent->IsESD())
+      return AssignMotherAndDaughtersESD(rsnEvent, ipart);
+   else if (rsnEvent->IsAOD())
+      return AssignMotherAndDaughtersAOD(rsnEvent, ipart);
+   else {
+      AliError("Unrecognized input event");
+      return kFALSE;
+   }
+}
+
+//__________________________________________________________________________________________________
+Bool_t AliRsnLoopPair::AssignMotherAndDaughtersESD(AliRsnEvent *rsnEvent, Int_t ipart)
+{
+//
+// Gets a particle in the MC event and try to assign it to the mother.
+// If it has two daughters, retrieve them and assign also them.
+// NOTE: assignment is done only for MC, since reconstructed match is assigned in the same way
+//       for ESD and AOD, if available
+// ---
+// Implementation for ESD inputs
+//
+
+   AliMCEvent    *mc      = rsnEvent->GetRefMCESD();
+   AliStack      *stack   = mc->Stack();
+   AliMCParticle *mother  = (AliMCParticle*)mc->GetTrack(ipart);
+   TParticle     *motherP = mother->Particle();
+   Int_t          ntracks = stack->GetNtrack();
+   
+   // check PDG code and exit if it is wrong
+   if (TMath::Abs(motherP->GetPdgCode()) != fPairDef->GetMotherPDG()) return kFALSE;
+   
+   // check number of daughters and exit if it is not 2
+   if (motherP->GetNDaughters() < 2) return kFALSE;
+   //if (!stack->IsPhysicalPrimary(ipart)) return kFALSE;
+   
+   /*
+   // check distance from primary vertex
+   TLorentzVector vprod;
+   motherP->ProductionVertex(vprod);
+   if (!CheckDistanceFromPV(vprod.X(), vprod.Y(), vprod.Z())) {
+      AliDebugClass(1, "Distant production vertex");
+      return kFALSE;
+   }
+   */
+   
+   // get the daughters and check their PDG code and charge:
+   // if they match one of the pair daughter definitions, 
+   // assign them as MC reference of the 'fDaughter' objects
+   fDaughter[0].Reset();
+   fDaughter[1].Reset();
+   Int_t index[2] = {motherP->GetDaughter(0), motherP->GetDaughter(1)};
+   Int_t i, pdg;
+   Short_t charge;
+   AliMCParticle *daughter = 0x0;
+   for (i = 0; i < 2; i++) {
+      // check index for stack
+      if (index[i] < 0 || index[i] > ntracks) {
+         AliError(Form("Index %d overflow: value = %d, max = %d", i, index[i], ntracks));
+         return kFALSE;
+      }
+      // get daughter and its PDG and charge
+      daughter = (AliMCParticle*)mc->GetTrack(index[i]);
+      pdg      = TMath::Abs(daughter->Particle()->GetPdgCode());
+      charge   = (Short_t)(daughter->Particle()->GetPDG()->Charge() / 3);
+      // check if it matches one definition
+      if (fPairDef->GetDef1().MatchesPDG(pdg) && fPairDef->GetDef1().MatchesChargeS(charge)) {
+         fDaughter[0].SetGood();
+         fDaughter[0].SetRefMC(daughter);
+         fDaughter[0].SetLabel(index[i]);
+      } else if (fPairDef->GetDef2().MatchesPDG(pdg) && fPairDef->GetDef2().MatchesChargeS(charge)) {
+         fDaughter[1].SetGood();
+         fDaughter[1].SetRefMC(daughter);
+         fDaughter[1].SetLabel(index[i]);
+      }
+   }
+   
+   // return success if both daughters were assigned
+   if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
+      return kTRUE;
+   } else {
+      fDaughter[0].Reset();
+      fDaughter[1].Reset();
+      return kFALSE;
+   }
+}
+
+//__________________________________________________________________________________________________
+Bool_t AliRsnLoopPair::AssignMotherAndDaughtersAOD(AliRsnEvent *rsnEvent, Int_t ipart)
+{
+//
+// Gets a particle in the MC event and try to assign it to the mother.
+// If it has two daughters, retrieve them and assign also them.
+// NOTE: assignment is done only for MC, since reconstructed match is assigned in the same way
+//       for ESD and AOD, if available
+// ---
+// Implementation for AOD inputs
+//
+
+   AliAODEvent      *aod     = rsnEvent->GetRefAOD();
+   TClonesArray     *listAOD = (TClonesArray*)(aod->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
+   AliAODMCParticle *mother  = (AliAODMCParticle*)listAOD->At(ipart);
+   
+   // check PDG code and exit if it is wrong
+   if (TMath::Abs(mother->GetPdgCode()) != fPairDef->GetMotherPDG()) return kFALSE;
+   
+   // check number of daughters and exit if it is not 2
+   if (mother->GetNDaughters() < 2) return kFALSE;
+   if (!mother->IsPrimary()) return kFALSE;
+   
+   /*
+   // check distance from primary vertex
+   Double_t vprod[3] = {(Double_t)mother->Xv(), (Double_t)mother->Yv(), (Double_t)mother->Zv()};
+   Double_t dv = DistanceFromPV(vprod[0], vprod[1], vprod[2]);
+   if (dv > fMaxDistPV) {
+      AliDebugClass(1, "Distant production vertex");
+      return kFALSE;
+   }
+   */
+   
+   // get the daughters and check their PDG code and charge:
+   // if they match one of the pair daughter definitions, 
+   // assign them as MC reference of the 'fDaughter' objects
+   fDaughter[0].Reset();
+   fDaughter[1].Reset();
+   Int_t index[2] = {(Int_t)mother->GetDaughter(0), (Int_t)mother->GetDaughter(1)};
+   Int_t ntracks = listAOD->GetEntriesFast();
+   Int_t i, pdg;
+   Short_t charge;
+   AliAODMCParticle *daughter = 0x0;
+   for (i = 0; i < 2; i++) {
+      // check index for stack
+      if (index[i] < 0 || index[i] > ntracks) {
+         AliError(Form("Index %d overflow: value = %d, max = %d", i, index[i], ntracks));
+         return kFALSE;
+      }
+      // get daughter and its PDG and charge
+      daughter = (AliAODMCParticle*)listAOD->At(index[i]);
+      pdg      = TMath::Abs(daughter->GetPdgCode());
+      charge   = (Short_t)(daughter->Charge() / 3);
+      // check if it matches one definition
+      if (fPairDef->GetDef1().MatchesPDG(pdg) && fPairDef->GetDef1().MatchesChargeS(charge)) {
+         fDaughter[0].SetGood();
+         fDaughter[0].SetRefMC(daughter);
+         fDaughter[0].SetLabel(index[i]);
+      } else if (fPairDef->GetDef2().MatchesPDG(pdg) && fPairDef->GetDef2().MatchesChargeS(charge)) {
+         fDaughter[1].SetGood();
+         fDaughter[1].SetRefMC(daughter);
+         fDaughter[1].SetLabel(index[i]);
+      }
+   }
+   
+   // return success if both daughters were assigned
+   if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
+      return kTRUE;
+   } else {
+      fDaughter[0].Reset();
+      fDaughter[1].Reset();
+      return kFALSE;
+   }
+}
+
+//_____________________________________________________________________________
+Int_t AliRsnLoopPair::LoopTrueMC(AliRsnEvent *rsn)
+{
+//
+// Loop on event and fill containers
+//
+
+   // check presence of MC reference
+   if (!rsn->GetRefMC()) {
+      AliError("Need a MC to compute efficiency");
+      return 0;
+   }
+   
+   // check event type:
+   // must be ESD or AOD, and then use a bool to know in the rest
+   if (!rsn->IsESD() && !rsn->IsAOD()) {
+      AliError("Need to process ESD or AOD input");
+      return 0;
+   }
+   
+   // retrieve the MC primary vertex position
+   // and do some additional coherence checks
+   //Double_t fVertex[3] = {0.0, 0.0, 0.0};
+   Int_t npart = 0;
+   if (rsn->IsESD()) {
+      //TArrayF mcVertex(3);
+      //AliGenEventHeader *genEH = rsn->GetRefMCESD()->GenEventHeader();
+      //genEH->PrimaryVertex(mcVertex);
+      //for (i = 0; i < 3; i++) fVertex[i] = (Double_t)mcVertex[i];
+      npart = rsn->GetRefMCESD()->GetNumberOfTracks();
+   } else {
+      //for (i = 0; i < 3; i++) fVertex[i] = 0.0;
+      AliAODEvent *aod = rsn->GetRefMCAOD();
+      TClonesArray *listAOD = (TClonesArray*)(aod->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
+      if (listAOD) npart = listAOD->GetEntries();
+      //AliAODMCHeader *mcH = static_cast<AliAODMCHeader*>(aod->FindListObject(AliAODMCHeader::StdBranchName()));
+      //if (mcH) mcH->GetVertex(fVertex);
+   }
+   
+   // check number of particles
+   if (!npart) {
+      AliInfo("Empty event");
+      return 0;
+   }
+   
+   // utility variables
+   Int_t ipart, count = 0;
+   AliRsnDaughter check;
+   
+   TObjArrayIter next(&fOutputs);
+   AliRsnListOutput *out = 0x0;
+   
+   // loop over particles
+   for (ipart = 0; ipart < npart; ipart++) {
+      // check i-th particle
+      if (!AssignMotherAndDaughters(rsn, ipart)) continue;
+      // if assignment was successful, for first step, use MC info
+      fDaughter[0].SetRef(fDaughter[0].GetRefMC());
+      fDaughter[1].SetRef(fDaughter[1].GetRefMC());
+      fMother.SetRefEvent(rsn);
+      fMother.ComputeSum(fPairDef->GetDef1().GetMass(), fPairDef->GetDef2().GetMass(), fPairDef->GetMotherMass());
+      // check rapidity range
+      if (TMath::Abs(fMother.Rapidity(0)) > fRangeY) {
+         AliDebugClass(2, Form("[%s]: Outside rapidity range", GetName()));
+         continue;
+      }
+      // fill outputs
+      next.Reset();
+      while ( (out = (AliRsnListOutput*)next()) ) {
+         if (out->Fill(&fMother)) count++;
+         else AliDebugClass(3, Form("[%s]: failed computation", GetName()));
+      }
+   }
+   
+   return count;
+}