////////////////////////////////////////////////////////////////////////
// $Id: FitTrackSRListModule.cxx,v 1.32 2005/04/20 17:23:53 minoscvs Exp $
//
// FitTrackSRListModule.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 CandFitTrackSRList from CandTrackList.
//
// Author:  R. Lee 2001.03.30
//
// Also see <a href="../../root_crib/index.html">The ROOT Crib</a> and 
// <a href="../CandFitTrackSR.html"> CandFitTrackSR Classes</a> (part of
// <a href="../index.html">The MINOS Class User Guide</a>)End_Html
////////////////////////////////////////////////////////////////////////

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


#include "CandFitTrackSR/FitTrackSRListModule.h"

#include "Algorithm/AlgConfig.h"
#include "Algorithm/AlgFactory.h"
#include "Algorithm/AlgHandle.h"
#include "CandData/CandHeader.h"
#include "CandData/CandRecord.h"
#include "CandFitTrackSR/CandFitTrackSRListHandle.h"
#include "CandFitTrackSR/CandFitTrackSRList.h"
#include "CandFitTrackSR/CandFitTrackSRHandle.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/RawHeader.h"
#include "RawData/RawRecord.h"
#include "RecoBase/CandClusterListHandle.h"
#include "RecoBase/CandSliceListHandle.h"
#include "Validity/VldContext.h"

ClassImp(FitTrackSRListModule)

//......................................................................
CVSID("$Id: FitTrackSRListModule.cxx,v 1.32 2005/04/20 17:23:53 minoscvs Exp $");
JOBMODULE(FitTrackSRListModule, "FitTrackSRListModule",
         "Builds CandFitTrackSRList from CandTrackList");

//......................................................................
FitTrackSRListModule::FitTrackSRListModule()
{
}

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

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

//......................................................................

const Registry &FitTrackSRListModule::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("FitTrackListAlgorithm","AlgFitTrackSRList");
  def_cfg.Set("FitTrackListAlgConfig","default");
  def_cfg.Set("ListIn","CandSliceList");
  def_cfg.Set("ListOut","CandFitTrackSRList");
  def_cfg.Set("LogLevel","Fatal");
  return def_cfg;
}



//......................................................................
JobCResult FitTrackSRListModule::Reco(MomNavigator *mom)
{
  
  JobCResult result(JobCResult::kPassed); // The default result
  // 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("FitTrackListAlgorithm",tmps)) alg_name = tmps;
  if (cfg.Get("FitTrackListAlgConfig",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("FitTrackSR", Msg::kWarning) << "No PrimaryCandidateRecord in MOM."
				      << endl;
     // Return failed with warning result
     result.SetWarning().SetFailed();
     return result;
   }

// Require number of CandSlices to be non-zero.
   CandSliceListHandle *cslh = dynamic_cast<CandSliceListHandle *>
      (candrec->FindCandHandle("CandSliceListHandle",list_in));
   if (!cslh || cslh->GetNDaughters() < 1) {
     MSG("FitTrackSR", Msg::kDebug)
                  << "Null CandSlice list.  Bail out of event." << endl;
     result.SetFailed();
     return result;
   }

   CandTrackListHandle *ctlh = dynamic_cast<CandTrackListHandle *>
     (candrec->FindCandHandle("CandTrackListHandle"));
   // Require number of CandTracks to be non-zero.
   if (!ctlh || ctlh->GetNDaughters() < 1) {
     MSG("FitTrackSR", Msg::kDebug)
       << "Null CandTrack list.  Bail out of event." << endl;
     return result;
   }

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

   TObjArray cxin;
   cxin.Add(cslh);
   cxin.Add(ctlh);

   AlgFactory &af = AlgFactory::GetInstance();

// Build a CandFitTrackSRList containing all CandFitTrackSRs in Frame.
   AlgHandle adlh = af.GetAlgHandle(alg_name,alg_config_name);
   CandContext cx(this, mom);
   cx.SetDataIn(&cxin);
   cx.SetCandRecord(candrec);
   CandFitTrackSRListHandle ctllh = CandFitTrackSRList::MakeCandidate(adlh, cx);

   //      dummyt = times(&t2);
   //   cout << " fitter time " << (Double_t)(t2.tms_utime+t2.tms_stime-t1.tms_utime-t1.tms_stime)/ticksPerSecond << endl;
   ctllh.SetName(list_out);
   ctllh.SetTitle(TString("Created by FitTrackSRListModule from ").
                 Append(ctlh->GetName()));
   candrec->SecureCandHandle(ctllh);

   return result;
}

