CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FastPixelHitMatcher.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: EgammaElectronAlgos
4 // Class: FastPixelHitMatcher
5 //
13 //
14 // Original Author: Patrick Janot
15 //
16 //
17 
26 
29 
30 //#define FAMOS_DEBUG
31 
32 FastPixelHitMatcher::FastPixelHitMatcher(float ephi1min, float ephi1max,
33  float pphi1min, float pphi1max,
34  float phi2min, float phi2max,
35  float z2minB, float z2maxB,
36  float r2minF, float r2maxF,
37  float rMinI, float rMaxI,
38  bool searchInTIDTEC) :
39  ephi1min(ephi1min), ephi1max(ephi1max),
40  pphi1min(pphi1min), pphi1max(pphi1max),
41  phi2min(phi2min), phi2max(phi2max),
42  z2minB(z2minB), z2maxB(z2maxB),
43  r2minF(r2minF), r2maxF(r2maxF),
44  rMinI(rMinI), rMaxI(rMaxI),
45  searchInTIDTEC(searchInTIDTEC),
46  theTrackerGeometry(0),
47  theMagneticField(0),
48  theGeomSearchTracker(0),
49  _theGeometry(0),
50  thePixelLayers(50,static_cast<TrackerLayer*>(0)),
51  vertex(0.) {}
52 
54 
55 void
57  const TrackerGeometry* aTrackerGeometry,
58  const GeometricSearchTracker* geomSearchTracker,
59  const TrackerInteractionGeometry* interactionGeometry) {
60 
61  // initialize the tracker geometry and the magnetic field map
62  theTrackerGeometry = aTrackerGeometry;
63  //theMagneticField = aMagField;
64  theGeomSearchTracker = geomSearchTracker;
65  _theGeometry = interactionGeometry;
66  theFieldMap = aFieldMap;
67 
68  // Initialize (if not already done) the simplified magnetic field geometry
69  // MagneticFieldMap::instance( theMagneticField, _theGeometry );
70 
71  // The pixel layers in the simplified geometry
72  unsigned layer = 1;
73  std::list<TrackerLayer>::const_iterator cyliter = _theGeometry->cylinderBegin();
74  for ( ; cyliter != _theGeometry->cylinderEnd() ; ++cyliter ) {
75  if ( layer != cyliter->layerNumber() ) continue;
76  thePixelLayers[layer++] = &(*cyliter);
77  }
78 
79 }
80 
81 std::vector< std::pair<FastPixelHitMatcher::ConstRecHitPointer,
84  const GlobalPoint& theVertex,
85  float energy,
86  std::vector<TrackerRecHit>& theHits) {
87 
88  std::vector< std::pair<FastPixelHitMatcher::ConstRecHitPointer,
89  FastPixelHitMatcher::ConstRecHitPointer> > result;
90 #ifdef FAMOS_DEBUG
91  std::cout << "[FastPixelHitMatcher::compatibleHits] entering .. " << std::endl;
92 #endif
93 
94  double zCluster = thePos.z();
95  double rCluster = thePos.perp();
96 
97  // The cluster inferred energy-momentum
98  double theLength = thePos.mag();
99  XYZTLorentzVector theMom(thePos.x(), thePos.y(), thePos.z(), theLength);
100  theMom *= energy / theLength;
101  XYZTLorentzVector theVert(thePos.x(),thePos.y(),thePos.z(),0.);
102  XYZTLorentzVector theNominalVertex(theVertex.x(), theVertex.y(), theVertex.z(), 0.);
103 
104  // The corresponding RawParticles (to be propagated for e- and e+
105  ParticlePropagator myElec(theMom,theVert,-1.,theFieldMap);
106  ParticlePropagator myPosi(theMom,theVert,+1.,theFieldMap);
107 #ifdef FAMOS_DEBUG
108  std::cout << "elec/posi before propagation " << std::endl << myElec << std::endl << myPosi << std::endl;
109 #endif
110 
111  // Propagate the e- and the e+ hypothesis to the nominal vertex
112  // by modifying the pT direction in an appropriate manner.
113  myElec.propagateToNominalVertex(theNominalVertex);
114  myPosi.propagateToNominalVertex(theNominalVertex);
115 #ifdef FAMOS_DEBUG
116  std::cout << "elec/posi after propagation " << std::endl << myElec << std::endl << myPosi << std::endl;
117 #endif
118 
119  // Look for an appropriate see in the pixel detector
120  bool thereIsASeed = false;
121  unsigned nHits = theHits.size();
122 
123  for ( unsigned firstHit=0; firstHit<nHits-1; ++firstHit ) {
124  for ( unsigned secondHit=firstHit+1; secondHit<nHits; ++secondHit ) {
125 
126  // Is there a seed associated to this pair of Pixel hits?
127  thereIsASeed = isASeed(myElec,myPosi,theVertex,
128  rCluster,zCluster,
129  theHits[firstHit],
130  theHits[secondHit]);
131 
132 #ifdef FAMOS_DEBUG
133  std::cout << "Is there a seed with hits " << firstHit << " & "<< secondHit << "? " << thereIsASeed << std::endl;
134 #endif
135  if ( !thereIsASeed ) continue;
136 
137  ConstRecHitPointer theFirstHit =
138  GenericTransientTrackingRecHit::build(theHits[firstHit].geomDet(),
139  theHits[firstHit].hit());
140  ConstRecHitPointer theSecondHit =
141  GenericTransientTrackingRecHit::build(theHits[secondHit].geomDet(),
142  theHits[secondHit].hit());
143  result.push_back(std::pair<
144  FastPixelHitMatcher::ConstRecHitPointer,
145  FastPixelHitMatcher::ConstRecHitPointer>(theFirstHit,theSecondHit));
146 
147  }
148  }
149 
150  return result;
151 }
152 
154  const ParticlePropagator& myPosi,
155  const GlobalPoint& theVertex,
156  double rCluster,
157  double zCluster,
158  const TrackerRecHit& hit1,
159  const TrackerRecHit& hit2) {
160 
161  // Check that the two hits are not on the same layer
162  if ( hit2.isOnTheSameLayer(hit1) ) return false;
163 #ifdef FAMOS_DEBUG
164  std::cout << "isASeed: The two hits are not on the same layer - OK " << std::endl;
165 #endif
166 
167  // Check that the first hit is on PXB or PXD
168  if ( hit1.subDetId() > 2 ) return false;
169 #ifdef FAMOS_DEBUG
170  std::cout << "isASeed: The first hits is on the pixel detector " << std::endl;
171 #endif
172 
173  // Impose the track to originate from zVertex = 0. and check the
174  // compatibility with the first hit (beam spot constraint)
175  GlobalPoint firstHit = hit1.globalPosition();
176  bool rzok = checkRZCompatibility(zCluster, rCluster, 0., z1min, z1max, firstHit, hit1.subDetId()>1);
177 #ifdef FAMOS_DEBUG
178  std::cout << "isASeed: rzok (1) = " << rzok << std::endl;
179 #endif
180  if ( !rzok ) return false;
181 
182  // Refine the Z vertex by imposing the track to pass through the first RecHit,
183  // and check the compatibility with the second rechit
184  GlobalPoint secondHit = hit2.globalPosition();
185  rzok = false;
186 
187  // The orgin Z vertex for thet track passing through the first rechit
188  vertex = zVertex(zCluster, rCluster, firstHit);
189 
190  // Compute R (forward) or Z (barrel) predicted for the second hit and check compatibility
191  if ( hit2.subDetId() == 1 ) {
192  rzok = checkRZCompatibility(zCluster, rCluster, vertex, z2minB, z2maxB, secondHit, false);
193  } else if ( hit2.subDetId() == 2 ) {
194  rzok = checkRZCompatibility(zCluster, rCluster, vertex, r2minF, r2maxF, secondHit, true);
195  } else {
196  rzok = checkRZCompatibility(zCluster, rCluster, vertex, rMinI, rMaxI, secondHit, true);
197  }
198 #ifdef FAMOS_DEBUG
199  std::cout << "isASeed: rzok (2) = " << rzok << std::endl;
200 #endif
201  if ( !rzok ) return false;
202 
203  // Propagate the inferred electron (positron) to the first layer,
204  // check the compatibility with the first hit, and propagate back
205  // to the nominal vertex with the hit constraint
206  ParticlePropagator elec(myElec);
207  ParticlePropagator posi(myPosi);
208 #ifdef FAMOS_DEBUG
209  std::cout << "isASeed: elec1 to be propagated to first layer" << std::endl;
210 #endif
211  bool elec1 = propagateToLayer(elec,theVertex,firstHit,
213 #ifdef FAMOS_DEBUG
214  std::cout << "isASeed: posi1 to be propagated to first layer" << std::endl;
215 #endif
216  bool posi1 = propagateToLayer(posi,theVertex,firstHit,
218 
219 #ifdef FAMOS_DEBUG
220  std::cout << "isASeed: elec1 / posi1 " << elec1 << " " << posi1 << std::endl;
221 #endif
222  // Neither the electron not the positron hypothesis work...
223  if ( !elec1 && !posi1 ) return false;
224 
225  // Otherwise, propagate to the second layer, check the compatibility
226  // with the second hit and propagate back to the nominal vertex with
227  // the hit constraint
228 #ifdef FAMOS_DEBUG
229  std::cout << "isASeed: elec2 to be propagated to second layer" << std::endl;
230 #endif
231  bool elec2 = elec1 && propagateToLayer(elec,theVertex,secondHit,
233 
234 #ifdef FAMOS_DEBUG
235  std::cout << "isASeed: posi2 to be propagated to second layer" << std::endl;
236 #endif
237  bool posi2 = posi1 && propagateToLayer(posi,theVertex,secondHit,
239 
240 #ifdef FAMOS_DEBUG
241  std::cout << "isASeed: elec2 / posi2 " << elec2 << " " << posi2 << std::endl;
242 #endif
243  if ( !elec2 && !posi2 ) return false;
244 
245  return true;
246 
247 }
248 
249 bool
251  const GlobalPoint& theVertex,
252  GlobalPoint& theHit,
253  double phimin, double phimax,
254  unsigned layer) {
255 
256  // Set the z position of the particle to the predicted one
257  XYZTLorentzVector theNominalVertex(theVertex.x(), theVertex.y(), vertex, 0.);
258  myPart.setVertex(theNominalVertex);
259 #ifdef FAMOS_DEBUG
260  std::cout << "propagateToLayer: propagateToLayer: Before propagation (0) " << myPart << std::endl;
261 #endif
262 
263  // Propagate the inferred electron (positron) to the first layer
264  // Use the radius (barrel) or the z (forward) of the hit instead
265  // of the inaccurate layer radius and z.
266  double rCyl = thePixelLayers[layer]->forward() ? 999. : theHit.perp();
267  double zCyl = thePixelLayers[layer]->forward() ? fabs(theHit.z()) : 999.;
268  BaseParticlePropagator* myBasePart = (BaseParticlePropagator*)(&myPart);
269  myBasePart->setPropagationConditions(rCyl,zCyl);
270  // myPart.setPropagationConditions(*(thePixelLayers[layer]));
271 
272  // bool success = myPart.propagateToBoundSurface(*(thePixelLayers[layer]));
273  bool success = myPart.propagate();
274 #ifdef FAMOS_DEBUG
275  std::cout << "propagateToLayer: Success ? " << success << std::endl;
276  std::cout << "propagateToLayer: After propagation (1) " << myPart << std::endl;
277  std::cout << "propagateToLayer: The hit " << theHit << std::endl;
278 #endif
279 
280  // Check that propagated particle is within the proper phi range.
281  if ( success ) {
282  double dphi = myPart.vertex().phi() - theHit.phi();
283  if ( dphi < -M_PI )
284  dphi = dphi + 2.*M_PI;
285  else if ( dphi > M_PI )
286  dphi = dphi - 2.*M_PI;
287 #ifdef FAMOS_DEBUG
288  std::cout << "propagateToLayer: Phi range ? " << phimin << " < " << dphi << " < " << phimax << std::endl;
289 #endif
290  if ( dphi < phimin || dphi > phimax ) success = false;
291  }
292 
293  // Impose the track to go through the hit and propagate back to
294  // the nominal vertex
295  if ( success ) {
296  myPart.setVertex( XYZTLorentzVector(theHit.x(), theHit.y(), theHit.z(), 0.) );
297  myPart.propagateToNominalVertex(theNominalVertex);
298 #ifdef FAMOS_DEBUG
299  std::cout << "propagateToLayer: After propagation (2) " << myPart << std::endl;
300 #endif
301  }
302 
303  return success;
304 
305 }
306 
307 
308 double
310  double rCluster,
311  GlobalPoint& theHit)
312 {
313 
314  // Refine the Z vertex by imposing the track to pass through the RecHit
315  double pxHitz = theHit.z();
316  double pxHitr = theHit.perp();
317  return pxHitz - pxHitr*(zCluster-pxHitz)/(rCluster-pxHitr);
318 
319 }
320 
321 
322 bool
323 FastPixelHitMatcher::checkRZCompatibility(double zCluster,double rCluster,
324  double zVertex,
325  float rzMin, float rzMax,
326  GlobalPoint& theHit,
327  bool forward)
328 {
329 
330  // The hit position
331  double zHit = theHit.z();
332  double rHit = theHit.perp();
333 
334  // Compute the intersection of a line joining the cluster position
335  // and the predicted z origin (zVertex) with the layer hit
336  // (returns R for a forward layer, and Z for a barrel layer)
337  double checkRZ = forward ?
338  (zHit-zVertex)/(zCluster-zVertex) * rCluster
339  :
340  zVertex + rHit * (zCluster-zVertex)/rCluster;
341 
342  // This value is then compared to check with the actual hit position
343  // (in R for a forward layer, in Z for a barrel layer)
344 
345  return forward ?
346  checkRZ+rzMin < rHit && rHit < checkRZ+rzMax
347  :
348  checkRZ+rzMin < zHit && zHit < checkRZ+rzMax;
349 
350 }
351 
352 
353 
354 
355 
356 
357 
T perp() const
Definition: PV3DBase.h:71
unsigned int cylinderNumber() const
The global layer number in the nested cylinder geometry.
Definition: TrackerRecHit.h:87
Geom::Phi< T > phi() const
Definition: PV3DBase.h:68
T y() const
Definition: PV3DBase.h:62
std::list< TrackerLayer >::const_iterator cylinderEnd() const
Returns the last pointer in the cylinder list.
void setPropagationConditions(double r, double z, bool firstLoop=true)
Set the propagation characteristics (rCyl, zCyl and first loop only)
GlobalPoint globalPosition() const
The global position.
Definition: TrackerRecHit.h:96
bool isOnTheSameLayer(const TrackerRecHit &other) const
Check if two hits are on the same layer of the same subdetector.
std::vector< const TrackerLayer * > thePixelLayers
double zVertex(double zCluster, double rCluster, GlobalPoint &theHit)
static RecHitPointer build(const GeomDet *geom, const TrackingRecHit *rh)
T mag() const
Definition: PV3DBase.h:66
std::vector< std::pair< ConstRecHitPointer, ConstRecHitPointer > > compatibleHits(const GlobalPoint &xmeas, const GlobalPoint &vprim, float energy, std::vector< TrackerRecHit > &theHits)
TransientTrackingRecHit::ConstRecHitPointer ConstRecHitPointer
T z() const
Definition: PV3DBase.h:63
tuple result
Definition: query.py:137
bool isASeed(const ParticlePropagator &myElec, const ParticlePropagator &myPosi, const GlobalPoint &theVertex, double rCluster, double zCluster, const TrackerRecHit &hit1, const TrackerRecHit &hit2)
bool propagateToLayer(ParticlePropagator &myPart, const GlobalPoint &theVertex, GlobalPoint &theHit, double phimin, double phimax, unsigned layer)
const GeometricSearchTracker * theGeomSearchTracker
const MagneticFieldMap * theFieldMap
const XYZTLorentzVector & vertex() const
the vertex fourvector
Definition: RawParticle.h:284
#define M_PI
Definition: BFit3D.cc:3
FastPixelHitMatcher(float, float, float, float, float, float, float, float, float, float, float, float, bool)
const TrackerGeometry * theTrackerGeometry
std::list< TrackerLayer >::const_iterator cylinderBegin() const
Returns the first pointer in the cylinder list.
const TrackerInteractionGeometry * _theGeometry
bool checkRZCompatibility(double zCluster, double rCluster, double zVertex, float rzMin, float rzMax, GlobalPoint &theHit, bool forward)
unsigned int subDetId() const
The subdet Id.
Definition: TrackerRecHit.h:78
bool propagateToNominalVertex(const XYZTLorentzVector &hit2=XYZTLorentzVector(0., 0., 0., 0.))
void setES(const MagneticFieldMap *aFieldMap, const TrackerGeometry *aTrackerGeometry, const GeometricSearchTracker *geomSearchTracker, const TrackerInteractionGeometry *interactionGeometry)
tuple cout
Definition: gather_cfg.py:121
T x() const
Definition: PV3DBase.h:61
void setVertex(const XYZTLorentzVector &vtx)
set the vertex
Definition: RawParticle.h:287
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:15