// FileName: reco_near_Spill_Chopped_R1_18_3.C
// Created by: Joshua Boehm
// Last Modified: February 10, 2006
                                                                                
// Usage
// cp <path>/reco_near_Spill_Chopped_R1_18_3.C reco_spill.C
// loon -bq "reco_spill.C()" <data_file>
                                                                               
/////////////////////////////////////////////////////////
// Description of this file:                           //
// This file will produce a Spill stream (events that  //
//  make it through the spill trigger). This is        //
//  only meant to do NearDet processing in R1-18-3.    //
//  Processing occurs through a single path "Spill"    //
//  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                                //
//        CandChop                                     //
//                                                     //
// Output:                                             //
// This file produces BeamNtp Information in each      //
//   output stream                                     //
// 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_spill(){

  //normal reco is a subset
  LoadLibraries();  //Needs to be called first

  JobC jc;  

  //Creating Path

  jc.Path.Create("Spill",
                 "RecordSetupModule::Get "
                 "NeardetBeamSelect::Ana "
		 "DigitListModule::Get "
		 "DigitListModule::Reco "
                 "FilterDigitListModule::Reco "
                 "ChopModule::Reco "
		 "SliceFromChopModule::Reco "                 
                 "TrackSRListModule::Reco "
                 "FitTrackSRListModule::Reco "
                 "ClusterSRListModule::Reco "
                 "SubShowerSRListModule::Reco "	 
                 "ShowerSRListModule::Reco "     
                 "EventSRListModule::Reco "
                 "RecordSetupModule::Reco "
                 "NtpBDLite::Reco "		 
                 "Output::Put "
		);

  // Note that the order Track/FitTrack/Cluster/Shower matters. 
 
  //Input Parameters
  jc.Input.Set("Format=input");
  jc.Input.Set("Streams=DaqSnarl");

  //////////////////////////////////////////////
  // Set up the Calibrator 
   Calibrator& cal = Calibrator::Instance();
   cal.Set("TimeCalibrator", "PulserTimeCalScheme");
   cal.Set("PeCalibrator",   "PEGainCalScheme");
   cal.Set("VALinCalibrator","VaLinearityCalScheme");
   cal.Set("DriftCalibrator","SimpleCalScheme"); // -> NOT default
   cal.Set("LinCalibrator",  "SimpleCalScheme"); // -> NOT default
   cal.Set("StripCalibrator","StripToStripCalScheme");
   cal.Set("AttenCalibrator","StripAttenCalScheme");
   cal.Set("MIPCalibrator",  "MIPCalScheme");
   cal.Set("Thermometer",    "TemperatureCalScheme");
   cal.Set("TimeCalibrator=SimpleCalScheme");

  //End of Calibrator Setup
  //////////////////////////////////////////////

  //Filter out non-Beam spill events - all other filters off
  jc.Path("Spill").SetAllFilters(0);
  jc.Path("Spill").Node("NeardetBeamSelect::Ana").FilterOn();    


  //////////////////////////////////////
  //Configure Reconstruction Software for Near Det Beam data .
  jc.Path("Spill").Mod("ClusterSRListModule").Set("ClusterListAlgConfig=NearBeam");
  jc.Path("Spill").Mod("TrackSRListModule").Set("TrackListAlgConfig=NearBeam");
  jc.Path("Spill").Mod("FitTrackSRListModule").Set("FitTrackListAlgConfig=NearBeam");
  jc.Path("Spill").Mod("EventSRListModule").Set("EventListAlgConfig=NearBeam");

  //The following settings are meant for use when using the CandSubShower Package
  jc.Path("Spill").Mod("SubShowerSRListModule").Set("SubShowerSRListAlgConfig=default");
  jc.Path("Spill").Mod("ShowerSRListModule").Set("ShowerListAlgorithm=AlgShowerSSList");
  jc.Path("Spill").Mod("ShowerSRListModule").Set("ShowerListAlgConfig=default");
  jc.Path("Spill").Mod("ShowerSRListModule").Set("ListOut=CandShowerSRList");
  
  //DigitListModule parameters
  jc.Path("Spill").Mod("DigitListModule").Set("ListsToMake=1"); 

  jc.Path("Spill").Mod("FilterDigitListModule").Set("FilterDigitListAlgorithm=AlgFilterDigitList");
  jc.Path("Spill").Mod("FilterDigitListModule").Set("FilterDigitListAlgConfig=NearDet");
  jc.Path("Spill").Mod("FilterDigitListModule").Set("SwitchPersToTemp=1"); //

  jc.Path("Spill").Mod("ChopModule").Set("ChopAlgorithm=AlgChopListSharp2");
  //  End of Configuration settings for main reconstruction //
  ////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////
  // Display the Configuration of modules
  jc.Path("Spill").Mod("FilterDigitListModule").Report();
  jc.Path("Spill").Mod("ShowerSRListModule").Report();
  jc.Path("Spill").Mod("TrackSRListModule").Report();
  jc.Path("Spill").Mod("FitTrackSRListModule").Report();
  jc.Path("Spill").Mod("SubShowerSRListModule").Report();
  ///////////////////////////////////////////////////////////////


  /////////////////////////////////////////////////
  //    Setting the Output Paths                 //
  //  - This script produces 3 output files      // 
  //    this will become the cand, cntp, cnts    //
  //     files for near det                      //
  /////////////////////////////////////////////////

  //Set Candidate Output to CandA.root (all unfiltered snarls included in output)
  //this will become the .cand. file
  SetCandOutputWithBNtp(jc.Path("Spill").Mod("Output"), "CandS.root"); 

  //Ntuple record has its own output file so needs its own output module
  jc.Path.Create("bNtpSR",
                 "NtpStModule::Get "
                 "NtpSRModule::Reco "
                 "Output::Put ");

  jc.Path("bNtpSR").Mod("NtpSRModule").Set("UseStandard=1"); // use NtpSt
  jc.Path("bNtpSR").SetAllFilters(false);

  //Set the ntuple output to ntupleStS.root (unfiltered Snarls included in output)
  // this will become the .sntp. file
  SetNtpStOutputWithBNtp(jc.Path("bNtpSR").Mod("Output"), "ntupleStS.root");
  jc.Path.Attach("Spill","bNtpSR");

  // Ntuple abridged record
  jc.Path.Create("bNtpSRFilter",
                 "NtpStFilterModule::Reco "
                 "Output::Put ");

  //Sets the output to ntupleStS.sub.root (all of the Snarls included)
  // this will become the .snts. file
  SetNtpStOutputWithBNtp(jc.Path("bNtpSRFilter").Mod("Output"), "ntupleStS.sub.root");
  jc.Path.Attach("Spill", "bNtpSRFilter");

  //////////////////////////////////////////////////////
  ///         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("Spill").Run(10000);
  jc.Path("Spill").Report();
  jc.Msg.Stats(); //Output the message statistics to see what is generating output

}















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

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


