//____________________________________________________________________________________________________
// 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
  grefmultCorrUtil->setVzForWeight(6, -6.0, 6.0);
  grefmultCorrUtil->readScaleForWeight("StRoot/StRefMultCorr/macros/weight_grefmult_vpd30_vpd5_Run14.txt");

  // 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;
  }
  //----------------------------------------------------------------------------------------------------

  // 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 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);
  //----------------------------------------------------------------------------------------------------

  // 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() ;

  // 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() ;

  //----------------------------------------------------------------------------------------------------
  // 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() ;

  //----------------------------------------------------------------------------------------------------
  // 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;
}
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();
}
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();
}