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
119  std::vector< SiPixelTemplateStore > thePixelTemp_;
120  std::vector< SiPixelTemplateStore2D > thePixelTemp2D_;
121  // Strip template
122  std::vector< SiStripTemplateStore > theStripTemp_;
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>("vertices"));
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
287 
288  // Load strip templates
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(
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  SiStripTemplate strip_templ_(theStripTemp_);
1000  int strip_templQbin_ = strip_templ_.qbin( ID, cotalpha_, cotbeta_, strip_cluster_charge );
1001 
1002  if ( strip_templQbin_ < 0 || strip_templQbin_ > 5 )
1003  {
1004  // Do nothing...
1005  // cout << "Wrong strip strip_templQbin_ = " << strip_templQbin_ << endl;
1006  } // if ( strip_templQbin_ < 0 || strip_templQbin_ > 5 )
1007  else // if ( strip_templQbin_ < 0 || strip_templQbin_ > 5 ) {...} else
1008  {
1009  if ( strip_templQbin_ != 0 )
1010  {
1011  // Do not split this cluster. Do nothing.
1012  //cout << endl;
1013  //cout << "Do NOT split this cluster" << endl;
1014 
1015  } // if ( strip_templQbin_ != 0 )
1016  else // if ( templQbin_ != 0 ) {...} else
1017  {
1018  //cout << endl;
1019  //cout << "Split this cluster" << endl;
1020 
1021  // gavril : Is this OK ?
1022  uint16_t first_strip = theStripCluster->firstStrip();
1023 
1024  LocalVector lbfield = ( stripDet->surface() ).toLocal( magfield_->inTesla( stripDet->surface().position() ) );
1025  float locBy = lbfield.y();
1026 
1027  // Initialize values coming back from SiStripTemplateSplit::StripTempSplit
1028  float stripTemplXrec1_ = -99999.9;
1029  float stripTemplXrec2_ = -99999.9;
1030  float stripTemplSigmaX_ = -99999.9;
1031  float stripTemplProbX_ = -99999.9;
1032  int stripTemplQbin_ = -99999;
1033  float stripTemplProbQ_ = -99999.9;
1034 
1035 
1036  /*
1037  cout << endl;
1038  cout << "About to call SiStripTemplateSplit::StripTempSplit(...)" << endl;
1039 
1040  cout << endl;
1041  cout << "ID = " << ID << endl;
1042  cout << "cotalpha_ = " << cotalpha_ << endl;
1043  cout << "cotbeta_ = " << cotbeta_ << endl;
1044  cout << "locBy = " << locBy << endl;
1045  cout << "Amplitudes: ";
1046  for (int i=0; i<(int)vec_cluster_charge.size(); ++i)
1047  cout << vec_cluster_charge[i] << ", ";
1048  cout << endl;
1049  */
1050 
1051  int ierr =
1053  cotalpha_, cotbeta_,
1054  locBy,
1055  vec_cluster_charge,
1056  strip_templ_,
1057  stripTemplXrec1_,
1058  stripTemplXrec2_,
1059  stripTemplSigmaX_,
1060  stripTemplProbX_,
1061  stripTemplQbin_,
1062  stripTemplProbQ_ );
1063 
1064 
1065 
1066  stripTemplXrec1_ += 2*strip_templ_.xsize();
1067  stripTemplXrec2_ += 2*strip_templ_.xsize();
1068 
1069 
1070 
1071  if ( ierr != 0 )
1072  {
1073  //cout << endl;
1074  //cout << "Strip cluster splitting failed: ierr = " << ierr << endl;
1075  }
1076  else // if ( ierr != 0 )
1077  {
1078  // Cluster was successfully split.
1079  // Make the two split clusters and put them in the split cluster collection
1080 
1081  //cout << endl;
1082  //cout << "Cluster was successfully split" << endl;
1083 
1084  cluster_was_successfully_split = true;
1085 
1086  std::vector<float> strip_cluster1;
1087  std::vector<float> strip_cluster2;
1088 
1089  strip_cluster1.clear();
1090  strip_cluster2.clear();
1091 
1092  // gavril : Is this OK ?!?!?!?!
1093  for (int i=0; i<BXSIZE; ++i)
1094  {
1095  strip_cluster1.push_back(0.0);
1096  strip_cluster2.push_back(0.0);
1097  }
1098 
1099  //cout << endl;
1100  //cout << "About to call interpolate and sxtemp" << endl;
1101 
1102  strip_templ_.interpolate(ID, cotalpha_, cotbeta_, locBy);
1103  strip_templ_.sxtemp(stripTemplXrec1_, strip_cluster1);
1104  strip_templ_.sxtemp(stripTemplXrec2_, strip_cluster2);
1105 
1106 
1107 
1108  vector<SiStripDigi> vecSiStripDigi1;
1109  vecSiStripDigi1.clear();
1110  int strip_cluster1_size = (int)strip_cluster1.size();
1111  for (int i=2; i<strip_cluster1_size; ++i)
1112  {
1113  if ( strip_cluster1[i] > 0.0 )
1114  {
1115  SiStripDigi current_digi1( first_strip + i-2, strip_cluster1[i] );
1116 
1117  vecSiStripDigi1.push_back( current_digi1 );
1118  }
1119  }
1120 
1121 
1122 
1123  vector<SiStripDigi> vecSiStripDigi2;
1124  vecSiStripDigi2.clear();
1125  int strip_cluster2_size = (int)strip_cluster2.size();
1126  for (int i=2; i<strip_cluster2_size; ++i)
1127  {
1128  if ( strip_cluster2[i] > 0.0 )
1129  {
1130  SiStripDigi current_digi2( first_strip + i-2, strip_cluster2[i] );
1131 
1132  vecSiStripDigi2.push_back( current_digi2 );
1133  }
1134  }
1135 
1136 
1137 
1138 
1139  std::vector<SiStripDigi>::const_iterator SiStripDigiIterBegin1 = vecSiStripDigi1.begin();
1140  std::vector<SiStripDigi>::const_iterator SiStripDigiIterEnd1 = vecSiStripDigi1.end();
1141  std::pair<std::vector<SiStripDigi>::const_iterator,
1142  std::vector<SiStripDigi>::const_iterator> SiStripDigiRange1
1143  = make_pair(SiStripDigiIterBegin1, SiStripDigiIterEnd1);
1144 
1145  //if ( SiStripDigiIterBegin1 == SiStripDigiIterEnd1 )
1146  //{
1147  // throw cms::Exception("TrackClusterSplitter : ")
1148  //<< "\nERROR: SiStripDigiIterBegin1 = SiStripDigiIterEnd1 !!!" << "\n\n";
1149  //}
1150 
1151  std::vector<SiStripDigi>::const_iterator SiStripDigiIterBegin2 = vecSiStripDigi2.begin();
1152  std::vector<SiStripDigi>::const_iterator SiStripDigiIterEnd2 = vecSiStripDigi2.end();
1153  std::pair<std::vector<SiStripDigi>::const_iterator,
1154  std::vector<SiStripDigi>::const_iterator> SiStripDigiRange2
1155  = make_pair(SiStripDigiIterBegin2, SiStripDigiIterEnd2);
1156 
1157  // Sanity check...
1158  //if ( SiStripDigiIterBegin2 == SiStripDigiIterEnd2 )
1159  //{
1160  // cout << endl;
1161  // cout << "SiStripDigiIterBegin2 = SiStripDigiIterEnd2 !!!!!!!!!!!!!!!" << endl;
1162  //}
1163 
1164 
1165  // Save the split clusters
1166 
1167  if ( SiStripDigiIterBegin1 != SiStripDigiIterEnd1 )
1168  {
1169  // gavril : Raw id ?
1170  SiStripCluster cl1( SiStripDigiRange1 );
1171 
1172  cl1.setSplitClusterError( stripTemplSigmaX_ );
1173 
1174  output.push_back( cl1 );
1175 
1176  if ( (int)cl1.amplitudes().size() <= 0 )
1177  {
1178  throw cms::Exception("TrackClusterSplitter : ")
1179  << "\nERROR: (1) Wrong split cluster of size = " << (int)cl1.amplitudes().size() << "\n\n";
1180  }
1181 
1182  } // if ( SiStripDigiIterBegin1 != SiStripDigiIterEnd1 )
1183 
1184  if ( SiStripDigiIterBegin2 != SiStripDigiIterEnd2 )
1185  {
1186  // gavril : Raw id ?
1187  SiStripCluster cl2( SiStripDigiRange2 );
1188  cl2.setSplitClusterError( stripTemplSigmaX_ );
1189  output.push_back( cl2 );
1190 
1191  if ( (int)cl2.amplitudes().size() <= 0 )
1192  {
1193  throw cms::Exception("TrackClusterSplitter : ")
1194  << "\nERROR: (2) Wrong split cluster of size = " << (int)cl2.amplitudes().size() << "\n\n";
1195  }
1196 
1197  } // if ( SiStripDigiIterBegin2 != SiStripDigiIterEnd2 )
1198 
1199 
1200 
1201  } // else // if ( ierr != 0 )
1202 
1203  } // else // if ( strip_templQbin_ != 0 ) {...} else
1204 
1205  } // else // if ( strip_templQbin_ < 0 || strip_templQbin_ > 5 ) {...} else
1206 
1207  } // else // if ( (int)theStripCluster->amplitudes().size() <= 1 )
1208 
1209 
1210  if ( !cluster_was_successfully_split )
1211  output.push_back( *c.cluster );
1212 
1213  } // if ( theStripCluster )
1214  else
1215  {
1216  throw cms::Exception("TrackClusterSplitter : ")
1217  << "\nERROR: This is not a SiStripCluster !!!" << "\n\n";
1218  }
1219 
1220  } // else if ( strip_tmpSplit_ )
1221  else
1222  {
1223  // gavril : Neither sim nor template splitter. Just add the cluster as it was.
1224  output.push_back( *c.cluster );
1225  }
1226 }
1227 
1228 template<>
1229 void TrackClusterSplitter::splitCluster<SiPixelCluster> (const SiPixelClusterWithTracks &c,
1230  const GlobalVector &vtx,
1232  DetId detId
1233  ) const
1234 {
1235  // The sim splitter:
1236  if ( simSplitPixel_ )
1237  {
1238  // cout << "Cluster splitting using simhits " << endl;
1239 
1240  int minPixelRow = (*c.cluster).minPixelRow();
1241  int maxPixelRow = (*c.cluster).maxPixelRow();
1242  int minPixelCol = (*c.cluster).minPixelCol();
1243  int maxPixelCol = (*c.cluster).maxPixelCol();
1244  int dsl = 0; // number of digisimlinks
1245 
1247  if (isearch != pixeldigisimlink->end()){
1248  edm::DetSet<PixelDigiSimLink> digiLink = (*isearch);
1249 
1250  edm::DetSet<PixelDigiSimLink>::const_iterator linkiter = digiLink.data.begin();
1251  //create a vector for the track ids in the digisimlinks
1252  std::vector<int> simTrackIdV;
1253  simTrackIdV.clear();
1254  //create a vector for the new splittedClusters
1255  std::vector<SiPixelCluster> splittedCluster;
1256  splittedCluster.clear();
1257 
1258  for ( ; linkiter != digiLink.data.end(); linkiter++)
1259  { // loop over all digisimlinks
1260  dsl++;
1261  std::pair<int,int> pixel_coord = PixelDigi::channelToPixel(linkiter->channel());
1262 
1263  // is the digisimlink inside the cluster boundaries?
1264  if ( pixel_coord.first <= maxPixelRow &&
1265  pixel_coord.first >= minPixelRow &&
1266  pixel_coord.second <= maxPixelCol &&
1267  pixel_coord.second >= minPixelCol )
1268  {
1269  bool inStock(false); // did we see this simTrackId before?
1270 
1271  SiPixelCluster::PixelPos newPixelPos(pixel_coord.first, pixel_coord.second); // coordinates to the pixel
1272 
1273  //loop over the pixels from the cluster to get the charge in this pixel
1274  int newPixelCharge(0); //fraction times charge in the original cluster pixel
1275 
1276  const std::vector<SiPixelCluster::Pixel>& pixvector = (*c.cluster).pixels();
1277 
1278  for(std::vector<SiPixelCluster::Pixel>::const_iterator itPix = pixvector.begin(); itPix != pixvector.end(); itPix++)
1279  {
1280  if (((int) itPix->x) == ((int) pixel_coord.first)&&(((int) itPix->y) == ((int) pixel_coord.second)))
1281  {
1282  newPixelCharge = (int) (linkiter->fraction()*itPix->adc);
1283  }
1284  }
1285 
1286  if ( newPixelCharge < 2500 )
1287  continue;
1288 
1289  //add the pixel to an already existing cluster if the charge is above the threshold
1290  int clusVecPos = 0;
1291  std::vector<int>::const_iterator sTIter = simTrackIdV.begin();
1292 
1293  for ( ; sTIter < simTrackIdV.end(); sTIter++)
1294  {
1295  if (((*sTIter)== (int) linkiter->SimTrackId()))
1296  {
1297  inStock=true; // now we saw this id before
1298  // // std::cout << " adding a pixel to the cluster " << (int) (clusVecPos) <<std::endl;
1299  // // std::cout << "newPixelCharge " << newPixelCharge << std::endl;
1300  splittedCluster.at(clusVecPos).add(newPixelPos,newPixelCharge); // add the pixel to the cluster
1301  }
1302  clusVecPos++;
1303  }
1304 
1305  //look if the splitted cluster was already made before, if not create one
1306 
1307  if ( !inStock )
1308  {
1309  // std::cout << "creating a new cluster " << std::endl;
1310  simTrackIdV.push_back(linkiter->SimTrackId()); // add the track id to the vector
1311  splittedCluster.push_back(SiPixelCluster(newPixelPos,newPixelCharge)); // add the cluster to the vector
1312  }
1313  }
1314  }
1315 
1316  // std::cout << "will add clusters : simTrackIdV.size() " << simTrackIdV.size() << std::endl;
1317 
1318  if ( ( ( (int)simTrackIdV.size() ) == 1 ) || ( *c.cluster).size()==1 )
1319  {
1320  // cout << "putting in this cluster" << endl;
1321  output.push_back(*c.cluster );
1322  // std::cout << "cluster added " << output.size() << std::endl;
1323  }
1324  else
1325  {
1326  for (std::vector<SiPixelCluster>::const_iterator cIter = splittedCluster.begin(); cIter != splittedCluster.end(); cIter++ )
1327  {
1328  output.push_back( (*cIter) );
1329  }
1330  }
1331 
1332  simTrackIdV.clear();
1333  splittedCluster.clear();
1334  }//if (isearch != pixeldigisimlink->end())
1335  }
1336  else if ( tmpSplitPixel_ )
1337  {
1338  bool cluster_was_successfully_split = false;
1339 
1340  const SiPixelCluster* thePixelCluster = static_cast<const SiPixelCluster*>(c.cluster);
1341 
1342  if ( thePixelCluster )
1343  {
1344  // Do not attempt to split clusters of size one
1345  if ( (int)thePixelCluster->size() <= 1 )
1346  {
1347  // Do nothing.
1348  //cout << "Will not attempt to split this clusters: " << endl;
1349  //cout << "(int)thePixelCluster->size() = " << (int)thePixelCluster->size() << endl;
1350  }
1351  else
1352  {
1353  // For barrel use template id 40 and for endcaps use template id 41
1354  int ID = -99999;
1355  if ( (int)detId.subdetId() == (int)PixelSubdetector::PixelBarrel )
1356  {
1357  // cout << "We are in the barrel : " << (int)PixelSubdetector::PixelBarrel << endl;
1358  ID = 40;
1359  }
1360  else if ( (int)detId.subdetId() == (int)PixelSubdetector::PixelEndcap )
1361  {
1362  // cout << "We are in the endcap : " << (int)PixelSubdetector::PixelEndcap << endl;
1363  ID = 41;
1364  }
1365  else
1366  {
1367  // cout << "Not a pixel detector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
1368  }
1369 
1370 
1371  // Begin: determine incident angles ============================================================
1372 
1373  float cotalpha_ = -99999.9;
1374  float cotbeta_ = -99999.9;
1375 
1376  // First, determine track angles from straight track approximation
1377 
1378  // Find crude cluster center.
1379  float xcenter = thePixelCluster->x();
1380  float ycenter = thePixelCluster->y();
1381 
1382  const GeomDetUnit* theDet = geometry_->idToDetUnit( detId );
1383  const PixelGeomDetUnit* pixDet = dynamic_cast<const PixelGeomDetUnit*>( theDet );
1384 
1385  const PixelTopology* theTopol = (&(pixDet->specificTopology()));
1386 
1387  // Transform from measurement to local coordinates (in cm)
1388  LocalPoint lp = theTopol->localPosition( MeasurementPoint(xcenter, ycenter) );
1389 
1390  // Transform from local to global coordinates
1391  GlobalPoint gp0 = theDet->surface().toGlobal( lp );
1392 
1393  // Make a vector pointing from the PV to the cluster center
1394  GlobalPoint gp(gp0.x()-vtx.x(), gp0.y()-vtx.y(), gp0.z()-vtx.z() );
1395 
1396  // Make gp a unit vector, gv, pointing from the PV to the cluster center
1397  float gp_mod = sqrt( gp.x()*gp.x() + gp.y()*gp.y() + gp.z()*gp.z() );
1398  float gpx = gp.x()/gp_mod;
1399  float gpy = gp.y()/gp_mod;
1400  float gpz = gp.z()/gp_mod;
1401  GlobalVector gv(gpx, gpy, gpz);
1402 
1403  // Make unit vectors in local coordinates and then transform them in global coordinates
1404  const Local3DVector lvx(1.0, 0.0, 0.0);
1405  GlobalVector gvx = theDet->surface().toGlobal( lvx );
1406  const Local3DVector lvy(0.0, 1.0, 0.0);
1407  GlobalVector gvy = theDet->surface().toGlobal( lvy );
1408  const Local3DVector lvz(0.0, 0.0, 1.0);
1409  GlobalVector gvz = theDet->surface().toGlobal( lvz );
1410 
1411  // Calculate angles alpha and beta
1412  float gv_dot_gvx = gv.x()*gvx.x() + gv.y()*gvx.y() + gv.z()*gvx.z();
1413  float gv_dot_gvy = gv.x()*gvy.x() + gv.y()*gvy.y() + gv.z()*gvy.z();
1414  float gv_dot_gvz = gv.x()*gvz.x() + gv.y()*gvz.y() + gv.z()*gvz.z();
1415 
1416  //float alpha_ = atan2( gv_dot_gvz, gv_dot_gvx );
1417  //float beta_ = atan2( gv_dot_gvz, gv_dot_gvy );
1418 
1419  cotalpha_ = gv_dot_gvx / gv_dot_gvz;
1420  cotbeta_ = gv_dot_gvy / gv_dot_gvz;
1421 
1422 
1423 
1424 
1425  // Attempt to get a better angle from tracks (either pixel tracks or full tracks)
1426  if ( !useStraightTracks_ )
1427  {
1428  // Use either pixel tracks (useTrajectories_ = False) or fully reconstructed tracks (useTrajectories_ = True)
1429  // When pixel/full tracks are not associated with the current cluster, will use angles from straight tracks
1430 
1431  // These are the tracks associated with this cluster
1432  std::vector<TrackAndState> vec_tracks_states = c.tracks;
1433 
1434 
1435 
1436  if ( (int)vec_tracks_states.size() > 0 )
1437  {
1438  //cout << "There is at least one track associated with this cluster. Pick the one with largest Pt." << endl;
1439  //cout << "(int)vec_tracks_states.size() = " << (int)vec_tracks_states.size() << endl;
1440 
1441  int index_max_pt = -99999; // index of the track with the highest Pt
1442  float max_pt = -99999.9;
1443 
1444  for (int i=0; i<(int)vec_tracks_states.size(); ++i )
1445  {
1446  const reco::Track* one_track = vec_tracks_states[i].track;
1447 
1448  if ( one_track->pt() > max_pt )
1449  {
1450  index_max_pt = i;
1451  max_pt = one_track->pt();
1452  }
1453  }
1454 
1455  // Pick the tsos from the track with highest Pt
1456  // gavril: Should we use highest Pt or best Chi2 ?
1457  TrajectoryStateOnSurface one_tsos = vec_tracks_states[index_max_pt].state;
1458 
1459  LocalTrajectoryParameters ltp = one_tsos.localParameters();
1460 
1461  LocalVector localDir = ltp.momentum()/ltp.momentum().mag();
1462 
1463  float locx = localDir.x();
1464  float locy = localDir.y();
1465  float locz = localDir.z();
1466 
1467  //alpha_ = atan2( locz, locx );
1468  //beta_ = atan2( locz, locy );
1469 
1470  cotalpha_ = locx/locz;
1471  cotbeta_ = locy/locz;
1472 
1473 
1474 
1475  } // if ( (int)vec_tracks_states.size() > 0 )
1476 
1477  } // if ( !useStraightTracks_ )
1478 
1479  // End: determine incident angles ============================================================
1480 
1481 
1482 
1483  //cout << "Calling qbin to see if the cluster has to be split..." << endl;
1486  int templQbin_ = templ_.qbin( ID, cotalpha_, cotbeta_, thePixelCluster->charge() );
1487 
1488  if ( templQbin_ < 0 || templQbin_ > 5 )
1489  {
1490  // gavril : check this....
1491  // cout << "Template call failed. Cannot decide if cluster should be split !!!!!!! " << endl;
1492  // cout << "Do nothing." << endl;
1493  }
1494  else // if ( templQbin_ < 0 || templQbin_ > 5 ) {...} else
1495  {
1496  //cout << " Returned OK from PixelTempReco2D..." << endl;
1497 
1498  // Check for split clusters: we split the clusters with larger than expected charge: templQbin_ == 0
1499  if ( templQbin_ != 0 )
1500  {
1501  // gavril: do not split this cluster
1502  //cout << "TEMPLATE SPLITTER SAYS : NO SPLIT " << endl;
1503  //cout << "This cluster will note be split !!!!!!!!!! " << endl;
1504  }
1505  else // if ( templQbin_ != 0 ) {...} else
1506  {
1507  //cout << "TEMPLATE SPLITTER SAYS : SPLIT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
1508  //cout << "Found a cluster that has to be split. templQbin_ = " << templQbin_ << endl;
1509 
1510  // gavril: Call the template splitter
1511  //cout << "Calling the splitter..." << endl;
1512 
1513  // Put the pixels of this clusters in a 2x2 array to be used by the template splitter
1514 
1515  const std::vector<SiPixelCluster::Pixel> & pixVec = thePixelCluster->pixels();
1516  std::vector<SiPixelCluster::Pixel>::const_iterator pixIter = pixVec.begin(), pixEnd = pixVec.end();
1517 
1518  const int cluster_matrix_size_x = 13;
1519  const int cluster_matrix_size_y = 21;
1520 
1521  boost::multi_array<float, 2> clust_array_2d(boost::extents[cluster_matrix_size_x][cluster_matrix_size_y]);
1522 
1523  int row_offset = thePixelCluster->minPixelRow();
1524  int col_offset = thePixelCluster->minPixelCol();
1525 
1526  // Copy clust's pixels (calibrated in electrons) into clust_array_2d;
1527 
1528  for ( ; pixIter != pixEnd; ++pixIter )
1529  {
1530  int irow = int(pixIter->x) - row_offset; // do we need +0.5 ???
1531  int icol = int(pixIter->y) - col_offset; // do we need +0.5 ???
1532 
1533  if ( irow<cluster_matrix_size_x && icol<cluster_matrix_size_y )
1534  {
1535  clust_array_2d[irow][icol] = (float)pixIter->adc;
1536  }
1537  }
1538 
1539  // Make and fill the bool arrays flagging double pixels
1540  std::vector<bool> ydouble(cluster_matrix_size_y), xdouble(cluster_matrix_size_x);
1541 
1542  // x directions (shorter), rows
1543  for (int irow = 0; irow < cluster_matrix_size_x; ++irow)
1544  {
1545  xdouble[irow] = theTopol->isItBigPixelInX( irow+row_offset );
1546  }
1547 
1548  // y directions (longer), columns
1549  for (int icol = 0; icol < cluster_matrix_size_y; ++icol)
1550  {
1551  ydouble[icol] = theTopol->isItBigPixelInY( icol+col_offset );
1552  }
1553 
1554  // gavril: Initialize values coming back from SiPixelTemplateSplit::PixelTempSplit
1555  float templYrec1_ = -99999.9;
1556  float templYrec2_ = -99999.9;
1557  float templSigmaY_ = -99999.9;
1558  float templProbY_ = -99999.9;
1559  float templXrec1_ = -99999.9;
1560  float templXrec2_ = -99999.9;
1561  float templSigmaX_ = -99999.9;
1562  float templProbX_ = -99999.9;
1563  float dchisq = -99999.9;
1564  float templProbQ_ = -99999.9;
1565 
1566  int ierr =
1568  cotalpha_, cotbeta_,
1569  clust_array_2d,
1570  ydouble, xdouble,
1571  templ_,
1572  templYrec1_, templYrec2_, templSigmaY_, templProbY_,
1573  templXrec1_, templXrec2_, templSigmaX_, templProbX_,
1574  templQbin_,
1575  templProbQ_,
1576  true,
1577  dchisq,
1578  templ2D_ );
1579 
1580  if ( ierr != 0 )
1581  {
1582  // cout << "Cluster splitting failed: ierr = " << ierr << endl;
1583  }
1584  else
1585  {
1586  // gavril: Cluster was successfully split.
1587  // gavril: Make the two split clusters and put them in the split cluster collection
1588  //cout << "Cluster splitting OK: ierr = " << ierr << endl;
1589 
1590  // 2D templates have origin at the lower left corner of template2d[1][1] which is
1591  // also 2 pixels larger than the cluster container
1592 
1593  float xsize = templ_.xsize(); // this is the pixel x-size in microns
1594  float ysize = templ_.ysize(); // this is the pixel y-size in microns
1595 
1596  // Shift the coordinates to the 2-D template system
1597  float yrecp1 = -99999.9;
1598  float yrecp2 = -99999.9;
1599  float xrecp1 = -99999.9;
1600  float xrecp2 = -99999.9;
1601 
1602  if ( ydouble[0] )
1603  {
1604  yrecp1 = templYrec1_ + ysize;
1605  yrecp2 = templYrec2_ + ysize;
1606  }
1607  else
1608  {
1609  yrecp1 = templYrec1_ + ysize/2.0;
1610  yrecp2 = templYrec2_ + ysize/2.0;
1611  }
1612 
1613  if ( xdouble[0] )
1614  {
1615  xrecp1 = templXrec1_ + xsize;
1616  xrecp2 = templXrec2_ + xsize;
1617  }
1618  else
1619  {
1620  xrecp1 = templXrec1_ + xsize/2.0;
1621  xrecp2 = templXrec2_ + xsize/2.0;
1622  }
1623 
1624  // The xytemp method adds charge to a zeroed buffer
1625 
1626  float template2d1[BXM2][BYM2];
1627  float template2d2[BXM2][BYM2];
1628 
1629  for ( int j=0; j<BXM2; ++j )
1630  {
1631  for ( int i=0; i<BYM2; ++i )
1632  {
1633  template2d1[j][i] = 0.0;
1634  template2d2[j][i] = 0.0;
1635  }
1636  }
1637 
1638 
1639  bool template_OK
1640  = templ2D_.xytemp(ID, cotalpha_, cotbeta_,
1641  xrecp1, yrecp1,
1642  ydouble, xdouble,
1643  template2d1);
1644 
1645  template_OK
1646  = template_OK &&
1647  templ2D_.xytemp(ID, cotalpha_, cotbeta_,
1648  xrecp2, yrecp2,
1649  ydouble, xdouble,
1650  template2d2);
1651 
1652  if ( !template_OK )
1653  {
1654  // gavril: check this
1655  //cout << "Template is not OK. Fill out with zeros !!!!!!!!!!!!!!! " << endl;
1656 
1657  for ( int j=0; j<BXM2; ++j )
1658  {
1659  for ( int i=0; i<BYM2; ++i )
1660  {
1661  template2d1[j][i] = 0.0;
1662  template2d2[j][i] = 0.0;
1663  }
1664  }
1665 
1666  if ( !templ_.simpletemplate2D(xrecp1, yrecp1,
1667  xdouble, ydouble,
1668  template2d1) )
1669  {
1670  cluster_was_successfully_split = false;
1671  }
1672 
1673  if ( !templ_.simpletemplate2D(xrecp2, yrecp2,
1674  xdouble, ydouble,
1675  template2d2) )
1676  {
1677  cluster_was_successfully_split = false;
1678  }
1679 
1680  } // if ( !template_OK )
1681  else
1682  {
1683  cluster_was_successfully_split = true;
1684 
1685  // Next, copy the 2-d templates into cluster containers, replace small signals with zero.
1686  // Cluster 1 and cluster 2 should line up with clust_array_2d (same origin and pixel indexing)
1687 
1688  float q50 = templ_.s50();
1689 
1690 
1691  float cluster1[TXSIZE][TYSIZE];
1692  float cluster2[TXSIZE][TYSIZE]; //Note that TXSIZE = BXM2 - 2, TYSIZE = BYM2 - 2
1693 
1694  for ( int j=0; j<TXSIZE; ++j )
1695  {
1696  for ( int i=0; i<TYSIZE; ++i )
1697  {
1698  cluster1[j][i] = template2d1[j+1][i+1];
1699 
1700  if ( cluster1[j][i] < q50 )
1701  cluster1[j][i] = 0.0;
1702 
1703  cluster2[j][i] = template2d2[j+1][i+1];
1704 
1705  if ( cluster2[j][i] < q50 )
1706  cluster2[j][i] = 0.0;
1707 
1708  //cout << "cluster1[j][i] = " << cluster1[j][i] << endl;
1709  //cout << "cluster2[j][i] = " << cluster2[j][i] << endl;
1710  }
1711  }
1712 
1713 
1714  // Find the coordinates of first pixel in each of the two split clusters
1715  int i1 = -999;
1716  int j1 = -999;
1717  int i2 = -999;
1718  int j2 = -999;
1719 
1720  bool done_searching = false;
1721  for ( int i=0; i<13 && !done_searching; ++i)
1722  {
1723  for (int j=0; j<21 && !done_searching; ++j)
1724  {
1725  if ( cluster1[i][j] > 0 )
1726  {
1727  i1 = i;
1728  j1 = j;
1729  done_searching = true;
1730  }
1731  }
1732  }
1733 
1734  done_searching = false;
1735  for ( int i=0; i<13 && !done_searching; ++i)
1736  {
1737  for (int j=0; j<21 && !done_searching; ++j)
1738  {
1739  if ( cluster2[i][j] > 0 )
1740  {
1741  i2 = i;
1742  j2 = j;
1743  done_searching = true;
1744  }
1745  }
1746  }
1747 
1748 
1749  // Make clusters out of the first pixels in each of the two split clsuters
1750 
1751  SiPixelCluster cl1( SiPixelCluster::PixelPos( i1 + row_offset, j1 + col_offset),
1752  cluster1[i1][j1] );
1753 
1754  SiPixelCluster cl2( SiPixelCluster::PixelPos( i2 + row_offset, j2 + col_offset),
1755  cluster2[i2][j2] );
1756 
1757 
1758  // Now add the rest of the pixels to the split clusters
1759 
1760  for ( int i=0; i<13; ++i)
1761  {
1762  for (int j=0; j<21; ++j)
1763  {
1764 
1765  if ( cluster1[i][j] > 0.0 && (i!=i1 || j!=j1 ) )
1766  {
1767  cl1.add( SiPixelCluster::PixelPos( i + row_offset, j + col_offset),
1768  cluster1[i][j] );
1769 
1770  //cout << "cluster1[i][j] = " << cluster1[i][j] << endl;
1771  }
1772 
1773 
1774  if ( cluster2[i][j] > 0.0 && (i!=i2 || j!=j2 ) )
1775  {
1776  cl2.add( SiPixelCluster::PixelPos( i + row_offset, j + col_offset),
1777  cluster2[i][j] );
1778 
1779  //cout << "cluster2[i][j] = " << cluster2[i][j] << endl;
1780  }
1781  }
1782  }
1783 
1784  // Attach errors and probabilities to the split Clusters
1785  // The errors will be later attahed to the SiPixelRecHit
1786 
1787 
1788  cl1.setSplitClusterErrorX( templSigmaX_ );
1789  cl1.setSplitClusterErrorY( templSigmaY_ );
1790  //cl1.prob_q = templProbQ_;
1791 
1792  cl2.setSplitClusterErrorX( templSigmaX_ );
1793  cl2.setSplitClusterErrorY( templSigmaY_ );
1794  //cl2.prob_q = templProbQ_;
1795 
1796 
1797  // Save the split clusters
1798  output.push_back( cl1 );
1799  output.push_back( cl2 );
1800 
1801  // Some sanity checks
1802 
1803  if ( (int)cl1.size() <= 0 )
1804  {
1805  edm::LogError("TrackClusterSplitter : ")
1806  << "1) Cluster of size = " << (int)cl1.size() << " !!! " << endl;
1807  }
1808 
1809  if ( (int)cl2.size() <= 0 )
1810  {
1811  edm::LogError("TrackClusterSplitter : ")
1812  << "2) Cluster of size = " << (int)cl2.size() << " !!! " << endl;
1813  }
1814 
1815  if ( cl1.charge() <= 0 )
1816  {
1817  edm::LogError("TrackClusterSplitter : ")
1818  << "1) Cluster of charge = " << (int)cl1.charge() << " !!! " << endl;
1819 
1820  }
1821 
1822  if ( cl2.charge() <= 0 )
1823  {
1824  edm::LogError("TrackClusterSplitter : ")
1825  << "2) Cluster of charge = " << (int)cl2.charge() << " !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
1826  }
1827 
1828 
1829  } // if ( !template_OK ) ... else
1830 
1831  } // if ( ierr2 != 0 ) ... else
1832 
1833  } // if ( templQbin_ != 0 ) ... else
1834 
1835  } // else // if ( templQbin_ < 0 || templQbin_ > 5 ) {...} else
1836 
1837  } // if ( (int)thePixelCluster->size() <= 1 ) {... } else
1838 
1839  if ( !cluster_was_successfully_split )
1840  output.push_back(*c.cluster);
1841 
1842  } // if ( theSiPixelCluster )
1843  else
1844  {
1845  throw cms::Exception("TrackClusterSplitter :")
1846  << "This is not a SiPixelCluster !!! " << "\n";
1847  }
1848  }
1849  else
1850  {
1851  // gavril : Neither sim nor template splitter. Just add the cluster as it was.
1852  // original from G.P.
1853  output.push_back( *c.cluster );
1854  }
1855 }
1856 
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:446
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:119
float xsize()
strip x-size (microns)
double y() const
y coordinate
Definition: Vertex.h:110
static bool pushfile(int filenum, std::vector< SiPixelTemplateStore2D > &thePixelTemp_)
FreeTrajectoryState innerFreeState(const reco::Track &tk, const MagneticField *field)
uint32_t ID
Definition: Definitions.h:26
static bool pushfile(int filenum, std::vector< SiPixelTemplateStore > &thePixelTemp_)
T y() const
Definition: PV3DBase.h:63
std::vector< SiPixelTemplateStore > thePixelTemp_
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)
const Int_t ysize
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:40
void associateSimpleRecHitCluster(const SiStripCluster *clust, const DetId &detid, std::vector< SimHitIdpr > &simtrackid, std::vector< simhitAddr > *simhitCFPos=0) const
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
std::vector< SiPixelTemplateStore2D > thePixelTemp2D_
edm::EDGetTokenT< edmNew::DetSetVector< SiPixelCluster > > pixelClusters_
DataContainer const & measurements() const
Definition: Trajectory.h:203
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:230
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:42
T mag() const
Definition: PV3DBase.h:67
int minPixelRow() const
const T & max(const T &a, const T &b)
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:113
T sqrt(T t)
Definition: SSEVec.h:48
double pt() const
track transverse momentum
Definition: TrackBase.h:597
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:112
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:104
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:75
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
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
std::vector< SiStripTemplateStore > theStripTemp_
Definition: DetId.h:18
double x() const
x coordinate
Definition: Vertex.h:108
#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:62
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
bool isValid() const
id_type detId() const
Definition: DetSetNew.h:83
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
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:108
ClusterWithTracks< SiStripCluster > SiStripClusterWithTracks
const Int_t xsize
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
tuple size
Write out results.
float x() const
const std::vector< uint8_t > & amplitudes() const
const std::vector< Pixel > pixels() const
static bool pushfile(int filenum, std::vector< SiStripTemplateStore > &theStripTemp_)
Pixel Reconstructed Hit.
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:109
int size() const
TrackClusterSplitter(const edm::ParameterSet &iConfig)
virtual bool isItBigPixelInY(const int iybin) const =0
iterator begin()
Definition: DetSetNew.h:67