44 struct LayerRZPredictions {
53 cfg.getParameter<double>(
"extraHitRZtolerance")),
55 "extraHitRPhitolerance")),
57 cfg.getParameter<double>(
"extraZKDBox")),
59 cfg.getParameter<double>(
"extraRKDBox")),
64 maxChi2(cfg.getParameter<double>(
"maxChi2")),
65 refitHits(cfg.getParameter<bool>(
"refitHits")),
66 filterName_(cfg.getParameter<std::
string>(
"ClusterShapeHitFilterName")),
67 builderName_(cfg.existsAs<std::
string>(
"TTRHBuilder") ? cfg.getParameter<std::
string>(
"TTRHBuilder")
68 : std::
string(
"WithTrackAngle")),
89 if (cfg.
exists(
"SimpleMagneticField")) {
114 desc.
add<
bool>(
"useFixedPreFiltering",
false);
115 desc.
add<
double>(
"phiPreFiltering", 0.3);
118 desc.
add<
double>(
"extraHitRPhitolerance", 0);
119 desc.
add<
double>(
"extraHitRZtolerance", 0);
120 desc.
add<
double>(
"extraZKDBox", 0.2);
121 desc.
add<
double>(
"extraRKDBox", 0.2);
122 desc.
add<
double>(
"extraPhiKDBox", 0.005);
123 desc.
add<
double>(
"fnSigmaRZ", 2.0);
126 desc.
add<
bool>(
"refitHits",
true);
127 desc.
add<
std::string>(
"ClusterShapeHitFilterName",
"ClusterShapeHitFilter");
131 desc.
add<
double>(
"maxChi2", 5.0);
132 desc.
add<
bool>(
"chi2VsPtCut",
true);
133 desc.
add<std::vector<double> >(
"pt_interv", std::vector<double>{{0.4, 0.7, 1.0, 2.0}});
134 desc.
add<std::vector<double> >(
"chi2_cuts", std::vector<double>{{3.0, 4.0, 5.0, 5.0}});
137 desc.
add<std::vector<int> >(
"detIdsToDebug", std::vector<int>{{0, 0, 0}});
149 cloner = (*builder).cloner();
155 if (range.first > second.max() || range.second < second.min())
157 if (range.first < second.min())
158 range.first = second.min();
159 if (range.second > second.max())
160 range.second = second.max();
161 return range.first < range.second;
170 std::vector<SeedingLayerSetsHits::SeedingLayer> thirdLayers) {
173 <<
" 3rd lay size: " << thirdLayers.size();
176 LogTrace(
"MultiHitGeneratorFromChi2") <<
"";
189 const std::vector<SeedingLayerSetsHits::SeedingLayer>& thirdLayers,
192 int size = thirdLayers.size();
194 vector<const DetLayer*> thirdLayerDetLayer(size,
nullptr);
195 for (
int il = 0; il <
size; ++il) {
196 thirdHitMap[il] = &layerCache(thirdLayers[il], region);
198 thirdLayerDetLayer[il] = thirdLayers[il].detLayer();
200 hitSets(region, result, doublets, thirdHitMap, thirdLayerDetLayer, size, refittedHitStorage);
207 const std::vector<const DetLayer*>& thirdLayerDetLayer,
208 const int nThirdLayers) {
209 hitSets(region, result, doublets, thirdHitMap, thirdLayerDetLayer, nThirdLayers,
cache);
216 const std::vector<const DetLayer*>& thirdLayerDetLayer,
217 const int nThirdLayers,
225 std::array<bool, 3> bl;
232 std::vector<KDTreeNodeInfo<RecHitsSortedInPhi::HitIter, 2> > layerTree;
233 std::vector<RecHitsSortedInPhi::HitIter> foundNodes;
234 foundNodes.reserve(100);
237 float rzError[nThirdLayers];
239 const float maxDelphi = region.
ptMin() < 0.3f ? float(
M_PI) / 4.f : float(
M_PI) / 8.f;
240 const float maxphi =
M_PI + maxDelphi, minphi = -maxphi;
241 const float safePhi =
M_PI - maxDelphi;
244 for (
int il = 0; il < nThirdLayers; il++) {
245 LogTrace(
"MultiHitGeneratorFromChi2")
246 <<
"considering third layer: with hits: " << thirdHitMap[il]->
all().second - thirdHitMap[il]->
all().first;
248 LayerRZPredictions& predRZ = mapPred[il];
249 predRZ.line.initLayer(layer);
253 auto const& layer3 = *thirdHitMap[il];
257 if (!layer3.empty()) {
260 for (
auto i = 0U;
i < layer3.size(); ++
i) {
261 auto hi = layer3.theHits.begin() +
i;
262 auto angle = layer3.phi(
i);
263 auto myz = layer3.v[
i];
265 IfLogTrace(hi->hit()->rawId() == debug_Id2,
"MultiHitGeneratorFromChi2")
266 <<
"filling KDTree with hit in id=" << debug_Id2 <<
" with pos: " << hi->hit()->globalPosition()
267 <<
" phi=" << hi->hit()->globalPosition().phi() <<
" z=" << hi->hit()->globalPosition().z()
268 <<
" r=" << hi->hit()->globalPosition().perp();
278 auto myerr = layer3.dv[
i];
279 if (myerr > maxErr) {
287 else if (
angle < -safePhi)
294 hitTree[il].build(layerTree, phiZ);
295 rzError[il] = maxErr;
302 LogTrace(
"MultiHitGeneratorFromChi2") <<
"doublet size=" << doublets.
size() << std::endl;
313 if (
hh->isMatched()) {
318 }
else if (
hh->isProjected()) {
322 }
else if (
hh->isSingle()) {
332 for (std::size_t ip = 0; ip != doublets.
size(); ip++) {
333 int foundTripletsFromPair = 0;
334 bool usePair =
false;
347 bool debugPair = oriHit0->rawId() == debug_Id0 && oriHit1->rawId() == debug_Id1;
349 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") << endl
351 <<
"found new pair with ids " << oriHit0->rawId() <<
" "
352 << 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";
368 bool passFilterHit1 = filterHit(hit1->hit(), tsos1.
globalMomentum());
369 IfLogTrace(debugPair && !passFilterHit1,
"MultiHitGeneratorFromChi2") <<
"hit1 did not pass cluster shape filter";
377 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2")
378 <<
"charge=" << tsos0.
charge() << std::endl
383 <<
"positions after refitting: " << hit0->globalPosition() <<
" " << hit1->globalPosition();
398 auto toPos = std::signbit(gp1.z() - gp0.
z());
403 if (!intersect(pairCurvature,
Range(-curv, curv))) {
404 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2")
405 <<
"curvature cut: curv=" << curv <<
" gc=(" << pairCurvature.first <<
", " << pairCurvature.second <<
")";
409 std::array<GlobalPoint, 3>
gp;
410 std::array<GlobalError, 3> ge;
411 gp[0] = hit0->globalPosition();
412 ge[0] = hit0->globalPositionError();
413 gp[1] = hit1->globalPosition();
414 ge[1] = hit1->globalPositionError();
417 for (
int il = 0; (il < nThirdLayers) & (!usePair); il++) {
418 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2")
420 <<
" for this pair. Location: " << thirdLayerDetLayer[il]->location();
422 if (hitTree[il].
empty()) {
423 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"empty hitTree";
432 auto const& layer3 = *thirdHitMap[il];
434 bl[2] = layer3.isBarrel;
436 if ((!barrelLayer) & (toPos != std::signbit(layer->
position().
z())))
439 LayerRZPredictions& predRZ = mapPred[il];
440 predRZ.line.initPropagator(&line);
444 Range rzRange = predRZ.line();
446 if (rzRange.first >= rzRange.second) {
447 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"rzRange empty";
452 if (!intersect(rzRange, predRZ.line.detSize())) {
453 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"rzRange and detector do not intersect";
456 Range radius = barrelLayer ? predRZ.line.detRange() : rzRange;
463 float phi0 = oriHit0->globalPosition().phi();
467 if (pairCurvature.first < 0. && pairCurvature.second < 0.) {
469 }
else if (pairCurvature.first >= 0. && pairCurvature.second >= 0.) {
472 radius.first = radius.second;
474 auto phi12 = predictionRPhi.
phi(pairCurvature.first, radius.first);
475 auto phi22 = predictionRPhi.
phi(pairCurvature.second, radius.second);
477 phi22 =
proxim(phi22, phi12);
478 phiRange =
Range(phi12, phi22);
482 float prmin = phiRange.min(), prmax = phiRange.max();
484 if (prmax - prmin > maxDelphi) {
485 auto prm = phiRange.mean();
486 prmin = prm - 0.5f * maxDelphi;
487 prmax = prm + 0.5f * maxDelphi;
494 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"defining kd tree box";
501 hitTree[il].search(phiZ, foundNodes);
503 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2")
506 << rzRange.max() +
fnSigmaRZ * rzError[il] +
extraZKDBox <<
" rzRange: " << rzRange.min() <<
","
514 hitTree[il].search(phiR, foundNodes);
516 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2")
519 << rzRange.max() +
fnSigmaRZ * rzError[il] +
extraRKDBox <<
" rzRange: " << rzRange.min() <<
","
523 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"kd tree box size: " << foundNodes.size();
526 for (std::vector<RecHitsSortedInPhi::HitIter>::iterator ih = foundNodes.begin();
527 ih != foundNodes.end() && !usePair;
529 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") << endl <<
"triplet candidate";
533 auto oriHit2 = KDdata->hit();
534 auto kk = KDdata - layer3.theHits.begin();
536 auto gp2 = layer3.gp(
kk);
541 initMomentum /= initMomentum.
perp();
544 bool passFilterHit2 = filterHit(oriHit2->hit(), initMomentum);
548 *oriHit2->surface());
557 gp[2] = hit2->globalPosition();
558 ge[2] = hit2->globalPositionError();
559 RZLine rzLine(gp, ge, bl);
563 bool debugTriplet = debugPair && hit2->rawId() == debug_Id2;
565 IfLogTrace(debugTriplet,
"MultiHitGeneratorFromChi2")
567 <<
"triplet candidate in debug id" << std::endl
568 <<
"hit in id=" << hit2->rawId() <<
" (from KDTree) with pos: " << KDdata->hit()->globalPosition()
569 <<
" refitted: " << hit2->globalPosition() <<
" chi2: " <<
chi2;
577 float rho = theCircle.
rho();
578 float cm2GeV = 0.01f * 0.3f * tesla0;
579 float pt = cm2GeV *
rho;
580 IfLogTrace(debugTriplet,
"MultiHitGeneratorFromChi2") <<
"triplet pT=" <<
pt;
581 if (pt < region.
ptMin())
610 edm::LogError(
"TooManyTriplets") <<
" number of triples exceed maximum. no triplets produced.";
613 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"triplet made";
624 chi2FromThisLayer =
chi2;
625 foundTripletsFromPair++;
626 if (foundTripletsFromPair >= 2) {
628 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"using pair";
637 if (chi2FromThisLayer < minChi2) {
639 minChi2 = chi2FromThisLayer;
651 if (foundTripletsFromPair == 0)
655 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"Done seed #" << result.
size();
659 assert(1 == foundTripletsFromPair);
661 result.emplace_back(&*hit0, &*hit1, &*bestH2);
664 refittedHitStorage.emplace_back(const_cast<BaseTrackerRecHit*>(hit0.
release()));
665 refittedHitStorage.emplace_back(const_cast<BaseTrackerRecHit*>(hit1.
release()));
666 refittedHitStorage.emplace_back(
std::move(bestH2));
674 LogTrace(
"MultiHitGeneratorFromChi2") <<
"triplet size=" << result.
size();
690 IfLogTrace(isDebug,
"MultiHitGeneratorFromChi2")
691 <<
"positions before refitting: " << hit1->globalPosition() <<
" " << hit2->globalPosition();
696 float rho = theCircle.
rho();
697 float cm2GeV = 0.01f * 0.3f * tesla0;
698 float pt = cm2GeV *
rho;
703 GlobalVector p0(gp0.y() - cc.y(), -gp0.x() + cc.x(), 0.);
704 p0 = p0 * pt / p0.
perp();
706 p1 = p1 * pt / p1.
perp();
708 p2 = p2 * pt / p2.
perp();
711 if ((p0.
x() * (gp1.
x() - gp0.x()) + p0.
y() * (gp1.
y() - gp0.y())) < 0) {
718 auto zv = vec20.
z() / vec20.
perp();
725 if ((gp1 - cc).x() * p1.
y() - (gp1 - cc).
y() * p1.
x() > 0)
float originRBound() const
bounds the particle vertex in the transverse plane
LayerCacheType * theLayerCache
unsigned int size() const override
unsigned int stereoId() const
MultiHitGeneratorFromChi2(const edm::ParameterSet &cfg, edm::ConsumesCollector &&iC)
~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.
#define IfLogTrace(cond, cat)
constexpr bool isNotFinite(T x)
PixelRecoRange< float > Range
static constexpr auto TID
TkTransientTrackingRecHitBuilder const * builder
std::vector< cacheHitPointer > cacheHits
std::vector< int > detIdsToDebug
SiStripCluster const & monoCluster() const
const ClusterShapeHitFilter * filter
constexpr T normalizedPhi(T phi)
void hitTriplets(const TrackingRegion ®ion, OrderedMultiHits &result, const HitDoublets &doublets, const RecHitsSortedInPhi **thirdHitMap, const std::vector< const DetLayer * > &thirdLayerDetLayer, const int nThirdLayers) override
Geom::Phi< T > phi() const
bool exists(std::string const ¶meterName) const
checks if a parameter exists
Log< level::Error, false > LogError
edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > transientTrackingRecHitBuilderESToken_
void swap(Association< C > &lhs, Association< C > &rhs)
T curvature(T InversePt, const MagneticField &field)
constexpr T proxim(T b, T a)
constexpr std::array< uint8_t, layerIndexSize > layer
tuple extraHitRZtolerance
const uint16_t range(const Frame &aFrame)
Range curvature(double transverseIP) const
__constant__ float const minz[nPairs]
bool getData(T &iHolder) const
U second(std::pair< T, U > const &p)
HitLayer const & outerLayer() const
constexpr float fnSigmaRZ
BaseTrackerRecHit const * ConstRecHitPointer
bool useFixedPreFiltering
std::vector< HitWithPhi >::const_iterator HitIter
const MagneticField * bfield
edm::ESGetToken< ClusterShapeHitFilter, CkfComponentsRecord > clusterShapeHitFilterESToken_
void initES(const edm::EventSetup &es) override
GlobalPoint gp(int i, layer l) const
tuple extraHitRPhitolerance
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::vector< double > pt_interv
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
__constant__ float const maxz[nPairs]
virtual const Surface::PositionType & position() const
Returns position of the surface.
T getParameter(std::string const &) const
float ptMin() const
minimal pt of interest
static constexpr auto TIB
float extraHitRPhitolerance
std::vector< double > chi2_cuts
Hit const & hit(int i, layer l) const
SiStripCluster const & stereoCluster() const
bool isCompatible(const SiPixelRecHit &recHit, const LocalVector &ldir, const SiPixelClusterShapeCache &clusterShapeCache, PixelData const *pd=nullptr) const
GlobalVector globalMomentum() const
std::unique_ptr< HitPairGeneratorFromLayerPair > thePairGenerator
static void fillDescriptions(edm::ParameterSetDescription &desc)
#define declareDynArray(T, n, x)
unsigned int monoId() const
const unsigned int theMaxElement
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magneticFieldESToken_
static void fillDescriptions(edm::ParameterSetDescription &desc)
float phi(float curvature, float radius) const
tuple size
Write out results.
tuple useFixedPreFiltering
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)