CMS 3D CMS Logo

PixelQuadrupletGenerator.cc
Go to the documentation of this file.
2 #include "ThirdHitRZPrediction.h"
6 
10 
16 
19 
21 
23 
24 namespace {
25  template <typename T>
26  T sqr(T x) {
27  return x*x;
28  }
29 }
30 
32 
34  extraHitRZtolerance(cfg.getParameter<double>("extraHitRZtolerance")), //extra window in ThirdHitRZPrediction range
35  extraHitRPhitolerance(cfg.getParameter<double>("extraHitRPhitolerance")), //extra window in ThirdHitPredictionFromCircle range (divide by R to get phi)
36  extraPhiTolerance(cfg.getParameter<edm::ParameterSet>("extraPhiTolerance")),
37  maxChi2(cfg.getParameter<edm::ParameterSet>("maxChi2")),
38  fitFastCircle(cfg.getParameter<bool>("fitFastCircle")),
39  fitFastCircleChi2Cut(cfg.getParameter<bool>("fitFastCircleChi2Cut")),
40  useBendingCorrection(cfg.getParameter<bool>("useBendingCorrection"))
41 {
42  if(cfg.exists("SeedComparitorPSet")) {
43  edm::ParameterSet comparitorPSet =
44  cfg.getParameter<edm::ParameterSet>("SeedComparitorPSet");
45  std::string comparitorName = comparitorPSet.getParameter<std::string>("ComponentName");
46  if(comparitorName != "none") {
47  theComparitor.reset(SeedComparitorFactory::get()->create(comparitorName, comparitorPSet, iC));
48  }
49  }
50 }
51 
53 
55  desc.add<double>("extraHitRZtolerance", 0.1);
56  desc.add<double>("extraHitRPhitolerance", 0.1);
57 
58  edm::ParameterSetDescription descExtraPhi;
59  descExtraPhi.add<double>("pt1", 0.1);
60  descExtraPhi.add<double>("pt2", 0.1);
61  descExtraPhi.add<double>("value1", 999);
62  descExtraPhi.add<double>("value2", 0.15);
63  descExtraPhi.add<bool>("enabled", false);
64  desc.add<edm::ParameterSetDescription>("extraPhiTolerance", descExtraPhi);
65 
66  edm::ParameterSetDescription descMaxChi2;
67  descMaxChi2.add<double>("pt1", 0.2);
68  descMaxChi2.add<double>("pt2", 1.5);
69  descMaxChi2.add<double>("value1", 500);
70  descMaxChi2.add<double>("value2", 50);
71  descMaxChi2.add<bool>("enabled", true);
72  desc.add<edm::ParameterSetDescription>("maxChi2", descMaxChi2);
73 
74  desc.add<bool>("fitFastCircle", false);
75  desc.add<bool>("fitFastCircleChi2Cut", false);
76  desc.add<bool>("useBendingCorrection", false);
77 
78  edm::ParameterSetDescription descComparitor;
79  descComparitor.add<std::string>("ComponentName", "none");
80  descComparitor.setAllowAnything(); // until we have moved SeedComparitor too to EDProducers
81  desc.add<edm::ParameterSetDescription>("SeedComparitorPSet", descComparitor);
82 }
83 
84 
86  const edm::Event& ev, const edm::EventSetup& es,
87  const SeedingLayerSetsHits::SeedingLayerSet& tripletLayers,
88  const std::vector<SeedingLayerSetsHits::SeedingLayer>& fourthLayers)
89 {
91  theTripletGenerator->hitTriplets(region, triplets, ev, es,
92  tripletLayers, // pair generator picks the correct two layers from these
93  std::vector<SeedingLayerSetsHits::SeedingLayer>{tripletLayers[2]});
94  if(triplets.empty()) return;
95 
96  assert(theLayerCache);
97  hitQuadruplets(region, result, ev, es, triplets.begin(), triplets.end(), fourthLayers, *theLayerCache);
98 }
99 
101  const edm::Event& ev, const edm::EventSetup& es,
102  OrderedHitTriplets::const_iterator tripletsBegin,
103  OrderedHitTriplets::const_iterator tripletsEnd,
104  const std::vector<SeedingLayerSetsHits::SeedingLayer>& fourthLayers,
105  LayerCacheType& layerCache)
106 {
107  if (theComparitor) theComparitor->init(ev, es);
108 
109  const size_t size = fourthLayers.size();
110 
111  const RecHitsSortedInPhi *fourthHitMap[size];
113 
114  using NodeInfo = KDTreeNodeInfo<unsigned int>;
115  std::vector<NodeInfo > layerTree; // re-used throughout
116  std::vector<unsigned int> foundNodes; // re-used thoughout
117 
119  float rzError[size]; //save maximum errors
120 
122 
123  // Build KDtrees
124  for(size_t il=0; il!=size; ++il) {
125  fourthHitMap[il] = &(layerCache)(fourthLayers[il], region, es);
126  auto const& hits = *fourthHitMap[il];
127 
128  ThirdHitRZPrediction<PixelRecoLineRZ> & pred = preds[il];
129  pred.initLayer(fourthLayers[il].detLayer());
131 
132  layerTree.clear();
133  float maxphi = Geom::ftwoPi(), minphi = -maxphi; // increase to cater for any range
134  float minv=999999.0, maxv= -999999.0; // Initialise to extreme values in case no hits
135  float maxErr=0.0f;
136  for (unsigned int i=0; i!=hits.size(); ++i) {
137  auto angle = hits.phi(i);
138  auto v = hits.gv(i);
139  //use (phi,r) for endcaps rather than (phi,z)
140  minv = std::min(minv,v); maxv = std::max(maxv,v);
141  float myerr = hits.dv[i];
142  maxErr = std::max(maxErr,myerr);
143  layerTree.emplace_back(i, angle, v); // save it
144  if (angle < 0) // wrap all points in phi
145  { layerTree.emplace_back(i, angle+Geom::ftwoPi(), v);}
146  else
147  { layerTree.emplace_back(i, angle-Geom::ftwoPi(), v);}
148  }
149  KDTreeBox phiZ(minphi, maxphi, minv-0.01f, maxv+0.01f); // declare our bounds
150  //add fudge factors in case only one hit and also for floating-point inaccuracy
151  hitTree[il].build(layerTree, phiZ); // make KDtree
152  rzError[il] = maxErr; // save error
153  }
154 
155  const QuantityDependsPtEval maxChi2Eval = maxChi2.evaluator(es);
156  const QuantityDependsPtEval extraPhiToleranceEval = extraPhiTolerance.evaluator(es);
157 
158  // re-used thoughout
159  std::array<float, 4> bc_r;
160  std::array<float, 4> bc_z;
161  std::array<float, 4> bc_errZ2;
162  std::array<GlobalPoint, 4> gps;
163  std::array<GlobalError, 4> ges;
164  std::array<bool, 4> barrels;
165 
166  // Loop over triplets
167  for(auto iTriplet = tripletsBegin; iTriplet != tripletsEnd; ++iTriplet) {
168  const auto& triplet = *iTriplet;
169  GlobalPoint gp0 = triplet.inner()->globalPosition();
170  GlobalPoint gp1 = triplet.middle()->globalPosition();
171  GlobalPoint gp2 = triplet.outer()->globalPosition();
172 
173  PixelRecoLineRZ line(gp0, gp2);
174  ThirdHitPredictionFromCircle predictionRPhi(gp0, gp2, extraHitRPhitolerance);
175 
176  const double curvature = predictionRPhi.curvature(ThirdHitPredictionFromCircle::Vector2D(gp1.x(), gp1.y()));
177 
178  const float abscurv = std::abs(curvature);
179  const float thisMaxChi2 = maxChi2Eval.value(abscurv);
180  const float thisExtraPhiTolerance = extraPhiToleranceEval.value(abscurv);
181 
182  constexpr float nSigmaRZ = 3.46410161514f; // std::sqrt(12.f); // ...and continue as before
183 
184  auto isBarrel = [](const unsigned id) -> bool {
185  return id == PixelSubdetector::PixelBarrel;
186  };
187 
188  gps[0] = triplet.inner()->globalPosition();
189  ges[0] = triplet.inner()->globalPositionError();
190  barrels[0] = isBarrel(triplet.inner()->geographicalId().subdetId());
191 
192  gps[1] = triplet.middle()->globalPosition();
193  ges[1] = triplet.middle()->globalPositionError();
194  barrels[1] = isBarrel(triplet.middle()->geographicalId().subdetId());
195 
196  gps[2] = triplet.outer()->globalPosition();
197  ges[2] = triplet.outer()->globalPositionError();
198  barrels[2] = isBarrel(triplet.outer()->geographicalId().subdetId());
199 
200  for(size_t il=0; il!=size; ++il) {
201  if(hitTree[il].empty()) continue; // Don't bother if no hits
202 
203  auto const& hits = *fourthHitMap[il];
204  const DetLayer *layer = fourthLayers[il].detLayer();
205  bool barrelLayer = layer->isBarrel();
206 
207  auto& predictionRZ = preds[il];
208  predictionRZ.initPropagator(&line);
209  Range rzRange = predictionRZ(); // z in barrel, r in endcap
210 
211  // construct search box and search
212  Range phiRange;
213  if(barrelLayer) {
214  auto radius = static_cast<const BarrelDetLayer *>(layer)->specificSurface().radius();
215  double phi = predictionRPhi.phi(curvature, radius);
216  phiRange = Range(phi-thisExtraPhiTolerance, phi+thisExtraPhiTolerance);
217  }
218  else {
219  double phi1 = predictionRPhi.phi(curvature, rzRange.min());
220  double phi2 = predictionRPhi.phi(curvature, rzRange.max());
221  phiRange = Range(std::min(phi1, phi2)-thisExtraPhiTolerance, std::max(phi1, phi2)+thisExtraPhiTolerance);
222  }
223 
224  KDTreeBox phiZ(phiRange.min(), phiRange.max(),
225  rzRange.min()-nSigmaRZ*rzError[il],
226  rzRange.max()+nSigmaRZ*rzError[il]);
227 
228  foundNodes.clear();
229  hitTree[il].search(phiZ, foundNodes);
230 
231  if(foundNodes.empty()) {
232  continue;
233  }
234 
235  SeedingHitSet::ConstRecHitPointer selectedHit = nullptr;
236  float selectedChi2 = std::numeric_limits<float>::max();
237  for(auto hitIndex: foundNodes) {
238  const auto& hit = hits.theHits[hitIndex].hit();
239 
240  // Reject comparitor. For now, because of technical
241  // limitations, pass three hits to the comparitor
242  // TODO: switch to using hits from 2-3-4 instead of 1-3-4?
243  // Eventually we should fix LowPtClusterShapeSeedComparitor to
244  // accept quadruplets.
245  if(theComparitor) {
246  SeedingHitSet tmpTriplet(triplet.inner(), triplet.outer(), hit);
247  if(!theComparitor->compatible(tmpTriplet)) {
248  continue;
249  }
250  }
251 
252  gps[3] = hit->globalPosition();
253  ges[3] = hit->globalPositionError();
254  barrels[3] = isBarrel(hit->geographicalId().subdetId());
255 
256  float chi2 = std::numeric_limits<float>::quiet_NaN();
257  // TODO: Do we have any use case to not use bending correction?
259  // Following PixelFitterByConformalMappingAndLine
260  const float simpleCot = ( gps.back().z()-gps.front().z() )/ (gps.back().perp() - gps.front().perp() );
261  const float pt = 1/PixelRecoUtilities::inversePt(abscurv, es);
262  for (int i=0; i< 4; ++i) {
263  const GlobalPoint & point = gps[i];
264  const GlobalError & error = ges[i];
265  bc_r[i] = sqrt( sqr(point.x()-region.origin().x()) + sqr(point.y()-region.origin().y()) );
267  bc_z[i] = point.z()-region.origin().z();
268  bc_errZ2[i] = (barrels[i]) ? error.czz() : error.rerr(point)*sqr(simpleCot);
269  }
270  RZLine rzLine(bc_r,bc_z,bc_errZ2, RZLine::ErrZ2_tag());
271  chi2 = rzLine.chi2();
272  }
273  else {
274  RZLine rzLine(gps, ges, barrels);
275  chi2 = rzLine.chi2();
276  }
277  if(edm::isNotFinite(chi2) || chi2 > thisMaxChi2) {
278  continue;
279  }
280  // TODO: Do we have any use case to not use circle fit? Maybe
281  // HLT where low-pT inefficiency is not a problem?
282  if(fitFastCircle) {
283  FastCircleFit c(gps, ges);
284  chi2 += c.chi2();
285  if(edm::isNotFinite(chi2))
286  continue;
287  if(fitFastCircleChi2Cut && chi2 > thisMaxChi2)
288  continue;
289  }
290 
291 
292  if(chi2 < selectedChi2) {
293  selectedChi2 = chi2;
294  selectedHit = hit;
295  }
296  }
297  if(selectedHit)
298  result.emplace_back(triplet.inner(), triplet.middle(), triplet.outer(), selectedHit);
299  }
300  }
301 }
size
Write out results.
T getParameter(std::string const &) const
QuantityDependsPtEval evaluator(const edm::EventSetup &es) const
GlobalPoint const & origin() const
constexpr float ftwoPi()
Definition: Pi.h:36
void initLayer(const DetLayer *layer)
def create(alignables, pedeDump, additionalData, outputFile, config)
T y() const
Definition: PV3DBase.h:63
bool exists(std::string const &parameterName) const
checks if a parameter exists
static void fillDescriptions(edm::ParameterSetDescription &desc)
bool ev
#define constexpr
Range curvature(double transverseIP) const
T inversePt(T curvature, const edm::EventSetup &iSetup)
BaseTrackerRecHit const * ConstRecHitPointer
Definition: SeedingHitSet.h:11
bool isNotFinite(T x)
Definition: isFinite.h:10
T curvature(T InversePt, const edm::EventSetup &iSetup)
PixelRecoRange< float > Range
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
void hitQuadruplets(const TrackingRegion &region, OrderedHitSeeds &result, const edm::Event &ev, const edm::EventSetup &es, const SeedingLayerSetsHits::SeedingLayerSet &tripletLayers, const std::vector< SeedingLayerSetsHits::SeedingLayer > &fourthLayers) override
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
T min(T a, T b)
Definition: MathUtil.h:58
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::unique_ptr< SeedComparitor > theComparitor
SeedingHitSet::ConstRecHitPointer Hit
BaseTrackerRecHit const * Hit
Definition: RZLine.h:12
const QuantityDependsPt extraPhiTolerance
PixelQuadrupletGenerator(const edm::ParameterSet &cfg, edm::ConsumesCollector &&iC)
bool isBarrel() const
Definition: DetLayer.h:32
float chi2() const
Definition: FastCircleFit.h:66
T rerr(const GlobalPoint &aPoint) const
HLT enums.
Square< F >::type sqr(const F &f)
Definition: Square.h:13
#define declareDynArray(T, n, x)
Definition: DynArray.h:59
const QuantityDependsPt maxChi2
void initTolerance(float tolerance)
long double T
T x() const
Definition: PV3DBase.h:62
float chi2() const
Definition: RZLine.h:97
float phi(float curvature, float radius) const
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
std::unique_ptr< HitTripletGeneratorFromPairAndLayers > theTripletGenerator
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11