00001 #include "RecoVertex/LinearizationPointFinders/interface/CrossingPtBasedLinearizationPointFinder.h"
00002 #include "RecoVertex/LinearizationPointFinders/interface/LinPtException.h"
00003 #include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistance.h"
00004 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00005 #include "RecoVertex/VertexTools/interface/ModeFinder3d.h"
00006 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00007 #include "RecoVertex/LinearizationPointFinders/interface/FallbackLinearizationPointFinder.h"
00008 #include <cmath>
00009 #include <algorithm>
00010
00011
00012 #ifdef Use_GraphicsHarvester
00013 #include "RecoVertex/VertexSimpleVis/interface/PrimitivesHarvester.h"
00014 #include "Utilities/UI/interface/SimpleConfigurable.h"
00015 #include "RecoVertex/VertexTools/interface/SubsetHsmModeFinder3d.h"
00016 #include "RecoVertex/VertexTools/interface/HsmModeFinder3d.h"
00017 #include "RecoVertex/VertexTools/interface/LmsModeFinder3d.h"
00018 #endif
00019
00020 namespace
00021 {
00022 inline GlobalPoint operator - ( const GlobalPoint & a, const GlobalPoint & b )
00023 {
00024 return GlobalPoint ( a.x() - b.x(), a.y() - b.y(), a.z() - b.z() );
00025 }
00026
00027 inline GlobalPoint operator + ( const GlobalPoint & a, const GlobalPoint & b )
00028 {
00029 return GlobalPoint ( a.x() + b.x(), a.y() + b.y(), a.z() + b.z() );
00030 }
00031
00032 inline GlobalPoint operator / ( const GlobalPoint & a, const double b )
00033 {
00034 return GlobalPoint ( a.x() / b, a.y() / b, a.z() / b );
00035 }
00036
00037 inline GlobalPoint operator * ( const GlobalPoint & a, const double b )
00038 {
00039 return GlobalPoint ( a.x() * b, a.y() * b, a.z() * b );
00040 }
00041
00042 inline GlobalPoint operator * ( const double b , const GlobalPoint & a )
00043 {
00044 return GlobalPoint ( a.x() * b, a.y() * b, a.z() * b );
00045 }
00046
00047 inline unsigned int sum ( unsigned int nr )
00048 {
00049
00050
00051
00052
00053
00054
00055
00056
00057 return ( nr * ( nr + 1 ) ) / 2;
00058 }
00059
00060 #ifdef Use_GraphicsHarvester
00061
00062 void graphicsDebug ( const std::vector < PointAndDistance > & input )
00063 {
00064 bool sve = SimpleConfigurable<bool> (false,
00065 "CrossingPointStudy:Harvest").value();
00066 std::string fname = SimpleConfigurable<string>("crossingpoints.txt",
00067 "CrossingPointStudy:FileName").value();
00068 if (sve)
00069 {
00070 for ( std::vector< PointAndDistance >::const_iterator i=input.begin();
00071 i!=input.end() ; ++i )
00072 {
00073 std::map < std::string, MultiType > attrs;
00074 attrs["name"]="GlobalPoint";
00075 attrs["color"]="yellow";
00076 attrs["mag"]=.7;
00077 attrs["comment"]="Input for CrossingPtBasedLinearizationPointFinder";
00078 PrimitivesHarvester( fname )
00079 .save ( i->first, attrs );
00080 }
00081 std::map < std::string, MultiType > attrs;
00082 attrs["name"]="The Mode(*theAlgo)";
00083 attrs["color"]="green";
00084 attrs["comment"]="Output from CrossingPtBasedLinearizationPointFinder";
00085 PrimitivesHarvester( fname )
00086 .save ( ret, attrs );
00087 GlobalPoint subsethsm = SubsetHsmModeFinder3d()( input );
00088 attrs["name"]="The Mode(SubsetHSM)";
00089 attrs["color"]="red";
00090 PrimitivesHarvester( fname ).save ( subsethsm, attrs );
00091 GlobalPoint hsm = HsmModeFinder3d()( input );
00092 attrs["name"]="The Mode(HSM)";
00093 attrs["color"]="blue";
00094 PrimitivesHarvester( fname ).save ( hsm, attrs );
00095 GlobalPoint lms = LmsModeFinder3d()( input );
00096 attrs["name"]="The Mode(LMS)";
00097 attrs["color"]="gold";
00098 PrimitivesHarvester( fname ).save ( lms, attrs );
00099 }
00100 }
00101 #endif
00102 }
00103
00104 CrossingPtBasedLinearizationPointFinder::CrossingPtBasedLinearizationPointFinder(
00105 const ModeFinder3d & algo, const signed int n_pairs ) :
00106 useMatrix ( false ) , theNPairs ( n_pairs ), theMatrix ( 0 ),
00107 theAlgo ( algo.clone() )
00108 {}
00109
00110 CrossingPtBasedLinearizationPointFinder::CrossingPtBasedLinearizationPointFinder(
00111 const RecTracksDistanceMatrix * m, const ModeFinder3d & algo,
00112 const signed int n_pairs ) :
00113 useMatrix ( m->hasCrossingPoints() ) ,
00114 theNPairs ( n_pairs ), theMatrix ( m ), theAlgo ( algo.clone() )
00115 {}
00116
00117 CrossingPtBasedLinearizationPointFinder::CrossingPtBasedLinearizationPointFinder
00118 ( const CrossingPtBasedLinearizationPointFinder & o ) :
00119 useMatrix ( o.useMatrix ), theNPairs ( o.theNPairs ),
00120 theMatrix ( o.theMatrix ),
00121 theAlgo ( o.theAlgo->clone() )
00122 {}
00123
00124 CrossingPtBasedLinearizationPointFinder::~CrossingPtBasedLinearizationPointFinder()
00125 {
00126 delete theAlgo;
00127 }
00128
00129 std::vector <reco::TransientTrack> CrossingPtBasedLinearizationPointFinder::getBestTracks (
00130 const std::vector<reco::TransientTrack> & tracks ) const
00131 {
00132 unsigned int n_tracks = (2*(unsigned int) (theNPairs)) < tracks.size() ? 2*theNPairs : tracks.size();
00133
00134 std::vector <reco::TransientTrack> newtracks = tracks;
00135 partial_sort ( newtracks.begin(), newtracks.begin()+n_tracks, newtracks.end(), CompareTwoTracks() );
00136 newtracks.erase ( newtracks.begin()+n_tracks, newtracks.end() );
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 return newtracks;
00148 }
00149
00150 typedef std::pair < GlobalPoint , float > PointAndDistance;
00151
00152 GlobalPoint CrossingPtBasedLinearizationPointFinder::useAllTracks(
00153 const std::vector<reco::TransientTrack> & tracks ) const
00154 {
00155 std::vector< PointAndDistance > vgp;
00156
00157 TwoTrackMinimumDistance ttmd;
00158 bool status;
00159 std::vector<reco::TransientTrack>::const_iterator end=tracks.end();
00160 std::vector<reco::TransientTrack>::const_iterator endm1=(end-1);
00161 for ( std::vector<reco::TransientTrack>::const_iterator x=tracks.begin();
00162 x!=endm1 ; ++x )
00163 {
00164 for ( std::vector<reco::TransientTrack>::const_iterator y=x+1;
00165 y!=end; ++y )
00166 {
00167 status = ttmd.calculate( (*x).impactPointState(), (*y).impactPointState() );
00168 if (status) {
00169 std::pair < GlobalPoint, GlobalPoint > pts = ttmd.points();
00170 std::pair < GlobalPoint , float > v ( ( pts.second + pts.first ) / 2. ,
00171 ( pts.second - pts.first ).mag() );
00172 vgp.push_back( v );
00173 }
00174 }
00175 }
00176 if (! vgp.size() )
00177 {
00178 return FallbackLinearizationPointFinder().getLinearizationPoint ( tracks );
00179 }
00180 return find ( vgp );
00181 }
00182
00183 GlobalPoint CrossingPtBasedLinearizationPointFinder::useFullMatrix(
00184 const std::vector<reco::TransientTrack> & tracks ) const
00185 {
00186 std::vector< PointAndDistance > vgp;
00187 vgp.reserve ( (int) ( tracks.size() * ( tracks.size() -1 ) / 2. - 1 ) );
00188 std::vector<reco::TransientTrack>::const_iterator end=tracks.end();
00189 std::vector<reco::TransientTrack>::const_iterator endm1=(end-1);
00190 for ( std::vector<reco::TransientTrack>::const_iterator x=tracks.begin();
00191 x!=endm1 ; ++x )
00192 {
00193 for ( std::vector<reco::TransientTrack>::const_iterator y=x+1;
00194 y!=end; ++y )
00195 {
00196 PointAndDistance v ( theMatrix->crossingPoint ( *x , *y ),
00197 theMatrix->distance ( *x, *y ) );
00198 vgp.push_back ( v );
00199 }
00200 }
00201 if (! vgp.size() )
00202 {
00203 return FallbackLinearizationPointFinder().getLinearizationPoint ( tracks );
00204 }
00205 return find ( vgp );
00206 }
00207
00208 GlobalPoint CrossingPtBasedLinearizationPointFinder::getLinearizationPoint(
00209 const std::vector<FreeTrajectoryState> & tracks ) const
00210 {
00211 return LinearizationPointFinder::getLinearizationPoint ( tracks );
00212 }
00213
00214 GlobalPoint CrossingPtBasedLinearizationPointFinder::find (
00215 const std::vector < PointAndDistance > & input ) const
00216 {
00217
00218
00219
00220 GlobalPoint ret = (*theAlgo) (input);
00221 #ifdef Use_GraphicsHarvester
00222
00223 graphicsDebug ( input );
00224 #endif
00225
00226 return ret;
00227 }
00228
00229 GlobalPoint CrossingPtBasedLinearizationPointFinder::getLinearizationPoint(
00230 const std::vector<reco::TransientTrack> & tracks ) const
00231 {
00232 if ( tracks.size() < 2 )
00233 throw LinPtException
00234 ("CrossingPtBasedLinPtFinder: too few tracks given.");
00235 std::vector < PointAndDistance > vgp;
00236 if ( theNPairs == -1 )
00237 {
00238 if ( useMatrix )
00239 {
00240 return useFullMatrix( tracks );
00241 }
00242 else
00243 {
00244 return useAllTracks ( tracks );
00245 }
00246 }
00247
00248 if ( sum ( tracks.size() - 1 ) < ((unsigned int) (theNPairs)) )
00249 {
00250
00251
00252
00253
00254
00255
00256 return useAllTracks ( tracks );
00257 }
00258
00259 std::vector <reco::TransientTrack> goodtracks = getBestTracks ( tracks );
00260
00261
00262 if ( goodtracks.size() < 2 )
00263 throw LinPtException (
00264 "CrossingPtBasedLinPtFinder: less than two tracks given");
00265
00266 unsigned int t_first = 0;
00267 unsigned int t_interval = goodtracks.size() / 2;
00268 unsigned int lim = goodtracks.size() - 1;
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 bool dir = false;
00280
00281 while ( vgp.size() < ((unsigned int) (theNPairs)) )
00282 {
00283 reco::TransientTrack rt1 = goodtracks [ t_first ];
00284 reco::TransientTrack rt2 = goodtracks [ t_first + t_interval ];
00285
00286 if ( useMatrix )
00287 {
00288 PointAndDistance v ( theMatrix->crossingPoint ( rt1, rt2 ),
00289 theMatrix->distance ( rt1, rt2 ) );
00290 vgp.push_back ( v );
00291 }
00292 else
00293 {
00294 TwoTrackMinimumDistance ttmd;
00295 bool status = ttmd.calculate( rt1.impactPointState(), rt2.impactPointState() );
00296 if (status) {
00297 std::pair < GlobalPoint, GlobalPoint > pts = ttmd.points();
00298 PointAndDistance v ( ( pts.second + pts.first ) / 2. ,
00299 ( pts.second - pts.first ).mag() );
00300 vgp.push_back( v );
00301 }
00302 }
00303 if ( ( t_first + t_interval ) < lim )
00304 {
00305 t_first++;
00306 }
00307 else if ( dir )
00308 {
00309 t_first=0;
00310 t_interval--;
00311 if ( t_interval == 0 )
00312 {
00313
00314
00315 break;
00316 }
00317 }
00318 else
00319 {
00320 t_first=0;
00321 t_interval++;
00322 if ( t_interval == goodtracks.size() )
00323 {
00324
00325
00326
00327 dir=true;
00328 t_interval = goodtracks.size() / 2 - 1;
00329 }
00330 }
00331 }
00332 if (! vgp.size() )
00333 {
00334
00335 return FallbackLinearizationPointFinder().getLinearizationPoint ( tracks );
00336 }
00337 return find ( vgp );
00338
00339 return GlobalPoint(0.,0.,0.);
00340 }