// FileName: reco_MC_near_CamFit_Dev.C
// Created by: Joshua Boehm
// Last Modified: January 19, 2006

// Usage
// cp <path>/reco_MC_near_CamFit_Dev.C reco_MC.C
// loon -bq "reco_MC.C()" <reroot_file>

/////////////////////////////////////////////////////////
// Description of this                                 //
// This file will produce an MC simulated Spill stream //
//  Only meant to do NearDet processing in R1-18.      //
//  Processing occurs through a single path "Reco"     //
//  No filtering applied outside of finding the spills //
//  Each output stream requires its own processing     //
//   branch and so there are small offshoot branches   //
//  Uses: CandSubShower                                //
//        FitTrackCam                                  //
//                                                     //
// Output:                                             //
// Output Files:                                       //
//  CandS.root - candidate output file                 //
//  ntupleStS.root - NtpSt ntuple output               //
//  ntupleStS.sub.root - NtpSt trimmed of stp info     //
/////////////////////////////////////////////////////////

class JobC;

int LoadLibraries();
int GetRunNumber();

void SetCalibrator();

void SetCandOutputWithBNtp(JobCModule &jcm, TString file);
void SetCandOutputNoBNtp(JobCModule &jcm, TString file);
void SetNtpStOutputWithBNtp(JobCModule &jcm, TString file);
void SetNtpStOutputNoBNtp(JobCModule &jcm, TString file);

void SetMSGLevels(JobC &jc);

