// FilterShares.cpp #include "FilterShares.h" #include #include #include #include "objstream/ObjData.hpp" #include "objstream/ObjTable.hpp" #include "trfutil/trfstream.h" #include "trfutil/trfstream.h" #include "trffit/MTrack.h" using std::pair; using std::vector; using std::sort; using trf::ClusterPtr; using trf::HitList; using trf::Filter; using trf::FilterShares; //********************************************************************** // Free functions. //********************************************************************** namespace { // Creator. ObjPtr create(const ObjData& data) { assert( data.get_object_type() == "FilterShares" ); int count = data.get_int("min_share_count"); bool last_match = false; if ( data.has("last_match") ) { last_match = data.get_bool("last_match"); } return ObjPtr( new FilterShares(count, last_match) ); } } //********************************************************************** // Helpers //********************************************************************** namespace { // Return true if indices are in order of increasing chi-square. class CompareChiSquare { private: static const Filter::MTrackArray* _ptrms; public: CompareChiSquare(const Filter::MTrackArray* ptrms) { assert( ! _ptrms ); _ptrms = ptrms; }; ~CompareChiSquare() { _ptrms = 0; }; static bool compare(int i1, int i2) { assert( _ptrms != 0 ); const Filter::MTrackArray& trms = *_ptrms; assert( i1 >= 0 ); assert( i2 >= 0 ); assert( i1 < trms.size() ); assert( i2 < trms.size() ); return trms[i1]->get_chi_square() < trms[i2]->get_chi_square(); }; }; const Filter::MTrackArray* CompareChiSquare::_ptrms = 0; //********************************************************************** // Return the number of clusters shared by two tracks. int count_shares(const vector& cl1, const vector& cl2) { int nshare = 0; // Count common clusters. // Assume cluster lists are sorted in ascending order. vector::const_iterator i = cl1.begin(); vector::const_iterator j = cl2.begin(); while(i != cl1.end() && j != cl2.end()) { if(*i < *j) ++i; else if(*i > *j) ++j; else { ++nshare; ++i; ++j; } } return nshare; } } // end unnamed namespace //********************************************************************** // Member functions. //********************************************************************** // output stream void FilterShares::ostr(ostream& stream) const { stream << begin_object; stream << "Filter tracks sharing " << _nshare << " or more clusters"; if ( _last_match ) { stream << " with last match."; } else { stream << " without last match."; } stream << end_object; } //********************************************************************** // constructor FilterShares::FilterShares(int nshare, bool last_match) : _nshare(nshare), _last_match(last_match) { } //********************************************************************** // Return the creator. ObjCreator FilterShares::get_creator() { return create; } //********************************************************************** // Write the object data. ObjData FilterShares::write_data() const { ObjData data( get_type_name() ); data.add_int( "min_share_count", get_min_share_count() ); data.add_bool("last_match", _last_match); return data; } //********************************************************************** // Process tracks. FilterShares::FlagArray FilterShares::process(MTrackArray& trms) const { // Create the output array initialized to accept all. int size = trms.size(); FlagArray flags(size, true); // We construct a CompareChiSquare object to set the list of tracks. CompareChiSquare cmp(&trms); // Create a vector of indices and sort by chi-square. vector indices(size,0); for ( int i0=0; i0 > clists; clists.reserve(size); for(MTrackArray::const_iterator i=trms.begin(); i!=trms.end(); ++i) { clists.push_back(vector()); const HitList& hlist = (*i)->get_hits(); clists.back().reserve(hlist.size()); for(HitList::const_iterator j=hlist.begin(); j!=hlist.end(); ++j) clists.back().push_back((*j)->get_cluster()); sort(clists.back().begin(), clists.back().end()); } // Loop over indices in order of increasing chi-square. for ( int i=0; i= _nshare ) { bool delete_one = true; // If last_match is set, require that the last hits match // before a track is deleted.. if ( _last_match ) { const ClusterPtr& pclui = trms[i]->get_hits().back()->get_cluster(); const ClusterPtr& pcluj = trms[i]->get_hits().back()->get_cluster(); delete_one = pclui == pcluj; } if ( delete_one ) { flags[jtrm] = false; typedef pair Pair; make_report(*this, "kill", Pair(trms[jtrm].pointer(), trms[itrm].pointer())); } } } // end loop over second index. } // end loop over first index. return flags; } //**********************************************************************