#include "AliAnalysisTaskHighPtDeDxV0.h" // ROOT includes #include #include #include #include #include #include // AliRoot includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "AliCentrality.h" #include "AliESDtrackCuts.h" #include #include #include // STL includes #include using namespace std; //_____________________________________________________________________________ // // Responsible: // Peter Christiansen (Lund) // //_____________________________________________________________________________ ClassImp(AliAnalysisTaskHighPtDeDxV0) const Double_t AliAnalysisTaskHighPtDeDxV0::fgkClight = 2.99792458e-2; //_____________________________________________________________________________ AliAnalysisTaskHighPtDeDxV0::AliAnalysisTaskHighPtDeDxV0(): AliAnalysisTaskSE(), fESD(0x0), fAOD(0x0), fMC(0x0), fMCStack(0x0), fMCArray(0x0), fTrackFilter(0x0), fTrackFilterGolden(0x0), fTrackFilterTPC(0x0), fAnalysisType("ESD"), fAnalysisMC(kFALSE), fAnalysisPbPb(kFALSE), ftrigBit1(0x0), ftrigBit2(0x0), fEvent(0x0), fV0ArrayGlobalPar(0x0), fV0ArrayTPCPar(0x0), fTrackArrayMC(0x0), fVtxCut(10.0), fEtaCut(0.9), fMinPt(0.1), fMinCent(0.0), fMaxCent(100.0), fMassCut(0.1), fTreeOption(0), fRequireRecV0(kTRUE), fStoreMcIn(kFALSE), fMcProcessType(-999), fTriggeredEventMB(-999), fVtxStatus(-999), fZvtx(-999), fZvtxMC(-999), fRun(-999), fEventId(-999), fListOfObjects(0), fEvents(0x0), fVtx(0x0), fVtxMC(0x0), fVtxBeforeCuts(0x0), fVtxAfterCuts(0x0), fTree(0x0), fnv0(0) { // Default constructor (should not be used) } //______________________________________________________________________________ AliAnalysisTaskHighPtDeDxV0::AliAnalysisTaskHighPtDeDxV0(const char *name): AliAnalysisTaskSE(name), fESD(0x0), fAOD(0x0), fMC(0x0), fMCStack(0x0), fMCArray(0x0), fTrackFilter(0x0), fTrackFilterGolden(0x0), fTrackFilterTPC(0x0), fAnalysisType("ESD"), fAnalysisMC(kFALSE), fAnalysisPbPb(kFALSE), ftrigBit1(0x0), ftrigBit2(0x0), fEvent(0x0), fV0ArrayGlobalPar(0x0), fV0ArrayTPCPar(0x0), fTrackArrayMC(0x0), fVtxCut(10.0), fEtaCut(0.9), fMinPt(0.1), fMinCent(0.0), fMaxCent(100.0), fMassCut(0.1), fTreeOption(0), fRequireRecV0(kTRUE), fStoreMcIn(kFALSE), fMcProcessType(-999), fTriggeredEventMB(-999), fVtxStatus(-999), fZvtx(-999), fZvtxMC(-999), fRun(-999), fEventId(-999), fListOfObjects(0), fEvents(0x0), fVtx(0x0), fVtxMC(0x0), fVtxBeforeCuts(0x0), fVtxAfterCuts(0x0), fTree(0x0), fnv0(0) { // Output slot #1 writes into a TList DefineOutput(1, TList::Class()); } //_____________________________________________________________________________ AliAnalysisTaskHighPtDeDxV0::~AliAnalysisTaskHighPtDeDxV0() { // Destructor // histograms are in the output list and deleted when the output // list is deleted by the TSelector dtor if (fListOfObjects && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) { delete fListOfObjects; fListOfObjects = 0; } // //for proof running; I cannot create tree do to memory limitations -> work with THnSparse // if (fListOfObjects && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) delete fOutputList; } //______________________________________________________________________________ void AliAnalysisTaskHighPtDeDxV0::UserCreateOutputObjects() { // This method is called once per worker node // Here we define the output: histograms and debug tree if requested OpenFile(1); fListOfObjects = new TList(); fListOfObjects->SetOwner(); // // Histograms // fEvents = new TH1I("fEvents","Number of analyzed events; Events; Counts", 1, 0, 1); fListOfObjects->Add(fEvents); fVtx = new TH1I("fVtx","Vtx info (0=no, 1=yes); Vtx; Counts", 2, -0.5, 1.5); fListOfObjects->Add(fVtx); fnv0 = new TH1F("fnv0","# V0's", 10000,0,10000); fListOfObjects->Add(fnv0); fVtxBeforeCuts = new TH1F("fVtxBeforeCuts", "Vtx distribution (before cuts); Vtx z [cm]; Counts", 120, -30, 30); fListOfObjects->Add(fVtxBeforeCuts); fVtxAfterCuts = new TH1F("fVtxAfterCuts", "Vtx distribution (before cuts); Vtx z [cm]; Counts", 120, -30, 30); fListOfObjects->Add(fVtxAfterCuts); if (fAnalysisMC) { fVtxMC = new TH1I("fVtxMC","Vtx info - no trigger cut (0=no, 1=yes); Vtx; Counts", 2, -0.5, 1.5); fListOfObjects->Add(fVtxMC); } if (fTreeOption) { fTree = new TTree("tree","Event data"); fEvent = new DeDxEvent(); fTree->Branch("event", &fEvent); fV0ArrayGlobalPar = new TClonesArray("DeDxV0", 1000); fTree->Bronch("v0GlobalPar", "TClonesArray", &fV0ArrayGlobalPar); fV0ArrayTPCPar = new TClonesArray("DeDxV0", 1000); fTree->Bronch("v0TPCPar", "TClonesArray", &fV0ArrayTPCPar); if (fAnalysisMC && fStoreMcIn) { fTrackArrayMC = new TClonesArray("DeDxTrackMC", 1000); fTree->Bronch("trackMC", "TClonesArray", &fTrackArrayMC); } fTree->SetDirectory(0); fListOfObjects->Add(fTree); } // Post output data. PostData(1, fListOfObjects); } //______________________________________________________________________________ void AliAnalysisTaskHighPtDeDxV0::UserExec(Option_t *) { // Main loop // // Comment: This method matches completely the same method for the high pT // tracks // // // First we make sure that we have valid input(s)! // if (fAnalysisType == "ESD"){ fESD = dynamic_cast(InputEvent()); if(!fESD){ Printf("%s:%d ESDEvent not found in Input Manager",(char*)__FILE__,__LINE__); this->Dump(); return; } } else { fAOD = dynamic_cast(InputEvent()); if(!fAOD){ Printf("%s:%d AODEvent not found in Input Manager",(char*)__FILE__,__LINE__); this->Dump(); return; } } if (fAnalysisMC) { if (fAnalysisType == "ESD"){ fMC = dynamic_cast(MCEvent()); if(!fMC){ Printf("%s:%d MCEvent not found in Input Manager",(char*)__FILE__,__LINE__); this->Dump(); return; } fMCStack = fMC->Stack(); if(!fMCStack){ Printf("%s:%d MCStack not found in Input Manager",(char*)__FILE__,__LINE__); this->Dump(); return; } } else { // AOD fMC = dynamic_cast(MCEvent()); if(fMC) fMC->Dump(); fMCArray = (TClonesArray*)fAOD->FindListObject("mcparticles"); if(!fMCArray){ Printf("%s:%d AOD MC array not found in Input Manager",(char*)__FILE__,__LINE__); this->Dump(); return; } } } // Get trigger decision fTriggeredEventMB = 0; //init if(((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler())) ->IsEventSelected() & ftrigBit1 ){ fTriggeredEventMB = 1; //event triggered as minimum bias } if(((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler())) ->IsEventSelected() & ftrigBit2 ){ // From AliVEvent: // kINT7 = BIT(1), // V0AND trigger, offline V0 selection fTriggeredEventMB += 2; } // Get process type for MC fMcProcessType = 0; // -1=invalid, 0=data, 1=ND, 2=SD, 3=DD // real data that are not triggered we skip if(!fAnalysisMC && !fTriggeredEventMB) return; if (fAnalysisMC) { if (fAnalysisType == "ESD"){ AliHeader* headerMC = fMC->Header(); if (headerMC) { AliGenEventHeader* genHeader = headerMC->GenEventHeader(); TArrayF vtxMC(3); // primary vertex MC vtxMC[0]=9999; vtxMC[1]=9999; vtxMC[2]=9999; //initialize with dummy if (genHeader) { genHeader->PrimaryVertex(vtxMC); } fZvtxMC = vtxMC[2]; // PYTHIA: AliGenPythiaEventHeader* pythiaGenHeader = dynamic_cast(headerMC->GenEventHeader()); if (pythiaGenHeader) { //works only for pythia fMcProcessType = GetPythiaEventProcessType(pythiaGenHeader->ProcessType()); } // PHOJET: AliGenDPMjetEventHeader* dpmJetGenHeader = dynamic_cast(headerMC->GenEventHeader()); if (dpmJetGenHeader) { fMcProcessType = GetDPMjetEventProcessType(dpmJetGenHeader->ProcessType()); } } } else { // AOD AliAODMCHeader* mcHeader = dynamic_cast(fAOD->FindListObject("mcHeader")); if(mcHeader) { fZvtxMC = mcHeader->GetVtxZ(); if(strstr(mcHeader->GetGeneratorName(), "Pythia")) { fMcProcessType = GetPythiaEventProcessType(mcHeader->GetEventType()); } else { fMcProcessType = GetDPMjetEventProcessType(mcHeader->GetEventType()); } } } } // There are 3 cases // Vertex: NO - status -1 // Vertex: YES : outside cut - status 0 // : inside cut - status 1 // We have to be careful how we normalize because we probably want to // normalize to: // Nevents=(No vertex + outside + inside)/(out + in)*in if (fAnalysisType == "ESD") fZvtx = GetVertex(fESD); else // AOD fZvtx = GetVertex(fAOD); fVtxStatus = -999; if(fZvtx<-990) { fVtxStatus = -1; if(fTriggeredEventMB) fVtx->Fill(0); if(fAnalysisMC) fVtxMC->Fill(0); } else { if(fTriggeredEventMB) fVtx->Fill(1); if(fAnalysisMC) fVtxMC->Fill(1); fVtxBeforeCuts->Fill(fZvtx); fVtxStatus = 0; if (TMath::Abs(fZvtx) < fVtxCut) { fVtxAfterCuts->Fill(fZvtx); fVtxStatus = 1; } } // store MC event data no matter what if(fAnalysisMC && fStoreMcIn) { if (fAnalysisType == "ESD") { ProcessMCTruthESD(); } else { // AOD ProcessMCTruthAOD(); } } Float_t centrality = -10; // only analyze triggered events if(fTriggeredEventMB) { if (fAnalysisType == "ESD"){ if(fAnalysisPbPb){ AliCentrality *centObject = fESD->GetCentrality(); centrality = centObject->GetCentralityPercentile("V0M"); if((centrality>fMaxCent)||(centralityGetNumberOfV0s(); cout<<"&&&&&&&&&&&&&&&& hello world"<Fill(nv0test); AnalyzeESD(fESD); } else { // AOD if(fAnalysisPbPb){ AliCentrality *centObject = fAOD->GetCentrality(); centrality = centObject->GetCentralityPercentile("V0M"); if((centrality>fMaxCent)||(centralityGetNumberOfV0s(); fnv0->Fill(nv0test); AnalyzeAOD(fAOD); } } if( fTreeOption) { fEvent->process = fMcProcessType; fEvent->trig = fTriggeredEventMB; fEvent->zvtxMC = fZvtxMC; fEvent->cent = centrality; if(!fRequireRecV0 || fEvent->n > 0) // only fill if there are accepted V0s fTree->Fill(); fV0ArrayGlobalPar->Clear(); fV0ArrayTPCPar->Clear(); if (fAnalysisMC && fStoreMcIn) fTrackArrayMC->Clear(); } // Post output data. PostData(1, fListOfObjects); } //________________________________________________________________________ void AliAnalysisTaskHighPtDeDxV0::AnalyzeESD(AliESDEvent* esdEvent) { fRun = esdEvent->GetRunNumber(); fEventId = 0; if(esdEvent->GetHeader()) fEventId = GetEventIdAsLong(esdEvent->GetHeader()); // Int_t event = esdEvent->GetEventNumberInFile(); UInt_t time = esdEvent->GetTimeStamp(); // ULong64_t trigger = esdEvent->GetTriggerMask(); Float_t magf = esdEvent->GetMagneticField(); Short_t isPileup = esdEvent->IsPileupFromSPD(); // centrality Float_t centrality = 120; AliCentrality *centObject = esdEvent->GetCentrality(); if(centObject) centrality = centObject->GetCentralityPercentile("V0M"); if(fTriggeredEventMB) {// Only MC case can we have not triggered events if(fVtxStatus==1) { // accepted vertex // accepted event fEvents->Fill(0); ProduceArrayTrksESD( esdEvent, kGlobalTrk );//produce array with global track parameters ProduceArrayTrksESD( esdEvent, kTPCTrk );//array with tpc track parametes } // end if vtx status } // end if triggered if(fTreeOption) { fEvent->run = fRun; fEvent->eventid = fEventId; fEvent->time = time; //fEvent->cent = centrality; fEvent->mag = magf; fEvent->zvtx = fZvtx; fEvent->vtxstatus = fVtxStatus; //fEvent->trackmult = trackmult; //fEvent->n = nadded; fEvent->pileup = isPileup; } } //________________________________________________________________________ void AliAnalysisTaskHighPtDeDxV0::AnalyzeAOD(AliAODEvent* aodEvent) { fRun = aodEvent->GetRunNumber(); fEventId = 0; if(aodEvent->GetHeader()) fEventId = GetEventIdAsLong(aodEvent->GetHeader()); // Int_t event = aodEvent->GetEventNumberInFile(); UInt_t time = 0; // Missing AOD info? aodEvent->GetTimeStamp(); // ULong64_t trigger = aodEvent->GetTriggerMask(); Float_t magf = aodEvent->GetMagneticField(); Int_t trackmult = 0; // no pt cuts Int_t nadded = 0; Short_t isPileup = aodEvent->IsPileupFromSPD(); // centrality Float_t centrality = 120; AliCentrality *centObject = aodEvent->GetCentrality(); if(centObject) centrality = centObject->GetCentralityPercentile("V0M"); if(fTriggeredEventMB) {// Only MC case can we have not triggered events if(fVtxStatus==1) { // accepted vertex // accepted event fEvents->Fill(0); ProduceArrayTrksAOD( aodEvent, kGlobalTrk );//produce array with global track parameters ProduceArrayTrksAOD( aodEvent, kTPCTrk );//array with tpc track parametes } // end if vtx status } // end if triggered if(fTreeOption) { fEvent->run = fRun; fEvent->eventid = fEventId; fEvent->time = time; //fEvent->cent = centrality; fEvent->mag = magf; fEvent->zvtx = fZvtx; fEvent->vtxstatus = fVtxStatus; //fEvent->trackmult = trackmult; //fEvent->n = nadded; fEvent->pileup = isPileup; } } //_____________________________________________________________________________ Float_t AliAnalysisTaskHighPtDeDxV0::GetVertex(const AliVEvent* event) const { Float_t zvtx = -999; const AliVVertex* primaryVertex = event->GetPrimaryVertex(); if(primaryVertex->GetNContributors()>0) zvtx = primaryVertex->GetZ(); return zvtx; } //_____________________________________________________________________________ Short_t AliAnalysisTaskHighPtDeDxV0::GetPidCode(Int_t pdgCode) const { // return our internal code for pions, kaons, and protons Short_t pidCode = 6; switch (TMath::Abs(pdgCode)) { case 211: pidCode = 1; // pion break; case 321: pidCode = 2; // kaon break; case 2212: pidCode = 3; // proton break; case 11: pidCode = 4; // electron break; case 13: pidCode = 5; // proton break; default: pidCode = 6; // something else? }; return pidCode; } //_____________________________________________________________________________ void AliAnalysisTaskHighPtDeDxV0::ProcessMCTruthESD() { // Fill the special MC histogram with the MC truth info Short_t trackmult = 0; Short_t nadded = 0; const Int_t nTracksMC = fMCStack->GetNtrack(); for (Int_t iTracks = 0; iTracks < nTracksMC; iTracks++) { //Cuts if(!(fMCStack->IsPhysicalPrimary(iTracks))) continue; TParticle* trackMC = fMCStack->Particle(iTracks); Double_t chargeMC = trackMC->GetPDG()->Charge(); if (chargeMC != 0) // select charge 0 particles! continue; if (TMath::Abs(trackMC->Eta()) > fEtaCut ) continue; trackmult++; // "charge:pt:p:eta:phi:pidCode" Float_t ptMC = trackMC->Pt(); Float_t pMC = trackMC->P(); Float_t etaMC = trackMC->Eta(); Float_t phiMC = trackMC->Phi(); Int_t pdgCode = trackMC->GetPdgCode(); if(!(pdgCode==310 || pdgCode == 3122 || pdgCode == -3122)) continue; Short_t pidCodeMC = 0; pidCodeMC = GetPidCode(pdgCode); // Warning: In the data code we cut on the daughters..... if (trackMC->Pt() < fMinPt) continue; if(fTreeOption) { DeDxTrackMC* track = new((*fTrackArrayMC)[nadded]) DeDxTrackMC(); nadded++; track->pMC = pMC; track->ptMC = ptMC; track->etaMC = etaMC; track->phiMC = phiMC; track->qMC = Short_t(chargeMC); track->pidMC = pidCodeMC; track->pdgMC = pdgCode; } }//MC track loop if(fTreeOption) { Sort(fTrackArrayMC, kTRUE); fEvent->trackmultMC = trackmult; fEvent->nMC = nadded; } } //_____________________________________________________________________________ void AliAnalysisTaskHighPtDeDxV0::ProcessMCTruthAOD() { // Fill the special MC histogram with the MC truth info Short_t trackmult = 0; Short_t nadded = 0; const Int_t nTracksMC = fMCArray->GetEntriesFast(); for (Int_t iTracks = 0; iTracks < nTracksMC; iTracks++) { AliAODMCParticle* trackMC = dynamic_cast(fMCArray->At(iTracks)); //Cuts if(!(trackMC->IsPhysicalPrimary())) continue; Double_t chargeMC = trackMC->Charge(); if (chargeMC != 0) // Keep the neutral particles continue; if (TMath::Abs(trackMC->Eta()) > fEtaCut ) continue; trackmult++; // "charge:pt:p:eta:phi:pidCode" Float_t ptMC = trackMC->Pt(); Float_t pMC = trackMC->P(); Float_t etaMC = trackMC->Eta(); Float_t phiMC = trackMC->Phi(); Int_t pdgCode = trackMC->PdgCode(); if(!(pdgCode==310 || pdgCode == 3122 || pdgCode == -3122)) continue; Short_t pidCodeMC = 0; pidCodeMC = GetPidCode(pdgCode); if (trackMC->Pt() < fMinPt) continue; if(fTreeOption) { DeDxTrackMC* track = new((*fTrackArrayMC)[nadded]) DeDxTrackMC(); nadded++; track->pMC = pMC; track->ptMC = ptMC; track->etaMC = etaMC; track->phiMC = phiMC; track->qMC = Short_t(chargeMC); track->pidMC = pidCodeMC; track->pdgMC = pdgCode; } }//MC track loop if(fTreeOption) { Sort(fTrackArrayMC, kTRUE); fEvent->trackmultMC = trackmult; fEvent->nMC = nadded; } } //_____________________________________________________________________________ Short_t AliAnalysisTaskHighPtDeDxV0::GetPythiaEventProcessType(Int_t pythiaType) { // // Get the process type of the event. PYTHIA // // source PWG0 dNdpt Short_t globalType = -1; //init if(pythiaType==92||pythiaType==93){ globalType = 2; //single diffractive } else if(pythiaType==94){ globalType = 3; //double diffractive } //else if(pythiaType != 91){ // also exclude elastic to be sure... CKB?? else { globalType = 1; //non diffractive } return globalType; } //_____________________________________________________________________________ Short_t AliAnalysisTaskHighPtDeDxV0::GetDPMjetEventProcessType(Int_t dpmJetType) { // // get the process type of the event. PHOJET // //source PWG0 dNdpt // can only read pythia headers, either directly or from cocktalil header Short_t globalType = -1; if (dpmJetType == 1 || dpmJetType == 4) { // explicitly inelastic plus central diffraction globalType = 1; } else if (dpmJetType==5 || dpmJetType==6) { globalType = 2; } else if (dpmJetType==7) { globalType = 3; } return globalType; } //_____________________________________________________________________________ ULong64_t AliAnalysisTaskHighPtDeDxV0::GetEventIdAsLong(AliVHeader* header) const { // To have a unique id for each event in a run! // Modified from AliRawReader.h return ((ULong64_t)header->GetBunchCrossNumber()+ (ULong64_t)header->GetOrbitNumber()*3564+ (ULong64_t)header->GetPeriodNumber()*16777215*3564); } //____________________________________________________________________ TParticle* AliAnalysisTaskHighPtDeDxV0::FindPrimaryMother(AliStack* stack, Int_t label) { // // Finds the first mother among the primary particles of the particle identified by