CMS 3D CMS Logo

CosmicTrackSplitter.cc
Go to the documentation of this file.
5 
8 
14 
21 
22 // added by me
23 
30 
36 
38 
41 
43 
47 
51 
52 #include <boost/regex.hpp>
53 
75 namespace reco {
76  namespace modules {
78  public:
79  CosmicTrackSplitter(const edm::ParameterSet &iConfig);
80  void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override;
81 
82  private:
86  size_t minimumHits_;
87 
93 
94  double dZcut_;
95  double dXYcut_;
96 
97  std::vector<uint32_t> detsToIgnore_;
98 
103 
105  std::vector<TrackingRecHit *>::iterator hitsBegin,
106  std::vector<TrackingRecHit *>::iterator hitsEnd);
107 
108  }; // class
109 
111  : minimumHits_(iConfig.getParameter<uint32_t>("minimumHits")),
112  replaceWithInactiveHits_(iConfig.getParameter<bool>("replaceWithInactiveHits")),
113  stripFrontInvalidHits_(iConfig.getParameter<bool>("stripFrontInvalidHits")),
114  stripBackInvalidHits_(iConfig.getParameter<bool>("stripBackInvalidHits")),
115  stripAllInvalidHits_(iConfig.getParameter<bool>("stripAllInvalidHits")),
116  excludePixelHits_(iConfig.getParameter<bool>("excludePixelHits")),
117  dZcut_(iConfig.getParameter<double>("dzCut")),
118  dXYcut_(iConfig.getParameter<double>("dxyCut")),
119  detsToIgnore_(iConfig.getParameter<std::vector<uint32_t> >("detsToIgnore")) {
120  // sanity check
122  throw cms::Exception("Configuration") << "Inconsistent Configuration: you can't set both 'stripAllInvalidHits' "
123  "and 'replaceWithInactiveHits' to true\n";
124  }
125  tokenTracks = consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("tracks"));
127  consumes<TrajTrackAssociationCollection>(iConfig.getParameter<edm::InputTag>("tjTkAssociationMapTag"));
128  tokenGeometry = esConsumes<TrackerGeometry, TrackerDigiGeometryRecord>();
129  tokenMagField = esConsumes<MagneticField, IdealMagneticFieldRecord>();
130 
131  LogDebug("CosmicTrackSplitter") << "sanity check";
132 
133  // sort detids to ignore
134  std::sort(detsToIgnore_.begin(), detsToIgnore_.end());
135 
136  totalTracks_ = 0;
137 
138  // issue the produce<>
139  produces<TrackCandidateCollection>();
140  }
141 
143  LogDebug("CosmicTrackSplitter") << "IN THE SPLITTER!!!!!";
144 
145  // read with View, so we can read also a TrackRefVector
147  iEvent.getByToken(tokenTracks, tracks);
148 
149  // also need trajectories ...
150  // Retrieve trajectories and tracks from the event
151  // -> merely skip if collection is empty
153  iEvent.getByToken(tokenTrajTrack, m_TrajTracksMap);
154 
155  // read from EventSetup
158 
159  // prepare output collection
160  auto output = std::make_unique<TrackCandidateCollection>();
161  output->reserve(tracks->size());
162 
163  // working area and tools
164  std::vector<TrackingRecHit *> hits;
165 
166  // Form pairs of trajectories and tracks
167  //ConstTrajTrackPairCollection trajTracks;
168  LogDebug("CosmicTrackSplitter") << "size of map: " << m_TrajTracksMap->size();
169  int HITTOSPLITFROM = 0;
170  for (TrajTrackAssociationCollection::const_iterator iPair = m_TrajTracksMap->begin();
171  iPair != m_TrajTracksMap->end();
172  iPair++) {
173  const Trajectory *trajFromMap = &(*(*iPair).key);
174  const reco::Track *trackFromMap = &(*(*iPair).val);
175 
176  // loop to find the hit to split from (by taking dot product of pT and transverse position
177  std::vector<TrajectoryMeasurement> measurements = trajFromMap->measurements();
178  int totalNumberOfHits = measurements.size();
179  int numberOfHits = 0;
180  double previousDotProduct = 0;
181  for (trackingRecHit_iterator ith = trackFromMap->recHitsBegin(), edh = trackFromMap->recHitsEnd(); ith != edh;
182  ++ith) {
183  GlobalVector stateMomentum = measurements[numberOfHits].forwardPredictedState().globalMomentum();
184  GlobalPoint statePosition = measurements[numberOfHits].forwardPredictedState().globalPosition();
185  double dotProduct = stateMomentum.x() * statePosition.x() + stateMomentum.y() * statePosition.y();
186  if (dotProduct * previousDotProduct < 0) {
187  //found hit to split from...
188  HITTOSPLITFROM = numberOfHits;
189  }
190 
191  previousDotProduct = dotProduct;
192  numberOfHits++;
193  }
194  LogDebug("CosmicTrackSplitter") << "number of rechits: " << numberOfHits;
195 
196  // check if the trajectories and rechits are in reverse order...
197  trackingRecHit_iterator bIt = trackFromMap->recHitsBegin();
198  trackingRecHit_iterator fIt = trackFromMap->recHitsEnd() - 1;
199  const TrackingRecHit *bHit = (*bIt);
200  const TrackingRecHit *fHit = (*fIt);
201  // hit type valid = 0, missing = 1, inactive = 2, bad = 3
202  if (bHit->type() != 0 || bHit->isValid() != 1) {
203  //loop over hits forwards until first Valid hit is found
205  for (ihit = trackFromMap->recHitsBegin(); ihit != trackFromMap->recHitsEnd(); ++ihit) {
206  const TrackingRecHit *iHit = (*ihit);
207  if (iHit->type() == 0 && iHit->isValid() == 1) {
208  bHit = iHit;
209  break;
210  }
211  }
212  }
213  DetId bdetid = bHit->geographicalId();
214  GlobalPoint bPosHit = theGeometry->idToDetUnit(bdetid)->surface().toGlobal(bHit->localPosition());
215  if (fHit->type() != 0 || fHit->isValid() != 1) {
216  //loop over hits backwards until first Valid hit is found
218  for (ihitf = trackFromMap->recHitsEnd() - 1; ihitf != trackFromMap->recHitsBegin(); --ihitf) {
219  const TrackingRecHit *iHit = (*ihitf);
220  if (iHit->type() == 0 && iHit->isValid() == 1) {
221  fHit = iHit;
222  break;
223  }
224  }
225  }
226  DetId fdetid = fHit->geographicalId();
227  GlobalPoint fPosHit = theGeometry->idToDetUnit(fdetid)->surface().toGlobal(fHit->localPosition());
228  GlobalPoint bPosState = measurements[0].updatedState().globalPosition();
229  GlobalPoint fPosState = measurements[measurements.size() - 1].updatedState().globalPosition();
230  bool trajReversedFlag = false;
231  /*
232  DetId bdetid = bHit->geographicalId();
233  DetId fdetid = fHit->geographicalId();
234  GlobalPoint bPosHit = theGeometry->idToDetUnit( bdetid )->surface().toGlobal(bHit->localPosition());
235  GlobalPoint fPosHit = theGeometry->idToDetUnit( fdetid )->surface().toGlobal(fHit->localPosition());
236  GlobalPoint bPosState = measurements[0].updatedState().globalPosition();
237  GlobalPoint fPosState = measurements[measurements.size() - 1].updatedState().globalPosition();
238  bool trajReversedFlag = false;
239  */
240  if (((bPosHit - bPosState).mag() > (bPosHit - fPosState).mag()) &&
241  ((fPosHit - fPosState).mag() > (fPosHit - bPosState).mag())) {
242  trajReversedFlag = true;
243  }
244  if (trajReversedFlag) {
245  int temp = HITTOSPLITFROM;
246  HITTOSPLITFROM = totalNumberOfHits - temp;
247  }
248  }
249 
250  totalTracks_ = totalTracks_ + tracks->size();
251  // loop on tracks
252  for (std::vector<reco::Track>::const_iterator itt = tracks->begin(), edt = tracks->end(); itt != edt; ++itt) {
253  hits.clear(); // extra safety
254 
255  LogDebug("CosmicTrackSplitter") << "ntracks: " << tracks->size();
256 
257  // try to find distance of closest approach
258  GlobalPoint v(itt->vx(), itt->vy(), itt->vz());
259 
260  //checks on impact parameter
261  bool continueWithTrack = true;
262  if (fabs(v.z()) > dZcut_)
263  continueWithTrack = false;
264  if (v.perp() > dXYcut_)
265  continueWithTrack = false;
266  if (continueWithTrack == false)
267  return;
268 
269  // LOOP TWICE, ONCE FOR TOP AND ONCE FOR BOTTOM
270  for (int i = 0; i < 2; ++i) {
271  hits.clear(); // extra safety
272  LogDebug("CosmicTrackSplitter") << " loop on hits of track #" << (itt - tracks->begin());
273  int usedHitCtr = 0;
274  int hitCtr = 0;
275  for (trackingRecHit_iterator ith = itt->recHitsBegin(), edh = itt->recHitsEnd(); ith != edh; ++ith) {
276  //hitCtr++;
277  const TrackingRecHit *hit = (*ith); // ith is an iterator on edm::Ref to rechit
278  LogDebug("CosmicTrackSplitter") << " hit number " << (ith - itt->recHitsBegin());
279  // let's look at valid hits
280  if (hit->isValid()) {
281  LogDebug("CosmicTrackSplitter") << " valid, detid = " << hit->geographicalId().rawId();
282  DetId detid = hit->geographicalId();
283 
284  if (detid.det() == DetId::Tracker) { // check for tracker hits
285  LogDebug("CosmicTrackSplitter") << " valid, tracker ";
286  bool verdict = false;
287 
288  //trying to get the global position of the hit
289  //const GeomDetUnit* geomDetUnit = theGeometry->idToDetUnit( detid ).;
290 
291  const GlobalPoint pos = theGeometry->idToDetUnit(detid)->surface().toGlobal(hit->localPosition());
292  LogDebug("CosmicTrackSplitter") << "hit pos: " << pos << ", dca pos: " << v;
293 
294  // top half
295  if ((i == 0) && (hitCtr < HITTOSPLITFROM)) {
296  verdict = true;
297  LogDebug("CosmicTrackSplitter") << "tophalf";
298  }
299  // bottom half
300  if ((i == 1) && (hitCtr >= HITTOSPLITFROM)) {
301  verdict = true;
302  LogDebug("CosmicTrackSplitter") << "bottomhalf";
303  }
304 
305  // if the hit is good, check again at module level
306  if (verdict && std::binary_search(detsToIgnore_.begin(), detsToIgnore_.end(), detid.rawId())) {
307  verdict = false;
308  }
309 
310  // if hit is good check to make sure that we are keeping pixel hits
311  if (excludePixelHits_) {
312  // check for pixel hits
313  if ((detid.det() == DetId::Tracker) && ((detid.subdetId() == 1) || (detid.subdetId() == 2))) {
314  verdict = false;
315  }
316  }
317 
318  LogDebug("CosmicTrackSplitter")
319  << " verdict after module list: " << (verdict ? "ok" : "no");
320  if (verdict == true) {
321  // just copy the hit
322  hits.push_back(hit->clone());
323  usedHitCtr++;
324  } else {
325  // still, if replaceWithInactiveHits is true we have to put a new hit
327  hits.push_back(new InvalidTrackingRecHit(*hit->det(), TrackingRecHit::inactive));
328  }
329  }
330  } else { // just copy non tracker hits
331  hits.push_back(hit->clone());
332  }
333  } else {
334  if (!stripAllInvalidHits_) {
335  hits.push_back(hit->clone());
336  }
337  } // is valid hit
338  LogDebug("CosmicTrackSplitter") << " end of hit " << (ith - itt->recHitsBegin());
339  hitCtr++;
340  } // loop on hits
341  LogDebug("CosmicTrackSplitter") << " end of loop on hits of track #" << (itt - tracks->begin());
342 
343  std::vector<TrackingRecHit *>::iterator begin = hits.begin(), end = hits.end();
344 
345  LogDebug("CosmicTrackSplitter") << " selected " << hits.size() << " hits ";
346 
347  // strip invalid hits at the beginning
349  while ((begin != end) && ((*begin)->isValid() == false))
350  ++begin;
351  }
352 
353  LogDebug("CosmicTrackSplitter") << " after front stripping we have " << (end - begin) << " hits ";
354 
355  // strip invalid hits at the end
356  if (stripBackInvalidHits_ && (begin != end)) {
357  --end;
358  while ((begin != end) && ((*end)->isValid() == false))
359  --end;
360  ++end;
361  }
362 
363  LogDebug("CosmicTrackSplitter") << " after back stripping we have " << (end - begin) << " hits ";
364 
365  // if we still have some hits
366  //if ((end - begin) >= int(minimumHits_)) {
367  if (usedHitCtr >= int(minimumHits_)) {
368  output->push_back(makeCandidate(*itt, begin, end));
369  LogDebug("CosmicTrackSplitter") << "we made a candidate of " << hits.size() << " hits!";
370  }
371  // now delete the hits not used by the candidate
372  for (begin = hits.begin(), end = hits.end(); begin != end; ++begin) {
373  if (*begin)
374  delete *begin;
375  }
376  LogDebug("CosmicTrackSplitter")
377  << "loop: " << i << " has " << usedHitCtr << " active hits and " << hits.size() << " total hits...";
378  hits.clear();
379  } // loop twice for top and bottom
380  } // loop on tracks
381  LogDebug("CosmicTrackSplitter") << "totalTracks_ = " << totalTracks_;
382  iEvent.put(std::move(output));
383  }
384 
386  std::vector<TrackingRecHit *>::iterator hitsBegin,
387  std::vector<TrackingRecHit *>::iterator hitsEnd) {
388  LogDebug("CosmicTrackSplitter") << "Making a candidate!";
389 
392  if (pdir == anyDirection)
393  throw cms::Exception("UnimplementedFeature") << "Cannot work with tracks that have 'anyDirecton' \n";
394  //if ( (pdir == alongMomentum) == ( tk.p() >= tk.outerP() ) ) {
395  if ((pdir == alongMomentum) == ((tk.outerPosition() - tk.innerPosition()).Dot(tk.momentum()) >= 0)) {
396  // use inner state
397  TrajectoryStateOnSurface originalTsosIn(
400  } else {
401  // use outer state
402  TrajectoryStateOnSurface originalTsosOut(
405  }
406 
408 
410  ownHits.reserve(hitsEnd - hitsBegin);
411  for (; hitsBegin != hitsEnd; ++hitsBegin) {
412  ownHits.push_back(*hitsBegin);
413  }
414 
415  TrackCandidate cand(ownHits, seed, state, tk.seedRef());
416 
417 #ifdef EDM_ML_DEBUG
418  LogDebug("CosmicTrackSplitter") << " dumping the hits now: ";
419  for (auto const &hit : cand.recHits()) {
420  LogTrace("CosmicTrackSplitter") << " hit detid = " << hit.geographicalId().rawId()
421  << ", type = " << typeid(hit).name();
422  }
423 #endif
424 
425  return cand;
426  }
427 
428  } // namespace modules
429 } // namespace reco
430 
431 // ========= MODULE DEF ==============
434 
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
const TrackerGeomDet * idToDetUnit(DetId) const override
Return the pointer to the GeomDetUnit corresponding to a given DetId.
const math::XYZPoint & outerPosition() const
position of the outermost hit
Definition: Track.h:62
TrajectoryStateOnSurface outerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field, bool withErr=true)
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > tokenGeometry
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > tokenMagField
edm::EDGetTokenT< reco::TrackCollection > tokenTracks
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
TrackCandidate makeCandidate(const reco::Track &tk, std::vector< TrackingRecHit *>::iterator hitsBegin, std::vector< TrackingRecHit *>::iterator hitsEnd)
edm::ESHandle< TrackerGeometry > theGeometry
const edm::RefToBase< TrajectorySeed > & seedRef() const
Definition: Track.h:155
PropagationDirection
#define LogTrace(id)
DataContainer const & measurements() const
Definition: Trajectory.h:178
const_iterator end() const
last iterator over the map (read only)
size_type size() const
map size
void push_back(D *&d)
Definition: OwnVector.h:326
int iEvent
Definition: GenABIO.cc:224
bool isValid() const
Type type() const
edm::ESHandle< MagneticField > theMagField
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:91
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
unsigned int innerDetId() const
DetId of the detector on which surface the innermost state is located.
Definition: Track.h:82
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:88
edm::EDGetTokenT< TrajTrackAssociationCollection > tokenTrajTrack
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< float >, ROOT::Math::GlobalCoordinateSystemTag > GlobalVector
vector in glovbal coordinate system
Definition: Vector3D.h:28
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:79
Definition: DetId.h:17
const PropagationDirection & seedDirection() const
direction of how the hits were sorted in the original seed
Definition: Track.h:148
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
DetId geographicalId() const
unsigned int outerDetId() const
DetId of the detector on which surface the outermost state is located.
Definition: Track.h:79
const Vector & momentum() const
track momentum vector
Definition: TrackBase.h:664
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float >, ROOT::Math::GlobalCoordinateSystemTag > GlobalPoint
point in global coordinate system
Definition: Point3D.h:18
const_iterator begin() const
first iterator over the map (read only)
fixed size matrix
CosmicTrackSplitter(const edm::ParameterSet &iConfig)
Definition: output.py:1
virtual LocalPoint localPosition() const =0
const math::XYZPoint & innerPosition() const
position of the innermost hit
Definition: Track.h:56
def move(src, dest)
Definition: eostools.py:511
void reserve(size_t)
Definition: OwnVector.h:320
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
TrajectoryStateOnSurface innerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field, bool withErr=true)
#define LogDebug(id)