CMS 3D CMS Logo

FastTrackerRecHitMatcher.cc
Go to the documentation of this file.
1 // system include files
2 #include <cfloat>
3 #include <memory>
4 
5 // framework stuff
11 
12 // fast tracker rechits
17 
18 // geometry stuff
25 
26 // sim stuff
29 
31 public:
33  ~FastTrackerRecHitMatcher() override { ; }
34  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
35 
36 private:
37  void produce(edm::Event&, const edm::EventSetup&) override;
38 
39  // ---------- typedefs -----------------------------
40  typedef std::pair<LocalPoint, LocalPoint> StripPosition;
41 
42  // ----------internal functions ---------------------------
43 
44  // create projected hit
45  std::unique_ptr<FastTrackerRecHit> projectOnly(const FastSingleTrackerRecHit* originalRH,
46  const GeomDet* monoDet,
47  const GluedGeomDet* gluedDet,
48  LocalVector& ldir) const;
49 
50  // create matched hit
51  std::unique_ptr<FastTrackerRecHit> match(const FastSingleTrackerRecHit* monoRH,
52  const FastSingleTrackerRecHit* stereoRH,
53  const GluedGeomDet* gluedDet,
54  LocalVector& trackdirection,
55  bool stereLayerFirst) const;
56 
58  const GluedGeomDet* glueddet,
59  const StripPosition& strip,
60  const LocalVector& trackdirection) const;
61 
63  if (!recHit->isSingle()) {
64  throw cms::Exception("FastTrackerRecHitMatcher")
65  << "all rechits in simHit2RecHitMap must be instances of FastSingleTrackerRecHit. recHit's rtti: "
66  << recHit->rtti() << std::endl;
67  }
68  return dynamic_cast<const FastSingleTrackerRecHit*>(recHit);
69  }
70 
71  // ----------member data ---------------------------
75 };
76 
78  : trackerGeometryESToken(esConsumes()) {
79  simHitsToken = consumes<edm::PSimHitContainer>(iConfig.getParameter<edm::InputTag>("simHits"));
81  consumes<FastTrackerRecHitRefCollection>(iConfig.getParameter<edm::InputTag>("simHit2RecHitMap"));
82 
83  produces<FastTrackerRecHitCollection>();
84  produces<FastTrackerRecHitRefCollection>("simHit2RecHitMap");
85 }
86 
88  // services
89  auto const& geometry = iSetup.getData(trackerGeometryESToken);
90 
91  // input
93  iEvent.getByToken(simHitsToken, simHits);
94 
97 
98  // output
99  auto output_recHits = std::make_unique<FastTrackerRecHitCollection>();
100  auto output_simHit2RecHitMap =
101  std::make_unique<FastTrackerRecHitRefCollection>(simHit2RecHitMap->size(), FastTrackerRecHitRef());
102  edm::RefProd<FastTrackerRecHitCollection> output_recHits_refProd =
103  iEvent.getRefBeforePut<FastTrackerRecHitCollection>();
104 
105  bool skipNext = false;
106  for (unsigned simHitCounter = 0; simHitCounter < simHits->size(); ++simHitCounter) {
107  // skip hit in case it was matched to previous one
108  if (skipNext) {
109  skipNext = false;
110  continue;
111  }
112  skipNext = false;
113 
114  // get simHit and associated recHit
115  const PSimHit& simHit = (*simHits)[simHitCounter];
116  const FastTrackerRecHitRef& recHitRef = (*simHit2RecHitMap)[simHitCounter];
117 
118  // skip simHits w/o associated recHit
119  if (recHitRef.isNull())
120  continue;
121 
122  // cast
123  const FastSingleTrackerRecHit* recHit = _cast2Single(recHitRef.get());
124 
125  // get subdetector id
126  DetId detid = recHit->geographicalId();
127  unsigned int subdet = detid.subdetId();
128 
129  // treat pixel hits
130  if (subdet <= 2) {
131  (*output_simHit2RecHitMap)[simHitCounter] = recHitRef;
132  }
133 
134  // treat strip hits
135  else {
136  StripSubdetector stripSubDetId(detid);
137 
138  // treat regular regular strip hits
139  if (!stripSubDetId.glued()) {
140  (*output_simHit2RecHitMap)[simHitCounter] = recHitRef;
141  }
142 
143  // treat strip hits on glued layers
144  else {
145  // Obtain direction of simtrack at simhit in local coordinates of glued module
146  // - direction of simtrack at simhit, in coordindates of the single module
147  LocalVector localSimTrackDir = simHit.localDirection();
148  // - transform to global coordinates
149  GlobalVector globalSimTrackDir = recHit->det()->surface().toGlobal(localSimTrackDir);
150  // - transform to local coordinates of glued module
151  const GluedGeomDet* gluedDet = (const GluedGeomDet*)geometry.idToDet(DetId(stripSubDetId.glued()));
152  LocalVector gluedLocalSimTrackDir = gluedDet->surface().toLocal(globalSimTrackDir);
153 
154  // check whether next hit is partner
155  const FastSingleTrackerRecHit* partnerRecHit = nullptr;
156  // - there must be a next hit
157  if (simHitCounter + 1 < simHits->size()) {
158  const FastTrackerRecHitRef& nextRecHitRef = (*simHit2RecHitMap)[simHitCounter + 1];
159  const PSimHit& nextSimHit = (*simHits)[simHitCounter + 1];
160  // - partner hit must not be null
161  // - simHit and partner simHit must belong to same simTrack
162  // - partner hit must be on the module glued to the module of the hit
163  if ((!nextRecHitRef.isNull()) && simHit.trackId() == nextSimHit.trackId() &&
164  StripSubdetector(nextRecHitRef->geographicalId()).partnerDetId() == detid.rawId()) {
165  partnerRecHit = _cast2Single(nextRecHitRef.get());
166  skipNext = true;
167  }
168  }
169 
170  std::unique_ptr<FastTrackerRecHit> newRecHit(nullptr);
171 
172  // if partner found: create a matched hit
173  if (partnerRecHit) {
174  newRecHit = match(stripSubDetId.stereo() ? partnerRecHit : recHit,
175  stripSubDetId.stereo() ? recHit : partnerRecHit,
176  gluedDet,
177  gluedLocalSimTrackDir,
178  stripSubDetId.stereo());
179  }
180  // else: create projected hit
181  else {
182  newRecHit = projectOnly(recHit, geometry.idToDet(detid), gluedDet, gluedLocalSimTrackDir);
183  }
184  output_recHits->push_back(std::move(newRecHit));
185  (*output_simHit2RecHitMap)[simHitCounter] =
186  FastTrackerRecHitRef(output_recHits_refProd, output_recHits->size() - 1);
187  }
188  }
189  }
190 
191  iEvent.put(std::move(output_recHits));
192  iEvent.put(std::move(output_simHit2RecHitMap), "simHit2RecHitMap");
193 }
194 
195 std::unique_ptr<FastTrackerRecHit> FastTrackerRecHitMatcher::match(const FastSingleTrackerRecHit* monoRH,
196  const FastSingleTrackerRecHit* stereoRH,
197  const GluedGeomDet* gluedDet,
198  LocalVector& trackdirection,
199  bool stereoHitFirst) const {
200  // stripdet = mono
201  // partnerstripdet = stereo
202  const GeomDetUnit* stripdet = gluedDet->monoDet();
203  const GeomDetUnit* partnerstripdet = gluedDet->stereoDet();
204  const StripTopology& topol = (const StripTopology&)stripdet->topology();
205 
207 
208  // position of the initial and final point of the strip (RPHI cluster) in local strip coordinates
209  MeasurementPoint RPHIpoint = topol.measurementPosition(monoRH->localPosition());
210  MeasurementPoint RPHIpointini = MeasurementPoint(RPHIpoint.x(), -0.5);
211  MeasurementPoint RPHIpointend = MeasurementPoint(RPHIpoint.x(), 0.5);
212 
213  // position of the initial and final point of the strip in local coordinates (mono det)
214  StripPosition stripmono = StripPosition(topol.localPosition(RPHIpointini), topol.localPosition(RPHIpointend));
215 
216  // in case of no track hypothesis assume a track from the origin through the center of the strip
217  if (trackdirection.mag2() < FLT_MIN) {
218  LocalPoint lcenterofstrip = monoRH->localPosition();
219  GlobalPoint gcenterofstrip = (stripdet->surface()).toGlobal(lcenterofstrip);
220  GlobalVector gtrackdirection = gcenterofstrip - GlobalPoint(0, 0, 0);
221  trackdirection = (gluedDet->surface()).toLocal(gtrackdirection);
222  }
223 
224  //project mono hit on glued det
225  StripPosition projectedstripmono = project(stripdet, gluedDet, stripmono, trackdirection);
226  const StripTopology& partnertopol = (const StripTopology&)partnerstripdet->topology();
227 
228  //error calculation (the part that depends on mono RH only)
229  LocalVector RPHIpositiononGluedendvector = projectedstripmono.second - projectedstripmono.first;
230  double c1 = sin(RPHIpositiononGluedendvector.phi());
231  double s1 = -cos(RPHIpositiononGluedendvector.phi());
232  MeasurementError errormonoRH = topol.measurementError(monoRH->localPosition(), monoRH->localPositionError());
233  double pitch = topol.localPitch(monoRH->localPosition());
234  double sigmap12 = errormonoRH.uu() * pitch * pitch;
235 
236  // position of the initial and final point of the strip (STEREO cluster)
237  MeasurementPoint STEREOpoint = partnertopol.measurementPosition(stereoRH->localPosition());
238 
239  MeasurementPoint STEREOpointini = MeasurementPoint(STEREOpoint.x(), -0.5);
240  MeasurementPoint STEREOpointend = MeasurementPoint(STEREOpoint.x(), 0.5);
241 
242  // position of the initial and final point of the strip in local coordinates (stereo det)
243  StripPosition stripstereo(partnertopol.localPosition(STEREOpointini), partnertopol.localPosition(STEREOpointend));
244 
245  //project stereo hit on glued det
246  StripPosition projectedstripstereo = project(partnerstripdet, gluedDet, stripstereo, trackdirection);
247 
248  //perform the matching
249  //(x2-x1)(y-y1)=(y2-y1)(x-x1)
251  AlgebraicVector2 c, solution;
252  m(0, 0) = -(projectedstripmono.second.y() - projectedstripmono.first.y());
253  m(0, 1) = (projectedstripmono.second.x() - projectedstripmono.first.x());
254  m(1, 0) = -(projectedstripstereo.second.y() - projectedstripstereo.first.y());
255  m(1, 1) = (projectedstripstereo.second.x() - projectedstripstereo.first.x());
256  c(0) = m(0, 1) * projectedstripmono.first.y() + m(0, 0) * projectedstripmono.first.x();
257  c(1) = m(1, 1) * projectedstripstereo.first.y() + m(1, 0) * projectedstripstereo.first.x();
258  m.Invert();
259  solution = m * c;
260  position = LocalPoint(solution(0), solution(1));
261 
262  //
263  // temporary fix by tommaso
264  //
265 
266  LocalError tempError(100, 0, 100);
267 
268  // calculate the error
269  LocalVector stereopositiononGluedendvector = projectedstripstereo.second - projectedstripstereo.first;
270  double c2 = sin(stereopositiononGluedendvector.phi());
271  double s2 = -cos(stereopositiononGluedendvector.phi());
272  MeasurementError errorstereoRH =
273  partnertopol.measurementError(stereoRH->localPosition(), stereoRH->localPositionError());
274  pitch = partnertopol.localPitch(stereoRH->localPosition());
275  double sigmap22 = errorstereoRH.uu() * pitch * pitch;
276  double diff = (c1 * s2 - c2 * s1);
277  double invdet2 = 1 / (diff * diff);
278  float xx = invdet2 * (sigmap12 * s2 * s2 + sigmap22 * s1 * s1);
279  float xy = -invdet2 * (sigmap12 * c2 * s2 + sigmap22 * c1 * s1);
280  float yy = invdet2 * (sigmap12 * c2 * c2 + sigmap22 * c1 * c1);
282 
283  //Added by DAO to make sure y positions are zero.
284  DetId det(monoRH->geographicalId());
285  if (det.subdetId() > 2) {
286  return std::make_unique<FastMatchedTrackerRecHit>(position, error, *gluedDet, *monoRH, *stereoRH, stereoHitFirst);
287 
288  }
289 
290  else {
291  throw cms::Exception("FastTrackerRecHitMatcher") << "Matched Pixel!?";
292  }
293 }
294 
296  const GluedGeomDet* glueddet,
297  const StripPosition& strip,
298  const LocalVector& trackdirection) const {
299  GlobalPoint globalpointini = (det->surface()).toGlobal(strip.first);
300  GlobalPoint globalpointend = (det->surface()).toGlobal(strip.second);
301 
302  // position of the initial and final point of the strip in glued local coordinates
303  LocalPoint positiononGluedini = (glueddet->surface()).toLocal(globalpointini);
304  LocalPoint positiononGluedend = (glueddet->surface()).toLocal(globalpointend);
305 
306  //correct the position with the track direction
307 
308  float scale = -positiononGluedini.z() / trackdirection.z();
309 
310  LocalPoint projpositiononGluedini = positiononGluedini + scale * trackdirection;
311  LocalPoint projpositiononGluedend = positiononGluedend + scale * trackdirection;
312 
313  return StripPosition(projpositiononGluedini, projpositiononGluedend);
314 }
315 
316 std::unique_ptr<FastTrackerRecHit> FastTrackerRecHitMatcher::projectOnly(const FastSingleTrackerRecHit* originalRH,
317  const GeomDet* monoDet,
318  const GluedGeomDet* gluedDet,
319  LocalVector& ldir) const {
320  LocalPoint position(originalRH->localPosition().x(), 0., 0.);
321  const BoundPlane& gluedPlane = gluedDet->surface();
322  const BoundPlane& hitPlane = monoDet->surface();
323 
324  double delta = gluedPlane.localZ(hitPlane.position());
325 
326  LocalPoint lhitPos = gluedPlane.toLocal(monoDet->surface().toGlobal(position));
327  LocalPoint projectedHitPos = lhitPos - ldir * delta / ldir.z();
328 
329  LocalVector hitXAxis = gluedPlane.toLocal(hitPlane.toGlobal(LocalVector(1, 0, 0)));
330  LocalError hitErr = originalRH->localPositionError();
331 
332  if (gluedPlane.normalVector().dot(hitPlane.normalVector()) < 0) {
333  // the two planes are inverted, and the correlation element must change sign
334  hitErr = LocalError(hitErr.xx(), -hitErr.xy(), hitErr.yy());
335  }
336  LocalError rotatedError = hitErr.rotate(hitXAxis.x(), hitXAxis.y());
337 
338  const GeomDetUnit* gluedMonoDet = gluedDet->monoDet();
339  const GeomDetUnit* gluedStereoDet = gluedDet->stereoDet();
340  int isMono = 0;
341  int isStereo = 0;
342 
343  if (monoDet->geographicalId() == gluedMonoDet->geographicalId())
344  isMono = 1;
345  if (monoDet->geographicalId() == gluedStereoDet->geographicalId())
346  isStereo = 1;
347  //Added by DAO to make sure y positions are zero and correct Mono or stereo Det is filled.
348 
349  if ((isMono && isStereo) || (!isMono && !isStereo))
350  throw cms::Exception("FastTrackerRecHitMatcher") << "Something wrong with DetIds.";
351  return std::make_unique<FastProjectedTrackerRecHit>(projectedHitPos, rotatedError, *gluedDet, *originalRH);
352 }
353 
354 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
356  //The following says we do not know what parameters are allowed so do no validation
357  // Please change this to state exactly what you do use, even if it is no parameters
359  desc.setUnknown();
360  descriptions.addDefault(desc);
361 }
362 
363 //define this as a plug-in
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
std::pair< LocalPoint, LocalPoint > StripPosition
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:30
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
LocalError rotate(float x, float y) const
Return a new LocalError, rotated by an angle defined by the direction (x,y)
Definition: LocalError.h:37
unsigned int stereo() const
stereo
T z() const
Definition: PV3DBase.h:61
void produce(edm::Event &, const edm::EventSetup &) override
virtual const Topology & topology() const
Definition: GeomDet.cc:67
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
unsigned int glued() const
glued
std::unique_ptr< FastTrackerRecHit > match(const FastSingleTrackerRecHit *monoRH, const FastSingleTrackerRecHit *stereoRH, const GluedGeomDet *gluedDet, LocalVector &trackdirection, bool stereLayerFirst) const
T x() const
Definition: PV2DBase.h:43
T mag2() const
Definition: PV3DBase.h:63
std::unique_ptr< FastTrackerRecHit > projectOnly(const FastSingleTrackerRecHit *originalRH, const GeomDet *monoDet, const GluedGeomDet *gluedDet, LocalVector &ldir) const
LocalPoint toLocal(const GlobalPoint &gp) const
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > trackerGeometryESToken
edm::Ref< FastTrackerRecHitCollection > FastTrackerRecHitRef
FastTrackerRecHitMatcher(const edm::ParameterSet &)
float yy() const
Definition: LocalError.h:24
T x() const
Definition: PV3DBase.h:59
virtual float localPitch(const LocalPoint &) const =0
T y() const
Definition: PV3DBase.h:60
Measurement2DPoint MeasurementPoint
Measurement points are two-dimensional by default.
int iEvent
Definition: GenABIO.cc:224
void addDefault(ParameterSetDescription const &psetDescription)
ROOT::Math::SVector< double, 2 > AlgebraicVector2
virtual MeasurementError measurementError(const LocalPoint &, const LocalError &) const =0
edm::EDGetTokenT< FastTrackerRecHitRefCollection > simHit2RecHitMapToken
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
edm::EDGetTokenT< edm::PSimHitContainer > simHitsToken
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
virtual MeasurementPoint measurementPosition(const LocalPoint &) const =0
const FastSingleTrackerRecHit * _cast2Single(const FastTrackerRecHit *recHit) const
unsigned int trackId() const
Definition: PSimHit.h:106
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:64
bool isNull() const
Checks for null.
Definition: Ref.h:235
LocalVector toLocal(const reco::Track::Vector &v, const Surface &s)
const GeomDetUnit * monoDet() const
Definition: GluedGeomDet.h:19
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:79
float xy() const
Definition: LocalError.h:23
LocalError localPositionError() const override
Definition: DetId.h:17
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
DetId geographicalId() const
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
const GeomDetUnit * stereoDet() const
Definition: GluedGeomDet.h:20
LocalPoint localPosition() const override
static int position[264][3]
Definition: ReadPGInfo.cc:289
ROOT::Math::SMatrix< double, 2, 2, ROOT::Math::MatRepStd< double, 2, 2 > > AlgebraicMatrix22
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
virtual LocalPoint localPosition(float strip) const =0
StripPosition project(const GeomDetUnit *det, const GluedGeomDet *glueddet, const StripPosition &strip, const LocalVector &trackdirection) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
float xx() const
Definition: LocalError.h:22
def move(src, dest)
Definition: eostools.py:511