47 #define IfLogTrace(cond, cat) if(cond) LogTrace(cat)
49 #define IfLogTrace(cond, cat) LogTrace(cat)
57 struct LayerRZPredictions {
64 useFixedPreFiltering(cfg.getParameter<bool>(
"useFixedPreFiltering")),
65 extraHitRZtolerance(cfg.getParameter<double>(
"extraHitRZtolerance")),
66 extraHitRPhitolerance(cfg.getParameter<double>(
"extraHitRPhitolerance")),
67 extraZKDBox(cfg.getParameter<double>(
"extraZKDBox")),
68 extraRKDBox(cfg.getParameter<double>(
"extraRKDBox")),
70 fnSigmaRZ(cfg.getParameter<double>(
"fnSigmaRZ")),
71 chi2VsPtCut(cfg.getParameter<bool>(
"chi2VsPtCut")),
72 maxChi2(cfg.getParameter<double>(
"maxChi2")),
73 refitHits(cfg.getParameter<bool>(
"refitHits")),
74 filterName_(cfg.getParameter<std::
string>(
"ClusterShapeHitFilterName")),
75 builderName_(cfg.existsAs<std::
string>(
"TTRHBuilder") ? cfg.getParameter<std::
string>(
"TTRHBuilder") : std::
string(
"WithTrackAngle")),
97 if (cfg.
exists(
"SimpleMagneticField")) {
123 cloner = (*builder).cloner();
131 if (range.first > second.max() || range.second < second.min())
133 if (range.first < second.min())
134 range.first = second.min();
135 if (range.second > second.max())
136 range.second = second.max();
137 return range.first < range.second;
146 std::vector<SeedingLayerSetsHits::SeedingLayer> thirdLayers)
152 LogDebug(
"MultiHitGeneratorFromChi2") <<
"pair: " <<
thePairGenerator->innerLayer(pairLayers).name() <<
"+" <<
thePairGenerator->outerLayer(pairLayers).name() <<
" 3rd lay size: " << thirdLayers.size();
156 pairs.reserve(30000);
158 LogTrace(
"MultiHitGeneratorFromChi2") <<
"";
165 int size = thirdLayers.size();
169 std::vector<KDTreeNodeInfo<RecHitsSortedInPhi::HitIter> > layerTree;
170 std::vector<RecHitsSortedInPhi::HitIter> foundNodes;
171 foundNodes.reserve(100);
173 std::vector<KDTreeLinkerAlgo<RecHitsSortedInPhi::HitIter>> hitTree(size);
180 map<std::string, LayerRZPredictions> mapPred;
184 for(
int il = 0; il <
size; il++) {
185 thirdHitMap[il] = &(*theLayerCache)(thirdLayers[il],
region,
ev, es);
186 LogTrace(
"MultiHitGeneratorFromChi2") <<
"considering third layer: " << thirdLayers[il].name() <<
" with hits: " << thirdHitMap[il]->
all().second-thirdHitMap[il]->
all().first;
187 const DetLayer *layer = thirdLayers[il].detLayer();
188 LayerRZPredictions &predRZ = mapPred[thirdLayers[il].name()];
189 predRZ.line.initLayer(layer);
195 double minz=999999.0, maxz= -999999.0;
198 if (hitRange.first != hitRange.second)
199 { minz = barrelLayer? hitRange.first->hit()->globalPosition().z() : hitRange.first->hit()->globalPosition().perp();
202 {
double angle = hi->phi();
203 double myz = barrelLayer? hi->hit()->globalPosition().z() : hi->hit()->globalPosition().perp();
205 IfLogTrace(hi->hit()->rawId()==debug_Id2,
"MultiHitGeneratorFromChi2") <<
"filling KDTree with hit in id=" << debug_Id2
206 <<
" with pos: " << hi->hit()->globalPosition()
207 <<
" phi=" << hi->hit()->globalPosition().phi()
208 <<
" z=" << hi->hit()->globalPosition().z()
209 <<
" r=" << hi->hit()->globalPosition().perp();
211 if (myz < minz) { minz = myz;}
else {
if (myz > maxz) {maxz = myz;}}
212 float myerr = barrelLayer? hi->hit()->errorGlobalZ(): hi->hit()->errorGlobalR();
213 if (myerr > maxErr) { maxErr = myerr;}
221 KDTreeBox phiZ(minphi, maxphi, minz-0.01, maxz+0.01);
223 hitTree[il].
build(layerTree, phiZ);
224 rzError[il] = maxErr;
231 LogTrace(
"MultiHitGeneratorFromChi2") <<
"pair size=" << pairs.
size() << std::endl;
234 for (OrderedHitPairs::const_iterator ip = pairs.begin(); ip != pairs.end(); ++ip) {
236 int foundTripletsFromPair = 0;
237 bool usePair =
false;
250 bool debugPair = ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1;
252 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") << endl << endl
253 <<
"found new pair with ids "<<debug_Id0<<
" "<<debug_Id1<<
" with pos: " << gp0 <<
" " << gp1;
267 bool passFilterHit0 =
true;
274 const std::type_info &tid =
typeid(*hit0->hit());
287 IfLogTrace(debugPair&&!passFilterHit0,
"MultiHitGeneratorFromChi2") <<
"hit0 did not pass cluster shape filter";
288 if (!passFilterHit0)
continue;
289 bool passFilterHit1 =
true;
296 const std::type_info &tid =
typeid(*hit1->hit());
309 IfLogTrace(debugPair&&!passFilterHit1,
"MultiHitGeneratorFromChi2") <<
"hit1 did not pass cluster shape filter";
310 if (!passFilterHit1)
continue;
325 if (!intersect(pairCurvature,
Range(-curv, curv))) {
326 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"curvature cut: curv=" << curv
327 <<
" gc=(" << pairCurvature.first <<
", " << pairCurvature.second <<
")";
332 for(
int il = 0; (il <
size) & (!usePair); il++) {
334 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"cosider layer: " << thirdLayers[il].name() <<
" for this pair. Location: " << thirdLayers[il].detLayer()->location();
336 if (hitTree[il].
empty()) {
337 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"empty hitTree";
344 const DetLayer *layer = thirdLayers[il].detLayer();
347 LayerRZPredictions &predRZ = mapPred.find(thirdLayers[il].
name())->second;
348 predRZ.line.initPropagator(&line);
352 Range rzRange = predRZ.line();
354 if (rzRange.first >= rzRange.second) {
355 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"rzRange empty";
360 if (!intersect(rzRange, predRZ.line.detSize())) {
361 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"rzRange and detector do not intersect";
364 Range radius = barrelLayer ? predRZ.line.detRange() : rzRange;
371 float phi0 = ip->outer()->globalPosition().phi();
375 if (pairCurvature.first<0. && pairCurvature.second<0.) {
376 float phi12 = predictionRPhi.
phi(pairCurvature.first,radius.second);
377 float phi21 = predictionRPhi.
phi(pairCurvature.second,radius.first);
378 while(
unlikely(phi12 < phi21)) phi12 += float(2. *
M_PI);
379 phiRange =
Range(phi21,phi12);
380 }
else if (pairCurvature.first>=0. && pairCurvature.second>=0.) {
381 float phi11 = predictionRPhi.
phi(pairCurvature.first,radius.first);
382 float phi22 = predictionRPhi.
phi(pairCurvature.second,radius.second);
383 while(
unlikely(phi11 < phi22)) phi11 += float(2. *
M_PI);
384 phiRange =
Range(phi22,phi11);
386 float phi12 = predictionRPhi.
phi(pairCurvature.first,radius.second);
387 float phi22 = predictionRPhi.
phi(pairCurvature.second,radius.second);
388 while(
unlikely(phi12 < phi22)) phi12 += float(2. *
M_PI);
389 phiRange =
Range(phi22,phi12);
397 float prmin=phiRange.min(), prmax=phiRange.max();
405 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"defining kd tree box";
411 hitTree[il].
search(phiZ, foundNodes);
414 <<
" z: "<< rzRange.min()-
fnSigmaRZ*rzError[il]-extraZKDBox <<
","<<rzRange.max()+
fnSigmaRZ*rzError[il]+extraZKDBox
415 <<
" rzRange: " << rzRange.min() <<
","<<rzRange.max();
421 hitTree[il].
search(phiR, foundNodes);
424 <<
" r: "<< rzRange.min()-
fnSigmaRZ*rzError[il]-extraRKDBox <<
","<<rzRange.max()+
fnSigmaRZ*rzError[il]+extraRKDBox
425 <<
" rzRange: " << rzRange.min() <<
","<<rzRange.max();
428 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"kd tree box size: " << foundNodes.size();
432 for (std::vector<RecHitsSortedInPhi::HitIter>::iterator ih = foundNodes.begin();
433 ih !=foundNodes.end() && !usePair; ++ih) {
435 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") << endl <<
"triplet candidate";
445 GlobalVector initMomentum(oriHit2->globalPosition() - gp1);
446 initMomentum *= (1./initMomentum.perp());
452 bool passFilterHit2 =
true;
458 const std::type_info &tid =
typeid(*hit2->hit());
471 IfLogTrace(debugPair&&!passFilterHit2,
"MultiHitGeneratorFromChi2") <<
"hit2 did not pass cluster shape filter";
472 if (!passFilterHit2)
continue;
502 vector<GlobalPoint> gp(3);
503 vector<GlobalError> ge(3);
505 gp[0] = hit0->globalPosition();
506 ge[0] = hit0->globalPositionError();
507 int subid0 = hit0->geographicalId().subdetId();
509 gp[1] = hit1->globalPosition();
510 ge[1] = hit1->globalPositionError();
511 int subid1 = hit1->geographicalId().subdetId();
513 gp[2] = hit2->globalPosition();
514 ge[2] = hit2->globalPositionError();
515 int subid2 = hit2->geographicalId().subdetId();
518 float cottheta, intercept, covss, covii, covsi;
519 rzLine.
fit(cottheta, intercept, covss, covii, covsi);
520 float chi2 = rzLine.
chi2(cottheta, intercept);
523 bool debugTriplet = debugPair && hit2->rawId()==debug_Id2;
525 IfLogTrace(debugTriplet,
"MultiHitGeneratorFromChi2") << endl <<
"triplet candidate in debug id" << std::endl
526 <<
"hit in id="<<hit2->rawId()<<
" (from KDTree) with pos: " << KDdata->hit()->globalPosition()
527 <<
" refitted: " << hit2->globalPosition()
528 <<
" chi2: " << chi2;
534 FastCircle theCircle(hit2->globalPosition(),hit1->globalPosition(),hit0->globalPosition());
536 float rho = theCircle.rho();
537 float cm2GeV = 0.01 * 0.3*tesla0;
538 float pt = cm2GeV *
rho;
539 IfLogTrace(debugTriplet,
"MultiHitGeneratorFromChi2") <<
"triplet pT=" <<
pt;
540 if (pt<region.
ptMin())
continue;
568 edm::LogError(
"TooManyTriplets")<<
" number of triples exceed maximum. no triplets produced.";
571 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"triplet made";
582 chi2FromThisLayer = chi2;
583 foundTripletsFromPair++;
584 if (foundTripletsFromPair>=2) {
586 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"using pair";
594 if (chi2FromThisLayer<minChi2) {
596 minChi2 = chi2FromThisLayer;
608 if (foundTripletsFromPair==0)
continue;
611 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"Done seed #" << result.
size();
612 if (usePair) result.push_back(
SeedingHitSet(ip->inner(), ip->outer()));
614 assert(1==foundTripletsFromPair);
616 result.emplace_back(&*hit0,&*hit1,&*bestH2);
618 cache.emplace_back(const_cast<BaseTrackerRecHit*>(hit0.
release()));
619 cache.emplace_back(const_cast<BaseTrackerRecHit*>(hit1.
release()));
627 LogTrace(
"MultiHitGeneratorFromChi2") <<
"triplet size=" << result.
size();
631 {
while (phi > phi2) phi -= 2. *
M_PI;
632 while (phi < phi1) phi += 2. *
M_PI;
636 std::pair<float, float>
638 const std::pair<float, float> &
r2)
const
639 {
float r2Min = r2.first;
640 float r2Max = r2.second;
641 while (r1.first - r2Min > +
M_PI) r2Min += 2. *
M_PI, r2Max += 2. *
M_PI;
642 while (r1.first - r2Min < -
M_PI) r2Min -= 2. *
M_PI, r2Max -= 2. *
M_PI;
644 return std::make_pair(
min(r1.first, r2Min),
max(r1.second, r2Max));
658 IfLogTrace(isDebug,
"MultiHitGeneratorFromChi2") <<
"positions before refitting: " << hit1->globalPosition() <<
" " << hit2->globalPosition();
663 float rho = theCircle.
rho();
664 float cm2GeV = 0.01 * 0.3*tesla0;
665 float pt = cm2GeV *
rho;
671 p0 = p0*pt/p0.
perp();
673 p1 = p1*pt/p1.perp();
675 p2 = p2*pt/p2.perp();
678 if ( (p0.x()*(gp1.
x()-gp0.x())+p0.y()*(gp1.
y()-gp0.y()) ) < 0 ) {
691 if ((gp1-cc).
x()*p1.y() - (gp1-cc).
y()*p1.x() > 0) q =-q;
701 IfLogTrace(isDebug,
"MultiHitGeneratorFromChi2") <<
"charge=" << q << std::endl
704 <<
"positions after refitting: " << hit1->globalPosition() <<
" " << hit2->globalPosition();
float originRBound() const
bounds the particle vertex in the transverse plane
T getParameter(std::string const &) const
std::pair< float, float > mergePhiRanges(const std::pair< float, float > &r1, const std::pair< float, float > &r2) const
unsigned int stereoId() const
void build(std::vector< KDTreeNodeInfo > &eltList, const KDTreeBox ®ion)
std::unique_ptr< BaseTrackerRecHit > cacheHitPointer
GlobalPoint const & origin() const
virtual Location location() const =0
Which part of the detector (barrel, endcap)
int nominalValue() const
The nominal field value for this map in kGauss.
TkTransientTrackingRecHitBuilder const * builder
std::vector< int > detIdsToDebug
SiStripCluster const & monoCluster() const
const ClusterShapeHitFilter * filter
Geom::Phi< T > phi() const
bool exists(std::string const ¶meterName) const
checks if a parameter exists
#define IfLogTrace(cond, cat)
virtual unsigned int size() const
void search(const KDTreeBox &searchBox, std::vector< KDTreeNodeInfo > &resRecHitList)
Range curvature(double transverseIP) const
Geom::Theta< T > theta() const
LocalVector localMomentum() const
U second(std::pair< T, U > const &p)
virtual unsigned int size() const
std::pair< HitIter, HitIter > Range
BaseTrackerRecHit const * ConstRecHitPointer
virtual void hitSets(const TrackingRegion ®ion, OrderedMultiHits &trs, const edm::Event &ev, const edm::EventSetup &es, SeedingLayerSetsHits::SeedingLayerSet pairLayers, std::vector< SeedingLayerSetsHits::SeedingLayer > thirdLayers)
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
Tan< T >::type tan(const T &t)
MultiHitGeneratorFromChi2(const edm::ParameterSet &cfg)
std::vector< double > pt_interv
bool isCompatible(const SiPixelRecHit &recHit, const LocalVector &ldir, const SiPixelClusterShapeCache &clusterShapeCache, PixelData const *pd=0) const
SeedingHitSet::ConstRecHitPointer Hit
BaseTrackerRecHit const * Hit
SiStripRecHit2D originalHit() const
PixelRecoRange< float > Range
float extraHitRZtolerance
T const * product() const
float ptMin() const
minimal pt of interest
Geom::Phi< T > phi() const
float extraHitRPhitolerance
std::vector< double > chi2_cuts
virtual ~MultiHitGeneratorFromChi2()
SiStripCluster const & stereoCluster() const
GlobalVector globalMomentum() const
std::unique_ptr< HitPairGeneratorFromLayerPair > thePairGenerator
void fit(float &cotTheta, float &intercept, float &covss, float &covii, float &covsi) const
float chi2(float cotTheta, float intercept) const
unsigned int monoId() const
volatile std::atomic< bool > shutdown_flag false
const unsigned int theMaxElement
float phi(float curvature, float radius) const
static const float fnSigmaRZ
tuple size
Write out results.
bool checkPhiInRange(float phi, float phi1, float phi2) 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)