// FileName: reco_MC_daikon_far_MRCC_srsafitter_cedar_phy.C
// Last Modified: October 11, 2007
// October 11, 2007: (SC) added MRCC
// Most Recent Modifications:
// January 10, 2007: (JAB) Original Creation Date
//  branched from the official Cedar MC scripts
//
// Usage
// cp <path>/reco_MC_daikon_far_cedar_phy_srsafitter.C reco_MC.C
// loon -bq GoodSpillTime.C "reco_MC.C()" <reroot_file>

/////////////////////////////////////////////////////////
// Description:                                        //
// This file will produce an MC sim of a Spill stream  //
//  This is only meant to do MC FarDet processing      //
//  for nue, numu, or nutau in Daikon MC in Cedar      //
//  Simulations processing takes place in the Reco     //
//   path, while reconstruction occurs in the "Reco1"  //
//   path.                                             //
//  Each output stream requires its own processing     //
//   branch and so there are small offshoot branches   //
// Uses: CandSubShower Module                          //
//       CandChop                                      //
//       CandEventSR (modified to use SS)              //
//       CandFitTrackCam                               //
//       CandTrackCam                                  //
//       GeoGeometry (in reco)                         //
// Demuxer: Alt/Cambridge                              //
//                                                     //
// Notes: Fixes for the SimSnarl path and lost         //
//        (unreco'd) events is an additional change    //
//
// Does both sr and sa fitting
//                                                     //
// Output:                                             //
// Output Files:                                       //
//  CandS.root - candidate output file                 //
//  ntupleStS.root - NtpSt ntuple output               //
//  ntupleMRNT.root                                    //
//  Output stream for Cand file includes SimSnarl      //
/////////////////////////////////////////////////////////

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 SetNtpStOutputNoBNtpSA(JobCModule &jcm, TString file);
void AttachMRCCPath(JobC &jc, char* RecTitle);

void SetMSGLevels(JobC &jc);

void reco_MC(int nSkip=0,int nRun=100000)
{
  reco_MC_daikon_far_MRCC_srsafitter_cedar_phy(nSkip,nRun);
}

