52 struct LayerRZPredictions {
62 extraZKDBox(cfg.getParameter<double>(
"extraZKDBox")),
63 extraRKDBox(cfg.getParameter<double>(
"extraRKDBox")),
65 fnSigmaRZ(cfg.getParameter<double>(
"fnSigmaRZ")),
67 maxChi2(cfg.getParameter<double>(
"maxChi2")),
69 filterName_(cfg.getParameter<
std::
string>(
"ClusterShapeHitFilterName")),
70 builderName_(cfg.existsAs<
std::
string>(
"TTRHBuilder") ? cfg.getParameter<
std::
string>(
"TTRHBuilder") :
std::
string(
"WithTrackAngle")),
84 detIdsToDebug.push_back(0);
85 detIdsToDebug.push_back(0);
86 detIdsToDebug.push_back(0);
92 if (cfg.
exists(
"SimpleMagneticField")) {
108 desc.
add<
bool>(
"useFixedPreFiltering",
false);
109 desc.
add<
double>(
"phiPreFiltering", 0.3);
112 desc.
add<
double>(
"extraHitRPhitolerance", 0);
113 desc.
add<
double>(
"extraHitRZtolerance", 0);
114 desc.
add<
double>(
"extraZKDBox", 0.2);
115 desc.
add<
double>(
"extraRKDBox", 0.2);
116 desc.
add<
double>(
"extraPhiKDBox", 0.005);
117 desc.
add<
double>(
"fnSigmaRZ", 2.0);
120 desc.
add<
bool>(
"refitHits",
true);
121 desc.
add<
std::string>(
"ClusterShapeHitFilterName",
"ClusterShapeHitFilter");
125 desc.
add<
double>(
"maxChi2", 5.0);
126 desc.
add<
bool>(
"chi2VsPtCut",
true);
127 desc.
add<std::vector<double> >(
"pt_interv", std::vector<double>{{0.4,0.7,1.0,2.0}});
128 desc.
add<std::vector<double> >(
"chi2_cuts", std::vector<double>{{3.0,4.0,5.0,5.0}});
131 desc.
add<std::vector<int> >(
"detIdsToDebug", std::vector<int>{{0,0,0}});
154 cloner = (*builder).cloner();
163 if (range.first > second.max() || range.second < second.min())
165 if (range.first < second.min())
166 range.first = second.min();
167 if (range.second > second.max())
168 range.second = second.max();
169 return range.first < range.second;
178 std::vector<SeedingLayerSetsHits::SeedingLayer> thirdLayers)
180 LogDebug(
"MultiHitGeneratorFromChi2") <<
"pair: " <<
thePairGenerator->innerLayer(pairLayers).name() <<
"+" <<
thePairGenerator->outerLayer(pairLayers).name() <<
" 3rd lay size: " << thirdLayers.size();
183 LogTrace(
"MultiHitGeneratorFromChi2") <<
"";
196 const std::vector<SeedingLayerSetsHits::SeedingLayer>& thirdLayers,
199 int size = thirdLayers.size();
201 vector<const DetLayer *> thirdLayerDetLayer(size,
nullptr);
202 for (
int il=0; il<
size; ++il)
204 thirdHitMap[il] = &layerCache(thirdLayers[il], region, es);
206 thirdLayerDetLayer[il] = thirdLayers[il].detLayer();
208 hitSets(region, result, es, doublets, thirdHitMap, thirdLayerDetLayer, size, refittedHitStorage);
217 const std::vector<const DetLayer *> & thirdLayerDetLayer,
218 const int nThirdLayers)
220 hitSets(region, result, es, doublets, thirdHitMap, thirdLayerDetLayer, nThirdLayers,
cache);
227 const std::vector<const DetLayer *>& thirdLayerDetLayer,
228 const int nThirdLayers,
236 std::array<bool, 3> bl;
244 std::vector<KDTreeNodeInfo<RecHitsSortedInPhi::HitIter> > layerTree;
245 std::vector<RecHitsSortedInPhi::HitIter> foundNodes;
246 foundNodes.reserve(100);
249 float rzError[nThirdLayers];
252 const float maxphi =
M_PI+maxDelphi, minphi = -maxphi;
253 const float safePhi =
M_PI-maxDelphi;
257 for(
int il = 0; il < nThirdLayers; il++) {
258 LogTrace(
"MultiHitGeneratorFromChi2") <<
"considering third layer: with hits: " << thirdHitMap[il]->
all().second-thirdHitMap[il]->
all().first;
259 const DetLayer *layer = thirdLayerDetLayer[il];
260 LayerRZPredictions &predRZ = mapPred[il];
261 predRZ.line.initLayer(layer);
265 auto const & layer3 = *thirdHitMap[il];
267 float minz=999999.0f, maxz= -minz;
273 for (
auto i=0
U;
i<layer3.size(); ++
i)
275 auto hi = layer3.theHits.begin()+
i;
276 auto angle = layer3.phi(
i);
277 auto myz = layer3.v[
i];
279 IfLogTrace(
hi->hit()->rawId()==debug_Id2,
"MultiHitGeneratorFromChi2") <<
"filling KDTree with hit in id=" << debug_Id2
280 <<
" with pos: " <<
hi->hit()->globalPosition()
281 <<
" phi=" <<
hi->hit()->globalPosition().phi()
282 <<
" z=" <<
hi->hit()->globalPosition().z()
283 <<
" r=" <<
hi->hit()->globalPosition().perp();
286 if (myz < minz) { minz = myz;}
else {
if (myz > maxz) {maxz = myz;}}
287 auto myerr = layer3.dv[
i];
288 if (myerr > maxErr) { maxErr = myerr;}
295 KDTreeBox phiZ(minphi, maxphi, minz-0.01
f, maxz+0.01
f);
297 hitTree[il].build(layerTree, phiZ);
298 rzError[il] = maxErr;
305 LogTrace(
"MultiHitGeneratorFromChi2") <<
"doublet size=" << doublets.
size() << std::endl;
317 if (hh->isMatched()) {
321 }
else if (hh->isProjected()) {
324 }
else if (hh->isSingle()) {
333 for (std::size_t ip =0; ip!=doublets.
size(); ip++) {
335 int foundTripletsFromPair = 0;
336 bool usePair =
false;
349 bool debugPair = oriHit0->rawId()==debug_Id0 && oriHit1->rawId()==debug_Id1;
351 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") << endl << endl
352 <<
"found new pair with ids "<<oriHit0->rawId()<<
" "<<oriHit1->rawId()<<
" with pos: " << gp0 <<
" " << gp1;
364 bool passFilterHit0 = filterHit(hit0->hit(),tsos0.
globalMomentum());
365 IfLogTrace(debugPair&&!passFilterHit0,
"MultiHitGeneratorFromChi2") <<
"hit0 did not pass cluster shape filter";
366 if (!passFilterHit0)
continue;
367 bool passFilterHit1 = filterHit(hit1->hit(),tsos1.
globalMomentum());
368 IfLogTrace(debugPair&&!passFilterHit1,
"MultiHitGeneratorFromChi2") <<
"hit1 did not pass cluster shape filter";
369 if (!passFilterHit1)
continue;
375 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"charge=" << tsos0.
charge() << std::endl
378 <<
"positions after refitting: " << hit0->globalPosition() <<
" " << hit1->globalPosition();
393 auto toPos = std::signbit(gp1.z()-gp0.
z());
399 if (!intersect(pairCurvature,
Range(-curv, curv))) {
400 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"curvature cut: curv=" << curv
401 <<
" gc=(" << pairCurvature.first <<
", " << pairCurvature.second <<
")";
406 std::array<GlobalPoint, 3>
gp;
407 std::array<GlobalError, 3> ge;
408 gp[0] = hit0->globalPosition();
409 ge[0] = hit0->globalPositionError();
410 gp[1] = hit1->globalPosition();
411 ge[1] = hit1->globalPositionError();
415 for(
int il = 0; (il < nThirdLayers) & (!usePair); il++) {
416 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"cosider layer:" <<
" for this pair. Location: " << thirdLayerDetLayer[il]->location();
418 if (hitTree[il].
empty()) {
419 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"empty hitTree";
426 const DetLayer *layer = thirdLayerDetLayer[il];
428 auto const & layer3 = *thirdHitMap[il];
430 bl[2] = layer3.isBarrel;
432 if ( (!barrelLayer) & (toPos != std::signbit(layer->
position().
z())) )
continue;
435 LayerRZPredictions &predRZ = mapPred[il];
436 predRZ.line.initPropagator(&line);
440 Range rzRange = predRZ.line();
442 if (rzRange.first >= rzRange.second) {
443 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"rzRange empty";
448 if (!intersect(rzRange, predRZ.line.detSize())) {
449 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"rzRange and detector do not intersect";
452 Range radius = barrelLayer ? predRZ.line.detRange() : rzRange;
459 float phi0 = oriHit0->globalPosition().phi();
463 if (pairCurvature.first<0. && pairCurvature.second<0.) {
465 }
else if (pairCurvature.first>=0. && pairCurvature.second>=0.) {;}
467 radius.first=radius.second;
469 auto phi12 = predictionRPhi.
phi(pairCurvature.first,radius.first);
470 auto phi22 = predictionRPhi.
phi(pairCurvature.second,radius.second);
472 phi22 =
proxim(phi22,phi12);
473 phiRange =
Range(phi12,phi22); phiRange.sort();
476 float prmin=phiRange.min(), prmax=phiRange.max();
478 if (prmax-prmin>maxDelphi) {
479 auto prm = phiRange.mean();
480 prmin = prm - 0.5f*maxDelphi;
481 prmax = prm + 0.5f*maxDelphi;
491 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"defining kd tree box";
497 hitTree[il].search(phiZ, foundNodes);
500 <<
" z: "<< rzRange.min()-
fnSigmaRZ*rzError[il]-extraZKDBox <<
","<<rzRange.max()+
fnSigmaRZ*rzError[il]+extraZKDBox
501 <<
" rzRange: " << rzRange.min() <<
","<<rzRange.max();
507 hitTree[il].search(phiR, foundNodes);
510 <<
" r: "<< rzRange.min()-
fnSigmaRZ*rzError[il]-extraRKDBox <<
","<<rzRange.max()+
fnSigmaRZ*rzError[il]+extraRKDBox
511 <<
" rzRange: " << rzRange.min() <<
","<<rzRange.max();
514 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"kd tree box size: " << foundNodes.size();
518 for (std::vector<RecHitsSortedInPhi::HitIter>::iterator ih = foundNodes.begin();
519 ih !=foundNodes.end() && !usePair; ++ih) {
521 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") << endl <<
"triplet candidate";
525 auto oriHit2 = KDdata->hit();
526 auto kk = KDdata - layer3.theHits.begin();
528 auto gp2 = layer3.gp(
kk);
533 initMomentum /= initMomentum.
perp();
536 bool passFilterHit2 = filterHit(oriHit2->hit(),initMomentum);
537 if (!passFilterHit2)
continue;
547 gp[2] = hit2->globalPosition();
548 ge[2] = hit2->globalPositionError();
553 bool debugTriplet = debugPair && hit2->rawId()==debug_Id2;
555 IfLogTrace(debugTriplet,
"MultiHitGeneratorFromChi2") << endl <<
"triplet candidate in debug id" << std::endl
556 <<
"hit in id="<<hit2->rawId()<<
" (from KDTree) with pos: " << KDdata->hit()->globalPosition()
557 <<
" refitted: " << hit2->globalPosition()
558 <<
" chi2: " <<
chi2;
566 float rho = theCircle.
rho();
567 float cm2GeV = 0.01f * 0.3f*tesla0;
568 float pt = cm2GeV *
rho;
569 IfLogTrace(debugTriplet,
"MultiHitGeneratorFromChi2") <<
"triplet pT=" <<
pt;
570 if (pt<region.
ptMin())
continue;
598 edm::LogError(
"TooManyTriplets")<<
" number of triples exceed maximum. no triplets produced.";
601 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"triplet made";
612 chi2FromThisLayer =
chi2;
613 foundTripletsFromPair++;
614 if (foundTripletsFromPair>=2) {
616 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"using pair";
624 if (chi2FromThisLayer<minChi2) {
626 minChi2 = chi2FromThisLayer;
638 if (foundTripletsFromPair==0)
continue;
641 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"Done seed #" << result.
size();
642 if (usePair) result.push_back(
SeedingHitSet(oriHit0, oriHit1));
644 assert(1==foundTripletsFromPair);
646 result.emplace_back(&*hit0,&*hit1,&*bestH2);
648 refittedHitStorage.emplace_back(const_cast<BaseTrackerRecHit*>(hit0.
release()));
649 refittedHitStorage.emplace_back(const_cast<BaseTrackerRecHit*>(hit1.
release()));
650 refittedHitStorage.emplace_back(
std::move(bestH2));
651 assert(hit0.
empty()); assert(hit1.
empty());assert(!bestH2);
657 LogTrace(
"MultiHitGeneratorFromChi2") <<
"triplet size=" << result.
size();
672 IfLogTrace(isDebug,
"MultiHitGeneratorFromChi2") <<
"positions before refitting: " << hit1->globalPosition() <<
" " << hit2->globalPosition();
677 float rho = theCircle.
rho();
678 float cm2GeV = 0.01f * 0.3f*tesla0;
679 float pt = cm2GeV *
rho;
685 p0 = p0*pt/p0.
perp();
687 p1 = p1*pt/p1.perp();
689 p2 = p2*pt/p2.perp();
692 if ( (p0.x()*(gp1.
x()-gp0.x())+p0.y()*(gp1.
y()-gp0.y()) ) < 0 ) {
699 auto zv = vec20.
z()/vec20.
perp();
706 if ((gp1-cc).x()*p1.
y() - (gp1-cc).
y()*p1.
x() > 0) q =-q;
float originRBound() const
bounds the particle vertex in the transverse plane
LayerCacheType * theLayerCache
T getParameter(std::string const &) const
unsigned int stereoId() const
~MultiHitGeneratorFromChi2() override
TrackCharge charge() const
std::unique_ptr< BaseTrackerRecHit > cacheHitPointer
GlobalPoint const & origin() const
HitLayer const & innerLayer() const
int nominalValue() const
The nominal field value for this map in kGauss.
constexpr bool isNotFinite(T x)
TkTransientTrackingRecHitBuilder const * builder
unsigned int size() const override
std::vector< cacheHitPointer > cacheHits
std::vector< int > detIdsToDebug
SiStripCluster const & monoCluster() const
const ClusterShapeHitFilter * filter
constexpr T normalizedPhi(T phi)
Geom::Phi< T > phi() const
bool exists(std::string const ¶meterName) const
checks if a parameter exists
#define IfLogTrace(cond, cat)
void swap(Association< C > &lhs, Association< C > &rhs)
constexpr T proxim(T b, T a)
Range curvature(double transverseIP) const
U second(std::pair< T, U > const &p)
HitLayer const & outerLayer() const
BaseTrackerRecHit const * ConstRecHitPointer
T curvature(T InversePt, const edm::EventSetup &iSetup)
bool useFixedPreFiltering
std::vector< HitWithPhi >::const_iterator HitIter
const MagneticField * bfield
void initES(const edm::EventSetup &es) override
MultiHitGeneratorFromChi2(const edm::ParameterSet &cfg)
GlobalPoint gp(int i, layer l) const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::vector< double > pt_interv
bool isCompatible(const SiPixelRecHit &recHit, const LocalVector &ldir, const SiPixelClusterShapeCache &clusterShapeCache, PixelData const *pd=0) const
BaseTrackerRecHit const * Hit
UniformMagneticField ufield
SiStripRecHit2D originalHit() const
float extraHitRZtolerance
void hitSets(const TrackingRegion ®ion, OrderedMultiHits &trs, const edm::Event &ev, const edm::EventSetup &es, SeedingLayerSetsHits::SeedingLayerSet pairLayers, std::vector< SeedingLayerSetsHits::SeedingLayer > thirdLayers) override
virtual const Surface::PositionType & position() const
Returns position of the surface.
float ptMin() const
minimal pt of interest
float extraHitRPhitolerance
std::vector< double > chi2_cuts
Hit const & hit(int i, layer l) const
SiStripCluster const & stereoCluster() const
GlobalVector globalMomentum() const
std::unique_ptr< HitPairGeneratorFromLayerPair > thePairGenerator
static void fillDescriptions(edm::ParameterSetDescription &desc)
void hitTriplets(const TrackingRegion ®ion, OrderedMultiHits &result, const edm::EventSetup &es, const HitDoublets &doublets, const RecHitsSortedInPhi **thirdHitMap, const std::vector< const DetLayer * > &thirdLayerDetLayer, const int nThirdLayers) override
#define declareDynArray(T, n, x)
unsigned int monoId() const
const unsigned int theMaxElement
PixelRecoRange< float > Range
static void fillDescriptions(edm::ParameterSetDescription &desc)
float phi(float curvature, float radius) const
T const * product() const
Global3DVector GlobalVector
void refit2Hits(HitOwnPtr &hit0, HitOwnPtr &hit1, TrajectoryStateOnSurface &tsos0, TrajectoryStateOnSurface &tsos1, const TrackingRegion ®ion, float nomField, bool isDebug)
T angle(T x1, T y1, T z1, T x2, T y2, T z2)