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