#include "StFemtoDstInclusiveSelector.h" #include "StBTofHeader.h" #include "TBranch.h" #include "StPhysicalHelixD.hh" ClassImp(StFemtoDstInclusiveSelector) // Set maximum file size to 1.9 GB (Root has a 2GB limit) #define MAXFILESIZE 1900000000 //_________________ StFemtoDstInclusiveSelector::StFemtoDstInclusiveSelector(StMuDstMaker *muMaker, const Char_t *oFileName) { std::cout << "StFemtoDstInclusiveSelector::Constructor - Creating an instance..."; mOutFileName = oFileName; mMuDstMaker = muMaker; mMuDst = mMuDstMaker->muDst(); mRefMultCorrUtil = NULL; mCompression = 9; mCollisionTypeAuAu = false; // pp: false; AuAu: true mLoopAllVert = false; // Not first primary vertex does not contain tracks with fast detectors (TOF) mEventIsGood = false; mNEventsIn = 0; mNEventsPassed = 0; mAuAuCorrectZdc = true; mIsGoodTrack = false; mCurrentTrigger = 0; //Initialize event cut variables mPrimVtxZ[0] = -70.; mPrimVtxZ[1] = 70.; mPrimVtxR[0] = -1.; mPrimVtxR[1] = 10.; mPrimVtxVpdVzDiff[0] = -5.; mPrimVtxVpdVzDiff[1]= 5.; mPrimVtxXShift = 0.; mPrimVtxYShift = 0.; //Initialize single-particle cut variables mTrackMomentum[0] = 0.1; mTrackMomentum[1] = 1.7; mTrackDca[0] = 0.; mTrackDca[1] = 5.; mTrackDcaGlobal[0] = 0.; mTrackDcaGlobal[1] = 5.; mTrackNHits[0] = 14; mTrackNHits[1] = 50; mTrackEta[0] = -1.; mTrackEta[1] = 1.; mTrackFlag[0] = 0; mTrackFlag[1] = 1000; mSelectPions = true; mSelectTpcPions = true; mPionTpcMomentum[0] = 0.15; mPionTpcMomentum[1] = 0.65; mPionTpcNSigmaElectron[0]= -2.; mPionTpcNSigmaElectron[1]= 2.; mPionTpcNSigmaPion[0]= -3.; mPionTpcNSigmaPion[1]= 3.; mPionTpcNSigmaKaon[0]= -1.5; mPionTpcNSigmaKaon[1]= 1.5; mPionTpcNSigmaProton[0]= -3.; mPionTpcNSigmaProton[1]= 3.; mSelectTofPions = true; mPionTofMomentum[0] = 0.15; mPionTofMomentum[1] = 1.75; mPionMassSqr[0] = -0.01; mPionMassSqr[1] = 0.09; mSelectKaons = true; mSelectTpcKaons = true; mKaonTpcMomentum[0] = 0.15; mKaonTpcMomentum[1] = 0.65; mKaonTpcNSigmaElectron[0]= -2.; mKaonTpcNSigmaElectron[1]= 2.; mKaonTpcNSigmaPion[0]= -1.5; mKaonTpcNSigmaPion[1]= 1.5; mKaonTpcNSigmaKaon[0]= -3.; mKaonTpcNSigmaKaon[1]= 3.; mKaonTpcNSigmaProton[0]= -3.; mKaonTpcNSigmaProton[1]= 3.; mSelectTofKaons = true; mKaonTofMomentum[0] = 0.15; mKaonTofMomentum[1] = 1.75; mKaonMassSqr[0] = 0.16; mKaonMassSqr[1] = 0.35; mSelectProtons = false; mSelectTpcProtons = true; mProtonTpcMomentum[0] = 0.15; mProtonTpcMomentum[1] = 1.2; mProtonTpcNSigmaElectron[0]= -3.; mProtonTpcNSigmaElectron[1]= 3.; mProtonTpcNSigmaPion[0]= -3.; mProtonTpcNSigmaPion[1]= 3.; mProtonTpcNSigmaKaon[0]= -3.; mProtonTpcNSigmaKaon[1]= 3.; mProtonTpcNSigmaProton[0]= -3.; mProtonTpcNSigmaProton[1]= 3.; mSelectTofProtons = true; mProtonTofMomentum[0] = 0.15; mProtonTofMomentum[1] = 1.75; mProtonMassSqr[0] = 0.65; mProtonMassSqr[1] = 1.05; std::cout << "\t[DONE]" << std::endl; } //_________________ StFemtoDstInclusiveSelector::~StFemtoDstInclusiveSelector() { /* do nothing */ } //_________________ Int_t StFemtoDstInclusiveSelector::Init() { std::cout << "StFemtoDstInclusiveSelector::Init - Initializing the maker" << std::endl << "Creating output file: " << mOutFileName; mFemtoEvent = new StFemtoEvent(); mOutFile = new TFile(mOutFileName, "RECREATE"); mOutFile->SetCompressionLevel(mCompression); std::cout << "\t[DONE]" << std::endl; mTree = new TTree("StFemtoDst","StFemtoDst"); mTree->SetMaxTreeSize(MAXFILESIZE); //mTree->SetAutoSave(1000000); mTree->Branch("StFemtoEvent","StFemtoEvent", &mFemtoEvent); if(mCollisionTypeAuAu) { //For AuAu only if(!mRefMultCorrUtil) { std::cout << "StFemtoDstInclusiveSelector::Init - Initializing StRefMultCorr..."; mRefMultCorrUtil = new StRefMultCorr("refmult"); std::cout << "\t[DONE]" << endl; } } mNBytes = 0; std::cout << "StFemtoDstInclusiveSelector::Init - Initialization has been finished" << std::endl; return StMaker::Init(); } //_________________ void StFemtoDstInclusiveSelector::Clear(Option_t *option) { StMaker::Clear(option); } //_________________ Int_t StFemtoDstInclusiveSelector::Make() { // Get MuEvent from the MuDst mNEventsIn++; StMuEvent *mMuEvent = mMuDst->event(); if (!AcceptTrigger(mMuEvent)) { // If trigger the trigger was not found return kStOk; } if (mMuEvent->refMult() < 0) { // Multiplicity can't be negative return kStOk; } UShort_t mNVertices = mLoopAllVert ? mMuDst->numberOfPrimaryVertices() : 1; Short_t mNPrimTracks = mMuDst->numberOfPrimaryTracks(); Short_t mNGlobTracks = mMuDst->numberOfGlobalTracks(); //Reasonable amount of tracks if (mNPrimTracks < 0 || mNPrimTracks > 10000) { return kStOk; } Bool_t mEventIsGood = false; Float_t mVpdVz = 0.; StBTofHeader *mTofHeader = mMuDst->btofHeader(); // Centrality variables Int_t mCent16; Double_t mCentWeight, mRefMultCorrVal; // If pp collisions if (!mCollisionTypeAuAu) { mCent16 = -1; mCentWeight = -999.; } Float_t mRanking = 0; StMuPrimaryVertex *mPrimVertex = NULL; StMuTrack *mPrimTrack = NULL; StMuTrack *mGlobTrack = NULL; Float_t mMassSqr = -999.; Float_t mBeta = -999.; Bool_t mIsTofTrack = false; Bool_t mIsTpcPion = false; Bool_t mIsTofPion = false; Bool_t mIsTpcKaon = false; Bool_t mIsTofKaon = false; Bool_t mIsTpcProton = false; Bool_t mIsTofProton = false; //Calculate the amount of the pile-up vertices UShort_t mNVtxInBunchCross = 0; for(UShort_t iVert=0; iVertnumberOfPrimaryVertices(); iVert++) { mPrimVertex = mMuDst->primaryVertex(iVert); if(!mPrimVertex || !mTofHeader) continue; if(mPrimVertex->ranking() <= 0.) continue; if(TMath::Abs(mPrimVertex->position().x()) < 1e-5 && TMath::Abs(mPrimVertex->position().y()) < 1e-5 && TMath::Abs(mPrimVertex->position().z()) < 1e-5) { continue; } if(TMath::Abs( mPrimVertex->position().z() - mTofHeader->vpdVz()) < 5. ) { mNVtxInBunchCross++; } } //for(unsigned short iVert=0; iVert 1) { return kStOk; } // Vertex loop for (UShort_t iVert = 0; iVert < mNVertices; iVert++) { mEventIsGood = false; mPrimVertex = mMuDst->primaryVertex(iVert); if (!mPrimVertex) { //std::cout << "No primary vertices in the event. Skip..." << std::endl; continue; } mRanking = mPrimVertex->ranking(); //Positive ranking only if (mPrimVertex->ranking() <= 0) continue; //Not (0,0,0) position of the primary vertex if (TMath::Abs(mPrimVertex->position().x()) < 1e-5 && TMath::Abs(mPrimVertex->position().y()) < 1e-5 && TMath::Abs(mPrimVertex->position().z()) < 1e-5 ) continue; StThreeVectorF mVertPosition = mPrimVertex->position(); if(mTofHeader) { //In case of the absence of the vpd information mVpdVz = mTofHeader->vpdVz(); } else { mVpdVz = mVertPosition.z(); } // Event cut if (!AcceptPrimVtx(mVertPosition, mVpdVz)) continue; mEventIsGood = true; // Set StRefMultCorr if (mCollisionTypeAuAu) { // Only for AuAu collisions mRefMultCorrUtil->init(mMuEvent->runId()); //Check for the bad run if (mRefMultCorrUtil->isBadRun(mMuEvent->runId())) { std::cout << "StRefMultCorrUtil::IsBadRun" << std::endl; continue; } if (mAuAuCorrectZdc == true) { mRefMultCorrUtil->initEvent(mMuEvent->refMult(), mVertPosition.z(), mMuEvent->runInfo().zdcCoincidenceRate()); } else { mRefMultCorrUtil->initEvent(mMuEvent->refMult(), mVertPosition.z()); } mCent16 = mRefMultCorrUtil->getCentralityBin16(); if (mCent16 < 0) continue; //Some AuAu collisions have -1 value mCentWeight = mRefMultCorrUtil->getWeight(); mRefMultCorrVal = mRefMultCorrUtil->getRefMultCorr(); } // Write event information to the FemtoDst mNEventsPassed++; mFemtoEvent->SetEventId( mMuEvent->eventId() ); mFemtoEvent->SetRunId( mMuEvent->runId() ); mFemtoEvent->SetCollisionType( mCollisionTypeAuAu ); mFemtoEvent->SetRefMult( mMuEvent->refMult() ); mFemtoEvent->SetRefMultCorr( mRefMultCorrVal ); mFemtoEvent->SetRefMultCorrWeight( mCentWeight ); mFemtoEvent->SetCent16( mCent16 ); mFemtoEvent->SetRefMultPos( mMuEvent->refMultPos() ); mFemtoEvent->SetNumberOfBTofHit( mMuDst->numberOfBTofHit() ); //mMuEvent->btofTrayMultiplicity() ); //mFemtoEvent->SetZDCe( mMuEvent->zdcTriggerDetector().adc(4) ); //mFemtoEvent->SetZDCw( mMuEvent->zdcTriggerDetector().adc(0) ); mFemtoEvent->SetNumberOfPrimaryTracks( mNPrimTracks ); mFemtoEvent->SetNumberOfGlobalTracks( mNGlobTracks ); mFemtoEvent->SetMagneticField( mMuEvent->magneticField() ); mFemtoEvent->SetPrimaryVertexPosition( mVertPosition.x(), mVertPosition.y(), mVertPosition.z() ); mFemtoEvent->SetVpdVz(mVpdVz); mFemtoEvent->SetTriggerId(mCurrentTrigger); mFemtoEvent->SetPrimaryVertexRanking(mRanking); UInt_t refMult2 = 0; UInt_t refMult2Pos = 0; //Primary track loop for(UShort_t iTrk = 0; iTrk < mNPrimTracks; iTrk++) { mPrimTrack = mMuDst->primaryTracks(iTrk); mGlobTrack = mMuDst->globalTracks(mPrimTrack->index2Global()); //RefMult2 calculation if ( AcceptRefMult2(mPrimTrack) ) { refMult2++; if(mPrimTrack->charge() > 0) refMult2Pos++; } //Track cut if ( !AcceptTrack(mPrimTrack, iVert) ) continue; mIsTofTrack = false; mIsTofTrack = IsTofTrack(mGlobTrack); mIsTpcPion = false; mIsTofPion = false; mIsTpcKaon = false; mIsTofKaon = false; mIsTpcProton = false; mIsTofProton = false; mBeta = -999.; mMassSqr = -999.; // Check if track has ToF signal if(mIsTofTrack) { mBeta = mGlobTrack->btofPidTraits().beta(); mMassSqr = mPrimTrack->momentum().mag2() * ( 1./(mBeta * mBeta) - 1.); } // Pion selection if (mSelectPions) { if (mSelectTpcPions) mIsTpcPion = IsTpcPion(mPrimTrack); if (mSelectTofPions && mIsTofTrack) mIsTofPion = IsTofPion(mMassSqr, mGlobTrack->p().mag()); } // Kaon selection if (mSelectKaons) { if (mSelectTpcKaons) mIsTpcKaon = IsTpcKaon(mPrimTrack); if (mSelectTofKaons && mIsTofTrack) mIsTofKaon = IsTofKaon(mMassSqr, mGlobTrack->p().mag()); } // Proton selection if (mSelectProtons) { if (mSelectTpcProtons) mIsTpcProton = IsTpcProton(mPrimTrack); if (mSelectTofProtons && mIsTofTrack) mIsTofProton = IsTofProton(mMassSqr, mGlobTrack->p().mag()); } // Write StFemtoTrack if (mIsTpcPion || mIsTofPion || mIsTpcKaon || mIsTofKaon || mIsTpcProton || mIsTofProton) { mFTrack = mFemtoEvent->AddFemtoTrack(); mFTrack->SetId( mPrimTrack->id() ); mFTrack->SetNHits( (Char_t)(mPrimTrack->charge()*mPrimTrack->nHits()) ); mFTrack->SetNHitsPoss( mPrimTrack->nHitsPoss(kTpcId) ); //mFTrack->SetNHitsDedx( mPrimTrack->nHitsDedx() ); mFTrack->SetNSigmaElectron( mPrimTrack->nSigmaElectron() ); mFTrack->SetNSigmaPion( mPrimTrack->nSigmaPion() ); mFTrack->SetNSigmaKaon( mPrimTrack->nSigmaKaon() ); mFTrack->SetNSigmaProton( mPrimTrack->nSigmaProton() ); mFTrack->SetDedx( mPrimTrack->dEdx() ); //mFTrack->SetChi2( mPrimTrack->chi2() ); mFTrack->SetMap0( mGlobTrack->topologyMap().data(0) ); mFTrack->SetMap1( mGlobTrack->topologyMap().data(1) ); mFTrack->SetP( mPrimTrack->momentum().x(), mPrimTrack->momentum().y(), mPrimTrack->momentum().z() ); mFTrack->SetDCAxGlobal( mPrimTrack->dcaGlobal().x() ); mFTrack->SetDCAyGlobal( mPrimTrack->dcaGlobal().y() ); mFTrack->SetDCAzGlobal( mPrimTrack->dcaGlobal().z() ); mFTrack->SetGlobalP( mGlobTrack->p().x(), mGlobTrack->p().y(), mGlobTrack->p().z() ); if(mIsTofTrack) { mFTrack->SetBeta( mBeta ); } else { mFTrack->SetBeta( -999. ); } } } //for(Int_t iTrk = 0; iTrk < mNPrimTracks; iTrk++) //Store RefMult2 mFemtoEvent->SetRefMult2(refMult2); mFemtoEvent->SetRefMult2Pos(refMult2Pos); // // If event is good then write it // if(mEventIsGood) { mNBytes += mTree->Fill(); mFemtoEvent->Clear(); } } //(Int_t iVert = 0; iVert < mNVertices; iVert++) return kStOk; } //_________________ Bool_t StFemtoDstInclusiveSelector::AcceptRefMult2(StMuTrack *trk) { Bool_t mIsGoodTrack = false; if ( trk->flag()> 0 && trk->charge() != 0 && trk->nHitsFit() >= 10 && trk->dca().mag() < 3.0 && trk->momentum().mag() >= 1e-10 && TMath::Abs(trk->eta()) <= 1.0) { mIsGoodTrack = true; } return mIsGoodTrack; } //_________________ Bool_t StFemtoDstInclusiveSelector::AcceptTrigger(StMuEvent *muEvent) { //We will store the bit mask for the list of triggers. //The list of triggers should be the same and in the same //order, in order to read it later Bool_t mIsGoodTrigger = false; mCurrentTrigger = 0; if(mTriggerIdCollection.empty()) { mIsGoodTrigger = true; } else { for (UInt_t iTrg = 0; iTrg < mTriggerIdCollection.size(); iTrg++) { if(muEvent->triggerIdCollection().nominal().isTrigger(mTriggerIdCollection.at(iTrg))) { mIsGoodTrigger = true; mCurrentTrigger |= (1<= mPrimVtxZ[0] && vtxPos.z() <= mPrimVtxZ[1] && vtxR >= mPrimVtxR[0] && vtxR <= mPrimVtxR[1] && vpdDiff >= mPrimVtxVpdVzDiff[0] && vpdDiff <= mPrimVtxVpdVzDiff[1]) { mIsGoodVtx = true; } return mIsGoodVtx; } //_________________ Bool_t StFemtoDstInclusiveSelector::AcceptTrack(StMuTrack *trk, UShort_t vtxInd) { Bool_t mIsGoodTrack = false; if( trk->vertexIndex() == vtxInd && trk->momentum().mag() >= mTrackMomentum[0] && trk->momentum().mag() <= mTrackMomentum[1] && trk->type() == 1 && trk->eta() >= mTrackEta[0] && trk->eta() <= mTrackEta[1] && trk->nHits() >= mTrackNHits[0] && trk->nHits() <= mTrackNHits[1] && trk->flag() >= mTrackFlag[0] && trk->flag() <= mTrackFlag[1] && trk->dca(vtxInd).perp() >= mTrackDca[0] && trk->dca(vtxInd).perp() <= mTrackDca[1] && trk->dcaGlobal(vtxInd).perp() >= mTrackDcaGlobal[0] && trk->dcaGlobal(vtxInd).perp() <= mTrackDcaGlobal[1]) { mIsGoodTrack = true; } return mIsGoodTrack; } //_________________ Bool_t StFemtoDstInclusiveSelector::IsTofTrack(StMuTrack *trk) { //Only for globals Bool_t mIsTofHit = false; if(trk->btofPidTraits().beta() > 0 && trk->btofPidTraits().timeOfFlight() > 0) { mIsTofHit = true; } return mIsTofHit; } //_________________ Int_t StFemtoDstInclusiveSelector::Finish() { mOutFile->cd(); mOutFile->Write(); //mTree->Write(); mOutFile->Close(); delete mTree; delete mOutFile; std::cout << "*********************************************" << std::endl << "StFemtoDstInclusiveSelector has been finished" << std::endl << "\t nEventsPassed : " << mNEventsPassed << std::endl << "\t nEventsProcessed: " << mNEventsIn << std::endl << "**********************************************" << std::endl; return kStOk; } //_________________ Bool_t StFemtoDstInclusiveSelector::IsTpcPion(StMuTrack *pTrk) { Float_t p = pTrk->p().mag(); Float_t nSElectron = pTrk->nSigmaElectron(); Float_t nSPion = pTrk->nSigmaPion(); Float_t nSKaon = pTrk->nSigmaKaon(); Float_t nSProton = pTrk->nSigmaProton(); return ( (p >= mPionTpcMomentum[0]) && (p <= mPionTpcMomentum[1]) && ( (nSPion >= mPionTpcNSigmaPion[0]) && (nSPion <= mPionTpcNSigmaPion[1]) ) && ( (nSElectron <= mPionTpcNSigmaElectron[0]) || (nSElectron >= mPionTpcNSigmaElectron[1])) && ( (nSKaon <= mPionTpcNSigmaKaon[0]) || (nSKaon >= mPionTpcNSigmaKaon[1]) ) && ( (nSProton <= mPionTpcNSigmaProton[0]) || (nSProton >= mPionTpcNSigmaProton[1]) ) ); } //_________________ Bool_t StFemtoDstInclusiveSelector::IsTpcKaon(StMuTrack *pTrk) { Float_t p = pTrk->p().mag(); Float_t nSElectron = pTrk->nSigmaElectron(); Float_t nSPion = pTrk->nSigmaPion(); Float_t nSKaon = pTrk->nSigmaKaon(); Float_t nSProton = pTrk->nSigmaProton(); return ( (p >= mKaonTpcMomentum[0]) && (p <= mKaonTpcMomentum[1]) && ( (nSKaon >= mKaonTpcNSigmaKaon[0]) && (nSKaon <= mKaonTpcNSigmaKaon[1]) ) && ( (nSElectron <= mKaonTpcNSigmaElectron[0]) || (nSElectron >= mKaonTpcNSigmaElectron[1]) ) && ( (nSPion <= mKaonTpcNSigmaPion[0]) || (nSPion >= mKaonTpcNSigmaPion[1]) ) && ( (nSProton <= mKaonTpcNSigmaProton[0]) || (nSProton >= mKaonTpcNSigmaProton[1]) ) ); } //_________________ Bool_t StFemtoDstInclusiveSelector::IsTpcProton(StMuTrack *pTrk) { Float_t p = pTrk->p().mag(); Float_t nSElectron = pTrk->nSigmaElectron(); Float_t nSPion = pTrk->nSigmaPion(); Float_t nSKaon = pTrk->nSigmaKaon(); Float_t nSProton = pTrk->nSigmaProton(); return ( (p >= mProtonTpcMomentum[0]) && (p <= mProtonTpcMomentum[1]) && ( (nSProton >= mProtonTpcNSigmaProton[0]) && (nSProton <= mProtonTpcNSigmaProton[1]) ) && ( (nSElectron <= mProtonTpcNSigmaElectron[0]) || (nSElectron >= mProtonTpcNSigmaElectron[1]) ) && ( (nSPion <= mProtonTpcNSigmaPion[0]) || (nSPion >= mProtonTpcNSigmaPion[1]) ) && ( (nSKaon <= mProtonTpcNSigmaKaon[0]) || (nSKaon >= mProtonTpcNSigmaKaon[1]) ) ); } //_________________ Bool_t StFemtoDstInclusiveSelector::IsTofPion(Float_t mSqr, Float_t p) { return ( (p >= mPionTofMomentum[0]) && (p <= mPionTofMomentum[1]) && (mSqr >= mPionMassSqr[0]) && (mSqr <= mPionMassSqr[1]) ); } //_________________ Bool_t StFemtoDstInclusiveSelector::IsTofKaon(Float_t mSqr, Float_t p) { return ( (p >= mKaonTofMomentum[0]) && (p <= mKaonTofMomentum[1]) && (mSqr >= mKaonMassSqr[0]) && (mSqr <= mKaonMassSqr[1]) ); } //_________________ Bool_t StFemtoDstInclusiveSelector::IsTofProton(Float_t mSqr, Float_t p) { return ( (p >= mProtonTofMomentum[0]) && (p <= mProtonTofMomentum[1]) && (mSqr >= mProtonMassSqr[0]) && (mSqr <= mProtonMassSqr[1]) ); } //_________________ void StFemtoDstInclusiveSelector::AddTriggerId(const UInt_t& id) { mTriggerIdCollection.push_back(id); }