// MTrack.cpp #include "MTrack.h" #include "trfutil/trfstream.h" using trf::HitPtr; using trf::HitList; using trf::MissPtr; using trf::ETrack; using trf::HTrack; using trf::MTrack; //********************************************************************** // methods //********************************************************************** // output stream void MTrack::ostr(ostream& stream) const { stream << begin_object; stream << "MTrack is "; if ( ! is_fit() ) { stream << "not fit."; } else { stream << "fit:"; stream << new_line; stream << _tre; stream << new_line; stream << "Chi-square: " << _chisq; } stream << new_line; // fetch the combined list of hits and misses HitMissList hitmisses = get_hits_and_misses(); stream << "Track has " << _hits.size() << " hit"; if ( _hits.size() != 1 ) stream << 's'; stream << " and " << _misses.size() << " miss"; if ( _misses.size() != 1 ) stream << "es"; if ( hitmisses.size() > 0 ) { stream << ':'; HitMissIterator ihm = hitmisses.begin(); for ( ihm=hitmisses.begin(); ihm!=hitmisses.end(); ++ihm ) { stream << new_line; if ( (*ihm).is_hit() ) { HitPtr phit = (*ihm).get_hit(); if ( phit ) stream << *phit; else stream << "Invalid hit"; } else { stream << *(*ihm).get_miss(); } } } else { stream << '.'; } stream << end_object; } //********************************************************************** // Default constructor. MTrack::MTrack() : HTrack() { _hit_counts.push_back(0); } //********************************************************************** // Constructor from a starting track. MTrack::MTrack(const ETrack& tre) : HTrack(tre) { _hit_counts.push_back(0); } //********************************************************************** // Constructor from the base class. MTrack::MTrack(const HTrack& trh) : HTrack(trh) { _hit_counts.push_back(0); } //********************************************************************** // Copy constructor. MTrack::MTrack(const MTrack& trm) : HTrack(trm), _misses(trm._misses), _hit_counts(trm._hit_counts) { } //********************************************************************** // Destructor. MTrack::~MTrack() { } //********************************************************************** // Add a hit to the back of the list. void MTrack::add_hit(const HitPtr& phit) { // increment the # hits preceeding the next miss ++_hit_counts.back(); // add the hit to the hit list HTrack::add_hit(phit); } //********************************************************************** // Drop the last hit. void MTrack::drop_hit() { // Find the count containing this miss (last nonzero count). CountIterator icnt = _hit_counts.end(); --icnt; while ( *icnt == 0 ) { if ( icnt == _hit_counts.begin() ) { return; } --icnt; } // Decrement the counter. --(*icnt); // Drop the hit from the hit list. HTrack::drop_hit(); } //********************************************************************** // Add a miss to the back of the list. void MTrack::add_miss(const Miss& miss) { // Create the next count entry. _hit_counts.push_back(0); // Add the miss to the list. _misses.push_back( MissPtr(miss.new_copy()) ); // Update the miss likelihood. } //********************************************************************** // Drop the last miss on the list. void MTrack::drop_miss() { if ( _hit_counts.size() == 0 ) { return; } // Combine the last and preceeding counts. int oldcount = _hit_counts.back(); _hit_counts.pop_back(); if ( _hit_counts.size() == 0 ) { return; } _hit_counts.back() += oldcount; // Drop the miss. _misses.pop_back(); } //********************************************************************** // Drop all the hits and misses. void MTrack::drop_hits() { _hit_counts.erase( _hit_counts.begin(), _hit_counts.end() ); _hit_counts.push_back(0); _misses.erase( _misses.begin(), _misses.end() ); HTrack::drop_hits(); } //********************************************************************** // Fetch the combined list of hits and misses. const MTrack::HitMissList MTrack::get_hits_and_misses() const { HitMissList hitmisses; // Loop over misses. HitList::const_iterator ihit = _hits.begin(); MissList::const_iterator imiss; CountConstIterator icnt = _hit_counts.begin(); for ( imiss=_misses.begin(); imiss!=_misses.end(); ++imiss ) { // Add the hits preceeding the miss. for ( int nhit=0; nhit<(*icnt); ++nhit ) hitmisses.push_back( HitMissPtr(*ihit++) ); // Add the miss. hitmisses.push_back( HitMissPtr(*imiss) ); ++icnt; } // Add the last hits. for ( int nhit=0; nhit<(*icnt); ++nhit ) hitmisses.push_back( HitMissPtr(*ihit++) ); assert( ++icnt == _hit_counts.end() ); assert( hitmisses.size() == get_hits().size() + get_misses().size() ); return hitmisses; } //********************************************************************** // Fetch the total miss likelihood. // This is the product of the indivudual miss likelihoods. double MTrack::get_miss_likelihood() const { double likelihood = 1.0; MissList::const_iterator imiss; for ( imiss=_misses.begin(); imiss!=_misses.end(); ++imiss ) likelihood *= (**imiss).get_likelihood(); return likelihood; } //********************************************************************** // External functions for MTrack. //********************************************************************** // Equality. bool operator==(const MTrack& lhs, const MTrack& rhs) { if ( (const HTrack&) lhs != (const HTrack&) rhs ) return false; return lhs.get_hits_and_misses() == rhs.get_hits_and_misses(); } //********************************************************************** // Inequality. bool operator!=(const MTrack& lhs, const MTrack& rhs) { return ! ( lhs == rhs ); } //********************************************************************** // Methods for nested class MTrack::HitMissPtr. //********************************************************************** // Default constructor. MTrack::HitMissPtr::HitMissPtr() : _is_hit(false) { } //********************************************************************** // Constructor from a hit pointer. MTrack::HitMissPtr::HitMissPtr(const HitPtr& phit) : _is_hit(true), _ptr(phit) { } //********************************************************************** // Constructor from a miss pointer. MTrack::HitMissPtr::HitMissPtr(const MissPtr& pmiss) : _is_hit(false), _ptr(pmiss) { } //********************************************************************** // Return hit pointer. const HitPtr& MTrack::HitMissPtr::get_hit() const { assert( is_hit() ); return *_ptr._pphit; } //********************************************************************** // Return miss pointer. const MissPtr& MTrack::HitMissPtr::get_miss() const { assert( is_miss() ); return *_ptr._ppmiss; } //********************************************************************** // Note that x._ptr._pphit holds a pointer to a hit pointer (HitPtr). // Comparison is by hit pointer. bool MTrack::HitMissPtr::operator==(const MTrack::HitMissPtr& rhs) const { return this->_ptr._pphit->pointer() == rhs._ptr._pphit->pointer(); } //********************************************************************** bool MTrack::HitMissPtr::operator<(const MTrack::HitMissPtr& rhs) const { return this->_ptr._pphit->pointer() < rhs._ptr._pphit->pointer(); } //**********************************************************************