CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoVertex/LinearizationPointFinders/src/CrossingPtBasedLinearizationPointFinder.cc

Go to the documentation of this file.
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 // #define Use_GraphicsHarvester
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     int ret=0;
00051     for ( int i=1; i<= nr ; i++ )
00052     {
00053       ret+=i;
00054     }
00055     return ret;
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 /* nope, we dont clone!! */ ),
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      * old version, when we have a default constructor
00140      *
00141     
00142     std::vector <reco::TransientTrack> newtracks ( n_tracks );
00143     partial_sort_copy ( tracks.begin(), tracks.end(), newtracks.begin(),
00144                         newtracks.begin() + n_tracks  , CompareTwoTracks() );
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     // vgp.reserve ( ( tracks.size() * ( tracks.size()-1 ) ) / 2 - 1 );
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          } // If sth goes wrong, we just dont add. Who cares?
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     std::cout << "[CrossingPtBasedLinearizationPointFinder] input size="
00219          << input.size() << std::endl;*/
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             std::cout << "[CrossingPtBasedLinearizationPointFinder] we exploit all track pairs"
00252                  << std::endl;*/
00253             // we have fewer track pair options than is foreseen
00254             // in the quota.
00255             // so we exploit all tracks pairs.
00256             return useAllTracks ( tracks );
00257         }
00258 
00259         std::vector <reco::TransientTrack> goodtracks = getBestTracks ( tracks );
00260 
00261         // we sort according to momenta.
00262         if ( goodtracks.size() < 2 )
00263             throw LinPtException (
00264                 "CrossingPtBasedLinPtFinder: less than two tracks given");
00265         // vgp.reserve ( theNPairs - 1 );
00266         unsigned int t_first = 0;
00267         unsigned int t_interval = goodtracks.size() / 2;
00268         unsigned int lim = goodtracks.size() - 1;
00269 
00270         /*
00271         std::cout << "[CrossingPtBasedLinearizationPointFinder] we start: npairs=" << theNPairs
00272              << std::endl;
00273         std::cout << "[CrossingPtBasedLinearizationPointFinder] t_interval=" << t_interval << std::endl;
00274         std::cout << "[CrossingPtBasedLinearizationPointFinder goodtracks.size=" << goodtracks.size()
00275              << std::endl;*/
00276 
00277         // the 'direction' false: intervals will expand
00278         // true: intervals will shrink
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             // std::cout << "Considering now: " << t_first << ", " << t_first+t_interval << std::endl;
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             { // No DistanceMatrix available
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                     /* std::cout << "[CrossingPtBasedLinearizationPointFinder] t_interval=0. break."
00314                          << std::endl;*/
00315                     break;
00316                 }
00317             }
00318             else
00319             {
00320                 t_first=0;
00321                 t_interval++;
00322                 if ( t_interval == goodtracks.size() )
00323                 {
00324                     /* std::cout << "[CrossingPtBasedLinearizationPointFinder] t_interval="
00325                          << goodtracks.size() << "(max). start to decrease intervals"
00326                          << std::endl; */
00327                     dir=true;
00328                     t_interval =  goodtracks.size() / 2 - 1;
00329                 }
00330             }
00331         }
00332         if (! vgp.size() )
00333         {
00334             // no crossing points? Fallback to a crossingpoint-less lin pt finder!
00335             return FallbackLinearizationPointFinder().getLinearizationPoint ( tracks );
00336         }
00337         return find ( vgp );
00338     
00339     return GlobalPoint(0.,0.,0.); // if nothing else, then return 0,0,0
00340 }