CMS 3D CMS Logo

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