////////////////////////////////////////////////////////////////////////
// $Id: AlgTrackSRList.h,v 1.34 2005/12/13 15:59:46 rhatcher Exp $
//
// AlgTrackSRList.h
//
// AlgTrackSRList is a concrete TrackSRList Algorithm class.
//
// Author:  R. Lee 2001.02.26
// Revised: B. Rebel 2003.06.23
//
////////////////////////////////////////////////////////////////////////

#ifndef ALGTRACKSRLIST_H
#define ALGTRACKSRLIST_H

#include "Algorithm/AlgBase.h"
#include<vector>
#include<map>
#include "Conventions/Detector.h"
#include "UgliGeometry/UgliGeomHandle.h"
#include "CandDigit/CandDigitListHandle.h"
#include "RecoBase/CandStripListHandle.h"
#include "RecoBase/CandStripListHandle.h"
#include "RecoBase/CandSliceListHandle.h"
#include "Conventions/PlaneView.h"
#include "Conventions/SimFlag.h"
#include "Validity/VldContext.h"
#include "DataUtil/PlaneOutline.h"

class CandStripHandleItr;
class TrackClusterSRItr;
class TrackClusterSR;
class Track2DSR;
class Track2DSRItr;
class CandTrackSRHandleItr;
class CandTrackSRListHandle;
class TObjArray;
class CandSliceHandle;

class AlgTrackSRList : public AlgBase
{

public:
  AlgTrackSRList();
  virtual ~AlgTrackSRList();
  virtual void RunAlg(AlgConfig &ac, CandHandle &ch, CandContext &cx);
  virtual void Trace(const char *c) const;

private:

  void AddBestPlaneClusterToTrack(TrackClusterSR *besttc, Track2DSR *track);
  Int_t AddClustersToTracks(Track2DSRItr &trackItr,  
			    TrackClusterSRItr &planeClusterItr,
			    Int_t direction, Int_t iterate, std::vector<Int_t>&hitPlanes, Int_t trk2dmin);
  Bool_t CheckForBadClusters(TrackClusterSR *besttc, Track2DSR *track, Int_t &planesBefore, 
			     Int_t direction, Int_t trk2dmin);
  void CleanUp(TObjArray *trackList, TObjArray *clusterList);
  void DeleteTwinTracks(CandTrackSRHandleItr &candTracks1, CandTrackSRHandleItr &candTracks2,
			TObjArray *candTracks, Int_t uMaxTrack, Int_t vMaxTrack, 
			Int_t nmax3dtrk, CandHandle &ch);
  void FillInGaps(Track2DSRItr &trackItr, TrackClusterSRItr &clusterItr, Int_t direction);
  Int_t FillTrackList(TrackClusterSRItr &clusterItr, TObjArray *trackList, TObjArray *seedClusters,
		      Double_t houghSlope, Double_t houghIntercept,
		      Int_t direction, Int_t iterate, Int_t &begPlane);
  void Find2DTrackEndPoints(CandStripHandleItr &stripItr, Int_t &vtxPlane, 
			    Int_t &endPlane, Int_t &numPlanes);
  Bool_t PlaneIsActive(Int_t plane, Float_t u, Float_t v, Float_t tol);
  Int_t FindNumSkippedPlanes(Int_t currentPlane, Int_t prevPlane, 
			     std::vector<Int_t>& hitPlanes, 
			     Int_t direction);
  Int_t FindNumSkippedPlanes(Int_t currentPlane, Int_t prevPlane, Float_t prevTPos, 
			     Float_t prevZPos, Double_t trackSlope, 
			     Int_t direction, PlaneView::PlaneView_t view);									     
  Int_t FindNumSkippedPlanes(Int_t currentPlane, Int_t prevPlane,
			   Float_t PrevUPos, Float_t PrevVPos, 
			   Float_t prevZPos,
			   Double_t trackSlopeU, 
			   Double_t trackSlopeV,
			   Int_t direction,
			   PlaneView::PlaneView_t view);
  Int_t FindTimingDirection(CandStripHandleItr &allStripItr, Float_t uTrackSlope, 
			    Float_t uTrackIntercept, Float_t vTrackSlope,
			    Float_t vTrackIntercept);
  Int_t FindTimingDirection(TrackClusterSRItr &clusterItr);
  void FormCandTrackSR(Track2DSRItr &uTrackItr, Track2DSRItr &vTrackItr, 
		       TObjArray *candTracks, CandHandle &ch, 
		       CandSliceHandle *slice, AlgHandle ah, CandContext cxx, 
		       Int_t direction);
  Int_t IdentifyBadTracks(Track2DSRItr &trackItr, Int_t iterate, Int_t trk2dmin);
  Bool_t IsBestClusterInPlane(TrackClusterSR *planeCluster,
			      TrackClusterSR *prevCluster, 
			      Int_t numSkippedHit, Int_t nHit, 
			      Int_t planesBefore, 
			      Double_t trackSlope, Track2DSR *track, 
			      Double_t *residParams, Int_t dplane,Bool_t isSpectrometerPlane);
  Int_t LookForBadClusters(TrackClusterSRItr &clusterItr, TObjArray *trackList,
			   Int_t direction);
  void MakeTrackClusters(TObjArray *trackClusterList,
			 CandStripHandleItr &stripItr, 
			 CandTrackSRListHandle &cth, 
			 Int_t expectedStrips, Int_t direction);
  void MarkUsedClusters(Track2DSRItr &trackItr, TrackClusterSRItr &clusterItr, 
			Int_t iterate, Int_t nmaxtrack, Double_t houghSlope, 
			Double_t houghIntercept);
  Int_t RemoveTrackSubsets(Track2DSRItr &trackItr1, Track2DSRItr &trackItr2,  
			  TObjArray *trackList);