int LoadLibraries()
{
// Link dynamic libraries

  //far Cam Libraries
  gSystem->Load("libDataUtil");
  gSystem->Load("libRecoBase");
  gSystem->Load("libNoiseFilter");
  gSystem->Load("libFilterDigitSR");
  gSystem->Load("libBField");
  gSystem->Load("libNumericalMethods");
  gSystem->Load("libSwimmer");
  gSystem->Load("libFilterLI");
  gSystem->Load("libCandStripSR");
  gSystem->Load("libCandChop");
  gSystem->Load("libCandSliceSR");
  gSystem->Load("libCandTrackSR");
  gSystem->Load("libCandClusterSR");
  gSystem->Load("libCandSubShowerSR");
  gSystem->Load("libCandShowerSR");
  gSystem->Load("libCandFitTrackSR");
  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("libCandNtupleSRModule");
  gSystem->Load("libTruthHelperNtupleModule");
  gSystem->Load("libStandardNtupleModule");

  gSystem->Load("libFiltration");
  gSystem->Load("libCandShield");     // Only to be used R1.17+
  gSystem->Load("libSpillTiming");
  gSystem->Load("libBeamDataUtil");   //Beam mon
  gSystem->Load("libBeamDataNtuple"); //Beam Mon
}

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=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){
  jc.Msg.SetLevel("NoiseFilter","Error");
  jc.Msg.SetLevel("Cand","Error");
  jc.Msg.SetLevel("Calibrator","Error");
  jc.Msg.SetLevel("Dbi","Error");
  jc.Msg.SetLevel("DetSim","Error");
  jc.Msg.SetLevel("Photon","Warning");
  jc.Msg.SetLevel("Per","Error");
  jc.Msg.SetLevel("Io", "Error");
  jc.Msg.SetLevel("Plex","Error");
  jc.Msg.SetLevel("FitTrackSR","Warning");
  jc.Msg.SetLevel("AlgFitTrackSR","Warning"); 
  jc.Msg.SetLevel("AlgFilterDigitList","Warning");
  jc.Msg.SetLevel("AlgShowerSS","Error");
  jc.Msg.SetLevel("SubShowerSR","Error");
  jc.Msg.SetLevel("AlgShowerSS", "Warning");
}
