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 = [&] () {
129 auto doWide = [&] () {
133 auto printSegments = [&] {
134 #ifdef EDM_ML_DEBUG // have lines below only compiled when in debug mode 135 for(
unsigned int iS = 0; iS < segments.size(); ++iS) {
136 const auto& seg = segments[iS];
138 const auto& rechits = seg.specificRecHits();
139 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU] segment in chamber " << chId <<
" which contains "<<rechits.size()<<
" rechits and with specs: \n"<<seg;
140 for (
auto rh=rechits.begin(); rh!=rechits.end(); ++rh){
141 auto me0id = rh->me0Id();
142 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<<
" ]";
177 BoolContainer& used, std::vector<ME0Segment>& segments)
const {
178 auto ib = rechits.begin();
179 auto ie = rechits.end();
180 std::vector<std::pair<float,HitAndPositionPtrContainer> > proto_segments;
182 for (
auto i1 =
ib; i1 != ie; ++i1) {
183 const auto& h1 = *i1;
186 if(used[h1.idx])
continue;
187 if(recHits_per_layer[h1.layer-1]>100)
continue;
191 for (
auto i2 = ie-1; i2 != i1; --i2) {
193 const auto& h2 = *i2;
196 if(used[h2.idx])
continue;
197 if(recHits_per_layer[h2.layer-1]>100)
continue;
200 if((
std::abs(
int(h2.layer) -
int(h1.layer)) + 1) <
int(n_seg_min))
break;
202 if(std::fabs(h1.rh->tof()-h2.rh->tof()) > params.
maxTOFDiff + 1.0 )
continue;
207 std::unique_ptr<MuonSegFit> current_fit;
208 current_fit =
addHit(current_proto_segment,h1);
209 current_fit =
addHit(current_proto_segment,h2);
213 if(current_proto_segment.size() > n_seg_min)
216 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;
218 if(current_proto_segment.size() < n_seg_min)
continue;
219 const float current_metric = current_fit->chi2()/current_fit->ndof();
225 for(
const auto* rh : current_proto_segment ) {
226 if(std::fabs(rh->rh->tof()) < 2 ) nCentral++;
229 if(nNonCentral >= nCentral)
continue;
233 proto_segments.emplace_back( current_metric, current_proto_segment);
242 std::sort(proto_segments.begin(),proto_segments.end(),
243 [](
const std::pair<float,HitAndPositionPtrContainer> &
a,
244 const std::pair<float,HitAndPositionPtrContainer> &
b) {
return a.first <
b.first;});
247 std::vector<unsigned int> usedHits;
248 for(
unsigned int iS = 0; iS < proto_segments.size(); ++iS){
252 bool alreadyFilled=
false;
253 for(
unsigned int iH = 0; iH < currentProtoSegment.size(); ++iH){
254 for(
unsigned int iOH = 0; iOH < usedHits.size(); ++iOH){
255 if(usedHits[iOH]!=currentProtoSegment[iH]->
idx)
continue;
256 alreadyFilled =
true;
260 if(alreadyFilled)
continue;
261 for(
const auto*
h : currentProtoSegment){
262 usedHits.push_back(
h->idx);
266 std::unique_ptr<MuonSegFit> current_fit =
makeFit(currentProtoSegment);
271 float averageTime=0.;
272 for(
const auto*
h : currentProtoSegment){
273 averageTime +=
h->rh->tof();
275 averageTime /=
float(currentProtoSegment.size());
277 for(
const auto*
h : currentProtoSegment){
278 timeUncrt += (
h->rh->tof()-averageTime)*(
h->rh->tof()-averageTime);
280 timeUncrt =
std::sqrt(timeUncrt/
float(currentProtoSegment.size()-1));
282 std::sort(currentProtoSegment.begin(),currentProtoSegment.end(),
286 std::vector<const ME0RecHit*> bareRHs; bareRHs.reserve(currentProtoSegment.size());
287 for(
const auto* rh : currentProtoSegment) bareRHs.push_back(rh->rh);
290 current_fit->localdir(), current_fit->covarianceMatrix(), current_fit->chi2(), averageTime, timeUncrt, dPhi);
291 segments.push_back(
temp);
298 const BoolContainer& used, HitAndPositionContainer::const_iterator i1, HitAndPositionContainer::const_iterator i2)
const {
311 for(
auto iH = i1 + 1; iH != i2; ++iH ){
312 if(iH->layer == i1->layer)
continue;
313 if(iH->layer == i2->layer)
break;
314 if(used[iH->idx])
continue;
316 if (!
isHitNearSegment(maxETA,maxPhi,current_fit,proto_segment,*iH))
continue;
326 diff = std::fabs(h1.
eta() - h1.
eta());
327 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;
328 return (diff <
std::max(maxETA,
float(0.01)) );
333 edm::LogVerbatim(
"ME0SegAlgoRU") <<
"[ME0SegAlgoRU::areHitsCloseInGlobalPhi] gp1 = "<<h1<<
" and gp2 = "<<h2<<
" ==> dPhi = "<<dphi12<<
" ==> return "<<(fabs(dphi12) <
std::max(maxPHI,
float(0.02)))<<std::endl;
334 return fabs(dphi12) <
std::max(maxPHI,
float(
float(nLayDisp)*0.004));
339 const float avgETA = (proto_segment[1]->gp.eta() + proto_segment[0]->gp.eta())/2.;
341 if(std::fabs(h.
gp.
eta() - avgETA) >
std::max(maxETA,
float(0.01) ))
return false;
348 return (std::fabs(dPhi) <
std::max(maxPHI,
float(0.001)));
352 std::vector<float> tofs; tofs.reserve(proto_segment.size() + 1);
353 tofs.push_back(h.
rh->
tof());
354 for(
const auto* ih : proto_segment) tofs.push_back(ih->rh->tof());
355 std::sort(tofs.begin(),tofs.end());
356 if(std::fabs(tofs.front() - tofs.back()) < maxTOF +1.0 )
return true;
361 float x = fit->xfit(z);
362 float y = fit->yfit(z);
367 proto_segment.push_back(&aHit);
376 for (
auto rh=proto_segment.begin();rh<proto_segment.end(); rh++){
380 muonRecHits.push_back(trkRecHit);
382 std::unique_ptr<MuonSegFit> currentFit(
new MuonSegFit(muonRecHits));
388 while(proto_segment.size() > n_seg_min && fit->chi2()/fit->ndof() >
maxChi2){
390 HitAndPositionPtrContainer::iterator worstHit;
391 for(
auto it = proto_segment.begin(); it != proto_segment.end(); ++it){
393 if(dev < maxDev)
continue;
397 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;
398 proto_segment.erase( worstHit);
406 const float du = fit->xdev(lp.x(),lp.z());
407 const float dv = fit->ydev(lp.y(),lp.z());
409 ROOT::Math::SMatrix<double,2,2,ROOT::Math::MatRepSym<double,2> > IC;
416 return du*du*IC(0,0) + 2.*du*dv*IC(0,1) + dv*dv*IC(1,1);
420 for(
const auto*
h : proto_segment)
if(
h->layer == layer)
return true;
428 HitAndPositionPtrContainer::const_iterator it;
429 for (
auto it = new_proto_segment.begin(); it != new_proto_segment.end();) {
430 if ((*it)->layer == new_hit.
layer) {
432 it = new_proto_segment.erase(it);
437 if(old_hit == 0)
return;
438 auto new_fit =
addHit(new_proto_segment,new_hit);
442 if(old_hit->
lp == new_hit.
lp ){
444 for(
const auto*
h : current_proto_segment)
445 if(old_hit !=
h) avgtof +=
h->rh->tof();
446 avgtof /=
float(current_proto_segment.size() - 1);
451 else if(new_fit->chi2() < current_fit->chi2()) useNew =
true;
454 current_proto_segment = new_proto_segment;
462 auto new_fit =
addHit(new_proto_segment,new_hit);
464 if(new_fit->chi2()/new_fit->ndof() <
maxChi2 ){
465 current_proto_segment = new_proto_segment;
std::shared_ptr< TrackingRecHit > MuonRecHitPtr
T getParameter(std::string const &) const
virtual ME0RecHit * clone() const
Point3DBase< Scalar, LocalTag > LocalPoint
void setPosition(LocalPoint pos)
Set local position.
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
virtual LocalError localPositionError() const
Return the 3-dimensional error on the local position.
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
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
virtual LocalPoint localPosition() const
Return the 3-dimensional local position.
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
const ME0Chamber * theChamber
bool areHitsCloseInEta(const float maxETA, const bool beamConst, const GlobalPoint &h1, const GlobalPoint &h2) const
std::vector< ME0Segment > run(const ME0Chamber *chamber, const HitAndPositionContainer &rechits)
SegmentParameters wideParameters
std::unique_ptr< MuonSegFit > addHit(HitAndPositionPtrContainer &proto_segment, const HitAndPosition &aHit) const
unsigned int minNumberOfHits