CMS 3D CMS Logo

PhotonConversionTrajectorySeedProducerFromSingleLegAlgo.cc
Go to the documentation of this file.
3 
8 
9 //#define debugTSPFSLA
10 
11 namespace {
12  inline double sqr(double a) { return a * a; }
13 } // namespace
14 
16  const edm::ParameterSet& conf, edm::ConsumesCollector&& iC)
17  : theHitsGenerator(new CombinedHitPairGeneratorForPhotonConversion(
18  conf.getParameter<edm::ParameterSet>("OrderedHitsFactoryPSet"), iC)),
19  theSeedCreator(new SeedForPhotonConversion1Leg(conf.getParameter<edm::ParameterSet>("SeedCreatorPSet"))),
20  theRegionProducer(
21  new GlobalTrackingRegionProducerFromBeamSpot(conf.getParameter<edm::ParameterSet>("RegionFactoryPSet"), iC)),
22  theClusterCheck(conf.getParameter<edm::ParameterSet>("ClusterCheckPSet"), iC),
23  theSilentOnClusterCheck(conf.getParameter<edm::ParameterSet>("ClusterCheckPSet")
24  .getUntrackedParameter<bool>("silentClusterCheck", false)),
25  _vtxMinDoF(conf.getParameter<double>("vtxMinDoF")),
26  _maxDZSigmas(conf.getParameter<double>("maxDZSigmas")),
27  _maxNumSelVtx(conf.getParameter<uint32_t>("maxNumSelVtx")),
28  _applyTkVtxConstraint(conf.getParameter<bool>("applyTkVtxConstraint")),
29  _countSeedTracks(0),
30  _primaryVtxInputTag(conf.getParameter<edm::InputTag>("primaryVerticesTag")),
31  _beamSpotInputTag(conf.getParameter<edm::InputTag>("beamSpotInputTag")) {
34  token_refitter = iC.consumes<reco::TrackCollection>(conf.getParameter<edm::InputTag>("TrackRefitter"));
35 }
36 
38 
40  const edm::EventSetup& setup,
42  myEsetup = &setup;
43  myEvent = &event;
44 
45  assert(seedCollection == nullptr);
46 
48 
49  size_t clustsOrZero = theClusterCheck.tooManyClusters(event);
50  if (clustsOrZero) {
52  edm::LogError("TooManyClusters") << "Found too many clusters (" << clustsOrZero << "), bailing out.\n";
53  seedCollection = nullptr;
54  return;
55  }
56 
57  edm::ESHandle<MagneticField> handleMagField;
58  setup.get<IdealMagneticFieldRecord>().get(handleMagField);
59  magField = handleMagField.product();
60  if (UNLIKELY(magField->inTesla(GlobalPoint(0., 0., 0.)).z() < 0.01)) {
61  seedCollection = nullptr;
62  return;
63  }
64 
66 
67  event.getByToken(token_vertex, vertexHandle);
68  if (!vertexHandle.isValid() || vertexHandle->empty()) {
69  edm::LogError("PhotonConversionFinderFromTracks")
70  << "Error! Can't get the product primary Vertex Collection " << _primaryVtxInputTag << "\n";
71  seedCollection = nullptr;
72  return;
73  }
74 
75  event.getByToken(token_bs, recoBeamSpotHandle);
76 
77  regions = theRegionProducer->regions(event, setup);
78 
79  // find seeds
80  loopOnTracks();
81 
82 #ifdef debugTSPFSLA
83  std::stringstream ss;
84  ss.str("");
85  ss << "\n++++++++++++++++++\n";
86  ss << "seed collection size " << seedCollection->size();
87  for (auto const& tjS : *seedCollection) {
88  po.print(ss, tjS);
89  }
90  edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
91  //-------------------------------------------------
92 #endif
93 
94  // clear memory
95  theHitsGenerator->clearCache();
96 
97  seedCollection = nullptr;
98 }
99 
101  //--- Get Tracks
103 
104  if (trackCollectionH.isValid() == 0) {
105  edm::LogError("MissingInput")
106  << " could not find track collecion in PhotonConversionTrajectorySeedProducerFromSingleLegAlgo";
107  return;
108  }
109 
110  size_t idx = 0, sel = 0;
111  _countSeedTracks = 0;
112 
113 #ifdef debugTSPFSLA
114  ss.str("");
115 #endif
116 
117  for (reco::TrackCollection::const_iterator tr = trackCollectionH->begin(); tr != trackCollectionH->end();
118  tr++, idx++) {
119  if (rejectTrack(*tr))
120  continue;
121  std::vector<reco::Vertex> selectedPriVtxCompatibleWithTrack;
122  if (!_applyTkVtxConstraint) {
123  selectedPriVtxCompatibleWithTrack.push_back(*(vertexHandle->begin())); //Same approach as before
124  } else {
125  if (!selectPriVtxCompatibleWithTrack(*tr, selectedPriVtxCompatibleWithTrack))
126  continue;
127  }
128 
129  sel++;
130  loopOnPriVtx(*tr, selectedPriVtxCompatibleWithTrack);
131  }
132 #ifdef debugTSPFSLA
133  edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
134  edm::LogInfo("debugTrajSeedFromSingleLeg") << "Inspected " << sel << " tracks over " << idx
135  << " tracks. \t # tracks providing at least one seed " << _countSeedTracks;
136 #endif
137 }
138 
140  const reco::Track& tk, std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack) {
141  std::vector<std::pair<double, short> > idx;
142  short count = -1;
143 
144  double cosPhi = tk.px() / tk.pt();
145  double sinPhi = tk.py() / tk.pt();
146  double sphi2 = tk.covariance(2, 2);
147  double stheta2 = tk.covariance(1, 1);
148 
149  for (const reco::Vertex& vtx : *vertexHandle) {
150  count++;
151  if (vtx.ndof() <= _vtxMinDoF)
152  continue;
153 
154  double _dz = tk.dz(vtx.position());
155  double _dzError = tk.dzError();
156 
157  double cotTheta = tk.pz() / tk.pt();
158  double dx = vtx.position().x();
159  double dy = vtx.position().y();
160  double sx2 = vtx.covariance(0, 0);
161  double sy2 = vtx.covariance(1, 1);
162 
163  double sxy2 = sqr(cosPhi * cotTheta) * sx2 + sqr(sinPhi * cotTheta) * sy2 +
164  sqr(cotTheta * (-dx * sinPhi + dy * cosPhi)) * sphi2 +
165  sqr((1 + cotTheta * cotTheta) * (dx * cosPhi + dy * sinPhi)) * stheta2;
166 
167  _dzError = sqrt(
168  _dzError * _dzError + vtx.covariance(2, 2) +
169  sxy2); //there is a missing component, related to the element (vtx.x*px+vtx.y*py)/pt * pz/pt. since the tk ref point is at the point of closest approach, this scalar product should be almost zero.
170 
171 #ifdef debugTSPFSLA
172  ss << " primary vtx " << vtx.position() << " \tk vz " << tk.vz() << " vx " << tk.vx() << " vy " << tk.vy()
173  << " pz/pt " << tk.pz() / tk.pt() << " \t dz " << _dz << " \t " << _dzError << " sxy2 " << sxy2
174  << " \t dz/dzErr " << _dz / _dzError << std::endl;
175 #endif
176 
177  if (fabs(_dz) / _dzError > _maxDZSigmas)
178  continue;
179 
180  idx.push_back(std::pair<double, short>(fabs(_dz), count));
181  }
182  if (idx.empty()) {
183 #ifdef debugTSPFSLA
184  ss << "no vertex selected " << std::endl;
185 #endif
186  return false;
187  }
188 
189  std::stable_sort(
190  idx.begin(), idx.end(), [](std::pair<double, short> a, std::pair<double, short> b) { return a.first < b.first; });
191 
192  for (size_t i = 0; i < _maxNumSelVtx && i < idx.size(); ++i) {
193  selectedPriVtxCompatibleWithTrack.push_back((*vertexHandle)[idx[i].second]);
194 #ifdef debugTSPFSLA
195  ss << "selected vtx dz " << idx[0].first << " position" << idx[0].second << std::endl;
196 #endif
197  }
198 
199  return true;
200 }
201 
203  const reco::Track& tk, const std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack) {
204  bool foundAtLeastASeedCand = false;
205  for (auto const& vtx : selectedPriVtxCompatibleWithTrack) {
206  math::XYZPoint primaryVertexPoint = math::XYZPoint(vtx.position());
207 
208  for (IR ir = regions.begin(), irEnd = regions.end(); ir < irEnd; ++ir) {
209  const TrackingRegion& region = **ir;
210 
211 #ifdef debugTSPFSLA
212  ss << "[PrintRegion] " << region.print() << std::endl;
213 #endif
214 
215  //This if is just for the _countSeedTracks. otherwise
216  //inspectTrack(&tk,region, primaryVertexPoint);
217  //would be enough
218 
219  if (inspectTrack(&tk, region, primaryVertexPoint) and !foundAtLeastASeedCand) {
220  foundAtLeastASeedCand = true;
222  }
223  }
224  }
225 }
226 
229  if (recoBeamSpotHandle.isValid()) {
231 
232  _IdealHelixParameters.setData(&track, beamSpot);
233  if (_IdealHelixParameters.GetTangentPoint().r() == 0) {
234  //this case means a null results on the _IdealHelixParameters side
235  return true;
236  }
237 
238  float rMin = 2.; //cm
240  //this case means a track that has the tangent point nearby the primary vertex
241  // if the track is primary, this number tends to be the primary vertex itself
242  //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
243  //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
244  return true;
245  }
246  }
247 
248  //-------------------------------------------------------
249  /*
250  float maxPt2=64.; //Cut on pt^2 Indeed doesn't do almost nothing
251  if(track.momentum().Perp2() > maxPt2)
252  return true;
253  */
254  //-------------------------------------------------------
255  //Cut in the barrel eta region FIXME: to be extended to endcaps
256  /*
257  float maxEta=1.3;
258  if(fabs(track.eta()) > maxEta)
259  return true;
260  */
261  //-------------------------------------------------------
262  //Reject tracks that have a first valid hit in the pixel barrel/endcap layer/disk 1
263  //assume that the hits are aligned along momentum
264  /*
265  const reco::HitPattern& p=track.hitPattern();
266  for (int i=0; i<p.numberOfHits(); i++) {
267  uint32_t hit = p.getHitPattern(i);
268  // if the hit is valid and in pixel barrel, print out the layer
269  if (! p.validHitFilter(hit) ) continue;
270  if( (p.pixelBarrelHitFilter(hit) || p.pixelEndcapHitFilter(hit))
271  &&
272  p.getLayer(hit) == 1
273  )
274  return true;
275  else
276  break; //because the first valid hit is in a different layer
277  }
278  */
279  //-------------------------------------------------------
280 
281  return false;
282 }
283 
285  const TrackingRegion& region,
286  math::XYZPoint& primaryVertexPoint) {
287  _IdealHelixParameters.setData(track, primaryVertexPoint);
288 
290  (_IdealHelixParameters.GetTangentPoint().r() == 0)) {
291  //this case means a null results on the _IdealHelixParameters side
292  return false;
293  }
294 
295  float rMin = 3.; //cm
297  //this case means a track that has the tangent point nearby the primary vertex
298  // if the track is primary, this number tends to be the primary vertex itself
299  //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
300  //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
301  return false;
302  }
303 
304  float ptmin = 0.5;
305  float originRBound = 3;
306  float originZBound = 3.;
307 
308  GlobalPoint originPos;
312  float cotTheta;
314  cotTheta =
316  } else {
318  cotTheta = 99999.f;
319  else
320  cotTheta = -99999.f;
321  }
322  GlobalVector originBounds(originRBound, originRBound, originZBound);
323 
324  GlobalPoint pvtxPoint(primaryVertexPoint.x(), primaryVertexPoint.y(), primaryVertexPoint.z());
325 
326  ConversionRegion convRegion(originPos, pvtxPoint, cotTheta, track->thetaError(), -1 * track->charge());
327 
328 #ifdef debugTSPFSLA
329  ss << "\nConversion Point " << originPos << " " << originPos.perp() << "\n";
330 #endif
331 
332  const OrderedSeedingHits& hitss = theHitsGenerator->run(convRegion, region, *myEvent, *myEsetup);
333 
334  unsigned int nHitss = hitss.size();
335 
336  if (nHitss == 0)
337  return false;
338 
339 #ifdef debugTSPFSLA
340  ss << "\n nHitss " << nHitss << "\n";
341 #endif
342 
343  if (seedCollection->empty())
344  seedCollection->reserve(
345  nHitss); // don't do multiple reserves in the case of multiple regions: it would make things even worse
346  // as it will cause N re-allocations instead of the normal log(N)/log(2)
347  for (unsigned int iHits = 0; iHits < nHitss; ++iHits) {
348 #ifdef debugTSPFSLA
349  ss << "\n iHits " << iHits << "\n";
350 #endif
351  const SeedingHitSet& hits = hitss[iHits];
352  theSeedCreator->trajectorySeed(
353  *seedCollection, hits, originPos, originBounds, ptmin, *myEsetup, convRegion.cotTheta(), ss);
354  }
355  return true;
356 }
T getParameter(std::string const &) const
void setData(const reco::Track *track, const math::XYZVector &refPoint=math::XYZVector(0, 0, 0))
PhotonConversionTrajectorySeedProducerFromSingleLegAlgo(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
T perp() const
Definition: PV3DBase.h:69
void setMagnField(const MagneticField *magnField)
void find(const edm::Event &event, const edm::EventSetup &setup, TrajectorySeedCollection &output)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:605
math::XYZVector GetMomentumAtTangentPoint() const
U second(std::pair< T, U > const &p)
math::XYZVector GetTangentPoint() const
std::vector< TrajectorySeed > TrajectorySeedCollection
CovarianceMatrix covariance() const
return track covariance matrix
Definition: TrackBase.h:677
T sqrt(T t)
Definition: SSEVec.h:19
double pt() const
track transverse momentum
Definition: TrackBase.h:602
T z() const
Definition: PV3DBase.h:61
size_t tooManyClusters(const edm::Event &e) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
virtual unsigned int size() const =0
void print(std::stringstream &ss, const SiStripCluster &clus)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool isValid() const
Definition: HandleBase.h:70
bool inspectTrack(const reco::Track *track, const TrackingRegion &region, math::XYZPoint &primaryVertexPoint)
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:611
double dz() const
dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to...
Definition: TrackBase.h:596
double dzError() const
error on dz
Definition: TrackBase.h:725
double vz() const
z coordinate of the reference point on track
Definition: TrackBase.h:626
void loopOnPriVtx(const reco::Track &tk, const std::vector< reco::Vertex > &selectedPriVtxCompatibleWithTrack)
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
double b
Definition: hdecay.h:118
virtual std::string print() const
double ptmin
Definition: HydjetWrapper.h:84
double vy() const
y coordinate of the reference point on track
Definition: TrackBase.h:623
std::unique_ptr< CombinedHitPairGeneratorForPhotonConversion > theHitsGenerator
HLT enums.
double a
Definition: hdecay.h:119
Square< F >::type sqr(const F &f)
Definition: Square.h:14
T get() const
Definition: EventSetup.h:73
int charge() const
track electric charge
Definition: TrackBase.h:575
const Point & position() const
position
Definition: BeamSpot.h:59
#define UNLIKELY(x)
Definition: Likely.h:21
T const * product() const
Definition: ESHandle.h:86
bool selectPriVtxCompatibleWithTrack(const reco::Track &tk, std::vector< reco::Vertex > &selectedPriVtxCompatibleWithTrack)
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:608
Definition: event.py:1
double vx() const
x coordinate of the reference point on track
Definition: TrackBase.h:620
double thetaError() const
error on theta
Definition: TrackBase.h:704