00001 #include "RecoVertex/VertexTools/interface/hsm_3d.h" 00002 #include "RecoVertex/VertexTools/interface/SubsetHsmModeFinder3d.h" 00003 00004 #include "RecoVertex/VertexPrimitives/interface/VertexException.h" 00005 00006 #include <algorithm> 00007 00008 typedef pair < GlobalPoint, float > PointAndDistance; 00009 00010 namespace { 00011 struct compareByDistance 00012 { 00013 bool operator() ( const PointAndDistance & p1, 00014 const PointAndDistance & p2 ) { 00015 return ( p1.second < p2.second ); 00016 }; 00017 }; 00018 } 00019 00020 GlobalPoint SubsetHsmModeFinder3d::operator() ( const vector< PointAndDistance> & values ) 00021 const 00022 { 00023 if ( values.size() == 0 ) 00024 { 00025 throw VertexException ("SubsetHsmModeFinder3d: no value given."); 00026 }; 00027 00028 vector < GlobalPoint > pts; pts.reserve ( values.size()-1 ); 00029 vector< PointAndDistance> sorted_values ( values.size() ); 00030 partial_sort_copy ( values.begin(), values.end(), 00031 sorted_values.begin(), sorted_values.end(), compareByDistance() ); 00032 00033 vector< PointAndDistance>::iterator end = sorted_values.end(); 00034 vector< PointAndDistance>::iterator begin = sorted_values.begin(); 00035 00036 float dmax = 0.004; // 40 microns, as a first try. 00037 00038 // we want at least 30 values 00039 unsigned int min_num = values.size() < 30 ? values.size() : 30; 00040 00041 // we also want at least 50 % of all values 00042 if ( values.size() > 2 * min_num ) min_num = (int) values.size() / 2; 00043 00044 while ( pts.size() < min_num ) 00045 { 00046 // we cut at a dmax 00047 vector< PointAndDistance>::iterator i; 00048 for ( i=begin; i!=end && ( i->second < dmax ) ; ++i ) 00049 { 00050 pts.push_back ( i->first ); 00051 }; 00052 dmax +=0.003; // add 30 microns with every iteration 00053 begin=i; 00054 }; 00055 00056 GlobalPoint ret = hsm_3d ( pts ); 00057 return ret; 00058 } 00059 00060 SubsetHsmModeFinder3d * SubsetHsmModeFinder3d::clone() const 00061 { 00062 return new SubsetHsmModeFinder3d ( * this ); 00063 }