// FileName: reco_far_all_cedar_phy_srsafitter.C
// Last Modified: April 23, 2007
// Most Recent Modifications:
// Jan. 09, 2007: (JAB) Adding some data quality commands from A. Blake
// Oct.  26, 2006: (JAB) Fixing CandChop LI setting
// Sept. 14, 2006: (JAB) Removing Snts
// August 25, 2006: (JAB) Branching for Cedar and
//                         setting fTitle
// July 20, 2006: (JAB) Branching for R1-24 running

// Usage
// cp <path>/reco_far_all_cedar_phy_srsafitter.C reco_all.C
// loon -bq "reco_all.C()" <data_file>

/////////////////////////////////////////////////////////
// Description:                                        //
// This file will produce an All stream (both spill    //
//  and cosmic events) but all processed with the      //
//  settings for the cosmic reconstruction. This is    //
//  only meant to do FarDet processing in Cedar        //
//  Processing occurs through a single path "All"      //
//  Each output stream requires its own processing     //
//   branch and so there are small offshoot branches   //
// Uses: CandChop                                      //
//       CandTrackCam                                  //
//       CandFitTrackCam                               //
//       GeoGeometry (in reco)                         //
//       DataQualityReader                             //
// Demuxer: Alt/Cambridge                              //
//  
// Does sa fitter
//                                                     //
// Output:                                             //
// This file produces BeamNtp Information in each      //
//   output stream                                     //
// Output Files:                                       //
//  CandA.root - candidate output file                 //
//  ntupleStA.root - NtpSt ntuple output               //
/////////////////////////////////////////////////////////

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 SetNtpStOutputWithBNtpSA(JobCModule &jcm, TString file);


void SetMSGLevels(JobC &jc);

void reco_all(int nSkip=0, int nRun=100000)
{
  reco_far_all_cedar_phy(nSkip, nRun);
}

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

  JobC jc;

  //The Normal Reco chain
  jc.Path.Create("All",
                 "DataQualityReader::Reco "
                 "NoiseFilterModule::Ana "
		 "RecordSetupModule::Get "
		 "DigitListModule::Get "
		 "DigitListModule::Reco "
                 "FilterDigitListModule::Reco "
                 "FilterLIModule::Ana "
		 "ChopModule::Reco "
		 "BiggestChopModule::Reco "
		 "DeMuxDigitListModule::Reco "
		 "StripSRListModule::Reco "
		 "SliceSRListModule::Reco "
		 "TrackCamListModule::Reco "
		 "FitTrackCamListModule::Reco "
		 "ClusterSRListModule::Reco "
		 "ShowerSRListModule::Reco "
		 "EventSRListModule::Reco "
		 "RecordSetupModule::Reco "
                 "NtpBDLite::Reco "             // Fills BeamMon Ntuple
		 );

  //Input Parameters
  jc.Input.Set("Format=input");
  jc.Input.Set("Streams=DaqSnarl,DaqMonitor,LightInjection");   //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
  ///////////////////////////////////////////////////////////


  //////////////////////////////////////
  //Configure Reconstruction Software for Far Det MC "All" data .
  // For a full description of the different possible module options see the 
  //   Document:  ConfigOptions.txt
  
  jc.Path("All").SetAllFilters(1); 
  jc.Path("All").Mod("DataQualityReader").Set("FilterOnOff=1");
  //The next line removes snarls with >10,000 digits generated 
  //  during the development of the spill trigger
  jc.Path("All").Mod("DataQualityReader").Set("FilterWord=4096");
  jc.Path("All").Node("DataQualityReader::Reco").FilterOn();


  jc.Path("All").Mod("FilterLIModule").Set("LIFinderName=SimplePatternFinder");
  //This setting provided by Andy Blake 1/9/2007 to filter out the bulk of the Light Injection
  jc.Path("All").Mod("FilterLIModule").Set("MaxNDigits=1100");

  //Additional Configuration settings supplied by Nathaniel 
  jc.Path("All").Mod("ChopModule").Set("ChopAlgorithm=AlgChopListFar");
  jc.Path("All").Mod("BiggestChopModule").Set("MinEnergy=0.0"); //No cut.
  jc.Path("All").Mod("BiggestChopModule").Set("OmitLiEvents=1"); //kill LI
  jc.Path("All").Mod("BiggestChopModule").Set("LiVetoWindowLow=-1.0e-6");
  jc.Path("All").Mod("BiggestChopModule").Set("LiVetoWindowHigh=31.0e-6");

  jc.Path("All").Mod("SliceSRListModule").Set("SliceListAlgConfig=FarCosmic");
  jc.Path("All").Mod("ClusterSRListModule").Set("ClusterListAlgConfig=FarCosmic");

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

  jc.Path("All").Mod("FitTrackCamListModule").Set("NameListIn=CandTrackSRList");
  jc.Path("All").Mod("EventSRListModule").Set("EventListAlgorithm=AlgEventSRList");
  jc.Path("All").Mod("EventSRListModule").Set("EventListAlgConfig=FarCosmic");
  jc.Path("All").Mod("ShowerSRListModule").Set("ShowerListAlgConfig=FarCosmic");

  jc.Path("All").Mod("FilterDigitListModule").Set("FilterDigitListAlgorithm=AlgFilterDigitListSR");
  jc.Path("All").Mod("FilterDigitListModule").Set("SwitchPersToTemp=1");
  jc.Path("All").Mod("DeMuxDigitListModule").Set("SwitchPersToTemp=1");
  jc.Path("All").Mod("DeMuxDigitListModule").Set("NameListOut=altdemux");
  jc.Path("All").Mod("DeMuxDigitListModule").Set("DeMuxDigitListAlgConfig=devel");
  jc.Path("All").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("All").Mod("DeMuxDigitListModule").Report();
  jc.Path("All").Mod("StripSRListModule").Report();
  jc.Path("All").Mod("ShowerSRListModule").Report();
  jc.Path("All").Mod("TrackCamListModule").Report();
  jc.Path("All").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 "
                 );
  SetCandOutputWithBNtp(jc.Path("CandOut").Mod("Output"), "CandA.root");
  jc.Path.Attach("All", "CandOut");

  //Ntuple record has its own output file so needs its own output module
  jc.Path.Create("sNtpSR",
                 "NtpStModule::Get "
                 "NtpSRModule::Reco "
                //      "Output::Put "
                 "FitTrackSAListModule::Reco "
                 "NtpFitSAModule::Reco "
		 "Output::Put "
		 );
  jc.Path("sNtpSR").Mod("NtpSRModule").Set("UseStandard=1"); // use NtpSt

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



  //picks up new HV table April 23, 2007
  jc.Path("sNtpSR").Mod("NtpSRModule").Set("HvSinglesTask=1");


  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)", BaseRel, RootVer.c_str());
                                                                                
  jc.Path("sNtpSR").Mod("NtpStModule").Set(RecTitle);

  SetNtpStOutputWithBNtpSA(jc.Path("sNtpSR").Mod("Output"), "ntupleStA.root");
  jc.Path.Attach("All","sNtpSR");


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

  SetMSGLevels(jc);
  
  jc.Input.Next(nSkip);  //Skip nSkip Snarls
  jc.Path("All").Run(nRun);
  jc.Path("All").Report();

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

}


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

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