void reco_MC_daikon_far_MRCC_srsafitter_cedar_phy(int nSkip=0,int nRun=100000)
{
  LoadLibraries();


  JobC jc;

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

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

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

  //turn off all filters
  jc.Path("Reco").SetAllFilters(0);
  jc.Path("Reco1").SetAllFilters(0);

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

  //Settings for PhotonTransport Module
  JobCModule& photon=jc.Path("Reco").Mod("PhotonTransport");
  photon.Set("GeVPerMip=0.001786");//was 0.001737 and 0.001730
  //This setting was updated by Jeff Hartnell on 26/Apr/2007

  //Additional Configuration settings supplied by Nathaniel
  JobCModule& detsim = jc.Path("Reco").Mod("DetSim");
  detsim.Set("applyTrigger=0");    //Turn off all triggers - soill trigger event
  photon.Set("NoiseWindow=40e-6"); //Increase noise window to +- 40 us of noise for spill trigger

  jc.Path("Reco1").Mod("ChopModule").Set("ChopAlgorithm=AlgChopListFar");
  jc.Path("Reco1").Mod("BiggestChopModule").Set("MinEnergy=0.0"); //No cut.
  jc.Path("Reco1").Mod("BiggestChopModule").Set("OmitLiEvents=1"); //kill LI
  jc.Path("Reco1").Mod("BiggestChopModule").Set("LiVetoWindowLow=-1.0e-6");
  jc.Path("Reco1").Mod("BiggestChopModule").Set("LiVetoWindowHigh=31.0e-6");

  jc.Path("Reco1").Mod("SliceSRListModule").Set("SliceListAlgConfig=FarBeam");
  jc.Path("Reco1").Mod("ClusterSRListModule").Set("ClusterListAlgConfig=FarBeam");

  jc.Path("Reco1").Mod("TrackCamListModule").Set("TrackListAlgConfig=default");
  jc.Path("Reco1").Mod("TrackCamListModule").Set("NameListIn=CandSliceList");
  jc.Path("Reco1").Mod("TrackCamListModule").Set("NameListOut=CandTrackSRList");

  jc.Path("Reco1").Mod("FitTrackCamListModule").Set("NameListIn=CandTrackSRList");
  jc.Path("Reco1").Mod("EventSRListModule").Set("EventListAlgorithm=AlgEventSSList");
  jc.Path("Reco1").Mod("EventSRListModule").Set("EventListAlgConfig=FarBeam");

  //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");
  //End CandSubShower Settings

  jc.Path("Reco1").Mod("DeMuxDigitListModule").Set("SwitchPersToTemp=1");
  jc.Path("Reco1").Mod("DeMuxDigitListModule").Set("NameListOut=altdemux");
  jc.Path("Reco1").Mod("DeMuxDigitListModule").Set("DeMuxDigitListAlgConfig=devel");
  jc.Path("Reco1").Mod("StripSRListModule").Set("ListIn=altdemux");

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

  // Set the simulated date of the events as to allow for consistent calibration
  // RerootExodus::SetOverrideVldTimeStamp();

  // Set Ugli to use only database.
  UgliLoanPool::SetAlwaysUseDbi(true);

  // Use GeoGeometry for reconstruction instead of UgliGeometry
  UgliLoanPool::Instance()->SetUseGeo(true);

  SetCalibrator();

  //  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("DeMuxDigitListModule").Report();
  jc.Path("Reco1").Mod("StripSRListModule").Report();
  jc.Path("Reco1").Mod("ShowerSRListModule").Report();
  jc.Path("Reco1").Mod("TrackCamListModule").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)
  //this will become the .cand. file
  jc.Path.Create("CandOut",
		 "Output::Put "
                 );
  SetCandOutputNoBNtp(jc.Path("CandOut").Mod("Output"), "CandS.root");
  jc.Path.Attach("Reco1", "CandOut");

  //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 "
                 "FitTrackSAListModule::Reco "
                 "NtpFitSAModule::Reco "
		 "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


  jc.Path("NtpSR").Mod("FitTrackSAListModule").Set("ListIn=CandFitTrackCamList");
  //  jc.Path("NtpSR").Mod("Output").Set("FileName=ntpSA.root");
  // jc.Path.Attach("Reco","NtpSA");
  jc.Path("NtpSR").Mod("FitTrackSAListModule").Report();

  const char *BaseRel = getenv("SRT_BASE_RELEASE");
  const char *RootRel = getenv("ROOTSYS");

  string RootVer(RootRel);
  RootVer.replace(0,RootVer.rfind("/")+1,"");

  char RecTitle[100];
  sprintf(RecTitle, "RecordTitle=CEDAR_PHY(minossoft:%s,root:%s,Daikon,SAFitter)", BaseRel, RootVer.c_str());

  jc.Path("NtpSR").Mod("NtpStModule").Set(RecTitle);

  SetNtpStOutputNoBNtpSA(jc.Path("NtpSR").Mod("Output"), "ntupleStS.root");
  jc.Path.Attach("Reco1","NtpSR");

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

  /////////////////////////////////////////////////////
  ///         Attach the MRCC code                  ///

  AttachMRCCPath(jc, RecTitle);
  jc.Path.Attach("Reco1", "muonremoval");

  SetMSGLevels(jc);

  //Other Run Options
  //  jc.Path("All").Run(100);  //Run over the first 100 snarls
  jc.Input.Next(nSkip);  //Skip 10 Snarls
  jc.Path("Reco").Run(nRun);
  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("libGeoGeometry");
  gSystem->Load("libNumericalMethods");
  gSystem->Load("libSwimmer");
  gSystem->Load("libDeMux");
  gSystem->Load("libCandStripSR");
  gSystem->Load("libCandSliceSR");
  gSystem->Load("libCandChop");
  gSystem->Load("libCandTrackSR");
  gSystem->Load("libCandTrackCam");
  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("libDcsUser");
  gSystem->Load("libCandMorgue");
  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("libMuonRemoval");
  gSystem->Load("libMuonRemovalModule");
  gSystem->Load("libCandShield");
  gSystem->Load("libAltDeMux");
  gSystem->Load("libFiltration");
  gSystem->Load("libNtpFitSA");
  gSystem->Load("libCandFitTrackSA");
  gSystem->Load("libNtpFitSAModule");
}



