CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TkGluedMeasurementDet.cc
Go to the documentation of this file.
10 #include "RecHitPropagator.h"
12 
14 #include <iostream>
15 
16 #include <typeinfo>
17 
18 // #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
20 
21 using namespace std;
22 
23 TkGluedMeasurementDet::TkGluedMeasurementDet( const GluedGeomDet* gdet,
24  const SiStripRecHitMatcher* matcher,
25  const StripClusterParameterEstimator* cpe) :
26  MeasurementDet(gdet),
27  theMatcher(matcher), theCPE(cpe),
28  theMonoDet(nullptr), theStereoDet(nullptr)
29 {}
30 
32  const MeasurementDet* stereoDet) {
33  theMonoDet = dynamic_cast<const TkStripMeasurementDet *>(monoDet);
34  theStereoDet = dynamic_cast<const TkStripMeasurementDet *>(stereoDet);
35 
36  if ((theMonoDet == 0) || (theStereoDet == 0)) {
37  throw MeasurementDetException("TkGluedMeasurementDet ERROR: Trying to glue a det which is not a TkStripMeasurementDet");
38  }
39 }
40 
41 TkGluedMeasurementDet::RecHitContainer
42 TkGluedMeasurementDet::recHits( const TrajectoryStateOnSurface& ts) const
43 {
44 
45  RecHitContainer result;
46  HitCollectorForRecHits collector( &fastGeomDet(), theMatcher, theCPE, result );
47  collectRecHits(ts, collector);
48  return result;
49 }
50 
51 struct take_address { template<typename T> const T * operator()(const T &val) const { return &val; } };
52 
53 #ifdef DOUBLE_MATCH
54 template<typename Collector>
55 void
56 TkGluedMeasurementDet::collectRecHits( const TrajectoryStateOnSurface& ts, Collector & collector) const
57 {
58  doubleMatch(ts,collector);
59 }
60 #else
61 template<typename Collector>
62 void
63 TkGluedMeasurementDet::collectRecHits( const TrajectoryStateOnSurface& ts, Collector & collector) const
64 {
65  //------ WARNING: here ts is used as it is on the mono/stereo surface.
66  //----- A further propagation is necessary.
67  //----- To limit the problem, the SimpleCPE should be used
68  RecHitContainer monoHits = theMonoDet->recHits( ts);
69  GlobalVector glbDir = (ts.isValid() ? ts.globalParameters().momentum() : position()-GlobalPoint(0,0,0));
70 
71  //edm::LogWarning("TkGluedMeasurementDet::recHits") << "Query-for-detid-" << theGeomDet->geographicalId().rawId();
72 
73  //checkProjection(ts, monoHits, stereoHits);
74 
75  if (monoHits.empty()) {
76  // make stereo TTRHs and project them
77  projectOnGluedDet( collector, theStereoDet->recHits(ts), glbDir);
78  } else {
79  // collect simple stereo hits
80  static std::vector<SiStripRecHit2D> simpleSteroHitsByValue;
81  simpleSteroHitsByValue.clear();
82  theStereoDet->simpleRecHits(ts, simpleSteroHitsByValue);
83 
84  if (simpleSteroHitsByValue.empty()) {
85  projectOnGluedDet( collector, monoHits, glbDir);
86  } else {
87 
88  LocalVector tkDir = (ts.isValid() ? ts.localDirection() : surface().toLocal( position()-GlobalPoint(0,0,0)));
90  vsStereoHits.resize(simpleSteroHitsByValue.size());
91  std::transform(simpleSteroHitsByValue.begin(), simpleSteroHitsByValue.end(), vsStereoHits.begin(), take_address());
92 
93  // convert mono hits to type expected by matcher
94  for (RecHitContainer::const_iterator monoHit = monoHits.begin();
95  monoHit != monoHits.end(); ++monoHit) {
96  const TrackingRecHit* tkhit = (**monoHit).hit();
97  const SiStripRecHit2D* verySpecificMonoHit = reinterpret_cast<const SiStripRecHit2D*>(tkhit);
98  theMatcher->match( verySpecificMonoHit, vsStereoHits.begin(), vsStereoHits.end(),
99  collector.collector(), &specificGeomDet(), tkDir);
100 
101  if (collector.hasNewMatchedHits()) {
102  collector.clearNewMatchedHitsFlag();
103  } else {
104  collector.addProjected( **monoHit, glbDir );
105  }
106  } // loop on mono hit
107  }
108  //GIO// std::cerr << "TkGluedMeasurementDet hits " << monoHits.size() << "/" << stereoHits.size() << " => " << result.size() << std::endl;
109  }
110 }
111 #endif
112 
113 #include<cstdint>
114 #include<cstdio>
115 namespace {
116  struct Stat {
117  double totCall=0;
118  double totMono=0;
119  double totStereo=0;
120  double totComb=0;
121  double totMatched=0;
122  double filtMono=0;
123  double filtStereo=0;
124  double filtComb=0;
125  double matchT=0;
126  double matchF=0;
127  double singleF=0;
128  double zeroM=0;
129  double zeroS=0;
130 
131  void match(uint64_t t) {
132  if(t!=0) ++matchT;
133  totMatched+=t;
134  }
135  void operator()(uint64_t m,uint64_t s, uint64_t fm, uint64_t fs) {
136  ++totCall;
137  totMono+=m;
138  totStereo+=s;
139  totComb += m*s;
140  filtMono+=fm;
141  filtStereo+=fs;
142  filtComb += fm*fs;
143  if(fm==0) ++zeroM;
144  if(fs==0) ++zeroS;
145  if(fm!=0&&fs!=0) ++matchF;
146  if(fm!=0||fs!=0) ++singleF;
147  }
148  ~Stat() {
149  if ( totCall>0)
150  printf("Matches:%d/%d/%d/%d/%d/%d : %f/%f/%f/%f/%f/%f/%f\n",
151  int(totCall),int(matchF),int(singleF-matchF),int(matchT),int(zeroM),int(zeroS),
152  totMono/totCall,totStereo/totCall,totComb/totCall,totMatched/matchT,
153  filtMono/totCall,filtStereo/totCall,filtComb/matchF);
154  }
155  };
156 
157  Stat stat;
158 }
159 
160 
161 bool TkGluedMeasurementDet::measurements( const TrajectoryStateOnSurface& stateOnThisDet,
162  const MeasurementEstimator& est,
163  TempMeasurements & result) const {
164 
165  if unlikely((!theMonoDet->isActive()) && (!theStereoDet->isActive())) {
166  // LogDebug("TkStripMeasurementDet") << " DetID " << geomDet().geographicalId().rawId() << " (glued) fully inactive";
167  result.add (InvalidTransientRecHit::build(&fastGeomDet(), TrackingRecHit::inactive),0.F);
168  return true;
169  }
170 
171  auto oldSize = result.size();
172 
173  HitCollectorForFastMeasurements collector( &fastGeomDet(), theMatcher, theCPE, stateOnThisDet, est, result);
174  collectRecHits(stateOnThisDet, collector);
175 
176 
177  if (result.size()>oldSize) return true;
178 
179  //LogDebug("TkStripMeasurementDet") << "No hit found on TkGlued. Testing strips... ";
180  const BoundPlane &gluedPlane = geomDet().surface();
181  if ( // sorry for the big IF, but I want to exploit short-circuiting of logic
182  stateOnThisDet.hasError() && ( /* do this only if the state has uncertainties, otherwise it will throw
183  (states without uncertainties are passed to this code from seeding */
184  (theMonoDet->isActive() &&
185  (theMonoDet->hasAllGoodChannels() ||
186  testStrips(stateOnThisDet,gluedPlane,*theMonoDet)
187  )
188  ) /*Mono OK*/ ||
189  (theStereoDet->isActive() &&
190  (theStereoDet->hasAllGoodChannels() ||
191  testStrips(stateOnThisDet,gluedPlane,*theStereoDet)
192  )
193  ) /*Stereo OK*/
194  ) /* State has errors */
195  ) {
196  result.add(InvalidTransientRecHit::build(&fastGeomDet(),TrackingRecHit::missing), 0.F);
197  return false;
198  }
199  result.add(InvalidTransientRecHit::build(&fastGeomDet(), TrackingRecHit::inactive), 0.F);
200  return true;
201 
202 }
203 
204 TkGluedMeasurementDet::RecHitContainer
205 TkGluedMeasurementDet::projectOnGluedDet( const RecHitContainer& hits,
206  const TrajectoryStateOnSurface& ts) const
207 {
208  if (hits.empty()) return hits;
210  RecHitContainer result;
211  for ( RecHitContainer::const_iterator ihit = hits.begin(); ihit!=hits.end(); ihit++) {
212  result.push_back( proj.project( **ihit, fastGeomDet(), ts));
213  }
214  return result;
215 }
216 
217 template<typename Collector>
218 void
219 TkGluedMeasurementDet::projectOnGluedDet( Collector& collector,
220  const RecHitContainer& hits,
221  const GlobalVector & gdir ) const
222 {
223  for ( RecHitContainer::const_iterator ihit = hits.begin(); ihit!=hits.end(); ihit++) {
224  collector.addProjected( **ihit, gdir );
225  }
226 }
227 
228 void TkGluedMeasurementDet::checkProjection(const TrajectoryStateOnSurface& ts,
229  const RecHitContainer& monoHits,
230  const RecHitContainer& stereoHits) const
231 {
232  for (RecHitContainer::const_iterator i=monoHits.begin(); i != monoHits.end(); ++i) {
233  checkHitProjection( **i, ts, fastGeomDet());
234  }
235  for (RecHitContainer::const_iterator i=stereoHits.begin(); i != stereoHits.end(); ++i) {
236  checkHitProjection( **i, ts, fastGeomDet());
237  }
238 }
239 
240 void TkGluedMeasurementDet::checkHitProjection(const TransientTrackingRecHit& hit,
241  const TrajectoryStateOnSurface& ts,
242  const GeomDet& det) const
243 {
245  TransientTrackingRecHit::RecHitPointer projectedHit = proj.project( hit, det, ts);
246 
247  RecHitPropagator prop;
248  TrajectoryStateOnSurface propState = prop.propagate( hit, det.surface(), ts);
249 
250  if ((projectedHit->localPosition()-propState.localPosition()).mag() > 0.0001) {
251  cout << "PROBLEM: projected and propagated hit positions differ by "
252  << (projectedHit->localPosition()-propState.localPosition()).mag() << endl;
253  }
254 
255  LocalError le1 = projectedHit->localPositionError();
256  LocalError le2 = propState.localError().positionError();
257  double eps = 1.e-5;
258  double cutoff = 1.e-4; // if element below cutoff, use absolute instead of relative accuracy
259  double maxdiff = std::max( std::max( fabs(le1.xx() - le2.xx())/(cutoff+le1.xx()),
260  fabs(le1.xy() - le2.xy())/(cutoff+fabs(le1.xy()))),
261  fabs(le1.yy() - le2.yy())/(cutoff+le1.xx()));
262  if (maxdiff > eps) {
263  cout << "PROBLEM: projected and propagated hit errors differ by "
264  << maxdiff << endl;
265  }
266 
267 }
268 
269 bool
270 TkGluedMeasurementDet::testStrips(const TrajectoryStateOnSurface& tsos,
271  const BoundPlane &gluedPlane,
272  const TkStripMeasurementDet &mdet) const {
273  // from TrackingRecHitProjector
274  const GeomDet &det = mdet.fastGeomDet();
275  const BoundPlane &stripPlane = det.surface();
276 
277  //LocalPoint glp = tsos.localPosition();
278  LocalError err = tsos.localError().positionError();
279  /*LogDebug("TkStripMeasurementDet") <<
280  "Testing local pos glued: " << glp <<
281  " local err glued: " << tsos.localError().positionError() <<
282  " in? " << gluedPlane.bounds().inside(glp) <<
283  " in(3s)? " << gluedPlane.bounds().inside(glp, err, 3.0f);*/
284 
285  GlobalVector gdir = tsos.globalParameters().momentum();
286 
287  LocalPoint slp = stripPlane.toLocal(tsos.globalPosition());
288  LocalVector sld = stripPlane.toLocal(gdir);
289 
290  double delta = stripPlane.localZ( tsos.globalPosition());
291  LocalPoint pos = slp - sld * delta/sld.z();
292 
293 
294  // now the error
295  LocalVector hitXAxis = stripPlane.toLocal( gluedPlane.toGlobal( LocalVector(1,0,0)));
296  if (stripPlane.normalVector().dot( gluedPlane.normalVector()) < 0) {
297  // the two planes are inverted, and the correlation element must change sign
298  err = LocalError( err.xx(), -err.xy(), err.yy());
299  }
300  LocalError rotatedError = err.rotate( hitXAxis.x(), hitXAxis.y());
301 
302  /* // This is probably meaningless
303  LogDebug("TkStripMeasurementDet") <<
304  "Testing local pos on strip (SLP): " << slp <<
305  " in? :" << stripPlane.bounds().inside(slp) <<
306  " in(3s)? :" << stripPlane.bounds().inside(slp, rotatedError, 3.0f);
307  // but it helps to test bugs in the formula for POS */
308  /*LogDebug("TkStripMeasurementDet") <<
309  "Testing local pos strip: " << pos <<
310  " in? " << stripPlane.bounds().inside(pos) <<
311  " in(3s)? " << stripPlane.bounds().inside(pos, rotatedError, 3.0f);*/
312 
313  // now we need to convert to MeasurementFrame
314  const StripTopology &topo = mdet.specificGeomDet().specificTopology();
315  float utraj = topo.measurementPosition(pos).x();
316  float uerr = std::sqrt(topo.measurementError(pos,rotatedError).uu());
317  return mdet.testStrips(utraj, uerr);
318 }
319 
320 #include<boost/bind.hpp>
321 TkGluedMeasurementDet::HitCollectorForRecHits::HitCollectorForRecHits(const GeomDet * geomDet,
322  const SiStripRecHitMatcher * matcher, const StripClusterParameterEstimator* cpe,
323  RecHitContainer & target) :
324  geomDet_(geomDet), matcher_(matcher), cpe_(cpe),target_(target),
325  collector_(boost::bind(&HitCollectorForRecHits::add,boost::ref(*this),_1)),
326  hasNewHits_(false)
327 {
328 }
329 
330 void
331 TkGluedMeasurementDet::HitCollectorForRecHits::addProjected(const TransientTrackingRecHit& hit,
332  const GlobalVector & gdir)
333 {
335  target_.push_back( proj.project( hit, *geomDet_, gdir));
336 }
337 
338 TkGluedMeasurementDet::HitCollectorForFastMeasurements::HitCollectorForFastMeasurements
339 (const GeomDet * geomDet,
340  const SiStripRecHitMatcher * matcher, const StripClusterParameterEstimator* cpe,
341  const TrajectoryStateOnSurface& stateOnThisDet,
342  const MeasurementEstimator& est,
343  TempMeasurements & target) :
344  geomDet_(geomDet), matcher_(matcher), cpe_(cpe),stateOnThisDet_(stateOnThisDet), est_(est), target_(target),
345  collector_(boost::bind(&HitCollectorForFastMeasurements::add,boost::ref(*this),_1)),
346  hasNewHits_(false)
347 {
348 }
349 
350 void
351 TkGluedMeasurementDet::HitCollectorForFastMeasurements::add(SiStripMatchedRecHit2D const& hit2d)
352 {
353  static LocalCache<TSiStripMatchedRecHit> lcache; // in case of pool allocator it will be cleared centrally
354  std::auto_ptr<TSiStripMatchedRecHit> & cache = lcache.ptr;
355  TSiStripMatchedRecHit::buildInPlace( cache, geomDet_, &hit2d, matcher_, cpe_ );
356  std::pair<bool,double> diffEst = est_.estimate( stateOnThisDet_, *cache);
357  if ( diffEst.first) {
358  cache->clonePersistentHit(); // clone and take ownership of the persistent 2D hit
359  target_.add(RecHitPointer(cache.release()),
360  diffEst.second);
361  } else {
362  cache->clearPersistentHit(); // drop ownership
363  }
364  hasNewHits_ = true; //FIXME: see also what happens moving this within testAndPush
365 }
366 
367 void
368 TkGluedMeasurementDet::HitCollectorForFastMeasurements::addProjected(const TransientTrackingRecHit& hit,
369  const GlobalVector & gdir)
370 {
371  // here we're ok with some extra casual new's and delete's
373  RecHitPointer && phit = proj.project( hit, *geomDet_, gdir );
374  std::pair<bool,double> diffEst = est_.estimate( stateOnThisDet_, *phit);
375  if ( diffEst.first) {
376  target_.add(phit, diffEst.second);
377  }
378 
379 }
380 
381 
382 
383 #ifdef DOUBLE_MATCH
384 #include "doubleMatch.icc"
385 #endif
dbl * delta
Definition: mlp_gen.cc:36
int i
Definition: DBlmapReader.cc:9
float xx() const
Definition: LocalError.h:24
TrajectoryStateOnSurface propagate(const TransientTrackingRecHit &hit, const Plane &plane, const TrajectoryStateOnSurface &ts) const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
LocalVector localDirection() const
#define nullptr
int init
Definition: HydjetWrapper.h:63
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
T y() const
Definition: PV3DBase.h:63
GlobalPoint globalPosition() const
void add(const std::vector< const T * > &source, std::vector< const T * > &dest)
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
LocalError positionError() const
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
RecHitPointer project(const TransientTrackingRecHit &hit, const GeomDet &det, const TrajectoryStateOnSurface &ts) const
#define unlikely(x)
Definition: Likely.h:21
float xy() const
Definition: LocalError.h:25
virtual MeasurementError measurementError(const LocalPoint &, const LocalError &) const =0
float yy() const
Definition: LocalError.h:26
const T & max(const T &a, const T &b)
T sqrt(T t)
Definition: SSEVec.h:48
T z() const
Definition: PV3DBase.h:64
tuple result
Definition: query.py:137
float uu() const
virtual MeasurementPoint measurementPosition(const LocalPoint &) const =0
const LocalTrajectoryError & localError() const
const T * operator()(const T &val) const
unsigned long long uint64_t
Definition: Time.h:15
const GlobalTrajectoryParameters & globalParameters() const
std::vector< const SiStripRecHit2D * > SimpleHitCollection
tuple cout
Definition: gather_cfg.py:121
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:6
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
LocalError rotate(float x, float y) const
Return a new LocalError, rotated by an angle defined by the direction (x,y)
Definition: LocalError.h:39
T x() const
Definition: PV2DBase.h:45
long double T
T x() const
Definition: PV3DBase.h:62
std::auto_ptr< T > ptr