////////////////////////////////////////////////////////////////////////
// $Id: AlgFitTrackSRList.cxx,v 1.10 2004/08/20 13:48:08 musser Exp $
//
// AlgFitTrackSRList.cxx
//
// Begin_Html<img src="../../pedestrians.gif" align=center>
// <a href="../source_warning.html">Warning for beginners</a>.<br> 
//
// AlgFitTrackSRList is a concrete FitTrackSRList Algorithm class.
//
// 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>
#include <vector>
extern "C" {
#include <unistd.h>    // sysconf
#include <sys/times.h> // times()
}

#include "Algorithm/AlgFactory.h"
#include "Algorithm/AlgHandle.h"
#include "Algorithm/AlgConfig.h"
#include "Candidate/CandContext.h"
#include "CandFitTrackSR/AlgFitTrackSRList.h"
#include "CandFitTrackSR/CandFitTrackSR.h"
#include "./CandFitTrackSRHandle.h"
#include "CandFitTrackSR/CandFitTrackSRList.h"
#include "CandFitTrackSR/CandFitTrackSRListHandle.h"
#include "CandTrackSR/CandTrackSRListHandle.h"
#include "CandTrackSR/TrackClusterSR.h"
#include "Conventions/Mphysical.h"
#include "Conventions/Munits.h"
#include "Conventions/PlaneView.h"
#include "MessageService/MsgService.h"
#include "MinosObjectMap/MomNavigator.h"
#include "Navigation/NavKey.h"
#include "Navigation/NavSet.h"
#include "RecoBase/CandTrackHandle.h"
#include "RecoBase/CandTrackListHandle.h"
#include "RecoBase/CandSliceHandle.h"
#include "RecoBase/CandSliceListHandle.h"
#include "RecoBase/LinearFit.h"
#include "UgliGeometry/UgliGeomHandle.h"
#include "Validity/VldContext.h"


ClassImp(AlgFitTrackSRList)


//______________________________________________________________________
CVSID("$Id: AlgFitTrackSRList.cxx,v 1.10 2004/08/20 13:48:08 musser Exp $");

//______________________________________________________________________
AlgFitTrackSRList::AlgFitTrackSRList()
{
}

//______________________________________________________________________
AlgFitTrackSRList::~AlgFitTrackSRList()
{
}

//______________________________________________________________________
void AlgFitTrackSRList::RunAlg(AlgConfig & ac , CandHandle &ch,CandContext &cx)
{
  MSG("Alg", Msg::kDebug)
                           << "Starting AlgFitTrackSRList::RunAlg()" << endl;

  assert(cx.GetDataIn());

  if (!(cx.GetDataIn()->InheritsFrom("TObjArray"))) {
    return;
  }

  const char *pTrackAlgConfig = 0;
  ac.Get("FitTrackAlgConfig",pTrackAlgConfig);

  const CandSliceListHandle *slicelist = 0;
  const CandTrackListHandle *tracklist = 0;
  const CandTrackSRListHandle *tracksrlist = 0;
  const TObjArray *cxin = dynamic_cast<const TObjArray *>(cx.GetDataIn());
  for (Int_t i=0; i<=cxin->GetLast(); i++) {
    TObject *tobj = cxin->At(i);
    if (tobj->InheritsFrom("CandSliceListHandle")) {
      slicelist = dynamic_cast<CandSliceListHandle*>(tobj);
    }
    if (tobj->InheritsFrom("CandTrackListHandle")) {
      tracklist = dynamic_cast<CandTrackListHandle*>(tobj);
      if (tobj->InheritsFrom("CandTrackSRListHandle")) {
        tracksrlist = dynamic_cast<CandTrackSRListHandle*>(tobj);
      }
    }
  }
  if (!slicelist || !tracklist) {
    MSG("error",Msg::kError) <<
      "CandSliceListHandle or CandTrackListHandle missing\n";
  }

// Create Candcontext
  CandContext cxx(this,cx.GetMom());

// Get singleton instance of AlgFactory
  AlgFactory &af = AlgFactory::GetInstance();

// Get an AlgHandle to AlgSliceSR with default AlgConfig
  AlgHandle ah = af.GetAlgHandle("AlgFitTrackSR",pTrackAlgConfig);

  TIter trackItr(tracklist->GetDaughterIterator());

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

  while (CandTrackHandle *track = dynamic_cast<CandTrackHandle*>(trackItr())) {
    TObjArray cxin;
    cxin.Add(track);
    if (tracksrlist) {
      TObjArray *tclist = tracksrlist->GetTrackClusterList();
      assert(tclist);
      for (int i=0; i<=tclist->GetLast(); i++) {
        TrackClusterSR *tc = dynamic_cast<TrackClusterSR*>(tclist->At(i));
        assert(tc);
	MSG("FitTrackSR",Msg::kDebug) << "Input TC " << tc->GetPlane() << " " << tc->GetMinStrip() << "/" << tc->GetMaxStrip() << endl;
      }
      cxin.Add(tclist);
    }
    cxx.SetDataIn(&cxin);
    dummyt = times(&t1);
    CandFitTrackSRHandle fittrack = CandFitTrackSR::MakeCandidate(ah,cxx);
    dummyt = times(&t2);
    fittrack.SetCPUTime((Double_t)(t2.tms_utime+t2.tms_stime-t1.tms_utime-t1.tms_stime)/ticksPerSecond);
    ch.AddDaughterLink(fittrack);
  }

}


//______________________________________________________________________
void AlgFitTrackSRList::Trace(const char * /* c */) const
{
}

