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
00019 using namespace std;
00020
00021 TkGluedMeasurementDet::TkGluedMeasurementDet( const GluedGeomDet* gdet,
00022 const SiStripRecHitMatcher* matcher,
00023 const MeasurementDet* monoDet,
00024 const MeasurementDet* stereoDet) :
00025 MeasurementDet(gdet), theGeomDet(gdet),
00026 theMatcher(matcher),
00027 theMonoDet( dynamic_cast<const TkStripMeasurementDet *>(monoDet)),
00028 theStereoDet( dynamic_cast<const TkStripMeasurementDet *>(stereoDet))
00029 {
00030 if ((theMonoDet == 0) || (theStereoDet == 0)) {
00031 throw MeasurementDetException("TkGluedMeasurementDet ERROR: Trying to glue a det which is not a TkStripMeasurementDet");
00032 }
00033
00034 }
00035
00036 TkGluedMeasurementDet::RecHitContainer
00037 TkGluedMeasurementDet::recHits( const TrajectoryStateOnSurface& ts) const
00038 {
00039
00040 RecHitContainer result;
00041
00042
00043
00044
00045 RecHitContainer monoHits = theMonoDet->recHits( ts);
00046 RecHitContainer stereoHits = theStereoDet->recHits( ts);
00047
00048
00049
00050
00051
00052 if (monoHits.empty()) return projectOnGluedDet( stereoHits, ts);
00053 else if (stereoHits.empty()) return projectOnGluedDet(monoHits, ts);
00054 else {
00055 LocalVector tkDir = (ts.isValid() ? ts.localDirection() : surface().toLocal( position()-GlobalPoint(0,0,0)));
00056
00057
00058 SiStripRecHitMatcher::SimpleHitCollection vsStereoHits;
00059 vsStereoHits.reserve(stereoHits.size());
00060 for (RecHitContainer::const_iterator stereoHit = stereoHits.begin();
00061 stereoHit != stereoHits.end(); ++stereoHit) {
00062 const TrackingRecHit* tkhit = (**stereoHit).hit();
00063 const SiStripRecHit2D* verySpecificStereoHit =
00064 reinterpret_cast<const SiStripRecHit2D*>(tkhit);
00065
00066
00067
00068
00069 vsStereoHits.push_back( verySpecificStereoHit );
00070 }
00071
00072
00073 std::vector<SiStripMatchedRecHit2D*> tmp;
00074 tmp.reserve(vsStereoHits.size());
00075
00076 for (RecHitContainer::const_iterator monoHit = monoHits.begin();
00077 monoHit != monoHits.end(); ++monoHit) {
00078 const TrackingRecHit* tkhit = (**monoHit).hit();
00079 const SiStripRecHit2D* verySpecificMonoHit =
00080 reinterpret_cast<const SiStripRecHit2D*>(tkhit);
00081 tmp.clear();
00082 theMatcher->match( verySpecificMonoHit, vsStereoHits.begin(), vsStereoHits.end(),
00083 tmp, &specificGeomDet(), tkDir);
00084
00085 if (!tmp.empty()) {
00086 for (std::vector<SiStripMatchedRecHit2D*>::iterator i=tmp.begin(), e = tmp.end();
00087 i != e; ++i) {
00088 result.push_back(
00089 TSiStripMatchedRecHit::build( &geomDet(),
00090 std::auto_ptr<TrackingRecHit>(*i),
00091 theMatcher));
00092 }
00093 } else {
00094
00095
00096
00097
00098
00099
00100
00101 TrackingRecHitProjector<ProjectedRecHit2D> proj;
00102 result.push_back( proj.project( **monoHit, geomDet(), ts));
00103
00104 }
00105 }
00106 }
00107 return result;
00108 }
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 if (theMonoDet->isActive() || theStereoDet->isActive()) {
00117 NonPropagatingDetMeasurements realOne;
00118
00119 std::vector<TrajectoryMeasurement> ret = realOne.get( *this, stateOnThisDet, est);
00120
00121 if (!ret[0].recHit()->isValid()) {
00122
00123 const BoundPlane &gluedPlane = geomDet().surface();
00124 if (
00125 (theMonoDet->isActive() &&
00126 (theMonoDet->hasAllGoodChannels() ||
00127 testStrips(stateOnThisDet,gluedPlane,*theMonoDet)
00128 )
00129 ) ||
00130 (theStereoDet->isActive() &&
00131 (theStereoDet->hasAllGoodChannels() ||
00132 testStrips(stateOnThisDet,gluedPlane,*theStereoDet)
00133 )
00134 )
00135 ) {
00136
00137
00138 } else {
00139
00140
00141 ret[0] = TrajectoryMeasurement(stateOnThisDet,
00142 InvalidTransientRecHit::build(&geomDet(), TrackingRecHit::inactive),
00143 0.F);
00144 }
00145 } else {
00146
00147 }
00148 return ret;
00149 } else {
00150
00151 std::vector<TrajectoryMeasurement> result;
00152 result.push_back( TrajectoryMeasurement( stateOnThisDet,
00153 InvalidTransientRecHit::build(&geomDet(), TrackingRecHit::inactive),
00154 0.F));
00155 return result;
00156 }
00157
00158 }
00159
00160 TkGluedMeasurementDet::RecHitContainer
00161 TkGluedMeasurementDet::projectOnGluedDet( const RecHitContainer& hits,
00162 const TrajectoryStateOnSurface& ts) const
00163 {
00164 if (hits.empty()) return hits;
00165 TrackingRecHitProjector<ProjectedRecHit2D> proj;
00166 RecHitContainer result;
00167 for ( RecHitContainer::const_iterator ihit = hits.begin(); ihit!=hits.end(); ihit++) {
00168 result.push_back( proj.project( **ihit, geomDet(), ts));
00169 }
00170 return result;
00171 }
00172
00173
00174 void TkGluedMeasurementDet::checkProjection(const TrajectoryStateOnSurface& ts,
00175 const RecHitContainer& monoHits,
00176 const RecHitContainer& stereoHits) const
00177 {
00178 for (RecHitContainer::const_iterator i=monoHits.begin(); i != monoHits.end(); ++i) {
00179 checkHitProjection( **i, ts, geomDet());
00180 }
00181 for (RecHitContainer::const_iterator i=stereoHits.begin(); i != stereoHits.end(); ++i) {
00182 checkHitProjection( **i, ts, geomDet());
00183 }
00184 }
00185
00186 void TkGluedMeasurementDet::checkHitProjection(const TransientTrackingRecHit& hit,
00187 const TrajectoryStateOnSurface& ts,
00188 const GeomDet& det) const
00189 {
00190 TrackingRecHitProjector<ProjectedRecHit2D> proj;
00191 TransientTrackingRecHit::RecHitPointer projectedHit = proj.project( hit, det, ts);
00192
00193 RecHitPropagator prop;
00194 TrajectoryStateOnSurface propState = prop.propagate( hit, det.surface(), ts);
00195
00196 if ((projectedHit->localPosition()-propState.localPosition()).mag() > 0.0001) {
00197 cout << "PROBLEM: projected and propagated hit positions differ by "
00198 << (projectedHit->localPosition()-propState.localPosition()).mag() << endl;
00199 }
00200
00201 LocalError le1 = projectedHit->localPositionError();
00202 LocalError le2 = propState.localError().positionError();
00203 double eps = 1.e-5;
00204 double cutoff = 1.e-4;
00205 double maxdiff = std::max( std::max( fabs(le1.xx() - le2.xx())/(cutoff+le1.xx()),
00206 fabs(le1.xy() - le2.xy())/(cutoff+fabs(le1.xy()))),
00207 fabs(le1.yy() - le2.yy())/(cutoff+le1.xx()));
00208 if (maxdiff > eps) {
00209 cout << "PROBLEM: projected and propagated hit errors differ by "
00210 << maxdiff << endl;
00211 }
00212
00213 }
00214
00215 bool
00216 TkGluedMeasurementDet::testStrips(const TrajectoryStateOnSurface& tsos,
00217 const BoundPlane &gluedPlane,
00218 const TkStripMeasurementDet &mdet) const {
00219
00220 const GeomDet &det = mdet.geomDet();
00221 const BoundPlane &stripPlane = det.surface();
00222
00223 LocalPoint glp = tsos.localPosition();
00224 LocalError err = tsos.localError().positionError();
00225
00226
00227
00228
00229
00230
00231 GlobalVector gdir = tsos.globalParameters().momentum();
00232
00233 LocalPoint slp = stripPlane.toLocal(tsos.globalPosition());
00234 LocalVector sld = stripPlane.toLocal(gdir);
00235
00236 double delta = stripPlane.localZ( tsos.globalPosition());
00237 LocalPoint pos = slp - sld * delta/sld.z();
00238
00239
00240
00241 LocalVector hitXAxis = stripPlane.toLocal( gluedPlane.toGlobal( LocalVector(1,0,0)));
00242 if (stripPlane.normalVector().dot( gluedPlane.normalVector()) < 0) {
00243
00244 err = LocalError( err.xx(), -err.xy(), err.yy());
00245 }
00246 LocalError rotatedError = err.rotate( hitXAxis.x(), hitXAxis.y());
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 const StripTopology &topo = mdet.specificGeomDet().specificTopology();
00261 float utraj = topo.measurementPosition(pos).x();
00262 float uerr = std::sqrt(topo.measurementError(pos,rotatedError).uu());
00263 return mdet.testStrips(utraj, uerr);
00264 }