// FileName: reco_far_Alt_CandSub_Spill_Blind_R1_18.C
// Created by: Joshua Boehm
// Last Modified: July 18, 2005
                                                                               
// Usage
// cp <path>/reco_far_Alt_CandSub_Spill_Blind_R1_18.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 FarDet processing in R1-18.       //
//  Processing occurs through a single path "Spill"    //
//  A second path "blindpath" splits off at the end    //
//  and this path generates the smaller open files     //
//  No filtering applied outside of finding the spills //
//    or blinding                                      //
//  Each output stream requires its own processing     //
//   branch and so there are small offshoot branches   //
// Uses: CandSubShower Module                          //
// Demuxer: Alt/Cambridge                              //
//                                                     //
// Output:                                             //
// This file produces BeamNtp Information in each      //
//   output stream                                     //
// Output Files:                                       //
//  CandS.root - candidate output file (open)       //
//  ntupleStS.root - NtpSt ntuple output  (open)       //
//  ntupleStS.sub.root - trimmed NtpSt (open)          //
//                                                     //
//  CandSBlind.root - candidate output file (closed)//
//  ntupleStSBlind.root - NtpSt ntuple output  (closed)//
//  ntupleStSBlind.sub.root - trimmed NtpSt (closed)   //
/////////////////////////////////////////////////////////

class JobC;

