21 #include <Math/Functions.h> 22 #include <Math/SVector.h> 23 #include <Math/SMatrix.h> 56 LogDebug(
"ME0SegAlgoRU") <<
myName <<
" has algorithm cuts set to: \n" 57 <<
"--------------------------------------------------------------------\n" 73 #ifdef EDM_ML_DEBUG // have lines below only compiled when in debug mode 75 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegmentAlgorithm::run] build segments in chamber " << chId
76 <<
" which contains " << rechits.size() <<
" rechits";
77 for (
unsigned int iH = 0; iH < rechits.size(); ++iH) {
78 auto me0id = rechits[iH].rh->me0Id();
79 auto rhLP = rechits[iH].lp;
80 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[RecHit :: Loc x = " << std::showpos << std::setw(9) << rhLP.x()
81 <<
" Glb y = " << std::showpos << std::setw(9) << rhLP.y()
82 <<
" Time = " << std::showpos << rechits[iH].rh->tof() <<
" -- " << me0id.rawId()
83 <<
" = " << me0id <<
" ]" << std::endl;
87 if (rechits.size() < 3 || rechits.size() > 300) {
88 return std::vector<ME0Segment>();
93 std::vector<unsigned int> recHits_per_layer(6, 0);
94 for (
unsigned int iH = 0; iH < rechits.size(); ++iH) {
95 recHits_per_layer[rechits[iH].layer - 1]++;
114 std::vector<ME0Segment> segments;
120 auto doDisplaced = [&]() {
129 auto printSegments = [&] {
130 #ifdef EDM_ML_DEBUG // have lines below only compiled when in debug mode 131 for (
unsigned int iS = 0; iS < segments.size(); ++iS) {
132 const auto& seg = segments[iS];
134 const auto& rechits = seg.specificRecHits();
135 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU] segment in chamber " << chId <<
" which contains " 136 << rechits.size() <<
" rechits and with specs: \n" 138 for (
auto rh = rechits.begin(); rh != rechits.end(); ++rh) {
139 auto me0id = rh->me0Id();
140 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[RecHit :: Loc x = " << std::showpos << std::setw(9)
141 << rh->localPosition().x() <<
" Loc y = " << std::showpos << std::setw(9)
142 << rh->localPosition().y() <<
" Time = " << std::showpos << rh->tof() <<
" -- " 143 << me0id.rawId() <<
" = " << me0id <<
" ]";
176 const unsigned int n_seg_min,
178 const std::vector<unsigned int>& recHits_per_layer,
180 std::vector<ME0Segment>& segments)
const {
181 auto ib = rechits.begin();
182 auto ie = rechits.end();
183 std::vector<std::pair<float, HitAndPositionPtrContainer> > proto_segments;
185 for (
auto i1 =
ib;
i1 != ie; ++
i1) {
186 const auto& h1 = *
i1;
191 if (recHits_per_layer[h1.layer - 1] > 100)
196 for (
auto i2 = ie - 1;
i2 !=
i1; --
i2) {
198 const auto& h2 = *
i2;
203 if (recHits_per_layer[h2.layer - 1] > 100)
207 if ((
std::abs(
int(h2.layer) -
int(h1.layer)) + 1) <
int(n_seg_min))
210 if (std::fabs(h1.rh->tof() - h2.rh->tof()) >
params.maxTOFDiff + 1.0)
218 std::unique_ptr<MuonSegFit> current_fit;
219 current_fit =
addHit(current_proto_segment, h1);
220 current_fit =
addHit(current_proto_segment, h2);
227 current_proto_segment,
232 if (current_proto_segment.size() > n_seg_min)
235 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU::lookForSegments] # of hits in segment " 236 << current_proto_segment.size() <<
" min # " << n_seg_min <<
" => " 237 << (current_proto_segment.size() >= n_seg_min) <<
" chi2/ndof " 238 << current_fit->chi2() / current_fit->ndof() <<
" => " 239 << (current_fit->chi2() / current_fit->ndof() <
params.maxChi2GoodSeg)
242 if (current_proto_segment.size() < n_seg_min)
244 const float current_metric = current_fit->chi2() / current_fit->ndof();
245 if (current_metric >
params.maxChi2GoodSeg)
248 if (
params.requireCentralBX) {
251 for (
const auto* rh : current_proto_segment) {
252 if (std::fabs(rh->rh->tof()) < 2)
257 if (nNonCentral >= nCentral)
262 proto_segments.emplace_back(current_metric, current_proto_segment);
269 std::vector<ME0Segment>& segments,
272 proto_segments.end(),
273 [](
const std::pair<float, HitAndPositionPtrContainer>&
a,
274 const std::pair<float, HitAndPositionPtrContainer>&
b) {
return a.first <
b.first; });
277 std::vector<unsigned int> usedHits;
278 for (
unsigned int iS = 0; iS < proto_segments.size(); ++iS) {
282 bool alreadyFilled =
false;
283 for (
unsigned int iH = 0; iH < currentProtoSegment.size(); ++iH) {
284 for (
unsigned int iOH = 0; iOH < usedHits.size(); ++iOH) {
285 if (usedHits[iOH] != currentProtoSegment[iH]->
idx)
287 alreadyFilled =
true;
293 for (
const auto*
h : currentProtoSegment) {
294 usedHits.push_back(
h->idx);
298 std::unique_ptr<MuonSegFit> current_fit =
makeFit(currentProtoSegment);
303 float averageTime = 0.;
304 for (
const auto*
h : currentProtoSegment) {
305 averageTime +=
h->rh->tof();
307 averageTime /=
float(currentProtoSegment.size());
308 float timeUncrt = 0.;
309 for (
const auto*
h : currentProtoSegment) {
310 timeUncrt += (
h->rh->tof() - averageTime) * (
h->rh->tof() - averageTime);
312 timeUncrt =
std::sqrt(timeUncrt /
float(currentProtoSegment.size() - 1));
315 currentProtoSegment.end(),
318 std::vector<const ME0RecHit*> bareRHs;
319 bareRHs.reserve(currentProtoSegment.size());
320 for (
const auto* rh : currentProtoSegment)
321 bareRHs.push_back(rh->rh);
324 current_fit->intercept(),
325 current_fit->localdir(),
326 current_fit->covarianceMatrix(),
331 segments.push_back(
temp);
339 std::unique_ptr<MuonSegFit>& current_fit,
342 HitAndPositionContainer::const_iterator
i1,
343 HitAndPositionContainer::const_iterator
i2)
const {
356 for (
auto iH =
i1 + 1; iH !=
i2; ++iH) {
357 if (iH->layer ==
i1->layer)
359 if (iH->layer ==
i2->layer)
375 const bool beamConst,
379 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU::areHitsCloseInEta] gp1 = " << h1 <<
" in eta part = " << h1.
eta()
380 <<
" and gp2 = " << h2 <<
" in eta part = " << h2.
eta() <<
" ==> dEta = " <<
diff 381 <<
" ==> return " << (
diff < 0.1) << std::endl;
387 const unsigned int nLayDisp,
391 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU::areHitsCloseInGlobalPhi] gp1 = " << h1 <<
" and gp2 = " << h2
392 <<
" ==> dPhi = " << dphi12 <<
" ==> return " 393 << (fabs(dphi12) <
std::max(maxPHI, 0.02
f)) << std::endl;
394 return fabs(dphi12) <
std::max(maxPHI,
float(
float(nLayDisp) * 0.004));
399 const std::unique_ptr<MuonSegFit>&
fit,
403 const float avgETA = (proto_segment[1]->gp.eta() + proto_segment[0]->gp.eta()) / 2.;
419 std::vector<float> tofs;
420 tofs.reserve(proto_segment.size() + 1);
421 tofs.push_back(
h.rh->tof());
422 for (
const auto* ih : proto_segment)
423 tofs.push_back(ih->rh->tof());
425 if (std::fabs(tofs.front() - tofs.back()) < maxTOF + 1.0)
431 float x =
fit->xfit(
z);
432 float y =
fit->yfit(
z);
438 proto_segment.push_back(&aHit);
447 for (
auto rh = proto_segment.begin(); rh < proto_segment.end(); rh++) {
451 muonRecHits.push_back(trkRecHit);
453 std::unique_ptr<MuonSegFit> currentFit(
new MuonSegFit(muonRecHits));
460 std::unique_ptr<MuonSegFit>&
fit,
461 const unsigned int n_seg_min)
const {
462 while (proto_segment.size() > n_seg_min &&
fit->chi2() /
fit->ndof() >
maxChi2) {
464 HitAndPositionPtrContainer::iterator worstHit;
465 for (
auto it = proto_segment.begin();
it != proto_segment.end(); ++
it) {
472 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU::pruneBadHits] pruning one hit-> layer: " << (*worstHit)->layer
473 <<
" eta: " << (*worstHit)->gp.eta() <<
" phi: " << (*worstHit)->gp.phi()
474 <<
" old chi2/dof: " <<
fit->chi2() /
fit->ndof() << std::endl;
475 proto_segment.erase(worstHit);
481 const auto lp =
hit.localPosition();
482 const auto le =
hit.localPositionError();
483 const float du =
fit->xdev(lp.x(), lp.z());
484 const float dv =
fit->ydev(lp.y(), lp.z());
486 ROOT::Math::SMatrix<double, 2, 2, ROOT::Math::MatRepSym<double, 2> > IC;
493 return du * du * IC(0, 0) + 2. * du * dv * IC(0, 1) + dv * dv * IC(1, 1);
497 for (
const auto*
h : proto_segment)
509 for (
auto it = new_proto_segment.begin();
it != new_proto_segment.end();) {
510 if ((*it)->layer == new_hit.
layer) {
512 it = new_proto_segment.erase(
it);
517 if (old_hit ==
nullptr)
519 auto new_fit =
addHit(new_proto_segment, new_hit);
523 if (old_hit->
lp == new_hit.
lp) {
525 for (
const auto*
h : current_proto_segment)
527 avgtof +=
h->rh->tof();
528 avgtof /=
float(current_proto_segment.size() - 1);
532 else if (new_fit->chi2() < current_fit->chi2())
536 current_proto_segment = new_proto_segment;
542 std::unique_ptr<MuonSegFit>& current_fit,
546 auto new_fit =
addHit(new_proto_segment, new_hit);
548 if (new_fit->chi2() / new_fit->ndof() <
maxChi2) {
549 current_proto_segment = new_proto_segment;
std::shared_ptr< TrackingRecHit > MuonRecHitPtr
Log< level::Info, true > LogVerbatim
T getParameter(std::string const &) const
Point3DBase< Scalar, LocalTag > LocalPoint
void setPosition(LocalPoint pos)
Set local position.
void pruneBadHits(const float maxChi2, HitAndPositionPtrContainer &proto_segment, std::unique_ptr< MuonSegFit > &fit, const unsigned int n_seg_min) const
bool hasHitOnLayer(const HitAndPositionPtrContainer &proto_segment, const unsigned int layer) const
Geom::Phi< T > phi() const
void addUniqueSegments(SegmentByMetricContainer &proto_segments, std::vector< ME0Segment > &segments, BoolContainer &used) const
std::unique_ptr< MuonSegFit > makeFit(const HitAndPositionPtrContainer &proto_segment) const
float computeDeltaPhi(const LocalPoint &position, const LocalVector &direction) const
SegmentParameters displacedParameters
std::vector< HitAndPosition > HitAndPositionContainer
void increaseProtoSegment(const float maxChi2, std::unique_ptr< MuonSegFit > ¤t_fit, HitAndPositionPtrContainer ¤t_proto_segment, const HitAndPosition &new_hit) const
std::vector< const HitAndPosition * > HitAndPositionPtrContainer
bool areHitsCloseInEta(const float maxETA, const bool beamConst, const GlobalPoint &h1, const GlobalPoint &h2) const
ME0SegAlgoRU(const edm::ParameterSet &ps)
Constructor.
std::vector< bool > BoolContainer
bool isHitNearSegment(const float maxETA, const float maxPHI, const std::unique_ptr< MuonSegFit > &fit, const HitAndPositionPtrContainer &proto_segment, const HitAndPosition &h) const
std::vector< MuonRecHitPtr > MuonRecHitContainer
Abs< T >::type abs(const T &t)
float getHitSegChi2(const std::unique_ptr< MuonSegFit > &fit, const ME0RecHit &hit) const
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
SegmentParameters stdParameters
GlobalPoint globalAtZ(const std::unique_ptr< MuonSegFit > &fit, float z) const
bool areHitsCloseInGlobalPhi(const float maxPHI, const unsigned int nLayDisp, const GlobalPoint &h1, const GlobalPoint &h2) const
ME0RecHit * clone() const override
bool areHitsConsistentInTime(const float maxTOF, const HitAndPositionPtrContainer &proto_segment, const HitAndPosition &h) const
std::vector< std::pair< float, HitAndPositionPtrContainer > > SegmentByMetricContainer
const ME0Chamber * theChamber
void tryAddingHitsToSegment(const float maxTOF, const float maxETA, const float maxPhi, const float maxChi2, std::unique_ptr< MuonSegFit > ¤t_fit, HitAndPositionPtrContainer &proto_segment, const BoolContainer &used, HitAndPositionContainer::const_iterator i1, HitAndPositionContainer::const_iterator i2) const
std::vector< ME0Segment > run(const ME0Chamber *chamber, const HitAndPositionContainer &rechits) override
void compareProtoSegment(std::unique_ptr< MuonSegFit > ¤t_fit, HitAndPositionPtrContainer ¤t_proto_segment, const HitAndPosition &new_hit) const
std::unique_ptr< MuonSegFit > addHit(HitAndPositionPtrContainer &proto_segment, const HitAndPosition &aHit) const
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
SegmentParameters wideParameters
void lookForSegments(const SegmentParameters ¶ms, const unsigned int n_seg_min, const HitAndPositionContainer &rechits, const std::vector< unsigned int > &recHits_per_layer, BoolContainer &used, std::vector< ME0Segment > &segments) const
unsigned int minNumberOfHits