void reco_MC()
{
    LoadLibraries();

    JobC jc;
  
  //Create path - first the reroot job
  jc.Path.Create("Reco",  //STANDARD REROOT
                 "RerootToTruthModule::Get "
                 "PhotonTransport::Get "
                 "DetSim::Get "
                );

  //And Now the Normal Reco chain
  jc.Path.Create("Reco1",
		 "NoiseFilterModule::Ana "
		 "RecordSetupModule::Get "
		 "DigitListModule::Get "
		 "DigitListModule::Reco "
		 "StripSRListModule::Reco "
		 "SliceSRListModule::Reco "
		 "TrackSRListModule::Reco "
		 "FitTrackCamListModule::Reco "
		 "ClusterSRListModule::Reco "
                 "SubShowerSRListModule::Reco "
		 "ShowerSRListModule::Reco "
		 "EventSRListModule::Reco "
		 "RecordSetupModule::Reco "
		 "Output::Put");

  //Attach the normal reco chain after the reroot path
  jc.Path.Attach("Reco","Reco1");


  //Input Parameters
  jc.Input.Set("Format=reroot");
  jc.Input.Set("Streams=DaqSnarl");   //takes reroot data as input

  // Set up RerootExodus to build the event as MC (instead of Reroot)
  RerootExodus::SetVldSimFlag(SimFlag::kMC);

  jc.Path("Reco").SetAllFilters(0);
  //turn off the detsim and photontransport
  jc.Path("Reco1").SetAllFilters(0);
  //turn off the reconstruction filters

  //////////////////////////////////////
  //Configure Reconstruction Software for Near Det MC "Spill" data .
  // For a full description of the different possible module options see the 
  //   Document:  ConfigOptions.txt

  //Setting modifications for neardet-PhotonTransport
  //explicitly set the value of GeVPerMip
  JobCModule& photon=jc.Path("Reco").Mod("PhotonTransport");
  photon.Set("GeVPerMip=0.001759");//was 0.001730
  //End of photon transport - this value was given by Jeff Hartnell on 11/4/2005


  jc.Path("Reco1").Mod("SliceSRListModule").Set("SliceListAlgConfig=NearBeam");
  jc.Path("Reco1").Mod("ClusterSRListModule").Set("ClusterListAlgConfig=NearBeam");
  jc.Path("Reco1").Mod("ShowerSRListModule").Set("ShowerListAlgConfig=NearBeam");
  jc.Path("Reco1").Mod("TrackSRListModule").Set("TrackListAlgConfig=NearBeam");
  
  jc.Path("Reco1").Mod("EventSRListModule").Set("EventListAlgorithm=AlgEventSSList");
  jc.Path("Reco1").Mod("EventSRListModule").Set("EventListAlgConfig=NearBeam");
  


  //Set up the conditions for the CandSubShower Package
  jc.Path("Reco1").Mod("SubShowerSRListModule").Set("SubShowerSRListAlgConfig=default");
  jc.Path("Reco1").Mod("ShowerSRListModule").Set("ShowerListAlgorithm=AlgShowerSSList");
  jc.Path("Reco1").Mod("ShowerSRListModule").Set("ShowerListAlgConfig=default");
  jc.Path("Reco1").Mod("ShowerSRListModule").Set("ListOut=CandShowerSRList");
	
  jc.Path("Reco1").Mod("StripSRListModule").Set("ListIn=canddigitlist");
  jc.Path("Reco1").Mod("DigitListModule").Set("ListsToMake=3");    //Write both canddigitlist and candmcdigitlist.

   jc.Path("Reco1").Mod("FitTrackCamListModule").Set("NameListIn=CandTrackSRList");


  //////////////////////////////////////
 
   
  // Set Ugli to use only database.
  UgliLoanPool::SetAlwaysUseDbi(true);
 
  //  End of Configuration settings     //
  ////////////////////////////////////////

  ////////////////////////////////////////////////////////////////
  //Display the Configuration of modules 
  jc.Path("Reco").Mod("RerootToTruthModule").Report();
  jc.Path("Reco").Mod("PhotonTransport").Report();
  jc.Path("Reco").Mod("DetSim").Report();
  jc.Path("Reco1").Mod("StripSRListModule").Report();
  jc.Path("Reco1").Mod("ShowerSRListModule").Report();
  jc.Path("Reco1").Mod("TrackSRListModule").Report();
  jc.Path("Reco1").Mod("FitTrackCamListModule").Report();
  ///////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////
  //    Setting the Output Paths                 //
  //  - This script produces the 3 output        // 
  //    streams, cand, snts, sntp                //
  /////////////////////////////////////////////////


  //Set Candidate Output to CandA.root (all of the snarls included in output)
  SetCandOutputNoBNtp(jc.Path("Reco1").Mod("Output"), "CandS.root");

  //Ntuple record has its own output file so needs its own output module
  jc.Path.Create("NtpSR",
                 "NtpStModule::Get "
                 "NtpSRModule::Reco "
		 "NtpMCModule::Reco " //Necessary to write the MC info tree
                 "NtpTHModule::Reco " //Necessary to write the MC th tree
		 "Output::Put ");
  jc.Path("NtpSR").Mod("NtpMCModule").Set("UseStandard=1"); // use NtpSt
  jc.Path("NtpSR").Mod("NtpTHModule").Set("UseStandard=1"); // use NtpSt
  jc.Path("NtpSR").Mod("NtpSRModule").Set("UseStandard=1"); // use NtpSt
  SetNtpStOutputNoBNtp(jc.Path("NtpSR").Mod("Output"), "ntupleStS.root");
  jc.Path.Attach("Reco1","NtpSR");

  // Ntuple abridged record
  jc.Path.Create("NtpSRFilter",
		 "NtpStFilterModule::Reco "
		 "Output::Put ");
  SetNtpStOutputNoBNtp(jc.Path("NtpSRFilter").Mod("Output"), "ntupleStS.sub.root");  
  jc.Path.Attach("Reco1", "NtpSRFilter");

  //////////////////////////////////////////////////////
  ///         End of Output Settings                ////
  //////////////////////////////////////////////////////

      SetMSGLevels(jc);

  //Other Run Options
  //  jc.Path("All").Run(100);  //Run over the first 100 snarls
  //  jc.Input.Next(10);  //Skip to Snarl 10  
  jc.Path("Reco").Run();
  jc.Path("Reco").Report();

  //Get Message Statistics
  jc.Msg.Stats();

}


//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//  Everything from this point forward are sub-functions        //

