///////////////////////////////////////////////////////////////////////
// $Id: TrackSRListModule.cxx,v 1.62 2005/06/24 02:54:08 urheim Exp $
//
// TrackSRListModule.cxx
//
// Begin_Html<img src="../../pedestrians.gif" align=center>
// <a href="../source_warning.html">Warning for beginners</a>.<br> 
//
// A JobControl Module for filling raw CandTrackSRList from
// CandSliceList.
//
// Author:  R. Lee 2001.02.26
//
// Also see <a href="../../root_crib/index.html">The ROOT Crib</a> and 
// <a href="../CandTrackSR.html"> CandTrackSR Classes</a> (part of
// <a href="../index.html">The MINOS Class User Guide</a>)End_Html
////////////////////////////////////////////////////////////////////////

#include <assert.h>
extern "C" {
#include <unistd.h>    // sysconf
#include <sys/times.h> // times()
}

#include "Algorithm/AlgConfig.h"
#include "Algorithm/AlgFactory.h"
#include "Algorithm/AlgHandle.h"
#include "Calibrator/Calibrator.h"
#include "CandData/CandHeader.h"
#include "CandData/CandRecord.h"
#include "CandDigit/CandDigitListHandle.h"
#include "CandTrackSR/CandTrackSRListHandle.h"
#include "CandTrackSR/CandTrackSRList.h"
#include "CandTrackSR/CandTrackSRHandle.h"
#include "CandTrackSR/TrackSRListModule.h"
#include "CandTrackSR/TrackClusterSR.h"
#include "Candidate/CandContext.h"
#include "Conventions/Munits.h"
#include "JobControl/JobCModuleRegistry.h"
#include "JobControl/JobCommand.h"
#include "MessageService/MsgService.h"
#include "MinosObjectMap/MomNavigator.h"
#include "RawData/RawDigit.h"
#include "RawData/RawHeader.h"
#include "RawData/RawRecord.h"
#include "RawData/RawChannelId.h"
#include "RawData/RawDaqSnarlHeader.h"
#include "RawData/RawDaqHeaderBlock.h"
#include "RawData/RawDigitDataBlock.h"
#include "RawData/RawVarcErrorInTfBlock.h"
#include "RecoBase/CandSliceHandle.h"
#include "RecoBase/CandSliceListHandle.h"
#include "RecoBase/CandStripHandle.h"
#include "RecoBase/CandStripListHandle.h"
#include "RecoBase/CandTrackHandle.h"
#include "RecoBase/CandTrackListHandle.h"
#include "RecoBase/LinearFit.h"
#include "UgliGeometry/UgliGeomHandle.h"
#include "UgliGeometry/UgliStripHandle.h"
#include "Validity/VldContext.h"

#include "MINF_Classes/MINFast.h"
#include "REROOT_Classes/REROOT_FluxWgt.h"
#include "REROOT_Classes/REROOT_NeuKin.h"
#include "REROOT_Classes/REROOT_NeuVtx.h"
#include "REROOT_Classes/REROOT_Event.h"


ClassImp(TrackSRListModule)

//......................................................................
CVSID("$Id: TrackSRListModule.cxx,v 1.62 2005/06/24 02:54:08 urheim Exp $");
JOBMODULE(TrackSRListModule, "TrackSRListModule",
         "Builds CandTrackSRList from CandSliceList");

//......................................................................
TrackSRListModule::TrackSRListModule()
{
}

//......................................................................
TrackSRListModule::~TrackSRListModule() 
{
}

//......................................................................
void TrackSRListModule::BeginJob() 
{
}

const Registry &TrackSRListModule::DefaultConfig() const
{

//
//  Purpose:    Method to return default configuration.
//
//  Arguments:  n/a
//
//  Return:     Registry item containing default configuration.
//

static Registry def_cfg;
  static bool been_here = false;
  if(been_here)return def_cfg;
  been_here=true;

  string name = this->JobCModule::GetName();
  name += ".config.default";
  def_cfg.SetName(name.c_str());

  // Set default
  def_cfg.Set("TrackListAlgorithm","AlgTrackSRList");
  def_cfg.Set("TrackListAlgConfig","default");
  def_cfg.Set("ListIn","CandSliceList");
  def_cfg.Set("ListOut","CandTrackSRList");
  def_cfg.Set("LogLevel","Fatal");
  return def_cfg;
}

//......................................................................
JobCResult TrackSRListModule::Reco(MomNavigator *mom)
{
   JobCResult result(JobCResult::kPassed);
// load configuration 
  const char* tmps = 0;
  const char* alg_name = 0;
  const char* alg_config_name = 0;
  const char* list_in = 0;
  const char* list_out = 0;

  Registry& cfg = this->GetConfig();
  if (cfg.Get("TrackListAlgorithm",tmps)) alg_name = tmps;
  if (cfg.Get("TrackListAlgConfig",tmps)) alg_config_name = tmps;
  if (cfg.Get("ListIn",tmps)) list_in = tmps;
  if (cfg.Get("ListOut",tmps)) list_out = tmps;

// Find PrimaryCandidateRecord fragment in MOM.
   CandRecord *candrec = dynamic_cast<CandRecord *>
             (mom->GetFragment("CandRecord", "PrimaryCandidateRecord"));
   if (candrec == 0) {
     MSG("TrackSR", Msg::kWarning) << "No PrimaryCandidateRecord in MOM."
                                                                << endl;
     result.SetWarning().SetFailed();
     return result;

   }

// (Re)Initialize VldContext in StripCalibrator
   Calibrator::Instance().Reset(*candrec->GetVldContext());

// Find CandSliceList fragment in PrimaryCandidateRecord
   CandSliceListHandle *cslh = dynamic_cast<CandSliceListHandle *>
      (candrec->FindCandHandle("CandSliceListHandle",list_in));

// Require number of CandSlices to be non-zero.
   if (!cslh || cslh->GetNDaughters() < 1) {
     MAXMSG("TrackSR", Msg::kInfo,1)
                  << "Null CandSlice list.  Bail out of event." << endl;

//--ju 6/22/05 not an error condition, so don't return error code.
//   result.SetWarning().SetFailed();
     result.SetFailed();
     return result;
   }

   TObjArray cxin;
   cxin.Add(cslh);

   AlgFactory &af = AlgFactory::GetInstance();

// Build a CandTrackSRList containing all CandTrackSRs in Frame.
   AlgHandle adlh = af.GetAlgHandle(alg_name,alg_config_name);
   CandContext cx(this, mom);
   cx.SetDataIn(&cxin);
   cx.SetCandRecord(candrec);

   clock_t dummyt;
   struct tms t1;
   struct tms t2;
   static double ticksPerSecond = sysconf(_SC_CLK_TCK);
   dummyt = times(&t1);

   CandTrackSRListHandle csllh = CandTrackSRList::MakeCandidate(adlh, cx);
   csllh.SetName(list_out);
   csllh.SetTitle(TString("Created by TrackSRListModule from ").
                 Append(cslh->GetName()));

   dummyt = times(&t2);
   csllh.SetCPUTime((Double_t)(t2.tms_utime+t2.tms_stime-t1.tms_utime-t1.tms_stime)/ticksPerSecond);

   candrec->SecureCandHandle(csllh);
   return result;
}
