+
+ return result;
+}
+
+
+//________________________________________________________________________________
+Bool_t AliDielectronMC::CheckParticleSource(Int_t label, AliDielectronSignalMC::ESource source) const {
+ //
+ // Check the source for the particle
+ //
+
+ switch (source) {
+ case AliDielectronSignalMC::kDontCare :
+ return kTRUE;
+ break;
+ case AliDielectronSignalMC::kPrimary :
+ if(label>=0 && label<GetNPrimary()) return kTRUE;
+ else return kFALSE;
+ break;
+ case AliDielectronSignalMC::kSecondary :
+ if(label>=GetNPrimary()) return kTRUE;
+ else return kFALSE;
+ break;
+ case AliDielectronSignalMC::kDirect :
+ if(label>=0 && GetMothersLabel(label)<0) return kTRUE;
+ else return kFALSE;
+ break;
+ case AliDielectronSignalMC::kDecayProduct :
+ if(label>=0 && GetMothersLabel(label)>=0) return kTRUE;
+ else return kFALSE;
+ break;
+ default :
+ return kFALSE;
+ }
+ return kFALSE;
+}
+
+
+//________________________________________________________________________________
+Bool_t AliDielectronMC::IsMCTruth(Int_t label, AliDielectronSignalMC* signalMC, Int_t branch) {
+ //
+ // Check if the particle corresponds to the MC truth in signalMC in the branch specified
+ //
+
+ // NOTE: Some particles have the sign of the label flipped. It is related to the quality of matching
+ // between the ESD and the MC track. The negative labels indicate a poor matching quality
+ //if(label<0) return kFALSE;
+ if(label<0) label *= -1;
+ AliVParticle* part = GetMCTrackFromMCEvent(label);
+ if (!part) {
+ AliError(Form("Could not find MC particle with label %d",label));
+ return kFALSE;
+ }
+ // check the leg
+ if(!ComparePDG(part->PdgCode(),signalMC->GetLegPDG(branch),signalMC->GetCheckBothChargesLegs(branch))) return kFALSE;
+ if(!CheckParticleSource(label, signalMC->GetLegSource(branch))) return kFALSE;
+
+ // check the mother
+ AliVParticle* mcMother=0x0;
+ Int_t mLabel = -1;
+ if(signalMC->GetMotherPDG(branch)!=0 || signalMC->GetMotherSource(branch)!=AliDielectronSignalMC::kDontCare) {
+ if(part) {
+ mLabel = GetMothersLabel(label);
+ mcMother = GetMCTrackFromMCEvent(mLabel);
+ }
+ if(!mcMother) return kFALSE;
+
+ if(!ComparePDG(mcMother->PdgCode(),signalMC->GetMotherPDG(branch),signalMC->GetCheckBothChargesMothers(branch))) return kFALSE;
+ if(!CheckParticleSource(mLabel, signalMC->GetMotherSource(branch))) return kFALSE;
+ }
+
+ // check the grandmother
+ if(signalMC->GetGrandMotherPDG(branch)!=0 || signalMC->GetGrandMotherSource(branch)!=AliDielectronSignalMC::kDontCare) {
+ AliVParticle* mcGrandMother=0x0;
+ Int_t gmLabel = -1;
+ if(mcMother) {
+ gmLabel = GetMothersLabel(mLabel);
+ mcGrandMother = static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(gmLabel));
+ }
+ if(!mcGrandMother) return kFALSE;
+
+ if(!ComparePDG(mcGrandMother->PdgCode(),signalMC->GetGrandMotherPDG(branch),signalMC->GetCheckBothChargesGrandMothers(branch))) return kFALSE;
+ if(!CheckParticleSource(gmLabel, signalMC->GetGrandMotherSource(branch))) return kFALSE;
+ }
+
+ return kTRUE;
+}
+
+
+//________________________________________________________________________________
+Bool_t AliDielectronMC::IsMCTruth(const AliDielectronPair* pair, const AliDielectronSignalMC* signalMC) const {
+ //
+ // Check if the pair corresponds to the MC truth in signalMC
+ //
+
+ // legs (daughters)
+ const AliVParticle * mcD1 = pair->GetFirstDaughter();
+ const AliVParticle * mcD2 = pair->GetSecondDaughter();
+ Int_t labelD1 = (mcD1 ? mcD1->GetLabel() : -1);
+ Int_t labelD2 = (mcD2 ? mcD2->GetLabel() : -1);
+ if(labelD1<0) labelD1 *= -1;
+ if(labelD2<0) labelD2 *= -1;
+ Int_t d1Pdg = 0;
+ Int_t d2Pdg = 0;
+ d1Pdg=GetPdgFromLabel(labelD1);
+ d2Pdg=GetPdgFromLabel(labelD2);
+
+ // mothers
+ AliVParticle* mcM1=0x0;
+ AliVParticle* mcM2=0x0;
+
+ // grand-mothers
+ AliVParticle* mcG1 = 0x0;
+ AliVParticle* mcG2 = 0x0;
+
+ // make direct(1-1 and 2-2) and cross(1-2 and 2-1) comparisons for the whole branch
+ Bool_t directTerm = kTRUE;
+ // daughters
+ directTerm = directTerm && mcD1 && ComparePDG(d1Pdg,signalMC->GetLegPDG(1),signalMC->GetCheckBothChargesLegs(1))
+ && CheckParticleSource(labelD1, signalMC->GetLegSource(1));
+
+ directTerm = directTerm && mcD2 && ComparePDG(d2Pdg,signalMC->GetLegPDG(2),signalMC->GetCheckBothChargesLegs(2))
+ && CheckParticleSource(labelD2, signalMC->GetLegSource(2));
+
+ // mothers
+ Int_t labelM1 = -1;
+ if(signalMC->GetMotherPDG(1)!=0 || signalMC->GetMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
+ labelM1 = GetMothersLabel(labelD1);
+ if(labelD1>-1 && labelM1>-1) mcM1 = GetMCTrackFromMCEvent(labelM1);
+ directTerm = directTerm && mcM1
+ && ComparePDG(mcM1->PdgCode(),signalMC->GetMotherPDG(1),signalMC->GetCheckBothChargesMothers(1))
+ && CheckParticleSource(labelM1, signalMC->GetMotherSource(1));
+ }
+
+ Int_t labelM2 = -1;
+ if(signalMC->GetMotherPDG(2)!=0 || signalMC->GetMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
+ labelM2 = GetMothersLabel(labelD2);
+ if(labelD2>-1 && labelM2>-1) mcM2 = GetMCTrackFromMCEvent(labelM2);
+ directTerm = directTerm && mcM2
+ && ComparePDG(mcM2->PdgCode(),signalMC->GetMotherPDG(2),signalMC->GetCheckBothChargesMothers(2))
+ && CheckParticleSource(labelM2, signalMC->GetMotherSource(2));
+ }
+
+ // grand-mothers
+ Int_t labelG1 = -1;
+ if(signalMC->GetGrandMotherPDG(1)!=0 || signalMC->GetGrandMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
+ labelG1 = GetMothersLabel(labelM1);
+ if(mcM1 && labelG1>-1) mcG1 = GetMCTrackFromMCEvent(labelG1);
+ directTerm = directTerm && mcG1
+ && ComparePDG(mcG1->PdgCode(),signalMC->GetGrandMotherPDG(1),signalMC->GetCheckBothChargesGrandMothers(1))
+ && CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(1));
+ }
+
+ Int_t labelG2 = -1;
+ if(signalMC->GetGrandMotherPDG(2)!=0 || signalMC->GetGrandMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
+ labelG2 = GetMothersLabel(labelM2);
+ if(mcM2 && labelG2>-1) mcG2 = GetMCTrackFromMCEvent(labelG2);
+ directTerm = directTerm && mcG2
+ && ComparePDG(mcG2->PdgCode(),signalMC->GetGrandMotherPDG(2),signalMC->GetCheckBothChargesGrandMothers(2))
+ && CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(2));
+ }
+
+ // Cross term
+ Bool_t crossTerm = kTRUE;
+ // daughters
+ crossTerm = crossTerm && mcD2
+ && ComparePDG(d2Pdg,signalMC->GetLegPDG(1),signalMC->GetCheckBothChargesLegs(1))
+ && CheckParticleSource(labelD2, signalMC->GetLegSource(1));
+
+ crossTerm = crossTerm && mcD1
+ && ComparePDG(d1Pdg,signalMC->GetLegPDG(2),signalMC->GetCheckBothChargesLegs(2))
+ && CheckParticleSource(labelD1, signalMC->GetLegSource(2));
+
+ // mothers
+ if(signalMC->GetMotherPDG(1)!=0 || signalMC->GetMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
+ if(!mcM2 && labelD2>-1) {
+ labelM2 = GetMothersLabel(labelD2);
+ if(labelM2>-1) mcM2 = GetMCTrackFromMCEvent(labelM2);
+ }
+ crossTerm = crossTerm && mcM2
+ && ComparePDG(mcM2->PdgCode(),signalMC->GetMotherPDG(1),signalMC->GetCheckBothChargesMothers(1))
+ && CheckParticleSource(labelM2, signalMC->GetMotherSource(1));
+ }
+
+ if(signalMC->GetMotherPDG(2)!=0 || signalMC->GetMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
+ if(!mcM1 && labelD1>-1) {
+ labelM1 = GetMothersLabel(labelD1);
+ if(labelM1>-1) mcM1 = GetMCTrackFromMCEvent(labelM1);
+ }
+ crossTerm = crossTerm && mcM1
+ && ComparePDG(mcM1->PdgCode(),signalMC->GetMotherPDG(2),signalMC->GetCheckBothChargesMothers(2))
+ && CheckParticleSource(labelM1, signalMC->GetMotherSource(2));
+ }
+
+ // grand-mothers
+ if(signalMC->GetGrandMotherPDG(1)!=0 || signalMC->GetGrandMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
+ if(!mcG2 && mcM2) {
+ labelG2 = GetMothersLabel(labelM2);
+ if(labelG2>-1) mcG2 = GetMCTrackFromMCEvent(labelG2);
+ }
+ crossTerm = crossTerm && mcG2
+ && ComparePDG(mcG2->PdgCode(),signalMC->GetGrandMotherPDG(1),signalMC->GetCheckBothChargesGrandMothers(1))
+ && CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(1));
+ }
+
+ if(signalMC->GetGrandMotherPDG(2)!=0 || signalMC->GetGrandMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
+ if(!mcG1 && mcM1) {
+ labelG1 = GetMothersLabel(labelM1);
+ if(labelG2>-1) mcG1 = GetMCTrackFromMCEvent(labelG1);
+ }
+ crossTerm = crossTerm && mcG1
+ && ComparePDG(mcG1->PdgCode(),signalMC->GetGrandMotherPDG(2),signalMC->GetCheckBothChargesGrandMothers(2))
+ && CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(2));
+ }
+
+ Bool_t motherRelation = kTRUE;
+ if(signalMC->GetMothersRelation()==AliDielectronSignalMC::kSame) {
+ motherRelation = motherRelation && HaveSameMother(pair);
+ }
+ if(signalMC->GetMothersRelation()==AliDielectronSignalMC::kDifferent) {
+ motherRelation = motherRelation && !HaveSameMother(pair);
+ }
+
+ return ((directTerm || crossTerm) && motherRelation);
+}
+
+
+
+//____________________________________________________________
+Bool_t AliDielectronMC::HaveSameMother(const AliDielectronPair * pair) const
+{
+ //
+ // Check whether two particles have the same mother
+ //
+
+ const AliVParticle * daughter1 = pair->GetFirstDaughter();
+ const AliVParticle * daughter2 = pair->GetSecondDaughter();
+
+ AliVParticle *mcDaughter1=GetMCTrackFromMCEvent(daughter1->GetLabel());
+ AliVParticle *mcDaughter2=GetMCTrackFromMCEvent(daughter2->GetLabel());
+ if (!mcDaughter1 || !mcDaughter2) return 0;
+
+ Int_t labelMother1=-1;
+ Int_t labelMother2=-1;
+
+ if (mcDaughter1->IsA()==AliMCParticle::Class()){
+ labelMother1=(static_cast<AliMCParticle*>(mcDaughter1))->GetMother();
+ labelMother2=(static_cast<AliMCParticle*>(mcDaughter2))->GetMother();
+ } else if (mcDaughter1->IsA()==AliAODMCParticle::Class()) {
+ labelMother1=(static_cast<AliAODMCParticle*>(mcDaughter1))->GetMother();
+ labelMother2=(static_cast<AliAODMCParticle*>(mcDaughter2))->GetMother();
+ }
+
+ Bool_t sameMother=(labelMother1>-1)&&(labelMother2>-1)&&(labelMother1==labelMother2);
+
+ return sameMother;
+}
+
+//________________________________________________________________
+Int_t AliDielectronMC::IsJpsiPrimary(const AliDielectronPair * pair)
+{
+ // return: "0" for primary jpsi
+ // "1" for secondary jpsi (from beauty)
+ // "2" for background
+ if(!HaveSameMother(pair)) return 2;
+ AliVParticle *mcDaughter1=GetMCTrackFromMCEvent((pair->GetFirstDaughter())->GetLabel());
+ Int_t labelMother=-1;
+
+ if (mcDaughter1->IsA()==AliMCParticle::Class()){
+ labelMother=(static_cast<AliMCParticle*>(mcDaughter1))->GetMother();
+ } else if (mcDaughter1->IsA()==AliAODMCParticle::Class()) {
+ labelMother=(static_cast<AliAODMCParticle*>(mcDaughter1))->GetMother();
+ }
+
+ AliVParticle* mcMother=GetMCTrackFromMCEvent(labelMother);
+ if(!IsMCMotherToEE(mcMother,443)) return 2;
+ return IsJpsiPrimary(mcMother);
+}
+
+//______________________________________________________________
+Int_t AliDielectronMC::IsJpsiPrimary(const AliVParticle * particle)
+{
+ // return: "0" for primary jpsi
+ // "1" for secondary jpsi (come from B decay)
+ Int_t labelMoth=-1;
+ Int_t pdgCode;
+
+ if (particle->IsA()==AliMCParticle::Class()){
+ labelMoth = (static_cast<const AliMCParticle*>(particle))->GetMother();
+ while(labelMoth>0){
+ particle = GetMCTrackFromMCEvent(labelMoth);
+ pdgCode = TMath::Abs((static_cast<const AliMCParticle*>(particle))->PdgCode());
+ if((pdgCode>500 && pdgCode<600) || (pdgCode>5000 && pdgCode<6000)) return 1;
+ labelMoth = (static_cast<const AliMCParticle*>(particle))->GetMother();
+ }
+ }
+ else if (particle->IsA()==AliAODMCParticle::Class()){
+ labelMoth = (static_cast<const AliAODMCParticle*>(particle))->GetMother();
+ while(labelMoth>0){
+ particle = GetMCTrackFromMCEvent(labelMoth);
+ pdgCode = TMath::Abs((static_cast<const AliAODMCParticle*>(particle))->PdgCode());
+ if((pdgCode>500 && pdgCode<600) || (pdgCode>5000 && pdgCode<6000)) return 1;
+ labelMoth = (static_cast<const AliAODMCParticle*>(particle))->GetMother();
+ }
+ }
+ return 0;