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 
101  seedCollection = nullptr;
102 
103 }
104 
105 
108 
109  //--- Get Tracks
111 
112  if(trackCollectionH.isValid()==0){
113  edm::LogError("MissingInput")<<" could not find track collecion in PhotonConversionTrajectorySeedProducerFromSingleLegAlgo";
114  return;
115  }
116 
117  size_t idx=0, sel=0;
119 
120 #ifdef debugTSPFSLA
121  ss.str("");
122 #endif
123 
124  for( reco::TrackCollection::const_iterator tr = trackCollectionH->begin();
125  tr != trackCollectionH->end(); tr++, idx++) {
126 
127 
128  if(rejectTrack(*tr)) continue;
129  std::vector<reco::Vertex> selectedPriVtxCompatibleWithTrack;
131  selectedPriVtxCompatibleWithTrack.push_back(*(vertexHandle->begin())); //Same approach as before
132  }else{
133  if(!selectPriVtxCompatibleWithTrack(*tr,selectedPriVtxCompatibleWithTrack)) continue;
134  }
135 
136  sel++;
137  loopOnPriVtx(*tr,selectedPriVtxCompatibleWithTrack);
138  }
139 #ifdef debugTSPFSLA
140  edm::LogInfo("debugTrajSeedFromSingleLeg") << ss.str();
141  edm::LogInfo("debugTrajSeedFromSingleLeg") << "Inspected " << sel << " tracks over " << idx << " tracks. \t # tracks providing at least one seed " << _countSeedTracks ;
142 #endif
143 }
144 
146 selectPriVtxCompatibleWithTrack(const reco::Track& tk, std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack){
147 
148  std::vector< std::pair< double, short> > idx;
149  short count=-1;
150 
151  double cosPhi=tk.px()/tk.pt();
152  double sinPhi=tk.py()/tk.pt();
153  double sphi2=tk.covariance(2,2);
154  double stheta2=tk.covariance(1,1);
155 
156  for ( const reco::Vertex& vtx : *vertexHandle){
157  count++;
158  if(vtx.ndof()<= _vtxMinDoF) continue;
159 
160  double _dz= tk.dz(vtx.position());
161  double _dzError=tk.dzError();
162 
163  double cotTheta=tk.pz()/tk.pt();
164  double dx = vtx.position().x();
165  double dy = vtx.position().y();
166  double sx2=vtx.covariance(0,0);
167  double sy2=vtx.covariance(1,1);
168 
169  double sxy2= sqr(cosPhi*cotTheta)*sx2+
170  sqr(sinPhi*cotTheta)*sy2+
171  sqr(cotTheta*(-dx*sinPhi+dy*cosPhi))*sphi2+
172  sqr((1+cotTheta*cotTheta)*(dx*cosPhi+dy*sinPhi))*stheta2;
173 
174  _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.
175 
176 #ifdef debugTSPFSLA
177  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;
178 #endif
179 
180  if(fabs(_dz)/_dzError > _maxDZSigmas) continue;
181 
182  idx.push_back(std::pair<double,short>(fabs(_dz),count));
183  }
184  if(idx.size()==0) {
185 #ifdef debugTSPFSLA
186  ss << "no vertex selected " << std::endl;
187 #endif
188  return false;
189 }
190 
191  std::stable_sort(idx.begin(),idx.end(), [](std::pair<double,short> a, std::pair<double,short> b) { return a.first<b.first; });
192 
193  for(size_t i=0;i<_maxNumSelVtx && i<idx.size();++i){
194  selectedPriVtxCompatibleWithTrack.push_back((*vertexHandle)[idx[i].second]);
195 #ifdef debugTSPFSLA
196  ss << "selected vtx dz " << idx[0].first << " position" << idx[0].second << std::endl;
197 #endif
198  }
199 
200  return true;
201 }
202 
204 loopOnPriVtx(const reco::Track& tk, const std::vector<reco::Vertex>& selectedPriVtxCompatibleWithTrack){
205 
206  bool foundAtLeastASeedCand=false;
207  for (auto const & vtx : selectedPriVtxCompatibleWithTrack){
208 
209  math::XYZPoint primaryVertexPoint=math::XYZPoint(vtx.position());
210 
211  for (IR ir=regions.begin(), irEnd=regions.end(); ir < irEnd; ++ir) {
212  const TrackingRegion & region = **ir;
213 
214 #ifdef debugTSPFSLA
215  ss << "[PrintRegion] " << region.print() << std::endl;
216 #endif
217 
218  //This if is just for the _countSeedTracks. otherwise
219  //inspectTrack(&tk,region, primaryVertexPoint);
220  //would be enough
221 
222  if(
223  inspectTrack(&tk,region, primaryVertexPoint)
224  and
225  !foundAtLeastASeedCand
226  ){
227  foundAtLeastASeedCand=true;
228  _countSeedTracks++;
229  }
230 
231  }
232  }
233 }
234 
236 rejectTrack(const reco::Track& track){
237 
240  beamSpot = math::XYZVector(recoBeamSpotHandle->position());
241 
242  _IdealHelixParameters.setData(&track,beamSpot);
244  //this case means a null results on the _IdealHelixParameters side
245  return true;
246  }
247 
248  float rMin=2.; //cm
249  if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
250  //this case means a track that has the tangent point nearby the primary vertex
251  // if the track is primary, this number tends to be the primary vertex itself
252  //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
253  //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
254  return true;
255  }
256  }
257 
258  //-------------------------------------------------------
259  /*
260  float maxPt2=64.; //Cut on pt^2 Indeed doesn't do almost nothing
261  if(track.momentum().Perp2() > maxPt2)
262  return true;
263  */
264  //-------------------------------------------------------
265  //Cut in the barrel eta region FIXME: to be extended to endcaps
266  /*
267  float maxEta=1.3;
268  if(fabs(track.eta()) > maxEta)
269  return true;
270  */
271  //-------------------------------------------------------
272  //Reject tracks that have a first valid hit in the pixel barrel/endcap layer/disk 1
273  //assume that the hits are aligned along momentum
274  /*
275  const reco::HitPattern& p=track.hitPattern();
276  for (int i=0; i<p.numberOfHits(); i++) {
277  uint32_t hit = p.getHitPattern(i);
278  // if the hit is valid and in pixel barrel, print out the layer
279  if (! p.validHitFilter(hit) ) continue;
280  if( (p.pixelBarrelHitFilter(hit) || p.pixelEndcapHitFilter(hit))
281  &&
282  p.getLayer(hit) == 1
283  )
284  return true;
285  else
286  break; //because the first valid hit is in a different layer
287  }
288  */
289  //-------------------------------------------------------
290 
291 
292  return false;
293 }
294 
295 
297 inspectTrack(const reco::Track* track, const TrackingRegion & region, math::XYZPoint& primaryVertexPoint){
298 
299  _IdealHelixParameters.setData(track,primaryVertexPoint);
300 
303  //this case means a null results on the _IdealHelixParameters side
304  return false;
305  }
306 
307  float rMin=3.; //cm
308  if(_IdealHelixParameters.GetTangentPoint().rho()<rMin){
309  //this case means a track that has the tangent point nearby the primary vertex
310  // if the track is primary, this number tends to be the primary vertex itself
311  //Rejecting all the potential photon conversions having a "vertex" inside the beampipe
312  //We should not miss too much, seen that the conversions at the beam pipe are the better reconstructed
313  return false;
314  }
315 
316  float ptmin = 0.5;
317  float originRBound = 3;
318  float originZBound = 3.;
319 
320  GlobalPoint originPos;
324  );
325  float cotTheta;
328  }else{
330  cotTheta=99999.f;
331  else
332  cotTheta=-99999.f;
333  }
334  GlobalVector originBounds(originRBound,originRBound,originZBound);
335 
336  GlobalPoint pvtxPoint(primaryVertexPoint.x(),
337  primaryVertexPoint.y(),
338  primaryVertexPoint.z()
339  );
340 
341  ConversionRegion convRegion(originPos, pvtxPoint, cotTheta, track->thetaError(), -1*track->charge());
342 
343 #ifdef debugTSPFSLA
344  ss << "\nConversion Point " << originPos << " " << originPos.perp() << "\n";
345 #endif
346 
347  const OrderedSeedingHits & hitss = theHitsGenerator->run(convRegion, region, *myEvent, *myEsetup);
348 
349  unsigned int nHitss = hitss.size();
350 
351  if(nHitss==0)
352  return false;
353 
354 #ifdef debugTSPFSLA
355  ss << "\n nHitss " << nHitss << "\n";
356 #endif
357 
358  if (seedCollection->empty()) seedCollection->reserve(nHitss); // don't do multiple reserves in the case of multiple regions: it would make things even worse
359  // as it will cause N re-allocations instead of the normal log(N)/log(2)
360  for (unsigned int iHits = 0; iHits < nHitss; ++iHits) {
361 
362 #ifdef debugTSPFSLA
363  ss << "\n iHits " << iHits << "\n";
364 #endif
365  const SeedingHitSet & hits = hitss[iHits];
366  theSeedCreator->trajectorySeed(*seedCollection, hits, originPos, originBounds, ptmin, *myEsetup,convRegion.cotTheta(),ss);
367  }
368  return true;
369 }
370 
371 
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:462
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: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:622
math::XYZVector GetMomentumAtTangentPoint() const
#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:726
T sqrt(T t)
Definition: SSEVec.h:18
double pt() const
track transverse momentum
Definition: TrackBase.h:616
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)
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:634
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:604
double dzError() const
error on dz
Definition: TrackBase.h:809
double vz() const
z coordinate of the reference point on track
Definition: TrackBase.h:664
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:56
T const * product() const
Definition: ESHandle.h:86
double b
Definition: hdecay.h:120
virtual std::string print() const
return(e1-e2)*(e1-e2)+dp *dp
double ptmin
Definition: HydjetWrapper.h:90
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:121
Square< F >::type sqr(const F &f)
Definition: Square.h:13
int charge() const
track electric charge
Definition: TrackBase.h:562
volatile std::atomic< bool > shutdown_flag false
bool selectPriVtxCompatibleWithTrack(const reco::Track &tk, std::vector< reco::Vertex > &selectedPriVtxCompatibleWithTrack)
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:628
double vx() const
x coordinate of the reference point on track
Definition: TrackBase.h:652
double thetaError() const
error on theta
Definition: TrackBase.h:767