void exampleStMuIOMaker(const char* file="/star/data14/reco/productionCentral/ReversedFullField/P02ge/2001/324/st_physics_2324001_raw_0006.MuDst.root") { gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); loadSharedLibraries(); StMuDebug::setLevel(0); int counter=0; int iret=0; StMuIOMaker* maker = new StMuIOMaker("MuDst"); maker->SetFileAndOpen(file); // maker->SetFileName("st_physics_2313018_raw_0029.MuDst.root"); TMemStat memStat("exampleMuIO"); StMuDst* mu; // evtid is an unique id of an event in a run which may involve several files! // it is different from sequential index in a run which starts from "0"! // for ( int evtid=80673; evtid<80694; evtid++) { // for ( int evtid=6300; evtid<6321; evtid++) { // iret = maker->Make( StUKey(2271008,evtid) ); // iret = maker->Make( StUKey(2313018,evtid) ); // alterative for ( int i=0; i<20; i++) { // iret = maker->Make(); // read an event in natural sequential iret = maker->Make(i); // read an event with seqential index if ( iret == kStOK) { StMuDst* mu = maker->muDst(); if ( !mu ) continue; // if(i%10 != 0) continue; // take a look at branches of tracks int n; n= mu->globalTracks()->GetEntries(); for (int l=0; l<n; l++) globalPt.Fill(mu->globalTracks(l)->pt()); n= mu->primaryTracks()->GetEntries(); for (int l=0; l<n; l++) primaryPt.Fill(mu->primaryTracks(l)->pt()); n= mu->l3Tracks()->GetEntries(); for (int l=0; l<n; l++) {l3Pt.Fill( mu->l3Tracks(l)->pt() );} // take a look at event branch StMuEvent* muEvent = mu->event(); int referenceMultiplicity = muEvent->refMult(); refMult.Fill(referenceMultiplicity); cout << "#" << i << " index=" << maker->currentIndex() // cout << "eventId =" << evtid << " index=" << maker->currentIndex() << " refmult= "<< referenceMultiplicity << " used= "<< memStat.Used() << " size= "<< memStat.ProgSize() << endl; counter++; } } cout << " # of events:" << counter << endl; globalPt.Draw(); primaryPt.Draw("same"); l3Pt.Draw("same"); TFile f("testMuIO.root","RECREATE"); globalPt.Write(); primaryPt.Write(); l3Pt.Write(); refMult.Write(); f.Close(); }
/** * 1. Data sample : pp200 W->e nu with pile-up corresponding to 1 MHz min. bias * events, 50 K event y2011, 10 K event y2012. * * 2. Proof of principal: no pile-up for both PPV and KFV * * a. Reconstructed primary track multiplicity versus corresponding MC * "reconstructable" (i.e. in n STAR acceptance,no. TPC MC hits >= 15) tracks * multiplicity. * * b. Corrected reconstructed primary track multiplicity (i.e. multiplied by * QA/100.) versus corresponding MC "reconstructable" (i.e. in n STAR * acceptance,no. TPC MC hits >= 15) tracks multiplicity. * * c. Efficiency primary vertex reconstruction versus MC "reconstructable" * tracks multiplicity. * * 3. With pileup. repeat above (a-c) with old ranking scheme for * * I. Any reconstructed primary vertex which is matched with MC trigger * vertex (MC = 1) * * II. The best (in sense of ranking) reconstructed primary vertex which is * matched with MC trigger vertex (MC = 1) * * III. The best (in sense of ranking) reconstructed primary vertex which is * not matched with MC trigger vertex (MC != 1) * * 4. With pileup. repeat above (a-c) with new ranking scheme for cases I-III */ void MuMcPrVKFV2012(Long64_t nevent, const char *file, const std::string& outFile, bool fillNtuple) { #ifdef __TMVA__ boost::replace_last(outFile, ".root", ""); outFile += ".TMVArank.root"; // create a set of variables and declare them to the reader // - the variable names must corresponds in name and type to // those given in the weight file(s) that you use TString separator(":"); TString Vnames(vnames); TObjArray *array = Vnames.Tokenize(separator); std::vector<std::string> inputVars; TIter next(array); TObjString *objs; while ((objs = (TObjString *) next())) { std::cout << objs->GetString() << std::endl; } inputVars.push_back("beam"); inputVars.push_back("postx"); inputVars.push_back("prompt"); inputVars.push_back("cross"); inputVars.push_back("tof"); inputVars.push_back("notof"); inputVars.push_back("EEMC"); inputVars.push_back("noEEMC"); inputVars.push_back("chi2"); std::vector<double> *inputVec = new std::vector<double>( inputVars.size() ); IClassifierReader *classReader = new ReadBDT( inputVars ); #endif /* __TMVA__ */ TFile *fOut = TFile::Open(outFile.c_str(), "recreate"); data_t data; // Book histograms const int nMcRecMult = 75; TArrayD xMult(nMcRecMult + 1); xMult[0] = -0.5; for (int i = 1; i <= nMcRecMult; i++) { if (xMult[i - 1] < 50) xMult[i] = xMult[i - 1] + 1; // 1 - 50 else if (xMult[i - 1] < 100) xMult[i] = xMult[i - 1] + 2; // 51 - 75 else if (xMult[i - 1] < 200) xMult[i] = xMult[i - 1] + 10; // 76 - 85 else xMult[i] = xMult[i - 1] + 100; // 86 -100 } TH1D *McRecMulT = new TH1D("McRecMulT", "Reconstructable multiplicity for trigger Mc Vertex", nMcRecMult, xMult.GetArray()); struct Name_t { const Char_t *Name; const Char_t *Title; }; const Name_t HCases[3] = { {"Any", "Any vertex matched with MC == 1"}, {"Good", "The best rank vertex with MC == 1"}, {"Bad", "The best rank vertex with MC != 1"} }; const Name_t Plots[4] = { {"Mult" , "the reconstructed (uncorrected) track multiplicity versus Reconstructable multiplicity"}, {"MultQA" , "the reconstructed (corrected for QA) track multiplicity versus Reconstructable multiplicity"}, {"McRecMul", "Reconstructable multiplicity"}, {"YvsX" , "Bad versus Good value"} }; /* h p */ TH1 *hists[3][4]; for (int h = 0; h < 3; h++) { for (int p = 0; p < 4; p++) { TString Name(Plots[p].Name); Name += HCases[h].Name; TString Title(Plots[p].Title); Title += " for "; Title += HCases[h].Title; Title += " vertex"; if (p < 2) hists[h][p] = new TH2D(Name, Title, nMcRecMult, xMult.GetArray(), nMcRecMult, xMult.GetArray()); else if (p == 2) hists[h][p] = new TH1D(Name, Title, nMcRecMult, xMult.GetArray()); } } TNtuple *VertexG = new TNtuple("VertexG", "good vertex & global params info", vnames); TNtuple *VertexB = new TNtuple("VertexB", "bad vertex & global params info", vnames); // ---------------------------------------------- StMuDstMaker *maker = new StMuDstMaker(0, 0, "", file, "st:MuDst.root", 1e9); // set up maker in read mode // 0,0 this mean read mode // dir read all files in this directory // file bla.lis real all file in this list, if (file!="") dir is ignored // filter apply filter to filenames, multiple filters are separated by ':' // 10 maximum number of file to read maker->SetStatus("*", 0); std::vector<std::string> activeBranchNames = { "MuEvent", "PrimaryVertices", "StStMuMcVertex", "StStMuMcTrack" }; // Set Active braches for (const auto& branchName : activeBranchNames) maker->SetStatus(branchName.c_str(), 1); TChain *tree = maker->chain(); Long64_t nentries = tree->GetEntries(); nevent = TMath::Min(nevent, nentries); std::cout << nentries << " events in chain " << nevent << " will be read." << std::endl; tree->SetCacheSize(-1); //by setting the read cache to -1 we set it to the AutoFlush value when writing tree->SetCacheLearnEntries(1); //one entry is sufficient to learn tree->SetCacheEntryRange(0, nevent); for (Long64_t ev = 0; ev < nevent; ev++) { if (maker->Make()) break; StMuDst *muDst = maker->muDst(); // get a pointer to the StMuDst class, the class that points to all the data StMuEvent *muEvent = muDst->event(); // get a pointer to the class holding event-wise information int referenceMultiplicity = muEvent->refMult(); // get the reference multiplicity TClonesArray *PrimaryVertices = muDst->primaryVertices(); int nPrimaryVertices = PrimaryVertices->GetEntriesFast(); TClonesArray *MuMcVertices = muDst->mcArray(0); int nMuMcVertices = MuMcVertices->GetEntriesFast(); TClonesArray *MuMcTracks = muDst->mcArray(1); int nMuMcTracks = MuMcTracks->GetEntriesFast(); if ( nevent >= 10 && ev % int(nevent*0.1) == 0 ) { std::cout << "Event #" << ev << "\tRun\t" << muEvent->runId() << "\tId: " << muEvent->eventId() << " refMult= " << referenceMultiplicity << "\tPrimaryVertices " << nPrimaryVertices << "\t" << " " << nMuMcVertices << "\t" << " " << nMuMcTracks << std::endl; } // const Double_t field = muEvent->magneticField()*kilogauss; if (! nMuMcVertices || ! nMuMcTracks || nPrimaryVertices <= 0) { std::cout << "Ev. " << ev << " has no MC information ==> skip it" << std::endl; std::cout << "OR no reconstructed verticies found" << std::endl; continue; } // Count number of MC tracks at a vertex with TPC reconstructable tracks std::multimap<int, int> Mc2McHitTracks; for (int m = 0; m < nMuMcTracks; m++) { StMuMcTrack *McTrack = (StMuMcTrack *) MuMcTracks->UncheckedAt(m); if (McTrack->No_tpc_hit() < 15) continue; Mc2McHitTracks.insert(std::pair<int, int>(McTrack->IdVx(), McTrack->Id())); } // This is the "reconstructable" track multiplicity int nMcTracksWithHits = Mc2McHitTracks.count(1); // Let's skip events in which we do not expect to reconstruct any tracks // (and thus vertex) from the primary vertex if (nMcTracksWithHits <= 0) continue; // This is our denominator histogram for efficiencies McRecMulT->Fill(nMcTracksWithHits); // ============= Build map between Rc and Mc vertices std::map<StMuPrimaryVertex *, StMuMcVertex *> reco2McVertices; TArrayF vertexRanks(nPrimaryVertices); int mcMatchedVertexIndex = -1; // any vertex with MC==1 and highest reconstrated multiplicity. int vertexMaxMultiplicity = -1; // First loop over all verticies in this event. There is at least one // must be available for (int recoVertexIndex = 0; recoVertexIndex < nPrimaryVertices; recoVertexIndex++) { vertexRanks[recoVertexIndex] = -1e10; StMuPrimaryVertex *recoVertex = (StMuPrimaryVertex *) PrimaryVertices->UncheckedAt(recoVertexIndex); if ( !AcceptVX(recoVertex) ) continue; // Check Mc if (recoVertex->idTruth() < 0 || recoVertex->idTruth() > nMuMcVertices) { std::cout << "ERROR: Illegal idTruth " << recoVertex->idTruth() << " The track is ignored" << std::endl; continue; } StMuMcVertex *mcVertex = (StMuMcVertex *) MuMcVertices->UncheckedAt(recoVertex->idTruth() - 1); if (mcVertex->Id() != recoVertex->idTruth()) { std::cout << "ERROR: Mismatched idTruth " << recoVertex->idTruth() << " and mcVertex Id " << mcVertex->Id() << " The vertex is ignored" << std::endl; continue; } reco2McVertices[recoVertex] = mcVertex; vertexRanks[recoVertexIndex] = recoVertex->ranking(); if (recoVertex->idTruth() == 1 && recoVertex->noTracks() > vertexMaxMultiplicity) { mcMatchedVertexIndex = recoVertexIndex; vertexMaxMultiplicity = recoVertex->noTracks(); } FillData(data, recoVertex); #ifdef __TMVA__ Float_t *dataArray = &data.beam; for (size_t j = 0; j < inputVec->size(); j++) (*inputVec)[j] = dataArray[j]; vertexRanks[recoVertexIndex] = classReader->GetMvaValue( *inputVec ); #endif } // If we reconstructed a vertex which matches the MC one we fill the // numerator of the "Any" efficiency histogram if (mcMatchedVertexIndex != -1) { StMuPrimaryVertex *recoVertexMatchedMc = (StMuPrimaryVertex*) PrimaryVertices->UncheckedAt(mcMatchedVertexIndex); double nTracks = recoVertexMatchedMc->noTracks(); double nTracksQA = nTracks * recoVertexMatchedMc->qaTruth() / 100.; hists[0][0]->Fill(nMcTracksWithHits, nTracks); hists[0][1]->Fill(nMcTracksWithHits, nTracksQA); hists[0][2]->Fill(nMcTracksWithHits); } // Now deal with the highest rank vertex int maxRankVertexIndex = TMath::LocMax(nPrimaryVertices, vertexRanks.GetArray()); StMuPrimaryVertex *recoVertexMaxRank = (StMuPrimaryVertex*) PrimaryVertices->UncheckedAt(maxRankVertexIndex); StMuMcVertex *mcVertex = reco2McVertices[recoVertexMaxRank]; double nTracks = recoVertexMaxRank->noTracks(); double nTracksQA = nTracks * recoVertexMaxRank->qaTruth() / 100.; // Fill numerator for "good" and "bad" efficiencies int h = ( mcVertex && mcVertex->Id() == 1) ? 1 : 2; hists[h][0]->Fill(nMcTracksWithHits, nTracks); hists[h][1]->Fill(nMcTracksWithHits, nTracksQA); hists[h][2]->Fill(nMcTracksWithHits); // Proceed with filling ntuple only if requested by the user if ( !fillNtuple ) continue; // Second loop over all verticies in this event for (int recoVertexIndex = 0; recoVertexIndex < nPrimaryVertices; recoVertexIndex++) { StMuPrimaryVertex *recoVertex = (StMuPrimaryVertex *) PrimaryVertices->UncheckedAt(recoVertexIndex); if ( !AcceptVX(recoVertex) ) continue; StMuMcVertex *mcVertex = reco2McVertices[recoVertex]; if ( !mcVertex ) { std::cout << "No Match from RC to MC" << std::endl; continue; } if (vtxeval::gDebugFlag) { std::cout << Form("Vx[%3i]", recoVertexIndex) << *recoVertex << " " << *mcVertex; int nMcTracksWithHitsatL = Mc2McHitTracks.count(recoVertex->idTruth()); std::cout << Form("Number of McTkHit %4i rank %8.3f", nMcTracksWithHitsatL, vertexRanks[recoVertexIndex]); } int IdPar = mcVertex->IdParTrk(); if (IdPar > 0 && IdPar <= nMuMcTracks) { StMuMcTrack *mcTrack = (StMuMcTrack *) MuMcTracks->UncheckedAt(IdPar - 1); if (mcTrack && vtxeval::gDebugFlag) std::cout << " " << mcTrack->GeName(); } FillData(data, recoVertex); double nTracks = recoVertex->noTracks(); if (mcVertex->Id() == 1 && nTracks == vertexMaxMultiplicity) {// good VertexG->Fill(&data.beam); } else { // bad VertexB->Fill(&data.beam); } } if ( !gROOT->IsBatch() ) { if (vtxeval::ask_user()) return; } else { vtxeval::gDebugFlag = false; } } fOut->Write(); }
void makeMuDstQA(TString InputFileList, Int_t nFiles, Int_t nEvents, TString OutputDir ) { // Load libraries for CINT mode #ifdef __CINT__ gROOT -> Macro("loadMuDst.C"); #endif // List of member links in the chain StChain* chain = new StChain ; StMuDstMaker* muDstMaker = new StMuDstMaker(0,0,"",InputFileList,"MuDst",nFiles) ; // ---------------- modify here according to your QA purpose -------------------------- // Turn off everything but Primary tracks in order to speed up the analysis and eliminate IO muDstMaker -> SetStatus("*",0) ; // Turn off all branches muDstMaker -> SetStatus("MuEvent",1) ; // Turn on the Event data (esp. Event number) muDstMaker -> SetStatus("PrimaryVertices",1) ; // Turn on the primary track data muDstMaker -> SetStatus("PrimaryTracks",1) ; // Turn on the primary track data muDstMaker -> SetStatus("GlobalTracks",1) ; // Turn on the global track data muDstMaker -> SetStatus("CovGlobTrack",1); // to fix the refmult in Run14!!! muDstMaker -> SetStatus("BTofHeader",1) ; // Turn on the btof data muDstMaker -> SetDebug(0) ; // Turn off Debug information if ( nEvents == 0 ) nEvents = 10000000 ; // Take all events in nFiles if nEvents = 0 // ---------------- modify here according to your QA purpose -------------------------- //book histograms or trees if you need TString oFile(muDstMaker->GetFile()); TString oChopFile; int fileBeginIndex = oFile.Index("st_",0); oFile.Remove(0,fileBeginIndex); short indx1 = oFile.First('.'); short indx2 = oFile.Last('.'); if (indx1!=indx2) oFile.Remove(indx1+1,(indx2-indx1)); oChopFile=oFile; oFile.Insert(indx1+1,"moretags."); oFile.Prepend(OutputDir); oChopFile.Insert(indx1+1,"chopper."); oChopFile.ReplaceAll("root","txt"); oChopFile.Prepend(OutputDir); ofstream chop_output(oChopFile); TFile *tags_output = new TFile( oFile, "recreate" ) ; tags_output->cd(); //TH1F *hPhi = new TH1F("hPhi","Phi of proton",200,-TMath::Pi(),TMath::Pi()); //TH2F *hPhiFirstZ = new TH2F("hPhiFirstZ","Phi vs. FirstZ",200,-150,150,200,-TMath::Pi(),TMath::Pi()); //Prepare the output tree Int_t mRunId, mEvtId; Int_t mnRefMult, mngRefMult, mnTofMatch; Float_t mVX, mVY, mVZ; Float_t mVpdVz; Float_t mPVRank; TTree *mMoreTagsTree = new TTree("MoreTags","MoreTags"); mMoreTagsTree->Branch("RunId",&mRunId,"RunId/I"); mMoreTagsTree->Branch("EvtId",&mEvtId,"EvtId/I"); mMoreTagsTree->Branch("nRefMult",&mnRefMult,"nRefMult/I"); mMoreTagsTree->Branch("ngRefMult",&mngRefMult,"ngRefMult/I"); mMoreTagsTree->Branch("nTofMatch",&mnTofMatch,"nTofMatch/I"); mMoreTagsTree->Branch("VX",&mVX,"VX/F"); mMoreTagsTree->Branch("VY",&mVY,"VY/F"); mMoreTagsTree->Branch("VZ",&mVZ,"VZ/F"); mMoreTagsTree->Branch("VpdVz",&mVpdVz,"VpdVz/F"); mMoreTagsTree->Branch("PVRank",&mPVRank,"PVRank/F"); mMoreTagsTree->SetAutoSave(10000000); // ---------------- end of histogram and tree booking -------------------------------- // Loop over the links in the chain Int_t iInit = chain -> Init() ; if (iInit) chain->FatalErr(iInit,"on init"); // chain -> EventLoop(1,nEvents) ; //will output lots of useless debugging info. Int_t istat = 0, i = 1; while (i <= nEvents && istat != 2) { if(i%10==0)cout << endl << "== Event " << i << " start ==" << endl; chain->Clear(); istat = chain->Make(i); if (istat == 2) cout << "Last event processed. Status = " << istat << endl; if (istat == 3) cout << "Error event processed. Status = " << istat << endl; i++; if(istat != kStOK)continue; //skip those suspectible events // ---------------- modify here according to your QA purpose -------------------------- //let's do the QA here... //start with event cutting... //cout<<"In event #. "<<i-1<<" Maker status "<<istat<<endl; StMuDst* mMuDst = muDstMaker->muDst(); if(!mMuDst) { LOG_WARN << " No MuDst " << endm; continue; } StMuEvent* mMuEvent = mMuDst->event(); if(!mMuEvent) { LOG_WARN << " No MuEvent " << endm; continue; } //vzVpd StBTofHeader const* mBTofHeader = mMuDst->btofHeader(); Float_t vzVpd=-999; if (mBTofHeader) vzVpd = mBTofHeader->vpdVz(); /* //Run14 vertex selection ////////////////////////////////////// // select the right vertex using VPD ///////////////////////////////////// for(unsigned int i=0;i<mMuDst->numberOfPrimaryVertices();i++) { StMuPrimaryVertex *vtx = mMuDst->primaryVertex(i); if(!vtx) continue; Float_t vz = vtx->position().z(); if(fabs(vzVpd)<100 && fabs(vzVpd-vz)<3.) { mMuDst->setVertexIndex(i); break; } } ///////////////////////////////////// */ /* //Run16 vertex selection //////////////////////////////////////////////////////////////// if (fabs(vzVpd) < 200) { for (unsigned int iVtx = 0; iVtx < mMuDst->numberOfPrimaryVertices(); ++iVtx) { StMuPrimaryVertex* vtx = mMuDst->primaryVertex(iVtx); if (!vtx) continue; if (fabs(vzVpd - vtx->position().z()) < 3.) { mMuDst->setVertexIndex(iVtx); break; } } } //////////////////////////////////////////////////////////////// */ /* //Run15 pAu & Run16 dAu vertex selection int index = 0; const double mTpcVpdVzDiffCut = 6; if (mBTofHeader && fabs(vzVpd) < 200) { for (unsigned int iVtx = 0; iVtx < mMuDst->numberOfPrimaryVertices(); ++iVtx) { StMuPrimaryVertex* vtx = mMuDst->primaryVertex(iVtx); if (!vtx) continue; if (fabs(vzVpd - vtx->position().z()) < mTpcVpdVzDiffCut) { index = iVtx; break; } } } if(index>=0) mMuDst->setVertexIndex(index); */ mRunId = mMuEvent->runNumber(); mEvtId = mMuEvent->eventNumber(); mnRefMult = mMuEvent->refMult(); Int_t nTofMatPrTrack = 0; TObjArray* prtracks = muDstMaker->muDst()->primaryTracks() ; // Create a TObject array containing the global tracks TObjArrayIter GetPrTracks(prtracks) ; // Create an iterator to step through the tracks StMuTrack* prtrack ; // Pointer to a track while ( ( prtrack = (StMuTrack*)GetPrTracks.Next() ) ) // Main loop for Iterating over tracks { if(prtrack->btofPidTraits().matchFlag()) nTofMatPrTrack ++; } mnTofMatch = nTofMatPrTrack; mVX = mMuEvent->primaryVertexPosition().x(); mVY = mMuEvent->primaryVertexPosition().y(); mVZ = mMuEvent->primaryVertexPosition().z(); mVpdVz = vzVpd; if(mMuDst->primaryVertex())mPVRank = mMuDst->primaryVertex()->ranking(); else mPVRank = -1e9; Int_t nGlTrack = 0; TObjArray* gltracks = muDstMaker->muDst()->globalTracks() ; // Create a TObject array containing the global tracks TObjArrayIter GetGlTracks(gltracks) ; // Create an iterator to step through the tracks StMuTrack* gltrack ; // Pointer to a track while ( ( gltrack = (StMuTrack*)GetGlTracks.Next() ) ) // Main loop for Iterating over tracks { if(fabs(gltrack->eta())>=0.5)continue; if(gltrack->nHitsFit()<10)continue; if(gltrack->dca().mag()>=3.0)continue; nGlTrack++ ; } mngRefMult = nGlTrack; mMoreTagsTree->Fill(); //Event info (for debug) //cout<<"Run#: "<<mMuEvent->runNumber()<<endl; //cout<<"Evt#: "<<mMuEvent->eventNumber()<<endl; //cout<<muDstMaker->muDst()->currentVertexIndex()<<endl; //cout<<"refmult: "<<mMuEvent->refMult()<<endl; //Event cuts (NO EVENT CUTS TILL HERE!) //trigger if ( ! mMuEvent->triggerIdCollection().nominal().isTrigger(410008) && ! mMuEvent->triggerIdCollection().nominal().isTrigger(410005) ) continue; //Vz if ( fabs(mMuEvent->primaryVertexPosition().z()) > 30.0 ) continue ; //Vr //if ( mMuEvent->primaryVertexPosition().perp() > 100.0 ) continue ; //VF failed (for some old dataset) //if ( fabs(mMuEvent->primaryVertexPosition().x()) < 1e-5 && fabs(mMuEvent->primaryVertexPosition().y()) < 1e-5 && fabs(mMuEvent->primaryVertexPosition().z()) < 1e-5 ) continue; chop_output<<mRunId<<'\t'<<mEvtId<<endl; /* //fill Event QA histograms TObjArray* tracks = muDstMaker->muDst()->primaryTracks() ; TObjArrayIter GetTracks(tracks) ; StMuTrack* gtrack ; while ( ( gtrack = (StMuTrack*)GetTracks.Next() ) ) { //const StMuTrack * gtrack = track->globalTrack(); if(gtrack->nHits()<=15)continue; if(gtrack->flag()<=0)continue; if(abs(gtrack->charge())!=1) continue; if(gtrack->pt()>0.5) continue; if(fabs(gtrack->nSigmaProton())>2)continue; hPhi->Fill(gtrack->phi()); hPhiFirstZ->Fill(gtrack->firstPoint().z(),gtrack->phi()); } //end of the filling */ } if (nEvents > 1) chain -> Finish() ; if(tags_output!=NULL) tags_output -> Write() ; if(tags_output!=NULL) tags_output -> Close() ; //flush(tags_output); delete tags_output; chop_output.close(); // Cleanup delete chain ; }