CMS 3D CMS Logo

CAHitTripletGenerator.cc
Go to the documentation of this file.
1 #include <unordered_map>
2 
4 
6 
12 
14 
15 #include "CellularAutomaton.h"
16 
18 
20 
21 namespace
22 {
23 
24 template<typename T>
25 T sqr(T x)
26 {
27  return x * x;
28 }
29 }
30 
31 using namespace std;
32 using namespace ctfseeding;
33 
35 
38  bool needSeedingLayerSetsHits) :
39  extraHitRPhitolerance(cfg.getParameter<double>("extraHitRPhitolerance")), //extra window in ThirdHitPredictionFromCircle range (divide by R to get phi)
40  maxChi2(cfg.getParameter < edm::ParameterSet > ("maxChi2")),
41  useBendingCorrection(cfg.getParameter<bool>("useBendingCorrection")),
42  caThetaCut( cfg.getParameter<double>("CAThetaCut")),
43  caPhiCut(cfg.getParameter<double>("CAPhiCut")),
44  caHardPtCut(cfg.getParameter<double>("CAHardPtCut"))
45 {
46 
47  if(needSeedingLayerSetsHits)
49 
50  if (cfg.exists("SeedComparitorPSet"))
51  {
52  edm::ParameterSet comparitorPSet = cfg.getParameter < edm::ParameterSet
53  > ("SeedComparitorPSet");
54  std::string comparitorName = comparitorPSet.getParameter < std::string
55  > ("ComponentName");
56  if (comparitorName != "none")
57  {
58  theComparitor.reset(
59  SeedComparitorFactory::get()->create(comparitorName,
60  comparitorPSet, iC));
61  }
62  }
63 }
64 
66 {
67 }
68 
70  desc.add<double>("extraHitRPhitolerance", 0.06);
71  desc.add<bool>("useBendingCorrection", false);
72  desc.add<double>("CAThetaCut", 0.00125);
73  desc.add<double>("CAPhiCut", 0.1);
74  desc.add<double>("CAHardPtCut", 0);
75 
76  edm::ParameterSetDescription descMaxChi2;
77  descMaxChi2.add<double>("pt1", 0.8);
78  descMaxChi2.add<double>("pt2", 2);
79  descMaxChi2.add<double>("value1", 50);
80  descMaxChi2.add<double>("value2", 8);
81  descMaxChi2.add<bool>("enabled", true);
82  desc.add<edm::ParameterSetDescription>("maxChi2", descMaxChi2);
83 
84  edm::ParameterSetDescription descComparitor;
85  descComparitor.add<std::string>("ComponentName", "none");
86  descComparitor.setAllowAnything(); // until we have moved SeedComparitor too to EDProducers
87  desc.add<edm::ParameterSetDescription>("SeedComparitorPSet", descComparitor);
88 }
89 
91  if (theComparitor) theComparitor->init(ev, es);
92 }
93 
94 namespace {
95  void createGraphStructure(const SeedingLayerSetsHits& layers, CAGraph& g) {
96  for (unsigned int i = 0; i < layers.size(); i++)
97  {
98  for (unsigned int j = 0; j < 3; ++j)
99  {
100  auto vertexIndex = 0;
101  auto foundVertex = std::find(g.theLayers.begin(), g.theLayers.end(),
102  layers[i][j].name());
103  if (foundVertex == g.theLayers.end())
104  {
105  g.theLayers.emplace_back(layers[i][j].name(),
106  layers[i][j].hits().size());
107  vertexIndex = g.theLayers.size() - 1;
108  }
109  else
110  {
111  vertexIndex = foundVertex - g.theLayers.begin();
112  }
113  if (j == 0)
114  {
115 
116  if (std::find(g.theRootLayers.begin(), g.theRootLayers.end(),
117  vertexIndex) == g.theRootLayers.end())
118  {
119  g.theRootLayers.emplace_back(vertexIndex);
120 
121  }
122 
123  }
124  }
125  }
126  }
127 
128  void clearGraphStructure(const SeedingLayerSetsHits& layers, CAGraph& g) {
129  g.theLayerPairs.clear();
130  for (unsigned int i = 0; i < g.theLayers.size(); i++ ){
131  g.theLayers[i].theInnerLayers.clear();
132  g.theLayers[i].theInnerLayerPairs.clear();
133  g.theLayers[i].theOuterLayers.clear();
134  g.theLayers[i].theOuterLayerPairs.clear();
135  for (auto & v : g.theLayers[i].isOuterHitOfCell) v.clear();
136  }
137 
138  }
139 
140  template <typename T_HitDoublets, typename T_GeneratorOrPairsFunction>
141  void fillGraph(const SeedingLayerSetsHits& layers, CAGraph& g, T_HitDoublets& hitDoublets,
142  T_GeneratorOrPairsFunction generatorOrPairsFunction) {
143  for (unsigned int i = 0; i < layers.size(); i++)
144  {
145  for (unsigned int j = 0; j < 3; ++j)
146  {
147  auto vertexIndex = 0;
148  auto foundVertex = std::find(g.theLayers.begin(), g.theLayers.end(),
149  layers[i][j].name());
150 
151  if (foundVertex == g.theLayers.end())
152  {
153  vertexIndex = g.theLayers.size() - 1;
154  }
155  else
156  {
157  vertexIndex = foundVertex - g.theLayers.begin();
158  }
159 
160 
161  if (j > 0)
162  {
163 
164  auto innerVertex = std::find(g.theLayers.begin(),
165  g.theLayers.end(), layers[i][j - 1].name());
166 
167  CALayerPair tmpInnerLayerPair(innerVertex - g.theLayers.begin(),
168  vertexIndex);
169 
170  if (std::find(g.theLayerPairs.begin(), g.theLayerPairs.end(),
171  tmpInnerLayerPair) == g.theLayerPairs.end())
172  {
173  const bool nonEmpty = generatorOrPairsFunction(layers[i][j - 1], layers[i][j], hitDoublets);
174  if(nonEmpty) {
175  g.theLayerPairs.push_back(tmpInnerLayerPair);
176  g.theLayers[vertexIndex].theInnerLayers.push_back(
177  innerVertex - g.theLayers.begin());
178  innerVertex->theOuterLayers.push_back(vertexIndex);
179  g.theLayers[vertexIndex].theInnerLayerPairs.push_back(
180  g.theLayerPairs.size() - 1);
181  innerVertex->theOuterLayerPairs.push_back(
182  g.theLayerPairs.size() - 1);
183  }
184  }
185 
186  }
187 
188  }
189  }
190  }
191 }
192 
195  const edm::EventSetup& es)
196 {
198  ev.getByToken(theSeedingLayerToken, hlayers);
199  const SeedingLayerSetsHits& layers = *hlayers;
200  if (layers.numberOfLayersInSet() != 3)
201  throw cms::Exception("Configuration")
202  << "CAHitTripletGenerator expects SeedingLayerSetsHits::numberOfLayersInSet() to be 3, got "
203  << layers.numberOfLayersInSet();
204 
205  CAGraph g;
206 
207  std::vector<HitDoublets> hitDoublets;
208 
209 
210 
211  HitPairGeneratorFromLayerPair thePairGenerator(0, 1, &theLayerCache);
212  createGraphStructure(layers,g);
213  fillGraph(layers, g, hitDoublets, [&](const SeedingLayerSetsHits::SeedingLayer& inner, const SeedingLayerSetsHits::SeedingLayer& outer, std::vector<HitDoublets>& hitDoublets) {
214  hitDoublets.emplace_back(thePairGenerator.doublets(region, ev, es, inner, outer));
215  return true;
216  });
217 
218 
219  if (theComparitor)
220  theComparitor->init(ev, es);
221 
222  std::vector<const HitDoublets *> hitDoubletsPtr;
223  hitDoubletsPtr.reserve(hitDoublets.size());
224  for(const auto& e: hitDoublets)
225  hitDoubletsPtr.emplace_back(&e);
226 
227  hitTriplets(region, result, hitDoubletsPtr, g, es);
229 }
230 
232  std::vector<OrderedHitSeeds>& result,
233  const edm::EventSetup& es,
234  const SeedingLayerSetsHits& layers) {
235  CAGraph g;
236 
237  std::vector<const HitDoublets *> hitDoublets;
238 
239  auto layerPairEqual = [](const IntermediateHitDoublets::LayerPairHitDoublets& pair,
242  return pair.innerLayerIndex() == inner && pair.outerLayerIndex() == outer;
243  };
244  std::vector<CACell::CAntuplet> foundTriplets;
245 
246  int index =0;
247  for(const auto& regionLayerPairs: regionDoublets) {
248 
249  const TrackingRegion& region = regionLayerPairs.region();
250  hitDoublets.clear();
251  foundTriplets.clear();
252 
253  if (index == 0){
254  createGraphStructure(layers, g);
255  }
256  else{
257  clearGraphStructure(layers, g);
258  }
259  fillGraph(layers, g, hitDoublets,
260  [&](const SeedingLayerSetsHits::SeedingLayer& inner,
262  std::vector<const HitDoublets *>& hitDoublets) {
263  using namespace std::placeholders;
264  auto found = std::find_if(regionLayerPairs.begin(), regionLayerPairs.end(),
265  std::bind(layerPairEqual, _1, inner.index(), outer.index()));
266  if(found != regionLayerPairs.end()) {
267  hitDoublets.emplace_back(&(found->doublets()));
268  return true;
269  }
270  return false;
271  });
272  CellularAutomaton ca(g);
273  ca.findTriplets(hitDoublets, foundTriplets, region, caThetaCut, caPhiCut,
274  caHardPtCut);
275 
276  auto & allCells = ca.getAllCells();
277 
278  const QuantityDependsPtEval maxChi2Eval = maxChi2.evaluator(es);
279 
280  // re-used thoughout, need to be vectors because of RZLine interface
281  std::array<float, 3> bc_r;
282  std::array<float, 3> bc_z;
283  std::array<float, 3> bc_errZ2;
284  std::array<GlobalPoint, 3> gps;
285  std::array<GlobalError, 3> ges;
286  std::array<bool, 3> barrels;
287 
288  unsigned int numberOfFoundTriplets = foundTriplets.size();
289  for (unsigned int tripletId = 0; tripletId < numberOfFoundTriplets;
290  ++tripletId)
291  {
292 
293  OrderedHitTriplet tmpTriplet(allCells[foundTriplets[tripletId][0]].getInnerHit(),
294  allCells[foundTriplets[tripletId][0]].getOuterHit(),
295  allCells[foundTriplets[tripletId][1]].getOuterHit());
296 
297  auto isBarrel = [](const unsigned id) -> bool
298  {
299  return id == PixelSubdetector::PixelBarrel;
300  };
301  for (unsigned int i = 0; i < 2; ++i)
302  {
303  auto const& ahit = allCells[foundTriplets[tripletId][i]].getInnerHit();
304  gps[i] = ahit->globalPosition();
305  ges[i] = ahit->globalPositionError();
306  barrels[i] = isBarrel(ahit->geographicalId().subdetId());
307  }
308 
309  auto const& ahit = allCells[foundTriplets[tripletId][1]].getOuterHit();
310  gps[2] = ahit->globalPosition();
311  ges[2] = ahit->globalPositionError();
312  barrels[2] = isBarrel(ahit->geographicalId().subdetId());
313 
314  PixelRecoLineRZ line(gps[0], gps[2]);
315  ThirdHitPredictionFromCircle predictionRPhi(gps[0], gps[2],
317  const float curvature = predictionRPhi.curvature(
318  ThirdHitPredictionFromCircle::Vector2D(gps[1].x(), gps[1].y()));
319  const float abscurv = std::abs(curvature);
320  const float thisMaxChi2 = maxChi2Eval.value(abscurv);
321  float chi2 = std::numeric_limits<float>::quiet_NaN();
322  // TODO: Do we have any use case to not use bending correction?
323 
325  {
326  // Following PixelFitterByConformalMappingAndLine
327  const float simpleCot = (gps.back().z() - gps.front().z())
328  / (gps.back().perp() - gps.front().perp());
329  const float pt = 1.f / PixelRecoUtilities::inversePt(abscurv, es);
330  for (int i = 0; i < 3; ++i)
331  {
332  const GlobalPoint & point = gps[i];
333  const GlobalError & error = ges[i];
334  bc_r[i] = sqrt(
335  sqr(point.x() - region.origin().x())
336  + sqr(point.y() - region.origin().y()));
338  es)(bc_r[i]);
339  bc_z[i] = point.z() - region.origin().z();
340  bc_errZ2[i] =
341  (barrels[i]) ?
342  error.czz() :
343  error.rerr(point) * sqr(simpleCot);
344  }
345  RZLine rzLine(bc_r, bc_z, bc_errZ2, RZLine::ErrZ2_tag());
346  chi2 = rzLine.chi2();
347  }
348  else
349  {
350  RZLine rzLine(gps, ges, barrels);
351  chi2 = rzLine.chi2();
352  }
353 
354  if (edm::isNotFinite(chi2) || chi2 > thisMaxChi2)
355  {
356  continue;
357 
358  }
359 
360  if (theComparitor)
361  {
362  if (!theComparitor->compatible(tmpTriplet))
363  {
364 
365  continue;
366  }
367  }
368  result[index].emplace_back(tmpTriplet);
369 
370  }
371  index++;
372  }
373 }
374 
377  std::vector<const HitDoublets *>& hitDoublets, CAGraph& g,
378  const edm::EventSetup& es) {
379  std::vector<CACell::CAntuplet> foundTriplets;
380  CellularAutomaton ca(g);
381 
382  ca.findTriplets(hitDoublets, foundTriplets, region, caThetaCut, caPhiCut,
383  caHardPtCut);
384 
385  auto & allCells = ca.getAllCells();
386 
387  unsigned int numberOfFoundTriplets = foundTriplets.size();
388 
389  const QuantityDependsPtEval maxChi2Eval = maxChi2.evaluator(es);
390 
391  // re-used thoughout, need to be vectors because of RZLine interface
392  std::array<float, 3> bc_r;
393  std::array<float, 3> bc_z;
394  std::array<float, 3> bc_errZ2;
395  std::array < GlobalPoint, 3 > gps;
396  std::array < GlobalError, 3 > ges;
397  std::array<bool, 3> barrels;
398 
399  for (unsigned int tripletId = 0; tripletId < numberOfFoundTriplets;
400  ++tripletId)
401  {
402 
403  OrderedHitTriplet tmpTriplet(allCells[foundTriplets[tripletId][0]].getInnerHit(),
404  allCells[foundTriplets[tripletId][0]].getOuterHit(),
405  allCells[foundTriplets[tripletId][1]].getOuterHit());
406 
407  auto isBarrel = [](const unsigned id) -> bool
408  {
409  return id == PixelSubdetector::PixelBarrel;
410  };
411  for (unsigned int i = 0; i < 2; ++i)
412  {
413  auto const& ahit = allCells[foundTriplets[tripletId][i]].getInnerHit();
414  gps[i] = ahit->globalPosition();
415  ges[i] = ahit->globalPositionError();
416  barrels[i] = isBarrel(ahit->geographicalId().subdetId());
417  }
418 
419  auto const& ahit = allCells[foundTriplets[tripletId][1]].getOuterHit();
420  gps[2] = ahit->globalPosition();
421  ges[2] = ahit->globalPositionError();
422  barrels[2] = isBarrel(ahit->geographicalId().subdetId());
423 
424  PixelRecoLineRZ line(gps[0], gps[2]);
425  ThirdHitPredictionFromCircle predictionRPhi(gps[0], gps[2],
427  const float curvature = predictionRPhi.curvature(
428  ThirdHitPredictionFromCircle::Vector2D(gps[1].x(), gps[1].y()));
429  const float abscurv = std::abs(curvature);
430  const float thisMaxChi2 = maxChi2Eval.value(abscurv);
431  float chi2 = std::numeric_limits<float>::quiet_NaN();
432  // TODO: Do we have any use case to not use bending correction?
434  {
435  // Following PixelFitterByConformalMappingAndLine
436  const float simpleCot = (gps.back().z() - gps.front().z())
437  / (gps.back().perp() - gps.front().perp());
438  const float pt = 1.f / PixelRecoUtilities::inversePt(abscurv, es);
439  for (int i = 0; i < 3; ++i)
440  {
441  const GlobalPoint & point = gps[i];
442  const GlobalError & error = ges[i];
443  bc_r[i] = sqrt(
444  sqr(point.x() - region.origin().x())
445  + sqr(point.y() - region.origin().y()));
447  es)(bc_r[i]);
448  bc_z[i] = point.z() - region.origin().z();
449  bc_errZ2[i] =
450  (barrels[i]) ?
451  error.czz() :
452  error.rerr(point) * sqr(simpleCot);
453  }
454  RZLine rzLine(bc_r, bc_z, bc_errZ2, RZLine::ErrZ2_tag());
455  chi2 = rzLine.chi2();
456  }
457  else
458  {
459  RZLine rzLine(gps, ges, barrels);
460  chi2 = rzLine.chi2();
461  }
462 
463  if (edm::isNotFinite(chi2) || chi2 > thisMaxChi2)
464  {
465  continue;
466 
467  }
468 
469  if (theComparitor)
470  {
471  if (!theComparitor->compatible(tmpTriplet))
472  {
473 
474  continue;
475  }
476  }
477 
478  result.push_back(tmpTriplet);
479 
480  }
482 }
483 
size
Write out results.
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
T getParameter(std::string const &) const
unsigned short numberOfLayersInSet() const
Get number of layers in each SeedingLayerSets.
const QuantityDependsPt maxChi2
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
GlobalPoint const & origin() const
def create(alignables, pedeDump, additionalData, outputFile, config)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:460
T y() const
Definition: PV3DBase.h:63
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::vector< CACell > & getAllCells()
void hitNtuplets(const IntermediateHitDoublets &regionDoublets, std::vector< OrderedHitSeeds > &result, const edm::EventSetup &es, const SeedingLayerSetsHits &layers)
bool ev
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
CAHitTripletGenerator(const edm::ParameterSet &cfg, edm::ConsumesCollector &&iC, bool needSeedingLayerSetsHits=true)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
#define constexpr
Range curvature(double transverseIP) const
edm::EDGetTokenT< SeedingLayerSetsHits > theSeedingLayerToken
T inversePt(T curvature, const edm::EventSetup &iSetup)
T x() const
Cartesian x coordinate.
QuantityDependsPtEval evaluator(const edm::EventSetup &es) const
bool isNotFinite(T x)
Definition: isFinite.h:10
T curvature(T InversePt, const edm::EventSetup &iSetup)
SeedingLayerSetsHits::LayerIndex innerLayerIndex() const
T sqrt(T t)
Definition: SSEVec.h:18
std::vector< CALayer > theLayers
Definition: CAGraph.h:63
T z() const
Definition: PV3DBase.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void initEvent(const edm::Event &ev, const edm::EventSetup &es)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::vector< CALayerPair > theLayerPairs
Definition: CAGraph.h:64
HitDoublets doublets(const TrackingRegion &reg, const edm::Event &ev, const edm::EventSetup &es, Layers layers)
Definition: RZLine.h:12
virtual void hitTriplets(const TrackingRegion &reg, OrderedHitTriplets &triplets, const edm::Event &ev, const edm::EventSetup &es)
from base class
T rerr(const GlobalPoint &aPoint) const
HLT enums.
SeedingLayerSetsHits::LayerIndex outerLayerIndex() const
Square< F >::type sqr(const F &f)
Definition: Square.h:13
std::vector< int > theRootLayers
Definition: CAGraph.h:65
static void fillDescriptions(edm::ParameterSetDescription &desc)
void findTriplets(const std::vector< const HitDoublets * > &hitDoublets, std::vector< CACell::CAntuplet > &foundTriplets, const TrackingRegion &region, const float thetaCut, const float phiCut, const float hardPtCut)
long double T
T x() const
Definition: PV3DBase.h:62
std::unique_ptr< SeedComparitor > theComparitor
float chi2() const
Definition: RZLine.h:97
unsigned short size() const
Get the number of SeedingLayerSets.
static unsigned int minLayers
T get(const Candidate &c)
Definition: component.h:55
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5