int LoadLibraries()
{

  gSystem->Load("libDcsUser");
  gSystem->Load("libCandMorgue");

  // Link dynamic libraries
  gSystem->Load("libDataUtil");
  gSystem->Load("libRecoBase");
  gSystem->Load("libNoiseFilter");
  gSystem->Load("libFarDetDataQuality");
  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("libCandShield");
  gSystem->Load("libAltDeMux");  
  gSystem->Load("libFiltration"); 

  gSystem->Load("libSpillTiming.so");
  gSystem->Load("libBeamDataNtuple");
  gSystem->Load("libBeamDataAnaSummary.so");
  gSystem->Load("libBeamDataUtil.so");
  gSystem->Load("libNtpFitSA");
  gSystem->Load("libCandFitTrackSA");
  gSystem->Load("libNtpFitSAModule");

}

void SetCalibrator()
{
  Calibrator& cal = Calibrator::Instance();

  cal.Set("TimeCalibrator", "PulserTimeCalScheme");
   //PeCalibrator changed April 23,2007
  cal.Set("PeCalibrator", "PEGainAggCalScheme");
  // cal.Set("PeCalibrator",   "PEGainCalScheme");
  cal.Set("VALinCalibrator","VaLinearityCalScheme");
  cal.Set("DriftCalibrator","MuonDriftCalScheme");
  cal.Set("LinCalibrator",  "PulserLinearityCalScheme");
  cal.Set("StripCalibrator","StripToStripCalScheme");
  cal.Set("AttenCalibrator","StripAttenCalScheme");
  cal.Set("MIPCalibrator",  "MIPCalScheme");
  cal.Set("Thermometer",    "TemperatureCalScheme");
                                                                                
  // Sets it to use Andy Blake's timing constants
  //    the alternative being Brians
  Calibrator::TimeCalibrator().Set("MuonTask=Andys");
  //This turns on Andy Blakes time-walk correction
  Calibrator::TimeCalibrator().Set("DoWalkCorrection=1");
  //This turns on 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");


	

}


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 SetNtpStOutputWithBNtpSA(JobCModule &jcm, TString file){
  jcm.Cmd("DefineStream NtpSt NtpStRecord");
  jcm.Cmd("DefineStream NtpBDLite NtpBDLiteRecord");
  jcm.Cmd("DefineStream NtpFitSA NtpFitSARecord");
  jcm.Set("Streams=NtpBDLite,NtpSt,NtpFitSA");  
  jcm.Set("FileName="+file);
}


void SetMSGLevels(JobC &jc){
  //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("DataQuality","Warning");
  jc.Msg.SetLevel("FitTrackSA","Error");
}