void SetCalibrator()
{
  Calibrator& cal = Calibrator::Instance();
  cal.Set("TimeCalibrator", "SimpleCalScheme");
  //PeCalibrator changed April 23,2007
  cal.Set("PeCalibrator", "PEGainAggCalScheme");
  //cal.Set("PeCalibrator",   "PEGainCalScheme");
  cal.Set("VALinCalibrator","SimpleCalScheme");
  cal.Set("DriftCalibrator","MuonDriftCalScheme");
  cal.Set("LinCalibrator",  "PulserLinearityCalScheme");
  cal.Set("StripCalibrator","StripToStripCalScheme");
  cal.Set("AttenCalibrator","StripAttenCalScheme");
  cal.Set("MIPCalibrator",  "MIPCalScheme");
  cal.Set("Thermometer",    "SimpleCalScheme");


}


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=NtpBDLite,Cand,Config,DaqSnarl");
  jcm.Set("FileName="+file);
}

void SetCandOutputNoBNtp(JobCModule &jcm, TString file){

  jcm.Cmd("DefineStream Config ConfigRecord");
  jcm.Set("Streams=SimSnarl,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 SetNtpStOutputNoBNtpSA(JobCModule &jcm, TString file){
  jcm.Cmd("DefineStream NtpSt NtpStRecord");
   jcm.Cmd("DefineStream NtpFitSA NtpFitSARecord");
  jcm.Set("Streams=NtpSt,NtpFitSA");
  //  jcm.Set("Streams=NtpFitSA");
  jcm.Set("FileName="+file);

  //jc.Path("NtpSR").Mod("Output").Cmd("DefineStream NtpFitSA NtpFitSARecord");
  //  jc.Path("NtpSR").Mod("Output").Set("Streams=NtpFitSA");

}

void SetMSGLevels(JobC &jc){

  jc.Msg.SetLevel("Plex","Error");




  //jc.Msg.SetLevel("FitTrackCamListModule","Error");
  jc.Msg.SetLevel("FitTrackSR","Warning");
  jc.Msg.SetLevel("NoiseFilter","Fatal");
  jc.Msg.SetLevel("Cand","Error");
  jc.Msg.SetLevel("Calibrator","Fatal");
  jc.Msg.SetLevel("Dbi","Fatal");
  jc.Msg.SetLevel("DetSim","Error");
  jc.Msg.SetLevel("Reroot","Error");
  jc.Msg.SetLevel("Photon","Warning");

  jc.Msg.SetLevel("Plex","Error");

  jc.Msg.SetLevel("AltDeMuxModule","Error");
  jc.Msg.SetLevel("AltDeMux","Fatal");
  jc.Msg.SetLevel("AlgAltDeMux","Fatal");
  jc.Msg.SetLevel("AlgShowerSS", "Warning");
  jc.Msg.SetLevel("SubShowerSR","Error");
  jc.Msg.SetLevel("AlgFitTrackSR", "Warning");

  jc.Msg.SetLevel("FitTrackSA","Error");

        jc.Msg.SetLevel("RmMu","Fatal");
        jc.Msg.SetLevel("AlgRmMu","Fatal");

}
void AttachMRCCPath(JobC &jc, char* RecTitle){

   jc.Path.Create("muonremoval",
                 "FiltTriggerPrescale::Ana ");

   jc.Path.Create("muonreco",
                 "RemoveMuon::Reco "
                 "StripCands::Reco "
                   "StripSRListModule::Reco "
                 "SliceSRListModule::Reco "
                 "TrackCamListModule::Reco "
                 "FitTrackCamListModule::Reco "
                 "ClusterSRListModule::Reco "
                 "SubShowerSRListModule::Reco "
                 "ShowerSRListModule::Reco "
                 "EventSRListModule::Reco "
                 "RecordSetupModule::Reco "
                   "NtpStModule::Get "
                 "NtpSRModule::Reco "
                 "NtpMCModule::Reco " //Necessary to write the MC info tree
                 "NtpTHModule::Reco " //Necessary to write the MC th tree
//                 "FitTrackSAListModule::Reco "
//                 "NtpFitSAModule::Reco "
                 "NtpMRModule::Reco "
                 "Output::Put "
                 );


  jc.Path.Attach("muonremoval", "muonreco");
  //configure filters

  jc.Path("muonremoval").SetAllFilters(1);

  jc.Path("muonremoval").Mod("FiltTriggerPrescale").Set("Spill_N=1    Spill_M=1");

  jc.Path("muonreco").SetAllFilters(0);

  //configure my code
  jc.Path("muonreco").Mod("RemoveMuon").Set("StripListOut=stripdigitlist");
  jc.Path("muonreco").Mod("StripCands").Set("keepdigitlist=stripdigitlist");

  //Post Muon removal reconstruction
  jc.Path("muonreco").Mod("StripSRListModule").Set("ListIn=canddigitlist");
  jc.Path("muonreco").Mod("SliceSRListModule").Set("SliceListAlgConfig=FarBeam");
  jc.Path("muonreco").Mod("SliceSRListModule").Set("ListIn=CandStripList");
  jc.Path("muonreco").Mod("TrackCamListModule").Set("TrackListAlgConfig=default");
  jc.Path("muonreco").Mod("TrackCamListModule").Set("NameListIn=CandSliceList");
  jc.Path("muonreco").Mod("TrackCamListModule").Set("NameListOut=CandTrackSRList");
  jc.Path("muonreco").Mod("FitTrackCamListModule").Set("NameListIn=CandTrackSRList");
  jc.Path("muonreco").Mod("ClusterSRListModule").Set("ClusterListAlgConfig=FarBeam");
  jc.Path("muonreco").Mod("SubShowerSRListModule").Set("SubShowerSRListAlgConfig=default");
  jc.Path("muonreco").Mod("ShowerSRListModule").Set("ShowerListAlgorithm=AlgShowerSSList");
  jc.Path("muonreco").Mod("ShowerSRListModule").Set("ShowerListAlgConfig=default");
  jc.Path("muonreco").Mod("ShowerSRListModule").Set("ListOut=CandShowerSRList");
  jc.Path("muonreco").Mod("EventSRListModule").Set("EventListAlgorithm=AlgEventSSList");
  jc.Path("muonreco").Mod("EventSRListModule").Set("EventListAlgConfig=FarBeam");

  //configure output
  string outputfilename = "FileName=ntupleMRNT.root";
  jc.Path("muonreco").Mod("Output").Set(outputfilename.c_str());
  jc.Path("muonreco").Mod("NtpStModule").Set(RecTitle);
  jc.Path("muonreco").Mod("NtpStModule").Set("RecordName=MuonRemoved");
  jc.Path("muonreco").Mod("NtpSRModule").Set("UseStandard=1");
  jc.Path("muonreco").Mod("NtpSRModule").Set("RecordName=MuonRemoved");

  jc.Path("muonreco").Mod("Output").Cmd("DefineStream NtpSt NtpStRecord MuonRemoved");
  jc.Path("muonreco").Mod("Output").Cmd("DefineStream NtpMR NtpMRRecord");
  jc.Path("muonreco").Mod("Output").Set("Streams=NtpSt,NtpMR");

}


