52 #define IfLogTrace(cond, cat) if(cond) LogTrace(cat)
54 #define IfLogTrace(cond, cat) LogTrace(cat)
62 struct LayerRZPredictions {
69 useFixedPreFiltering(cfg.getParameter<bool>(
"useFixedPreFiltering")),
70 extraHitRZtolerance(cfg.getParameter<double>(
"extraHitRZtolerance")),
71 extraHitRPhitolerance(cfg.getParameter<double>(
"extraHitRPhitolerance")),
72 extraZKDBox(cfg.getParameter<double>(
"extraZKDBox")),
73 extraRKDBox(cfg.getParameter<double>(
"extraRKDBox")),
75 fnSigmaRZ(cfg.getParameter<double>(
"fnSigmaRZ")),
76 chi2VsPtCut(cfg.getParameter<bool>(
"chi2VsPtCut")),
77 maxChi2(cfg.getParameter<double>(
"maxChi2")),
78 refitHits(cfg.getParameter<bool>(
"refitHits")),
79 filterName_(cfg.getParameter<std::
string>(
"ClusterShapeHitFilterName")),
80 builderName_(cfg.existsAs<std::
string>(
"TTRHBuilder") ? cfg.getParameter<std::
string>(
"TTRHBuilder") : std::
string(
"WithTrackAngle")),
102 if (cfg.
exists(
"SimpleMagneticField")) {
128 cloner = (*builder).cloner();
136 if (range.first > second.max() || range.second < second.min())
138 if (range.first < second.min())
139 range.first = second.min();
140 if (range.second > second.max())
141 range.second = second.max();
142 return range.first < range.second;
151 std::vector<SeedingLayerSetsHits::SeedingLayer> thirdLayers)
157 LogDebug(
"MultiHitGeneratorFromChi2") <<
"pair: " <<
thePairGenerator->innerLayer(pairLayers).name() <<
"+" <<
thePairGenerator->outerLayer(pairLayers).name() <<
" 3rd lay size: " << thirdLayers.size();
161 pairs.reserve(30000);
163 LogTrace(
"MultiHitGeneratorFromChi2") <<
"";
170 int size = thirdLayers.size();
174 std::vector<KDTreeNodeInfo<RecHitsSortedInPhi::HitIter> > layerTree;
175 std::vector<RecHitsSortedInPhi::HitIter> foundNodes;
176 foundNodes.reserve(100);
180 const float maxDelphi = region.
ptMin() < 0.3f ? float(
M_PI)/4.f : float(
M_PI)/8.f;
181 const float maxphi =
M_PI+maxDelphi, minphi = -maxphi;
182 const float safePhi =
M_PI-maxDelphi;
184 std::map<std::string, LayerRZPredictions> mapPred;
188 for(
int il = 0; il <
size; il++) {
189 thirdHitMap[il] = &(*theLayerCache)(thirdLayers[il],
region,
ev, es);
190 LogTrace(
"MultiHitGeneratorFromChi2") <<
"considering third layer: " << thirdLayers[il].name() <<
" with hits: " << thirdHitMap[il]->
all().second-thirdHitMap[il]->
all().first;
191 const DetLayer *layer = thirdLayers[il].detLayer();
192 LayerRZPredictions &predRZ = mapPred[thirdLayers[il].name()];
193 predRZ.line.initLayer(layer);
199 float minz=999999.0f, maxz= -minz;
202 if (hitRange.first != hitRange.second)
203 { minz = barrelLayer? hitRange.first->hit()->globalPosition().z() : hitRange.first->hit()->globalPosition().perp();
206 {
auto angle = hi->phi();
207 auto myz = barrelLayer? hi->hit()->globalPosition().z() : hi->hit()->globalPosition().perp();
209 IfLogTrace(hi->hit()->rawId()==debug_Id2,
"MultiHitGeneratorFromChi2") <<
"filling KDTree with hit in id=" << debug_Id2
210 <<
" with pos: " << hi->hit()->globalPosition()
211 <<
" phi=" << hi->hit()->globalPosition().phi()
212 <<
" z=" << hi->hit()->globalPosition().z()
213 <<
" r=" << hi->hit()->globalPosition().perp();
215 if (myz < minz) { minz = myz;}
else {
if (myz > maxz) {maxz = myz;}}
216 auto myerr = barrelLayer? hi->hit()->errorGlobalZ(): hi->hit()->errorGlobalR();
217 if (myerr > maxErr) { maxErr = myerr;}
224 KDTreeBox phiZ(minphi, maxphi, minz-0.01
f, maxz+0.01
f);
226 hitTree[il].build(layerTree, phiZ);
227 rzError[il] = maxErr;
234 LogTrace(
"MultiHitGeneratorFromChi2") <<
"pair size=" << pairs.
size() << std::endl;
237 for (OrderedHitPairs::const_iterator ip = pairs.begin(); ip != pairs.end(); ++ip) {
239 int foundTripletsFromPair = 0;
240 bool usePair =
false;
253 bool debugPair = ip->inner()->rawId()==debug_Id0 && ip->outer()->rawId()==debug_Id1;
255 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") << endl << endl
256 <<
"found new pair with ids "<<debug_Id0<<
" "<<debug_Id1<<
" with pos: " << gp0 <<
" " << gp1;
270 bool passFilterHit0 =
true;
277 const std::type_info &tid =
typeid(*hit0->hit());
290 IfLogTrace(debugPair&&!passFilterHit0,
"MultiHitGeneratorFromChi2") <<
"hit0 did not pass cluster shape filter";
291 if (!passFilterHit0)
continue;
292 bool passFilterHit1 =
true;
299 const std::type_info &tid =
typeid(*hit1->hit());
312 IfLogTrace(debugPair&&!passFilterHit1,
"MultiHitGeneratorFromChi2") <<
"hit1 did not pass cluster shape filter";
313 if (!passFilterHit1)
continue;
325 auto toPos = std::signbit(gp1.z()-gp0.
z());
331 if (!intersect(pairCurvature,
Range(-curv, curv))) {
332 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"curvature cut: curv=" << curv
333 <<
" gc=(" << pairCurvature.first <<
", " << pairCurvature.second <<
")";
338 for(
int il = 0; (il <
size) & (!usePair); il++) {
340 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"cosider layer: " << thirdLayers[il].name() <<
" for this pair. Location: " << thirdLayers[il].detLayer()->location();
342 if (hitTree[il].
empty()) {
343 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"empty hitTree";
350 const DetLayer *layer = thirdLayers[il].detLayer();
353 if ( (!barrelLayer) & (toPos != std::signbit(layer->
position().
z())) )
continue;
356 LayerRZPredictions &predRZ = mapPred.find(thirdLayers[il].
name())->second;
357 predRZ.line.initPropagator(&line);
361 Range rzRange = predRZ.line();
363 if (rzRange.first >= rzRange.second) {
364 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"rzRange empty";
369 if (!intersect(rzRange, predRZ.line.detSize())) {
370 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"rzRange and detector do not intersect";
373 Range radius = barrelLayer ? predRZ.line.detRange() : rzRange;
380 float phi0 = ip->outer()->globalPosition().phi();
384 if (pairCurvature.first<0. && pairCurvature.second<0.) {
386 }
else if (pairCurvature.first>=0. && pairCurvature.second>=0.) {;}
388 radius.first=radius.second;
390 auto phi12 = predictionRPhi.
phi(pairCurvature.first,radius.first);
391 auto phi22 = predictionRPhi.
phi(pairCurvature.second,radius.second);
393 phi22 =
proxim(phi22,phi12);
394 phiRange =
Range(phi12,phi22); phiRange.sort();
397 float prmin=phiRange.min(), prmax=phiRange.max();
399 if (prmax-prmin>maxDelphi) {
400 auto prm = phiRange.mean();
401 prmin = prm - 0.5f*maxDelphi;
402 prmax = prm + 0.5f*maxDelphi;
412 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"defining kd tree box";
418 hitTree[il].search(phiZ, foundNodes);
421 <<
" z: "<< rzRange.min()-
fnSigmaRZ*rzError[il]-extraZKDBox <<
","<<rzRange.max()+
fnSigmaRZ*rzError[il]+extraZKDBox
422 <<
" rzRange: " << rzRange.min() <<
","<<rzRange.max();
428 hitTree[il].search(phiR, foundNodes);
431 <<
" r: "<< rzRange.min()-
fnSigmaRZ*rzError[il]-extraRKDBox <<
","<<rzRange.max()+
fnSigmaRZ*rzError[il]+extraRKDBox
432 <<
" rzRange: " << rzRange.min() <<
","<<rzRange.max();
435 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"kd tree box size: " << foundNodes.size();
439 for (std::vector<RecHitsSortedInPhi::HitIter>::iterator ih = foundNodes.begin();
440 ih !=foundNodes.end() && !usePair; ++ih) {
442 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") << endl <<
"triplet candidate";
452 GlobalVector initMomentum(oriHit2->globalPosition() - gp1);
453 initMomentum *= (1./initMomentum.perp());
459 bool passFilterHit2 =
true;
465 const std::type_info &tid =
typeid(*hit2->hit());
478 IfLogTrace(debugPair&&!passFilterHit2,
"MultiHitGeneratorFromChi2") <<
"hit2 did not pass cluster shape filter";
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);
530 bool debugTriplet = debugPair && hit2->rawId()==debug_Id2;
532 IfLogTrace(debugTriplet,
"MultiHitGeneratorFromChi2") << endl <<
"triplet candidate in debug id" << std::endl
533 <<
"hit in id="<<hit2->rawId()<<
" (from KDTree) with pos: " << KDdata->hit()->globalPosition()
534 <<
" refitted: " << hit2->globalPosition()
535 <<
" chi2: " <<
chi2;
541 FastCircle theCircle(hit2->globalPosition(),hit1->globalPosition(),hit0->globalPosition());
543 float rho = theCircle.rho();
544 float cm2GeV = 0.01 * 0.3*tesla0;
545 float pt = cm2GeV *
rho;
546 IfLogTrace(debugTriplet,
"MultiHitGeneratorFromChi2") <<
"triplet pT=" <<
pt;
547 if (pt<region.
ptMin())
continue;
575 edm::LogError(
"TooManyTriplets")<<
" number of triples exceed maximum. no triplets produced.";
578 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"triplet made";
589 chi2FromThisLayer =
chi2;
590 foundTripletsFromPair++;
591 if (foundTripletsFromPair>=2) {
593 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"using pair";
601 if (chi2FromThisLayer<minChi2) {
603 minChi2 = chi2FromThisLayer;
615 if (foundTripletsFromPair==0)
continue;
618 IfLogTrace(debugPair,
"MultiHitGeneratorFromChi2") <<
"Done seed #" << result.
size();
619 if (usePair) result.push_back(
SeedingHitSet(ip->inner(), ip->outer()));
621 assert(1==foundTripletsFromPair);
623 result.emplace_back(&*hit0,&*hit1,&*bestH2);
625 cache.emplace_back(const_cast<BaseTrackerRecHit*>(hit0.
release()));
626 cache.emplace_back(const_cast<BaseTrackerRecHit*>(hit1.
release()));
634 LogTrace(
"MultiHitGeneratorFromChi2") <<
"triplet size=" << result.
size();
648 IfLogTrace(isDebug,
"MultiHitGeneratorFromChi2") <<
"positions before refitting: " << hit1->globalPosition() <<
" " << hit2->globalPosition();
653 float rho = theCircle.
rho();
654 float cm2GeV = 0.01f * 0.3f*tesla0;
655 float pt = cm2GeV *
rho;
661 p0 = p0*pt/p0.
perp();
663 p1 = p1*pt/p1.perp();
665 p2 = p2*pt/p2.perp();
668 if ( (p0.x()*(gp1.
x()-gp0.x())+p0.y()*(gp1.
y()-gp0.y()) ) < 0 ) {
675 auto zv = vec20.
z()/vec20.
perp();
682 if ((gp1-cc).x()*p1.
y() - (gp1-cc).
y()*p1.
x() > 0) q =-q;
692 IfLogTrace(isDebug,
"MultiHitGeneratorFromChi2") <<
"charge=" << q << std::endl
695 <<
"positions after refitting: " << hit1->globalPosition() <<
" " << hit2->globalPosition();
float originRBound() const
bounds the particle vertex in the transverse plane
T getParameter(std::string const &) const
unsigned int stereoId() const
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.
PixelRecoRange< float > Range
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
Range curvature(double transverseIP) 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
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
BaseTrackerRecHit const * Hit
SiStripRecHit2D originalHit() const
float extraHitRZtolerance
virtual const Surface::PositionType & position() const
Returns position of the surface.
T const * product() const
float ptMin() const
minimal pt of interest
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
#define declareDynArray(T, n, x)
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
tuple size
Write out results.
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)