CMS 3D CMS Logo

PixelTripletHLTGenerator.cc
Go to the documentation of this file.
4 
6 #include "ThirdHitRZPrediction.h"
9 
12 #include "ThirdHitCorrection.h"
15 #include <iostream>
16 
19 
23 
25 
27 
28 #include<cstdio>
29 #include<iostream>
30 
33 
34 using namespace std;
35 
36 
39  useFixedPreFiltering(cfg.getParameter<bool>("useFixedPreFiltering")),
40  extraHitRZtolerance(cfg.getParameter<double>("extraHitRZtolerance")),
41  extraHitRPhitolerance(cfg.getParameter<double>("extraHitRPhitolerance")),
42  useMScat(cfg.getParameter<bool>("useMultScattering")),
43  useBend(cfg.getParameter<bool>("useBending")),
44  dphi(useFixedPreFiltering ? cfg.getParameter<double>("phiPreFiltering") : 0)
45 {
46  edm::ParameterSet comparitorPSet =
47  cfg.getParameter<edm::ParameterSet>("SeedComparitorPSet");
48  std::string comparitorName = comparitorPSet.getParameter<std::string>("ComponentName");
49  if(comparitorName != "none") {
50  theComparitor = std::unique_ptr<SeedComparitor>{SeedComparitorFactory::get()->create( comparitorName, comparitorPSet, iC)};
51  }
52 }
53 
55 
58  desc.add<double>("extraHitRPhitolerance", 0.032);
59  desc.add<double>("extraHitRZtolerance", 0.037);
60  desc.add<bool>("useMultScattering", true);
61  desc.add<bool>("useBending", true);
62  desc.add<bool>("useFixedPreFiltering", false);
63  desc.add<double>("phiPreFiltering", 0.3);
64 
65  edm::ParameterSetDescription descComparitor;
66  descComparitor.add<std::string>("ComponentName", "none");
67  descComparitor.setAllowAnything(); // until we have moved SeedComparitor too to EDProducers
68  desc.add<edm::ParameterSetDescription>("SeedComparitorPSet", descComparitor);
69 }
70 
73  const edm::Event & ev,
74  const edm::EventSetup& es,
75  const SeedingLayerSetsHits::SeedingLayerSet& pairLayers,
76  const std::vector<SeedingLayerSetsHits::SeedingLayer>& thirdLayers)
77 {
78  auto const & doublets = thePairGenerator->doublets(region,ev,es, pairLayers);
79  if (doublets.empty()) return;
80 
81  assert(theLayerCache);
82  hitTriplets(region, result, ev, es, doublets, thirdLayers, nullptr, *theLayerCache);
83 }
84 
86  const edm::Event& ev, const edm::EventSetup& es,
87  const HitDoublets& doublets,
88  const std::vector<SeedingLayerSetsHits::SeedingLayer>& thirdLayers,
89  std::vector<int> *tripletLastLayerIndex,
90  LayerCacheType& layerCache) {
91  if (theComparitor) theComparitor->init(ev, es);
92 
93  int size = thirdLayers.size();
94  const RecHitsSortedInPhi * thirdHitMap[size];
95  vector<const DetLayer *> thirdLayerDetLayer(size,nullptr);
96  for (int il=0; il<size; ++il)
97  {
98  thirdHitMap[il] = &layerCache(thirdLayers[il], region, es);
99  thirdLayerDetLayer[il] = thirdLayers[il].detLayer();
100  }
101  hitTriplets(region, result, es, doublets, thirdHitMap, thirdLayerDetLayer, size, tripletLastLayerIndex);
102 }
103 
105  const TrackingRegion& region,
107  const edm::EventSetup & es,
108  const HitDoublets & doublets,
109  const RecHitsSortedInPhi ** thirdHitMap,
110  const std::vector<const DetLayer *> & thirdLayerDetLayer,
111  const int nThirdLayers)
112 {
113  hitTriplets(region, result, es, doublets, thirdHitMap, thirdLayerDetLayer, nThirdLayers, nullptr);
114 }
115 
117  const edm::EventSetup & es,
118  const HitDoublets & doublets,
119  const RecHitsSortedInPhi ** thirdHitMap,
120  const std::vector<const DetLayer *> & thirdLayerDetLayer,
121  const int nThirdLayers,
122  std::vector<int> *tripletLastLayerIndex) {
123  auto outSeq = doublets.detLayer(HitDoublets::outer)->seqNum();
124 
125  float regOffset = region.origin().perp(); //try to take account of non-centrality (?)
126 
128  declareDynArray(ThirdHitCorrection, nThirdLayers, corrections);
129 
131 
132  using NodeInfo = KDTreeNodeInfo<unsigned int>;
133  std::vector<NodeInfo > layerTree; // re-used throughout
134  std::vector<unsigned int> foundNodes; // re-used thoughout
135  foundNodes.reserve(100);
136 
137  declareDynArray(KDTreeLinkerAlgo<unsigned int>,nThirdLayers, hitTree);
138  float rzError[nThirdLayers]; //save maximum errors
139 
140  const float maxDelphi = region.ptMin() < 0.3f ? float(M_PI)/4.f : float(M_PI)/8.f; // FIXME move to config??
141  const float maxphi = M_PI+maxDelphi, minphi = -maxphi; // increase to cater for any range
142  const float safePhi = M_PI-maxDelphi; // sideband
143 
144  // fill the prediction vector
145  for (int il=0; il<nThirdLayers; ++il) {
146  auto const & hits = *thirdHitMap[il];
147  ThirdHitRZPrediction<PixelRecoLineRZ> & pred = preds[il];
148  pred.initLayer(thirdLayerDetLayer[il]);
150 
151  corrections[il].init(es, region.ptMin(), *doublets.detLayer(HitDoublets::inner), *doublets.detLayer(HitDoublets::outer),
152  *thirdLayerDetLayer[il], useMScat, useBend);
153 
154  layerTree.clear();
155  float minv=999999.0f, maxv= -minv; // Initialise to extreme values in case no hits
156  float maxErr=0.0f;
157  for (unsigned int i=0; i!=hits.size(); ++i) {
158  auto angle = hits.phi(i);
159  auto v = hits.gv(i);
160  //use (phi,r) for endcaps rather than (phi,z)
161  minv = std::min(minv,v); maxv = std::max(maxv,v);
162  float myerr = hits.dv[i];
163  maxErr = std::max(maxErr,myerr);
164  layerTree.emplace_back(i, angle, v); // save it
165  // populate side-bands
166  if (angle>safePhi) layerTree.emplace_back(i, angle-Geom::ftwoPi(), v);
167  else if (angle<-safePhi) layerTree.emplace_back(i, angle+Geom::ftwoPi(), v);
168  }
169  KDTreeBox phiZ(minphi, maxphi, minv-0.01f, maxv+0.01f); // declare our bounds
170  //add fudge factors in case only one hit and also for floating-point inaccuracy
171  hitTree[il].build(layerTree, phiZ); // make KDtree
172  rzError[il] = maxErr; //save error
173  // std::cout << "layer " << thirdLayerDetLayer[il]->seqNum() << " " << layerTree.size() << std::endl;
174  }
175 
176  float imppar = region.originRBound();
177  float imppartmp = region.originRBound()+region.origin().perp();
178  float curv = PixelRecoUtilities::curvature(1.f/region.ptMin(), es);
179 
180  for (std::size_t ip =0; ip!=doublets.size(); ip++) {
181  auto xi = doublets.x(ip,HitDoublets::inner);
182  auto yi = doublets.y(ip,HitDoublets::inner);
183  auto zi = doublets.z(ip,HitDoublets::inner);
184  auto rvi = doublets.rv(ip,HitDoublets::inner);
185  auto xo = doublets.x(ip,HitDoublets::outer);
186  auto yo = doublets.y(ip,HitDoublets::outer);
187  auto zo = doublets.z(ip,HitDoublets::outer);
188  auto rvo = doublets.rv(ip,HitDoublets::outer);
189 
190  auto toPos = std::signbit(zo-zi);
191 
192  PixelRecoPointRZ point1(rvi, zi);
193  PixelRecoPointRZ point2(rvo, zo);
194  PixelRecoLineRZ line(point1, point2);
195  ThirdHitPredictionFromInvParabola predictionRPhi(xi-region.origin().x(),yi-region.origin().y(),
196  xo-region.origin().x(),yo-region.origin().y(),
197  imppar,curv,extraHitRPhitolerance);
198 
199  ThirdHitPredictionFromInvParabola predictionRPhitmp(xi,yi,xo,yo,imppartmp,curv,extraHitRPhitolerance);
200 
201  // printf("++Constr %f %f %f %f %f %f %f\n",xi,yi,xo,yo,imppartmp,curv,extraHitRPhitolerance);
202 
203  // std::cout << ip << ": " << point1.r() << ","<< point1.z() << " "
204  // << point2.r() << ","<< point2.z() <<std::endl;
205 
206  for (int il=0; il!=nThirdLayers; ++il) {
207  const DetLayer * layer = thirdLayerDetLayer[il];
208  auto barrelLayer = layer->isBarrel();
209 
210  if ( (!barrelLayer) & (toPos != std::signbit(layer->position().z())) ) continue;
211 
212  if (hitTree[il].empty()) continue; // Don't bother if no hits
213 
214  auto const & hits = *thirdHitMap[il];
215 
216  auto & correction = corrections[il];
217 
218  correction.init(line, point2, outSeq);
219 
220  auto & predictionRZ = preds[il];
221 
222  predictionRZ.initPropagator(&line);
223  Range rzRange = predictionRZ();
224  correction.correctRZRange(rzRange);
225 
226  Range phiRange;
227  if (useFixedPreFiltering) {
228  float phi0 = doublets.phi(ip,HitDoublets::outer);
229  phiRange = Range(phi0-dphi,phi0+dphi);
230  }
231  else {
232  Range radius;
233  if (barrelLayer) {
234  radius = predictionRZ.detRange();
235  } else {
236  radius = Range(max(rzRange.min(), predictionRZ.detSize().min()),
237  min(rzRange.max(), predictionRZ.detSize().max()) );
238  }
239  if (radius.empty()) continue;
240 
241  // std::cout << "++R " << radius.min() << " " << radius.max() << std::endl;
242 
243  auto rPhi1 = predictionRPhitmp(radius.max());
244  bool ok1 = !rPhi1.empty();
245  if (ok1) {
246  correction.correctRPhiRange(rPhi1);
247  rPhi1.first /= radius.max();
248  rPhi1.second /= radius.max();
249  }
250  auto rPhi2 = predictionRPhitmp(radius.min());
251  bool ok2 = !rPhi2.empty();
252  if (ok2) {
253  correction.correctRPhiRange(rPhi2);
254  rPhi2.first /= radius.min();
255  rPhi2.second /= radius.min();
256  }
257 
258  if (ok1) {
259  rPhi1.first = normalizedPhi(rPhi1.first);
260  rPhi1.second = proxim(rPhi1.second,rPhi1.first);
261  if(ok2) {
262  rPhi2.first = proxim(rPhi2.first,rPhi1.first);
263  rPhi2.second = proxim(rPhi2.second,rPhi1.first);
264  phiRange = rPhi1.sum(rPhi2);
265  } else phiRange=rPhi1;
266  } else if(ok2) {
267  rPhi2.first = normalizedPhi(rPhi2.first);
268  rPhi2.second = proxim(rPhi2.second,rPhi2.first);
269  phiRange=rPhi2;
270  } else continue;
271 
272  }
273 
274  constexpr float nSigmaRZ = 3.46410161514f; // std::sqrt(12.f); // ...and continue as before
275  constexpr float nSigmaPhi = 3.f;
276 
277  foundNodes.clear(); // Now recover hits in bounding box...
278  float prmin=phiRange.min(), prmax=phiRange.max();
279 
280 
281  if (prmax-prmin>maxDelphi) {
282  auto prm = phiRange.mean();
283  prmin = prm - 0.5f*maxDelphi;
284  prmax = prm + 0.5f*maxDelphi;
285  }
286 
287  if (barrelLayer)
288  {
289  Range regMax = predictionRZ.detRange();
290  Range regMin = predictionRZ(regMax.min()-regOffset);
291  regMax = predictionRZ(regMax.max()+regOffset);
292  correction.correctRZRange(regMin);
293  correction.correctRZRange(regMax);
294  if (regMax.min() < regMin.min()) { swap(regMax, regMin);}
295  KDTreeBox phiZ(prmin, prmax, regMin.min()-nSigmaRZ*rzError[il], regMax.max()+nSigmaRZ*rzError[il]);
296  hitTree[il].search(phiZ, foundNodes);
297  }
298  else
299  {
300  KDTreeBox phiZ(prmin, prmax,
301  rzRange.min()-regOffset-nSigmaRZ*rzError[il],
302  rzRange.max()+regOffset+nSigmaRZ*rzError[il]);
303  hitTree[il].search(phiZ, foundNodes);
304  }
305 
306  // std::cout << ip << ": " << thirdLayerDetLayer[il]->seqNum() << " " << foundNodes.size() << " " << prmin << " " << prmax << std::endl;
307 
308 
309  // int kk=0;
310  for (auto KDdata : foundNodes) {
311 
312  if (theMaxElement!=0 && result.size() >= theMaxElement){
313  result.clear();
314  if(tripletLastLayerIndex) tripletLastLayerIndex->clear();
315  edm::LogError("TooManyTriplets")<<" number of triples exceeds maximum. no triplets produced.";
316  return;
317  }
318 
319  float p3_u = hits.u[KDdata];
320  float p3_v = hits.v[KDdata];
321  float p3_phi = hits.lphi[KDdata];
322 
323  //if ((kk++)%100==0)
324  //std::cout << kk << ": " << p3_u << " " << p3_v << " " << p3_phi << std::endl;
325 
326 
327  Range allowed = predictionRZ(p3_u);
328  correction.correctRZRange(allowed);
329  float vErr = nSigmaRZ *hits.dv[KDdata];
330  Range hitRange(p3_v-vErr, p3_v+vErr);
331  Range crossingRange = allowed.intersection(hitRange);
332  if (crossingRange.empty()) continue;
333 
334  float ir = 1.f/hits.rv(KDdata);
335  // limit error to 90 degree
336  constexpr float maxPhiErr = 0.5*M_PI;
337  float phiErr = nSigmaPhi * hits.drphi[KDdata]*ir;
338  phiErr = std::min(maxPhiErr, phiErr);
339  bool nook=true;
340  for (int icharge=-1; icharge <=1; icharge+=2) {
341  Range rangeRPhi = predictionRPhi(hits.rv(KDdata), icharge);
342  if(rangeRPhi.first>rangeRPhi.second) continue; // range is empty
343  correction.correctRPhiRange(rangeRPhi);
344  if (checkPhiInRange(p3_phi, rangeRPhi.first*ir-phiErr, rangeRPhi.second*ir+phiErr,maxPhiErr)) {
345  // insert here check with comparitor
346  OrderedHitTriplet hittriplet( doublets.hit(ip,HitDoublets::inner), doublets.hit(ip,HitDoublets::outer), hits.theHits[KDdata].hit());
347  if (!theComparitor || theComparitor->compatible(hittriplet) ) {
348  result.push_back( hittriplet );
349  // to bookkeep the triplets and 3rd layers in triplet EDProducer
350  if(tripletLastLayerIndex) tripletLastLayerIndex->push_back(il);
351  } else {
352  LogDebug("RejectedTriplet") << "rejected triplet from comparitor ";
353  }
354  nook=false; break;
355  }
356  }
357  if (nook) LogDebug("RejectedTriplet") << "rejected triplet from second phicheck " << p3_phi;
358  }
359  }
360  }
361  // std::cout << "triplets " << result.size() << std::endl;
362 }
363 
#define LogDebug(id)
size
Write out results.
float originRBound() const
bounds the particle vertex in the transverse plane
T getParameter(std::string const &) const
std::size_t size() const
T perp() const
Definition: PV3DBase.h:72
GlobalPoint const & origin() const
constexpr float ftwoPi()
Definition: Pi.h:36
void initLayer(const DetLayer *layer)
void setAllowAnything()
allow any parameter label/value pairs
PixelRecoRange< float > Range
constexpr T normalizedPhi(T phi)
Definition: normalizedPhi.h:9
float x(int i, layer l) const
T y() const
Definition: PV3DBase.h:63
bool ev
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
std::unique_ptr< SeedComparitor > theComparitor
constexpr T proxim(T b, T a)
Definition: normalizedPhi.h:14
float z(int i, layer l) const
int seqNum() const
Definition: DetLayer.h:36
T curvature(T InversePt, const edm::EventSetup &iSetup)
static void fillDescriptions(edm::ParameterSetDescription &desc)
static void fillDescriptions(edm::ParameterSetDescription &desc)
T z() const
Definition: PV3DBase.h:64
void hitTriplets(const TrackingRegion &region, OrderedHitTriplets &trs, const edm::Event &ev, const edm::EventSetup &es, const SeedingLayerSetsHits::SeedingLayerSet &pairLayers, const std::vector< SeedingLayerSetsHits::SeedingLayer > &thirdLayers) override
PixelTripletHLTGenerator(const edm::ParameterSet &cfg, edm::ConsumesCollector &&iC)
double f[11][100]
T min(T a, T b)
Definition: MathUtil.h:58
float y(int i, layer l) const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
unsigned int size() const override
SeedingHitSet::ConstRecHitPointer Hit
BaseTrackerRecHit const * Hit
#define M_PI
bool isBarrel() const
Definition: DetLayer.h:32
float phi(int i, layer l) const
std::unique_ptr< HitPairGeneratorFromLayerPair > thePairGenerator
virtual const Surface::PositionType & position() const
Returns position of the surface.
float ptMin() const
minimal pt of interest
constexpr bool checkPhiInRange(T phi, T phi1, T phi2, float maxDphi=float(M_PI))
Definition: normalizedPhi.h:34
Hit const & hit(int i, layer l) const
PixelRecoRange< T > intersection(const PixelRecoRange< T > &r) const
#define declareDynArray(T, n, x)
Definition: DynArray.h:59
void initTolerance(float tolerance)
T x() const
Definition: PV3DBase.h:62
DetLayer const * detLayer(layer l) const
float rv(int i, layer l) const
T get(const Candidate &c)
Definition: component.h:55
#define constexpr
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11