CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
StripSubClusterShapeTrajectoryFilter.cc
Go to the documentation of this file.
2 
3 #include <map>
4 #include <set>
5 #include <algorithm>
6 
33 
36 
37 #ifdef StripSubClusterShapeFilterBase_COUNTERS
38 #define INC_COUNTER(X) X++;
39 #else
40 #define INC_COUNTER(X)
41 #endif
42 namespace {
43  class SlidingPeakFinder {
44  public:
45  SlidingPeakFinder(unsigned int size) :
46  size_(size), half_((size+1)/2) {}
47 
48  template<typename Test>
49  bool apply(const uint8_t *x, const uint8_t *begin, const uint8_t *end, const Test & test, bool verbose=false, int firststrip=0) {
50  const uint8_t * ileft = (x != begin) ? std::min_element(x-1,x+half_) : begin - 1;
51  const uint8_t * iright = ((x+size_) < end) ? std::min_element(x+half_,std::min(x+size_+1,end)) : end;
52  uint8_t left = (ileft < begin ? 0 : *ileft );
53  uint8_t right = (iright >= end ? 0 : *iright);
54  uint8_t center = *std::max_element(x, std::min(x+size_,end));
55  uint8_t maxmin = std::max(left,right);
56  if (maxmin < center) {
57  bool ret = test(center, maxmin);
58  if (ret) {
59  ret = test(ileft,iright,begin,end);
60  }
61  return ret;
62  } else {
63  return false;
64  }
65  }
66 
67  template<typename V, typename Test>
68  bool apply(const V & ampls, const Test & test, bool verbose=false, int firststrip=0) {
69  const uint8_t *begin = &*ampls.begin();
70  const uint8_t *end = &*ampls.end();
71  for (const uint8_t *x = begin; x < end - (half_-1); ++x) {
72  if (apply(x,begin,end,test,verbose,firststrip)) {
73  return true;
74  }
75  }
76  return false;
77  }
78 
79  private:
80  unsigned int size_, half_;
81 
82  };
83 
84  struct PeakFinderTest {
85  PeakFinderTest(float mip, uint32_t detid, uint32_t firstStrip, const SiStripNoises *theNoise,
86  float seedCutMIPs, float seedCutSN,
87  float subclusterCutMIPs, float subclusterCutSN) :
88  mip_(mip), detid_(detid), firstStrip_(firstStrip), noiseObj_(theNoise), noises_(theNoise->getRange(detid)),
89  subclusterCutMIPs_(subclusterCutMIPs), sumCut_(subclusterCutMIPs_*mip_), subclusterCutSN2_(subclusterCutSN*subclusterCutSN)
90  {
91  cut_ = std::min<float>(seedCutMIPs*mip, seedCutSN*noiseObj_->getNoise(firstStrip+1, noises_));
92  }
93 
94  bool operator()(uint8_t max, uint8_t min) const {
95  return max-min > cut_;
96  }
97  bool operator()(const uint8_t *left, const uint8_t *right, const uint8_t *begin, const uint8_t *end) const {
98  int yleft = (left < begin ? 0 : *left);
99  int yright = (right >= end ? 0 : *right);
100  float sum = 0.0;
101  int maxval = 0; float noise = 0;
102  for (const uint8_t *x = left+1; x < right; ++x) {
103  int baseline = (yleft * int(right-x) + yright * int(x-left)) / int(right-left);
104  sum += int(*x) - baseline;
105  noise += std::pow(noiseObj_->getNoise(firstStrip_ + int(x-begin), noises_), 2);
106  maxval = std::max(maxval, int(*x) - baseline);
107  }
108  if (sum > sumCut_ && sum*sum > noise*subclusterCutSN2_) return true;
109  return false;
110  }
111 
112  private:
113  float mip_;
114  unsigned int detid_; int firstStrip_;
115  const SiStripNoises *noiseObj_;
116  SiStripNoises::Range noises_;
117  uint8_t cut_;
118  float subclusterCutMIPs_, sumCut_, subclusterCutSN2_;
119  };
120 
121 }
122 
123 /*****************************************************************************/
126  label_(iCfg.getUntrackedParameter<std::string>("label","")),
127  maxNSat_(iCfg.getParameter<uint32_t>("maxNSat")),
128  trimMaxADC_(iCfg.getParameter<double>("trimMaxADC")),
129  trimMaxFracTotal_(iCfg.getParameter<double>("trimMaxFracTotal")),
130  trimMaxFracNeigh_(iCfg.getParameter<double>("trimMaxFracNeigh")),
131  maxTrimmedSizeDiffPos_(iCfg.getParameter<double>("maxTrimmedSizeDiffPos")),
132  maxTrimmedSizeDiffNeg_(iCfg.getParameter<double>("maxTrimmedSizeDiffNeg")),
133  subclusterWindow_(iCfg.getParameter<double>("subclusterWindow")),
134  seedCutMIPs_(iCfg.getParameter<double>("seedCutMIPs")),
135  seedCutSN_(iCfg.getParameter<double>("seedCutSN")),
136  subclusterCutMIPs_(iCfg.getParameter<double>("subclusterCutMIPs")),
137  subclusterCutSN_(iCfg.getParameter<double>("subclusterCutSN"))
138 #ifdef StripSubClusterShapeFilterBase_COUNTERS
139  ,called_(0),saturated_(0),test_(0),passTrim_(0),failTooLarge_(0),passSC_(0),failTooNarrow_(0)
140 #endif
141 {
142  if (iCfg.exists("layerMask")) {
143  const edm::ParameterSet &iLM = iCfg.getParameter<edm::ParameterSet>("layerMask");
144  const char *ndets[4] = { "TIB", "TID", "TOB", "TEC" };
145  const int idets[4] = { 3, 4, 5, 6 };
146  for (unsigned int i = 0; i < 4; ++i) {
147  if (iLM.existsAs<bool>(ndets[i])) {
148  std::fill(layerMask_[idets[i]].begin(), layerMask_[idets[i]].end(), iLM.getParameter<bool>(ndets[i]));
149  } else {
150  layerMask_[idets[i]][0] = 2;
151  std::fill(layerMask_[idets[i]].begin()+1, layerMask_[idets[i]].end(), 0);
152  for (uint32_t lay : iLM.getParameter<std::vector<uint32_t>>(ndets[i])) {
153  layerMask_[idets[i]][lay] = 1;
154  }
155  }
156  }
157  } else {
158  for (auto & arr : layerMask_) {
159  std::fill(arr.begin(), arr.end(), 1);
160  }
161  }
162 }
163 
164 /*****************************************************************************/
166 {
167 #if 0
168  std::cout << "StripSubClusterShapeFilterBase " << label_ <<": called " << called_ << std::endl;
169  std::cout << "StripSubClusterShapeFilterBase " << label_ <<": saturated " << saturated_ << std::endl;
170  std::cout << "StripSubClusterShapeFilterBase " << label_ <<": test " << test_ << std::endl;
171  std::cout << "StripSubClusterShapeFilterBase " << label_ <<": failTooNarrow " << failTooNarrow_ << std::endl;
172  std::cout << "StripSubClusterShapeFilterBase " << label_ <<": passTrim " << passTrim_ << std::endl;
173  std::cout << "StripSubClusterShapeFilterBase " << label_ <<": passSC " << passSC_ << std::endl;
174  std::cout << "StripSubClusterShapeFilterBase " << label_ <<": failTooLarge " << failTooLarge_ << std::endl;
175 #endif
176 }
177 
178 
180  (const TrackingRecHit *hit, const TrajectoryStateOnSurface &tsos, bool mustProject) const
181 {
182  return testLastHit(hit, tsos.globalPosition(), tsos.globalDirection(), mustProject);
183 
184 }
186  (const TrackingRecHit *hit, const GlobalPoint &gpos, const GlobalVector &gdir, bool mustProject) const
187 {
188  const TrackerSingleRecHit *stripHit = 0;
189  if (typeid(*hit) == typeid(SiStripMatchedRecHit2D)) {
190  const SiStripMatchedRecHit2D & mhit = static_cast<const SiStripMatchedRecHit2D &>(*hit);
191  SiStripRecHit2D mono = mhit.monoHit();
192  SiStripRecHit2D stereo = mhit.stereoHit();
193  return testLastHit(&mono, gpos, gdir, true) && testLastHit(&stereo, gpos, gdir, true);
194  } else if (typeid(*hit) == typeid(ProjectedSiStripRecHit2D)) {
195  const ProjectedSiStripRecHit2D & mhit = static_cast<const ProjectedSiStripRecHit2D &>(*hit);
196  const SiStripRecHit2D &orig = mhit.originalHit();
197  return testLastHit(&orig, gpos, gdir, true);
198  } else if ((stripHit = dynamic_cast<const TrackerSingleRecHit *>(hit)) != 0) {
199  DetId detId = hit->geographicalId();
200 
201  if (layerMask_[detId.subdetId()][0] == 0) {
202  return true; // no filtering here
203  } else if (layerMask_[detId.subdetId()][0] == 2) {
204  unsigned int ilayer = theTopology->layer(detId);
205  if (layerMask_[detId.subdetId()][ilayer] == 0) {
206  return true; // no filtering here
207  }
208  }
209 
210  const GeomDet *det = theTracker->idToDet(detId);
211  LocalVector ldir = det->toLocal(gdir);
212  LocalPoint lpos = det->toLocal(gpos);
213  if (mustProject) {
214  lpos -= ldir * lpos.z()/ldir.z();
215  }
216  int hitStrips; float hitPredPos;
217  const SiStripCluster &cluster = stripHit->stripCluster();
218  bool usable = theFilter->getSizes(detId, cluster, lpos, ldir, hitStrips, hitPredPos);
219  if (!usable) return true;
220 
221  INC_COUNTER(called_)
222  const auto &ampls = cluster.amplitudes();
223 
224  // pass-through of trivial case
225  if (std::abs(hitPredPos) < 1.5f && hitStrips <= 2) {
226  return true;
227  }
228 
229 
230  // compute number of consecutive saturated strips
231  // (i.e. with adc count >= 254, see SiStripCluster class for documentation)
232  unsigned int thisSat = (ampls[0] >= 254), maxSat = thisSat;
233  for (unsigned int i = 1, n = ampls.size(); i < n; ++i) {
234  if (ampls[i] >= 254) {
235  thisSat++;
236  } else if (thisSat > 0) {
237  maxSat = std::max<int>(maxSat, thisSat);
238  thisSat = 0;
239  }
240  }
241  if (thisSat > 0) {
242  maxSat = std::max<int>(maxSat, thisSat);
243  }
244  if (maxSat >= maxNSat_) {
245  INC_COUNTER(saturated_)
246  return true;
247  }
248 
249  // trimming
250  INC_COUNTER(test_)
251  unsigned int hitStripsTrim = ampls.size();
252  int sum = std::accumulate(ampls.begin(), ampls.end(), 0);
253  uint8_t trimCut = std::min<uint8_t>(trimMaxADC_, std::floor(trimMaxFracTotal_ * sum));
254  auto begin = ampls.begin();
255  auto last = ampls.end()-1;
256  while (hitStripsTrim > 1 && (*begin < std::max<uint8_t>(trimCut, trimMaxFracNeigh_*(*(begin+1)))) ) { hitStripsTrim--; ++begin; }
257  while (hitStripsTrim > 1 && (*last < std::max<uint8_t>(trimCut, trimMaxFracNeigh_*(*(last -1)))) ) { hitStripsTrim--; --last; }
258 
259  if (hitStripsTrim < std::floor(std::abs(hitPredPos)-maxTrimmedSizeDiffNeg_)) {
260  INC_COUNTER(failTooNarrow_)
261  return false;
262  } else if (hitStripsTrim <= std::ceil(std::abs(hitPredPos)+maxTrimmedSizeDiffPos_)) {
263  INC_COUNTER(passTrim_)
264  return true;
265  }
266 
267  const StripGeomDetUnit* stripDetUnit = dynamic_cast<const StripGeomDetUnit *>(det);
268  if (det == 0) { edm::LogError("Strip not a StripGeomDetUnit?") << " on " << detId.rawId() << "\n"; return true; }
269 
270  float MeVperADCStrip = 9.5665E-4; // conversion constant from ADC counts to MeV for the SiStrip detector
271  float mip = 3.9 / ( MeVperADCStrip/stripDetUnit->surface().bounds().thickness() ); // 3.9 MeV/cm = ionization in silicon
272  float mipnorm = mip/std::abs(ldir.z());
273  ::SlidingPeakFinder pf(std::max<int>(2,std::ceil(std::abs(hitPredPos)+subclusterWindow_)));
274  ::PeakFinderTest test(mipnorm, detId(), cluster.firstStrip(), &*theNoise, seedCutMIPs_, seedCutSN_, subclusterCutMIPs_, subclusterCutSN_);
275  if (pf.apply(cluster.amplitudes(), test)) {
276  INC_COUNTER(passSC_)
277  return true;
278  } else {
279  INC_COUNTER(failTooLarge_)
280  return false;
281  }
282 
283  }
284  return true;
285 }
286 
288  (const edm::Event &event, const edm::EventSetup &es)
289 {
290  // Get tracker geometry
291  es.get<TrackerDigiGeometryRecord>().get(theTracker);
292 
293  es.get<CkfComponentsRecord>().get("ClusterShapeHitFilter",theFilter);
294 
295  //Retrieve tracker topology from geometry
296  es.get<TrackerTopologyRcd>().get(theTopology);
297 
298  es.get<SiStripNoisesRcd>().get(theNoise);
299 
300 }
301 
302 /*****************************************************************************/
304 (Trajectory& trajectory) const
305 {
306  throw cms::Exception("toBeContinued(Traj) instead of toBeContinued(TempTraj)");
307 }
308 
309 /*****************************************************************************/
311 {
312  const TrackingRecHit* hit = last.recHit()->hit();
313  if (!last.updatedState().isValid()) return true;
314  if (hit == 0 || !hit->isValid()) return true;
315  if (hit->geographicalId().subdetId() < SiStripDetId::TIB) return true; // we look only at strips for now
316  return testLastHit(hit, last.updatedState(), false);
317 
318 }
319 
320 /*****************************************************************************/
322 (TempTrajectory& trajectory) const
323 {
324  const TempTrajectory::DataContainer & tms = trajectory.measurements();
325  return testLastHit(*tms.rbegin());
326 }
327 
328 /*****************************************************************************/
330  (const Trajectory& trajectory) const
331 {
332  const Trajectory::DataContainer & tms = trajectory.measurements();
333  return testLastHit(*tms.rbegin());
334 }
335 
336 /*****************************************************************************/
338  (const TempTrajectory& trajectory) const
339 {
340  const TempTrajectory::DataContainer & tms = trajectory.measurements();
341  return testLastHit(*tms.rbegin());
342 }
343 
344 
345 /*****************************************************************************/
348  StripSubClusterShapeFilterBase(iConfig,iC),
349  filterAtHelixStage_(iConfig.getParameter<bool>("FilterAtHelixStage"))
350 
351 {
352  if (filterAtHelixStage_) edm::LogError("Configuration") << "StripSubClusterShapeSeedFilter: FilterAtHelixStage is not yet working correctly.\n";
353 }
354 
355 
356 /*****************************************************************************/
359 {
360  if (filterAtHelixStage_) return true;
361  const TrackingRecHit* hit = thit->hit();
362  if (hit == 0 || !hit->isValid()) return true;
363  if (hit->geographicalId().subdetId() < SiStripDetId::TIB) return true; // we look only at strips for now
364  return testLastHit(hit, tsos, false);
365 }
366 
368  (const SeedingHitSet &hits, const GlobalTrajectoryParameters &helixStateAtVertex, const FastHelix &helix, const TrackingRegion & region) const
369 {
370  if (!filterAtHelixStage_) return true;
371 
372  if (!helix.isValid()) edm::LogWarning("InvalidHelix") << "PixelClusterShapeSeedComparitor helix is not valid, result is bad";
373 
374  float xc = helix.circle().x0(), yc = helix.circle().y0();
375 
376  GlobalPoint vertex = helixStateAtVertex.position();
377  GlobalVector momvtx = helixStateAtVertex.momentum();
378  float x0 = vertex.x(), y0 = vertex.y();
379  for (unsigned int i = 0, n = hits.size(); i < n; ++i) {
380  auto const & hit = *hits[i];
381  if (hit.geographicalId().subdetId() < SiStripDetId::TIB) continue;
382 
383  GlobalPoint pos = hit.globalPosition();
384  float x1 = pos.x(), y1 = pos.y(), dx1 = x1 - xc, dy1 = y1 - yc;
385 
386  // now figure out the proper tangent vector
387  float perpx = -dy1, perpy = dx1;
388  if (perpx * (x1-x0) + perpy * (y1 - y0) < 0) {
389  perpy = -perpy; perpx = -perpx;
390  }
391 
392  // now normalize (perpx, perpy, 1.0) to unity
393  float pnorm = 1.0/std::sqrt(perpx*perpx + perpy*perpy + 1);
394  GlobalVector gdir(perpx*pnorm, perpy*pnorm, (momvtx.z() > 0 ? pnorm : -pnorm));
395 
396  if (!testLastHit(&hit, pos, gdir)) {
397  return false; // not yet
398  }
399  }
400  return true;
401 }
402 
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
bool isValid() const
Definition: FastHelix.h:63
virtual bool qualityFilter(const TempTrajectory &) const override
string fill
Definition: lumiContext.py:319
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
virtual bool toBeContinued(TempTrajectory &) const override
ConstRecHitPointer const & recHit() const
double x0() const
Definition: FastCircle.h:50
const DataContainer & measurements() const
T y() const
Definition: PV3DBase.h:63
bool exists(std::string const &parameterName) const
checks if a parameter exists
GlobalPoint globalPosition() const
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:67
const Bounds & bounds() const
Definition: Surface.h:128
uint16_t firstStrip() const
const FastCircle & circle() const
Definition: FastHelix.h:67
virtual GlobalPoint globalPosition() const
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:40
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
virtual float thickness() const =0
DataContainer const & measurements() const
Definition: Trajectory.h:203
BaseTrackerRecHit const * ConstRecHitPointer
Definition: SeedingHitSet.h:11
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:42
T sqrt(T t)
Definition: SSEVec.h:48
T z() const
Definition: PV3DBase.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
bool testLastHit(const TrackingRecHit *hit, const TrajectoryStateOnSurface &tsos, bool mustProject=false) const
#define end
Definition: vmac.h:37
T min(T a, T b)
Definition: MathUtil.h:58
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
StripSubClusterShapeFilterBase(const edm::ParameterSet &iConfig, edm::ConsumesCollector &iC)
const_iterator rbegin() const
Definition: bqueue.h:163
void setEventBase(const edm::Event &, const edm::EventSetup &)
SiStripRecHit2D originalHit() const
Definition: DetId.h:18
virtual TrackingRecHit const * hit() const
SiStripRecHit2D stereoHit() const
SiStripCluster const & stripCluster() const
const T & get() const
Definition: EventSetup.h:56
bool isValid() const
virtual bool compatible(const TrajectoryStateOnSurface &tsos, SeedingHitSet::ConstRecHitPointer hit) const
SiStripRecHit2D monoHit() const
double y0() const
Definition: FastCircle.h:52
#define begin
Definition: vmac.h:30
const Range getRange(const uint32_t detID) const
unsigned int size() const
Definition: SeedingHitSet.h:44
tuple cout
Definition: gather_cfg.py:121
TrajectoryStateOnSurface const & updatedState() const
size_(0)
Definition: OwnArray.h:181
DetId geographicalId() const
bool testLastHit(const TrajectoryMeasurement &last) const
std::pair< ContainerIterator, ContainerIterator > Range
Definition: SiStripNoises.h:48
T x() const
Definition: PV3DBase.h:62
tuple size
Write out results.
const std::vector< uint8_t > & amplitudes() const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
Vec apply(Vec v, F f)
Definition: ExtVec.h:95
GlobalVector globalDirection() const
StripSubClusterShapeSeedFilter(const edm::ParameterSet &iConfig, edm::ConsumesCollector &iC)