CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoTracker/MeasurementDet/plugins/TkGluedMeasurementDet.cc

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