void runPicoD0AnaMaker(TString d0list, TString outFileName, TString badRunListFileName = "picoList_bad_MB.list")
{
  TStopwatch*   stopWatch = new TStopwatch();
  stopWatch->Start();
  //Check STAR Library. Please set SL_version to the original star library used in the production from http://www.star.bnl.gov/devcgi/dbProdOptionRetrv.pl
  string SL_version = "SL15c";
  string env_SL = getenv("STAR");
  if (env_SL.find(SL_version) == string::npos)
  {
    cout << "Environment Star Library does not match the requested library in runPicoD0EventMaker.C. Exiting..." << endl;
    exit(1);
  }

  gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C");
  loadSharedLibraries();

  gSystem->Load("StPicoDstMaker");
  gSystem->Load("StPicoPrescales");
  gSystem->Load("StPicoD0EventMaker");
  gSystem->Load("StPicoD0AnaMaker");
  gSystem->Load("StRefMultCorr");
  // gSystem->Load("StEventPlane");

  chain = new StChain();

  // create list of picoDst files
  TString command = "sed 's/hft\\\/d0tree/picodsts/g' " + d0list + " >correspondingPico.list";
  gSystem->Exec(command.Data());
  command = "sed -i 's/picoD0/picoDst/g' correspondingPico.list";
  gSystem->Exec(command.Data());
  command = "sed -i 's/kfProd2/physics2/g' correspondingPico.list";
  gSystem->Exec(command.Data());
  // create list of kfVertex files
  TString command = "sed 's/d0tree/kfVertex/g' " + d0list + " >correspondingkfVertex.list";
  gSystem->Exec(command.Data());
  command = "sed -i 's/picoD0/kfVertex/g' correspondingkfVertex.list";
  gSystem->Exec(command.Data());
  command = "sed -i 's/kfProd2/physics2/g' correspondingkfVertex.list";
  gSystem->Exec(command.Data());
  StPicoDstMaker* picoDstMaker = new StPicoDstMaker(0, "correspondingPico.list", "picoDstMaker");
  StRefMultCorr* grefmultCorrUtil  = CentralityMaker::instance()->getgRefMultCorr();
  // StEventPlane*  eventPlaneMaker = new StEventPlane("eventPlaneMaker",picoDstMaker,grefmultCorrUtil);
  // StPicoD0AnaMaker*  picoD0AnaMaker = new StPicoD0AnaMaker("picoD0AnaMaker", d0list, outFileName.Data(), picoDstMaker, grefmultCorrUtil, eventPlaneMaker);
  StPicoD0AnaMaker*  picoD0AnaMaker = new StPicoD0AnaMaker("picoD0AnaMaker", d0list, "correspondingkfVertex.list", outFileName.Data(), picoDstMaker, grefmultCorrUtil);
  picoD0AnaMaker->fillQaHistograms(false);
  grefmultCorrUtil->setVzForWeight(6, -6.0, 6.0);
  grefmultCorrUtil->readScaleForWeight("StRoot/StRefMultCorr/macros/weight_grefmult_vpd30_vpd5_Run14.txt");
  for(Int_t i=0;i<6;i++){
    cout << i << " " << grefmultCorrUtil->get(i, 0) << endl;
  }

  // -------------- USER variables -------------------------

  chain->Init();
  int nEntries = picoD0AnaMaker->getEntries();
  cout<<"Processing "<<nEntries<<" events..."<<endl;
  for (int iEvent = 0; iEvent < nEntries; ++iEvent)
  {
    chain->Clear();
    if(iEvent && iEvent%2000 == 0) cout<<"... finished processing "<<iEvent<<" events."<<endl;

    int iret = chain->Make();
    if (iret)
    {
      cout << "Bad return code!" << iret << endl;
      break;
    }
  }
  cout<<"Finished processing "<<nEntries<<" events."<<endl;

  chain->Finish();
  delete chain;

  // delete list of picos
  command = "rm -f correspondingPico.list";
  gSystem->Exec(command.Data());
  command = "rm -f correspondingkfVertex.list";
  gSystem->Exec(command.Data());
  stopWatch->Stop();   
  stopWatch->Print();
}
void runPicoMixedEvent(const Char_t *inputFile="test.list", const Char_t *outputFile="outputBaseName", 
			 const Char_t *badRunListFileName = "picoList_bad_MB.list") { 
  // -- Check STAR Library. Please set SL_version to the original star library used in the production 
  //    from http://www.star.bnl.gov/devcgi/dbProdOptionRetrv.pl
  TStopwatch*   stopWatch = new TStopwatch();
  stopWatch->Start();
  StMemStat mem;
  string SL_version = "SL15c";
  string env_SL = getenv ("STAR");
  if (env_SL.find(SL_version)==string::npos) {
      cout<<"Environment Star Library does not match the requested library in runPicoMixedEventMaker.C. Exiting..."<<endl;
      exit(1);
  }
  // ========================================================================================
  //   Testing 
  // ========================================================================================
  Int_t nEvents = 10000000;
  //Int_t nEvents = 20000;
	
  gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C");
  loadSharedLibraries();

  // gSystem->Load("StBTofUtil");
  gSystem->Load("StPicoDstMaker");
  gSystem->Load("StPicoPrescales");
  // gSystem->Load("StPicoCutsBase");
  // gSystem->Load("StPicoHFMaker");
  gSystem->Load("StRefMultCorr");
  gSystem->Load("StEventPlane");
  gSystem->Load("StPicoMixedEventMaker");
  
  
  chain = new StChain();

  // ========================================================================================
  // Still bone dry
  // ========================================================================================


  TString sInputFile(inputFile);
  TString sInputListHF("");  

  // create list of kfVertex files
  TString command = "sed 's/picodsts/hft\\\/kfVertex/g' " + sInputFile + " >correspondingkfVertex.list";
  gSystem->Exec(command.Data());
  command = "sed -i 's/picoDst/kfVertex/g' correspondingkfVertex.list";
  gSystem->Exec(command.Data());

  // ========================================================================================
  StPicoDstMaker* picoDstMaker = new StPicoDstMaker(0, sInputFile, "picoDstMaker");
  StRefMultCorr* grefmultCorrUtil  = CentralityMaker::instance()->getgRefMultCorr();
  cout<<"here"<<endl;
  grefmultCorrUtil->setVzForWeight(6, -6.0, 6.0);
  grefmultCorrUtil->readScaleForWeight("StRoot/StRefMultCorr/macros/weight_grefmult_vpd30_vpd5_Run14.txt");
  for(Int_t i=0;i<6;i++){
    cout << i << " " << grefmultCorrUtil->get(i, 0) << endl;
  }
  StEventPlane*  eventPlaneMaker = new StEventPlane("eventPlaneMaker",picoDstMaker,grefmultCorrUtil);
  StPicoMixedEventMaker* picoMixedEventMaker = new StPicoMixedEventMaker("picoMixedEventMaker", picoDstMaker, grefmultCorrUtil, eventPlaneMaker, outputFile, sInputListHF, "correspondingkfVertex.list");

  // ---------------------------------------------------
  // -- Set Base cuts for HF analysis

  // -- File name of bad run list
  //hfCuts->setBadRunListFileName(badRunListFileName);

  chain->Init();
  cout << "chain->Init();" << endl;

  int total = picoDstMaker->chain()->GetEntries();
  cout << " Total entries = " << total << endl;
  if(nEvents>total) nEvents = total;
  for (Int_t i=0; i<nEvents; i++) {
    if(i%1000==0)
      cout << "Working on eventNumber " << i << endl;
    
    chain->Clear();

    int iret = chain->Make(i);

    if (iret) { cout << "Bad return code!" << iret << endl; break;}
    
    total++;
  }
  
  cout << "****************************************** " << endl;
  cout << "Work done... now its time to close up shop!"<< endl;
  cout << "****************************************** " << endl;
  chain->Finish();
  cout << "****************************************** " << endl;
  cout << "total number of events  " << nEvents << endl;
  cout << "****************************************** " << endl;
  
  delete chain;
  // delete list of kfEvent list
  command = "rm -f correspondingkfVertex.list";
  gSystem->Exec(command.Data());

  stopWatch->Stop(); 
  stopWatch->Print();
}
//____________________________________________________________________________________________________
// Example macro for StRefMutlCorr class implementation
//   * Before accessing centrality bins via StRefMutlCorr, you must call 'init(const Int_t RunId)'
//     to specify which parameters you want to use
//     - If you stick to the one specific run, you only need to call this function once in your code.
//     - If you read data from multiple different runs, you need to call this function
//       whenever you switch to the run number
//
//   * In the standard STAR analysis maker, the best (and only) place to call 'init(...)' function 
//     is 'Make(...)'
//
//   * Comment for luminosity (zdc coincidence rate) correction
//     - Luminosity correction is only valid for 200 GeV
//     - The default argument is 0 for zdc coincidence rate in initEvent() function, see header StRefMultCorr.h,
//       so that you can still use previous initEvent() function like
//         void StRefMultCorr::initEvent(refmult, vz) ;
//       without specifying zdc coincidence rate for lower beam energies
//     - (Very important) You should use BBC coincidence rate for refmult2
//
//   * You can now use the interface "CentralityMaker" class to access the StRefMultCorr
//     see the usage below.
//   * The refmult2 & refmult3 correction classes are ready. You can access the correction by
//      - StRefMultCorr* refmult2CorrUtil = CentralityMaker::instance()->getRefMult2Corr() ;
//      (note the '2' in the function, replace 2 to 3 for refmult3)
//      - You can use exactly the same functions used in StRefMultCorr (see below)
void getCentralityBins()
{
  //----------------------------------------------------------------------------------------------------
  // NOTE:
  //   - The usage below is under the assumption that users add StRefMultCorr class in their StRoot/ and compiled it by cons. 
  //   - You can definitely use the correction classes in your local pc with ROOT
  //     because the codes under StRefMultCorr don't depend on any STAR libraries.
  //----------------------------------------------------------------------------------------------------

  // In the compiled code, don't forget to add
  // #include "StRoot/StRefMultCorr/StRefMultCorr.h"
  // #include "StRoot/StRefMultCorr/CentralityMaker.h"

  // Load StRefMultCorr library
  // NOTE: Add this line in your 'macro', not in the source code
  gSystem->Load("StRefMultCorr");

  // For refmult
  StRefMultCorr* refmultCorrUtil  = CentralityMaker::instance()->getRefMultCorr() ;

  // For refmult2
  StRefMultCorr* refmult2CorrUtil = CentralityMaker::instance()->getRefMult2Corr() ;

  // For refmult3
  StRefMultCorr* refmult3CorrUtil = CentralityMaker::instance()->getRefMult3Corr() ;

  // For grefmult
  StRefMultCorr* grefmultCorrUtil = CentralityMaker::instance()->getgRefMultCorr() ;

  // You can also access the StRefMultCorr by direct instantiation
  // StRefMultCorr* refmultCorrUtil  = new StRefMultCorr("refmult");
  // StRefMultCorr* refmult2CorrUtil = new StRefMultCorr("refmult2");

  // You need to specify the run number you are going to process
  refmultCorrUtil->init(11078000);
  refmult2CorrUtil->init(11078000);
  refmult3CorrUtil->init(11078000);
  grefmultCorrUtil->init(15075008);

  //----------------------------------------------------------------------------------------------------
  // *** Optional functions (not necessary to call)
  //    void StRefMultCorr::print(const Optiont_t option="");
  //    Int_t StRefMultCorr::getBeginRun(const Double_t energy, const Int_t year) ;
  //    Int_t StRefMultCorr::getEndRun(const Double_t energy, const Int_t year) ;

  // Print all parameters
//  refmultCorrUtil->print();
//  refmult2CorrUtil->print();
//  refmult3CorrUtil->print();
//  grefmultCorrUtil->print();

  // scale factor test
  // *****************************************************************************************************************************************
  // Actually you don't need it for Run14 Vpd30 and VpdNoVtx, but for easy,just copy these lines to youe macros, and in the StRefmult we already comment these factor in StRefmult Line 482
  grefmultCorrUtil->setVzForWeight(6, -100.0, 100.0);
  grefmultCorrUtil->readScaleForWeight("StRoot/StRefMultCorr/macros/weight_grefmult_vpd30_vpd5_Run14.txt");
  for(Int_t i=0;i<6;i++){
    cout << i << " " << grefmultCorrUtil->get(i, 0) << endl;
  }

  return;

  // Obtain begin and end run number from energy and year
  cout << "Run " << refmultCorrUtil->getBeginRun(200.0, 2010) << " - " << refmultCorrUtil->getEndRun(200.0, 2010) << endl;

  // You can check the 'bad run' based on the event-wise QA for refmult centrality
  // by using StRefMultCorr::isBadRun() function
  if ( refmultCorrUtil->isBadRun(12177061) ) {
    cout << "Run 12177061 is bad" << endl;
  }

  if ( refmult2CorrUtil->isBadRun(12177061) ) {
    cout << "Run 12177061 is bad" << endl;
  }

  if ( refmult3CorrUtil->isBadRun(12177061) ) {
    cout << "Run 12177061 is bad" << endl;
  }

  if ( grefmultCorrUtil->isBadRun(15106001) ) {
    cout << "Run 15106001 is bad" << endl;
  }
  //----------------------------------------------------------------------------------------------------

  // Dummy refmult and primary z-vertex to test the functions
  const UShort_t refmult  = 100 ;
  const UShort_t refmult2 = 100 ;
  const UShort_t refmult3 = 100 ;
  const UShort_t grefmult = 100 ;
  const Double_t vz      = 20.0 ; // cm
  const Double_t zdcCoincidenceRate = 20000 ; // Hz
  const Double_t bbcCoincidenceRate = 20000 ; // Hz

  // The following functions should be called inside the event loop (event-by-event)

  // ******* IMPORTANT ***********
  // Call initEvent(const UShort_t RefMult, const Double_t z) function
  // event-by-event at the beginning before using any other functions
  refmultCorrUtil->initEvent(refmult, vz, zdcCoincidenceRate) ;

  // This also works for 7.7 - 62.4 GeV (see comments above)
//  refmultCorrUtil->initEvent(refmult, vz);

  // ******* VERY IMPORTANT ***********
  // USE BBC COINCIDENCE RATE RATHER THAN ZDC COINCIDENCE RATE FOR REFMULT2
  refmult2CorrUtil->initEvent(refmult2, vz, bbcCoincidenceRate) ;

  // This also works for 7.7 - 62.4 GeV (see comments above)
//  refmult2CorrUtil->initEvent(refmult2, vz);

  refmult3CorrUtil->initEvent(refmult3, vz, zdcCoincidenceRate) ;

  // This also works for 7.7 - 62.4 GeV (see comments above)
//  refmult3CorrUtil->initEvent(refmult3, vz);
  //----------------------------------------------------------------------------------------------------

  grefmultCorrUtil->initEvent(grefmult, vz, zdcCoincidenceRate) ;
  // Get centrality bins
  //   - You can use exactly the same functions to obtain centrality, reweighting
  //     and corrected multiplicity for refmult2
  //
  //   see StRefMultCorr.h for the definition of centrality bins
  const Int_t cent16 = refmultCorrUtil->getCentralityBin16() ;
  const Int_t cent9  = refmultCorrUtil->getCentralityBin9() ;

  // Centrality from refmult2
  const Int_t cent16_refmult2 = refmult2CorrUtil->getCentralityBin16() ;
  const Int_t cent9_refmult2  = refmult2CorrUtil->getCentralityBin9() ;

  // Centrality from refmult3
  const Int_t cent16_refmult3 = refmult3CorrUtil->getCentralityBin16() ;
  const Int_t cent9_refmult3  = refmult3CorrUtil->getCentralityBin9() ;

  // Centrality from grefmult
  const Int_t cent16_grefmult = grefmultCorrUtil->getCentralityBin16() ;
  const Int_t cent9_grefmult  = grefmultCorrUtil->getCentralityBin9() ;

  // Re-weighting corrections for peripheral bins
  const Double_t reweight          = refmultCorrUtil->getWeight() ;
  const Double_t reweight_refmult2 = refmult2CorrUtil->getWeight() ;
  const Double_t reweight_refmult3 = refmult3CorrUtil->getWeight() ;
  const Double_t reweight_grefmult = grefmultCorrUtil->getWeight() ;

  //----------------------------------------------------------------------------------------------------
  // Corrected refmult (with z-vertex dependent correction and luminositiy correction)
  //  NOTE: type should be double or float, not integer
  const Double_t refmultCor  = refmultCorrUtil->getRefMultCorr() ;
  const Double_t refmult2Cor = refmult2CorrUtil->getRefMultCorr() ;
  const Double_t refmult3Cor = refmult3CorrUtil->getRefMultCorr() ;
  const Double_t grefmultCor = grefmultCorrUtil->getRefMultCorr() ;

  //----------------------------------------------------------------------------------------------------
  // Invalid run number test
  const Int_t runId = 12154037 ;
  cout << "Invalid run number test: " << runId << endl;
  cout << "The program should be stopped with the error messages from isIndexOk function" << endl;
  refmult2CorrUtil->init(runId);
  refmult2CorrUtil->getWeight();
  // Program should stop here
  cout << "Problem if you see this message. Contact [email protected]" << endl;
}