CMS 3D CMS Logo

TkGluedMeasurementDet.cc

Go to the documentation of this file.
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   //------ WARNING: here ts is used as it is on the mono/stereo surface.
00043   //-----           A further propagation is necessary.
00044   //-----           To limit the problem, the SimpleCPE should be used
00045   RecHitContainer monoHits = theMonoDet->recHits( ts);
00046   RecHitContainer stereoHits = theStereoDet->recHits( ts);
00047 
00048   //edm::LogWarning("TkGluedMeasurementDet::recHits") << "Query-for-detid-" << theGeomDet->geographicalId().rawId();
00049 
00050   //checkProjection(ts, monoHits, stereoHits);
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     // convert stereo hits to type expected by matcher
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         //dynamic_cast<const SiStripRecHit2D*>(tkhit);
00066         //if (verySpecificStereoHit == 0) {
00067         //   throw MeasurementDetException("TkGluedMeasurementDet ERROR: stereoHit is not SiStripRecHit2D");
00068         //}
00069         vsStereoHits.push_back( verySpecificStereoHit );
00070     }
00071 
00072     // auto_ptr in the loop will take care of passing ownership to Transient hit...
00073     std::vector<SiStripMatchedRecHit2D*> tmp;
00074     tmp.reserve(vsStereoHits.size());
00075     // convert mono hits to type expected by matcher
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           //<<<< if projecting 1 rec hit does not produce more than one rec hit ...
00095           //<<<< then the following is "suboptimal"
00096           //  RecHitContainer monoUnmatchedHit;     //better kept here, it is often never used at all in one call to recHits
00097           //  monoUnmatchedHit.push_back(*monoHit);
00098           //  RecHitContainer projectedMonoUnmatchedHit = projectOnGluedDet(monoUnmatchedHit, ts);
00099           //  result.insert(result.end(), projectedMonoUnmatchedHit.begin(), projectedMonoUnmatchedHit.end());
00100           //<<<< and so we use 
00101           TrackingRecHitProjector<ProjectedRecHit2D> proj;
00102           result.push_back( proj.project( **monoHit, geomDet(), ts));
00103             //<<<< end of change
00104         }
00105     } // loop on mono hit
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           //LogDebug("TkStripMeasurementDet") << "No hit found on TkGlued. Testing strips...  ";
00123           const BoundPlane &gluedPlane = geomDet().surface();
00124           if (  // sorry for the big IF, but I want to exploit short-circuiting of logic
00125                 (theMonoDet->isActive() && 
00126                     (theMonoDet->hasAllGoodChannels() || 
00127                        testStrips(stateOnThisDet,gluedPlane,*theMonoDet)
00128                     )
00129                 ) /*Mono OK*/ || 
00130                 (theStereoDet->isActive() && 
00131                     (theStereoDet->hasAllGoodChannels() || 
00132                        testStrips(stateOnThisDet,gluedPlane,*theStereoDet)
00133                     )
00134                 ) /*Stereo OK*/ 
00135               ) {
00136             //LogDebug("TkStripMeasurementDet") << " DetID " << geomDet().geographicalId().rawId() << " (glued) active but no hit found: missing";
00137             // no problem, at least one detector has good strips
00138           } else {
00139             //LogDebug("TkStripMeasurementDet") << "Tested strips on TkGlued, returning 'inactive' invalid hit";
00140             //LogDebug("TkStripMeasurementDet") << " DetID " << geomDet().geographicalId().rawId() << " (glued) globally active, but no hit found and faulty components: inactive";
00141             ret[0] = TrajectoryMeasurement(stateOnThisDet, 
00142                          InvalidTransientRecHit::build(&geomDet(), TrackingRecHit::inactive), 
00143                          0.F);
00144           }
00145       } else {
00146         //LogDebug("TkStripMeasurementDet") << " DetID " << geomDet().geographicalId().rawId() << " (glued) active, valid hit found, all ok";
00147       }
00148       return ret;
00149    } else {
00150      //     LogDebug("TkStripMeasurementDet") << " DetID " << geomDet().geographicalId().rawId() << " (glued) fully inactive";
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; // if element below cutoff, use absolute instead of relative accuracy
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    // from TrackingRecHitProjector
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    /*LogDebug("TkStripMeasurementDet") << 
00226       "Testing local pos glued: " << glp << 
00227       " local err glued: " << tsos.localError().positionError() << 
00228       " in? " << gluedPlane.bounds().inside(glp) <<
00229       " in(3s)? " << gluedPlane.bounds().inside(glp, err, 3.0f);*/
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    // now the error
00241    LocalVector hitXAxis = stripPlane.toLocal( gluedPlane.toGlobal( LocalVector(1,0,0)));
00242    if (stripPlane.normalVector().dot( gluedPlane.normalVector()) < 0) {
00243        // the two planes are inverted, and the correlation element must change sign
00244        err = LocalError( err.xx(), -err.xy(), err.yy());
00245    }
00246    LocalError rotatedError = err.rotate( hitXAxis.x(), hitXAxis.y());
00247 
00248    /* // This is probably meaningless 
00249    LogDebug("TkStripMeasurementDet") << 
00250       "Testing local pos on strip (SLP): " << slp << 
00251       " in? :" << stripPlane.bounds().inside(slp) <<
00252       " in(3s)? :" << stripPlane.bounds().inside(slp, rotatedError, 3.0f);
00253    // but it helps to test bugs in the formula for POS */
00254    /*LogDebug("TkStripMeasurementDet") << 
00255       "Testing local pos strip: " << pos << 
00256       " in? " << stripPlane.bounds().inside(pos) <<
00257       " in(3s)? " << stripPlane.bounds().inside(pos, rotatedError, 3.0f);*/
00258 
00259    // now we need to convert to MeasurementFrame
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 } 

Generated on Tue Jun 9 17:45:29 2009 for CMSSW by  doxygen 1.5.4