/************************************************************************** * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * * Authors: Svein Lindal, Daniel Lohner * * Version 1.0 * * * * Permission to use, copy, modify and distribute this software and its * * documentation strictly for non-commercial purposes is hereby granted * * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ //////////////////////////////////////////////// //--------------------------------------------- // Class handling all kinds of selection cuts for // Gamma Conversion analysis //--------------------------------------------- //////////////////////////////////////////////// #include "AliDalitzElectronCuts.h" #include "AliAODConversionPhoton.h" #include "AliKFVertex.h" #include "AliAODTrack.h" #include "AliESDtrack.h" #include "AliAnalysisManager.h" #include "AliInputEventHandler.h" #include "AliMCEventHandler.h" #include "AliAODHandler.h" #include "AliPIDResponse.h" #include "TH1.h" #include "TH2.h" #include "AliStack.h" #include "TObjString.h" #include "AliAODEvent.h" #include "AliESDEvent.h" #include "TList.h" class iostream; using namespace std; ClassImp(AliDalitzElectronCuts) const char* AliDalitzElectronCuts::fgkCutNames[AliDalitzElectronCuts::kNCuts] = { "GoodId", "ededxSigmaITSCut", "ededxSigmaTPCCut", "pidedxSigmaTPCCut", "piMinMomdedxSigmaTPCCut", "piMaxMomdedxSigmaTPCCut", "LowPRejectionSigmaCut", "kTOFelectronPID", "clsTPCCut", "EtaCut", "PsiPair", "RejectSharedElecGamma", "BackgroundScheme", }; //________________________________________________________________________ AliDalitzElectronCuts::AliDalitzElectronCuts(const char *name,const char *title) : AliAnalysisCuts(name,title), fHistograms(NULL), fPIDResponse(NULL), fesdTrackCuts(0), fEtaCut(0.9), fRadiusCut(1000.0), fPsiPairCut(0.45), fDeltaPhiCutMin(0.), fDeltaPhiCutMax(0.12), fMinClsTPC(0), // minimum clusters in the TPC fMinClsTPCToF(0), // minimum clusters to findable clusters fDodEdxSigmaITSCut(kFALSE), fDodEdxSigmaTPCCut(kTRUE), fDoTOFsigmaCut(kFALSE), // RRnewTOF fDoRejectSharedElecGamma(kFALSE), fDoPsiPairCut(kFALSE), fPIDnSigmaAboveElectronLineITS(100), fPIDnSigmaBelowElectronLineITS(-100), fPIDnSigmaAboveElectronLineTPC(100), fPIDnSigmaBelowElectronLineTPC(-100), fPIDnSigmaAbovePionLineTPC(0), fPIDnSigmaAbovePionLineTPCHighPt(-100), fTofPIDnSigmaAboveElectronLine(100), // RRnewTOF fTofPIDnSigmaBelowElectronLine(-100), // RRnewTOF fPIDMinPnSigmaAbovePionLineTPC(0), fPIDMaxPnSigmaAbovePionLineTPC(0), fDoKaonRejectionLowP(kFALSE), fDoProtonRejectionLowP(kFALSE), fDoPionRejectionLowP(kFALSE), fPIDnSigmaAtLowPAroundKaonLine(0), fPIDnSigmaAtLowPAroundProtonLine(0), fPIDnSigmaAtLowPAroundPionLine(0), fPIDMinPKaonRejectionLowP(1.5), fPIDMinPProtonRejectionLowP(2.0), fPIDMinPPionRejectionLowP(0.5), fUseCorrectedTPCClsInfo(kFALSE), fUseTOFpid(kFALSE), fUseTrackMultiplicityForBG(kFALSE), fBKGMethod(0), fCutString(NULL), hCutIndex(NULL), hdEdxCuts(NULL), hITSdEdxbefore(NULL), hITSdEdxafter(NULL), hTPCdEdxbefore(NULL), hTPCdEdxafter(NULL), hTOFbefore(NULL), hTOFafter(NULL) { InitPIDResponse(); for(Int_t jj=0;jjSetName(Form("ElectronCuts_%s",GetCutNumber().Data())); else fHistograms->SetName(Form("%s_%s",name.Data(),GetCutNumber().Data())); } hCutIndex=new TH1F(Form("IsElectronSelected %s",GetCutNumber().Data()),"IsElectronSelected",10,-0.5,9.5); hCutIndex->GetXaxis()->SetBinLabel(kElectronIn+1,"in"); hCutIndex->GetXaxis()->SetBinLabel(kNoTracks+1,"no tracks"); hCutIndex->GetXaxis()->SetBinLabel(kTrackCuts+1,"Track cuts"); hCutIndex->GetXaxis()->SetBinLabel(kdEdxCuts+1,"dEdx"); hCutIndex->GetXaxis()->SetBinLabel(kElectronOut+1,"out"); fHistograms->Add(hCutIndex); // dEdx Cuts hdEdxCuts=new TH1F(Form("dEdxCuts %s",GetCutNumber().Data()),"dEdxCuts",10,-0.5,9.5); hdEdxCuts->GetXaxis()->SetBinLabel(1,"in"); hdEdxCuts->GetXaxis()->SetBinLabel(2,"ITSelectron"); hdEdxCuts->GetXaxis()->SetBinLabel(3,"TPCelectron"); hdEdxCuts->GetXaxis()->SetBinLabel(4,"TPCpion"); hdEdxCuts->GetXaxis()->SetBinLabel(5,"TPCpionhighp"); hdEdxCuts->GetXaxis()->SetBinLabel(6,"TPCkaonlowprej"); hdEdxCuts->GetXaxis()->SetBinLabel(7,"TPCprotonlowprej"); hdEdxCuts->GetXaxis()->SetBinLabel(8,"TPCpionlowprej"); hdEdxCuts->GetXaxis()->SetBinLabel(9,"TOFelectron"); hdEdxCuts->GetXaxis()->SetBinLabel(10,"out"); fHistograms->Add(hdEdxCuts); TAxis *AxisBeforeITS = NULL; TAxis *AxisBeforedEdx = NULL; TAxis *AxisBeforeTOF = NULL; if(preCut){ hITSdEdxbefore=new TH2F(Form("Electron_ITS_before %s",GetCutNumber().Data()),"ITS dEdx electron before" ,150,0.05,20,400,-10,10); fHistograms->Add(hITSdEdxbefore); AxisBeforeITS = hITSdEdxbefore->GetXaxis(); hTPCdEdxbefore=new TH2F(Form("Electron_dEdx_before %s",GetCutNumber().Data()),"dEdx electron before" ,150,0.05,20,400,-10,10); fHistograms->Add(hTPCdEdxbefore); AxisBeforedEdx = hTPCdEdxbefore->GetXaxis(); hTOFbefore=new TH2F(Form("Electron_TOF_before %s",GetCutNumber().Data()),"TOF electron before" ,150,0.05,20,400,-6,10); fHistograms->Add(hTOFbefore); AxisBeforeTOF = hTOFbefore->GetXaxis(); } hITSdEdxafter=new TH2F(Form("Electron_ITS_after %s",GetCutNumber().Data()),"ITS dEdx electron after" ,150,0.05,20,400, -10,10); fHistograms->Add(hITSdEdxafter); hTPCdEdxafter=new TH2F(Form("Electron_dEdx_after %s",GetCutNumber().Data()),"dEdx electron after" ,150,0.05,20,400, -10,10); fHistograms->Add(hTPCdEdxafter); hTOFafter=new TH2F(Form("Electron_TOF_after %s",GetCutNumber().Data()),"TOF electron after" ,150,0.05,20,400,-6,10); fHistograms->Add(hTOFafter); TAxis *AxisAfter = hTPCdEdxafter->GetXaxis(); Int_t bins = AxisAfter->GetNbins(); Double_t from = AxisAfter->GetXmin(); Double_t to = AxisAfter->GetXmax(); Double_t *newBins = new Double_t[bins+1]; newBins[0] = from; Double_t factor = TMath::Power(to/from, 1./bins); for(Int_t i=1; i<=bins; ++i) newBins[i] = factor * newBins[i-1]; AxisAfter->Set(bins, newBins); AxisAfter = hTOFafter->GetXaxis(); AxisAfter->Set(bins, newBins); AxisAfter = hITSdEdxafter->GetXaxis(); AxisAfter->Set(bins, newBins); if(preCut){ AxisBeforeITS->Set(bins, newBins); AxisBeforedEdx->Set(bins, newBins); AxisBeforeTOF->Set(bins, newBins); } delete [] newBins; // Event Cuts and Info } //________________________________________________________________________ Bool_t AliDalitzElectronCuts::InitPIDResponse(){ // Set Pointer to AliPIDResponse AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager(); if(man) { AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler()); fPIDResponse = (AliPIDResponse*)inputHandler->GetPIDResponse(); if(fPIDResponse)return kTRUE; } return kFALSE; } ///________________________________________________________________________ Bool_t AliDalitzElectronCuts::ElectronIsSelected(AliESDtrack* lTrack) { //Selection of Reconstructed electrons if(hCutIndex)hCutIndex->Fill(kElectronIn); if ( ! lTrack->GetConstrainedParam() ){ return kFALSE; } if( ! lTrack ) { if(hCutIndex)hCutIndex->Fill(kNoTracks); return kFALSE; } AliVTrack * track = dynamic_cast(lTrack); // Track Cuts if( !TrackIsSelected(lTrack) ){ if(hCutIndex)hCutIndex->Fill(kTrackCuts); return kFALSE; } // dEdx Cuts if( ! dEdxCuts( track ) ) { if(hCutIndex)hCutIndex->Fill(kdEdxCuts); return kFALSE; } //Electron passed the cuts if(hCutIndex)hCutIndex->Fill(kElectronOut); return kTRUE; } ///________________________________________________________________________ Bool_t AliDalitzElectronCuts::TrackIsSelected(AliESDtrack* lTrack) { // Track Selection for Photon Reconstruction if( ! fesdTrackCuts->AcceptTrack(lTrack) ){ return kFALSE; } if( TMath::Abs( lTrack->Eta()) > fEtaCut ) { return kFALSE; } if( lTrack->GetNcls(1) < fMinClsTPC ) { return kFALSE; } //Findable clusters Double_t clsToF=0; if (!fUseCorrectedTPCClsInfo ){ if(lTrack->GetTPCNclsF()!=0){ clsToF = (Double_t)lTrack->GetNcls(1)/(Double_t)lTrack->GetTPCNclsF(); }// Ncluster/Nfindablecluster } else { //clsToF = lTrack->GetTPCClusterInfo(2,0,GetFirstTPCRow(photon->GetConversionRadius())); clsToF = lTrack->GetTPCClusterInfo(2,1); //NOTE ask friederike } if( clsToF < fMinClsTPCToF){ return kFALSE; } return kTRUE; } ///________________________________________________________________________ Bool_t AliDalitzElectronCuts::dEdxCuts(AliVTrack *fCurrentTrack){ // Electron Identification Cuts for Photon reconstruction if(!fPIDResponse){ InitPIDResponse(); }// Try to reinitialize PID Response if(!fPIDResponse){ AliError("No PID Response"); return kFALSE;}// if still missing fatal error //cout<<"dEdxCuts: //////////////////////////////////////////////////////////////////////////"<Fill(cutIndex); if(hITSdEdxbefore)hITSdEdxbefore->Fill(fCurrentTrack->P(),fPIDResponse->NumberOfSigmasITS(fCurrentTrack, AliPID::kElectron)); if(hTPCdEdxbefore)hTPCdEdxbefore->Fill(fCurrentTrack->P(),fPIDResponse->NumberOfSigmasTPC(fCurrentTrack, AliPID::kElectron)); cutIndex++; if( fDodEdxSigmaITSCut == kTRUE ){ if( fPIDResponse->NumberOfSigmasITS(fCurrentTrack,AliPID::kElectron)NumberOfSigmasITS(fCurrentTrack,AliPID::kElectron)> fPIDnSigmaAboveElectronLineITS ){ if(hdEdxCuts)hdEdxCuts->Fill(cutIndex); return kFALSE; } } if(hITSdEdxafter)hITSdEdxafter->Fill(fCurrentTrack->P(),fPIDResponse->NumberOfSigmasITS(fCurrentTrack, AliPID::kElectron)); cutIndex++; if(fDodEdxSigmaTPCCut == kTRUE){ // TPC Electron Line if( fPIDResponse->NumberOfSigmasTPC(fCurrentTrack,AliPID::kElectron)NumberOfSigmasTPC(fCurrentTrack,AliPID::kElectron)>fPIDnSigmaAboveElectronLineTPC){ if(hdEdxCuts)hdEdxCuts->Fill(cutIndex); return kFALSE; } cutIndex++; // TPC Pion Line if( fCurrentTrack->P()>fPIDMinPnSigmaAbovePionLineTPC && fCurrentTrack->P()NumberOfSigmasTPC(fCurrentTrack,AliPID::kElectron)>fPIDnSigmaBelowElectronLineTPC && fPIDResponse->NumberOfSigmasTPC(fCurrentTrack,AliPID::kElectron)NumberOfSigmasTPC(fCurrentTrack,AliPID::kPion)Fill(cutIndex); return kFALSE; } } cutIndex++; // High Pt Pion rej if( fCurrentTrack->P()>fPIDMaxPnSigmaAbovePionLineTPC ){ if(fPIDResponse->NumberOfSigmasTPC(fCurrentTrack,AliPID::kElectron)>fPIDnSigmaBelowElectronLineTPC && fPIDResponse->NumberOfSigmasTPC(fCurrentTrack,AliPID::kElectron)NumberOfSigmasTPC(fCurrentTrack,AliPID::kPion)Fill(cutIndex); return kFALSE; } } cutIndex++; } else{ cutIndex+=3; } if( fDoKaonRejectionLowP == kTRUE ){ if( fCurrentTrack->P() < fPIDMinPKaonRejectionLowP ){ if( TMath::Abs(fPIDResponse->NumberOfSigmasTPC(fCurrentTrack,AliPID::kKaon))Fill(cutIndex); return kFALSE; } } } cutIndex++; if( fDoProtonRejectionLowP == kTRUE ){ if( fCurrentTrack->P() < fPIDMinPProtonRejectionLowP ){ if( TMath::Abs( fPIDResponse->NumberOfSigmasTPC(fCurrentTrack,AliPID::kProton))Fill(cutIndex); return kFALSE; } } } cutIndex++; if(fDoPionRejectionLowP == kTRUE){ if( fCurrentTrack->P() < fPIDMinPPionRejectionLowP ){ if( TMath::Abs( fPIDResponse->NumberOfSigmasTPC(fCurrentTrack,AliPID::kPion)) < fPIDnSigmaAtLowPAroundPionLine ){ if(hdEdxCuts)hdEdxCuts->Fill(cutIndex); return kFALSE; } } } cutIndex++; if((fCurrentTrack->GetStatus() & AliESDtrack::kTOFpid) && !(fCurrentTrack->GetStatus() & AliESDtrack::kTOFmismatch)){ if(hTOFbefore) hTOFbefore->Fill(fCurrentTrack->P(),fPIDResponse->NumberOfSigmasTOF(fCurrentTrack, AliPID::kElectron)); if(fUseTOFpid){ if(fPIDResponse->NumberOfSigmasTOF(fCurrentTrack, AliPID::kElectron)>fTofPIDnSigmaAboveElectronLine || fPIDResponse->NumberOfSigmasTOF(fCurrentTrack, AliPID::kElectron)Fill(cutIndex); return kFALSE; } } if(hTOFafter)hTOFafter->Fill(fCurrentTrack->P(),fPIDResponse->NumberOfSigmasTOF(fCurrentTrack, AliPID::kElectron)); } cutIndex++; if(hdEdxCuts)hdEdxCuts->Fill(cutIndex); if(hTPCdEdxafter)hTPCdEdxafter->Fill(fCurrentTrack->P(),fPIDResponse->NumberOfSigmasTPC(fCurrentTrack, AliPID::kElectron)); return kTRUE; } ///________________________________________________________________________ AliVTrack *AliDalitzElectronCuts::GetTrack(AliVEvent * event, Int_t label){ //Returns pointer to the track with given ESD label //(Important for AOD implementation, since Track array in AOD data is different //from ESD array, but ESD tracklabels are stored in AOD Tracks) AliESDEvent * esdEvent = dynamic_cast(event); if(esdEvent) { if(label > event->GetNumberOfTracks() ) return NULL; AliESDtrack * track = esdEvent->GetTrack(label); return track; } else { for(Int_t ii=0; iiGetNumberOfTracks(); ii++) { AliVTrack * track = dynamic_cast(event->GetTrack(ii)); if(track) { if(track->GetID() == label) { return track; } } } } cout << "track not found " << label << " " << event->GetNumberOfTracks() << endl; return NULL; } ///________________________________________________________________________ Bool_t AliDalitzElectronCuts::RejectSharedElecGamma(TList *photons, Int_t indexEle){ for(Int_t i = 0;iGetEntries();i++){ AliAODConversionPhoton *photonComp = (AliAODConversionPhoton*) photons->At(i); Int_t posLabel = photonComp->GetTrackLabelPositive(); Int_t negLabel = photonComp->GetTrackLabelNegative(); if( (photonComp->GetConversionRadius() < fRadiusCut) && (posLabel == indexEle || negLabel == indexEle) ){ return kFALSE; } } return kTRUE; } Double_t AliDalitzElectronCuts::GetPsiPair( const AliESDtrack* trackPos, const AliESDtrack* trackNeg ) const { // // This angle is a measure for the contribution of the opening in polar // direction Δ0 to the opening angle ξ Pair // // Ref. Measurement of photons via conversion pairs with the PHENIX experiment at RHIC // Master Thesis. Thorsten Dahms. 2005 // https://twiki.cern.ch/twiki/pub/ALICE/GammaPhysicsPublications/tdahms_thesis.pdf // Double_t momPos[3]; Double_t momNeg[3]; if( trackPos->GetConstrainedPxPyPz(momPos) == 0 ) trackPos->GetPxPyPz( momPos ); if( trackNeg->GetConstrainedPxPyPz(momNeg) == 0 ) trackNeg->GetPxPyPz( momNeg ); TVector3 posDaughter; TVector3 negDaughter; posDaughter.SetXYZ( momPos[0], momPos[1], momPos[2] ); negDaughter.SetXYZ( momNeg[0], momNeg[1], momNeg[2] ); Double_t deltaTheta = negDaughter.Theta() - posDaughter.Theta(); Double_t openingAngle = posDaughter.Angle( negDaughter ); //TMath::ACos( posDaughter.Dot(negDaughter)/(negDaughter.Mag()*posDaughter.Mag()) ); if( openingAngle < 1e-20 ) return 0.; Double_t psiAngle = TMath::ASin( deltaTheta/openingAngle ); return psiAngle; } Bool_t AliDalitzElectronCuts::IsFromGammaConversion( Double_t psiPair, Double_t deltaPhi ) const { // // Returns true if it is a gamma conversion according to psi pair value // return ( (deltaPhi > fDeltaPhiCutMin && deltaPhi < fDeltaPhiCutMax) && TMath::Abs(psiPair) < ( fPsiPairCut - fPsiPairCut/fDeltaPhiCutMax * deltaPhi ) ); } ///________________________________________________________________________ Bool_t AliDalitzElectronCuts::UpdateCutString(cutIds cutID, Int_t value) { ///Update the cut string (if it has been created yet) if(fCutString && fCutString->GetString().Length() == kNCuts) { cout << "Updating cut id in spot number " << cutID << " to " << value << endl; fCutString->SetString(GetCutNumber()); } else { cout << "fCutString not yet initialized, will not be updated" << endl; return kFALSE; } // cout << fCutString->GetString().Data() << endl; return kTRUE; } ///________________________________________________________________________ Bool_t AliDalitzElectronCuts::InitializeCutsFromCutString(const TString analysisCutSelection ) { // Initialize Cuts from a given Cut string cout<<"Set Cut Number: "<InitializeCutsFromCutString("9069640364102")){ cout<<"Warning: Initialization of Standardcuts2010PbPb failed"<InitializeCutsFromCutString("9069640364102")){ cout<<"Warning: Initialization of Standardcuts2010pp failed"<