CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PhotonConversionTrajectorySeedProducerFromSingleLegAlgo.cc
Go to the documentation of this file.
4 
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"), iC)),
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  token_magField = iC.esConsumes();
36 }
37 
39 
41  const edm::EventSetup& setup,
43  myEsetup = &setup;
44  myEvent = &event;
45 
46  assert(seedCollection == nullptr);
47 
49 
50  size_t clustsOrZero = theClusterCheck.tooManyClusters(event);
51  if (clustsOrZero) {
53  edm::LogError("TooManyClusters") << "Found too many clusters (" << clustsOrZero << "), bailing out.\n";
54  seedCollection = nullptr;
55  return;
56  }
57 
58  const auto& magField = setup.getData(token_magField);
59  if (UNLIKELY(magField.inTesla(GlobalPoint(0., 0., 0.)).z() < 0.01)) {
60  seedCollection = nullptr;
61  return;
62  }
63 
65 
66  event.getByToken(token_vertex, vertexHandle);
67  if (!vertexHandle.isValid() || vertexHandle->empty()) {
68  edm::LogError("PhotonConversionFinderFromTracks")
69  << "Error! Can't get the product primary Vertex Collection " << _primaryVtxInputTag << "\n";
70  seedCollection = nullptr;
71  return;
72  }
73 
74  event.getByToken(token_bs, recoBeamSpotHandle);
75 
76  regions = theRegionProducer->regions(event, setup);
77 
78  // find seeds
79  loopOnTracks();
80 
81 #ifdef debugTSPFSLA
82  std::stringstream ss;
83  ss.str("");
84  ss << "\n++++++++++++++++++\n";
85  ss << "seed collection size " << seedCollection->size();
86  for (auto const& tjS : *seedCollection) {
87  po.print(ss, tjS);
88  }
89  edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
90  //-------------------------------------------------
91 #endif
92 
93  // clear memory
94  theHitsGenerator->clearCache();
95 
96  seedCollection = nullptr;
97 }
98 
100  //--- Get Tracks
102 
103  if (trackCollectionH.isValid() == 0) {
104  edm::LogError("MissingInput")
105  << " could not find track collecion in PhotonConversionTrajectorySeedProducerFromSingleLegAlgo";
106  return;
107  }
108 
109  size_t idx = 0, sel = 0;
110  _countSeedTracks = 0;
111 
112 #ifdef debugTSPFSLA
113  ss.str("");
114 #endif
115 
116  for (reco::TrackCollection::const_iterator tr = trackCollectionH->begin(); tr != trackCollectionH->end();
117  tr++, idx++) {
118  if (rejectTrack(*tr))
119  continue;
120  std::vector<reco::Vertex> selectedPriVtxCompatibleWithTrack;
121  if (!_applyTkVtxConstraint) {
122  selectedPriVtxCompatibleWithTrack.push_back(*(vertexHandle->begin())); //Same approach as before
123  } else {
124  if (!selectPriVtxCompatibleWithTrack(*tr, selectedPriVtxCompatibleWithTrack))
125  continue;
126  }
127 
128  sel++;
129  loopOnPriVtx(*tr, selectedPriVtxCompatibleWithTrack);
130  }
131 #ifdef debugTSPFSLA
132  edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
133  edm::LogInfo("debugTrajSeedFromSingleLeg") << "Inspected " << sel << " tracks over " << idx
134  << " tracks. \t # tracks providing at least one seed " << _countSeedTracks;
135 #endif
136 }
137 
139  const reco::Track& tk, std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack) {
140  std::vector<std::pair<double, short> > idx;
141  short count = -1;
142 
143  double cosPhi = tk.px() / tk.pt();
144  double sinPhi = tk.py() / tk.pt();
145  double sphi2 = tk.covariance(2, 2);
146  double stheta2 = tk.covariance(1, 1);
147 
148  for (const reco::Vertex& vtx : *vertexHandle) {
149  count++;
150  if (vtx.ndof() <= _vtxMinDoF)
151  continue;
152 
153  double _dz = tk.dz(vtx.position());
154  double _dzError = tk.dzError();
155 
156  double cotTheta = tk.pz() / tk.pt();
157  double dx = vtx.position().x();
158  double dy = vtx.position().y();
159  double sx2 = vtx.covariance(0, 0);
160  double sy2 = vtx.covariance(1, 1);
161 
162  double sxy2 = sqr(cosPhi * cotTheta) * sx2 + sqr(sinPhi * cotTheta) * sy2 +
163  sqr(cotTheta * (-dx * sinPhi + dy * cosPhi)) * sphi2 +
164  sqr((1 + cotTheta * cotTheta) * (dx * cosPhi + dy * sinPhi)) * stheta2;
165 
166  _dzError = sqrt(
167  _dzError * _dzError + vtx.covariance(2, 2) +
168  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.
169 
170 #ifdef debugTSPFSLA
171  ss << " primary vtx " << vtx.position() << " \tk vz " << tk.vz() << " vx " << tk.vx() << " vy " << tk.vy()
172  << " pz/pt " << tk.pz() / tk.pt() << " \t dz " << _dz << " \t " << _dzError << " sxy2 " << sxy2
173  << " \t dz/dzErr " << _dz / _dzError << std::endl;
174 #endif
175 
176  if (fabs(_dz) / _dzError > _maxDZSigmas)
177  continue;
178 
179  idx.push_back(std::pair<double, short>(fabs(_dz), count));
180  }
181  if (idx.empty()) {
182 #ifdef debugTSPFSLA
183  ss << "no vertex selected " << std::endl;
184 #endif
185  return false;
186  }
187 
188  std::stable_sort(
189  idx.begin(), idx.end(), [](std::pair<double, short> a, std::pair<double, short> b) { return a.first < b.first; });
190 
191  for (size_t i = 0; i < _maxNumSelVtx && i < idx.size(); ++i) {
192  selectedPriVtxCompatibleWithTrack.push_back((*vertexHandle)[idx[i].second]);
193 #ifdef debugTSPFSLA
194  ss << "selected vtx dz " << idx[0].first << " position" << idx[0].second << std::endl;
195 #endif
196  }
197 
198  return true;
199 }
200 
202  const reco::Track& tk, const std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack) {
203  bool foundAtLeastASeedCand = false;
204  for (auto const& vtx : selectedPriVtxCompatibleWithTrack) {
205  math::XYZPoint primaryVertexPoint = math::XYZPoint(vtx.position());
206 
207  for (IR ir = regions.begin(), irEnd = regions.end(); ir < irEnd; ++ir) {
208  const TrackingRegion& region = **ir;
209 
210 #ifdef debugTSPFSLA
211  ss << "[PrintRegion] " << region.print() << std::endl;
212 #endif
213 
214  //This if is just for the _countSeedTracks. otherwise
215  //inspectTrack(&tk,region, primaryVertexPoint);
216  //would be enough
217 
218  if (inspectTrack(&tk, region, primaryVertexPoint) and !foundAtLeastASeedCand) {
219  foundAtLeastASeedCand = true;
221  }
222  }
223  }
224 }
225 
228  if (recoBeamSpotHandle.isValid()) {
229  beamSpot = math::XYZVector(recoBeamSpotHandle->position());
230 
231  _IdealHelixParameters.setData(&track, beamSpot);
232  if (_IdealHelixParameters.GetTangentPoint().r() == 0) {
233  //this case means a null results on the _IdealHelixParameters side
234  return true;
235  }
236 
237  float rMin = 2.; //cm
238  if (_IdealHelixParameters.GetTangentPoint().rho() < rMin) {
239  //this case means a track that has the tangent point nearby the primary vertex
240  // if the track is primary, this number tends to be the primary vertex itself
241  //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
242  //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
243  return true;
244  }
245  }
246 
247  //-------------------------------------------------------
248  /*
249  float maxPt2=64.; //Cut on pt^2 Indeed doesn't do almost nothing
250  if(track.momentum().Perp2() > maxPt2)
251  return true;
252  */
253  //-------------------------------------------------------
254  //Cut in the barrel eta region FIXME: to be extended to endcaps
255  /*
256  float maxEta=1.3;
257  if(fabs(track.eta()) > maxEta)
258  return true;
259  */
260  //-------------------------------------------------------
261  //Reject tracks that have a first valid hit in the pixel barrel/endcap layer/disk 1
262  //assume that the hits are aligned along momentum
263  /*
264  const reco::HitPattern& p=track.hitPattern();
265  for (int i=0; i<p.numberOfHits(); i++) {
266  uint32_t hit = p.getHitPattern(i);
267  // if the hit is valid and in pixel barrel, print out the layer
268  if (! p.validHitFilter(hit) ) continue;
269  if( (p.pixelBarrelHitFilter(hit) || p.pixelEndcapHitFilter(hit))
270  &&
271  p.getLayer(hit) == 1
272  )
273  return true;
274  else
275  break; //because the first valid hit is in a different layer
276  }
277  */
278  //-------------------------------------------------------
279 
280  return false;
281 }
282 
284  const TrackingRegion& region,
285  math::XYZPoint& primaryVertexPoint) {
286  _IdealHelixParameters.setData(track, primaryVertexPoint);
287 
289  (_IdealHelixParameters.GetTangentPoint().r() == 0)) {
290  //this case means a null results on the _IdealHelixParameters side
291  return false;
292  }
293 
294  float rMin = 3.; //cm
295  if (_IdealHelixParameters.GetTangentPoint().rho() < rMin) {
296  //this case means a track that has the tangent point nearby the primary vertex
297  // if the track is primary, this number tends to be the primary vertex itself
298  //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
299  //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
300  return false;
301  }
302 
303  float ptmin = 0.5;
304  float originRBound = 3;
305  float originZBound = 3.;
306 
307  GlobalPoint originPos;
311  float cotTheta;
313  cotTheta =
315  } else {
317  cotTheta = 99999.f;
318  else
319  cotTheta = -99999.f;
320  }
321  GlobalVector originBounds(originRBound, originRBound, originZBound);
322 
323  GlobalPoint pvtxPoint(primaryVertexPoint.x(), primaryVertexPoint.y(), primaryVertexPoint.z());
324 
325  ConversionRegion convRegion(originPos, pvtxPoint, cotTheta, track->thetaError(), -1 * track->charge());
326 
327 #ifdef debugTSPFSLA
328  ss << "\nConversion Point " << originPos << " " << originPos.perp() << "\n";
329 #endif
330 
331  const OrderedSeedingHits& hitss = theHitsGenerator->run(convRegion, region, *myEvent, *myEsetup);
332 
333  unsigned int nHitss = hitss.size();
334 
335  if (nHitss == 0)
336  return false;
337 
338 #ifdef debugTSPFSLA
339  ss << "\n nHitss " << nHitss << "\n";
340 #endif
341 
342  if (seedCollection->empty())
343  seedCollection->reserve(
344  nHitss); // don't do multiple reserves in the case of multiple regions: it would make things even worse
345  // as it will cause N re-allocations instead of the normal log(N)/log(2)
346  for (unsigned int iHits = 0; iHits < nHitss; ++iHits) {
347 #ifdef debugTSPFSLA
348  ss << "\n iHits " << iHits << "\n";
349 #endif
350  const SeedingHitSet& hits = hitss[iHits];
351  theSeedCreator->trajectorySeed(
352  *seedCollection, hits, originPos, originBounds, ptmin, *myEsetup, convRegion.cotTheta(), ss);
353  }
354  return true;
355 }
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:539
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
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
virtual unsigned int size() const =0
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:640
Log< level::Error, false > LogError
int sqr(const T &t)
assert(be >=bs)
math::XYZVector GetMomentumAtTangentPoint() const
bool getData(T &iHolder) const
Definition: EventSetup.h:128
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:716
T sqrt(T t)
Definition: SSEVec.h:19
double pt() const
track transverse momentum
Definition: TrackBase.h:637
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
void print(std::stringstream &ss, const SiStripCluster &clus)
bool isValid() const
Definition: HandleBase.h:70
bool inspectTrack(const reco::Track *track, const TrackingRegion &region, math::XYZPoint &primaryVertexPoint)
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:646
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:622
double dzError() const
error on dz
Definition: TrackBase.h:778
Log< level::Info, false > LogInfo
double vz() const
z coordinate of the reference point on track
Definition: TrackBase.h:661
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
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
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:658
std::unique_ptr< CombinedHitPairGeneratorForPhotonConversion > theHitsGenerator
double a
Definition: hdecay.h:119
int charge() const
track electric charge
Definition: TrackBase.h:596
#define UNLIKELY(x)
Definition: Likely.h:21
bool selectPriVtxCompatibleWithTrack(const reco::Track &tk, std::vector< reco::Vertex > &selectedPriVtxCompatibleWithTrack)
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:643
double vx() const
x coordinate of the reference point on track
Definition: TrackBase.h:655
double thetaError() const
error on theta
Definition: TrackBase.h:757