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 #include <memory>
62 using namespace std;
63 
65 {
66 
67 public:
68  TrackClusterSplitter(const edm::ParameterSet& iConfig) ;
70  void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override ;
71 
72 private:
75 
80 
81  // Template splitting needs to know the track direction.
82  // We can use either straight tracks, pixel tracks of fully reconstructed track.
83  // Straight tracks go from the first pixel verterx in the pixel vertex collection
84  // to the cluster center of charge (we use pixel vertices because track vertices are
85  // are not available at this point)
86  // If we set useStraightTracks_ = True, then straight tracks are used
88 
89  // If straight track approximation is not used (useStraightTracks_ = False), then, one can use either fully
90  // reconstructed tracks (useTrajectories_ = True) or pixel tracks ((useTrajectories_ = False).
91  // The use of either straight or fully reconstructed tracks give very similar performance. Use straight tracks
92  // by default because it's faster and less involved. Pixel tracks DO NOT work.
94 
95  // These are either "generalTracks", if useTrajectories_ = True, or "pixelTracks" if useTrajectories_ = False
98 
99  // This is the pixel primary vertex collection
101 
104 
105  // gavril : what is this for ?
110 
111  // This is needed if we want to to sim/truth pixel splitting
113 
114  // This is needed if we want to to sim/truth strip splitting
116 
117 
118  // Template declarations
119  // Pixel templates
120  std::vector< SiPixelTemplateStore > thePixelTemp_;
121  std::vector< SiPixelTemplateStore2D > thePixelTemp2D_;
122  // Strip template
123  std::vector< SiStripTemplateStore > theStripTemp_;
124 
125  // A pointer to a track and a state on the detector
127  {
129  track(aTrack), state(aState) {}
132  };
133 
134  // A pointer to a cluster and a list of tracks on it
135  template<typename Cluster>
137  {
138  ClusterWithTracks(const Cluster &c) : cluster(&c) {}
139  const Cluster* cluster;
140  std::vector<TrackAndState> tracks;
141  };
142 
145 
146 
147  // a subset of a vector, but with vector-like interface.
148  typedef boost::sub_range<std::vector<SiPixelClusterWithTracks> > SiPixelClustersWithTracks;
149  typedef boost::sub_range<std::vector<SiStripClusterWithTracks> > SiStripClustersWithTracks;
150 
151 
152  // sim strip split
153  typedef std::pair<uint32_t, EncodedEventId> SimHitIdpr;
155  std::unique_ptr<TrackerHitAssociator> hitAssociator;
156 
157  template<typename C>
158  static const C* getCluster(const TrackingRecHit* hit) ;
159 
160  template<typename C>
161  static const C* equalClusters(const C &c1, const C &c2)
162  {
163  return nullptr;
164  }
165 
166  // Find a rechit in a vector of ClusterWithTrack
167  template<typename Cluster> class FindCluster
168  {
169 
170  public:
171 
172  FindCluster(const TrackingRecHit* hit) : toFind_( getCluster<Cluster>(hit) ) { }
173 
175  {
176  assert(test.cluster); // make sure this is not 0
177  return test.cluster == toFind_ || equalClusters<Cluster>(*test.cluster, *toFind_);
178  }
179 
180  private:
181 
182  const Cluster* toFind_;
183 
184  };
185 
186  // Attach tracks to cluster ?!?!
187  template<typename Cluster>
188  void markClusters(std::map<uint32_t, boost::sub_range<std::vector<ClusterWithTracks<Cluster> > > >& map,
189  const TrackingRecHit* hit,
190  const reco::Track* track,
191  const TrajectoryStateOnSurface& tsos) const ;
192 
193  template<typename Cluster>
194  std::auto_ptr<edmNew::DetSetVector<Cluster> >
195  splitClusters(const std::map<uint32_t,
196  boost::sub_range<std::vector<ClusterWithTracks<Cluster> > > > &input,
197  const reco::Vertex &vtx) const ;
198 
199  template<typename Cluster>
200  void splitCluster(const ClusterWithTracks<Cluster> &cluster,
201  const GlobalVector &dir,
203  DetId detId) const ;
204 
206  std::vector<SiPixelClusterWithTracks> allSiPixelClusters;
207  std::map<uint32_t, SiPixelClustersWithTracks> siPixelDetsWithClusters;
208 
209  std::vector<SiStripClusterWithTracks> allSiStripClusters;
210  std::map<uint32_t, SiStripClustersWithTracks> siStripDetsWithClusters;
211 
212 
213 };
214 
215 template<> const SiPixelCluster * TrackClusterSplitter::getCluster<SiPixelCluster>(const TrackingRecHit *hit) ;
216 
217 template<>
218 void TrackClusterSplitter::splitCluster<SiPixelCluster> (const SiPixelClusterWithTracks &cluster,
219  const GlobalVector &dir,
221  DetId detId
222  ) const ;
223 
224 template<> const SiStripCluster * TrackClusterSplitter::getCluster<SiStripCluster>(const TrackingRecHit *hit) ;
225 
226 template<>
227 void TrackClusterSplitter::splitCluster<SiStripCluster> (const SiStripClusterWithTracks &cluster,
228  const GlobalVector &dir,
230  DetId detId
231  ) const ;
232 
233 
234 #define foreach BOOST_FOREACH
235 
237  useTrajectories_(iConfig.getParameter<bool>("useTrajectories")),
238  trackerHitAssociatorConfig_(consumesCollector())
239 {
240  if (useTrajectories_) {
241  trajTrackAssociations_ = consumes<TrajTrackAssociationCollection>(iConfig.getParameter<edm::InputTag>("trajTrackAssociations"));
242  } else {
243  propagatorName_ = iConfig.getParameter<std::string>("propagator");
244  tracks_ = consumes<std::vector<reco::Track> >(iConfig.getParameter<edm::InputTag>("tracks"));
245  }
246 
247  pixelClusters_ = consumes<edmNew::DetSetVector<SiPixelCluster> >(iConfig.getParameter<edm::InputTag>("pixelClusters"));
248  stripClusters_ = consumes<edmNew::DetSetVector<SiStripCluster> >(iConfig.getParameter<edm::InputTag>("stripClusters"));
249  vertices_ = consumes<std::vector<reco::Vertex> >(iConfig.getParameter<edm::InputTag>("vertices"));
250 
251  produces< edmNew::DetSetVector<SiPixelCluster> >();
252 
253  produces< edmNew::DetSetVector<SiStripCluster> >();
254 
255  simSplitPixel_ = (iConfig.getParameter<bool>("simSplitPixel"));
256  simSplitStrip_ = (iConfig.getParameter<bool>("simSplitStrip"));
257  tmpSplitPixel_ = (iConfig.getParameter<bool>("tmpSplitPixel")); // not so nice... you don't want two bool but some switch
258  tmpSplitStrip_ = (iConfig.getParameter<bool>("tmpSplitStrip"));
259 
260  useStraightTracks_ = (iConfig.getParameter<bool>("useStraightTracks"));
261 
262 
263  if ( simSplitPixel_ ) pixeldigisimlinkToken = consumes< edm::DetSetVector<PixelDigiSimLink> >(edm::InputTag("simSiPixelDigis"));
264  if ( simSplitStrip_ ) stripdigisimlinkToken = consumes< edm::DetSetVector<StripDigiSimLink> >(edm::InputTag("simSiStripDigis"));
265 
266 
267 
268  /*
269  cout << "TrackClusterSplitter : " << endl;
270  cout << endl << endl << endl;
271  cout << "(int)simSplitPixel_ = " << (int)simSplitPixel_ << endl;
272  cout << "(int)simSplitStrip_ = " << (int)simSplitStrip_ << endl;
273  cout << "(int)tmpSplitPixel_ = " << (int)tmpSplitPixel_ << endl;
274  cout << "(int)tmpSplitStrip_ = " << (int)tmpSplitStrip_ << endl;
275  cout << "stripClusters_ = " << stripClusters_ << endl;
276  cout << "pixelClusters_ = " << pixelClusters_ << endl;
277  cout << "(int)useTrajectories_ = " << (int)useTrajectories_ << endl;
278  cout << "trajectories_ = " << trajectories_ << endl;
279  cout << "propagatorName_ = " << propagatorName_ << endl;
280  cout << "vertices_ = " << vertices_ << endl;
281  cout << "useStraightTracks_ = " << useStraightTracks_ << endl;
282  cout << endl << endl << endl;
283  */
284 
285  // Load template; 40 for barrel and 41 for endcaps
290 
291  // Load strip templates
298 
299 }
300 
301 
302 template<>
303 const SiStripCluster*
304 TrackClusterSplitter::getCluster<SiStripCluster>(const TrackingRecHit* hit)
305 {
306  if ( typeid(*hit) == typeid(SiStripRecHit2D) )
307  {
308  return (static_cast<const SiStripRecHit2D &>(*hit)).cluster().get();
309  }
310  else if ( typeid(*hit) == typeid(SiStripRecHit1D) )
311  {
312  return (static_cast<const SiStripRecHit1D &>(*hit)).cluster().get();
313  }
314  else
315  throw cms::Exception("Unsupported") << "Detid of type " << typeid(*hit).name() << " not supported.\n";
316 }
317 
318 template<>
319 const SiPixelCluster*
320 TrackClusterSplitter::getCluster<SiPixelCluster>(const TrackingRecHit* hit)
321 {
322  if ( typeid(*hit) == typeid(SiPixelRecHit) )
323  {
324  return (static_cast<const SiPixelRecHit&>(*hit)).cluster().get();
325  }
326  else
327  throw cms::Exception("Unsupported") << "Detid of type " << typeid(*hit).name() << " not supported.\n";
328 }
329 
331 {
332 }
333 
334 void
336 {
337  using namespace edm;
338 
340 
341  if ( !useTrajectories_ )
342  {
343  iSetup.get<IdealMagneticFieldRecord>().get( magfield_ );
344  iSetup.get<TrackingComponentsRecord>().get( "AnalyticalPropagator", propagator_ );
345  }
346 
347  Handle<edmNew::DetSetVector<SiPixelCluster> > inputPixelClusters;
348  Handle<edmNew::DetSetVector<SiStripCluster> > inputStripClusters;
349 
350  iEvent.getByToken(pixelClusters_, inputPixelClusters);
351 
352  iEvent.getByToken(stripClusters_, inputStripClusters);
353 
354  if(simSplitStrip_)
356 
357 
360 
361 
362  allSiPixelClusters.reserve(inputPixelClusters->dataSize()); // this is important, otherwise push_back invalidates the iterators
363  allSiStripClusters.reserve(inputStripClusters->dataSize()); // this is important, otherwise push_back invalidates the iterators
364 
365 
366  // fill in the list of all tracks
367  foreach(const edmNew::DetSet<SiPixelCluster> &ds, *inputPixelClusters)
368  {
369  std::vector<SiPixelClusterWithTracks>::iterator start = allSiPixelClusters.end();
370  allSiPixelClusters.insert(start, ds.begin(), ds.end());
371 
372  std::vector<SiPixelClusterWithTracks>::iterator end = allSiPixelClusters.end();
374  }
375 
376  foreach(const edmNew::DetSet<SiStripCluster> &ds, *inputStripClusters)
377  {
378  std::vector<SiStripClusterWithTracks>::iterator start = allSiStripClusters.end();
379  allSiStripClusters.insert(start, ds.begin(), ds.end());
380 
381  std::vector<SiStripClusterWithTracks>::iterator end = allSiStripClusters.end();
383  }
384 
385  if ( useTrajectories_ )
386  {
387  // Here use the fully reconstructed tracks to get the track angle
388 
390  iEvent.getByToken(trajTrackAssociations_, trajectories);
391  for ( TrajTrackAssociationCollection::const_iterator it = trajectories->begin(),
392  ed = trajectories->end(); it != ed; ++it )
393  {
394  const Trajectory & traj = *it->key;
395  const reco::Track * tk = &*it->val;
396 
397  if ( traj.measurements().size() != tk->recHitsSize() )
398  throw cms::Exception("Aargh") << "Sizes don't match: traj " << traj.measurements().size()
399  << ", tk " << tk->recHitsSize() << "\n";
400 
401  trackingRecHit_iterator it_hit = tk->recHitsBegin(), ed_hit = tk->recHitsEnd();
402 
403  const Trajectory::DataContainer & tms = traj.measurements();
404 
405  size_t i_hit = 0, last_hit = tms.size()-1;
406 
407  bool first = true, reversed = false;
408 
409  for (; it_hit != ed_hit; ++it_hit, ++i_hit)
410  {
411  // ignore hits with no detid
412 
413  if ((*it_hit)->geographicalId().rawId() == 0)
414  {
415  //cout << "It should never happen that a trackingRecHit has no detector ID !!!!!!!!!!!!!!!!! " << endl;
416  continue;
417  }
418 
419  // if it's the first hit, check the ordering of track vs trajectory
420  if (first)
421  {
422 
423  if ((*it_hit)->geographicalId() == tms[i_hit].recHit()->hit()->geographicalId())
424  {
425  reversed = false;
426  }
427  else if ((*it_hit)->geographicalId() == tms[last_hit-i_hit].recHit()->hit()->geographicalId())
428  {
429  reversed = true;
430  }
431  else
432  {
433  throw cms::Exception("Aargh") << "DetIDs don't match either way :-( \n";
434  }
435  }
436 
437  const TrackingRecHit *hit = *it_hit;
438  if ( hit == 0 || !hit->isValid() )
439  continue;
440 
441  int subdet = hit->geographicalId().subdetId();
442 
443  if (subdet >= 3)
444  { // strip
445  markClusters<SiStripCluster>(siStripDetsWithClusters, hit, tk, tms[reversed ? last_hit-i_hit : i_hit].updatedState());
446  }
447  else if (subdet >= 1)
448  { // pixel
449  markClusters<SiPixelCluster>(siPixelDetsWithClusters, hit, tk, tms[reversed ? last_hit-i_hit : i_hit].updatedState());
450  }
451  else
452  {
453  edm::LogWarning("HitNotFound") << "Hit of type " << typeid(*hit).name() << ", detid "
454  << hit->geographicalId().rawId() << ", subdet " << subdet;
455  }
456  }
457  }
458  }
459  else
460  {
461  // Here use the pixel tracks to get the track angles
462 
464  iEvent.getByToken(tracks_, tracks);
465  //TrajectoryStateTransform transform;
466  foreach (const reco::Track &track, *tracks)
467  {
469  trackingRecHit_iterator it_hit = track.recHitsBegin(), ed_hit = track.recHitsEnd();
470  for (; it_hit != ed_hit; ++it_hit)
471  {
472  const TrackingRecHit *hit = *it_hit;
473  if ( hit == 0 || !hit->isValid() )
474  continue;
475 
476  int subdet = hit->geographicalId().subdetId();
477 
478  if ( subdet == 0 )
479  continue;
480 
481  const GeomDet *det = geometry_->idToDet( hit->geographicalId() );
482 
483  if ( det == 0 )
484  {
485  edm::LogError("MissingDetId") << "DetIDs " << (int)(hit->geographicalId()) << " is not in geometry.\n";
486  continue;
487  }
488 
489  TrajectoryStateOnSurface prop = propagator_->propagate(atVtx, det->surface());
490  if ( subdet >= 3 )
491  { // strip
492  markClusters<SiStripCluster>(siStripDetsWithClusters, hit, &track, prop);
493  }
494  else if (subdet >= 1)
495  { // pixel
496  markClusters<SiPixelCluster>(siPixelDetsWithClusters, hit, &track, prop);
497  }
498  else
499  {
500  edm::LogWarning("HitNotFound") << "Hit of type " << typeid(*hit).name() << ", detid "
501  << hit->geographicalId().rawId() << ", subdet " << subdet;
502  }
503  }
504  }
505  }
506 
508  iEvent.getByToken(vertices_, vertices);
509 
510  // Needed in case of simsplit
511  if ( simSplitPixel_ )
513 
514  // Needed in case of strip simsplit
515  if ( simSplitStrip_ )
517 
518  // gavril : to do: choose the best vertex here instead of just choosing the first one ?
519  std::auto_ptr<edmNew::DetSetVector<SiPixelCluster> > newPixelClusters( splitClusters( siPixelDetsWithClusters, vertices->front() ) );
520  std::auto_ptr<edmNew::DetSetVector<SiStripCluster> > newStripClusters( splitClusters( siStripDetsWithClusters, vertices->front() ) );
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  auto const & 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  }
681 
682  // Now deal with this new DigiSimLink
683  thisTrackID = linkiter->SimTrackId();
684 
685  // Have we seen this track yet?
686  bool newTrack = true;
687  int thisTrackIdx = 9999;
688 
689  for (size_t i=0; i<trackID.size(); ++i)
690  {
691  if ( trackID[i] == thisTrackID )
692  {
693  thisTrackIdx = i;
694  newTrack = false;
695  }
696  }
697 
698  if ( newTrack )
699  {
700  trackInStrip.push_back(false); // We'll set it true below
701  trackID.push_back(thisTrackID);
702  firstStrip.push_back(currentChannel);
703  std::vector<uint16_t> ampTmp;
704  trackAmp.push_back(ampTmp);
705  trackFraction.push_back(0);
706  thisTrackIdx = trackID.size()-1;
707  }
708 
709  trackInStrip[thisTrackIdx] = true;
710  trackFraction[thisTrackIdx] += linkiter->fraction();
711  currentAmpl = rawAmpl;
712 
713  }
714 
715  }// end of loop over DigiSimLinks
716 
717  // we want to continue here!!!!
718 
719  std::vector<SiStripCluster> newCluster;
720  // Fill amplitudes for the last strip and create a cluster for each track
721  uint16_t thisAmpl;
722 
723  for (size_t i=0; i < trackID.size(); ++i)
724  {
725  if ( trackInStrip[i] )
726  {
727  if ( ( thisAmpl=rawAmpl ) < 254 )
728  thisAmpl = min(uint16_t(253), max(uint16_t(0), (uint16_t)(rawAmpl*trackFraction[i]+0.5)));
729 
730  if ( thisAmpl > 0 )
731  trackAmp[i].push_back( thisAmpl );
732  //else
733  //cout << "thisAmpl = " << (int)thisAmpl << endl;
734  }
735 
736  newCluster.push_back( SiStripCluster(
737  firstStrip[i],
738  trackAmp[i].begin(),
739  trackAmp[i].end() ) );
740 
741  }
742 
743 
744  for ( size_t i=0; i<newCluster.size(); ++i )
745  {
746 
747  // gavril : This is never used. Will use it below
748  float clusterAmp = 0.0;
749  for (size_t j=0; j<trackAmp[i].size(); ++j )
750  clusterAmp += (float)(trackAmp[i])[j];
751 
752  if ( clusterAmp > 0.0 && firstStrip[i] != 9999 && trackAmp[i].size() > 0 )
753  {
754  // gavril : I think this should work
755  output.push_back( newCluster[i] );
756 
757  //cout << endl << endl << endl;
758  //cout << "(int)(newCluster[i].amplitudes().size()) = " << (int)(newCluster[i].amplitudes().size()) << endl;
759  //for ( int j=0; j<(int)(newCluster[i].amplitudes().size()); ++j )
760  //cout << "(newCluster[i].amplitudes())[j] = " << (int)(newCluster[i].amplitudes())[j] << endl;
761 
762  cluster_was_successfully_split = true;
763  }
764  else
765  {
766  //std::cout << "\t\t Rejecting new cluster" << std::endl;
767 
768  // gavril : I think this pointer should be deleted above
769  //delete newCluster[i];
770  }
771  }
772 
773  } // if ( isearch != stripdigisimlink->end() ) ...
774  else
775  {
776  // Do nothing...
777  }
778  }
779 
780 
781  if ( !cluster_was_successfully_split )
782  output.push_back( *c.cluster );
783 
784  } // end of if ( strip_simSplit_ )...
785 
786  else if ( tmpSplitStrip_ )
787  {
788  bool cluster_was_successfully_split = false;
789 
790  const SiStripCluster* theStripCluster = static_cast<const SiStripCluster*>(c.cluster);
791 
792  if ( theStripCluster )
793  {
794  //SiStripDetId ssdid( theStripCluster->geographicalId() );
795  SiStripDetId ssdid( detId.rawId() );
796 
797  // Do not attempt to split clusters of size less than or equal to one.
798  // Only split clusters in IB1, IB2, OB1, OB2 (TIB and TOB).
799 
800  if ( (int)theStripCluster->amplitudes().size() <= 1 ||
801  ( (int)ssdid.moduleGeometry() != 1 &&
802  (int)ssdid.moduleGeometry() != 2 &&
803  (int)ssdid.moduleGeometry() != 3 &&
804  (int)ssdid.moduleGeometry() != 4 ) )
805  {
806  // Do nothing.
807  //cout << endl;
808  //cout << "Will NOT attempt to split this clusters: " << endl;
809  //cout << "(int)theStripCluster->amplitudes().size() = " << (int)theStripCluster->amplitudes().size() << endl;
810  //cout << "(int)ssdid.moduleGeometry() = " << (int)ssdid.moduleGeometry() << endl;
811 
812  }
813  else // if ( (int)theStripCluster->amplitudes().size() <= 1 )
814  {
815 
816  //cout << endl;
817  //cout << "Will attempt to split this clusters: " << endl;
818 
819  int ID = -99999;
820 
821  int is_stereo = (int)( ssdid.stereo() );
822 
823  if ( ssdid.moduleGeometry() == 1 ) // IB1
824  {
825  if ( !is_stereo )
826  ID = 11;
827  else
828  ID = 12;
829  }
830  else if ( ssdid.moduleGeometry() == 2 ) // IB2
831  {
832  ID = 13;
833  }
834  else if ( ssdid.moduleGeometry() == 3 ) // OB1
835  {
836  ID = 16;
837  }
838  else if ( ssdid.moduleGeometry() == 4 ) // OB2
839  {
840  if ( !is_stereo )
841  ID = 14;
842  else
843  ID = 15;
844  }
845  else
846  {
847  throw cms::Exception("TrackClusterSplitter::splitCluster")
848  << "\nERROR: Wrong strip teplate ID. Should only use templates for IB1, IB2, OB1 and OB2 !!!" << "\n\n";
849  }
850 
851 
852 
853 
854  // Begin: determine incident angles ============================================================
855 
856  float cotalpha_ = -99999.9;
857  float cotbeta_ = -99999.9;
858 
859  // First, determine track angles from straight track approximation
860 
861  // Find crude cluster center
862  // gavril : This is in local coordinates ?
863  float xcenter = theStripCluster->barycenter();
864 
865  const GeomDetUnit* theDet = geometry_->idToDetUnit( detId );
866  const StripGeomDetUnit* stripDet = dynamic_cast<const StripGeomDetUnit*>( theDet );
867 
868  if ( !stripDet )
869  {
870  throw cms::Exception("TrackClusterSplitter : ")
871  << "\nERROR: Wrong stripDet !!! " << "\n\n";
872  }
873 
874 
875  const StripTopology* theTopol = &( stripDet->specificTopology() );
876 
877  // Transform from measurement to local coordinates (in cm)
878  // gavril: may have to differently if kicks/bows are introduced. However, at this point there are no tracks...:
879  // LocalPoint lp = theTopol->localPosition( xcenter, /*const Topology::LocalTrackPred & */ trkPred );
880 
881  // gavril : What is lp.y() for strips ? It is zero, but is that the strip center or one of the ends ?
882  LocalPoint lp = theTopol->localPosition( xcenter );
883 
884  // Transform from local to global coordinates
885  GlobalPoint gp0 = theDet->surface().toGlobal( lp );
886 
887  // Make a vector pointing from the PV to the cluster center
888  GlobalPoint gp(gp0.x()-vtx.x(), gp0.y()-vtx.y(), gp0.z()-vtx.z() );
889 
890  // Make gp a unit vector, gv, pointing from the PV to the cluster center
891  float gp_mod = sqrt( gp.x()*gp.x() + gp.y()*gp.y() + gp.z()*gp.z() );
892  float gpx = gp.x()/gp_mod;
893  float gpy = gp.y()/gp_mod;
894  float gpz = gp.z()/gp_mod;
895  GlobalVector gv(gpx, gpy, gpz);
896 
897  // Make unit vectors in local coordinates and then transform them in global coordinates
898  const Local3DVector lvx(1.0, 0.0, 0.0);
899  GlobalVector gvx = theDet->surface().toGlobal( lvx );
900  const Local3DVector lvy(0.0, 1.0, 0.0);
901  GlobalVector gvy = theDet->surface().toGlobal( lvy );
902  const Local3DVector lvz(0.0, 0.0, 1.0);
903  GlobalVector gvz = theDet->surface().toGlobal( lvz );
904 
905  // Calculate angles alpha and beta
906  float gv_dot_gvx = gv.x()*gvx.x() + gv.y()*gvx.y() + gv.z()*gvx.z();
907  float gv_dot_gvy = gv.x()*gvy.x() + gv.y()*gvy.y() + gv.z()*gvy.z();
908  float gv_dot_gvz = gv.x()*gvz.x() + gv.y()*gvz.y() + gv.z()*gvz.z();
909 
910  // gavril : check beta !!!!!!!!!!!!
911  //float alpha_ = atan2( gv_dot_gvz, gv_dot_gvx );
912  //float beta_ = atan2( gv_dot_gvz, gv_dot_gvy );
913 
914  cotalpha_ = gv_dot_gvx / gv_dot_gvz;
915  cotbeta_ = gv_dot_gvy / gv_dot_gvz;
916 
917  // Attempt to get a better angle from tracks (either pixel tracks or full tracks)
918  if ( !useStraightTracks_ )
919  {
920  //cout << "TrackClusterSplitter.cc : " << endl;
921  //cout << "Should not be here for now !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
922 
923  // Use either pixel tracks (useTrajectories_ = False) or fully reconstructed tracks (useTrajectories_ = True)
924  // When pixel/full tracks are not associated with the current cluster, will use angles from straight tracks
925 
926  // These are the tracks associated with this cluster
927  std::vector<TrackAndState> vec_tracks_states = c.tracks;
928 
929  if ( (int)vec_tracks_states.size() > 0 )
930  {
931  //cout << "There is at least one track associated with this cluster. Pick the one with largest Pt." << endl;
932  //cout << "(int)vec_tracks_states.size() = " << (int)vec_tracks_states.size() << endl;
933 
934  int index_max_pt = -99999; // index of the track with the highest Pt
935  float max_pt = -99999.9;
936 
937  for (int i=0; i<(int)vec_tracks_states.size(); ++i )
938  {
939  const reco::Track* one_track = vec_tracks_states[i].track;
940 
941  if ( one_track->pt() > max_pt )
942  {
943  index_max_pt = i;
944  max_pt = one_track->pt();
945  }
946  }
947 
948  // Pick the tsos from the track with highest Pt
949  // gavril: Should we use highest Pt or best Chi2 ?
950  TrajectoryStateOnSurface one_tsos = vec_tracks_states[index_max_pt].state;
951 
953 
954  LocalVector localDir = ltp.momentum()/ltp.momentum().mag();
955 
956  float locx = localDir.x();
957  float locy = localDir.y();
958  float locz = localDir.z();
959 
960  //alpha_ = atan2( locz, locx );
961  //beta_ = atan2( locz, locy );
962 
963  cotalpha_ = locx/locz;
964  cotbeta_ = locy/locz;
965 
966  } // if ( (int)vec_tracks_states.size() > 0 )
967 
968  } // if ( !useStraightTracks_ )
969 
970 
971  // End: determine incident angles ============================================================
972 
973 
974  // Calculate strip cluster charge and store amplitudes in vector for later use
975 
976  //cout << endl;
977  //cout << "Calculate strip cluster charge and store amplitudes in vector for later use" << endl;
978 
979  float strip_cluster_charge = 0.0;
980  std::vector<float> vec_cluster_charge;
981  vec_cluster_charge.clear();
982  int cluster_size = (int)( (theStripCluster->amplitudes()).size() );
983 
984  int cluster_charge = 0;
985  for (int i=0; i<cluster_size; ++i)
986  {
987  float current_strip_charge = (float)( (theStripCluster->amplitudes())[i] );
988 
989  strip_cluster_charge += current_strip_charge;
990  vec_cluster_charge.push_back( current_strip_charge );
991 
992  cluster_charge +=current_strip_charge;
993  }
994 
995 
996  //cout << endl;
997  //cout << "Calling strip qbin to see if the strip cluster has to be split..." << endl;
998  SiStripTemplate strip_templ_(theStripTemp_);
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( 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( 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;
1485  int templQbin_ = templ_.qbin( ID, cotalpha_, cotbeta_, thePixelCluster->charge() );
1486 
1487  if ( templQbin_ < 0 || templQbin_ > 5 )
1488  {
1489  // gavril : check this....
1490  // cout << "Template call failed. Cannot decide if cluster should be split !!!!!!! " << endl;
1491  // cout << "Do nothing." << endl;
1492  }
1493  else // if ( templQbin_ < 0 || templQbin_ > 5 ) {...} else
1494  {
1495  //cout << " Returned OK from PixelTempReco2D..." << endl;
1496 
1497  // Check for split clusters: we split the clusters with larger than expected charge: templQbin_ == 0
1498  if ( templQbin_ != 0 )
1499  {
1500  // gavril: do not split this cluster
1501  //cout << "TEMPLATE SPLITTER SAYS : NO SPLIT " << endl;
1502  //cout << "This cluster will note be split !!!!!!!!!! " << endl;
1503  }
1504  else // if ( templQbin_ != 0 ) {...} else
1505  {
1506  //cout << "TEMPLATE SPLITTER SAYS : SPLIT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
1507  //cout << "Found a cluster that has to be split. templQbin_ = " << templQbin_ << endl;
1508 
1509  // gavril: Call the template splitter
1510  //cout << "Calling the splitter..." << endl;
1511 
1512  // Put the pixels of this clusters in a 2x2 array to be used by the template splitter
1513 
1514  const std::vector<SiPixelCluster::Pixel> & pixVec = thePixelCluster->pixels();
1515  std::vector<SiPixelCluster::Pixel>::const_iterator pixIter = pixVec.begin(), pixEnd = pixVec.end();
1516 
1517  const int cluster_matrix_size_x = 13;
1518  const int cluster_matrix_size_y = 21;
1519 
1520  boost::multi_array<float, 2> clust_array_2d(boost::extents[cluster_matrix_size_x][cluster_matrix_size_y]);
1521 
1522  int row_offset = thePixelCluster->minPixelRow();
1523  int col_offset = thePixelCluster->minPixelCol();
1524 
1525  // Copy clust's pixels (calibrated in electrons) into clust_array_2d;
1526 
1527  for ( ; pixIter != pixEnd; ++pixIter )
1528  {
1529  int irow = int(pixIter->x) - row_offset; // do we need +0.5 ???
1530  int icol = int(pixIter->y) - col_offset; // do we need +0.5 ???
1531 
1532  if ( irow<cluster_matrix_size_x && icol<cluster_matrix_size_y )
1533  {
1534  clust_array_2d[irow][icol] = (float)pixIter->adc;
1535  }
1536  }
1537 
1538  // Make and fill the bool arrays flagging double pixels
1539  std::vector<bool> ydouble(cluster_matrix_size_y), xdouble(cluster_matrix_size_x);
1540 
1541  // x directions (shorter), rows
1542  for (int irow = 0; irow < cluster_matrix_size_x; ++irow)
1543  {
1544  xdouble[irow] = theTopol->isItBigPixelInX( irow+row_offset );
1545  }
1546 
1547  // y directions (longer), columns
1548  for (int icol = 0; icol < cluster_matrix_size_y; ++icol)
1549  {
1550  ydouble[icol] = theTopol->isItBigPixelInY( icol+col_offset );
1551  }
1552 
1553  // gavril: Initialize values coming back from SiPixelTemplateSplit::PixelTempSplit
1554  float templYrec1_ = -99999.9;
1555  float templYrec2_ = -99999.9;
1556  float templSigmaY_ = -99999.9;
1557  float templProbY_ = -99999.9;
1558  float templXrec1_ = -99999.9;
1559  float templXrec2_ = -99999.9;
1560  float templSigmaX_ = -99999.9;
1561  float templProbX_ = -99999.9;
1562  float dchisq = -99999.9;
1563  float templProbQ_ = -99999.9;
1564 
1565  int ierr =
1567  cotalpha_, cotbeta_,
1568  clust_array_2d,
1569  ydouble, xdouble,
1570  templ_,
1571  templYrec1_, templYrec2_, templSigmaY_, templProbY_,
1572  templXrec1_, templXrec2_, templSigmaX_, templProbX_,
1573  templQbin_,
1574  templProbQ_,
1575  true,
1576  dchisq,
1577  templ2D_ );
1578 
1579  if ( ierr != 0 )
1580  {
1581  // cout << "Cluster splitting failed: ierr = " << ierr << endl;
1582  }
1583  else
1584  {
1585  // gavril: Cluster was successfully split.
1586  // gavril: Make the two split clusters and put them in the split cluster collection
1587  //cout << "Cluster splitting OK: ierr = " << ierr << endl;
1588 
1589  // 2D templates have origin at the lower left corner of template2d[1][1] which is
1590  // also 2 pixels larger than the cluster container
1591 
1592  float xsize = templ_.xsize(); // this is the pixel x-size in microns
1593  float ysize = templ_.ysize(); // this is the pixel y-size in microns
1594 
1595  // Shift the coordinates to the 2-D template system
1596  float yrecp1 = -99999.9;
1597  float yrecp2 = -99999.9;
1598  float xrecp1 = -99999.9;
1599  float xrecp2 = -99999.9;
1600 
1601  if ( ydouble[0] )
1602  {
1603  yrecp1 = templYrec1_ + ysize;
1604  yrecp2 = templYrec2_ + ysize;
1605  }
1606  else
1607  {
1608  yrecp1 = templYrec1_ + ysize/2.0;
1609  yrecp2 = templYrec2_ + ysize/2.0;
1610  }
1611 
1612  if ( xdouble[0] )
1613  {
1614  xrecp1 = templXrec1_ + xsize;
1615  xrecp2 = templXrec2_ + xsize;
1616  }
1617  else
1618  {
1619  xrecp1 = templXrec1_ + xsize/2.0;
1620  xrecp2 = templXrec2_ + xsize/2.0;
1621  }
1622 
1623  // The xytemp method adds charge to a zeroed buffer
1624 
1625  float template2d1[BXM2][BYM2];
1626  float template2d2[BXM2][BYM2];
1627 
1628  for ( int j=0; j<BXM2; ++j )
1629  {
1630  for ( int i=0; i<BYM2; ++i )
1631  {
1632  template2d1[j][i] = 0.0;
1633  template2d2[j][i] = 0.0;
1634  }
1635  }
1636 
1637 
1638  bool template_OK
1639  = templ2D_.xytemp(ID, cotalpha_, cotbeta_,
1640  xrecp1, yrecp1,
1641  ydouble, xdouble,
1642  template2d1);
1643 
1644  template_OK
1645  = template_OK &&
1646  templ2D_.xytemp(ID, cotalpha_, cotbeta_,
1647  xrecp2, yrecp2,
1648  ydouble, xdouble,
1649  template2d2);
1650 
1651  if ( !template_OK )
1652  {
1653  // gavril: check this
1654  //cout << "Template is not OK. Fill out with zeros !!!!!!!!!!!!!!! " << endl;
1655 
1656  for ( int j=0; j<BXM2; ++j )
1657  {
1658  for ( int i=0; i<BYM2; ++i )
1659  {
1660  template2d1[j][i] = 0.0;
1661  template2d2[j][i] = 0.0;
1662  }
1663  }
1664 
1665  if ( !templ_.simpletemplate2D(xrecp1, yrecp1,
1666  xdouble, ydouble,
1667  template2d1) )
1668  {
1669  cluster_was_successfully_split = false;
1670  }
1671 
1672  if ( !templ_.simpletemplate2D(xrecp2, yrecp2,
1673  xdouble, ydouble,
1674  template2d2) )
1675  {
1676  cluster_was_successfully_split = false;
1677  }
1678 
1679  } // if ( !template_OK )
1680  else
1681  {
1682  cluster_was_successfully_split = true;
1683 
1684  // Next, copy the 2-d templates into cluster containers, replace small signals with zero.
1685  // Cluster 1 and cluster 2 should line up with clust_array_2d (same origin and pixel indexing)
1686 
1687  float q50 = templ_.s50();
1688 
1689 
1690  float cluster1[TXSIZE][TYSIZE];
1691  float cluster2[TXSIZE][TYSIZE]; //Note that TXSIZE = BXM2 - 2, TYSIZE = BYM2 - 2
1692 
1693  for ( int j=0; j<TXSIZE; ++j )
1694  {
1695  for ( int i=0; i<TYSIZE; ++i )
1696  {
1697  cluster1[j][i] = template2d1[j+1][i+1];
1698 
1699  if ( cluster1[j][i] < q50 )
1700  cluster1[j][i] = 0.0;
1701 
1702  cluster2[j][i] = template2d2[j+1][i+1];
1703 
1704  if ( cluster2[j][i] < q50 )
1705  cluster2[j][i] = 0.0;
1706 
1707  //cout << "cluster1[j][i] = " << cluster1[j][i] << endl;
1708  //cout << "cluster2[j][i] = " << cluster2[j][i] << endl;
1709  }
1710  }
1711 
1712 
1713  // Find the coordinates of first pixel in each of the two split clusters
1714  int i1 = -999;
1715  int j1 = -999;
1716  int i2 = -999;
1717  int j2 = -999;
1718 
1719  bool done_searching = false;
1720  for ( int i=0; i<13 && !done_searching; ++i)
1721  {
1722  for (int j=0; j<21 && !done_searching; ++j)
1723  {
1724  if ( cluster1[i][j] > 0 )
1725  {
1726  i1 = i;
1727  j1 = j;
1728  done_searching = true;
1729  }
1730  }
1731  }
1732 
1733  done_searching = false;
1734  for ( int i=0; i<13 && !done_searching; ++i)
1735  {
1736  for (int j=0; j<21 && !done_searching; ++j)
1737  {
1738  if ( cluster2[i][j] > 0 )
1739  {
1740  i2 = i;
1741  j2 = j;
1742  done_searching = true;
1743  }
1744  }
1745  }
1746 
1747 
1748  // Make clusters out of the first pixels in each of the two split clsuters
1749 
1750  SiPixelCluster cl1( SiPixelCluster::PixelPos( i1 + row_offset, j1 + col_offset),
1751  cluster1[i1][j1] );
1752 
1753  SiPixelCluster cl2( SiPixelCluster::PixelPos( i2 + row_offset, j2 + col_offset),
1754  cluster2[i2][j2] );
1755 
1756 
1757  // Now add the rest of the pixels to the split clusters
1758 
1759  for ( int i=0; i<13; ++i)
1760  {
1761  for (int j=0; j<21; ++j)
1762  {
1763 
1764  if ( cluster1[i][j] > 0.0 && (i!=i1 || j!=j1 ) )
1765  {
1766  cl1.add( SiPixelCluster::PixelPos( i + row_offset, j + col_offset),
1767  cluster1[i][j] );
1768 
1769  //cout << "cluster1[i][j] = " << cluster1[i][j] << endl;
1770  }
1771 
1772 
1773  if ( cluster2[i][j] > 0.0 && (i!=i2 || j!=j2 ) )
1774  {
1775  cl2.add( SiPixelCluster::PixelPos( i + row_offset, j + col_offset),
1776  cluster2[i][j] );
1777 
1778  //cout << "cluster2[i][j] = " << cluster2[i][j] << endl;
1779  }
1780  }
1781  }
1782 
1783  // Attach errors and probabilities to the split Clusters
1784  // The errors will be later attahed to the SiPixelRecHit
1785 
1786 
1787  cl1.setSplitClusterErrorX( templSigmaX_ );
1788  cl1.setSplitClusterErrorY( templSigmaY_ );
1789  //cl1.prob_q = templProbQ_;
1790 
1791  cl2.setSplitClusterErrorX( templSigmaX_ );
1792  cl2.setSplitClusterErrorY( templSigmaY_ );
1793  //cl2.prob_q = templProbQ_;
1794 
1795 
1796  // Save the split clusters
1797  output.push_back( cl1 );
1798  output.push_back( cl2 );
1799 
1800  // Some sanity checks
1801 
1802  if ( (int)cl1.size() <= 0 )
1803  {
1804  edm::LogError("TrackClusterSplitter : ")
1805  << "1) Cluster of size = " << (int)cl1.size() << " !!! " << endl;
1806  }
1807 
1808  if ( (int)cl2.size() <= 0 )
1809  {
1810  edm::LogError("TrackClusterSplitter : ")
1811  << "2) Cluster of size = " << (int)cl2.size() << " !!! " << endl;
1812  }
1813 
1814  if ( cl1.charge() <= 0 )
1815  {
1816  edm::LogError("TrackClusterSplitter : ")
1817  << "1) Cluster of charge = " << (int)cl1.charge() << " !!! " << endl;
1818 
1819  }
1820 
1821  if ( cl2.charge() <= 0 )
1822  {
1823  edm::LogError("TrackClusterSplitter : ")
1824  << "2) Cluster of charge = " << (int)cl2.charge() << " !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
1825  }
1826 
1827 
1828  } // if ( !template_OK ) ... else
1829 
1830  } // if ( ierr2 != 0 ) ... else
1831 
1832  } // if ( templQbin_ != 0 ) ... else
1833 
1834  } // else // if ( templQbin_ < 0 || templQbin_ > 5 ) {...} else
1835 
1836  } // if ( (int)thePixelCluster->size() <= 1 ) {... } else
1837 
1838  if ( !cluster_was_successfully_split )
1839  output.push_back(*c.cluster);
1840 
1841  } // if ( theSiPixelCluster )
1842  else
1843  {
1844  throw cms::Exception("TrackClusterSplitter :")
1845  << "This is not a SiPixelCluster !!! " << "\n";
1846  }
1847  }
1848  else
1849  {
1850  // gavril : Neither sim nor template splitter. Just add the cluster as it was.
1851  // original from G.P.
1852  output.push_back( *c.cluster );
1853  }
1854 }
1855 
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:106
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
TrackerHitAssociator::Config trackerHitAssociatorConfig_
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:462
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:103
static bool pushfile(int filenum, std::vector< SiPixelTemplateStore2D > &thePixelTemp_)
uint32_t ID
Definition: Definitions.h:26
assert(m_qm.get())
static bool pushfile(int filenum, std::vector< SiPixelTemplateStore > &thePixelTemp_)
T y() const
Definition: PV3DBase.h:63
bool simpletemplate2D(float xhitp, float yhitp, std::vector< bool > &ydouble, std::vector< bool > &xdouble, float template2d[13+2][21+2])
Make simple 2-D templates from track angles set in interpolate and hit position.
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
static std::string const input
Definition: EdmProvDump.cc:44
#define BXM2
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:250
edm::ESHandle< MagneticField > magfield_
Measurement2DPoint MeasurementPoint
Measurement points are two-dimensional by default.
int iEvent
Definition: GenABIO.cc:230
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:44
T mag() const
Definition: PV3DBase.h:67
int minPixelRow() const
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:121
T sqrt(T t)
Definition: SSEVec.h:18
double pt() const
track transverse momentum
Definition: TrackBase.h:616
T z() const
Definition: PV3DBase.h:64
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:105
edm::ESHandle< GlobalTrackingGeometry > geometry_
float xsize()
pixel x-size (microns)
#define BYM2
float barycenter() const
tuple trajectories
#define end
Definition: vmac.h:37
void add(const PixelPos &pix, int adc)
LocalVector momentum() const
Momentum vector in the local frame.
T min(T a, T b)
Definition: MathUtil.h:58
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
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
bool xytemp(int id, float cotalpha, float cotbeta, float locBz, float xhit, float yhit, std::vector< bool > &ydouble, std::vector< bool > &xdouble, float template2d[13+2][21+2])
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:101
#define TYSIZE
tuple tracks
Definition: testEve_cfg.py:39
void sxtemp(float xhit, std::vector< float > &cluster)
const T & get() const
Definition: EventSetup.h:56
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:84
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::unique_ptr< TrackerHitAssociator > hitAssociator
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
DetId geographicalId() const
dbl *** dir
Definition: mlp_gen.cc:35
FreeTrajectoryState innerFreeState(const reco::Track &tk, const MagneticField *field, bool withErr=true)
ModuleGeometry moduleGeometry() const
Definition: SiStripDetId.h:134
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:104
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_)
TrackingRecHitCollection::base::const_iterator trackingRecHit_iterator
iterator over a vector of reference to TrackingRecHit in the same collection
Our base class.
Definition: SiPixelRecHit.h:23
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