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 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
00066
00067
00068 RecHitContainer monoHits = theMonoDet->recHits( ts);
00069 GlobalVector glbDir = (ts.isValid() ? ts.globalParameters().momentum() : position()-GlobalPoint(0,0,0));
00070
00071
00072
00073
00074
00075 if (monoHits.empty()) {
00076
00077 projectOnGluedDet( collector, theStereoDet->recHits(ts), glbDir);
00078 } else {
00079
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
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 }
00107 }
00108
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
00127 const BoundPlane &gluedPlane = geomDet().surface();
00128 if (
00129 stateOnThisDet.hasError() && (
00130
00131 (theMonoDet->isActive() &&
00132 (theMonoDet->hasAllGoodChannels() ||
00133 testStrips(stateOnThisDet,gluedPlane,*theMonoDet)
00134 )
00135 ) ||
00136 (theStereoDet->isActive() &&
00137 (theStereoDet->hasAllGoodChannels() ||
00138 testStrips(stateOnThisDet,gluedPlane,*theStereoDet)
00139 )
00140 )
00141 )
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
00151 if ( result.size() > 1) {
00152 sort( result.begin(), result.end(), TrajMeasLessEstim());
00153 }
00154 }
00155 } else {
00156
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;
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
00235 const GeomDet &det = mdet.fastGeomDet();
00236 const BoundPlane &stripPlane = det.surface();
00237
00238
00239 LocalError err = tsos.localError().positionError();
00240
00241
00242
00243
00244
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
00256 LocalVector hitXAxis = stripPlane.toLocal( gluedPlane.toGlobal( LocalVector(1,0,0)));
00257 if (stripPlane.normalVector().dot( gluedPlane.normalVector()) < 0) {
00258
00259 err = LocalError( err.xx(), -err.xy(), err.yy());
00260 }
00261 LocalError rotatedError = err.rotate( hitXAxis.x(), hitXAxis.y());
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
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;
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();
00319 target_.push_back(
00320 TrajectoryMeasurement( stateOnThisDet_,
00321 RecHitPointer(cache.release()),
00322 diffEst.second)
00323 );
00324 } else {
00325 cache->clearPersistentHit();
00326 }
00327 hasNewHits_ = true;
00328 }
00329
00330 void
00331 TkGluedMeasurementDet::HitCollectorForFastMeasurements::addProjected(const TransientTrackingRecHit& hit,
00332 const GlobalVector & gdir)
00333 {
00334
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