45 struct LayerRZPredictions {
51 : thePairGenerator(0),
53 useFixedPreFiltering(cfg.getParameter<bool>(
"useFixedPreFiltering")),
54 extraHitRZtolerance(cfg.getParameter<double>(
"extraHitRZtolerance")),
55 extraHitRPhitolerance(cfg.getParameter<double>(
"extraHitRPhitolerance")),
56 extraZKDBox(cfg.getParameter<double>(
"extraZKDBox")),
57 extraRKDBox(cfg.getParameter<double>(
"extraRKDBox")),
59 fnSigmaRZ(cfg.getParameter<double>(
"fnSigmaRZ")),
60 chi2VsPtCut(cfg.getParameter<bool>(
"chi2VsPtCut")),
61 maxChi2(cfg.getParameter<double>(
"maxChi2")),
62 refitHits(cfg.getParameter<bool>(
"refitHits")),
63 debug(cfg.getParameter<bool>(
"debug")),
64 filterName_(cfg.getParameter<std::
string>(
"ClusterShapeHitFilterName")),
65 builderName_(cfg.existsAs<std::
string>(
"TTRHBuilder") ? cfg.getParameter<std::
string>(
"TTRHBuilder") : std::
string(
"WithTrackAngle")),
88 if (cfg.
exists(
"SimpleMagneticField")) {
119 builder = (TkTransientTrackingRecHitBuilder
const *)(builderH.
product());
120 cloner = (*builder).cloner();
124 std::vector<SeedingLayerSetsHits::SeedingLayer> thirdLayers) {
133 if (range.first > second.max() || range.second < second.min())
135 if (range.first < second.min())
136 range.first = second.min();
137 if (range.second > second.max())
138 range.second = second.max();
139 return range.first < range.second;
157 pairs.reserve(30000);
158 thePairGenerator->hitPairs(region,pairs,ev,es);
170 std::vector<KDTreeNodeInfo<RecHitsSortedInPhi::HitIter> > layerTree;
171 std::vector<RecHitsSortedInPhi::HitIter> foundNodes;
172 foundNodes.reserve(100);
177 map<std::string, LayerRZPredictions> mapPred;
181 for(
int il = 0; il <
size; il++) {
182 thirdHitMap[il] = &(*theLayerCache)(
theLayers[il], region, ev, es);
183 if (
debug)
cout <<
"considering third layer: " << theLayers[il].name() <<
" with hits: " << thirdHitMap[il]->
all().second-thirdHitMap[il]->
all().first << endl;
184 const DetLayer *layer = theLayers[il].detLayer();
185 LayerRZPredictions &predRZ = mapPred[theLayers[il].name()];
186 predRZ.line.initLayer(layer);
192 double minz=999999.0, maxz= -999999.0;
195 if (hitRange.first != hitRange.second)
196 { minz = barrelLayer? hitRange.first->hit()->globalPosition().z() : hitRange.first->hit()->globalPosition().perp();
199 {
double angle = hi->phi();
200 double myz = barrelLayer? hi->hit()->globalPosition().z() : hi->hit()->globalPosition().perp();
202 if (
debug && hi->hit()->rawId()==debug_Id2) {
203 cout <<
"filling KDTree with hit in id=" << debug_Id2
204 <<
" with pos: " << hi->hit()->globalPosition()
205 <<
" phi=" << hi->hit()->globalPosition().phi()
206 <<
" z=" << hi->hit()->globalPosition().z()
207 <<
" 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;
234 for (OrderedHitPairs::const_iterator ip = pairs.begin(); ip != pairs.end(); ++ip) {
236 int foundTripletsFromPair = 0;
237 bool usePair =
false;
249 bool debugPair =
debug && ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1;
253 <<
"found new pair with ids "<<debug_Id0<<
" "<<debug_Id1<<
" with pos: " << gp0 <<
" " << gp1
265 bool passFilterHit0 =
true;
272 const std::type_info &tid =
typeid(*hit0->hit());
273 if (tid ==
typeid(SiStripMatchedRecHit2D)) {
274 const SiStripMatchedRecHit2D* matchedHit =
dynamic_cast<const SiStripMatchedRecHit2D *
>(hit0->hit());
277 }
else if (tid ==
typeid(SiStripRecHit2D)) {
278 const SiStripRecHit2D* recHit =
dynamic_cast<const SiStripRecHit2D *
>(hit0->hit());
280 }
else if (tid ==
typeid(ProjectedSiStripRecHit2D)) {
281 const ProjectedSiStripRecHit2D* precHit =
dynamic_cast<const ProjectedSiStripRecHit2D *
>(hit0->hit());
285 if (debugPair&&!passFilterHit0)
cout <<
"hit0 did not pass cluster shape filter" << endl;
286 if (!passFilterHit0)
continue;
287 bool passFilterHit1 =
true;
294 const std::type_info &tid =
typeid(*hit1->hit());
295 if (tid ==
typeid(SiStripMatchedRecHit2D)) {
296 const SiStripMatchedRecHit2D* matchedHit =
dynamic_cast<const SiStripMatchedRecHit2D *
>(hit1->hit());
299 }
else if (tid ==
typeid(SiStripRecHit2D)) {
300 const SiStripRecHit2D* recHit =
dynamic_cast<const SiStripRecHit2D *
>(hit1->hit());
302 }
else if (tid ==
typeid(ProjectedSiStripRecHit2D)) {
303 const ProjectedSiStripRecHit2D* precHit =
dynamic_cast<const ProjectedSiStripRecHit2D *
>(hit1->hit());
307 if (debugPair&&!passFilterHit1)
cout <<
"hit1 did not pass cluster shape filter" << endl;
308 if (!passFilterHit1)
continue;
323 if (!intersect(pairCurvature,
Range(-curv, curv))) {
324 if (debugPair)
std::cout <<
"curvature cut: curv=" << curv
325 <<
" gc=(" << pairCurvature.first <<
", " << pairCurvature.second <<
")" << std::endl;
330 for(
int il = 0; (il <
size) & (!usePair); il++) {
333 cout <<
"cosider layer: " <<
theLayers[il].name() <<
" for this pair. Location: " <<
theLayers[il].detLayer()->location() << endl;
335 if (hitTree[il].
empty()) {
337 cout <<
"empty hitTree" << endl;
348 LayerRZPredictions &predRZ = mapPred.find(
theLayers[il].
name())->second;
349 predRZ.line.initPropagator(&line);
353 Range rzRange = predRZ.line();
355 if (rzRange.first >= rzRange.second) {
357 cout <<
"rzRange empty" << endl;
363 if (!intersect(rzRange, predRZ.line.detSize())) {
365 cout <<
"rzRange and detector do not intersect" << endl;
369 Range radius = barrelLayer ? predRZ.line.detRange() : rzRange;
376 float phi0 = ip->outer()->globalPosition().phi();
380 if (pairCurvature.first<0. && pairCurvature.second<0.) {
381 float phi12 = predictionRPhi.
phi(pairCurvature.first,radius.second);
382 float phi21 = predictionRPhi.
phi(pairCurvature.second,radius.first);
383 while(
unlikely(phi12 < phi21)) phi12 += float(2. *
M_PI);
384 phiRange =
Range(phi21,phi12);
385 }
else if (pairCurvature.first>=0. && pairCurvature.second>=0.) {
386 float phi11 = predictionRPhi.
phi(pairCurvature.first,radius.first);
387 float phi22 = predictionRPhi.
phi(pairCurvature.second,radius.second);
388 while(
unlikely(phi11 < phi22)) phi11 += float(2. *
M_PI);
389 phiRange =
Range(phi22,phi11);
391 float phi12 = predictionRPhi.
phi(pairCurvature.first,radius.second);
392 float phi22 = predictionRPhi.
phi(pairCurvature.second,radius.second);
393 while(
unlikely(phi12 < phi22)) phi12 += float(2. *
M_PI);
394 phiRange =
Range(phi22,phi12);
402 float prmin=phiRange.min(), prmax=phiRange.max();
410 if (debugPair)
cout <<
"defining kd tree box" << endl;
416 hitTree[il].
search(phiZ, foundNodes);
419 <<
" z: "<< rzRange.min()-
fnSigmaRZ*rzError[il]-extraZKDBox <<
","<<rzRange.max()+
fnSigmaRZ*rzError[il]+extraZKDBox
420 <<
" rzRange: " << rzRange.min() <<
","<<rzRange.max()
427 hitTree[il].
search(phiR, foundNodes);
430 <<
" r: "<< rzRange.min()-
fnSigmaRZ*rzError[il]-extraRKDBox <<
","<<rzRange.max()+
fnSigmaRZ*rzError[il]+extraRKDBox
431 <<
" rzRange: " << rzRange.min() <<
","<<rzRange.max()
435 if (debugPair)
cout <<
"kd tree box size: " << foundNodes.size() << endl;
439 for (std::vector<RecHitsSortedInPhi::HitIter>::iterator ih = foundNodes.begin();
440 ih !=foundNodes.end() && !usePair; ++ih) {
442 if (debugPair)
std::cout << endl <<
"triplet candidate" << std::endl;
452 GlobalVector initMomentum(oriHit2->globalPosition() - gp1);
453 initMomentum *= (1./initMomentum.perp());
459 bool passFilterHit2 =
true;
465 const std::type_info &tid =
typeid(*hit2->hit());
466 if (tid ==
typeid(SiStripMatchedRecHit2D)) {
467 const SiStripMatchedRecHit2D* matchedHit =
dynamic_cast<const SiStripMatchedRecHit2D *
>(hit2->hit());
469 filter->
isCompatible(
DetId(matchedHit->stereoId()), matchedHit->stereoCluster(), initMomentum)==0) passFilterHit2 =
false;
470 }
else if (tid ==
typeid(SiStripRecHit2D)) {
471 const SiStripRecHit2D* recHit =
dynamic_cast<const SiStripRecHit2D *
>(hit2->hit());
473 }
else if (tid ==
typeid(ProjectedSiStripRecHit2D)) {
474 const ProjectedSiStripRecHit2D* precHit =
dynamic_cast<const ProjectedSiStripRecHit2D *
>(hit2->hit());
475 if (
filter->
isCompatible(precHit->originalHit(), initMomentum)==0) passFilterHit2 =
false;
478 if (debugPair&&!passFilterHit2)
cout <<
"hit2 did not pass cluster shape filter" << endl;
479 if (!passFilterHit2)
continue;
509 vector<GlobalPoint> gp(3);
510 vector<GlobalError> ge(3);
512 gp[0] = hit0->globalPosition();
513 ge[0] = hit0->globalPositionError();
514 int subid0 = hit0->geographicalId().subdetId();
516 gp[1] = hit1->globalPosition();
517 ge[1] = hit1->globalPositionError();
518 int subid1 = hit1->geographicalId().subdetId();
520 gp[2] = hit2->globalPosition();
521 ge[2] = hit2->globalPositionError();
522 int subid2 = hit2->geographicalId().subdetId();
525 float cottheta, intercept, covss, covii, covsi;
526 rzLine.
fit(cottheta, intercept, covss, covii, covsi);
527 float chi2 = rzLine.
chi2(cottheta, intercept);
529 bool debugTriplet = debugPair && hit2->rawId()==debug_Id2;
531 std::cout << endl <<
"triplet candidate in debug id" << std::endl;
532 cout <<
"hit in id="<<hit2->rawId()<<
" (from KDTree) with pos: " << KDdata->hit()->globalPosition()
533 <<
" refitted: " << hit2->globalPosition()
543 FastCircle theCircle(hit2->globalPosition(),hit1->globalPosition(),hit0->globalPosition());
545 float rho = theCircle.rho();
546 float cm2GeV = 0.01 * 0.3*tesla0;
547 float pt = cm2GeV *
rho;
549 std::cout <<
"triplet pT=" << pt << std::endl;
551 if (pt<region.
ptMin())
continue;
579 edm::LogError(
"TooManyTriplets")<<
" number of triples exceed maximum. no triplets produced.";
582 if (debugPair)
std::cout <<
"triplet made" << std::endl;
592 bestL2 = std::move(hit2);
593 chi2FromThisLayer = chi2;
594 foundTripletsFromPair++;
595 if (foundTripletsFromPair>=2) {
606 if (chi2FromThisLayer<minChi2) {
607 bestH2 = std::move(bestL2);
608 minChi2 = chi2FromThisLayer;
620 if (foundTripletsFromPair==0)
continue;
623 if (debugPair)
std::cout <<
"Done seed #" << result.
size() << std::endl;
624 if (usePair) result.push_back(
SeedingHitSet(ip->inner(), ip->outer()));
626 assert(1==foundTripletsFromPair);
628 result.emplace_back(&*hit0,&*hit1,&*bestH2);
630 cache.emplace_back(const_cast<BaseTrackerRecHit*>(hit0.
release()));
631 cache.emplace_back(const_cast<BaseTrackerRecHit*>(hit1.
release()));
632 cache.emplace_back(std::move(bestH2));
633 assert(hit0.
empty()); assert(hit1.
empty());assert(!bestH2);
645 {
while (phi > phi2) phi -= 2. *
M_PI;
646 while (phi < phi1) phi += 2. *
M_PI;
650 std::pair<float, float>
652 const std::pair<float, float> &
r2)
const
653 {
float r2Min = r2.first;
654 float r2Max = r2.second;
655 while (r1.first - r2Min > +
M_PI) r2Min += 2. *
M_PI, r2Max += 2. *
M_PI;
656 while (r1.first - r2Min < -
M_PI) r2Min -= 2. *
M_PI, r2Max -= 2. *
M_PI;
658 return std::make_pair(
min(r1.first, r2Min),
max(r1.second, r2Max));
673 cout <<
"positions before refitting: " << hit1->globalPosition() <<
" " << hit2->globalPosition() <<endl;
679 float rho = theCircle.
rho();
680 float cm2GeV = 0.01 * 0.3*tesla0;
681 float pt = cm2GeV *
rho;
687 p0 = p0*pt/p0.
perp();
689 p1 = p1*pt/p1.perp();
691 p2 = p2*pt/p2.perp();
694 if ( (p0.x()*(gp1.
x()-gp0.x())+p0.y()*(gp1.
y()-gp0.y()) ) < 0 ) {
707 if ((gp1-cc).
x()*p1.y() - (gp1-cc).
y()*p1.x() > 0) q =-q;
718 cout <<
"charge=" << q << endl;
721 cout <<
"positions after refitting: " << hit1->globalPosition() <<
" " << hit2->globalPosition() <<endl;
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
virtual HitPairGenerator * clone() const =0
void build(std::vector< KDTreeNodeInfo > &eltList, const KDTreeBox ®ion)
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
const ClusterShapeHitFilter * filter
Geom::Phi< T > phi() const
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
Geom::Theta< T > theta() const
LocalVector localMomentum() const
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
BaseTrackerRecHit const * ConstRecHitPointer
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
void initES(const edm::EventSetup &es) override
Tan< T >::type tan(const T &t)
MultiHitGeneratorFromChi2(const edm::ParameterSet &cfg)
unsigned int theMaxElement
std::vector< double > pt_interv
SeedingHitSet::ConstRecHitPointer Hit
BaseTrackerRecHit const * Hit
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
bool isCompatible(const SiPixelRecHit &recHit, const LocalVector &ldir, const SiPixelClusterShapeCache &clusterShapeCache, PixelData const *pd=nullptr) const
GlobalVector globalMomentum() const
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
std::unique_ptr< BaseTrackerRecHit > cacheHitPointer
list pairs
sort tag files by run number
float phi(float curvature, float radius) 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)
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)