int LoadLibraries();
int GetRunNumber();

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(){

  LoadLibraries();  //Needs to be called first

  JobC jc;

  //Creating Paths
  jc.Path.Create("Spill",
                 "RecordSetupModule::Get "
                 "FardetBeamSelect::Ana "      //Finds the Spill Events
                 "DigitListModule::Get "
                 "DigitListModule::Reco "
		 "FilterDigitListModule::Reco "
		 "DeMuxDigitListModule::Reco "
		 "StripSRListModule::Reco "     //The order of these are 
		 "SliceSRListModule::Reco "     //  very important
		 "TrackSRListModule::Reco "     // DO NOT CHANGE IT
		 "FitTrackSRListModule::Reco "  //strip, slice, track,
		 "ClusterSRListModule::Reco "   //fittrack, Cluster,
                 "SubShowerSRListModule::Reco "	//(SubShw), Shw, Event	 
		 "ShowerSRListModule::Reco "
                 "EventSRListModule::Reco "
                 "RecordSetupModule::Reco "
                 "NtpBDLite::Reco "             // Fills BeamMon Ntuple
		 "Output::Put "
		);

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

  // Protection for old runs to use the correct B field settings
  int runNumber = GetRunNumber();  
  
  ///////////////////////////////////////////////////////////
  //  This checks to make sure the B field is set to zero 
  //     when sm2 had no field  
  //Set B=0 for SM2 if runNumber < 17566
  if (runNumber < 17566) {
    UgliLoanPool* uglipool = UgliLoanPool::Instance(); //Redundant after 2005-01-12
    BfldLoanPool* bfldpool = BfldLoanPool::Instance();
    bfldpool->Set("NoFieldBeyondZ=15.3797");
    bfldpool->Update();
  }
  // End of Old file protection
  ///////////////////////////////////////////////////////////

  //////////////////////////////////////////////
  // Set up the Calibrator
  // The first line sets it to use Andy Blake's timing constants
  //    the alternative being Brians
  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");

  Calibrator::TimeCalibrator().Set("MuonTask=Andys");
  //This turns on Andy Blakes time-walk correction
  Calibrator::TimeCalibrator().Set("DoWalkCorrection=1");
  //This turns on the time jump table which corrects for hardware swaps
  //  through Fall 2004. (AB)
  Calibrator::TimeCalibrator().Set("UseJumps=1");
  //Turns on the automatic LI timewalk correction
  Calibrator::TimeCalibrator().Set("UsePulserCalibration=0");
  //End of Calibrator Setup
  //////////////////////////////////////////////

  ///////////////////////////////////////////////////////////
  // Starting Configuration of the Split Path //

  //These two lines turn off all Filters but the one that pulls out
  // the beam events from the cosmic background
  jc.Path("Spill").SetAllFilters(0);   //Turn off all filtering 
  // Then reactivate the spill filter
  jc.Path("Spill").Node("FardetBeamSelect::Ana").FilterOn();  
  
  //////////////////////////////////////
  //Configure Reconstruction Software for Far Det Beam data .
  // For a full description of the different possible module options see the 
  //   Document:  ConfigOptions.txt
  jc.Path("Spill").Mod("SliceSRListModule").Set("SliceListAlgConfig=FarBeam");
  jc.Path("Spill").Mod("ClusterSRListModule").Set("ClusterListAlgConfig=FarBeam");
  jc.Path("Spill").Mod("TrackSRListModule").Set("TrackListAlgConfig=FarBeam");
  jc.Path("Spill").Mod("FitTrackSRListModule").Set("FitTrackListAlgConfig=FarBeam");
  jc.Path("Spill").Mod("EventSRListModule").Set("EventListAlgConfig=FarBeam");
  jc.Path("Spill").Mod("DeMuxDigitListModule").Set("DeMuxDigitListAlgConfig=FarBeam");
  
  //Set up the conditions for 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");
  //End CandSubShower Settings
 
  //SwitchPersToTemp=1 Do not write out original CandDigitList
  //SwitchPersToTemp=0 Do write out original CandDigitList
  jc.Path("Spill").Mod("FilterDigitListModule").Set("SwitchPersToTemp=1"); 
  jc.Path("Spill").Mod("DeMuxDigitListModule").Set("SwitchPersToTemp=1");

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

//  jc.Path("Spill").Mod("DigitListModule").Set("ListsToMake=1"); 
  ////////////////////////////////////////////////////////////////

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

  /////////////////////////////////////////////////
  //    Setting the Output Paths                 //
  //  - This script produces both the blind and  // 
  //    unblind data sets and thus has 6 (2 x 3) //
  //    output files to generate                 //
  /////////////////////////////////////////////////


  /////////////////////////////////////////////////
  //   Setting the Output for all the Spill Data //
  //   This will consitute the Hidden/Closed     //
  //   files which are not to be used            //
  /////////////////////////////////////////////////

  //Set Candidate Output to CandSBlind.root (all of the Spill included in output)
  //this will become the .cand. file
  SetCandOutputWithBNtp(jc.Path("Spill").Mod("Output"), "CandSBlind.root");
 
 //Ntuple record has its own output file so needs its own output module
  jc.Path.Create("sNtpSR",
                 "NtpStModule::Get "
                 "NtpSRModule::Reco "
                 "Output::Put ");

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

  //Set the ntuple output to ntupleStBlind.root (all of the Spills included in output)
  // this will become the .sntp. file
  SetNtpStOutputWithBNtp(jc.Path("sNtpSR").Mod("Output"), "ntupleStSBlind.root");
  jc.Path.Attach("Spill","sNtpSR");
  
  ////////////////////////////////////////////////////
  //  Setting the Output Path with Blinding       ////
  //    These files have the blinding algorithm   ////
  //    applied and thus will be the open files   ////
  ////////////////////////////////////////////////////

  //Create a new path where the Blinding module may be used 
  //   all reco is of course the same
  jc.Path.Create("blindpath",
                 "Blinder::Ana "
                 "Output::Put ");

  //Explicitly turn on the Blinder Filtering
  jc.Path("blindpath").Node("Blinder::Ana").FilterOn();

  //Set Candidate Output to CandS.root (reduced number of Spills 
  //    are included in output)
  // This will become the ??.cand.?? file  
  SetCandOutputWithBNtp(jc.Path("blindpath").Mod("Output"), "CandS.root");  
  
  jc.Path.Create("blindSR",
//                   "NtpStModule::Get "
//                   "NtpSRModule::Reco "
                     "Output::Put ");

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

  //Set the ntuple output to ntupleSt.root (reduced number of Spills 
  //  included in output)
  // this will become the ??.sntp.?? file
  SetNtpStOutputWithBNtp(jc.Path("blindSR").Mod("Output"), "ntupleStS.root");   

  jc.Path.Attach("blindpath","blindSR");   //Attach to the blinded branch

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

  //Set the ntuple output to ntupleSt.root (reduced number of Spills 
  //  included in output)
  // this will become the ??.sntp.?? file
  SetNtpStOutputWithBNtp(jc.Path("blindNtpSRFilter").Mod("Output"), "ntupleStS.sub.root");    

  jc.Path.Attach("blindpath", "blindNtpSRFilter");  //Attach to the blinded Branch
   
  jc.Path.Attach("Spill", "blindpath"); //Attach the blinded branch to the Spill Path

  // Ntuple abridged record 
  jc.Path.Create("sNtpSRFilter",
                 "NtpStFilterModule::Reco "  //removes the strip info
                 "Output::Put ");

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


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

  SetMSGLevels(jc);

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

  jc.Path("Spill").Run();
  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("libFarDetDataQuality");
  gSystem->Load("libFilterDigitSR");
  gSystem->Load("libBField");
  gSystem->Load("libNumericalMethods");
  gSystem->Load("libSwimmer");
  gSystem->Load("libDeMux");
  gSystem->Load("libAltDeMux");  
  gSystem->Load("libFilterLI");
  gSystem->Load("libCandStripSR");
  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){

  //Configure the message service
  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("Reroot","Error");
  jc.Msg.SetLevel("Photon","Warning");
  jc.Msg.SetLevel("Per","Error");
  jc.Msg.SetLevel("Io", "Error");
  jc.Msg.SetLevel("DeMuxDigitListModule","Error");
  jc.Msg.SetLevel("Plex","Error");
  jc.Msg.SetLevel("FitTrackSR","Warning");
  jc.Msg.SetLevel("AlgFitTrackSR","Warning");

  jc.Msg.SetLevel("FilterLI", "Error");
  jc.Msg.SetLevel("LIPatternFinder","Error");
  jc.Msg.SetLevel("TrackSR","Warning");
  jc.Msg.SetLevel("ClusterSR","Error");
  jc.Msg.SetLevel("EventSR","Error");
  jc.Msg.SetLevel("SubShowerSR","Error");
  //jc.Msg.SetLevel("JobC","Warning");  //surpresses the final report
  jc.Msg.SetLevel("AltDeMuxModule","Error");
  jc.Msg.SetLevel("AltDeMux","Fatal");
  jc.Msg.SetLevel("AlgAltDeMux","Fatal");
  jc.Msg.SetLevel("AlgShowerSS", "Warning");

}

