PeterParfenov лет назад: 5
Родитель
Сommit
73c300284f
8 измененных файлов с 515 добавлено и 17 удалено
  1. 7 7
      CalcPID.C
  2. 6 5
      FemtoDstAnalyzer_FlowPIDHadrons.C
  3. 287 0
      FemtoDstAnalyzer_PID.C
  4. 9 5
      RunAnalyzer_FlowPIDHadrons.C
  5. 50 0
      RunAnalyzer_PID.C
  6. 7 0
      bin/CMakeLists.txt
  7. 94 0
      bin/flowPID.cpp
  8. 55 0
      bin/pid.cpp

+ 7 - 7
CalcPID.C

@@ -187,8 +187,8 @@ void Fit1DgausMassSqr(const Char_t *inFileName, const Char_t *outFileName)
     gausTriplePion[i]->SetParameters(parPion);
 
     hMsqrPion[i]->Fit(gausTriplePion[i],"R");
-    hMsqrSigmaPion->SetBinContent(i+1,gausTriplePion[i]->GetParameter(2));
-    hMsqrSigmaPion->SetBinError(i+1,gausTriplePion[i]->GetParError(2));
+    hMsqrSigmaPion->SetBinContent(i,gausTriplePion[i]->GetParameter(2));
+    hMsqrSigmaPion->SetBinError(i,gausTriplePion[i]->GetParError(2));
   }
 
   //Kaon
@@ -205,8 +205,8 @@ void Fit1DgausMassSqr(const Char_t *inFileName, const Char_t *outFileName)
     gausTripleKaon[i]->SetParameters(parKaon);
 
     hMsqrKaon[i]->Fit(gausTripleKaon[i],"R");
-    hMsqrSigmaKaon->SetBinContent(i+1,gausTripleKaon[i]->GetParameter(5));
-    hMsqrSigmaKaon->SetBinError(i+1,gausTripleKaon[i]->GetParError(5));
+    hMsqrSigmaKaon->SetBinContent(i,gausTripleKaon[i]->GetParameter(5));
+    hMsqrSigmaKaon->SetBinError(i,gausTripleKaon[i]->GetParError(5));
   }
 
   //Proton
@@ -223,8 +223,8 @@ void Fit1DgausMassSqr(const Char_t *inFileName, const Char_t *outFileName)
     gausTripleProton[i]->SetParameters(parProton);
 
     hMsqrProton[i]->Fit(gausTripleProton[i],"R");
-    hMsqrSigmaProton->SetBinContent(i+1,gausTripleProton[i]->GetParameter(8));
-    hMsqrSigmaProton->SetBinError(i+1,gausTripleProton[i]->GetParError(8));
+    hMsqrSigmaProton->SetBinContent(i,gausTripleProton[i]->GetParameter(8));
+    hMsqrSigmaProton->SetBinError(i,gausTripleProton[i]->GetParError(8));
   }
 
   TF1 *polPion = new TF1("polPion","pol8",0.15,4.9);
@@ -268,4 +268,4 @@ void CalcPID(const Char_t *inFileName, const Char_t *outFileName, const Int_t mo
   {
     Fit1DgausMassSqr(inFileName, outFileName);
   }
-}
+}

+ 6 - 5
FemtoDstAnalyzer_FlowPIDHadrons.C

@@ -27,6 +27,7 @@
 #include "TSystem.h"
 #include "TH1.h"
 #include "TH2.h"
+#include "TF1.h"
 #include "TMath.h"
 #include "TProfile2D.h"
 #include "TStopwatch.h"
