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