CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/RecoTracker/MeasurementDet/src/TkGluedMeasurementDet.cc

Go to the documentation of this file.
00001 #include "RecoTracker/MeasurementDet/interface/TkGluedMeasurementDet.h"
00002 #include "TrackingTools/MeasurementDet/interface/MeasurementDetException.h"
00003 #include "RecoTracker/TransientTrackingRecHit/interface/TSiStripMatchedRecHit.h"
00004 #include "Geometry/TrackerGeometryBuilder/interface/GluedGeomDet.h"
00005 #include "RecoLocalTracker/SiStripRecHitConverter/interface/SiStripRecHitMatcher.h"
00006 #include "RecoTracker/MeasurementDet/interface/NonPropagatingDetMeasurements.h"
00007 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00008 #include "TrackingTools/TransientTrackingRecHit/interface/TrackingRecHitProjector.h"
00009 #include "RecoTracker/TransientTrackingRecHit/interface/ProjectedRecHit2D.h"
00010 #include "RecoTracker/MeasurementDet/interface/RecHitPropagator.h"
00011 #include "TrackingTools/TransientTrackingRecHit/interface/InvalidTransientRecHit.h"
00012 
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014 #include <iostream>
00015 
00016 #include <typeinfo>
00017 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00018 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
00019 
00020 using namespace std;
00021 
00022 TkGluedMeasurementDet::TkGluedMeasurementDet( const GluedGeomDet* gdet, 
00023                                               const SiStripRecHitMatcher* matcher,
00024                                               const MeasurementDet* monoDet,
00025                                               const MeasurementDet* stereoDet) :
00026   MeasurementDet(gdet), theGeomDet(gdet), 
00027   theMatcher(matcher), 
00028   theMonoDet( dynamic_cast<const TkStripMeasurementDet *>(monoDet)), 
00029   theStereoDet( dynamic_cast<const TkStripMeasurementDet *>(stereoDet))
00030 {
00031   if ((theMonoDet == 0) || (theStereoDet == 0)) {
00032         throw MeasurementDetException("TkGluedMeasurementDet ERROR: Trying to glue a det which is not a TkStripMeasurementDet");
00033   }
00034   
00035 }
00036 
00037 TkGluedMeasurementDet::RecHitContainer 
00038 TkGluedMeasurementDet::recHits( const TrajectoryStateOnSurface& ts) const
00039 {
00040 
00041   RecHitContainer result;
00042   HitCollectorForRecHits collector( &geomDet(), theMatcher, result );
00043   collectRecHits(ts, collector);
00044   return result;
00045 }
00046 
00047 struct take_address { template<typename T> const T * operator()(const T &val) const { return &val; } };
00048 
00049 #ifdef DOUBLE_MATCH
00050 template<typename Collector>
00051 void
00052 TkGluedMeasurementDet::collectRecHits( const TrajectoryStateOnSurface& ts, Collector & collector) const
00053 {
00054   doubleMatch(ts,collector);
00055 }
00056 #else
00057 template<typename Collector>
00058 void
00059 TkGluedMeasurementDet::collectRecHits( const TrajectoryStateOnSurface& ts, Collector & collector) const
00060 {
00061   //------ WARNING: here ts is used as it is on the mono/stereo surface.
00062   //-----           A further propagation is necessary.
00063   //-----           To limit the problem, the SimpleCPE should be used
00064   RecHitContainer monoHits = theMonoDet->recHits( ts);
00065   GlobalVector glbDir = (ts.isValid() ? ts.globalParameters().momentum() : position()-GlobalPoint(0,0,0));
00066 
00067   //edm::LogWarning("TkGluedMeasurementDet::recHits") << "Query-for-detid-" << theGeomDet->geographicalId().rawId();
00068 
00069   //checkProjection(ts, monoHits, stereoHits);
00070 
00071   if (monoHits.empty()) {
00072       // make stereo TTRHs and project them
00073       projectOnGluedDet( collector, theStereoDet->recHits(ts), glbDir);
00074   } else {
00075       // collect simple stereo hits
00076       static std::vector<SiStripRecHit2D> simpleSteroHitsByValue;
00077       simpleSteroHitsByValue.clear();
00078       theStereoDet->simpleRecHits(ts, simpleSteroHitsByValue);
00079 
00080       if (simpleSteroHitsByValue.empty()) {
00081           projectOnGluedDet( collector, monoHits, glbDir);
00082       } else {
00083 
00084           LocalVector tkDir = (ts.isValid() ? ts.localDirection() : surface().toLocal( position()-GlobalPoint(0,0,0)));
00085           static SiStripRecHitMatcher::SimpleHitCollection vsStereoHits;
00086           vsStereoHits.resize(simpleSteroHitsByValue.size());
00087           std::transform(simpleSteroHitsByValue.begin(), simpleSteroHitsByValue.end(), vsStereoHits.begin(), take_address()); 
00088 
00089           // convert mono hits to type expected by matcher
00090           for (RecHitContainer::const_iterator monoHit = monoHits.begin();
00091                   monoHit != monoHits.end(); ++monoHit) {
00092               const TrackingRecHit* tkhit = (**monoHit).hit();
00093               const SiStripRecHit2D* verySpecificMonoHit = reinterpret_cast<const SiStripRecHit2D*>(tkhit);
00094               theMatcher->match( verySpecificMonoHit, vsStereoHits.begin(), vsStereoHits.end(), 
00095                       collector.collector(), &specificGeomDet(), tkDir);
00096 
00097               if (collector.hasNewMatchedHits()) {
00098                   collector.clearNewMatchedHitsFlag();
00099               } else {
00100                   collector.addProjected( **monoHit, glbDir );
00101               }
00102           } // loop on mono hit
00103       }
00104       //GIO// std::cerr << "TkGluedMeasurementDet hits " << monoHits.size() << "/" << stereoHits.size() << " => " << result.size() << std::endl;
00105   }
00106 }
00107 #endif
00108 
00109 std::vector<TrajectoryMeasurement> 
00110 TkGluedMeasurementDet::fastMeasurements( const TrajectoryStateOnSurface& stateOnThisDet, 
00111                                          const TrajectoryStateOnSurface& startingState, 
00112                                          const Propagator&, 
00113                                          const MeasurementEstimator& est) const
00114 {
00115    std::vector<TrajectoryMeasurement> result;
00116    if (theMonoDet->isActive() || theStereoDet->isActive()) {
00117 
00118       HitCollectorForFastMeasurements collector( &geomDet(), theMatcher, stateOnThisDet, est, result);
00119       collectRecHits(stateOnThisDet, collector);
00120        
00121       if ( result.empty()) {
00122           //LogDebug("TkStripMeasurementDet") << "No hit found on TkGlued. Testing strips...  ";
00123           const BoundPlane &gluedPlane = geomDet().surface();
00124           if (  // sorry for the big IF, but I want to exploit short-circuiting of logic
00125                stateOnThisDet.hasError() && ( /* do this only if the state has uncertainties, otherwise it will throw 
00126                                                  (states without uncertainties are passed to this code from seeding */
00127                 (theMonoDet->isActive() && 
00128                     (theMonoDet->hasAllGoodChannels() || 
00129                        testStrips(stateOnThisDet,gluedPlane,*theMonoDet)
00130                     )
00131                 ) /*Mono OK*/ || 
00132                 (theStereoDet->isActive() && 
00133                     (theStereoDet->hasAllGoodChannels() || 
00134                        testStrips(stateOnThisDet,gluedPlane,*theStereoDet)
00135                     )
00136                 ) /*Stereo OK*/ 
00137                ) /* State has errors */
00138               ) {
00139               result.push_back( TrajectoryMeasurement( stateOnThisDet, 
00140                           InvalidTransientRecHit::build(&geomDet()), 0.F)); 
00141           } else {
00142               result.push_back( TrajectoryMeasurement(stateOnThisDet, 
00143                          InvalidTransientRecHit::build(&geomDet(), TrackingRecHit::inactive), 0.F));
00144           }
00145       } else {
00146           // sort results according to estimator value
00147           if ( result.size() > 1) {
00148               sort( result.begin(), result.end(), TrajMeasLessEstim());
00149           }
00150       }
00151    } else {
00152      //     LogDebug("TkStripMeasurementDet") << " DetID " << geomDet().geographicalId().rawId() << " (glued) fully inactive";
00153       result.push_back( TrajectoryMeasurement( stateOnThisDet, 
00154                InvalidTransientRecHit::build(&geomDet(), TrackingRecHit::inactive), 
00155                0.F));
00156    }
00157    return result;       
00158 
00159 }
00160 
00161 TkGluedMeasurementDet::RecHitContainer 
00162 TkGluedMeasurementDet::projectOnGluedDet( const RecHitContainer& hits,
00163                                           const TrajectoryStateOnSurface& ts) const
00164 {
00165   if (hits.empty()) return hits;
00166   TrackingRecHitProjector<ProjectedRecHit2D> proj;
00167   RecHitContainer result;
00168   for ( RecHitContainer::const_iterator ihit = hits.begin(); ihit!=hits.end(); ihit++) {
00169     result.push_back( proj.project( **ihit, geomDet(), ts));
00170   }
00171   return result;
00172 }
00173 
00174 template<typename Collector>
00175 void 
00176 TkGluedMeasurementDet::projectOnGluedDet( Collector& collector,
00177                                           const RecHitContainer& hits,
00178                                           const GlobalVector & gdir ) const 
00179 {
00180   for ( RecHitContainer::const_iterator ihit = hits.begin(); ihit!=hits.end(); ihit++) {
00181     collector.addProjected( **ihit, gdir );
00182   }
00183 }
00184 
00185 void TkGluedMeasurementDet::checkProjection(const TrajectoryStateOnSurface& ts, 
00186                                             const RecHitContainer& monoHits, 
00187                                             const RecHitContainer& stereoHits) const
00188 {
00189   for (RecHitContainer::const_iterator i=monoHits.begin(); i != monoHits.end(); ++i) {
00190     checkHitProjection( **i, ts, geomDet());
00191   }
00192   for (RecHitContainer::const_iterator i=stereoHits.begin(); i != stereoHits.end(); ++i) {
00193     checkHitProjection( **i, ts, geomDet());
00194   }
00195 }
00196 
00197 void TkGluedMeasurementDet::checkHitProjection(const TransientTrackingRecHit& hit,
00198                                                const TrajectoryStateOnSurface& ts, 
00199                                                const GeomDet& det) const
00200 {
00201   TrackingRecHitProjector<ProjectedRecHit2D> proj;
00202   TransientTrackingRecHit::RecHitPointer projectedHit = proj.project( hit, det, ts);
00203 
00204   RecHitPropagator prop;
00205   TrajectoryStateOnSurface propState = prop.propagate( hit, det.surface(), ts);
00206 
00207   if ((projectedHit->localPosition()-propState.localPosition()).mag() > 0.0001) {
00208     cout << "PROBLEM: projected and propagated hit positions differ by " 
00209          << (projectedHit->localPosition()-propState.localPosition()).mag() << endl;
00210   }
00211 
00212   LocalError le1 = projectedHit->localPositionError();
00213   LocalError le2 = propState.localError().positionError();
00214   double eps = 1.e-5;
00215   double cutoff = 1.e-4; // if element below cutoff, use absolute instead of relative accuracy
00216   double maxdiff = std::max( std::max( fabs(le1.xx() - le2.xx())/(cutoff+le1.xx()),
00217                                        fabs(le1.xy() - le2.xy())/(cutoff+fabs(le1.xy()))),
00218                              fabs(le1.yy() - le2.yy())/(cutoff+le1.xx()));  
00219   if (maxdiff > eps) { 
00220     cout << "PROBLEM: projected and propagated hit errors differ by " 
00221          << maxdiff << endl;
00222   }
00223   
00224 }
00225 
00226 bool
00227 TkGluedMeasurementDet::testStrips(const TrajectoryStateOnSurface& tsos,
00228                                   const BoundPlane &gluedPlane,
00229                                   const TkStripMeasurementDet &mdet) const {
00230    // from TrackingRecHitProjector
00231    const GeomDet &det = mdet.geomDet();
00232    const BoundPlane &stripPlane = det.surface();
00233 
00234    LocalPoint glp = tsos.localPosition();
00235    LocalError  err = tsos.localError().positionError();
00236    /*LogDebug("TkStripMeasurementDet") << 
00237       "Testing local pos glued: " << glp << 
00238       " local err glued: " << tsos.localError().positionError() << 
00239       " in? " << gluedPlane.bounds().inside(glp) <<
00240       " in(3s)? " << gluedPlane.bounds().inside(glp, err, 3.0f);*/
00241 
00242    GlobalVector gdir = tsos.globalParameters().momentum();
00243 
00244    LocalPoint  slp = stripPlane.toLocal(tsos.globalPosition()); 
00245    LocalVector sld = stripPlane.toLocal(gdir);
00246 
00247    double delta = stripPlane.localZ( tsos.globalPosition());
00248    LocalPoint pos = slp - sld * delta/sld.z();
00249 
00250 
00251    // now the error
00252    LocalVector hitXAxis = stripPlane.toLocal( gluedPlane.toGlobal( LocalVector(1,0,0)));
00253    if (stripPlane.normalVector().dot( gluedPlane.normalVector()) < 0) {
00254        // the two planes are inverted, and the correlation element must change sign
00255        err = LocalError( err.xx(), -err.xy(), err.yy());
00256    }
00257    LocalError rotatedError = err.rotate( hitXAxis.x(), hitXAxis.y());
00258 
00259    /* // This is probably meaningless 
00260    LogDebug("TkStripMeasurementDet") << 
00261       "Testing local pos on strip (SLP): " << slp << 
00262       " in? :" << stripPlane.bounds().inside(slp) <<
00263       " in(3s)? :" << stripPlane.bounds().inside(slp, rotatedError, 3.0f);
00264    // but it helps to test bugs in the formula for POS */
00265    /*LogDebug("TkStripMeasurementDet") << 
00266       "Testing local pos strip: " << pos << 
00267       " in? " << stripPlane.bounds().inside(pos) <<
00268       " in(3s)? " << stripPlane.bounds().inside(pos, rotatedError, 3.0f);*/
00269 
00270    // now we need to convert to MeasurementFrame
00271    const StripTopology &topo = mdet.specificGeomDet().specificTopology();
00272    float utraj = topo.measurementPosition(pos).x();
00273    float uerr  = std::sqrt(topo.measurementError(pos,rotatedError).uu());
00274    return mdet.testStrips(utraj, uerr);
00275 } 
00276 
00277 #include<boost/bind.hpp>
00278 TkGluedMeasurementDet::HitCollectorForRecHits::HitCollectorForRecHits(const GeomDet * geomDet, 
00279         const SiStripRecHitMatcher * matcher,
00280         RecHitContainer & target) :
00281     geomDet_(geomDet), matcher_(matcher), target_(target),
00282     collector_(boost::bind(&HitCollectorForRecHits::add,boost::ref(*this),_1)),
00283     hasNewHits_(false)
00284 {
00285 }
00286 
00287 void
00288 TkGluedMeasurementDet::HitCollectorForRecHits::addProjected(const TransientTrackingRecHit& hit,
00289                                                             const GlobalVector & gdir)
00290 {
00291     TrackingRecHitProjector<ProjectedRecHit2D> proj;
00292     target_.push_back( proj.project( hit, *geomDet_, gdir));
00293 }
00294 
00295 TkGluedMeasurementDet::HitCollectorForFastMeasurements::HitCollectorForFastMeasurements(const GeomDet * geomDet, 
00296         const SiStripRecHitMatcher * matcher,
00297         const TrajectoryStateOnSurface& stateOnThisDet,
00298         const MeasurementEstimator& est,
00299         std::vector<TrajectoryMeasurement> & target) :
00300     geomDet_(geomDet), matcher_(matcher), stateOnThisDet_(stateOnThisDet), est_(est), target_(target),
00301     collector_(boost::bind(&HitCollectorForFastMeasurements::add,boost::ref(*this),_1)),
00302     hasNewHits_(false)
00303 {
00304 }
00305 
00306 void
00307 TkGluedMeasurementDet::HitCollectorForFastMeasurements::add(SiStripMatchedRecHit2D const& hit2d) 
00308 {
00309   static LocalCache<TSiStripMatchedRecHit> lcache; // in case of pool allocator it will be cleared centrally
00310   std::auto_ptr<TSiStripMatchedRecHit> & cache = lcache.ptr;
00311   TSiStripMatchedRecHit::buildInPlace( cache, geomDet_, &hit2d, matcher_ );
00312   std::pair<bool,double> diffEst = est_.estimate( stateOnThisDet_, *cache);
00313   if ( diffEst.first) {
00314     cache->clonePersistentHit(); // clone and take ownership of the persistent 2D hit
00315     target_.push_back( 
00316                       TrajectoryMeasurement( stateOnThisDet_, 
00317                                              RecHitPointer(cache.release()), 
00318                                              diffEst.second)
00319                        );
00320   } else {
00321     cache->clearPersistentHit(); // drop ownership
00322   } 
00323   hasNewHits_ = true; //FIXME: see also what happens moving this within testAndPush
00324 }
00325 
00326 void
00327 TkGluedMeasurementDet::HitCollectorForFastMeasurements::addProjected(const TransientTrackingRecHit& hit,
00328                                                             const GlobalVector & gdir)
00329 {
00330     // here we're ok with some extra casual new's and delete's
00331     TrackingRecHitProjector<ProjectedRecHit2D> proj;
00332     RecHitPointer phit = proj.project( hit, *geomDet_, gdir );
00333     std::pair<bool,double> diffEst = est_.estimate( stateOnThisDet_, *phit);
00334     if ( diffEst.first) {
00335         target_.push_back( TrajectoryMeasurement( stateOnThisDet_, phit, diffEst.second) );
00336     }
00337 
00338 }
00339 
00340 
00341 
00342 #ifdef DOUBLE_MATCH
00343 #include "doubleMatch.icc"
00344 #endif