21 #include <Math/Functions.h> 22 #include <Math/SVector.h> 23 #include <Math/SMatrix.h> 62 LogDebug(
"ME0SegAlgoRU") <<
myName <<
" has algorithm cuts set to: \n" 63 <<
"--------------------------------------------------------------------\n" 65 <<
"doCollisions = " <<doCollisions <<
"\n" 81 #ifdef EDM_ML_DEBUG // have lines below only compiled when in debug mode 83 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegmentAlgorithm::run] build segments in chamber " << chId <<
" which contains "<<rechits.size()<<
" rechits";
84 for(
unsigned int iH = 0; iH < rechits.size(); ++iH){
85 auto me0id = rechits[iH].rh->me0Id();
86 auto rhLP = rechits[iH].lp;
87 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[RecHit :: Loc x = "<<std::showpos<<std::setw(9)<<rhLP.x()<<
" Glb y = "<<std::showpos<<std::setw(9)<<rhLP.y()<<
" Time = "<<std::showpos<<rechits[iH].rh->tof()<<
" -- "<<me0id.rawId()<<
" = "<<me0id<<
" ]"<<std::endl;
92 if (rechits.size() < 3 || rechits.size()>300){
93 return std::vector<ME0Segment>();
98 std::vector<unsigned int> recHits_per_layer(6,0);
99 for(
unsigned int iH = 0; iH < rechits.size(); ++iH) {
100 recHits_per_layer[rechits[iH].layer-1]++;
119 std::vector<ME0Segment> segments;
121 auto doStd = [&] () {
125 auto doDisplaced = [&] () {
134 auto printSegments = [&] {
135 #ifdef EDM_ML_DEBUG // have lines below only compiled when in debug mode 136 for(
unsigned int iS = 0; iS < segments.size(); ++iS) {
137 const auto& seg = segments[iS];
139 const auto& rechits = seg.specificRecHits();
140 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU] segment in chamber " << chId <<
" which contains "<<rechits.size()<<
" rechits and with specs: \n"<<seg;
141 for (
auto rh=rechits.begin(); rh!=rechits.end(); ++rh){
142 auto me0id = rh->me0Id();
143 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[RecHit :: Loc x = "<<std::showpos<<std::setw(9)<<rh->localPosition().x()<<
" Loc y = "<<std::showpos<<std::setw(9)<<rh->localPosition().y()<<
" Time = "<<std::showpos<<rh->tof()<<
" -- "<<me0id.rawId()<<
" = "<<me0id<<
" ]";
178 BoolContainer& used, std::vector<ME0Segment>& segments)
const {
179 auto ib = rechits.begin();
180 auto ie = rechits.end();
181 std::vector<std::pair<float,HitAndPositionPtrContainer> > proto_segments;
183 for (
auto i1 =
ib; i1 != ie; ++i1) {
184 const auto& h1 = *i1;
187 if(used[h1.idx])
continue;
188 if(recHits_per_layer[h1.layer-1]>100)
continue;
192 for (
auto i2 = ie-1; i2 != i1; --i2) {
194 const auto& h2 = *i2;
197 if(used[h2.idx])
continue;
198 if(recHits_per_layer[h2.layer-1]>100)
continue;
201 if((
std::abs(
int(h2.layer) -
int(h1.layer)) + 1) <
int(n_seg_min))
break;
203 if(std::fabs(h1.rh->tof()-h2.rh->tof()) > params.
maxTOFDiff + 1.0 )
continue;
208 std::unique_ptr<MuonSegFit> current_fit;
209 current_fit =
addHit(current_proto_segment,h1);
210 current_fit =
addHit(current_proto_segment,h2);
214 if(current_proto_segment.size() > n_seg_min)
217 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU::lookForSegments] # of hits in segment " << current_proto_segment.size() <<
" min # "<< n_seg_min <<
" => "<< (current_proto_segment.size() >= n_seg_min) <<
" chi2/ndof "<<current_fit->chi2()/current_fit->ndof()<<
" => "<<(current_fit->chi2()/current_fit->ndof() < params.
maxChi2GoodSeg ) <<std::endl;
219 if(current_proto_segment.size() < n_seg_min)
continue;
220 const float current_metric = current_fit->chi2()/current_fit->ndof();
226 for(
const auto* rh : current_proto_segment ) {
227 if(std::fabs(rh->rh->tof()) < 2 ) nCentral++;
230 if(nNonCentral >= nCentral)
continue;
234 proto_segments.emplace_back( current_metric, current_proto_segment);
243 std::sort(proto_segments.begin(),proto_segments.end(),
244 [](
const std::pair<float,HitAndPositionPtrContainer> &
a,
245 const std::pair<float,HitAndPositionPtrContainer> &
b) {
return a.first <
b.first;});
248 std::vector<unsigned int> usedHits;
249 for(
unsigned int iS = 0; iS < proto_segments.size(); ++iS){
253 bool alreadyFilled=
false;
254 for(
unsigned int iH = 0; iH < currentProtoSegment.size(); ++iH){
255 for(
unsigned int iOH = 0; iOH < usedHits.size(); ++iOH){
256 if(usedHits[iOH]!=currentProtoSegment[iH]->
idx)
continue;
257 alreadyFilled =
true;
261 if(alreadyFilled)
continue;
262 for(
const auto*
h : currentProtoSegment){
263 usedHits.push_back(
h->idx);
267 std::unique_ptr<MuonSegFit> current_fit =
makeFit(currentProtoSegment);
272 float averageTime=0.;
273 for(
const auto*
h : currentProtoSegment){
274 averageTime +=
h->rh->tof();
276 averageTime /=
float(currentProtoSegment.size());
278 for(
const auto*
h : currentProtoSegment){
279 timeUncrt += (
h->rh->tof()-averageTime)*(
h->rh->tof()-averageTime);
281 timeUncrt =
std::sqrt(timeUncrt/
float(currentProtoSegment.size()-1));
283 std::sort(currentProtoSegment.begin(),currentProtoSegment.end(),
287 std::vector<const ME0RecHit*> bareRHs; bareRHs.reserve(currentProtoSegment.size());
288 for(
const auto* rh : currentProtoSegment) bareRHs.push_back(rh->rh);
291 current_fit->localdir(), current_fit->covarianceMatrix(), current_fit->chi2(), averageTime, timeUncrt,
dPhi);
292 segments.push_back(
temp);
299 const BoolContainer& used, HitAndPositionContainer::const_iterator i1, HitAndPositionContainer::const_iterator i2)
const {
312 for(
auto iH = i1 + 1; iH != i2; ++iH ){
313 if(iH->layer == i1->layer)
continue;
314 if(iH->layer == i2->layer)
break;
315 if(used[iH->idx])
continue;
317 if (!
isHitNearSegment(maxETA,maxPhi,current_fit,proto_segment,*iH))
continue;
327 diff = std::fabs(h1.
eta() - h1.
eta());
328 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU::areHitsCloseInEta] gp1 = "<<h1<<
" in eta part = "<<h1.
eta() <<
" and gp2 = "<<h2<<
" in eta part = "<<h2.
eta() <<
" ==> dEta = "<<diff<<
" ==> return "<<(diff < 0.1)<<std::endl;
329 return (diff <
std::max(maxETA,
float(0.01)) );
334 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU::areHitsCloseInGlobalPhi] gp1 = "<<h1<<
" and gp2 = "<<h2<<
" ==> dPhi = "<<dphi12<<
" ==> return "<<(fabs(dphi12) <
std::max(maxPHI,
float(0.02)))<<std::endl;
335 return fabs(dphi12) <
std::max(maxPHI,
float(
float(nLayDisp)*0.004));
340 const float avgETA = (proto_segment[1]->gp.eta() + proto_segment[0]->gp.eta())/2.;
342 if(std::fabs(h.
gp.
eta() - avgETA) >
std::max(maxETA,
float(0.01) ))
return false;
349 return (std::fabs(dPhi) <
std::max(maxPHI,
float(0.001)));
353 std::vector<float> tofs; tofs.reserve(proto_segment.size() + 1);
354 tofs.push_back(h.
rh->
tof());
355 for(
const auto* ih : proto_segment) tofs.push_back(ih->rh->tof());
356 std::sort(tofs.begin(),tofs.end());
357 if(std::fabs(tofs.front() - tofs.back()) < maxTOF +1.0 )
return true;
362 float x = fit->xfit(z);
363 float y = fit->yfit(z);
368 proto_segment.push_back(&aHit);
377 for (
auto rh=proto_segment.begin();rh<proto_segment.end(); rh++){
381 muonRecHits.push_back(trkRecHit);
383 std::unique_ptr<MuonSegFit> currentFit(
new MuonSegFit(muonRecHits));
389 while(proto_segment.size() > n_seg_min && fit->chi2()/fit->ndof() >
maxChi2){
391 HitAndPositionPtrContainer::iterator worstHit;
392 for(
auto it = proto_segment.begin(); it != proto_segment.end(); ++it){
394 if(dev < maxDev)
continue;
398 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU::pruneBadHits] pruning one hit-> layer: "<< (*worstHit)->layer <<
" eta: "<< (*worstHit)->gp.eta() <<
" phi: "<<(*worstHit)->gp.phi()<<
" old chi2/dof: "<<fit->chi2()/fit->ndof() << std::endl;
399 proto_segment.erase( worstHit);
407 const float du = fit->xdev(lp.x(),lp.z());
408 const float dv = fit->ydev(lp.y(),lp.z());
410 ROOT::Math::SMatrix<double,2,2,ROOT::Math::MatRepSym<double,2> > IC;
417 return du*du*IC(0,0) + 2.*du*dv*IC(0,1) + dv*dv*IC(1,1);
421 for(
const auto*
h : proto_segment)
if(
h->layer == layer)
return true;
429 HitAndPositionPtrContainer::const_iterator it;
430 for (
auto it = new_proto_segment.begin(); it != new_proto_segment.end();) {
431 if ((*it)->layer == new_hit.
layer) {
433 it = new_proto_segment.erase(it);
438 if(old_hit ==
nullptr)
return;
439 auto new_fit =
addHit(new_proto_segment,new_hit);
443 if(old_hit->
lp == new_hit.
lp ){
445 for(
const auto*
h : current_proto_segment)
446 if(old_hit !=
h) avgtof +=
h->rh->tof();
447 avgtof /=
float(current_proto_segment.size() - 1);
452 else if(new_fit->chi2() < current_fit->chi2()) useNew =
true;
455 current_proto_segment = new_proto_segment;
463 auto new_fit =
addHit(new_proto_segment,new_hit);
465 if(new_fit->chi2()/new_fit->ndof() <
maxChi2 ){
466 current_proto_segment = new_proto_segment;
std::shared_ptr< TrackingRecHit > MuonRecHitPtr
LocalError localPositionError() const override
Return the 3-dimensional error on the local position.
T getParameter(std::string const &) const
Point3DBase< Scalar, LocalTag > LocalPoint
void setPosition(LocalPoint pos)
Set local position.
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Geom::Phi< T > phi() const
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
bool areHitsCloseInGlobalPhi(const float maxPHI, const unsigned int nLayDisp, const GlobalPoint &h1, const GlobalPoint &h2) const
std::vector< std::pair< float, HitAndPositionPtrContainer > > SegmentByMetricContainer
SegmentParameters displacedParameters
void increaseProtoSegment(const float maxChi2, std::unique_ptr< MuonSegFit > ¤t_fit, HitAndPositionPtrContainer ¤t_proto_segment, const HitAndPosition &new_hit) const
std::unique_ptr< MuonSegFit > makeFit(const HitAndPositionPtrContainer &proto_segment) const
ME0DetId id() const
Return the ME0DetId of this chamber.
std::vector< HitAndPosition > HitAndPositionContainer
std::vector< const HitAndPosition * > HitAndPositionPtrContainer
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
void addUniqueSegments(SegmentByMetricContainer &proto_segments, std::vector< ME0Segment > &segments, BoolContainer &used) const
GlobalPoint globalAtZ(const std::unique_ptr< MuonSegFit > &fit, float z) const
LocalPoint localPosition() const override
Return the 3-dimensional local position.
ME0SegAlgoRU(const edm::ParameterSet &ps)
Constructor.
float computeDeltaPhi(const LocalPoint &position, const LocalVector &direction) const
std::vector< bool > BoolContainer
void pruneBadHits(const float maxChi2, HitAndPositionPtrContainer &proto_segment, std::unique_ptr< MuonSegFit > &fit, const unsigned int n_seg_min) const
std::vector< MuonRecHitPtr > MuonRecHitContainer
Abs< T >::type abs(const T &t)
bool areHitsConsistentInTime(const float maxTOF, const HitAndPositionPtrContainer &proto_segment, const HitAndPosition &h) const
void compareProtoSegment(std::unique_ptr< MuonSegFit > ¤t_fit, HitAndPositionPtrContainer ¤t_proto_segment, const HitAndPosition &new_hit) const
float getHitSegChi2(const std::unique_ptr< MuonSegFit > &fit, const ME0RecHit &hit) const
SegmentParameters stdParameters
bool isHitNearSegment(const float maxETA, const float maxPHI, const std::unique_ptr< MuonSegFit > &fit, const HitAndPositionPtrContainer &proto_segment, const HitAndPosition &h) const
bool hasHitOnLayer(const HitAndPositionPtrContainer &proto_segment, const unsigned int layer) const
ME0RecHit * clone() const override
const ME0Chamber * theChamber
std::vector< ME0Segment > run(const ME0Chamber *chamber, const HitAndPositionContainer &rechits) override
bool areHitsCloseInEta(const float maxETA, const bool beamConst, const GlobalPoint &h1, const GlobalPoint &h2) const
SegmentParameters wideParameters
std::unique_ptr< MuonSegFit > addHit(HitAndPositionPtrContainer &proto_segment, const HitAndPosition &aHit) const
unsigned int minNumberOfHits