  void SpectrometerTracking(TObjArray * trackList, CandTrackSRListHandle &cth, 
			    CandSliceHandle *slice,   CandSliceHandle  *dupSlice, 
			    CandContext cx);
  void MergeTracks(TObjArray * tracklist, Int_t direction);
void RemoveUnusedSpectStrips(CandTrackSRListHandle & cth, 
			     CandStripListHandle *striplist);
 void RemoveStripsInSlice(CandTrackSRListHandle & cth, 
			  CandSliceListHandle *slicelist);

  Detector::Detector_t fDetector;
  SimFlag::SimFlag_t fSimFlag;
  Int_t fMapIsWide[1000];
  Int_t fSliceVtxUPlane;
  Int_t fSliceVtxVPlane;
  Int_t fSliceEndUPlane;
  Int_t fSliceEndVPlane;
  Int_t fSliceVtxPlane;
  Int_t fSliceEndPlane;
  Int_t fSliceNUPlanes;
  Int_t fSliceNVPlanes;
  Int_t fSliceNPlanes;
  Double_t fSliceDzDs;
  VldContext fVldc;
  PlaneOutline fPL;

  Int_t fParmMaxNStrip; //Maximum number of strips allowed in a cluster
  Int_t fParmMaxNExtraStrip; //Fudge factor for max # of strips allowed
  Int_t fParmTrk2DPlnEnd; 
  Double_t fParmTrk2DWin0; //spread allowed in tpos
  Double_t fParmHitNTime; //time variable to see if digits in time
  Double_t fParmHitTime; //time variable to see if digits in time
  Int_t fParmTrk2DNSkip; //number of planes allowed between clusters same track
  Int_t fParmTrk2DNSkipHit; //number of planes allowed between clusters same track
  Double_t fParmTrk2DAlpha; //weighting factor for determining slope from one cluste rto the next
  Double_t fParmTrk2DMaxResid;
  Int_t fParmTrk2DNSkipRemove; 
  Int_t fParmTrkNPlaneGoodDir; //# of planes needed for good timing direction
  Double_t fParmTrk2DDirCosNSigma; //factor to determine allowed angle between clusters
  Double_t fParmTrk2DDirCosError2; 
  Int_t fParmTrk2DEndPlaneDiff;  //allowed # of planes diff between removed 
                                 //cluster and end of event

  Int_t fParmMinSingleHit; //min # of hits for single hit
  Int_t fParmSingleHitDef; //# of hits allowed for single hit

  Int_t fParmTrk2DNHough0; //max # of hits in a short track
  Double_t fParmTrk2DLinA0; //min max residual for lin fit to short track
  Double_t fParmTrk2DLinB0; //factor to increase max resid for short track based on #
                            // of skipped planes
  Int_t fParmTrk2DNHough; //max size of window when considering upstream info
  Double_t fParmTrk2DLinA; //min max residual when considering upstream info
  Double_t fParmTrk2DLinB; //factor to increase max resid when considering upstream info
  Double_t fParmTrk2DNSigmaA; //number of sigma allowed when on the seed cluster
  Int_t fParmTrk2DNSeed; //minimum # of planes needed to form a track
  Int_t fParmTrk2DNContiguous; //# of contiguous planes needed in a 2d track
  Double_t fParmTrk2DHitFraction; //min fraction of hit planes needed of total in view
  Double_t fParmTrk2DTwinMatchFraction; //fraction of matching clusters in tracks to 
                                        //determine if tracks are the same
  Int_t fParmTrk2DSubsetNHit; //max # of hits allowed to be shared by multiple tracks
  Int_t fParmTrk2DSubsetDHit; //parameter to check which track has the most hits

  Int_t fParmDiffViewBegPlaneMatch; //allowed # of planes between vtx in each view
  Int_t fParmDiffViewEndPlaneMatch; //allowed # of planes between end in each view
  Double_t fParmDiffViewPlaneOverlap; //used to check for 2d tracks belonging to a 3d track
  Double_t fParmDiffViewTimeMatch; //check if 2d tracks occur in time with each other

  Double_t fParmTrk3DTwinFrac; //check for copies of same 3d track

  Int_t fParmTrkClsNSkip; //number of strips you can skip and still be in same cluster
  Int_t fParmTrk3DTrackMax; //max # of 3d tracks allowed
  Int_t fParmIsCosmic; //is this a cosmic ray file?
  Double_t fParmMinStripPulseHeight; //minimum pulse height allowed for a strip to be used
  Double_t fParmMinClusterPulseHeight; //min pulse height allowed for a cluster to be used
  Int_t fParmUseWideClusters; //use clusters with more than expected # of strips
  Int_t fParmUseShowerLikePlanes; //use clusters from showerlike planes
  Double_t fParmMaxTimingResid; //max allowed timing residual for direction determination
  Double_t fParmMisalignmentError; //error due to strip misalignments
  //these are variables for HoughViewSR objects.  See that class for
  //their definitions
  Int_t fParmHoughMinBin; 
  Double_t fParmHoughMinFrac;
  Double_t fParmHoughMinFracZoom;
  Double_t fParmHoughMinInterBinSize;
  Double_t fParmExtrapError;
  CandDigitListHandle *fCDLHnew;
  CandStripListHandle *fCSLHnew;
  CandSliceListHandle *fCSlcLHnew;

  Float_t fHoughUSlope;
  Float_t fHoughVSlope;
  Float_t fHoughUIntercept;
  Float_t fHoughVIntercept;


ClassDef(AlgTrackSRList,3)                    // TrackSRList Algorithm Class


};

#endif                                                 // ALGTRACKSRLIST_H
