// FileName: reco_near_Cosmic_cedar.C
// Last Modified: Sept 14, 2006
// Most Recent Modifications:
// Sept. 14, 2006: (JAB) Removing Snts
// August 25, 2006: (JAB) Branching for Cedar and
//                         setting fTitle
// July 20, 2006: (JAB) Branched to run in R1-24
// July  3, 2006: (JAB) Modified to Use DataQualityReader (AB code)

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

/////////////////////////////////////////////////////////
// Description of this file:                           //
// This file will produce a Cosmic stream (no spill    //
//  data included based on the spill trigger). This is //
//  only meant for NearDet processing in Cedar         //
//  Processing occurs through a single path "Cosmic"   //
//  No filtering applied outside of finding the spills //
//  Each output stream requires its own processing     //
//   branch and so there are small offshoot branches   //
// Uses: CandFitTrackCam                               //
//       CandTrackCam                                  //
//       GeoGeometry (in reco)                         //
//       DataQualityReader                             //
//                                                     //
// 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 SetMSGLevels(JobC &jc);

void reco_all()
{
  reco_near_Cosmic_cedar();
}

void reco_near_Cosmic_cedar()
{

  LoadLibraries();  //Needs to be called first

  JobC jc;

  //Creating Path

  jc.Path.Create("Cosmic",
                 "DataQualityReader::Reco " 
                 "RecordSetupModule::Get "
                 "NoiseFilterModule::Ana "			   
                 "NeardetBeamSelect::Ana "
                 "FiltTriggerPrescale::Ana "
                 "DigitListModule::Get "
                 "DigitListModule::Reco "
                 "FilterDigitListModule::Reco "
                 "StripSRListModule::Reco "
                 "SliceSRListModule::Reco "
                 "TrackCamListModule::Reco "
		 "FitTrackCamListModule::Reco "
                 "ClusterSRListModule::Reco "
		 "ShowerSRListModule::Reco "
		 "EventSRListModule::Reco "		 
                 "RecordSetupModule::Reco "
                 "NtpBDLite::Reco "		 
		 );

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

  SetCalibrator();

  // Set Ugli to use only database.
  UgliLoanPool::SetAlwaysUseDbi(true);                                   
  // Use GeoGeometry for reconstruction instead of UgliGeometry
  UgliLoanPool::Instance()->SetUseGeo(true);


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

  jc.Path("Cosmic").Mod("DataQualityReader").Set("FilterOnOff=1");
  jc.Path("Cosmic").Node("DataQualityReader::Reco").FilterOn();

  ///////////////////////////////////////////////
  //  Setting Primary Filtering Configuration
  //  - Reverse the Beam Spill Filter to remove spill events   
  jc.Path("Cosmic").Node("NeardetBeamSelect::Ana").ReverseFilter();
  //  - Set Prescaling to remove 7/8 of the events based on Planes and Activity triggering
  jc.Path("Cosmic").Mod("FiltTriggerPrescale").Set("Plane_N=1    Plane_M=8");
  jc.Path("Cosmic").Mod("FiltTriggerPrescale").Set("Activity_N=1 Activity_M=8");
  //End of Prescaling and Beam Filtering
  ///////////////////////////////////////////////  

  ///////////////////////////////////////////////
  // Starting Configuration of the Cosmic Path //     

  //////////////////////////////////////
  //Configure Reconstruction Software for Near Det Cosmics data .
  jc.Path("Cosmic").Mod("SliceSRListModule").Set("SliceListAlgConfig=NearCosmic");
  jc.Path("Cosmic").Mod("ClusterSRListModule").Set("ClusterListAlgConfig=NearCosmic");
  jc.Path("Cosmic").Mod("ShowerSRListModule").Set("ShowerListAlgConfig=NearCosmic");
  jc.Path("Cosmic").Mod("FitTrackCamListModule").Set("NameListIn=CandTrackSRList");
  jc.Path("Cosmic").Mod("EventSRListModule").Set("EventListAlgConfig=NearCosmic");

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

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

  //DigitListModule parameters
  jc.Path("Cosmic").Mod("DigitListModule").Set("ListsToMake=1");
  jc.Path("Cosmic").Mod("StripSRListModule").Set("ListIn=canddigitlist");

  //Cosmics's filter digit list parameters
  jc.Path("Cosmic").Mod("FilterDigitListModule").Set("FilterDigitListAlgorithm=AlgFilterDigitList");
  jc.Path("Cosmic").Mod("FilterDigitListModule").Set("FilterDigitListAlgConfig=NearDet");
  jc.Path("Cosmic").Mod("FilterDigitListModule").Set("SwitchPersToTemp=1"); 
  //Don't write out original CandDigitList.

  //  End of Configuration settings for main reconstruction //
  ////////////////////////////////////////////////////////////


  ////////////////////////////////////////////////////////////////
  //Display the Configuration of modules
  jc.Path("Cosmic").Mod("FilterDigitListModule").Report();
  jc.Path("Cosmic").Mod("StripSRListModule").Report();
  jc.Path("Cosmic").Mod("ShowerSRListModule").Report();
  jc.Path("Cosmic").Mod("TrackCamListModule").Report();
  jc.Path("Cosmic").Mod("FitTrackCamListModule").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
  jc.Path.Create("CandOut",
                 "Output::Put "
                 );
  SetCandOutputNoBNtp(jc.Path("CandOut").Mod("Output"), "CandA.root");
  jc.Path.Attach("Cosmic", "CandOut");
  

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

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

  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(minossoft:%s,root:%s)", BaseRel, RootVer.c_str());
                                                                                
  jc.Path("cNtpSR").Mod("NtpStModule").Set(RecTitle);


  //Set the ntuple output to ntupleStA.root (all of the Snarls included in output)
  // this will become the .cntp. file
  SetNtpStOutputWithBNtp(jc.Path("cNtpSR").Mod("Output"), "ntupleStA.root");
  jc.Path.Attach("Cosmic","cNtpSR");

  //////////////////////////////////////////////////////
  ///         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 10 Snarls

  jc.Path("Cosmic").Run();
  jc.Path("Cosmic").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("libCandSliceSR");
  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("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("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");
  jc.Msg.SetLevel("DataQuality", "Warning");

}

void SetCalibrator()
{
     Calibrator& cal = Calibrator::Instance();
     cal.Set("TimeCalibrator", "PulserTimeCalScheme");
     cal.Set("PeCalibrator",   "PEGainCalScheme");
     cal.Set("VALinCalibrator","SimpleCalScheme");
     cal.Set("DriftCalibrator","MuonDriftCalScheme");
     cal.Set("LinCalibrator",  "QuadLinearityCalScheme");
     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");
}