@@ -537,7 +538,7 @@ void FemtoDstAnalyzer_FlowPIDHadrons(const Char_t *inFile = "st_physics_12150008
         Psi2WestEP[iGap] = AngleShift(Psi_ReCenter+dPsi,2.);
 
         //EAST 3-nd order
-        Psi_ReCenter = TMath::ATan2(fQv2EastEP[iGap].Y(),fQv2EastEP[iGap].X())/3.;
+        Psi_ReCenter = TMath::ATan2(fQv3EastEP[iGap].Y(),fQv3EastEP[iGap].X())/3.;
         dPsi = 0.;
         for (int iK=0; iK<NShiftOrderMax; iK++)
         {
@@ -554,7 +555,7 @@ void FemtoDstAnalyzer_FlowPIDHadrons(const Char_t *inFile = "st_physics_12150008
         Psi3EastEP[iGap] = AngleShift(Psi_ReCenter+dPsi,3.);
 
         //WEST 3-nd order
-        Psi_ReCenter = TMath::ATan2(fQv2WestEP[iGap].Y(),fQv2WestEP[iGap].X())/3.;
+        Psi_ReCenter = TMath::ATan2(fQv3WestEP[iGap].Y(),fQv3WestEP[iGap].X())/3.;
         dPsi = 0.;
         for (int iK=0; iK<NShiftOrderMax; iK++)
         {
@@ -614,8 +615,8 @@ void FemtoDstAnalyzer_FlowPIDHadrons(const Char_t *inFile = "st_physics_12150008
             }
             // kaon id
             if (TMath::Abs(femtoTrack->nSigmaKaon()) < cutNsigPID &&
-                femtoTrack->massSqr() > kaonMassSqr - NpidFactor*sigMsqrKaon->Eval(femtoTrack->pt()) &&
-                femtoTrack->massSqr() < kaonMassSqr + NpidFactor*sigMsqrKaon->Eval(femtoTrack->pt()))
+                femtoTrack->massSqr() > kaonMassSqr - NpidFactor*TMath::Abs(sigMsqrKaon->Eval(femtoTrack->pt())) &&
+                femtoTrack->massSqr() < kaonMassSqr + NpidFactor*TMath::Abs(sigMsqrKaon->Eval(femtoTrack->pt())) )
             {
               i_part = 1;
             }
@@ -729,7 +730,7 @@ Bool_t isGoodTrackFlowPID(StFemtoTrack *const &track, Float_t _energy, TVector3
   if (TMath::Abs(track->eta()) >= cutEta) return false;
   
   if (track->pt() <= cutPtMin.at(_energy)) return false;
-  //if (track->pt() > cutPtMax) return false;
+  if (track->pt() > 4.15) return false;
   if (track->ptot() > cutPMax) return false;
   if (track->gDCA(pVtx).Mag() >= cutDCA_PID) return false;
   return true;

+ 287 - 0
FemtoDstAnalyzer_PID.C

@@ -0,0 +1,287 @@
+/**
+ * \brief Example of how to read a file (list of files) using StFemtoEvent classes
+ *
+ * RunFemtoDstAnalyzer.C is an example of reading FemtoDst format.
+ * One can use either FemtoDst file or a list of femtoDst files (inFile.lis or
+ * inFile.list) as an input, and preform physics analysis
+ *
+ * \author Grigory Nigmatkulov
+ * \date May 29, 2018
+ */
+
+// This is needed for calling standalone classes
+#define _VANILLA_ROOT_
+
+// C++ headers
+#include <iostream>
+#include <vector>
+#include <map>
+
+// ROOT headers
+#include "TROOT.h"
+#include "TFile.h"
+#include "TChain.h"
+#include "TVector2.h"
+#include "TVector3.h"
+#include "TTree.h"
+#include "TSystem.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TMath.h"
+#include "TProfile2D.h"
+#include "TStopwatch.h"
+
+// FemtoDst headers
+#include "/mnt/pool/rhic/4/parfenovpeter/STAR/StFemtoEvent/StFemtoDstReader.h"
+#include "/mnt/pool/rhic/4/parfenovpeter/STAR/StFemtoEvent/StFemtoDst.h"
+#include "/mnt/pool/rhic/4/parfenovpeter/STAR/StFemtoEvent/StFemtoEvent.h"
+#include "/mnt/pool/rhic/4/parfenovpeter/STAR/StFemtoEvent/StFemtoTrack.h"
+
+// Load libraries (for ROOT_VERSTION_CODE >= 393215)
+#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 0, 0)
+R__LOAD_LIBRARY(/mnt/pool/rhic/4/parfenovpeter/STAR/build/libStFemtoDst.so)
+#endif
+
+#include "Constants.h"
+
+// inFile - is a name of name.FemtoDst.root file or a name
+//          of a name.lis(t) files, that contains a list of
+//          name1.FemtoDst.root, name2.FemtoDst.root, ... files
+
+//Used functions (see them below)
+Bool_t isGoodEvent(StFemtoEvent *const &event);
+Bool_t isGoodTrack(StFemtoTrack *const &track, Float_t _energy, TVector3 pVtx);
+Bool_t isGoodTrackFlow(StFemtoTrack *const &track, Float_t _energy, TVector3 pVtx);
+Double_t GetWeight(StFemtoTrack *const &track);
+TVector2 CalcQvector(StFemtoTrack *const &track, Int_t _harm);
+Double_t AngleShift(Double_t Psi, Double_t order);
+
+//_________________
+void FemtoDstAnalyzer_PID(const Char_t *inFile = "st_physics_12150008_raw_4030001.femtoDst.root",
+                                         const Char_t *outFile = "./oPIDTest.root")
+{
+
+  std::cout << "Hi! Lets do some physics, Master!" << std::endl;
+  TStopwatch timer;
+  timer.Start();
+
+#if ROOT_VERSION_CODE < ROOT_VERSION(6, 0, 0)
+  gSystem->Load("../libStFemtoDst.so");
+#endif
+
+  StFemtoDstReader *femtoReader = new StFemtoDstReader(inFile);
+  femtoReader->Init();
+
+  // This is a way if you want to spead up IO
+  std::cout << "Explicit read status for some branches" << std::endl;
+  femtoReader->SetStatus("*", 0);
+  femtoReader->SetStatus("Event", 1);
+  femtoReader->SetStatus("Track", 1);
+  std::cout << "Status has been set" << std::endl;
+
+  std::cout << "Now I know what to read, Master!" << std::endl;
+
+  if (!femtoReader->chain())
+  {
+    std::cout << "No chain has been found." << std::endl;
+  }
+  Long64_t eventsInTree = femtoReader->tree()->GetEntries();
+  std::cout << "eventsInTree: " << eventsInTree << std::endl;
+  Long64_t events2read = femtoReader->chain()->GetEntries();
+
+  std::cout << "Number of events to read: " << events2read << std::endl;
+
+
+  const int NptBins = 24;
+  const double ptBin [NptBins+1] = {0.,0.2,0.4,0.6,0.8,1.,1.2,1.4,1.6,1.8,2.,2.2,2.4,2.6,2.8,3.,3.2,3.4,3.6,3.8,4.,4.5,5.,5.5,6.};
+  TH2F *hNsigPionMSqr[NptBins];
+  TH2F *hNsigKaonMSqr[NptBins];
+  TH2F *hNsigProtonMSqr[NptBins];
+
+  //Initialization
+  for (int i=0; i<NptBins; i++)
+  {
+    hNsigPionMSqr[i] = new TH2F(Form("hNsigPionMSqr%i",i) ,Form("n#sigma_{#pi} vs M^{2} for %.2f < p_{T} < %.2f GeV/c;n#sigma_{#pi};m^{2} [GeV/c^{2}]^{2}",ptBin[i]+cutPtMin.at(energy),ptBin[i+1]+cutPtMin.at(energy)),1400,-35.,35.,1400,-2.,5.);
+    hNsigKaonMSqr[i] = new TH2F(Form("hNsigKaonMSqr%i",i) ,Form("n#sigma_{K} vs M^{2} for %.2f < p_{T} < %.2f GeV/c;n#sigma_{K};m^{2} [GeV/c^{2}]^{2}",ptBin[i]+cutPtMin.at(energy),ptBin[i+1]+cutPtMin.at(energy)),1400,-35.,35.,1400,-2.,5.);
+    hNsigProtonMSqr[i] = new TH2F(Form("hNsigProtonMSqr%i",i) ,Form("n#sigma_{p} vs M^{2} for %.2f < p_{T} < %.2f GeV/c;n#sigma_{p};m^{2} [GeV/c^{2}]^{2}",ptBin[i]+cutPtMin.at(energy),ptBin[i+1]+cutPtMin.at(energy)),1400,-35.,35.,1400,-2.,5.);
+  }
+
+  // Loop over events
+  for (Long64_t iEvent = 0; iEvent < events2read; iEvent++)
+  {
+
+    if ((iEvent+1) % 1000 == 0){
+      std::cout << "Working on event #[" << (iEvent + 1)
+                << "/" << events2read << "]" << std::endl;
+    }
+
+    Bool_t readEvent = femtoReader->readFemtoEvent(iEvent);
+    if (!readEvent)
+    {
+      std::cout << "Something went wrong, Master! Nothing to analyze..." << std::endl;
+      break;
+    }
+
+    // Retrieve femtoDst
+    StFemtoDst *dst = femtoReader->femtoDst();
+
+    // Retrieve event information
+    StFemtoEvent *event = dst->event();
+    if (!event)
+    {
+      std::cout << "Something went wrong, Master! Event is hiding from me..." << std::endl;
+      break;
+    }
+
+    TVector3 pVtx = event->primaryVertex();
+
+    // Event selection
+    if ( !isGoodEvent(event) ) continue;
+
+    // Track analysis
+    Int_t nTracks = dst->numberOfTracks();
+    
+
+    // Track loop
+    for (Int_t iTrk = 0; iTrk < nTracks; iTrk++)
+    {
+
+      // Retrieve i-th femto track
+      StFemtoTrack *femtoTrack = dst->track(iTrk);
+
+      if (!femtoTrack)
+        continue;
+
+      // Must be a primary track
+      if (!femtoTrack->isPrimary())
+        continue;
+
+      //Track selection
+      if (!isGoodTrackFlow(femtoTrack, energy, pVtx)) continue;
+
+      // Determine pt bin for PID plots
+      int i_pt = -1;
+      for (int i=0;i<NptBins;i++)
+      {
+        if (femtoTrack->pt() >= (ptBin[i] + cutPtMin.at(energy)) && femtoTrack->pt() < (ptBin[i+1] + cutPtMin.at(energy)))
+	{
+	  i_pt = i;
+	}
+      }
+      if (i_pt == -1) continue;
+
+      // Check if track has TOF signal
+      if (femtoTrack->isTofTrack())
+      {
+        if (femtoTrack->gDCA(pVtx).Mag() >= 1.) continue;
+
+        hNsigPionMSqr[i_pt]->Fill(femtoTrack->nSigmaPion(),femtoTrack->massSqr());
+        hNsigKaonMSqr[i_pt]->Fill(femtoTrack->nSigmaKaon(),femtoTrack->massSqr());
+        hNsigProtonMSqr[i_pt]->Fill(femtoTrack->nSigmaProton(),femtoTrack->massSqr());
+
+      } //if( isTofTrack() )
+
+    } //for(Int_t iTrk=0; iTrk<nTracks; iTrk++)
+
+  } //for(Long64_t iEvent=0; iEvent<events2read; iEvent++)
+
+  femtoReader->Finish();
+
+  TFile *output = new TFile(outFile,"recreate");
+
+  for (int i=0; i<NptBins; i++)
+  {
+    hNsigPionMSqr[i] -> Write();
+    hNsigKaonMSqr[i] -> Write();
+    hNsigProtonMSqr[i] -> Write();
+  }
+
+  output->Close();
+
+  std::cout << "I'm done with analysis. We'll have a Nobel Prize, Master!"
+            << std::endl;
+  timer.Stop();
+  timer.Print();
+}
+
+Bool_t isGoodEvent(StFemtoEvent *const &event)
+{
+  if (!event) return false;
+  if (event == nullptr) return false;
+
+  if (event->primaryVertex().Perp() > cutVtxR) return false;
+  if (TMath::Abs(event->primaryVertex().Z()) > cutVtxZEnergy.at(energy)) return false;
+
+  if ((energy == 200.) && TMath::Abs(event->primaryVertex().Z() - event->vpdVz()) > cutVpdVz) return false;
+
+  return true;
+}
+
+Bool_t isGoodTrack(StFemtoTrack *const &track, Float_t _energy, TVector3 pVtx)
+{
+  if (!track) return false;
+  // if (!track->isPrimary()) return false;
+  if (track->nHitsFit() < cutNhits) return false;
+  if (track->nHitsPoss() <= cutNhitsPoss) return false;
+  if ((Double_t) track->nHitsFit()/track->nHitsPoss() < cutNhitsRatio) return false;
+  if (TMath::Abs(track->eta()) >= cutEta) return false;
+  
+  if (track->pt() <= cutPtMin.at(_energy)) return false;
+  if (track->pt() > cutPtMax) return false;
+  if (track->ptot() > cutPMax) return false;
+  if (track->gDCA(pVtx).Mag() >= cutDCA.at(_energy)) return false;
+  return true;
+}
+
+Bool_t isGoodTrackFlow(StFemtoTrack *const &track, Float_t _energy, TVector3 pVtx)
+{
+  if (!track) return false;
+  // if (!track->isPrimary()) return false;
+  if (track->nHitsFit() < cutNhits) return false;
+  if (track->nHitsPoss() <= cutNhitsPoss) return false;
+  if ((Double_t) track->nHitsFit()/track->nHitsPoss() < cutNhitsRatio) return false;
+  if (TMath::Abs(track->eta()) >= cutEta) return false;
+  
+  if (track->pt() <= cutPtMin.at(_energy)) return false;
+  //if (track->pt() > cutPtMax) return false;
+  if (track->ptot() > cutPMax) return false;
+  if (track->gDCA(pVtx).Mag() >= cutDCA.at(_energy)) return false;
+  return true;
+}
+
+Double_t GetWeight(StFemtoTrack *const &track)
+{
+  Double_t weight;
+  if (track->pt() <= cutPtWeightEP)
+  {
+    weight = track->pt();
+  }
+  else
+  {
+    weight = cutPtWeightEP;
+  }
+  return weight;
+}
+
+TVector2 CalcQvector(StFemtoTrack *const &track, Int_t _harm)
+{
+  TVector2 qv(0.,0.);
+
+  qv.Set(TMath::Cos(_harm*track->phi()),TMath::Sin(_harm*track->phi()));
+
+  return qv;
+}
+
+Double_t AngleShift(Double_t Psi, Double_t order)
+{
+  Double_t PsiCorr = Psi;
+  if (PsiCorr > TMath::Pi()/order)
+  {
+    PsiCorr = Psi - 2.*TMath::Pi()/order;
+  }
+  if (PsiCorr < -1.*TMath::Pi()/order)
+  {
+    PsiCorr = Psi + 2.*TMath::Pi()/order;
+  }
+  return PsiCorr;
+}

+ 9 - 5
RunAnalyzer_FlowPIDHadrons.C

@@ -27,11 +27,15 @@
 #include "TString.h"
 
 //const Char_t* defaultFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/list/200gev_run_12132011.list";
-const Char_t* defaultFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/list/middle_200gev_run_12132011.list";
-// const Char_t* defaultFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/list/little_200gev_run_12132011.list";
-const Char_t* recFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/Analysis/macro/Flow/oReCenteringTest.root";
-const Char_t* shiftFile = "/mnt/pool/rhic/4/parfenovpeter/STAR/Analysis/macro/Flow/oShiftTest.root";
-const Char_t* resFile = "/mnt/pool/rhic/4/parfenovpeter/STAR/Analysis/macro/Flow/oResolutionTest.root";
+// const Char_t* defaultFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/list/middle_200gev_run_12132011.list";
+const Char_t* defaultFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/list/little_200gev_run_12132011.list";
+// const Char_t* recFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/Analysis/macro/Flow/oReCenteringTest.root";
+// const Char_t* shiftFile = "/mnt/pool/rhic/4/parfenovpeter/STAR/Analysis/macro/Flow/oShiftTest.root";
+// const Char_t* resFile = "/mnt/pool/rhic/4/parfenovpeter/STAR/Analysis/macro/Flow/oResolutionTest.root";
+
+const Char_t* recFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/OUT/200gev/merge/Recentering.root";
+const Char_t* shiftFile = "/mnt/pool/rhic/4/parfenovpeter/STAR/OUT/200gev/merge/ShiftCorr.root";
+const Char_t* resFile = "/mnt/pool/rhic/4/parfenovpeter/STAR/OUT/200gev/merge/Resolution.root";
 const Char_t* pidFile = "/mnt/pool/rhic/4/parfenovpeter/STAR/OUT/200gev/merge/pid_fit.root";
 
 //_________________

+ 50 - 0
RunAnalyzer_PID.C

@@ -0,0 +1,50 @@
+/**
+ * \brief Helper macros for analyzing name.femtoDst.root files using FemtoDstAnalyzer.C
+ *
+ *  This macros takes inFileName argument with a femtoDst.root file
+ *  or with a list of files (name.lis or name.list). It sets _VANILLA_ROOT_
+ *  (necessary for standalone mode), loads pre-compiled libStFemtoDst.so
+ *  (from StFemtoEvent), compiles and executes a text
+ *  FemtoDstAnalyzer.C macro with passing inFileName to it, and
+ *  cleans up the directory from the compilation products at the end.
+ *
+ *  Some details:
+ *    inFileName - is a name of name.femtoDst.root file or a name
+ *                 of a name.lis(t) files that contains a list of
+ *                 name1.femtoDst.root files.
+ *    NOTE: inFileName should contain either /absolutePath/inFileName
+ *          or /relative2currentDir/inFileName
+ *  It is assumed that FemtoDstAnalyzer.C is placed in the same
+ *  directory where the RunAnalyzer.C is stored.
+ *
+ * \author Grigory Nigmatkulov
+ * \date July 5, 2018
+ */
+
+// ROOT headers
+#include "TROOT.h"
+#include "TSystem.h"
+#include "TString.h"
+
+const Char_t* defaultFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/list/200gev_run_12132011.list";
+//const Char_t* defaultFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/list/middle_200gev_run_12132011.list";
+//const Char_t* defaultFileName = "/mnt/pool/rhic/4/parfenovpeter/STAR/list/little_200gev_run_12132011.list";
+
+//_________________
+void RunAnalyzer_PID(const Char_t *inFileName = defaultFileName,
+		 const Char_t *oFileName = "oPIDTest.root") {
+  // Next line is not needed if you are not running in a standalone mode
+  gROOT->ProcessLine("#define _VANILLA_ROOT_");
+  //gSystem->Load("$FEMTOSOFT/StFemtoEvent/libStFemtoDst.so");
+  gSystem->Load("/mnt/pool/rhic/4/parfenovpeter/STAR/build/libStFemtoDst.so");
+  TString str;
+  str = ".x /mnt/pool/rhic/4/parfenovpeter/STAR/Analysis/macro/Flow/FemtoDstAnalyzer_PID.C+(\"";
+  str += inFileName;
+  str += "\",\"";
+  str += oFileName;
+  str += "\")";
+  gROOT->ProcessLine( str.Data() );
+  // Next line should be commented if you run in a batch mode
+  //gROOT->ProcessLine(".!rm -f FemtoDstAnalyzer_C* ");
+}
+

+ 7 - 0
bin/CMakeLists.txt

@@ -9,3 +9,10 @@ target_link_libraries(resolution ${ST_FEMTO_DST} ${ROOT_LIBRARIES})
 
 add_executable(flowCH flowCH.cpp)
 target_link_libraries(flowCH ${ST_FEMTO_DST} ${ROOT_LIBRARIES})
+
+add_executable(flowPID flowPID.cpp)
+target_link_libraries(flowPID ${ST_FEMTO_DST} ${ROOT_LIBRARIES})
+
+
+add_executable(pid pid.cpp)
+target_link_libraries(pid ${ST_FEMTO_DST} ${ROOT_LIBRARIES})

+ 94 - 0
bin/flowPID.cpp

@@ -0,0 +1,94 @@
+#include <iostream>
+#include <stdlib.h>
+#include "FemtoDstAnalyzer_FlowPIDHadrons.C"
+
+int main(int argc, char** argv)
+{
+  TString inFileName, outFileName, reCentFileName, shiftFileName, resFileName, pidFileName;
+  Float_t energy;
+  if (argc < 13)
+  {
+    std::cerr << "./flowPID -i INPUTFILE -o OUTPUTFILE -reCent RECENTERINGFILE -shift SHIFTCORRFILE -resolution RESOLUTIONFILE -pid PIDFITFILE" << std::endl;
+    return 10;
+  }
+
+  for (int i=1;i<argc;i++)
+  {
+    if (std::string(argv[i]) != "-i" &&
+        std::string(argv[i]) != "-o" &&
+	std::string(argv[i]) != "-reCent" &&
+	std::string(argv[i]) != "-shift" &&
+	std::string(argv[i]) != "-resolution" &&
+	std::string(argv[i]) != "-pid")
+    {
+      std::cerr << "\nUnknown parameter: " << argv[i] << std::endl;
+      return 11;
+    }
+    else
+    {
+      if (std::string(argv[i]) == "-i" && i != argc-1)
+      {
+        inFileName = TString(argv[++i]);
+      }
+      if (std::string(argv[i]) == "-i" && i == argc-1)
+      {
+        std::cerr << "\nInput file was not specified!" << std::endl;
+	return 12;
+      }
+      if (std::string(argv[i]) == "-o" && i != argc-1)
+      {
+        outFileName = TString(argv[++i]);
+      }
+      if (std::string(argv[i]) == "-o" && i == argc-1)
+      {
+        std::cerr << "\nOutput file was not specified!" << std::endl;
+	return 13;
+      }
+      if (std::string(argv[i]) == "-reCent" && i != argc-1)
+      {
+        reCentFileName = TString(argv[++i]);
+      }
+      if (std::string(argv[i]) == "-reCent" && i == argc-1)
+      {
+        std::cerr << "\nOutput file was not specified!" << std::endl;
+	return 13;
+      }
+      if (std::string(argv[i]) == "-shift" && i != argc-1)
+      {
+        shiftFileName = TString(argv[++i]);
+      }
+      if (std::string(argv[i]) == "-shift" && i == argc-1)
+      {
+        std::cerr << "\nOutput file was not specified!" << std::endl;
+	return 13;
+      }
+      if (std::string(argv[i]) == "-resolution" && i != argc-1)
+      {
+        resFileName = TString(argv[++i]);
+      }
+      if (std::string(argv[i]) == "-resolution" && i == argc-1)
+      {
+        std::cerr << "\nOutput file was not specified!" << std::endl;
+	return 13;
+      }
+      if (std::string(argv[i]) == "-pid" && i != argc-1)
+      {
+        pidFileName = TString(argv[++i]);
+      }
+      if (std::string(argv[i]) == "-pid" && i == argc-1)
+      {
+        std::cerr << "\nOutput file was not specified!" << std::endl;
+	return 13;
+      }
+    }
+  }
+  if (inFileName == "" || outFileName == "" || reCentFileName == "" || shiftFileName == "" || resFileName == "" || pidFileName == "")
+  {
+    std::cerr << "\nInput/Output file has not been set properly!" << std::endl;
+    return 14;
+  }
+
+  FemtoDstAnalyzer_FlowPIDHadrons(inFileName.Data(),outFileName.Data(),reCentFileName.Data(),shiftFileName.Data(),resFileName.Data(),pidFileName.Data());
+
+  return 0;
+}

+ 55 - 0
bin/pid.cpp

@@ -0,0 +1,55 @@
+#include <iostream>
+#include <stdlib.h>
+#include "FemtoDstAnalyzer_PID.C"
+
+int main(int argc, char** argv)
+{
+  TString inFileName, outFileName;
+  Float_t energy;
+  TStopwatch timer;
+  if (argc < 5)
+  {
+    std::cerr << "./pid -i INPUTFILE -o OUTPUTFILE" << std::endl;
+    return 10;
+  }
+
+  for (int i=1;i<argc;i++)
+  {
+    if (std::string(argv[i]) != "-i" &&
+        std::string(argv[i]) != "-o")
+    {
+      std::cerr << "\nUnknown parameter: " << argv[i] << std::endl;
+      return 11;
+    }
+    else
+    {
+      if (std::string(argv[i]) == "-i" && i != argc-1)
+      {
+        inFileName = TString(argv[++i]);
+      }
+      if (std::string(argv[i]) == "-i" && i == argc-1)
+      {
+        std::cerr << "\nInput file was not specified!" << std::endl;
+	return 12;
+      }
+      if (std::string(argv[i]) == "-o" && i != argc-1)
+      {
+        outFileName = TString(argv[++i]);
+      }
+      if (std::string(argv[i]) == "-o" && i == argc-1)
+      {
+        std::cerr << "\nOutput file was not specified!" << std::endl;
+	return 13;
+      }
+    }
+  }
+  if (inFileName == "" || outFileName == "")
+  {
+    std::cerr << "\nInput/Output file has not been set properly!" << std::endl;
+    return 14;
+  }
+
+  FemtoDstAnalyzer_PID(inFileName.Data(),outFileName.Data());
+
+  return 0;
+}