43 struct LayerRZPredictions {
56 ,
fnSigmaRZ (cfg.getParameter<double>(
"fnSigmaRZ") )
57 ,
chi2VsPtCut (cfg.getParameter<bool> (
"chi2VsPtCut") )
58 ,
maxChi2 (cfg.getParameter<double>(
"maxChi2") )
59 ,
refitHits (cfg.getParameter<bool> (
"refitHits") )
60 ,
debug (cfg.getParameter<bool> (
"debug") )
61 , filterName_ (cfg.getParameter<std::
string>(
"ClusterShapeHitFilterName"))
62 , useSimpleMF_ (
false)
84 if (cfg.
exists(
"SimpleMagneticField")) {
100 std::vector<SeedingLayerSetsHits::SeedingLayer> thirdLayers) {
109 if (range.first > second.max() || range.second < second.min())
111 if (range.first < second.min())
112 range.first = second.min();
113 if (range.second > second.max())
114 range.second = second.max();
115 return range.first < range.second;
150 pairs.reserve(30000);
151 thePairGenerator->hitPairs(region,pairs,ev,es);
165 std::vector<KDTreeNodeInfo<RecHitsSortedInPhi::HitIter> > layerTree;
166 std::vector<RecHitsSortedInPhi::HitIter> foundNodes;
167 foundNodes.reserve(100);
173 map<std::string, LayerRZPredictions> mapPred;
177 for(
int il = 0; il <
size; il++) {
178 thirdHitMap[il] = &(*theLayerCache)(
theLayers[il], region, ev, es);
179 if (
debug)
cout <<
"considering third layer: " << theLayers[il].name() <<
" with hits: " << thirdHitMap[il]->
all().second-thirdHitMap[il]->
all().first << endl;
180 const DetLayer *layer = theLayers[il].detLayer();
181 LayerRZPredictions &predRZ = mapPred[theLayers[il].name()];
182 predRZ.line.initLayer(layer);
188 double minz=999999.0, maxz= -999999.0;
191 if (hitRange.first != hitRange.second)
192 { minz = barrelLayer? hitRange.first->hit()->globalPosition().z() : hitRange.first->hit()->globalPosition().perp();
195 {
double angle = hi->phi();
196 double myz = barrelLayer? hi->hit()->globalPosition().z() : hi->hit()->globalPosition().perp();
198 if (
debug && hi->hit()->rawId()==debug_Id2)
cout <<
"filling KDTree with hit in id=" << debug_Id2
199 <<
" with pos: " << hi->hit()->globalPosition()
200 <<
" phi=" << hi->hit()->globalPosition().phi()
201 <<
" z=" << hi->hit()->globalPosition().z()
202 <<
" r=" << hi->hit()->globalPosition().perp()
203 <<
" trans: " << hi->hit()->transientHits()[0]->globalPosition() <<
" "
204 << (hi->hit()->transientHits().size()>1 ? hi->hit()->transientHits()[1]->globalPosition() :
GlobalPoint(0,0,0))
208 if (myz < minz) { minz = myz;}
else {
if (myz > maxz) {maxz = myz;}}
209 float myerr = barrelLayer? hi->hit()->errorGlobalZ(): hi->hit()->errorGlobalR();
210 if (myerr > maxErr) { maxErr = myerr;}
218 KDTreeBox phiZ(minphi, maxphi, minz-0.01, maxz+0.01);
220 hitTree[il].
build(layerTree, phiZ);
221 rzError[il] = maxErr;
231 for (OrderedHitPairs::const_iterator ip = pairs.begin(); ip != pairs.end(); ++ip) {
233 int foundTripletsFromPair = 0;
234 bool usePair =
false;
246 pairMomentum *= (1./pairMomentum.
perp());
251 hit0 = hit0->clone(statePair0);
252 hit1 = hit1->clone(statePair1);
257 const std::type_info &tid =
typeid(*hit0->hit());
258 if (tid ==
typeid(SiStripMatchedRecHit2D)) {
259 const SiStripMatchedRecHit2D* matchedHit =
dynamic_cast<const SiStripMatchedRecHit2D *
>(hit0->hit());
262 }
else if (tid ==
typeid(SiStripRecHit2D)) {
263 const SiStripRecHit2D* recHit =
dynamic_cast<const SiStripRecHit2D *
>(hit0->hit());
274 const std::type_info &tid =
typeid(*hit1->hit());
275 if (tid ==
typeid(SiStripMatchedRecHit2D)) {
276 const SiStripMatchedRecHit2D* matchedHit =
dynamic_cast<const SiStripMatchedRecHit2D *
>(hit1->hit());
279 }
else if (tid ==
typeid(SiStripRecHit2D)) {
280 const SiStripRecHit2D* recHit =
dynamic_cast<const SiStripRecHit2D *
>(hit1->hit());
293 if (
debug && ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1) {
294 cout <<
"found new pair with ids "<<debug_Id0<<
" "<<debug_Id1<<
" with pos: " << gp0 <<
" " << gp1
295 <<
" trans0: " << ip->inner()->transientHits()[0]->globalPosition() <<
" " << ip->inner()->transientHits()[1]->globalPosition()
296 <<
" trans1: " << ip->outer()->transientHits()[0]->globalPosition() <<
" " << ip->outer()->transientHits()[1]->globalPosition()
306 if (!intersect(generalCurvature,
Range(-curv, curv))) {
307 if (
debug && ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1)
std::cout <<
"curvature cut: curv=" << curv <<
" gc=(" << generalCurvature.first <<
", " << generalCurvature.second <<
")" << std::endl;
312 for(
int il = 0; il < size && !usePair; il++) {
314 if (
debug && ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1)
315 cout <<
"cosider layer: " <<
theLayers[il].
name() <<
" for this pair. Location: " <<
theLayers[il].detLayer()->location() << endl;
317 if (hitTree[il].
empty()) {
318 if (
debug && ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1) {
319 cout <<
"empty hitTree" << endl;
334 LayerRZPredictions &predRZ = mapPred.find(
theLayers[il].
name())->second;
335 predRZ.line.initPropagator(&line);
339 Range rzRange = predRZ.line();
341 if (rzRange.first >= rzRange.second) {
342 if (
debug && ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1) {
343 cout <<
"rzRange empty" << endl;
353 float phi0 = ip->outer()->globalPosition().phi();
360 radius = predRZ.line.detRange();
361 if (!intersect(rzRange, predRZ.line.detSize())) {
362 if (
debug && ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1) {
363 cout <<
"rzRange and detector do not intersect" << endl;
369 if (!intersect(radius, predRZ.line.detSize())) {
370 if (
debug && ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1) {
371 cout <<
"rzRange and detector do not intersect" << endl;
379 Range rPhi1 = predictionRPhi(curvature, radius.first);
380 Range rPhi2 = predictionRPhi(curvature, radius.second);
381 rPhi1.first /= radius.first;
382 rPhi1.second /= radius.first;
383 rPhi2.first /= radius.second;
384 rPhi2.second /= radius.second;
398 float prmin=phiRange.min(), prmax=phiRange.max();
407 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1)
cout <<
"defining kd tree box" << endl;
409 Range detR = predRZ.line.detRange();
411 Range regMin = predRZ.line(detR.min());
412 Range regMax = predRZ.line(detR.max());
413 if (regMax.min() < regMin.min()) {
swap(regMax, regMin);}
418 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1)
cout <<
"kd tree box bounds, phi: " << prmin <<
","<< prmax
419 <<
" z: "<< regMin.min()-
fnSigmaRZ*rzError[il] <<
","<<regMax.max()+
fnSigmaRZ*rzError[il]
420 <<
" detR: " << detR.min() <<
","<<detR.max()
421 <<
" regMin: " << regMin.min() <<
","<<regMin.max()
422 <<
" regMax: " << regMax.min() <<
","<<regMax.max()
424 hitTree[il].
search(phiZ, foundNodes);
430 hitTree[il].
search(phiR, foundNodes);
432 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1)
cout <<
"kd tree box bounds, phi: " << prmin <<
","<< prmax
433 <<
" r: "<< rzRange.min()-
fnSigmaRZ*rzError[il] <<
","<<rzRange.max()+
fnSigmaRZ*rzError[il]
434 <<
" rzRange: " << rzRange.min() <<
","<<rzRange.max()
439 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1)
cout <<
"kd tree box size: " << foundNodes.size() << endl;
443 for (std::vector<RecHitsSortedInPhi::HitIter>::iterator ih = foundNodes.begin();
444 ih !=foundNodes.end() && !usePair; ++ih) {
448 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1)
std::cout <<
"triplet candidate" << std::endl;
454 GlobalVector initMomentum(hit2->globalPosition() - gp1);
455 initMomentum *= (1./initMomentum.perp());
459 const std::type_info &tid =
typeid(*hit2->hit());
460 if (tid ==
typeid(SiStripMatchedRecHit2D)) {
461 const SiStripMatchedRecHit2D* matchedHit =
dynamic_cast<const SiStripMatchedRecHit2D *
>(hit2->hit());
462 if (filterHandle_->isCompatible(
DetId(matchedHit->monoId()), matchedHit->monoCluster(), initMomentum)==0 ||
463 filterHandle_->isCompatible(
DetId(matchedHit->stereoId()), matchedHit->stereoCluster(), initMomentum)==0)
continue;
464 }
else if (tid ==
typeid(SiStripRecHit2D)) {
465 const SiStripRecHit2D* recHit =
dynamic_cast<const SiStripRecHit2D *
>(hit2->hit());
466 if (filterHandle_->isCompatible(*recHit, initMomentum)==0)
continue;
469 if (filterHandle_->isCompatible(precHit->
originalHit(), initMomentum)==0)
continue;;
474 hit2 = hit2->clone(state);
479 vector<GlobalPoint> gp(3);
480 vector<GlobalError> ge(3);
482 gp[0] = hit0->globalPosition();
483 ge[0] = hit0->globalPositionError();
484 int subid0 = hit0->geographicalId().subdetId();
486 gp[1] = hit1->globalPosition();
487 ge[1] = hit1->globalPositionError();
488 int subid1 = hit1->geographicalId().subdetId();
490 gp[2] = hit2->globalPosition();
491 ge[2] = hit2->globalPositionError();
492 int subid2 = hit2->geographicalId().subdetId();
495 float cottheta, intercept, covss, covii, covsi;
496 rzLine.
fit(cottheta, intercept, covss, covii, covsi);
497 float chi2 = rzLine.
chi2(cottheta, intercept);
499 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1) {
500 if (hit2->rawId()==debug_Id2) {
501 std::cout << endl <<
"triplet candidate" << std::endl;
502 cout <<
"hit in id="<<debug_Id2<<
" (from KDTree) with pos: " << KDdata->hit()->globalPosition()
503 <<
" refitted: " << hit2->globalPosition()
504 <<
" trans2: " << hit2->transientHits()[0]->globalPosition() <<
" " << (hit2->transientHits().size()>1 ? hit2->transientHits()[1]->globalPosition() :
GlobalPoint(0,0,0))
510 vector<float>
r(3),
z(3),errR(3);
511 r[0] = ip->inner()->globalPosition().perp();
512 z[0] = ip->inner()->globalPosition().z();
513 errR[0] =
sqrt(ip->inner()->globalPositionError().cxx()+ip->inner()->globalPositionError().cyy());
514 r[1] = ip->outer()->globalPosition().perp();
515 z[1] = ip->outer()->globalPosition().z();
516 errR[1] =
sqrt(ip->outer()->globalPositionError().cxx()+ip->outer()->globalPositionError().cyy());
517 r[2] = KDdata->hit()->globalPosition().perp();
518 z[2] = KDdata->hit()->globalPosition().z();
519 errR[2] =
sqrt(KDdata->hit()->globalPositionError().cxx()+KDdata->hit()->globalPositionError().cxx());
521 float cottheta_old, intercept_old, covss_old, covii_old, covsi_old;
522 oldLine.fit(cottheta_old, intercept_old, covss_old, covii_old, covsi_old);
523 float chi2_old = oldLine.chi2(cottheta_old, intercept_old);
524 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1 && hit2->rawId()==debug_Id2) {
525 cout <<
"triplet with ids: " << hit0->geographicalId().rawId() <<
" " << hit1->geographicalId().rawId() <<
" " << hit2->geographicalId().rawId()
526 <<
" hitpos: " << gp[0] <<
" " << gp[1] <<
" " << gp[2]
527 <<
" eta,phi: " << gp[0].eta() <<
"," << gp[0].phi() <<
" chi2: " << chi2 <<
" chi2_old: " << chi2_old << endl
528 <<
"trans0: " << hit0->transientHits()[0]->globalPosition() <<
" " << hit0->transientHits()[1]->globalPosition() << endl
529 <<
"trans1: " << hit1->transientHits()[0]->globalPosition() <<
" " << hit1->transientHits()[1]->globalPosition() << endl
530 <<
"trans2: " << hit2->transientHits()[0]->globalPosition() <<
" " << (hit2->transientHits().size()>1 ? hit2->transientHits()[1]->globalPosition() :
GlobalPoint(0,0,0))
547 FastCircle theCircle(hit2->globalPosition(),hit1->globalPosition(),hit0->globalPosition());
549 float rho = theCircle.rho();
550 float cm2GeV = 0.01 * 0.3*tesla0;
551 float pt = cm2GeV *
rho;
552 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1 && hit2->rawId()==debug_Id2) {
553 std::cout <<
"triplet pT=" << pt << std::endl;
555 if (pt<region.
ptMin())
continue;
561 for (
int icut=1; icut<ncuts-1; icut++){
567 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1 && hit2->rawId()==debug_Id2) {
568 std::cout <<
"triplet passed chi2 vs pt cut" << std::endl;
576 edm::LogError(
"TooManyTriplets")<<
" number of triples exceed maximum. no triplets produced.";
579 if (
debug && hit0->rawId()==debug_Id0 && hit1->rawId()==debug_Id1 && hit2->rawId()==debug_Id2)
std::cout <<
"triplet made" << std::endl;
582 chi2FromThisLayer = chi2;
583 foundTripletsFromPair++;
584 if (foundTripletsFromPair>=2) {
593 if (chi2FromThisLayer<minChi2) {
594 triplet = tripletFromThisLayer;
595 minChi2 = chi2FromThisLayer;
601 if (foundTripletsFromPair==0)
continue;
604 if (usePair) result.push_back(
SeedingHitSet(ip->inner(), ip->outer()));
605 else result.push_back(triplet);
614 {
while (phi > phi2) phi -= 2. *
M_PI;
615 while (phi < phi1) phi += 2. *
M_PI;
619 std::pair<float, float>
621 const std::pair<float, float> &
r2)
const
622 {
float r2Min = r2.first;
623 float r2Max = r2.second;
624 while (r1.first - r2Min > +
M_PI) r2Min += 2. *
M_PI, r2Max += 2. *
M_PI;
625 while (r1.first - r2Min < -
M_PI) r2Min -= 2. *
M_PI, r2Max -= 2. *
M_PI;
627 return std::make_pair(
min(r1.first, r2Min),
max(r1.second, r2Max));
float originRBound() const
bounds the particle vertex in the transverse plane
void swap(ora::Record &rh, ora::Record &lh)
T getParameter(std::string const &) const
std::pair< float, float > mergePhiRanges(const std::pair< float, float > &r1, const std::pair< float, float > &r2) const
tuple extraHitRPhitolerance
virtual HitPairGenerator * clone() const =0
void build(std::vector< KDTreeNodeInfo > &eltList, const KDTreeBox ®ion)
tuple useFixedPreFiltering
virtual Location location() const =0
Which part of the detector (barrel, endcap)
ThirdHitPredictionFromCircle::HelixRZ HelixRZ
int nominalValue() const
The nominal field value for this map in kGauss.
std::vector< int > detIdsToDebug
const ClusterShapeHitFilter * filter
Global3DPoint GlobalPoint
bool exists(std::string const ¶meterName) const
checks if a parameter exists
virtual unsigned int size() const
void search(const KDTreeBox &searchBox, std::vector< KDTreeNodeInfo > &resRecHitList)
Range curvature(double transverseIP) const
std::vector< SeedingLayerSetsHits::SeedingLayer > theLayers
U second(std::pair< T, U > const &p)
virtual unsigned int size() const
void init(const HitPairGenerator &pairs, LayerCacheType *layerCache) override
std::pair< HitIter, HitIter > Range
tuple extraHitRZtolerance
T curvature(T InversePt, const edm::EventSetup &iSetup)
bool useFixedPreFiltering
const T & max(const T &a, const T &b)
std::vector< HitWithPhi >::const_iterator HitIter
LayerCacheType * theLayerCache
void setSeedingLayers(SeedingLayerSetsHits::SeedingLayerSet pairLayers, std::vector< SeedingLayerSetsHits::SeedingLayer > thirdLayers) override
const MagneticField * bfield
MultiHitGeneratorFromChi2(const edm::ParameterSet &cfg)
unsigned int theMaxElement
bool isCompatible(const SiPixelRecHit &recHit, const LocalVector &ldir, PixelData const *pd=nullptr) const
std::vector< double > pt_interv
PixelRecoRange< float > Range
float extraHitRZtolerance
HitPairGenerator * thePairGenerator
T const * product() const
float ptMin() const
minimal pt of interest
float extraHitRPhitolerance
std::vector< double > chi2_cuts
TransientTrackingRecHit::ConstRecHitPointer Hit
void fit(float &cotTheta, float &intercept, float &covss, float &covii, float &covsi) const
float chi2(float cotTheta, float intercept) const
volatile std::atomic< bool > shutdown_flag false
const SiStripRecHit2D & originalHit() const
tuple size
Write out results.
virtual void setSeedingLayers(SeedingLayerSetsHits::SeedingLayerSet layers)=0
bool checkPhiInRange(float phi, float phi1, float phi2) const
virtual void hitSets(const TrackingRegion ®ion, OrderedMultiHits &trs, const edm::Event &ev, const edm::EventSetup &es)
T angle(T x1, T y1, T z1, T x2, T y2, T z2)