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
00062
00063
00064 RecHitContainer monoHits = theMonoDet->recHits( ts);
00065 GlobalVector glbDir = (ts.isValid() ? ts.globalParameters().momentum() : position()-GlobalPoint(0,0,0));
00066
00067
00068
00069
00070
00071 if (monoHits.empty()) {
00072
00073 projectOnGluedDet( collector, theStereoDet->recHits(ts), glbDir);
00074 } else {
00075
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
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 }
00103 }
00104
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
00123 const BoundPlane &gluedPlane = geomDet().surface();
00124 if (
00125 stateOnThisDet.hasError() && (
00126
00127 (theMonoDet->isActive() &&
00128 (theMonoDet->hasAllGoodChannels() ||
00129 testStrips(stateOnThisDet,gluedPlane,*theMonoDet)
00130 )
00131 ) ||
00132 (theStereoDet->isActive() &&
00133 (theStereoDet->hasAllGoodChannels() ||
00134 testStrips(stateOnThisDet,gluedPlane,*theStereoDet)
00135 )
00136 )
00137 )
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
00147 if ( result.size() > 1) {
00148 sort( result.begin(), result.end(), TrajMeasLessEstim());
00149 }
00150 }
00151 } else {
00152
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;
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
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
00237
00238
00239
00240
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
00252 LocalVector hitXAxis = stripPlane.toLocal( gluedPlane.toGlobal( LocalVector(1,0,0)));
00253 if (stripPlane.normalVector().dot( gluedPlane.normalVector()) < 0) {
00254
00255 err = LocalError( err.xx(), -err.xy(), err.yy());
00256 }
00257 LocalError rotatedError = err.rotate( hitXAxis.x(), hitXAxis.y());
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
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;
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();
00315 target_.push_back(
00316 TrajectoryMeasurement( stateOnThisDet_,
00317 RecHitPointer(cache.release()),
00318 diffEst.second)
00319 );
00320 } else {
00321 cache->clearPersistentHit();
00322 }
00323 hasNewHits_ = true;
00324 }
00325
00326 void
00327 TkGluedMeasurementDet::HitCollectorForFastMeasurements::addProjected(const TransientTrackingRecHit& hit,
00328 const GlobalVector & gdir)
00329 {
00330
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