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