CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PhotonConversionTrajectorySeedProducerFromSingleLegAlgo.cc
Go to the documentation of this file.
3 
8 
9 
10 //#define debugTSPFSLA
11 
12 namespace {
13  inline double sqr(double a){return a*a;}
14 }
15 
19  :
20  theHitsGenerator(new CombinedHitPairGeneratorForPhotonConversion(conf.getParameter<edm::ParameterSet>("OrderedHitsFactoryPSet"), iC)),
21  theSeedCreator(new SeedForPhotonConversion1Leg(conf.getParameter<edm::ParameterSet>("SeedCreatorPSet"))),
22  theRegionProducer(new GlobalTrackingRegionProducerFromBeamSpot(conf.getParameter<edm::ParameterSet>("RegionFactoryPSet"), iC)),
23  theClusterCheck(conf.getParameter<edm::ParameterSet>("ClusterCheckPSet"), iC),
24  theSilentOnClusterCheck(conf.getParameter<edm::ParameterSet>("ClusterCheckPSet").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"))
32 {
35  token_refitter = iC.consumes<reco::TrackCollection>(conf.getParameter<edm::InputTag>("TrackRefitter"));
36 }
37 
39 }
40 
41 void
43 
44  myEsetup = &setup;
45  myEvent = &event;
46 
47  assert(seedCollection==nullptr);
48 
50 
51 
52  size_t clustsOrZero = theClusterCheck.tooManyClusters(event);
53  if (clustsOrZero){
55  edm::LogError("TooManyClusters") << "Found too many clusters (" << clustsOrZero << "), bailing out.\n";
56  seedCollection= nullptr; return ;
57  }
58 
59 
60  edm::ESHandle<MagneticField> handleMagField;
61  setup.get<IdealMagneticFieldRecord>().get(handleMagField);
62  magField = handleMagField.product();
63  if (unlikely(magField->inTesla(GlobalPoint(0.,0.,0.)).z()<0.01)){seedCollection= nullptr; return;}
64 
66 
67 
68  event.getByToken(token_vertex, vertexHandle);
69  if (!vertexHandle.isValid() || vertexHandle->empty()){
70  edm::LogError("PhotonConversionFinderFromTracks") << "Error! Can't get the product primary Vertex Collection "<< _primaryVtxInputTag << "\n";
71  seedCollection= nullptr; return;
72  }
73 
74  event.getByToken(token_bs,recoBeamSpotHandle);
75 
76 
77  regions = theRegionProducer->regions(event,setup);
78 
79 
80 
81  // find seeds
82  loopOnTracks();
83 
84 
85 #ifdef debugTSPFSLA
86  std::stringstream ss;
87  ss.str("");
88  ss << "\n++++++++++++++++++\n";
89  ss << "seed collection size " << seedCollection->size();
90  for (auto const & tjS : *seedCollection){
91  po.print(ss, tjS);
92  }
93  edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
94  //-------------------------------------------------
95 #endif
96 
97 
98  // clear memory
99  theHitsGenerator->clearCache();
100  for (IR ir=regions.begin(), irEnd=regions.end(); ir < irEnd; ++ir) delete (*ir);
101 
102  seedCollection = nullptr;
103 
104 }
105 
106 
109 
110  //--- Get Tracks
112 
113  if(trackCollectionH.isValid()==0){
114  edm::LogError("MissingInput")<<" could not find track collecion in PhotonConversionTrajectorySeedProducerFromSingleLegAlgo";
115  return;
116  }
117 
118  size_t idx=0, sel=0;
120 
121 #ifdef debugTSPFSLA
122  ss.str("");
123 #endif
124 
125  for( reco::TrackCollection::const_iterator tr = trackCollectionH->begin();
126  tr != trackCollectionH->end(); tr++, idx++) {
127 
128 
129  if(rejectTrack(*tr)) continue;
130  std::vector<reco::Vertex> selectedPriVtxCompatibleWithTrack;
132  selectedPriVtxCompatibleWithTrack.push_back(*(vertexHandle->begin())); //Same approach as before
133  }else{
134  if(!selectPriVtxCompatibleWithTrack(*tr,selectedPriVtxCompatibleWithTrack)) continue;
135  }
136 
137  sel++;
138  loopOnPriVtx(*tr,selectedPriVtxCompatibleWithTrack);
139  }
140 #ifdef debugTSPFSLA
141  edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
142  edm::LogInfo("debugTrajSeedFromSingleLeg") << "Inspected " << sel << " tracks over " << idx << " tracks. \t # tracks providing at least one seed " << _countSeedTracks ;
143 #endif
144 }
145 
147 selectPriVtxCompatibleWithTrack(const reco::Track& tk, std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack){
148 
149  std::vector< std::pair< double, short> > idx;
150  short count=-1;
151 
152  double cosPhi=tk.px()/tk.pt();
153  double sinPhi=tk.py()/tk.pt();
154  double sphi2=tk.covariance(2,2);
155  double stheta2=tk.covariance(1,1);
156 
157  for ( const reco::Vertex& vtx : *vertexHandle){
158  count++;
159  if(vtx.ndof()<= _vtxMinDoF) continue;
160 
161  double _dz= tk.dz(vtx.position());
162  double _dzError=tk.dzError();
163 
164  double cotTheta=tk.pz()/tk.pt();
165  double dx = vtx.position().x();
166  double dy = vtx.position().y();
167  double sx2=vtx.covariance(0,0);
168  double sy2=vtx.covariance(1,1);
169 
170  double sxy2= sqr(cosPhi*cotTheta)*sx2+
171  sqr(sinPhi*cotTheta)*sy2+
172  sqr(cotTheta*(-dx*sinPhi+dy*cosPhi))*sphi2+
173  sqr((1+cotTheta*cotTheta)*(dx*cosPhi+dy*sinPhi))*stheta2;
174 
175  _dzError=sqrt(_dzError*_dzError+vtx.covariance(2,2)+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.
176 
177 #ifdef debugTSPFSLA
178  ss << " primary vtx " << vtx.position() << " \tk vz " << tk.vz() << " vx " << tk.vx() << " vy " << tk.vy() << " pz/pt " << tk.pz()/tk.pt() << " \t dz " << _dz << " \t " << _dzError << " sxy2 "<< sxy2<< " \t dz/dzErr " << _dz/_dzError<< std::endl;
179 #endif
180 
181  if(fabs(_dz)/_dzError > _maxDZSigmas) continue;
182 
183  idx.push_back(std::pair<double,short>(fabs(_dz),count));
184  }
185  if(idx.size()==0) {
186 #ifdef debugTSPFSLA
187  ss << "no vertex selected " << std::endl;
188 #endif
189  return false;
190 }
191 
192  std::stable_sort(idx.begin(),idx.end(), [](std::pair<double,short> a, std::pair<double,short> b) { return a.first<b.first; });
193 
194  for(size_t i=0;i<_maxNumSelVtx && i<idx.size();++i){
195  selectedPriVtxCompatibleWithTrack.push_back((*vertexHandle)[idx[i].second]);
196 #ifdef debugTSPFSLA
197  ss << "selected vtx dz " << idx[0].first << " position" << idx[0].second << std::endl;
198 #endif
199  }
200 
201  return true;
202 }
203 
205 loopOnPriVtx(const reco::Track& tk, const std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack){
206 
207  bool foundAtLeastASeedCand=false;
208  for (auto const & vtx : selectedPriVtxCompatibleWithTrack){
209 
210  math::XYZPoint primaryVertexPoint=math::XYZPoint(vtx.position());
211 
212  for (IR ir=regions.begin(), irEnd=regions.end(); ir < irEnd; ++ir) {
213  const TrackingRegion & region = **ir;
214 
215 #ifdef debugTSPFSLA
216  ss << "[PrintRegion] " << region.print() << std::endl;
217 #endif
218 
219  //This if is just for the _countSeedTracks. otherwise
220  //inspectTrack(&tk,region, primaryVertexPoint);
221  //would be enough
222 
223  if(
224  inspectTrack(&tk,region, primaryVertexPoint)
225  and
226  !foundAtLeastASeedCand
227  ){
228  foundAtLeastASeedCand=true;
229  _countSeedTracks++;
230  }
231 
232  }
233  }
234 }
235 
237 rejectTrack(const reco::Track& track){
238 
241  beamSpot = math::XYZVector(recoBeamSpotHandle->position());
242 
243  _IdealHelixParameters.setData(&track,beamSpot);
245  //this case means a null results on the _IdealHelixParameters side
246  return true;
247  }
248 
249  float rMin=2.; //cm
250  if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
251  //this case means a track that has the tangent point nearby the primary vertex
252  // if the track is primary, this number tends to be the primary vertex itself
253  //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
254  //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
255  return true;
256  }
257  }
258 
259  //-------------------------------------------------------
260  /*
261  float maxPt2=64.; //Cut on pt^2 Indeed doesn't do almost nothing
262  if(track.momentum().Perp2() > maxPt2)
263  return true;
264  */
265  //-------------------------------------------------------
266  //Cut in the barrel eta region FIXME: to be extended to endcaps
267  /*
268  float maxEta=1.3;
269  if(fabs(track.eta()) > maxEta)
270  return true;
271  */
272  //-------------------------------------------------------
273  //Reject tracks that have a first valid hit in the pixel barrel/endcap layer/disk 1
274  //assume that the hits are aligned along momentum
275  /*
276  const reco::HitPattern& p=track.hitPattern();
277  for (int i=0; i<p.numberOfHits(); i++) {
278  uint32_t hit = p.getHitPattern(i);
279  // if the hit is valid and in pixel barrel, print out the layer
280  if (! p.validHitFilter(hit) ) continue;
281  if( (p.pixelBarrelHitFilter(hit) || p.pixelEndcapHitFilter(hit))
282  &&
283  p.getLayer(hit) == 1
284  )
285  return true;
286  else
287  break; //because the first valid hit is in a different layer
288  }
289  */
290  //-------------------------------------------------------
291 
292 
293  return false;
294 }
295 
296 
298 inspectTrack(const reco::Track* track, const TrackingRegion & region, math::XYZPoint& primaryVertexPoint){
299 
300  _IdealHelixParameters.setData(track,primaryVertexPoint);
301 
304  //this case means a null results on the _IdealHelixParameters side
305  return false;
306  }
307 
308  float rMin=3.; //cm
309  if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
310  //this case means a track that has the tangent point nearby the primary vertex
311  // if the track is primary, this number tends to be the primary vertex itself
312  //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
313  //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
314  return false;
315  }
316 
317  float ptmin = 0.5;
318  float originRBound = 3;
319  float originZBound = 3.;
320 
321  GlobalPoint originPos;
325  );
326  float cotTheta;
329  }else{
331  cotTheta=99999.f;
332  else
333  cotTheta=-99999.f;
334  }
335  GlobalVector originBounds(originRBound,originRBound,originZBound);
336 
337  GlobalPoint pvtxPoint(primaryVertexPoint.x(),
338  primaryVertexPoint.y(),
339  primaryVertexPoint.z()
340  );
341 
342  ConversionRegion convRegion(originPos, pvtxPoint, cotTheta, track->thetaError(), -1*track->charge());
343 
344 #ifdef debugTSPFSLA
345  ss << "\nConversion Point " << originPos << " " << originPos.perp() << "\n";
346 #endif
347 
348  const OrderedSeedingHits & hitss = theHitsGenerator->run(convRegion, region, *myEvent, *myEsetup);
349 
350  unsigned int nHitss = hitss.size();
351 
352  if(nHitss==0)
353  return false;
354 
355 #ifdef debugTSPFSLA
356  ss << "\n nHitss " << nHitss << "\n";
357 #endif
358 
359  if (seedCollection->empty()) seedCollection->reserve(nHitss); // don't do multiple reserves in the case of multiple regions: it would make things even worse
360  // as it will cause N re-allocations instead of the normal log(N)/log(2)
361  for (unsigned int iHits = 0; iHits < nHitss; ++iHits) {
362 
363 #ifdef debugTSPFSLA
364  ss << "\n iHits " << iHits << "\n";
365 #endif
366  const SeedingHitSet & hits = hitss[iHits];
367  theSeedCreator->trajectorySeed(*seedCollection, hits, originPos, originBounds, ptmin, *myEsetup,convRegion.cotTheta(),ss);
368  }
369  return true;
370 }
371 
372 
T getParameter(std::string const &) const
void setData(const reco::Track *track, const math::XYZVector &refPoint=math::XYZVector(0, 0, 0))
int i
Definition: DBlmapReader.cc:9
PhotonConversionTrajectorySeedProducerFromSingleLegAlgo(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
T perp() const
Definition: PV3DBase.h:72
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:449
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
assert(m_qm.get())
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:13
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:580
math::XYZVector GetMomentumAtTangentPoint() const
return((rh^lh)&mask)
#define unlikely(x)
U second(std::pair< T, U > const &p)
bool isNotFinite(T x)
Definition: isFinite.h:10
math::XYZVector GetTangentPoint() const
std::vector< TrajectorySeed > TrajectorySeedCollection
CovarianceMatrix covariance() const
return track covariance matrix
Definition: TrackBase.h:684
T sqrt(T t)
Definition: SSEVec.h:48
double pt() const
track transverse momentum
Definition: TrackBase.h:574
T z() const
Definition: PV3DBase.h:64
size_t tooManyClusters(const edm::Event &e) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
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:75
bool inspectTrack(const reco::Track *track, const TrackingRegion &region, math::XYZPoint &primaryVertexPoint)
tuple conf
Definition: dbtoconf.py:185
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:592
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:562
double dzError() const
error on dz
Definition: TrackBase.h:767
double vz() const
z coordinate of the reference point on track
Definition: TrackBase.h:622
void loopOnPriVtx(const reco::Track &tk, const std::vector< reco::Vertex > &selectedPriVtxCompatibleWithTrack)
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
const T & get() const
Definition: EventSetup.h:55
T const * product() const
Definition: ESHandle.h:86
double b
Definition: hdecay.h:120
virtual std::string print() const
double ptmin
Definition: HydjetWrapper.h:85
double vy() const
y coordinate of the reference point on track
Definition: TrackBase.h:616
std::unique_ptr< CombinedHitPairGeneratorForPhotonConversion > theHitsGenerator
double a
Definition: hdecay.h:121
Square< F >::type sqr(const F &f)
Definition: Square.h:13
int charge() const
track electric charge
Definition: TrackBase.h:520
volatile std::atomic< bool > shutdown_flag false
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
bool selectPriVtxCompatibleWithTrack(const reco::Track &tk, std::vector< reco::Vertex > &selectedPriVtxCompatibleWithTrack)
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:586
double vx() const
x coordinate of the reference point on track
Definition: TrackBase.h:610
double thetaError() const
error on theta
Definition: TrackBase.h:725