int LoadLibraries()
{

// Link dynamic libraries
  gSystem->Load("libDataUtil");
  gSystem->Load("libRecoBase");
  gSystem->Load("libNoiseFilter");
  gSystem->Load("libFilterDigitSR");
  gSystem->Load("libBField");
  gSystem->Load("libNumericalMethods");
  gSystem->Load("libSwimmer");
  gSystem->Load("libCandStripSR");
  gSystem->Load("libCandSliceSR");
  gSystem->Load("libCandTrackSR");
  gSystem->Load("libCandClusterSR");
  gSystem->Load("libCandSubShowerSR");  
  gSystem->Load("libCandShowerSR");
  gSystem->Load("libCandFitTrackSR");
  gSystem->Load("libCandFitTrackCam");
  gSystem->Load("libCandEventSR");
  gSystem->Load("libVertexFinder");
  gSystem->Load("libTimeCalibratorSR");
  gSystem->Load("libAstroUtil");
  gSystem->Load("libCandNtupleSR");
  gSystem->Load("libMCNtuple");
  gSystem->Load("libTruthHelperNtuple");
  gSystem->Load("libStandardNtuple");
  gSystem->Load("libPhotonTransport");
  gSystem->Load("libDetSim");
  gSystem->Load("libMCNtupleModule");       
  gSystem->Load("libCandNtupleSRModule");
  gSystem->Load("libTruthHelperNtupleModule");
  gSystem->Load("libStandardNtupleModule");

  gSystem->Load("libCandShield");
  gSystem->Load("libFiltration"); 

}


int GetRunNumber(){
  ////////////////////////////////////////////////////////
  //Get the run number from the Input file name
  //Allows us to set the name of the dst file
  JobCEnv& jce = JobCEnv::Instance();
  string filename = jce.GetFileName(0);
  string rnumstring = filename.substr(filename.find_last_of("_")-8,8);
  int run = atoi(rnumstring.c_str());
//  string srnstring = filename.substr(filename.find_last_of("_")+1,4);
  return run;
}

void SetCandOutputWithBNtp(JobCModule &jcm, TString file){

  jcm.Cmd("DefineStream Config ConfigRecord");
  jcm.Cmd("DefineStream NtpBDLite NtpBDLiteRecord");
  jcm.Set("Streams=SimSnarl,NtpBDLite,Cand,Config,DaqSnarl");
  jcm.Set("FileName="+file);
}

void SetCandOutputNoBNtp(JobCModule &jcm, TString file){

  jcm.Cmd("DefineStream Config ConfigRecord");
  jcm.Set("Streams=Cand,Config,DaqSnarl");
  jcm.Set("FileName="+file);
}

void SetNtpStOutputWithBNtp(JobCModule &jcm, TString file){
  jcm.Cmd("DefineStream NtpSt NtpStRecord");
  jcm.Cmd("DefineStream NtpBDLite NtpBDLiteRecord");
  jcm.Set("Streams=NtpBDLite,NtpSt");
  jcm.Set("FileName="+file);
}

void SetNtpStOutputNoBNtp(JobCModule &jcm, TString file){
  jcm.Cmd("DefineStream NtpSt NtpStRecord");
  jcm.Set("Streams=NtpSt");
  jcm.Set("FileName="+file);
}

void SetMSGLevels(JobC &jc){
  //Configure the message service
  jc.Msg.SetLevel("NoiseFilter","Fatal");
  jc.Msg.SetLevel("Cand","Error");
  jc.Msg.SetLevel("Calibrator","Fatal");
  jc.Msg.SetLevel("Dbi","Fatal");
  jc.Msg.SetLevel("SigCor Calibrator","Fatal");
  jc.Msg.SetLevel("Time Calibrator","Fatal");
  jc.Msg.SetLevel("MuonCalibrator","Fatal");
  jc.Msg.SetLevel("PE Calibrator","Fatal");
  jc.Msg.SetLevel("MapperCalibrator","Fatal");
  jc.Msg.SetLevel("DetSim","Error");
  jc.Msg.SetLevel("Reroot","Error");
  jc.Msg.SetLevel("Photon","Warning"); 
  jc.Msg.SetLevel("Per","Fatal");
  jc.Msg.SetLevel("Io", "Fatal");
  jc.Msg.SetLevel("Plex","Error");
  jc.Msg.SetLevel("AlgShowerSS", "Warning");
  jc.Msg.SetLevel("SubShowerSR","Error");
  jc.Msg.SetLevel("FitTrackCamListModule", "Error");
}
