#ifndef ROOT_TreeSearch_Hit
#define ROOT_TreeSearch_Hit
#include "TimeToDistConv.h"
#include "WirePlane.h"
#include "TBits.h"
#include <utility>
#include <set>
#include <cassert>
#include <functional>
#include <iostream>
class TSeqCollection;
class TIterator;
namespace TreeSearch {
class Road;
extern const Double_t kBig;
class Hit : public TObject {
public:
Hit() : fWirePlane(0) {}
Hit( Int_t wnum, Double_t pos, Int_t tdc, Double_t time, Double_t res,
WirePlane* wp ) :
fWireNum(wnum), fRawTDC(tdc), fTime(time), fPos(pos), fPosL(pos),
fPosR(pos), fResolution(res), fWirePlane(wp)
#ifdef TESTCODE
, fCl(0), fMulti(0), fTdiff(0.0)
#endif
{ assert(fWirePlane); }
virtual ~Hit() {}
virtual Int_t Compare( const TObject* obj ) const;
Int_t Compare( const Hit* rhs, Double_t maxdist ) const;
Bool_t IsSortable () const { return kTRUE; }
virtual void Print( Option_t* opt="" ) const;
Double_t ConvertTimeToDist( Double_t slope );
Int_t GetWireNum() const { return fWireNum; }
Double_t GetWirePos() const { return fPos; }
Double_t GetZ() const;
Double_t GetRawTDC() const { return fRawTDC; }
Double_t GetDriftTime() const { return fTime; }
Double_t GetDriftDist() const { return fPosR-fPos; }
Double_t GetPosL() const { return fPosL; }
Double_t GetPosR() const { return fPosR; }
Double_t GetResolution() const { return fResolution; }
WirePlane* GetWirePlane() const { return fWirePlane; }
UInt_t GetPlaneNum() const { return fWirePlane->GetPlaneNum(); }
struct WireNumLess : public std::binary_function< Hit*, Hit*, bool >
{
bool operator() ( const Hit* a, const Hit* b ) const
{
assert( a && b );
if( a->GetWirePlane()->GetType() != b->GetWirePlane()->GetType() )
return (a->GetWirePlane()->GetType() < b->GetWirePlane()->GetType());
if( a->GetPlaneNum() < b->GetPlaneNum() ) return true;
if( a->GetPlaneNum() > b->GetPlaneNum() ) return false;
if( a->GetWireNum() < b->GetWireNum() ) return true;
if( a->GetWireNum() > b->GetWireNum() ) return false;
return ( a->GetDriftTime() < b->GetDriftTime() );
}
};
struct WireDistLess : public std::binary_function< Hit*, Hit*, bool >
{
WireDistLess( Int_t maxdist ) : fMaxDist(maxdist) { assert(maxdist>=0); }
bool operator() ( const Hit* a, const Hit* b ) const
{
assert( a && b );
if( a->GetWirePlane()->GetType() != b->GetWirePlane()->GetType() )
return (a->GetWirePlane()->GetType() < b->GetWirePlane()->GetType());
if( a->GetPlaneNum() < b->GetPlaneNum() ) return true;
if( a->GetPlaneNum() > b->GetPlaneNum() ) return false;
if( a->GetWireNum() + fMaxDist < b->GetWireNum() ) return true;
if( fMaxDist > 0 ) return false;
if( a->GetWireNum() > b->GetWireNum() ) return false;
return ( a->GetDriftTime() < b->GetDriftTime() );
}
Int_t GetMaxDist() const { return fMaxDist; }
private:
Int_t fMaxDist;
};
protected:
Int_t fWireNum;
Int_t fRawTDC;
Double_t fTime;
Double_t fPos;
Double_t fPosL;
Double_t fPosR;
Double_t fResolution;
WirePlane* fWirePlane;
#ifdef TESTCODE
Int_t fCl;
Int_t fMulti;
Double_t fTdiff;
friend void WirePlane::CheckCrosstalk();
#endif
ClassDef(Hit,1)
};
class MCTrack;
class MCHit : public Hit {
public:
MCHit() : fMCTrack(0) {}
MCHit( Int_t wnum, Double_t pos, Int_t tdc, Double_t time, Double_t res,
WirePlane* wp, MCTrack* mctrk, Double_t mcpos )
: Hit(wnum, pos, tdc, time, res, wp), fMCTrack(mctrk), fMCPos(mcpos) {}
virtual ~MCHit() {}
virtual void Print( Option_t* opt="" ) const;
MCTrack* GetMCTrack() const { return fMCTrack; }
Double_t GetMCPos() const { return fMCPos; }
protected:
MCTrack* fMCTrack;
Double_t fMCPos;
ClassDef(MCHit,1)
};
typedef std::pair<TObject*,TObject*> ObjPair_t;
class HitPairIter {
public:
HitPairIter( const TSeqCollection* collA, const TSeqCollection* collB,
Double_t maxdist );
HitPairIter( const HitPairIter& rhs );
HitPairIter& operator=( const HitPairIter& rhs );
virtual ~HitPairIter();
const TSeqCollection* GetCollection( Int_t n=0 ) const
{ return (n==0) ? fCollA : fCollB; }
void Reset();
HitPairIter& Next();
HitPairIter& operator++() { return Next(); }
const HitPairIter operator++(int) {
HitPairIter clone(*this); Next(); return clone;
}
ObjPair_t operator()() const { return fCurrent; }
ObjPair_t& operator* () { return fCurrent; }
bool operator==( const HitPairIter& rhs ) const {
return( fCollA == rhs.fCollA && fCollB == rhs.fCollB &&
fCurrent == rhs.fCurrent );
}
bool operator!=( const HitPairIter& rhs ) const { return !(*this==rhs); }
operator bool() const
{ return (fCurrent.first != 0 || fCurrent.second != 0); }
bool operator!() const { return !((bool)*this); }
private:
const TSeqCollection* fCollA;
const TSeqCollection* fCollB;
TIterator* fIterA;
TIterator* fIterB;
TIterator* fSaveIter;
Hit* fSaveHit;
Double_t fMaxDist;
Bool_t fStarted;
Bool_t fScanning;
ObjPair_t fCurrent;
ObjPair_t fNext;
HitPairIter();
ClassDef(HitPairIter,0)
};
class FitCoord : public TObject {
public:
FitCoord( Hit* hit, Road* road, Double_t pos,
Double_t trkpos2d, Double_t trkslope2d,
Double_t trkpos, Double_t trkslope )
: fHit(hit), fRoad(road), fPos(pos), fTrackPos(trkpos2d),
fTrackSlope(trkslope2d), f3DTrkPos(trkpos), f3DTrkSlope(trkslope),
fFitRank(0) {}
FitCoord() : fHit(0), fRoad(0) {}
virtual ~FitCoord() {}
Double_t GetChi2() const;
Hit* GetHit() const { return fHit; }
Road* GetRoad() const { return fRoad; }
Double_t GetPos() const { return fPos; }
Double_t GetDriftTime() const { return fHit ? fHit->GetDriftTime():kBig;}
Double_t GetDriftDist() const { return fHit ? fHit->GetDriftDist():kBig;}
Double_t GetTrackPos() const { return fTrackPos; }
Double_t GetTrackSlope() const { return fTrackSlope; }
Double_t GetTrackDist() const
{ return fHit ? fTrackPos-fHit->GetWirePos() : kBig; }
Double_t GetResidual() const { return fHit ? fTrackPos-fPos : kBig; }
Double_t Get3DTrkPos() const { return f3DTrkPos; }
Double_t Get3DTrkSlope() const { return f3DTrkSlope; }
Double_t Get3DTrkDist() const
{ return fHit ? f3DTrkPos-fHit->GetWirePos() : kBig; }
Double_t Get3DTrkResid() const { return fHit ? f3DTrkPos-fPos : kBig; }
Int_t GetWireNum() const { return fHit ? fHit->GetWireNum() : -1; }
private:
Hit* fHit;
Road* fRoad;
Double_t fPos;
Double_t fTrackPos;
Double_t fTrackSlope;
Double_t f3DTrkPos;
Double_t f3DTrkSlope;
UInt_t fFitRank;
ClassDef(FitCoord,1)
};
typedef std::set<Hit*,Hit::WireNumLess> Hset_t;
struct HitSet {
Hset_t hits;
UInt_t plane_pattern;
UInt_t nplanes;
mutable UInt_t used;
HitSet() : plane_pattern(0), nplanes(0), used(0) {}
virtual ~HitSet() {}
static Bool_t CheckMatch( const Hset_t& hits, const TBits* bits );
Bool_t CheckMatch( const TBits* bits ) const;
static UInt_t GetMatchValue( const Hset_t& hits );
Bool_t IsSimilarTo( const HitSet& tryset, Int_t maxdist=0 ) const;
ClassDef(HitSet, 0)
};
inline
Int_t Hit::Compare( const TObject* obj ) const
{
const Hit* rhs = dynamic_cast<const Hit*>(obj);
assert( rhs );
assert( fWirePlane == rhs->fWirePlane );
if( fPos < rhs->fPos ) return -1;
if( fPos > rhs->fPos ) return 1;
if( fTime < rhs->fTime ) return -1;
if( fTime > rhs->fTime ) return 1;
return 0;
}
inline
Int_t Hit::Compare( const Hit* rhs, Double_t maxdist ) const
{
if( fPosR+maxdist < rhs->fPosL )
return -1;
if( rhs->fPosR+maxdist < fPosL )
return +1;
return 0;
}
inline
Bool_t HitSet::CheckMatch( const Hset_t& hits, const TBits* bits )
{
return bits->TestBitNumber( GetMatchValue(hits) );
}
inline
Bool_t HitSet::CheckMatch( const TBits* bits ) const
{
assert( plane_pattern || hits.empty() );
return bits->TestBitNumber(plane_pattern);
}
#ifdef VERBOSE
inline
void PrintHits( const Hset_t& hits )
{
for( Hset_t::reverse_iterator it = hits.rbegin(); it != hits.rend();
++it ) {
std::cout << " ";
(*it)->Print();
}
}
#endif
}
#endif