CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TrackClusterSplitter.cc
Go to the documentation of this file.
6 
15 
18 
29 
30 //added for my stuff H.S.
34 
35 // gavril: the template header files
41 
46 
51 
52 // for strip sim splitting
55 
56 #include <boost/range.hpp>
57 #include <boost/foreach.hpp>
58 #include "boost/multi_array.hpp"
59 
60 #include <iostream>
61 using namespace std;
62 
64 {
65 
66 public:
67  TrackClusterSplitter(const edm::ParameterSet& iConfig) ;
69  void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override ;
70 
71 private:
74 
79 
80  // Template splitting needs to know the track direction.
81  // We can use either straight tracks, pixel tracks of fully reconstructed track.
82  // Straight tracks go from the first pixel verterx in the pixel vertex collection
83  // to the cluster center of charge (we use pixel vertices because track vertices are
84  // are not available at this point)
85  // If we set useStraightTracks_ = True, then straight tracks are used
87 
88  // If straight track approximation is not used (useStraightTracks_ = False), then, one can use either fully
89  // reconstructed tracks (useTrajectories_ = True) or pixel tracks ((useTrajectories_ = False).
90  // The use of either straight or fully reconstructed tracks give very similar performance. Use straight tracks
91  // by default because it's faster and less involved. Pixel tracks DO NOT work.
93 
94  // These are either "generalTracks", if useTrajectories_ = True, or "pixelTracks" if useTrajectories_ = False
97 
98  // This is the pixel primary vertex collection
100 
103 
104  // gavril : what is this for ?
109 
110  // This is needed if we want to to sim/truth pixel splitting
112 
113  // This is needed if we want to to sim/truth strip splitting
115 
116 
117  // Template declarations
118  // Pixel templates
121  // Strip template
123 
124  // A pointer to a track and a state on the detector
126  {
128  track(aTrack), state(aState) {}
131  };
132 
133  // A pointer to a cluster and a list of tracks on it
134  template<typename Cluster>
136  {
137  ClusterWithTracks(const Cluster &c) : cluster(&c) {}
138  const Cluster* cluster;
139  std::vector<TrackAndState> tracks;
140  };
141 
144 
145 
146  // a subset of a vector, but with vector-like interface.
147  typedef boost::sub_range<std::vector<SiPixelClusterWithTracks> > SiPixelClustersWithTracks;
148  typedef boost::sub_range<std::vector<SiStripClusterWithTracks> > SiStripClustersWithTracks;
149 
150 
151  // sim strip split
152  typedef std::pair<uint32_t, EncodedEventId> SimHitIdpr;
154 
155  template<typename C>
156  static const C* getCluster(const TrackingRecHit* hit) ;
157 
158  template<typename C>
159  static const C* equalClusters(const C &c1, const C &c2)
160  {
161  return nullptr;
162  }
163 
164  // Find a rechit in a vector of ClusterWithTrack
165  template<typename Cluster> class FindCluster
166  {
167 
168  public:
169 
170  FindCluster(const TrackingRecHit* hit) : toFind_( getCluster<Cluster>(hit) ) { }
171 
173  {
174  assert(test.cluster); // make sure this is not 0
175  return test.cluster == toFind_ || equalClusters<Cluster>(*test.cluster, *toFind_);
176  }
177 
178  private:
179 
180  const Cluster* toFind_;
181 
182  };
183 
184  // Attach tracks to cluster ?!?!
185  template<typename Cluster>
186  void markClusters(std::map<uint32_t, boost::sub_range<std::vector<ClusterWithTracks<Cluster> > > >& map,
187  const TrackingRecHit* hit,
188  const reco::Track* track,
189  const TrajectoryStateOnSurface& tsos) const ;
190 
191  template<typename Cluster>
192  std::auto_ptr<edmNew::DetSetVector<Cluster> >
193  splitClusters(const std::map<uint32_t,
194  boost::sub_range<std::vector<ClusterWithTracks<Cluster> > > > &input,
195  const reco::Vertex &vtx) const ;
196 
197  template<typename Cluster>
198  void splitCluster(const ClusterWithTracks<Cluster> &cluster,
199  const GlobalVector &dir,
201  DetId detId) const ;
202 
204  std::vector<SiPixelClusterWithTracks> allSiPixelClusters;
205  std::map<uint32_t, SiPixelClustersWithTracks> siPixelDetsWithClusters;
206 
207  std::vector<SiStripClusterWithTracks> allSiStripClusters;
208  std::map<uint32_t, SiStripClustersWithTracks> siStripDetsWithClusters;
209 
210 
211 };
212 
213 template<> const SiPixelCluster * TrackClusterSplitter::getCluster<SiPixelCluster>(const TrackingRecHit *hit) ;
214 
215 template<>
216 void TrackClusterSplitter::splitCluster<SiPixelCluster> (const SiPixelClusterWithTracks &cluster,
217  const GlobalVector &dir,
219  DetId detId
220  ) const ;
221 
222 template<> const SiStripCluster * TrackClusterSplitter::getCluster<SiStripCluster>(const TrackingRecHit *hit) ;
223 
224 template<>
225 void TrackClusterSplitter::splitCluster<SiStripCluster> (const SiStripClusterWithTracks &cluster,
226  const GlobalVector &dir,
228  DetId detId
229  ) const ;
230 
231 
232 #define foreach BOOST_FOREACH
233 
235  useTrajectories_(iConfig.getParameter<bool>("useTrajectories"))
236 {
237  if (useTrajectories_) {
238  trajTrackAssociations_ = consumes<TrajTrackAssociationCollection>(iConfig.getParameter<edm::InputTag>("trajTrackAssociations"));
239  } else {
240  propagatorName_ = iConfig.getParameter<std::string>("propagator");
241  tracks_ = consumes<std::vector<reco::Track> >(iConfig.getParameter<edm::InputTag>("tracks"));
242  }
243 
244  pixelClusters_ = consumes<edmNew::DetSetVector<SiPixelCluster> >(iConfig.getParameter<edm::InputTag>("pixelClusters"));
245  stripClusters_ = consumes<edmNew::DetSetVector<SiStripCluster> >(iConfig.getParameter<edm::InputTag>("stripClusters"));
246  vertices_ = consumes<std::vector<reco::Vertex> >(iConfig.getParameter<edm::InputTag>("stripClusters"));
247 
248  produces< edmNew::DetSetVector<SiPixelCluster> >();
249 
250  produces< edmNew::DetSetVector<SiStripCluster> >();
251 
252  simSplitPixel_ = (iConfig.getParameter<bool>("simSplitPixel"));
253  simSplitStrip_ = (iConfig.getParameter<bool>("simSplitStrip"));
254  tmpSplitPixel_ = (iConfig.getParameter<bool>("tmpSplitPixel")); // not so nice... you don't want two bool but some switch
255  tmpSplitStrip_ = (iConfig.getParameter<bool>("tmpSplitStrip"));
256 
257  useStraightTracks_ = (iConfig.getParameter<bool>("useStraightTracks"));
258 
259 
260  if ( simSplitPixel_ ) pixeldigisimlinkToken = consumes< edm::DetSetVector<PixelDigiSimLink> >(edm::InputTag("simSiPixelDigis"));
261  if ( simSplitStrip_ ) stripdigisimlinkToken = consumes< edm::DetSetVector<StripDigiSimLink> >(edm::InputTag("simSiStripDigis"));
262 
263 
264 
265  /*
266  cout << "TrackClusterSplitter : " << endl;
267  cout << endl << endl << endl;
268  cout << "(int)simSplitPixel_ = " << (int)simSplitPixel_ << endl;
269  cout << "(int)simSplitStrip_ = " << (int)simSplitStrip_ << endl;
270  cout << "(int)tmpSplitPixel_ = " << (int)tmpSplitPixel_ << endl;
271  cout << "(int)tmpSplitStrip_ = " << (int)tmpSplitStrip_ << endl;
272  cout << "stripClusters_ = " << stripClusters_ << endl;
273  cout << "pixelClusters_ = " << pixelClusters_ << endl;
274  cout << "(int)useTrajectories_ = " << (int)useTrajectories_ << endl;
275  cout << "trajectories_ = " << trajectories_ << endl;
276  cout << "propagatorName_ = " << propagatorName_ << endl;
277  cout << "vertices_ = " << vertices_ << endl;
278  cout << "useStraightTracks_ = " << useStraightTracks_ << endl;
279  cout << endl << endl << endl;
280  */
281 
282  // Load template; 40 for barrel and 41 for endcaps
283  templ_.pushfile( 40 );
284  templ_.pushfile( 41 );
285  templ2D_.pushfile( 40 );
286  templ2D_.pushfile( 41 );
287 
288  // Load strip templates
289  strip_templ_.pushfile( 11 );
290  strip_templ_.pushfile( 12 );
291  strip_templ_.pushfile( 13 );
292  strip_templ_.pushfile( 14 );
293  strip_templ_.pushfile( 15 );
294  strip_templ_.pushfile( 16 );
295 
296 }
297 
298 
299 template<>
300 const SiStripCluster*
301 TrackClusterSplitter::getCluster<SiStripCluster>(const TrackingRecHit* hit)
302 {
303  if ( typeid(*hit) == typeid(SiStripRecHit2D) )
304  {
305  return (static_cast<const SiStripRecHit2D &>(*hit)).cluster().get();
306  }
307  else if ( typeid(*hit) == typeid(SiStripRecHit1D) )
308  {
309  return (static_cast<const SiStripRecHit1D &>(*hit)).cluster().get();
310  }
311  else
312  throw cms::Exception("Unsupported") << "Detid of type " << typeid(*hit).name() << " not supported.\n";
313 }
314 
315 template<>
316 const SiPixelCluster*
317 TrackClusterSplitter::getCluster<SiPixelCluster>(const TrackingRecHit* hit)
318 {
319  if ( typeid(*hit) == typeid(SiPixelRecHit) )
320  {
321  return (static_cast<const SiPixelRecHit&>(*hit)).cluster().get();
322  }
323  else
324  throw cms::Exception("Unsupported") << "Detid of type " << typeid(*hit).name() << " not supported.\n";
325 }
326 
328 {
329 }
330 
331 void
333 {
334  using namespace edm;
335 
337 
338  if ( !useTrajectories_ )
339  {
340  iSetup.get<IdealMagneticFieldRecord>().get( magfield_ );
341  iSetup.get<TrackingComponentsRecord>().get( "AnalyticalPropagator", propagator_ );
342  }
343 
344  Handle<edmNew::DetSetVector<SiPixelCluster> > inputPixelClusters;
345  Handle<edmNew::DetSetVector<SiStripCluster> > inputStripClusters;
346 
347  iEvent.getByToken(pixelClusters_, inputPixelClusters);
348 
349  iEvent.getByToken(stripClusters_, inputStripClusters);
350 
351  if(simSplitStrip_)
352  hitAssociator = new TrackerHitAssociator(iEvent);
353 
354 
357 
358 
359  allSiPixelClusters.reserve(inputPixelClusters->dataSize()); // this is important, otherwise push_back invalidates the iterators
360  allSiStripClusters.reserve(inputStripClusters->dataSize()); // this is important, otherwise push_back invalidates the iterators
361 
362 
363  // fill in the list of all tracks
364  foreach(const edmNew::DetSet<SiPixelCluster> &ds, *inputPixelClusters)
365  {
366  std::vector<SiPixelClusterWithTracks>::iterator start = allSiPixelClusters.end();
367  allSiPixelClusters.insert(start, ds.begin(), ds.end());
368 
369  std::vector<SiPixelClusterWithTracks>::iterator end = allSiPixelClusters.end();
371  }
372 
373  foreach(const edmNew::DetSet<SiStripCluster> &ds, *inputStripClusters)
374  {
375  std::vector<SiStripClusterWithTracks>::iterator start = allSiStripClusters.end();
376  allSiStripClusters.insert(start, ds.begin(), ds.end());
377 
378  std::vector<SiStripClusterWithTracks>::iterator end = allSiStripClusters.end();
380  }
381 
382  if ( useTrajectories_ )
383  {
384  // Here use the fully reconstructed tracks to get the track angle
385 
387  iEvent.getByToken(trajTrackAssociations_, trajectories);
388  for ( TrajTrackAssociationCollection::const_iterator it = trajectories->begin(),
389  ed = trajectories->end(); it != ed; ++it )
390  {
391  const Trajectory & traj = *it->key;
392  const reco::Track * tk = &*it->val;
393 
394  if ( traj.measurements().size() != tk->recHitsSize() )
395  throw cms::Exception("Aargh") << "Sizes don't match: traj " << traj.measurements().size()
396  << ", tk " << tk->recHitsSize() << "\n";
397 
398  trackingRecHit_iterator it_hit = tk->recHitsBegin(), ed_hit = tk->recHitsEnd();
399 
400  const Trajectory::DataContainer & tms = traj.measurements();
401 
402  size_t i_hit = 0, last_hit = tms.size()-1;
403 
404  bool first = true, reversed = false;
405 
406  for (; it_hit != ed_hit; ++it_hit, ++i_hit)
407  {
408  // ignore hits with no detid
409 
410  if ((*it_hit)->geographicalId().rawId() == 0)
411  {
412  //cout << "It should never happen that a trackingRecHit has no detector ID !!!!!!!!!!!!!!!!! " << endl;
413  continue;
414  }
415 
416  // if it's the first hit, check the ordering of track vs trajectory
417  if (first)
418  {
419 
420  if ((*it_hit)->geographicalId() == tms[i_hit].recHit()->hit()->geographicalId())
421  {
422  reversed = false;
423  }
424  else if ((*it_hit)->geographicalId() == tms[last_hit-i_hit].recHit()->hit()->geographicalId())
425  {
426  reversed = true;
427  }
428  else
429  {
430  throw cms::Exception("Aargh") << "DetIDs don't match either way :-( \n";
431  }
432  }
433 
434  const TrackingRecHit *hit = it_hit->get();
435  if ( hit == 0 || !hit->isValid() )
436  continue;
437 
438  int subdet = hit->geographicalId().subdetId();
439 
440  if (subdet >= 3)
441  { // strip
442  markClusters<SiStripCluster>(siStripDetsWithClusters, hit, tk, tms[reversed ? last_hit-i_hit : i_hit].updatedState());
443  }
444  else if (subdet >= 1)
445  { // pixel
446  markClusters<SiPixelCluster>(siPixelDetsWithClusters, hit, tk, tms[reversed ? last_hit-i_hit : i_hit].updatedState());
447  }
448  else
449  {
450  edm::LogWarning("HitNotFound") << "Hit of type " << typeid(*hit).name() << ", detid "
451  << hit->geographicalId().rawId() << ", subdet " << subdet;
452  }
453  }
454  }
455  }
456  else
457  {
458  // Here use the pixel tracks to get the track angles
459 
461  iEvent.getByToken(tracks_, tracks);
462  //TrajectoryStateTransform transform;
463  foreach (const reco::Track &track, *tracks)
464  {
466  trackingRecHit_iterator it_hit = track.recHitsBegin(), ed_hit = track.recHitsEnd();
467  for (; it_hit != ed_hit; ++it_hit)
468  {
469  const TrackingRecHit *hit = it_hit->get();
470  if ( hit == 0 || !hit->isValid() )
471  continue;
472 
473  int subdet = hit->geographicalId().subdetId();
474 
475  if ( subdet == 0 )
476  continue;
477 
478  const GeomDet *det = geometry_->idToDet( hit->geographicalId() );
479 
480  if ( det == 0 )
481  {
482  edm::LogError("MissingDetId") << "DetIDs " << (int)(hit->geographicalId()) << " is not in geometry.\n";
483  continue;
484  }
485 
486  TrajectoryStateOnSurface prop = propagator_->propagate(atVtx, det->surface());
487  if ( subdet >= 3 )
488  { // strip
489  markClusters<SiStripCluster>(siStripDetsWithClusters, hit, &track, prop);
490  }
491  else if (subdet >= 1)
492  { // pixel
493  markClusters<SiPixelCluster>(siPixelDetsWithClusters, hit, &track, prop);
494  }
495  else
496  {
497  edm::LogWarning("HitNotFound") << "Hit of type " << typeid(*hit).name() << ", detid "
498  << hit->geographicalId().rawId() << ", subdet " << subdet;
499  }
500  }
501  }
502  }
503 
505  iEvent.getByToken(vertices_, vertices);
506 
507  // Needed in case of simsplit
508  if ( simSplitPixel_ )
510 
511  // Needed in case of strip simsplit
512  if ( simSplitStrip_ )
514 
515  // gavril : to do: choose the best vertex here instead of just choosing the first one ?
516  std::auto_ptr<edmNew::DetSetVector<SiPixelCluster> > newPixelClusters( splitClusters( siPixelDetsWithClusters, vertices->front() ) );
517  std::auto_ptr<edmNew::DetSetVector<SiStripCluster> > newStripClusters( splitClusters( siStripDetsWithClusters, vertices->front() ) );
518 
519  if ( simSplitStrip_ )
520  delete hitAssociator;
521 
522  iEvent.put(newPixelClusters);
523  iEvent.put(newStripClusters);
524 
527 
528 }
529 
530 template<typename Cluster>
531 void TrackClusterSplitter::markClusters( std::map<uint32_t, boost::sub_range<std::vector<ClusterWithTracks<Cluster> > > >& map,
532  const TrackingRecHit* hit,
533  const reco::Track* track,
534  const TrajectoryStateOnSurface& tsos) const
535 {
536  boost::sub_range<std::vector<ClusterWithTracks<Cluster> > >& range = map[hit->geographicalId().rawId()];
537 
538  typedef typename std::vector<ClusterWithTracks<Cluster> >::iterator IT;
539  IT match = std::find_if(range.begin(), range.end(), FindCluster<Cluster>(hit));
540 
541  if ( match != range.end() )
542  {
543  match->tracks.push_back( TrackAndState(track,tsos) );
544  }
545  else
546  {
547  edm::LogWarning("ClusterNotFound") << "Cluster of type " << typeid(Cluster).name() << " on detid "
548  << hit->geographicalId().rawId() << " from hit of type " << typeid(*hit).name();
549  }
550 }
551 
552 template<typename Cluster>
553 std::auto_ptr<edmNew::DetSetVector<Cluster> >
554 TrackClusterSplitter::splitClusters(const std::map<uint32_t, boost::sub_range<std::vector<ClusterWithTracks<Cluster> > > > &input,
555  const reco::Vertex &vtx) const
556 {
557  std::auto_ptr<edmNew::DetSetVector<Cluster> > output(new edmNew::DetSetVector<Cluster>());
558  typedef std::pair<uint32_t, boost::sub_range<std::vector<ClusterWithTracks<Cluster> > > > pair;
559 
560  foreach(const pair &p, input)
561  {
562  const GeomDet* det = geometry_->idToDet( DetId(p.first) );
563 
564  if ( det == 0 )
565  {
566  edm::LogError("MissingDetId") << "DetIDs " << p.first << " is not in geometry.\n";
567  continue;
568  }
569 
570  // gavril: Pass the PV instead of direction
571  // GlobalVector dir(det->position().x() - vtx.x(), det->position().y() - vtx.y(), det->position().z() - vtx.z());
572  GlobalVector primary_vtx( vtx.x(), vtx.y(), vtx.z() );
573 
574  // Create output collection
575  typename edmNew::DetSetVector<Cluster>::FastFiller detset(*output, p.first);
576 
577  // fill it
578  foreach(const ClusterWithTracks<Cluster> &c, p.second)
579  {
580  splitCluster(c, primary_vtx, detset, DetId(p.first) );
581  }
582  }
583 
584  return output;
585 }
586 
587 template<typename Cluster>
589  const GlobalVector &dir,
591  DetId detId) const
592 {
593  //cout << "Should never be here: TrackClusterSplitter, TrackClusterSplitter::splitCluster(...) !!!!!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
594  throw cms::Exception("LogicError", "This should not be called");
595 }
596 
597 template<>
598 void TrackClusterSplitter::splitCluster<SiStripCluster> (const SiStripClusterWithTracks& c,
599  const GlobalVector &vtx,
601  DetId detId
602  ) const
603 {
604  if ( simSplitStrip_ )
605  {
606  bool cluster_was_successfully_split = false;
607 
608  const SiStripCluster* clust = static_cast<const SiStripCluster*>(c.cluster);
609 
610  std::vector<SimHitIdpr> associatedIdpr;
611 
612  hitAssociator->associateSimpleRecHitCluster(clust, detId, associatedIdpr);
613 
614  size_t splittableClusterSize = 0;
615  splittableClusterSize = associatedIdpr.size();
616  std::vector<uint8_t> amp = clust->amplitudes();
617  int clusiz = amp.size();
618  associatedIdpr.clear();
619 
620  SiStripDetId ssdid( detId );
621 
622  // gavril : sim splitting can be applied to the forward detectors as well...
623 
624  if ( ( splittableClusterSize > 1 && amp.size() > 2 ) &&
625  ( (int)ssdid.moduleGeometry() == 1 ||
626  (int)ssdid.moduleGeometry() == 2 ||
627  (int)ssdid.moduleGeometry() == 3 ||
628  (int)ssdid.moduleGeometry() == 4 ) )
629  {
630 
632 
633  int first = clust->firstStrip();
634  int last = first + clusiz;
635  uint16_t rawAmpl = 0, currentAmpl = 0;
636 
637  std::vector<uint16_t> tmp1, tmp2;
638 
639  std::vector<int> firstStrip;
640  std::vector<bool> trackInStrip;
641  std::vector<unsigned int> trackID;
642  std::vector<float> trackFraction;
643  std::vector< std::vector<uint16_t> > trackAmp;
644  unsigned int currentChannel( 9999 );
645  unsigned int thisTrackID = 0;
646 
647  if ( isearch != stripdigisimlink->end() )
648  {
649  edm::DetSet<StripDigiSimLink> link_detset = (*isearch);
650 
651  for ( edm::DetSet<StripDigiSimLink>::const_iterator linkiter = link_detset.data.begin();
652  linkiter != link_detset.data.end(); linkiter++)
653  {
654  if ( (int)(linkiter->channel()) >= first && (int)(linkiter->channel()) < last )
655  {
656  int stripIdx = (int)linkiter->channel()-first;
657  rawAmpl = (uint16_t)(amp[stripIdx]);
658 
659  // DigiSimLinks are ordered first by channel; there can be > 1 track, and > 1 simHit for each track
660 
661  if ( linkiter->channel() != currentChannel )
662  {
663  // New strip; store amplitudes for the previous one
664  uint16_t thisAmpl;
665 
666  for (size_t i=0; i<trackID.size(); ++i)
667  {
668  if ( trackInStrip[i] )
669  {
670  if ( ( thisAmpl=currentAmpl ) < 254 )
671  thisAmpl = min( uint16_t(253), max(uint16_t(0), (uint16_t)(currentAmpl*trackFraction[i]+0.5)) );
672  trackAmp[i].push_back( thisAmpl );
673  }
674 
675  trackFraction[i] = 0;
676  trackInStrip[i] = false;
677  }
678 
679  currentChannel = linkiter->channel();
680  currentAmpl = rawAmpl;
681  }
682 
683  // Now deal with this new DigiSimLink
684  thisTrackID = linkiter->SimTrackId();
685 
686  // Have we seen this track yet?
687  bool newTrack = true;
688  int thisTrackIdx = 9999;
689 
690  for (size_t i=0; i<trackID.size(); ++i)
691  {
692  if ( trackID[i] == thisTrackID )
693  {
694  thisTrackIdx = i;
695  newTrack = false;
696  }
697  }
698 
699  if ( newTrack )
700  {
701  trackInStrip.push_back(false); // We'll set it true below
702  trackID.push_back(thisTrackID);
703  firstStrip.push_back(currentChannel);
704  std::vector<uint16_t> ampTmp;
705  trackAmp.push_back(ampTmp);
706  trackFraction.push_back(0);
707  thisTrackIdx = trackID.size()-1;
708  }
709 
710  trackInStrip[thisTrackIdx] = true;
711  trackFraction[thisTrackIdx] += linkiter->fraction();
712  currentAmpl = rawAmpl;
713 
714  }
715 
716  }// end of loop over DigiSimLinks
717 
718  // we want to continue here!!!!
719 
720  std::vector<SiStripCluster> newCluster;
721  // Fill amplitudes for the last strip and create a cluster for each track
722  uint16_t thisAmpl;
723 
724  for (size_t i=0; i < trackID.size(); ++i)
725  {
726  if ( trackInStrip[i] )
727  {
728  if ( ( thisAmpl=rawAmpl ) < 254 )
729  thisAmpl = min(uint16_t(253), max(uint16_t(0), (uint16_t)(rawAmpl*trackFraction[i]+0.5)));
730 
731  if ( thisAmpl > 0 )
732  trackAmp[i].push_back( thisAmpl );
733  //else
734  //cout << "thisAmpl = " << (int)thisAmpl << endl;
735  }
736 
737  newCluster.push_back( SiStripCluster( detId,
738  firstStrip[i],
739  trackAmp[i].begin(),
740  trackAmp[i].end() ) );
741 
742  }
743 
744 
745  for ( size_t i=0; i<newCluster.size(); ++i )
746  {
747 
748  // gavril : This is never used. Will use it below
749  float clusterAmp = 0.0;
750  for (size_t j=0; j<trackAmp[i].size(); ++j )
751  clusterAmp += (float)(trackAmp[i])[j];
752 
753  if ( clusterAmp > 0.0 && firstStrip[i] != 9999 && trackAmp[i].size() > 0 )
754  {
755  // gavril : I think this should work
756  output.push_back( newCluster[i] );
757 
758  //cout << endl << endl << endl;
759  //cout << "(int)(newCluster[i].amplitudes().size()) = " << (int)(newCluster[i].amplitudes().size()) << endl;
760  //for ( int j=0; j<(int)(newCluster[i].amplitudes().size()); ++j )
761  //cout << "(newCluster[i].amplitudes())[j] = " << (int)(newCluster[i].amplitudes())[j] << endl;
762 
763  cluster_was_successfully_split = true;
764  }
765  else
766  {
767  //std::cout << "\t\t Rejecting new cluster" << std::endl;
768 
769  // gavril : I think this pointer should be deleted above
770  //delete newCluster[i];
771  }
772  }
773 
774  } // if ( isearch != stripdigisimlink->end() ) ...
775  else
776  {
777  // Do nothing...
778  }
779  }
780 
781 
782  if ( !cluster_was_successfully_split )
783  output.push_back( *c.cluster );
784 
785  } // end of if ( strip_simSplit_ )...
786 
787  else if ( tmpSplitStrip_ )
788  {
789  bool cluster_was_successfully_split = false;
790 
791  const SiStripCluster* theStripCluster = static_cast<const SiStripCluster*>(c.cluster);
792 
793  if ( theStripCluster )
794  {
795  //SiStripDetId ssdid( theStripCluster->geographicalId() );
796  SiStripDetId ssdid( detId.rawId() );
797 
798  // Do not attempt to split clusters of size less than or equal to one.
799  // Only split clusters in IB1, IB2, OB1, OB2 (TIB and TOB).
800 
801  if ( (int)theStripCluster->amplitudes().size() <= 1 ||
802  ( (int)ssdid.moduleGeometry() != 1 &&
803  (int)ssdid.moduleGeometry() != 2 &&
804  (int)ssdid.moduleGeometry() != 3 &&
805  (int)ssdid.moduleGeometry() != 4 ) )
806  {
807  // Do nothing.
808  //cout << endl;
809  //cout << "Will NOT attempt to split this clusters: " << endl;
810  //cout << "(int)theStripCluster->amplitudes().size() = " << (int)theStripCluster->amplitudes().size() << endl;
811  //cout << "(int)ssdid.moduleGeometry() = " << (int)ssdid.moduleGeometry() << endl;
812 
813  }
814  else // if ( (int)theStripCluster->amplitudes().size() <= 1 )
815  {
816 
817  //cout << endl;
818  //cout << "Will attempt to split this clusters: " << endl;
819 
820  int ID = -99999;
821 
822  int is_stereo = (int)( ssdid.stereo() );
823 
824  if ( ssdid.moduleGeometry() == 1 ) // IB1
825  {
826  if ( !is_stereo )
827  ID = 11;
828  else
829  ID = 12;
830  }
831  else if ( ssdid.moduleGeometry() == 2 ) // IB2
832  {
833  ID = 13;
834  }
835  else if ( ssdid.moduleGeometry() == 3 ) // OB1
836  {
837  ID = 16;
838  }
839  else if ( ssdid.moduleGeometry() == 4 ) // OB2
840  {
841  if ( !is_stereo )
842  ID = 14;
843  else
844  ID = 15;
845  }
846  else
847  {
848  throw cms::Exception("TrackClusterSplitter::splitCluster")
849  << "\nERROR: Wrong strip teplate ID. Should only use templates for IB1, IB2, OB1 and OB2 !!!" << "\n\n";
850  }
851 
852 
853 
854 
855  // Begin: determine incident angles ============================================================
856 
857  float cotalpha_ = -99999.9;
858  float cotbeta_ = -99999.9;
859 
860  // First, determine track angles from straight track approximation
861 
862  // Find crude cluster center
863  // gavril : This is in local coordinates ?
864  float xcenter = theStripCluster->barycenter();
865 
866  const GeomDetUnit* theDet = geometry_->idToDetUnit( detId );
867  const StripGeomDetUnit* stripDet = dynamic_cast<const StripGeomDetUnit*>( theDet );
868 
869  if ( !stripDet )
870  {
871  throw cms::Exception("TrackClusterSplitter : ")
872  << "\nERROR: Wrong stripDet !!! " << "\n\n";
873  }
874 
875 
876  const StripTopology* theTopol = &( stripDet->specificTopology() );
877 
878  // Transform from measurement to local coordinates (in cm)
879  // gavril: may have to differently if kicks/bows are introduced. However, at this point there are no tracks...:
880  // LocalPoint lp = theTopol->localPosition( xcenter, /*const Topology::LocalTrackPred & */ trkPred );
881 
882  // gavril : What is lp.y() for strips ? It is zero, but is that the strip center or one of the ends ?
883  LocalPoint lp = theTopol->localPosition( xcenter );
884 
885  // Transform from local to global coordinates
886  GlobalPoint gp0 = theDet->surface().toGlobal( lp );
887 
888  // Make a vector pointing from the PV to the cluster center
889  GlobalPoint gp(gp0.x()-vtx.x(), gp0.y()-vtx.y(), gp0.z()-vtx.z() );
890 
891  // Make gp a unit vector, gv, pointing from the PV to the cluster center
892  float gp_mod = sqrt( gp.x()*gp.x() + gp.y()*gp.y() + gp.z()*gp.z() );
893  float gpx = gp.x()/gp_mod;
894  float gpy = gp.y()/gp_mod;
895  float gpz = gp.z()/gp_mod;
896  GlobalVector gv(gpx, gpy, gpz);
897 
898  // Make unit vectors in local coordinates and then transform them in global coordinates
899  const Local3DVector lvx(1.0, 0.0, 0.0);
900  GlobalVector gvx = theDet->surface().toGlobal( lvx );
901  const Local3DVector lvy(0.0, 1.0, 0.0);
902  GlobalVector gvy = theDet->surface().toGlobal( lvy );
903  const Local3DVector lvz(0.0, 0.0, 1.0);
904  GlobalVector gvz = theDet->surface().toGlobal( lvz );
905 
906  // Calculate angles alpha and beta
907  float gv_dot_gvx = gv.x()*gvx.x() + gv.y()*gvx.y() + gv.z()*gvx.z();
908  float gv_dot_gvy = gv.x()*gvy.x() + gv.y()*gvy.y() + gv.z()*gvy.z();
909  float gv_dot_gvz = gv.x()*gvz.x() + gv.y()*gvz.y() + gv.z()*gvz.z();
910 
911  // gavril : check beta !!!!!!!!!!!!
912  //float alpha_ = atan2( gv_dot_gvz, gv_dot_gvx );
913  //float beta_ = atan2( gv_dot_gvz, gv_dot_gvy );
914 
915  cotalpha_ = gv_dot_gvx / gv_dot_gvz;
916  cotbeta_ = gv_dot_gvy / gv_dot_gvz;
917 
918  // Attempt to get a better angle from tracks (either pixel tracks or full tracks)
919  if ( !useStraightTracks_ )
920  {
921  //cout << "TrackClusterSplitter.cc : " << endl;
922  //cout << "Should not be here for now !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
923 
924  // Use either pixel tracks (useTrajectories_ = False) or fully reconstructed tracks (useTrajectories_ = True)
925  // When pixel/full tracks are not associated with the current cluster, will use angles from straight tracks
926 
927  // These are the tracks associated with this cluster
928  std::vector<TrackAndState> vec_tracks_states = c.tracks;
929 
930  if ( (int)vec_tracks_states.size() > 0 )
931  {
932  //cout << "There is at least one track associated with this cluster. Pick the one with largest Pt." << endl;
933  //cout << "(int)vec_tracks_states.size() = " << (int)vec_tracks_states.size() << endl;
934 
935  int index_max_pt = -99999; // index of the track with the highest Pt
936  float max_pt = -99999.9;
937 
938  for (int i=0; i<(int)vec_tracks_states.size(); ++i )
939  {
940  const reco::Track* one_track = vec_tracks_states[i].track;
941 
942  if ( one_track->pt() > max_pt )
943  {
944  index_max_pt = i;
945  max_pt = one_track->pt();
946  }
947  }
948 
949  // Pick the tsos from the track with highest Pt
950  // gavril: Should we use highest Pt or best Chi2 ?
951  TrajectoryStateOnSurface one_tsos = vec_tracks_states[index_max_pt].state;
952 
954 
955  LocalVector localDir = ltp.momentum()/ltp.momentum().mag();
956 
957  float locx = localDir.x();
958  float locy = localDir.y();
959  float locz = localDir.z();
960 
961  //alpha_ = atan2( locz, locx );
962  //beta_ = atan2( locz, locy );
963 
964  cotalpha_ = locx/locz;
965  cotbeta_ = locy/locz;
966 
967  } // if ( (int)vec_tracks_states.size() > 0 )
968 
969  } // if ( !useStraightTracks_ )
970 
971 
972  // End: determine incident angles ============================================================
973 
974 
975  // Calculate strip cluster charge and store amplitudes in vector for later use
976 
977  //cout << endl;
978  //cout << "Calculate strip cluster charge and store amplitudes in vector for later use" << endl;
979 
980  float strip_cluster_charge = 0.0;
981  std::vector<float> vec_cluster_charge;
982  vec_cluster_charge.clear();
983  int cluster_size = (int)( (theStripCluster->amplitudes()).size() );
984 
985  int cluster_charge = 0;
986  for (int i=0; i<cluster_size; ++i)
987  {
988  float current_strip_charge = (float)( (theStripCluster->amplitudes())[i] );
989 
990  strip_cluster_charge += current_strip_charge;
991  vec_cluster_charge.push_back( current_strip_charge );
992 
993  cluster_charge +=current_strip_charge;
994  }
995 
996 
997  //cout << endl;
998  //cout << "Calling strip qbin to see if the strip cluster has to be split..." << endl;
999  int strip_templQbin_ = strip_templ_.qbin( ID, cotalpha_, cotbeta_, strip_cluster_charge );
1000 
1001  if ( strip_templQbin_ < 0 || strip_templQbin_ > 5 )
1002  {
1003  // Do nothing...
1004  // cout << "Wrong strip strip_templQbin_ = " << strip_templQbin_ << endl;
1005  } // if ( strip_templQbin_ < 0 || strip_templQbin_ > 5 )
1006  else // if ( strip_templQbin_ < 0 || strip_templQbin_ > 5 ) {...} else
1007  {
1008  if ( strip_templQbin_ != 0 )
1009  {
1010  // Do not split this cluster. Do nothing.
1011  //cout << endl;
1012  //cout << "Do NOT split this cluster" << endl;
1013 
1014  } // if ( strip_templQbin_ != 0 )
1015  else // if ( templQbin_ != 0 ) {...} else
1016  {
1017  //cout << endl;
1018  //cout << "Split this cluster" << endl;
1019 
1020  // gavril : Is this OK ?
1021  uint16_t first_strip = theStripCluster->firstStrip();
1022 
1023  LocalVector lbfield = ( stripDet->surface() ).toLocal( magfield_->inTesla( stripDet->surface().position() ) );
1024  float locBy = lbfield.y();
1025 
1026  // Initialize values coming back from SiStripTemplateSplit::StripTempSplit
1027  float stripTemplXrec1_ = -99999.9;
1028  float stripTemplXrec2_ = -99999.9;
1029  float stripTemplSigmaX_ = -99999.9;
1030  float stripTemplProbX_ = -99999.9;
1031  int stripTemplQbin_ = -99999;
1032  float stripTemplProbQ_ = -99999.9;
1033 
1034 
1035  /*
1036  cout << endl;
1037  cout << "About to call SiStripTemplateSplit::StripTempSplit(...)" << endl;
1038 
1039  cout << endl;
1040  cout << "ID = " << ID << endl;
1041  cout << "cotalpha_ = " << cotalpha_ << endl;
1042  cout << "cotbeta_ = " << cotbeta_ << endl;
1043  cout << "locBy = " << locBy << endl;
1044  cout << "Amplitudes: ";
1045  for (int i=0; i<(int)vec_cluster_charge.size(); ++i)
1046  cout << vec_cluster_charge[i] << ", ";
1047  cout << endl;
1048  */
1049 
1050  int ierr =
1052  cotalpha_, cotbeta_,
1053  locBy,
1054  vec_cluster_charge,
1055  strip_templ_,
1056  stripTemplXrec1_,
1057  stripTemplXrec2_,
1058  stripTemplSigmaX_,
1059  stripTemplProbX_,
1060  stripTemplQbin_,
1061  stripTemplProbQ_ );
1062 
1063 
1064 
1065  stripTemplXrec1_ += 2*strip_templ_.xsize();
1066  stripTemplXrec2_ += 2*strip_templ_.xsize();
1067 
1068 
1069 
1070  if ( ierr != 0 )
1071  {
1072  //cout << endl;
1073  //cout << "Strip cluster splitting failed: ierr = " << ierr << endl;
1074  }
1075  else // if ( ierr != 0 )
1076  {
1077  // Cluster was successfully split.
1078  // Make the two split clusters and put them in the split cluster collection
1079 
1080  //cout << endl;
1081  //cout << "Cluster was successfully split" << endl;
1082 
1083  cluster_was_successfully_split = true;
1084 
1085  std::vector<float> strip_cluster1;
1086  std::vector<float> strip_cluster2;
1087 
1088  strip_cluster1.clear();
1089  strip_cluster2.clear();
1090 
1091  // gavril : Is this OK ?!?!?!?!
1092  for (int i=0; i<BXSIZE; ++i)
1093  {
1094  strip_cluster1.push_back(0.0);
1095  strip_cluster2.push_back(0.0);
1096  }
1097 
1098  //cout << endl;
1099  //cout << "About to call interpolate and sxtemp" << endl;
1100 
1101  strip_templ_.interpolate(ID, cotalpha_, cotbeta_, locBy);
1102  strip_templ_.sxtemp(stripTemplXrec1_, strip_cluster1);
1103  strip_templ_.sxtemp(stripTemplXrec2_, strip_cluster2);
1104 
1105 
1106 
1107  vector<SiStripDigi> vecSiStripDigi1;
1108  vecSiStripDigi1.clear();
1109  int strip_cluster1_size = (int)strip_cluster1.size();
1110  for (int i=2; i<strip_cluster1_size; ++i)
1111  {
1112  if ( strip_cluster1[i] > 0.0 )
1113  {
1114  SiStripDigi current_digi1( first_strip + i-2, strip_cluster1[i] );
1115 
1116  vecSiStripDigi1.push_back( current_digi1 );
1117  }
1118  }
1119 
1120 
1121 
1122  vector<SiStripDigi> vecSiStripDigi2;
1123  vecSiStripDigi2.clear();
1124  int strip_cluster2_size = (int)strip_cluster2.size();
1125  for (int i=2; i<strip_cluster2_size; ++i)
1126  {
1127  if ( strip_cluster2[i] > 0.0 )
1128  {
1129  SiStripDigi current_digi2( first_strip + i-2, strip_cluster2[i] );
1130 
1131  vecSiStripDigi2.push_back( current_digi2 );
1132  }
1133  }
1134 
1135 
1136 
1137 
1138  std::vector<SiStripDigi>::const_iterator SiStripDigiIterBegin1 = vecSiStripDigi1.begin();
1139  std::vector<SiStripDigi>::const_iterator SiStripDigiIterEnd1 = vecSiStripDigi1.end();
1140  std::pair<std::vector<SiStripDigi>::const_iterator,
1141  std::vector<SiStripDigi>::const_iterator> SiStripDigiRange1
1142  = make_pair(SiStripDigiIterBegin1, SiStripDigiIterEnd1);
1143 
1144  //if ( SiStripDigiIterBegin1 == SiStripDigiIterEnd1 )
1145  //{
1146  // throw cms::Exception("TrackClusterSplitter : ")
1147  //<< "\nERROR: SiStripDigiIterBegin1 = SiStripDigiIterEnd1 !!!" << "\n\n";
1148  //}
1149 
1150  std::vector<SiStripDigi>::const_iterator SiStripDigiIterBegin2 = vecSiStripDigi2.begin();
1151  std::vector<SiStripDigi>::const_iterator SiStripDigiIterEnd2 = vecSiStripDigi2.end();
1152  std::pair<std::vector<SiStripDigi>::const_iterator,
1153  std::vector<SiStripDigi>::const_iterator> SiStripDigiRange2
1154  = make_pair(SiStripDigiIterBegin2, SiStripDigiIterEnd2);
1155 
1156  // Sanity check...
1157  //if ( SiStripDigiIterBegin2 == SiStripDigiIterEnd2 )
1158  //{
1159  // cout << endl;
1160  // cout << "SiStripDigiIterBegin2 = SiStripDigiIterEnd2 !!!!!!!!!!!!!!!" << endl;
1161  //}
1162 
1163 
1164  // Save the split clusters
1165 
1166  if ( SiStripDigiIterBegin1 != SiStripDigiIterEnd1 )
1167  {
1168  // gavril : Raw id ?
1169  SiStripCluster cl1( detId.rawId(), SiStripDigiRange1 );
1170 
1171  cl1.setSplitClusterError( stripTemplSigmaX_ );
1172 
1173  output.push_back( cl1 );
1174 
1175  if ( (int)cl1.amplitudes().size() <= 0 )
1176  {
1177  throw cms::Exception("TrackClusterSplitter : ")
1178  << "\nERROR: (1) Wrong split cluster of size = " << (int)cl1.amplitudes().size() << "\n\n";
1179  }
1180 
1181  } // if ( SiStripDigiIterBegin1 != SiStripDigiIterEnd1 )
1182 
1183  if ( SiStripDigiIterBegin2 != SiStripDigiIterEnd2 )
1184  {
1185  // gavril : Raw id ?
1186  SiStripCluster cl2( detId.rawId(), SiStripDigiRange2 );
1187  cl2.setSplitClusterError( stripTemplSigmaX_ );
1188  output.push_back( cl2 );
1189 
1190  if ( (int)cl2.amplitudes().size() <= 0 )
1191  {
1192  throw cms::Exception("TrackClusterSplitter : ")
1193  << "\nERROR: (2) Wrong split cluster of size = " << (int)cl2.amplitudes().size() << "\n\n";
1194  }
1195 
1196  } // if ( SiStripDigiIterBegin2 != SiStripDigiIterEnd2 )
1197 
1198 
1199 
1200  } // else // if ( ierr != 0 )
1201 
1202  } // else // if ( strip_templQbin_ != 0 ) {...} else
1203 
1204  } // else // if ( strip_templQbin_ < 0 || strip_templQbin_ > 5 ) {...} else
1205 
1206  } // else // if ( (int)theStripCluster->amplitudes().size() <= 1 )
1207 
1208 
1209  if ( !cluster_was_successfully_split )
1210  output.push_back( *c.cluster );
1211 
1212  } // if ( theStripCluster )
1213  else
1214  {
1215  throw cms::Exception("TrackClusterSplitter : ")
1216  << "\nERROR: This is not a SiStripCluster !!!" << "\n\n";
1217  }
1218 
1219  } // else if ( strip_tmpSplit_ )
1220  else
1221  {
1222  // gavril : Neither sim nor template splitter. Just add the cluster as it was.
1223  output.push_back( *c.cluster );
1224  }
1225 }
1226 
1227 template<>
1228 void TrackClusterSplitter::splitCluster<SiPixelCluster> (const SiPixelClusterWithTracks &c,
1229  const GlobalVector &vtx,
1231  DetId detId
1232  ) const
1233 {
1234  // The sim splitter:
1235  if ( simSplitPixel_ )
1236  {
1237  // cout << "Cluster splitting using simhits " << endl;
1238 
1239  int minPixelRow = (*c.cluster).minPixelRow();
1240  int maxPixelRow = (*c.cluster).maxPixelRow();
1241  int minPixelCol = (*c.cluster).minPixelCol();
1242  int maxPixelCol = (*c.cluster).maxPixelCol();
1243  int dsl = 0; // number of digisimlinks
1244 
1246  if (isearch != pixeldigisimlink->end()){
1247  edm::DetSet<PixelDigiSimLink> digiLink = (*isearch);
1248 
1249  edm::DetSet<PixelDigiSimLink>::const_iterator linkiter = digiLink.data.begin();
1250  //create a vector for the track ids in the digisimlinks
1251  std::vector<int> simTrackIdV;
1252  simTrackIdV.clear();
1253  //create a vector for the new splittedClusters
1254  std::vector<SiPixelCluster> splittedCluster;
1255  splittedCluster.clear();
1256 
1257  for ( ; linkiter != digiLink.data.end(); linkiter++)
1258  { // loop over all digisimlinks
1259  dsl++;
1260  std::pair<int,int> pixel_coord = PixelDigi::channelToPixel(linkiter->channel());
1261 
1262  // is the digisimlink inside the cluster boundaries?
1263  if ( pixel_coord.first <= maxPixelRow &&
1264  pixel_coord.first >= minPixelRow &&
1265  pixel_coord.second <= maxPixelCol &&
1266  pixel_coord.second >= minPixelCol )
1267  {
1268  bool inStock(false); // did we see this simTrackId before?
1269 
1270  SiPixelCluster::PixelPos newPixelPos(pixel_coord.first, pixel_coord.second); // coordinates to the pixel
1271 
1272  //loop over the pixels from the cluster to get the charge in this pixel
1273  int newPixelCharge(0); //fraction times charge in the original cluster pixel
1274 
1275  const std::vector<SiPixelCluster::Pixel>& pixvector = (*c.cluster).pixels();
1276 
1277  for(std::vector<SiPixelCluster::Pixel>::const_iterator itPix = pixvector.begin(); itPix != pixvector.end(); itPix++)
1278  {
1279  if (((int) itPix->x) == ((int) pixel_coord.first)&&(((int) itPix->y) == ((int) pixel_coord.second)))
1280  {
1281  newPixelCharge = (int) (linkiter->fraction()*itPix->adc);
1282  }
1283  }
1284 
1285  if ( newPixelCharge < 2500 )
1286  continue;
1287 
1288  //add the pixel to an already existing cluster if the charge is above the threshold
1289  int clusVecPos = 0;
1290  std::vector<int>::const_iterator sTIter = simTrackIdV.begin();
1291 
1292  for ( ; sTIter < simTrackIdV.end(); sTIter++)
1293  {
1294  if (((*sTIter)== (int) linkiter->SimTrackId()))
1295  {
1296  inStock=true; // now we saw this id before
1297  // // std::cout << " adding a pixel to the cluster " << (int) (clusVecPos) <<std::endl;
1298  // // std::cout << "newPixelCharge " << newPixelCharge << std::endl;
1299  splittedCluster.at(clusVecPos).add(newPixelPos,newPixelCharge); // add the pixel to the cluster
1300  }
1301  clusVecPos++;
1302  }
1303 
1304  //look if the splitted cluster was already made before, if not create one
1305 
1306  if ( !inStock )
1307  {
1308  // std::cout << "creating a new cluster " << std::endl;
1309  simTrackIdV.push_back(linkiter->SimTrackId()); // add the track id to the vector
1310  splittedCluster.push_back(SiPixelCluster(newPixelPos,newPixelCharge)); // add the cluster to the vector
1311  }
1312  }
1313  }
1314 
1315  // std::cout << "will add clusters : simTrackIdV.size() " << simTrackIdV.size() << std::endl;
1316 
1317  if ( ( ( (int)simTrackIdV.size() ) == 1 ) || ( *c.cluster).size()==1 )
1318  {
1319  // cout << "putting in this cluster" << endl;
1320  output.push_back(*c.cluster );
1321  // std::cout << "cluster added " << output.size() << std::endl;
1322  }
1323  else
1324  {
1325  for (std::vector<SiPixelCluster>::const_iterator cIter = splittedCluster.begin(); cIter != splittedCluster.end(); cIter++ )
1326  {
1327  output.push_back( (*cIter) );
1328  }
1329  }
1330 
1331  simTrackIdV.clear();
1332  splittedCluster.clear();
1333  }//if (isearch != pixeldigisimlink->end())
1334  }
1335  else if ( tmpSplitPixel_ )
1336  {
1337  bool cluster_was_successfully_split = false;
1338 
1339  const SiPixelCluster* thePixelCluster = static_cast<const SiPixelCluster*>(c.cluster);
1340 
1341  if ( thePixelCluster )
1342  {
1343  // Do not attempt to split clusters of size one
1344  if ( (int)thePixelCluster->size() <= 1 )
1345  {
1346  // Do nothing.
1347  //cout << "Will not attempt to split this clusters: " << endl;
1348  //cout << "(int)thePixelCluster->size() = " << (int)thePixelCluster->size() << endl;
1349  }
1350  else
1351  {
1352  // For barrel use template id 40 and for endcaps use template id 41
1353  int ID = -99999;
1354  if ( (int)detId.subdetId() == (int)PixelSubdetector::PixelBarrel )
1355  {
1356  // cout << "We are in the barrel : " << (int)PixelSubdetector::PixelBarrel << endl;
1357  ID = 40;
1358  }
1359  else if ( (int)detId.subdetId() == (int)PixelSubdetector::PixelEndcap )
1360  {
1361  // cout << "We are in the endcap : " << (int)PixelSubdetector::PixelEndcap << endl;
1362  ID = 41;
1363  }
1364  else
1365  {
1366  // cout << "Not a pixel detector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
1367  }
1368 
1369 
1370  // Begin: determine incident angles ============================================================
1371 
1372  float cotalpha_ = -99999.9;
1373  float cotbeta_ = -99999.9;
1374 
1375  // First, determine track angles from straight track approximation
1376 
1377  // Find crude cluster center.
1378  float xcenter = thePixelCluster->x();
1379  float ycenter = thePixelCluster->y();
1380 
1381  const GeomDetUnit* theDet = geometry_->idToDetUnit( detId );
1382  const PixelGeomDetUnit* pixDet = dynamic_cast<const PixelGeomDetUnit*>( theDet );
1383 
1384  const PixelTopology* theTopol = (&(pixDet->specificTopology()));
1385 
1386  // Transform from measurement to local coordinates (in cm)
1387  LocalPoint lp = theTopol->localPosition( MeasurementPoint(xcenter, ycenter) );
1388 
1389  // Transform from local to global coordinates
1390  GlobalPoint gp0 = theDet->surface().toGlobal( lp );
1391 
1392  // Make a vector pointing from the PV to the cluster center
1393  GlobalPoint gp(gp0.x()-vtx.x(), gp0.y()-vtx.y(), gp0.z()-vtx.z() );
1394 
1395  // Make gp a unit vector, gv, pointing from the PV to the cluster center
1396  float gp_mod = sqrt( gp.x()*gp.x() + gp.y()*gp.y() + gp.z()*gp.z() );
1397  float gpx = gp.x()/gp_mod;
1398  float gpy = gp.y()/gp_mod;
1399  float gpz = gp.z()/gp_mod;
1400  GlobalVector gv(gpx, gpy, gpz);
1401 
1402  // Make unit vectors in local coordinates and then transform them in global coordinates
1403  const Local3DVector lvx(1.0, 0.0, 0.0);
1404  GlobalVector gvx = theDet->surface().toGlobal( lvx );
1405  const Local3DVector lvy(0.0, 1.0, 0.0);
1406  GlobalVector gvy = theDet->surface().toGlobal( lvy );
1407  const Local3DVector lvz(0.0, 0.0, 1.0);
1408  GlobalVector gvz = theDet->surface().toGlobal( lvz );
1409 
1410  // Calculate angles alpha and beta
1411  float gv_dot_gvx = gv.x()*gvx.x() + gv.y()*gvx.y() + gv.z()*gvx.z();
1412  float gv_dot_gvy = gv.x()*gvy.x() + gv.y()*gvy.y() + gv.z()*gvy.z();
1413  float gv_dot_gvz = gv.x()*gvz.x() + gv.y()*gvz.y() + gv.z()*gvz.z();
1414 
1415  //float alpha_ = atan2( gv_dot_gvz, gv_dot_gvx );
1416  //float beta_ = atan2( gv_dot_gvz, gv_dot_gvy );
1417 
1418  cotalpha_ = gv_dot_gvx / gv_dot_gvz;
1419  cotbeta_ = gv_dot_gvy / gv_dot_gvz;
1420 
1421 
1422 
1423 
1424  // Attempt to get a better angle from tracks (either pixel tracks or full tracks)
1425  if ( !useStraightTracks_ )
1426  {
1427  // Use either pixel tracks (useTrajectories_ = False) or fully reconstructed tracks (useTrajectories_ = True)
1428  // When pixel/full tracks are not associated with the current cluster, will use angles from straight tracks
1429 
1430  // These are the tracks associated with this cluster
1431  std::vector<TrackAndState> vec_tracks_states = c.tracks;
1432 
1433 
1434 
1435  if ( (int)vec_tracks_states.size() > 0 )
1436  {
1437  //cout << "There is at least one track associated with this cluster. Pick the one with largest Pt." << endl;
1438  //cout << "(int)vec_tracks_states.size() = " << (int)vec_tracks_states.size() << endl;
1439 
1440  int index_max_pt = -99999; // index of the track with the highest Pt
1441  float max_pt = -99999.9;
1442 
1443  for (int i=0; i<(int)vec_tracks_states.size(); ++i )
1444  {
1445  const reco::Track* one_track = vec_tracks_states[i].track;
1446 
1447  if ( one_track->pt() > max_pt )
1448  {
1449  index_max_pt = i;
1450  max_pt = one_track->pt();
1451  }
1452  }
1453 
1454  // Pick the tsos from the track with highest Pt
1455  // gavril: Should we use highest Pt or best Chi2 ?
1456  TrajectoryStateOnSurface one_tsos = vec_tracks_states[index_max_pt].state;
1457 
1458  LocalTrajectoryParameters ltp = one_tsos.localParameters();
1459 
1460  LocalVector localDir = ltp.momentum()/ltp.momentum().mag();
1461 
1462  float locx = localDir.x();
1463  float locy = localDir.y();
1464  float locz = localDir.z();
1465 
1466  //alpha_ = atan2( locz, locx );
1467  //beta_ = atan2( locz, locy );
1468 
1469  cotalpha_ = locx/locz;
1470  cotbeta_ = locy/locz;
1471 
1472 
1473 
1474  } // if ( (int)vec_tracks_states.size() > 0 )
1475 
1476  } // if ( !useStraightTracks_ )
1477 
1478  // End: determine incident angles ============================================================
1479 
1480 
1481 
1482  //cout << "Calling qbin to see if the cluster has to be split..." << endl;
1483  int templQbin_ = templ_.qbin( ID, cotalpha_, cotbeta_, thePixelCluster->charge() );
1484 
1485  if ( templQbin_ < 0 || templQbin_ > 5 )
1486  {
1487  // gavril : check this....
1488  // cout << "Template call failed. Cannot decide if cluster should be split !!!!!!! " << endl;
1489  // cout << "Do nothing." << endl;
1490  }
1491  else // if ( templQbin_ < 0 || templQbin_ > 5 ) {...} else
1492  {
1493  //cout << " Returned OK from PixelTempReco2D..." << endl;
1494 
1495  // Check for split clusters: we split the clusters with larger than expected charge: templQbin_ == 0
1496  if ( templQbin_ != 0 )
1497  {
1498  // gavril: do not split this cluster
1499  //cout << "TEMPLATE SPLITTER SAYS : NO SPLIT " << endl;
1500  //cout << "This cluster will note be split !!!!!!!!!! " << endl;
1501  }
1502  else // if ( templQbin_ != 0 ) {...} else
1503  {
1504  //cout << "TEMPLATE SPLITTER SAYS : SPLIT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
1505  //cout << "Found a cluster that has to be split. templQbin_ = " << templQbin_ << endl;
1506 
1507  // gavril: Call the template splitter
1508  //cout << "Calling the splitter..." << endl;
1509 
1510  // Put the pixels of this clusters in a 2x2 array to be used by the template splitter
1511 
1512  const std::vector<SiPixelCluster::Pixel> & pixVec = thePixelCluster->pixels();
1513  std::vector<SiPixelCluster::Pixel>::const_iterator pixIter = pixVec.begin(), pixEnd = pixVec.end();
1514 
1515  const int cluster_matrix_size_x = 13;
1516  const int cluster_matrix_size_y = 21;
1517 
1518  boost::multi_array<float, 2> clust_array_2d(boost::extents[cluster_matrix_size_x][cluster_matrix_size_y]);
1519 
1520  int row_offset = thePixelCluster->minPixelRow();
1521  int col_offset = thePixelCluster->minPixelCol();
1522 
1523  // Copy clust's pixels (calibrated in electrons) into clust_array_2d;
1524 
1525  for ( ; pixIter != pixEnd; ++pixIter )
1526  {
1527  int irow = int(pixIter->x) - row_offset; // do we need +0.5 ???
1528  int icol = int(pixIter->y) - col_offset; // do we need +0.5 ???
1529 
1530  if ( irow<cluster_matrix_size_x && icol<cluster_matrix_size_y )
1531  {
1532  clust_array_2d[irow][icol] = (float)pixIter->adc;
1533  }
1534  }
1535 
1536  // Make and fill the bool arrays flagging double pixels
1537  std::vector<bool> ydouble(cluster_matrix_size_y), xdouble(cluster_matrix_size_x);
1538 
1539  // x directions (shorter), rows
1540  for (int irow = 0; irow < cluster_matrix_size_x; ++irow)
1541  {
1542  xdouble[irow] = theTopol->isItBigPixelInX( irow+row_offset );
1543  }
1544 
1545  // y directions (longer), columns
1546  for (int icol = 0; icol < cluster_matrix_size_y; ++icol)
1547  {
1548  ydouble[icol] = theTopol->isItBigPixelInY( icol+col_offset );
1549  }
1550 
1551  // gavril: Initialize values coming back from SiPixelTemplateSplit::PixelTempSplit
1552  float templYrec1_ = -99999.9;
1553  float templYrec2_ = -99999.9;
1554  float templSigmaY_ = -99999.9;
1555  float templProbY_ = -99999.9;
1556  float templXrec1_ = -99999.9;
1557  float templXrec2_ = -99999.9;
1558  float templSigmaX_ = -99999.9;
1559  float templProbX_ = -99999.9;
1560  float dchisq = -99999.9;
1561  float templProbQ_ = -99999.9;
1562 
1563  int ierr =
1565  cotalpha_, cotbeta_,
1566  clust_array_2d,
1567  ydouble, xdouble,
1568  templ_,
1569  templYrec1_, templYrec2_, templSigmaY_, templProbY_,
1570  templXrec1_, templXrec2_, templSigmaX_, templProbX_,
1571  templQbin_,
1572  templProbQ_,
1573  true,
1574  dchisq,
1575  templ2D_ );
1576 
1577  if ( ierr != 0 )
1578  {
1579  // cout << "Cluster splitting failed: ierr = " << ierr << endl;
1580  }
1581  else
1582  {
1583  // gavril: Cluster was successfully split.
1584  // gavril: Make the two split clusters and put them in the split cluster collection
1585  //cout << "Cluster splitting OK: ierr = " << ierr << endl;
1586 
1587  // 2D templates have origin at the lower left corner of template2d[1][1] which is
1588  // also 2 pixels larger than the cluster container
1589 
1590  float xsize = templ_.xsize(); // this is the pixel x-size in microns
1591  float ysize = templ_.ysize(); // this is the pixel y-size in microns
1592 
1593  // Shift the coordinates to the 2-D template system
1594  float yrecp1 = -99999.9;
1595  float yrecp2 = -99999.9;
1596  float xrecp1 = -99999.9;
1597  float xrecp2 = -99999.9;
1598 
1599  if ( ydouble[0] )
1600  {
1601  yrecp1 = templYrec1_ + ysize;
1602  yrecp2 = templYrec2_ + ysize;
1603  }
1604  else
1605  {
1606  yrecp1 = templYrec1_ + ysize/2.0;
1607  yrecp2 = templYrec2_ + ysize/2.0;
1608  }
1609 
1610  if ( xdouble[0] )
1611  {
1612  xrecp1 = templXrec1_ + xsize;
1613  xrecp2 = templXrec2_ + xsize;
1614  }
1615  else
1616  {
1617  xrecp1 = templXrec1_ + xsize/2.0;
1618  xrecp2 = templXrec2_ + xsize/2.0;
1619  }
1620 
1621  // The xytemp method adds charge to a zeroed buffer
1622 
1623  float template2d1[BXM2][BYM2];
1624  float template2d2[BXM2][BYM2];
1625 
1626  for ( int j=0; j<BXM2; ++j )
1627  {
1628  for ( int i=0; i<BYM2; ++i )
1629  {
1630  template2d1[j][i] = 0.0;
1631  template2d2[j][i] = 0.0;
1632  }
1633  }
1634 
1635 
1636  bool template_OK
1637  = templ2D_.xytemp(ID, cotalpha_, cotbeta_,
1638  xrecp1, yrecp1,
1639  ydouble, xdouble,
1640  template2d1);
1641 
1642  template_OK
1643  = template_OK &&
1644  templ2D_.xytemp(ID, cotalpha_, cotbeta_,
1645  xrecp2, yrecp2,
1646  ydouble, xdouble,
1647  template2d2);
1648 
1649  if ( !template_OK )
1650  {
1651  // gavril: check this
1652  //cout << "Template is not OK. Fill out with zeros !!!!!!!!!!!!!!! " << endl;
1653 
1654  for ( int j=0; j<BXM2; ++j )
1655  {
1656  for ( int i=0; i<BYM2; ++i )
1657  {
1658  template2d1[j][i] = 0.0;
1659  template2d2[j][i] = 0.0;
1660  }
1661  }
1662 
1663  if ( !templ_.simpletemplate2D(xrecp1, yrecp1,
1664  xdouble, ydouble,
1665  template2d1) )
1666  {
1667  cluster_was_successfully_split = false;
1668  }
1669 
1670  if ( !templ_.simpletemplate2D(xrecp2, yrecp2,
1671  xdouble, ydouble,
1672  template2d2) )
1673  {
1674  cluster_was_successfully_split = false;
1675  }
1676 
1677  } // if ( !template_OK )
1678  else
1679  {
1680  cluster_was_successfully_split = true;
1681 
1682  // Next, copy the 2-d templates into cluster containers, replace small signals with zero.
1683  // Cluster 1 and cluster 2 should line up with clust_array_2d (same origin and pixel indexing)
1684 
1685  float q50 = templ_.s50();
1686 
1687 
1688  float cluster1[TXSIZE][TYSIZE];
1689  float cluster2[TXSIZE][TYSIZE]; //Note that TXSIZE = BXM2 - 2, TYSIZE = BYM2 - 2
1690 
1691  for ( int j=0; j<TXSIZE; ++j )
1692  {
1693  for ( int i=0; i<TYSIZE; ++i )
1694  {
1695  cluster1[j][i] = template2d1[j+1][i+1];
1696 
1697  if ( cluster1[j][i] < q50 )
1698  cluster1[j][i] = 0.0;
1699 
1700  cluster2[j][i] = template2d2[j+1][i+1];
1701 
1702  if ( cluster2[j][i] < q50 )
1703  cluster2[j][i] = 0.0;
1704 
1705  //cout << "cluster1[j][i] = " << cluster1[j][i] << endl;
1706  //cout << "cluster2[j][i] = " << cluster2[j][i] << endl;
1707  }
1708  }
1709 
1710 
1711  // Find the coordinates of first pixel in each of the two split clusters
1712  int i1 = -999;
1713  int j1 = -999;
1714  int i2 = -999;
1715  int j2 = -999;
1716 
1717  bool done_searching = false;
1718  for ( int i=0; i<13 && !done_searching; ++i)
1719  {
1720  for (int j=0; j<21 && !done_searching; ++j)
1721  {
1722  if ( cluster1[i][j] > 0 )
1723  {
1724  i1 = i;
1725  j1 = j;
1726  done_searching = true;
1727  }
1728  }
1729  }
1730 
1731  done_searching = false;
1732  for ( int i=0; i<13 && !done_searching; ++i)
1733  {
1734  for (int j=0; j<21 && !done_searching; ++j)
1735  {
1736  if ( cluster2[i][j] > 0 )
1737  {
1738  i2 = i;
1739  j2 = j;
1740  done_searching = true;
1741  }
1742  }
1743  }
1744 
1745 
1746  // Make clusters out of the first pixels in each of the two split clsuters
1747 
1748  SiPixelCluster cl1( SiPixelCluster::PixelPos( i1 + row_offset, j1 + col_offset),
1749  cluster1[i1][j1] );
1750 
1751  SiPixelCluster cl2( SiPixelCluster::PixelPos( i2 + row_offset, j2 + col_offset),
1752  cluster2[i2][j2] );
1753 
1754 
1755  // Now add the rest of the pixels to the split clusters
1756 
1757  for ( int i=0; i<13; ++i)
1758  {
1759  for (int j=0; j<21; ++j)
1760  {
1761 
1762  if ( cluster1[i][j] > 0.0 && (i!=i1 || j!=j1 ) )
1763  {
1764  cl1.add( SiPixelCluster::PixelPos( i + row_offset, j + col_offset),
1765  cluster1[i][j] );
1766 
1767  //cout << "cluster1[i][j] = " << cluster1[i][j] << endl;
1768  }
1769 
1770 
1771  if ( cluster2[i][j] > 0.0 && (i!=i2 || j!=j2 ) )
1772  {
1773  cl2.add( SiPixelCluster::PixelPos( i + row_offset, j + col_offset),
1774  cluster2[i][j] );
1775 
1776  //cout << "cluster2[i][j] = " << cluster2[i][j] << endl;
1777  }
1778  }
1779  }
1780 
1781  // Attach errors and probabilities to the split Clusters
1782  // The errors will be later attahed to the SiPixelRecHit
1783 
1784 
1785  cl1.setSplitClusterErrorX( templSigmaX_ );
1786  cl1.setSplitClusterErrorY( templSigmaY_ );
1787  //cl1.prob_q = templProbQ_;
1788 
1789  cl2.setSplitClusterErrorX( templSigmaX_ );
1790  cl2.setSplitClusterErrorY( templSigmaY_ );
1791  //cl2.prob_q = templProbQ_;
1792 
1793 
1794  // Save the split clusters
1795  output.push_back( cl1 );
1796  output.push_back( cl2 );
1797 
1798  // Some sanity checks
1799 
1800  if ( (int)cl1.size() <= 0 )
1801  {
1802  edm::LogError("TrackClusterSplitter : ")
1803  << "1) Cluster of size = " << (int)cl1.size() << " !!! " << endl;
1804  }
1805 
1806  if ( (int)cl2.size() <= 0 )
1807  {
1808  edm::LogError("TrackClusterSplitter : ")
1809  << "2) Cluster of size = " << (int)cl2.size() << " !!! " << endl;
1810  }
1811 
1812  if ( cl1.charge() <= 0 )
1813  {
1814  edm::LogError("TrackClusterSplitter : ")
1815  << "1) Cluster of charge = " << (int)cl1.charge() << " !!! " << endl;
1816 
1817  }
1818 
1819  if ( cl2.charge() <= 0 )
1820  {
1821  edm::LogError("TrackClusterSplitter : ")
1822  << "2) Cluster of charge = " << (int)cl2.charge() << " !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
1823  }
1824 
1825 
1826  } // if ( !template_OK ) ... else
1827 
1828  } // if ( ierr2 != 0 ) ... else
1829 
1830  } // if ( templQbin_ != 0 ) ... else
1831 
1832  } // else // if ( templQbin_ < 0 || templQbin_ > 5 ) {...} else
1833 
1834  } // if ( (int)thePixelCluster->size() <= 1 ) {... } else
1835 
1836  if ( !cluster_was_successfully_split )
1837  output.push_back(*c.cluster);
1838 
1839  } // if ( theSiPixelCluster )
1840  else
1841  {
1842  throw cms::Exception("TrackClusterSplitter :")
1843  << "This is not a SiPixelCluster !!! " << "\n";
1844  }
1845  }
1846  else
1847  {
1848  // gavril : Neither sim nor template splitter. Just add the cluster as it was.
1849  // original from G.P.
1850  output.push_back( *c.cluster );
1851  }
1852 }
1853 
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:114
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
float charge() const
edm::ESHandle< Propagator > propagator_
edm::EDGetTokenT< edm::DetSetVector< StripDigiSimLink > > stripdigisimlinkToken
bool operator()(const ClusterWithTracks< Cluster > &test) const
int minPixelCol() const
edm::EDGetTokenT< TrajTrackAssociationCollection > trajTrackAssociations_
#define BXSIZE
static const C * equalClusters(const C &c1, const C &c2)
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
void setSplitClusterErrorY(float erry)
TrackAndState(const reco::Track *aTrack, TrajectoryStateOnSurface aState)
virtual LocalPoint localPosition(const MeasurementPoint &) const =0
const LocalTrajectoryParameters & localParameters() const
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
void markClusters(std::map< uint32_t, boost::sub_range< std::vector< ClusterWithTracks< Cluster > > > > &map, const TrackingRecHit *hit, const reco::Track *track, const TrajectoryStateOnSurface &tsos) const
int qbin(int id, float cotalpha, float cotbeta, float locBz, float qclus, float &pixmx, float &sigmay, float &deltay, float &sigmax, float &deltax, float &sy1, float &dy1, float &sy2, float &dy2, float &sx1, float &dx1, float &sx2, float &dx2)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
edm::EDGetTokenT< edmNew::DetSetVector< SiStripCluster > > stripClusters_
#define TXSIZE
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
size_t recHitsSize() const
Get number of RecHits. (Warning, this includes invalid hits, which are not physical hits)...
Definition: Track.h:68
float xsize()
strip x-size (microns)
double y() const
y coordinate
Definition: Vertex.h:96
FreeTrajectoryState innerFreeState(const reco::Track &tk, const MagneticField *field)
uint32_t ID
Definition: Definitions.h:26
T y() const
Definition: PV3DBase.h:63
std::auto_ptr< edmNew::DetSetVector< Cluster > > splitClusters(const std::map< uint32_t, boost::sub_range< std::vector< ClusterWithTracks< Cluster > > > > &input, const reco::Vertex &vtx) const
uint16_t firstStrip() const
int qbin(int id, float cotalpha, float cotbeta, float qclus)
LocalVector toLocal(const reco::Track::Vector &v, const Surface &s)
edm::Handle< edm::DetSetVector< PixelDigiSimLink > > pixeldigisimlink
virtual const StripTopology & specificTopology() const
Returns a reference to the strip proxy topology.
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
static std::string const input
Definition: EdmProvDump.cc:44
#define BXM2
bool xytemp(int id, float cotalpha, float cotbeta, float locBz, float xhit, float yhit, std::vector< bool > &ydouble, std::vector< bool > &xdouble, float template2d[BXM2][BYM2])
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
edm::EDGetTokenT< edmNew::DetSetVector< SiPixelCluster > > pixelClusters_
DataContainer const & measurements() const
Definition: Trajectory.h:215
edm::ESHandle< MagneticField > magfield_
bool simpletemplate2D(float xhitp, float yhitp, std::vector< bool > &ydouble, std::vector< bool > &xdouble, float template2d[BXM2][BYM2])
Make simple 2-D templates from track angles set in interpolate and hit position.
Measurement2DPoint MeasurementPoint
Measurement points are two-dimensional by default.
int iEvent
Definition: GenABIO.cc:243
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:42
T mag() const
Definition: PV3DBase.h:67
int minPixelRow() const
bool pushfile(int filenum)
const T & max(const T &a, const T &b)
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:116
T sqrt(T t)
Definition: SSEVec.h:48
double pt() const
track transverse momentum
Definition: TrackBase.h:129
T z() const
Definition: PV3DBase.h:64
int PixelTempSplit(int id, float cotalpha, float cotbeta, array_2d &cluster, std::vector< bool > &ydouble, std::vector< bool > &xdouble, SiPixelTemplate &templ, float &yrec1, float &yrec2, float &sigmay, float &prob2y, float &xrec1, float &xrec2, float &sigmax, float &prob2x, int &q2bin, float &prob2Q, bool resolve, int speed, float &dchisq, bool deadpix, std::vector< std::pair< int, int > > &zeropix, SiPixelTemplate2D &templ2D)
edm::EDGetTokenT< edm::DetSetVector< PixelDigiSimLink > > pixeldigisimlinkToken
edm::EDGetTokenT< std::vector< reco::Vertex > > vertices_
std::vector< SiPixelClusterWithTracks > allSiPixelClusters
working data
int j
Definition: DBlmapReader.cc:9
double z() const
y coordinate
Definition: Vertex.h:98
edm::ESHandle< GlobalTrackingGeometry > geometry_
float xsize()
pixel x-size (microns)
#define BYM2
float barycenter() const
#define end
Definition: vmac.h:37
void add(const PixelPos &pix, int adc)
LocalVector momentum() const
Momentum vector in the local frame.
A Digi for the silicon strip detector, containing both strip and adc information, and suitable for st...
Definition: SiStripDigi.h:12
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:62
std::pair< uint32_t, EncodedEventId > SimHitIdpr
std::vector< LinkConnSpec >::const_iterator IT
boost::sub_range< std::vector< SiPixelClusterWithTracks > > SiPixelClustersWithTracks
std::vector< SiStripClusterWithTracks > allSiStripClusters
bool first
Definition: L1TdeRCT.cc:79
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
boost::sub_range< std::vector< SiStripClusterWithTracks > > SiStripClustersWithTracks
FindCluster(const TrackingRecHit *hit)
float s50()
1/2 of the pixel threshold signal in electrons
TrackerHitAssociator * hitAssociator
void associateSimpleRecHitCluster(const SiStripCluster *clust, const uint32_t &detID, std::vector< SimHitIdpr > &simtrackid)
virtual bool isItBigPixelInX(const int ixbin) const =0
edm::Handle< edm::DetSetVector< StripDigiSimLink > > stripdigisimlink
Detector identifier class for the strip tracker.
Definition: SiStripDetId.h:17
void setSplitClusterErrorX(float errx)
std::map< uint32_t, SiStripClustersWithTracks > siStripDetsWithClusters
Definition: DetId.h:18
bool pushfile(int filenum)
double x() const
x coordinate
Definition: Vertex.h:94
#define TYSIZE
tuple tracks
Definition: testEve_cfg.py:39
void sxtemp(float xhit, std::vector< float > &cluster)
const T & get() const
Definition: EventSetup.h:55
static std::pair< int, int > channelToPixel(int ch)
Definition: PixelDigi.h:41
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
bool isValid() const
id_type detId() const
Definition: DetSetNew.h:83
const int cluster_matrix_size_y
int StripTempSplit(int id, float cotalpha, float cotbeta, float locBy, int speed, std::vector< float > &cluster, SiStripTemplate &templ, float &xrec1, float &xrec2, float &sigmax, float &prob2x, int &q2bin, float &prob2Q)
void setSplitClusterError(float errx)
std::map< uint32_t, SiPixelClustersWithTracks > siPixelDetsWithClusters
collection_type data
Definition: DetSet.h:78
Pixel cluster – collection of neighboring pixels above threshold.
#define begin
Definition: vmac.h:30
iterator end()
Definition: DetSetNew.h:70
edm::EDGetTokenT< std::vector< reco::Track > > tracks_
float y() const
virtual LocalPoint localPosition(float strip) const =0
bool pushfile(int filenum)
const int cluster_matrix_size_x
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:6
DetId geographicalId() const
dbl *** dir
Definition: mlp_gen.cc:35
ModuleGeometry moduleGeometry() const
Definition: SiStripDetId.h:132
collection_type::const_iterator const_iterator
Definition: DetSet.h:33
void splitCluster(const ClusterWithTracks< Cluster > &cluster, const GlobalVector &dir, typename edmNew::DetSetVector< Cluster >::FastFiller &output, DetId detId) const
collection_type::const_iterator const_iterator
Definition: DetSetVector.h:106
ClusterWithTracks< SiStripCluster > SiStripClusterWithTracks
bool interpolate(int id, float cotalpha, float cotbeta, float locBy)
T x() const
Definition: PV3DBase.h:62
const PositionType & position() const
float ysize()
pixel y-size (microns)
ClusterWithTracks< SiPixelCluster > SiPixelClusterWithTracks
SiPixelTemplate2D templ2D_
tuple size
Write out results.
float x() const
const std::vector< uint8_t > & amplitudes() const
const std::vector< Pixel > pixels() const
Pixel Reconstructed Hit.
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:64
int size() const
TrackClusterSplitter(const edm::ParameterSet &iConfig)
virtual bool isItBigPixelInY(const int iybin) const =0
iterator begin()
Definition: DetSetNew.h:67