CMS 3D CMS Logo

List of all members | Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes
ME0SegAlgoRU Class Reference

#include <ME0SegAlgoRU.h>

Inheritance diagram for ME0SegAlgoRU:
ME0SegmentAlgorithmBase

Classes

struct  SegmentParameters
 

Public Types

typedef std::vector< bool > BoolContainer
 
typedef std::vector< std::pair< float, HitAndPositionPtrContainer > > SegmentByMetricContainer
 
- Public Types inherited from ME0SegmentAlgorithmBase
typedef std::vector< HitAndPositionHitAndPositionContainer
 
typedef std::vector< const HitAndPosition * > HitAndPositionPtrContainer
 

Public Member Functions

 ME0SegAlgoRU (const edm::ParameterSet &ps)
 Constructor. More...
 
std::vector< ME0Segmentrun (const ME0Chamber *chamber, const HitAndPositionContainer &rechits) override
 
 ~ME0SegAlgoRU () override
 Destructor. More...
 
- Public Member Functions inherited from ME0SegmentAlgorithmBase
 ME0SegmentAlgorithmBase (const edm::ParameterSet &)
 Constructor. More...
 
virtual ~ME0SegmentAlgorithmBase ()
 Destructor. More...
 

Private Member Functions

std::unique_ptr< MuonSegFitaddHit (HitAndPositionPtrContainer &proto_segment, const HitAndPosition &aHit) const
 
void addUniqueSegments (SegmentByMetricContainer &proto_segments, std::vector< ME0Segment > &segments, BoolContainer &used) const
 
bool areHitsCloseInEta (const float maxETA, const bool beamConst, const GlobalPoint &h1, const GlobalPoint &h2) const
 
bool areHitsCloseInGlobalPhi (const float maxPHI, const unsigned int nLayDisp, const GlobalPoint &h1, const GlobalPoint &h2) const
 
bool areHitsConsistentInTime (const float maxTOF, const HitAndPositionPtrContainer &proto_segment, const HitAndPosition &h) const
 
void compareProtoSegment (std::unique_ptr< MuonSegFit > &current_fit, HitAndPositionPtrContainer &current_proto_segment, const HitAndPosition &new_hit) const
 
float getHitSegChi2 (const std::unique_ptr< MuonSegFit > &fit, const ME0RecHit &hit) const
 
GlobalPoint globalAtZ (const std::unique_ptr< MuonSegFit > &fit, float z) const
 
bool hasHitOnLayer (const HitAndPositionPtrContainer &proto_segment, const unsigned int layer) const
 
void increaseProtoSegment (const float maxChi2, std::unique_ptr< MuonSegFit > &current_fit, HitAndPositionPtrContainer &current_proto_segment, const HitAndPosition &new_hit) const
 
bool isHitNearSegment (const float maxETA, const float maxPHI, const std::unique_ptr< MuonSegFit > &fit, const HitAndPositionPtrContainer &proto_segment, const HitAndPosition &h) const
 
void lookForSegments (const SegmentParameters &params, const unsigned int n_seg_min, const HitAndPositionContainer &rechits, const std::vector< unsigned int > &recHits_per_layer, BoolContainer &used, std::vector< ME0Segment > &segments) const
 
std::unique_ptr< MuonSegFitmakeFit (const HitAndPositionPtrContainer &proto_segment) const
 
void pruneBadHits (const float maxChi2, HitAndPositionPtrContainer &proto_segment, std::unique_ptr< MuonSegFit > &fit, const unsigned int n_seg_min) const
 
void tryAddingHitsToSegment (const float maxTOF, const float maxETA, const float maxPhi, const float maxChi2, std::unique_ptr< MuonSegFit > &current_fit, HitAndPositionPtrContainer &proto_segment, const BoolContainer &used, HitAndPositionContainer::const_iterator i1, HitAndPositionContainer::const_iterator i2) const
 

Private Attributes

bool allowWideSegments
 
SegmentParameters displacedParameters
 
bool doCollisions
 
const std::string myName
 
SegmentParameters stdParameters
 
const ME0ChambertheChamber
 
SegmentParameters wideParameters
 

Detailed Description

adapted from CSC to ME0 bt Marcello Maggi

This is the original algorithm for building endcap muon track segments out of the rechit's in a ME0Chamber 'RU' = 'RUssia' = Road Usage

A ME0Segment is a RecSegment4D, and is built from ME0RecHit2D objects, each of which is a RecHit2DLocalPos.

This class is used by the ME0SegmentAlgorithm.
Alternative algorithms can be used for the segment building by writing classes like this, and then selecting which one is actually used via the ME0SegmentBuilder.

developed and implemented by Vladimir Palichik Vladi.nosp@m.mir..nosp@m.Paltc.nosp@m.hik@.nosp@m.cern..nosp@m.ch and Nikolay Voytishin nikol.nosp@m.ay.v.nosp@m.oytis.nosp@m.hin@.nosp@m.cern..nosp@m.ch

Definition at line 31 of file ME0SegAlgoRU.h.

Member Typedef Documentation

◆ BoolContainer

typedef std::vector<bool> ME0SegAlgoRU::BoolContainer

Definition at line 47 of file ME0SegAlgoRU.h.

◆ SegmentByMetricContainer

typedef std::vector<std::pair<float, HitAndPositionPtrContainer> > ME0SegAlgoRU::SegmentByMetricContainer

Definition at line 48 of file ME0SegAlgoRU.h.

Constructor & Destructor Documentation

◆ ME0SegAlgoRU()

ME0SegAlgoRU::ME0SegAlgoRU ( const edm::ParameterSet ps)
explicit

Constructor.

Definition at line 25 of file ME0SegAlgoRU.cc.

References allowWideSegments, displacedParameters, doCollisions, edm::ParameterSet::getParameter(), LogDebug, ME0SegAlgoRU::SegmentParameters::maxChi2Additional, ME0SegAlgoRU::SegmentParameters::maxChi2GoodSeg, ME0SegAlgoRU::SegmentParameters::maxChi2Prune, ME0SegAlgoRU::SegmentParameters::maxETASeeds, ME0SegAlgoRU::SegmentParameters::maxPhiAdditional, ME0SegAlgoRU::SegmentParameters::maxPhiSeeds, ME0SegAlgoRU::SegmentParameters::maxTOFDiff, ME0SegAlgoRU::SegmentParameters::minNumberOfHits, myName, ME0SegAlgoRU::SegmentParameters::requireBeamConstr, ME0SegAlgoRU::SegmentParameters::requireCentralBX, stdParameters, theChamber, and wideParameters.

25  : ME0SegmentAlgorithmBase(ps), myName("ME0SegAlgoRU") {
26  allowWideSegments = ps.getParameter<bool>("allowWideSegments");
27  doCollisions = ps.getParameter<bool>("doCollisions");
28 
29  stdParameters.maxChi2Additional = ps.getParameter<double>("maxChi2Additional");
30  stdParameters.maxChi2Prune = ps.getParameter<double>("maxChi2Prune");
31  stdParameters.maxChi2GoodSeg = ps.getParameter<double>("maxChi2GoodSeg");
32  stdParameters.maxPhiSeeds = ps.getParameter<double>("maxPhiSeeds");
33  stdParameters.maxPhiAdditional = ps.getParameter<double>("maxPhiAdditional");
34  stdParameters.maxETASeeds = ps.getParameter<double>("maxETASeeds");
35  stdParameters.maxTOFDiff = ps.getParameter<double>("maxTOFDiff");
36  stdParameters.requireCentralBX = ps.getParameter<bool>("requireCentralBX");
37  stdParameters.minNumberOfHits = ps.getParameter<unsigned int>("minNumberOfHits");
39 
46 
55 
56  LogDebug("ME0SegAlgoRU") << myName << " has algorithm cuts set to: \n"
57  << "--------------------------------------------------------------------\n"
58  << "allowWideSegments = " << allowWideSegments << "\n"
59  << "doCollisions = " << doCollisions << "\n"
60  << "maxChi2Additional = " << stdParameters.maxChi2Additional << "\n"
61  << "maxChi2Prune = " << stdParameters.maxChi2Prune << "\n"
62  << "maxChi2GoodSeg = " << stdParameters.maxChi2GoodSeg << "\n"
63  << "maxPhiSeeds = " << stdParameters.maxPhiSeeds << "\n"
64  << "maxPhiAdditional = " << stdParameters.maxPhiAdditional << "\n"
65  << "maxETASeeds = " << stdParameters.maxETASeeds << "\n"
66  << "maxTOFDiff = " << stdParameters.maxTOFDiff << "\n"
67  << std::endl;
68 
69  theChamber = nullptr;
70 }
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
SegmentParameters displacedParameters
Definition: ME0SegAlgoRU.h:132
const std::string myName
Definition: ME0SegAlgoRU.h:127
SegmentParameters stdParameters
Definition: ME0SegAlgoRU.h:131
const ME0Chamber * theChamber
Definition: ME0SegAlgoRU.h:136
bool allowWideSegments
Definition: ME0SegAlgoRU.h:129
SegmentParameters wideParameters
Definition: ME0SegAlgoRU.h:133
ME0SegmentAlgorithmBase(const edm::ParameterSet &)
Constructor.
#define LogDebug(id)

◆ ~ME0SegAlgoRU()

ME0SegAlgoRU::~ME0SegAlgoRU ( )
inlineoverride

Destructor.

Definition at line 53 of file ME0SegAlgoRU.h.

53 {};

Member Function Documentation

◆ addHit()

std::unique_ptr< MuonSegFit > ME0SegAlgoRU::addHit ( HitAndPositionPtrContainer proto_segment,
const HitAndPosition aHit 
) const
private

Definition at line 436 of file ME0SegAlgoRU.cc.

References makeFit().

Referenced by compareProtoSegment(), increaseProtoSegment(), and lookForSegments().

437  {
438  proto_segment.push_back(&aHit);
439  // make a fit
440  return makeFit(proto_segment);
441 }
std::unique_ptr< MuonSegFit > makeFit(const HitAndPositionPtrContainer &proto_segment) const

◆ addUniqueSegments()

void ME0SegAlgoRU::addUniqueSegments ( SegmentByMetricContainer proto_segments,
std::vector< ME0Segment > &  segments,
BoolContainer used 
) const
private

Definition at line 268 of file ME0SegAlgoRU.cc.

References a, b, ME0Chamber::computeDeltaPhi(), HLT_2023v12_cff::dPhi, nano_mu_digi_cff::float, h, heavyIonCSV_trainingSettings::idx, makeFit(), jetUpdater_cfi::sort, mathSSE::sqrt(), groupFilesInBlocks::temp, and theChamber.

Referenced by lookForSegments().

270  {
271  std::sort(proto_segments.begin(),
272  proto_segments.end(),
273  [](const std::pair<float, HitAndPositionPtrContainer>& a,
274  const std::pair<float, HitAndPositionPtrContainer>& b) { return a.first < b.first; });
275 
276  //Now add to the collect based on minChi2 marking the hits as used after
277  std::vector<unsigned int> usedHits;
278  for (unsigned int iS = 0; iS < proto_segments.size(); ++iS) {
279  HitAndPositionPtrContainer currentProtoSegment = proto_segments[iS].second;
280 
281  //check to see if we already used thes hits this round
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)
286  continue;
287  alreadyFilled = true;
288  break;
289  }
290  }
291  if (alreadyFilled)
292  continue;
293  for (const auto* h : currentProtoSegment) {
294  usedHits.push_back(h->idx);
295  used[h->idx] = true;
296  }
297 
298  std::unique_ptr<MuonSegFit> current_fit = makeFit(currentProtoSegment);
299 
300  // Create an actual ME0Segment - retrieve all info from the fit
301  // calculate the timing fron rec hits associated to the TrackingRecHits used
302  // to fit the segment
303  float averageTime = 0.;
304  for (const auto* h : currentProtoSegment) {
305  averageTime += h->rh->tof();
306  }
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);
311  }
312  timeUncrt = std::sqrt(timeUncrt / float(currentProtoSegment.size() - 1));
313 
314  std::sort(currentProtoSegment.begin(),
315  currentProtoSegment.end(),
316  [](const HitAndPosition* a, const HitAndPosition* b) { return a->layer < b->layer; });
317 
318  std::vector<const ME0RecHit*> bareRHs;
319  bareRHs.reserve(currentProtoSegment.size());
320  for (const auto* rh : currentProtoSegment)
321  bareRHs.push_back(rh->rh);
322  const float dPhi = theChamber->computeDeltaPhi(current_fit->intercept(), current_fit->localdir());
323  ME0Segment temp(bareRHs,
324  current_fit->intercept(),
325  current_fit->localdir(),
326  current_fit->covarianceMatrix(),
327  current_fit->chi2(),
328  averageTime,
329  timeUncrt,
330  dPhi);
331  segments.push_back(temp);
332  }
333 }
std::unique_ptr< MuonSegFit > makeFit(const HitAndPositionPtrContainer &proto_segment) const
float computeDeltaPhi(const LocalPoint &position, const LocalVector &direction) const
Definition: ME0Chamber.cc:64
std::vector< const HitAndPosition * > HitAndPositionPtrContainer
T sqrt(T t)
Definition: SSEVec.h:19
double b
Definition: hdecay.h:120
const ME0Chamber * theChamber
Definition: ME0SegAlgoRU.h:136
double a
Definition: hdecay.h:121
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4

◆ areHitsCloseInEta()

bool ME0SegAlgoRU::areHitsCloseInEta ( const float  maxETA,
const bool  beamConst,
const GlobalPoint h1,
const GlobalPoint h2 
) const
private

Definition at line 374 of file ME0SegAlgoRU.cc.

References change_name::diff, PV3DBase< T, PVType, FrameType >::eta(), f, SiStripPI::max, and HLT_2023v12_cff::maxETA.

Referenced by lookForSegments().

377  {
378  float diff = std::fabs(h1.eta() - h2.eta());
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;
382  //temp for floating point comparision...maxEta is the difference between partitions, so x1.5 to take into account non-circle geom.
383  return (diff < std::max(maxETA, 0.01f));
384 }
Log< level::Info, true > LogVerbatim
T eta() const
Definition: PV3DBase.h:73
double f[11][100]

◆ areHitsCloseInGlobalPhi()

bool ME0SegAlgoRU::areHitsCloseInGlobalPhi ( const float  maxPHI,
const unsigned int  nLayDisp,
const GlobalPoint h1,
const GlobalPoint h2 
) const
private

Definition at line 386 of file ME0SegAlgoRU.cc.

References PV3DBase< T, PVType, FrameType >::barePhi(), SiPixelRawToDigiRegional_cfi::deltaPhi, f, and SiStripPI::max.

Referenced by lookForSegments().

389  {
390  float dphi12 = deltaPhi(h1.barePhi(), h2.barePhi());
391  edm::LogVerbatim("ME0SegAlgoRU") << "[ME0SegAlgoRU::areHitsCloseInGlobalPhi] gp1 = " << h1 << " and gp2 = " << h2
392  << " ==> dPhi = " << dphi12 << " ==> return "
393  << (fabs(dphi12) < std::max(maxPHI, 0.02f)) << std::endl;
394  return fabs(dphi12) < std::max(maxPHI, float(float(nLayDisp) * 0.004));
395 }
Log< level::Info, true > LogVerbatim
T barePhi() const
Definition: PV3DBase.h:65
double f[11][100]

◆ areHitsConsistentInTime()

bool ME0SegAlgoRU::areHitsConsistentInTime ( const float  maxTOF,
const HitAndPositionPtrContainer proto_segment,
const HitAndPosition h 
) const
private

Definition at line 416 of file ME0SegAlgoRU.cc.

References h, and jetUpdater_cfi::sort.

Referenced by tryAddingHitsToSegment().

418  {
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());
424  std::sort(tofs.begin(), tofs.end());
425  if (std::fabs(tofs.front() - tofs.back()) < maxTOF + 1.0)
426  return true;
427  return false;
428 }
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4

◆ compareProtoSegment()

void ME0SegAlgoRU::compareProtoSegment ( std::unique_ptr< MuonSegFit > &  current_fit,
HitAndPositionPtrContainer current_proto_segment,
const HitAndPosition new_hit 
) const
private

Definition at line 503 of file ME0SegAlgoRU.cc.

References funct::abs(), addHit(), nano_mu_digi_cff::float, h, ME0SegmentAlgorithmBase::HitAndPosition::layer, ME0SegmentAlgorithmBase::HitAndPosition::lp, eostools::move(), ME0SegmentAlgorithmBase::HitAndPosition::rh, and ME0RecHit::tof().

Referenced by tryAddingHitsToSegment().

505  {
506  const HitAndPosition* old_hit = nullptr;
507  HitAndPositionPtrContainer new_proto_segment = current_proto_segment;
508 
509  for (auto it = new_proto_segment.begin(); it != new_proto_segment.end();) {
510  if ((*it)->layer == new_hit.layer) {
511  old_hit = *it;
512  it = new_proto_segment.erase(it);
513  } else {
514  ++it;
515  }
516  }
517  if (old_hit == nullptr)
518  return;
519  auto new_fit = addHit(new_proto_segment, new_hit);
520 
521  //If on the same strip but different BX choose the closest
522  bool useNew = false;
523  if (old_hit->lp == new_hit.lp) {
524  float avgtof = 0;
525  for (const auto* h : current_proto_segment)
526  if (old_hit != h)
527  avgtof += h->rh->tof();
528  avgtof /= float(current_proto_segment.size() - 1);
529  if (std::abs(avgtof - new_hit.rh->tof()) < std::abs(avgtof - old_hit->rh->tof()))
530  useNew = true;
531  } //otherwise base it on chi2
532  else if (new_fit->chi2() < current_fit->chi2())
533  useNew = true;
534 
535  if (useNew) {
536  current_proto_segment = new_proto_segment;
537  current_fit = std::move(new_fit);
538  }
539 }
std::vector< const HitAndPosition * > HitAndPositionPtrContainer
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
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.
Definition: Activities.doc:4
def move(src, dest)
Definition: eostools.py:511

◆ getHitSegChi2()

float ME0SegAlgoRU::getHitSegChi2 ( const std::unique_ptr< MuonSegFit > &  fit,
const ME0RecHit hit 
) const
private

Definition at line 480 of file ME0SegAlgoRU.cc.

Referenced by pruneBadHits().

480  {
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());
485 
486  ROOT::Math::SMatrix<double, 2, 2, ROOT::Math::MatRepSym<double, 2> > IC;
487  IC(0, 0) = le.xx();
488  IC(1, 0) = le.xy();
489  IC(1, 1) = le.yy();
490 
491  // Invert covariance matrix
492  IC.Invert();
493  return du * du * IC(0, 0) + 2. * du * dv * IC(0, 1) + dv * dv * IC(1, 1);
494 }

◆ globalAtZ()

GlobalPoint ME0SegAlgoRU::globalAtZ ( const std::unique_ptr< MuonSegFit > &  fit,
float  z 
) const
private

Definition at line 430 of file ME0SegAlgoRU.cc.

References theChamber, GeomDet::toGlobal(), x, y, and z.

Referenced by isHitNearSegment().

430  {
431  float x = fit->xfit(z);
432  float y = fit->yfit(z);
433  return theChamber->toGlobal(LocalPoint(x, y, z));
434 }
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:30
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
const ME0Chamber * theChamber
Definition: ME0SegAlgoRU.h:136

◆ hasHitOnLayer()

bool ME0SegAlgoRU::hasHitOnLayer ( const HitAndPositionPtrContainer proto_segment,
const unsigned int  layer 
) const
private

Definition at line 496 of file ME0SegAlgoRU.cc.

References h, and nano_mu_digi_cff::layer.

Referenced by tryAddingHitsToSegment().

496  {
497  for (const auto* h : proto_segment)
498  if (h->layer == layer)
499  return true;
500  return false;
501 }
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4

◆ increaseProtoSegment()

void ME0SegAlgoRU::increaseProtoSegment ( const float  maxChi2,
std::unique_ptr< MuonSegFit > &  current_fit,
HitAndPositionPtrContainer current_proto_segment,
const HitAndPosition new_hit 
) const
private

Definition at line 541 of file ME0SegAlgoRU.cc.

References addHit(), beam_dqm_sourceclient-live_cfg::maxChi2, and eostools::move().

Referenced by tryAddingHitsToSegment().

544  {
545  HitAndPositionPtrContainer new_proto_segment = current_proto_segment;
546  auto new_fit = addHit(new_proto_segment, new_hit);
547  // edm::LogVerbatim("ME0SegAlgoRU") << "[ME0SegAlgoRU::increaseProtoSegment] new chi2 = "<<new_fit->chi2()<<" new chi2/dof = "<<new_fit->chi2()/new_fit->ndof() <<" ==> add: " << (new_fit->chi2()/new_fit->ndof() < maxChi2 ) <<std::endl;
548  if (new_fit->chi2() / new_fit->ndof() < maxChi2) {
549  current_proto_segment = new_proto_segment;
550  current_fit = std::move(new_fit);
551  }
552 }
std::vector< const HitAndPosition * > HitAndPositionPtrContainer
std::unique_ptr< MuonSegFit > addHit(HitAndPositionPtrContainer &proto_segment, const HitAndPosition &aHit) const
def move(src, dest)
Definition: eostools.py:511

◆ isHitNearSegment()

bool ME0SegAlgoRU::isHitNearSegment ( const float  maxETA,
const float  maxPHI,
const std::unique_ptr< MuonSegFit > &  fit,
const HitAndPositionPtrContainer proto_segment,
const HitAndPosition h 
) const
private

Definition at line 397 of file ME0SegAlgoRU.cc.

References SiPixelRawToDigiRegional_cfi::deltaPhi, HLT_2023v12_cff::dPhi, f, globalAtZ(), h, SiStripPI::max, HLT_2023v12_cff::maxETA, and PV3DBase< T, PVType, FrameType >::phi().

Referenced by tryAddingHitsToSegment().

401  {
402  //Get average eta, based on the two seeds...asssumes that we have not started pruning yet!
403  const float avgETA = (proto_segment[1]->gp.eta() + proto_segment[0]->gp.eta()) / 2.;
404  // edm::LogVerbatim("ME0SegAlgoRU") << "[ME0SegAlgoRU::isHitNearSegment] average eta = "<<avgETA<<" additionalHit eta = "<<h.gp.eta() <<" ==> dEta = "<<std::fabs(h.gp.eta() - avgETA) <<" ==> return "<<(std::fabs(h.gp.eta() - avgETA) < std::max(maxETA,0.01f ))<<std::endl;
405  if (std::fabs(h.gp.eta() - avgETA) > std::max(maxETA, 0.01f))
406  return false;
407 
408  //Now check the dPhi based on the segment fit
409  GlobalPoint globIntercept = globalAtZ(fit, h.lp.z());
410  float dPhi = deltaPhi(h.gp.barePhi(), globIntercept.phi());
411  //check to see if it is inbetween the two rolls of the outer and inner hits
412  // edm::LogVerbatim("ME0SegAlgoRU") << "[ME0SegAlgoRU::isHitNearSegment] projected phi = "<<globIntercept.phi()<<" additionalHit phi = "<<h.gp.barePhi() <<" ==> dPhi = "<<dPhi <<" ==> return "<<(std::fabs(dPhi) < std::max(maxPHI,0.001f))<<std::endl;
413  return (std::fabs(dPhi) < std::max(maxPHI, 0.001f));
414 }
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
double f[11][100]
GlobalPoint globalAtZ(const std::unique_ptr< MuonSegFit > &fit, float z) const
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4

◆ lookForSegments()

void ME0SegAlgoRU::lookForSegments ( const SegmentParameters params,
const unsigned int  n_seg_min,
const HitAndPositionContainer rechits,
const std::vector< unsigned int > &  recHits_per_layer,
BoolContainer used,
std::vector< ME0Segment > &  segments 
) const
private

Definition at line 175 of file ME0SegAlgoRU.cc.

References funct::abs(), addHit(), addUniqueSegments(), areHitsCloseInEta(), areHitsCloseInGlobalPhi(), testProducerWithPsetDescEmpty_cfi::i1, testProducerWithPsetDescEmpty_cfi::i2, cuy::ib, submitPVValidationJobs::params, pruneBadHits(), HI_PhotonSkim_cff::rechits, and tryAddingHitsToSegment().

Referenced by run().

180  {
181  auto ib = rechits.begin();
182  auto ie = rechits.end();
183  std::vector<std::pair<float, HitAndPositionPtrContainer> > proto_segments;
184  // the first hit is taken from the back
185  for (auto i1 = ib; i1 != ie; ++i1) {
186  const auto& h1 = *i1;
187 
188  //skip if rh is used and the layer tat has big rh multiplicity(>25RHs)
189  if (used[h1.idx])
190  continue;
191  if (recHits_per_layer[h1.layer - 1] > 100)
192  continue;
193 
194  // bool segok = false;
195  // the second hit from the front
196  for (auto i2 = ie - 1; i2 != i1; --i2) {
197  // if(segok) break; //Currently turned off
198  const auto& h2 = *i2;
199 
200  //skip if rh is used and the layer tat has big rh multiplicity(>25RHs)
201  if (used[h2.idx])
202  continue;
203  if (recHits_per_layer[h2.layer - 1] > 100)
204  continue;
205 
206  //Stop if the distance between layers is not large enough
207  if ((std::abs(int(h2.layer) - int(h1.layer)) + 1) < int(n_seg_min))
208  break;
209 
210  if (std::fabs(h1.rh->tof() - h2.rh->tof()) > params.maxTOFDiff + 1.0)
211  continue;
212  if (!areHitsCloseInEta(params.maxETASeeds, params.requireBeamConstr, h1.gp, h2.gp))
213  continue;
214  if (!areHitsCloseInGlobalPhi(params.maxPhiSeeds, abs(int(h2.layer) - int(h1.layer)), h1.gp, h2.gp))
215  continue;
216 
217  HitAndPositionPtrContainer current_proto_segment;
218  std::unique_ptr<MuonSegFit> current_fit;
219  current_fit = addHit(current_proto_segment, h1);
220  current_fit = addHit(current_proto_segment, h2);
221 
222  tryAddingHitsToSegment(params.maxTOFDiff,
223  params.maxETASeeds,
224  params.maxPhiAdditional,
225  params.maxChi2Additional,
226  current_fit,
227  current_proto_segment,
228  used,
229  i1,
230  i2);
231 
232  if (current_proto_segment.size() > n_seg_min)
233  pruneBadHits(params.maxChi2Prune, current_proto_segment, current_fit, n_seg_min);
234 
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)
240  << std::endl;
241 
242  if (current_proto_segment.size() < n_seg_min)
243  continue;
244  const float current_metric = current_fit->chi2() / current_fit->ndof();
245  if (current_metric > params.maxChi2GoodSeg)
246  continue;
247 
248  if (params.requireCentralBX) {
249  int nCentral = 0;
250  int nNonCentral = 0;
251  for (const auto* rh : current_proto_segment) {
252  if (std::fabs(rh->rh->tof()) < 2)
253  nCentral++;
254  else
255  nNonCentral++;
256  }
257  if (nNonCentral >= nCentral)
258  continue;
259  }
260  // segok = true;
261 
262  proto_segments.emplace_back(current_metric, current_proto_segment);
263  }
264  }
265  addUniqueSegments(proto_segments, segments, used);
266 }
Log< level::Info, true > LogVerbatim
void pruneBadHits(const float maxChi2, HitAndPositionPtrContainer &proto_segment, std::unique_ptr< MuonSegFit > &fit, const unsigned int n_seg_min) const
void addUniqueSegments(SegmentByMetricContainer &proto_segments, std::vector< ME0Segment > &segments, BoolContainer &used) const
std::vector< const HitAndPosition * > HitAndPositionPtrContainer
bool areHitsCloseInEta(const float maxETA, const bool beamConst, const GlobalPoint &h1, const GlobalPoint &h2) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool areHitsCloseInGlobalPhi(const float maxPHI, const unsigned int nLayDisp, const GlobalPoint &h1, const GlobalPoint &h2) const
void tryAddingHitsToSegment(const float maxTOF, const float maxETA, const float maxPhi, const float maxChi2, std::unique_ptr< MuonSegFit > &current_fit, HitAndPositionPtrContainer &proto_segment, const BoolContainer &used, HitAndPositionContainer::const_iterator i1, HitAndPositionContainer::const_iterator i2) const
std::unique_ptr< MuonSegFit > addHit(HitAndPositionPtrContainer &proto_segment, const HitAndPosition &aHit) const
ib
Definition: cuy.py:661

◆ makeFit()

std::unique_ptr< MuonSegFit > ME0SegAlgoRU::makeFit ( const HitAndPositionPtrContainer proto_segment) const
private

Definition at line 443 of file ME0SegAlgoRU.cc.

References ME0RecHit::clone(), and ME0RecHit::setPosition().

Referenced by addHit(), addUniqueSegments(), and pruneBadHits().

443  {
444  // for ME0 we take the me0rechit from the proto_segment we transform into Tracking Rechits
445  // the local rest frame is the ME0Chamber
447  for (auto rh = proto_segment.begin(); rh < proto_segment.end(); rh++) {
448  ME0RecHit* newRH = (*rh)->rh->clone();
449  newRH->setPosition((*rh)->lp);
450  MuonSegFit::MuonRecHitPtr trkRecHit(newRH);
451  muonRecHits.push_back(trkRecHit);
452  }
453  std::unique_ptr<MuonSegFit> currentFit(new MuonSegFit(muonRecHits));
454  currentFit->fit();
455  return currentFit;
456 }
std::shared_ptr< TrackingRecHit > MuonRecHitPtr
Definition: MuonSegFit.h:38
void setPosition(LocalPoint pos)
Set local position.
Definition: ME0RecHit.h:52
std::vector< MuonRecHitPtr > MuonRecHitContainer
Definition: MuonSegFit.h:39
ME0RecHit * clone() const override
Definition: ME0RecHit.cc:26

◆ pruneBadHits()

void ME0SegAlgoRU::pruneBadHits ( const float  maxChi2,
HitAndPositionPtrContainer proto_segment,
std::unique_ptr< MuonSegFit > &  fit,
const unsigned int  n_seg_min 
) const
private

Definition at line 458 of file ME0SegAlgoRU.cc.

References getHitSegChi2(), makeFit(), and beam_dqm_sourceclient-live_cfg::maxChi2.

Referenced by lookForSegments().

461  {
462  while (proto_segment.size() > n_seg_min && fit->chi2() / fit->ndof() > maxChi2) {
463  float maxDev = -1;
464  HitAndPositionPtrContainer::iterator worstHit;
465  for (auto it = proto_segment.begin(); it != proto_segment.end(); ++it) {
466  const float dev = getHitSegChi2(fit, *(*it)->rh);
467  if (dev < maxDev)
468  continue;
469  maxDev = dev;
470  worstHit = it;
471  }
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);
476  fit = makeFit(proto_segment);
477  }
478 }
Log< level::Info, true > LogVerbatim
std::unique_ptr< MuonSegFit > makeFit(const HitAndPositionPtrContainer &proto_segment) const
float getHitSegChi2(const std::unique_ptr< MuonSegFit > &fit, const ME0RecHit &hit) const

◆ run()

std::vector< ME0Segment > ME0SegAlgoRU::run ( const ME0Chamber chamber,
const HitAndPositionContainer rechits 
)
overridevirtual

Here we must implement the algorithm

Implements ME0SegmentAlgorithmBase.

Definition at line 72 of file ME0SegAlgoRU.cc.

References allowWideSegments, relativeConstraints::chamber, displacedParameters, doCollisions, lookForSegments(), ME0SegAlgoRU::SegmentParameters::minNumberOfHits, HI_PhotonSkim_cff::rechits, stdParameters, and theChamber.

72  {
73 #ifdef EDM_ML_DEBUG // have lines below only compiled when in debug mode
74  ME0DetId chId(chamber->id());
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;
84  }
85 #endif
86 
87  if (rechits.size() < 3 || rechits.size() > 300) {
88  return std::vector<ME0Segment>();
89  }
90 
92 
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]++;
96  }
97 
98  BoolContainer used(rechits.size(), false);
99 
100  // We have at least 2 hits. We intend to try all possible pairs of hits to start
101  // segment building. 'All possible' means each hit lies on different layers in the chamber.
102  // after all same size segs are build we get rid of the overcrossed segments using the chi2 criteria
103  // the hits from the segs that are left are marked as used and are not added to segs in future iterations
104  // the hits from 3p segs are marked as used separately in order to try to assamble them in longer segments
105  // in case there is a second pass
106 
107  // Choose first hit (as close to IP as possible) h1 and second hit
108  // (as far from IP as possible) h2 To do this we iterate over hits
109  // in the chamber by layer - pick two layers. Then we
110  // iterate over hits within each of these layers and pick h1 and h2
111  // these. If they are 'close enough' we build an empty
112  // segment. Then try adding hits to this segment.
113 
114  std::vector<ME0Segment> segments;
115 
116  auto doStd = [&]() {
117  for (unsigned int n_seg_min = 6u; n_seg_min >= stdParameters.minNumberOfHits; --n_seg_min)
118  lookForSegments(stdParameters, n_seg_min, rechits, recHits_per_layer, used, segments);
119  };
120  auto doDisplaced = [&]() {
121  for (unsigned int n_seg_min = 6u; n_seg_min >= displacedParameters.minNumberOfHits; --n_seg_min)
122  lookForSegments(displacedParameters, n_seg_min, rechits, recHits_per_layer, used, segments);
123  };
124  // Not currently used
125  // auto doWide = [&] () {
126  // for(unsigned int n_seg_min = 6u; n_seg_min >= wideParameters.minNumberOfHits; --n_seg_min)
127  // lookForSegments(wideParameters,n_seg_min,rechits,recHits_per_layer, used,segments);
128  // };
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];
133  ME0DetId chId(seg.me0DetId());
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"
137  << seg;
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 << " ]";
144  }
145  }
146 #endif
147  };
148 
149  //If we arent doing collisions, do a single iteration
150  if (!doCollisions) {
151  doDisplaced();
152  printSegments();
153  return segments;
154  }
155 
156  //Iteration 1: STD processing
157  doStd();
158 
159  if (false) {
160  //How the CSC algorithm ~does iterations. for now not considering
161  //displaced muons will not worry about it later
162  //Iteration 2a: If we don't allow wide segments simply do displaced
163  // Or if we already found a segment simply skip to displaced
164  if (!allowWideSegments || !segments.empty()) {
165  doDisplaced();
166  return segments;
167  }
168  //doWide();
169  doDisplaced();
170  }
171  printSegments();
172  return segments;
173 }
Log< level::Info, true > LogVerbatim
SegmentParameters displacedParameters
Definition: ME0SegAlgoRU.h:132
std::vector< bool > BoolContainer
Definition: ME0SegAlgoRU.h:47
SegmentParameters stdParameters
Definition: ME0SegAlgoRU.h:131
const ME0Chamber * theChamber
Definition: ME0SegAlgoRU.h:136
bool allowWideSegments
Definition: ME0SegAlgoRU.h:129
void lookForSegments(const SegmentParameters &params, const unsigned int n_seg_min, const HitAndPositionContainer &rechits, const std::vector< unsigned int > &recHits_per_layer, BoolContainer &used, std::vector< ME0Segment > &segments) const

◆ tryAddingHitsToSegment()

void ME0SegAlgoRU::tryAddingHitsToSegment ( const float  maxTOF,
const float  maxETA,
const float  maxPhi,
const float  maxChi2,
std::unique_ptr< MuonSegFit > &  current_fit,
HitAndPositionPtrContainer proto_segment,
const BoolContainer used,
HitAndPositionContainer::const_iterator  i1,
HitAndPositionContainer::const_iterator  i2 
) const
private

Definition at line 335 of file ME0SegAlgoRU.cc.

References areHitsConsistentInTime(), compareProtoSegment(), hasHitOnLayer(), testProducerWithPsetDescEmpty_cfi::i1, testProducerWithPsetDescEmpty_cfi::i2, increaseProtoSegment(), isHitNearSegment(), beam_dqm_sourceclient-live_cfg::maxChi2, HLT_2023v12_cff::maxETA, and HLT_2023v12_cff::maxPhi.

Referenced by lookForSegments().

343  {
344  // Iterate over the layers with hits in the chamber
345  // Skip the layers containing the segment endpoints
346  // Test each hit on the other layers to see if it is near the segment
347  // If it is, see whether there is already a hit on the segment from the same layer
348  // - if so, and there are more than 2 hits on the segment, copy the segment,
349  // replace the old hit with the new hit. If the new segment chi2 is better
350  // then replace the original segment with the new one (by swap)
351  // - if not, copy the segment, add the hit. If the new chi2/dof is still satisfactory
352  // then replace the original segment with the new one (by swap)
353 
354  //Hits are ordered by layer, "i1" is the inner hit and i2 is the outer hit
355  //so possible hits to add must be between these two iterators
356  for (auto iH = i1 + 1; iH != i2; ++iH) {
357  if (iH->layer == i1->layer)
358  continue;
359  if (iH->layer == i2->layer)
360  break;
361  if (used[iH->idx])
362  continue;
363  if (!areHitsConsistentInTime(maxTOF, proto_segment, *iH))
364  continue;
365  if (!isHitNearSegment(maxETA, maxPhi, current_fit, proto_segment, *iH))
366  continue;
367  if (hasHitOnLayer(proto_segment, iH->layer))
368  compareProtoSegment(current_fit, proto_segment, *iH);
369  else
370  increaseProtoSegment(maxChi2, current_fit, proto_segment, *iH);
371  }
372 }
bool hasHitOnLayer(const HitAndPositionPtrContainer &proto_segment, const unsigned int layer) const
void increaseProtoSegment(const float maxChi2, std::unique_ptr< MuonSegFit > &current_fit, HitAndPositionPtrContainer &current_proto_segment, const HitAndPosition &new_hit) const
bool isHitNearSegment(const float maxETA, const float maxPHI, const std::unique_ptr< MuonSegFit > &fit, const HitAndPositionPtrContainer &proto_segment, const HitAndPosition &h) const
bool areHitsConsistentInTime(const float maxTOF, const HitAndPositionPtrContainer &proto_segment, const HitAndPosition &h) const
void compareProtoSegment(std::unique_ptr< MuonSegFit > &current_fit, HitAndPositionPtrContainer &current_proto_segment, const HitAndPosition &new_hit) const

Member Data Documentation

◆ allowWideSegments

bool ME0SegAlgoRU::allowWideSegments
private

Definition at line 129 of file ME0SegAlgoRU.h.

Referenced by ME0SegAlgoRU(), and run().

◆ displacedParameters

SegmentParameters ME0SegAlgoRU::displacedParameters
private

Definition at line 132 of file ME0SegAlgoRU.h.

Referenced by ME0SegAlgoRU(), and run().

◆ doCollisions

bool ME0SegAlgoRU::doCollisions
private

Definition at line 128 of file ME0SegAlgoRU.h.

Referenced by ME0SegAlgoRU(), and run().

◆ myName

const std::string ME0SegAlgoRU::myName
private

Definition at line 127 of file ME0SegAlgoRU.h.

Referenced by ME0SegAlgoRU().

◆ stdParameters

SegmentParameters ME0SegAlgoRU::stdParameters
private

Definition at line 131 of file ME0SegAlgoRU.h.

Referenced by ME0SegAlgoRU(), and run().

◆ theChamber

const ME0Chamber* ME0SegAlgoRU::theChamber
private

Definition at line 136 of file ME0SegAlgoRU.h.

Referenced by addUniqueSegments(), globalAtZ(), ME0SegAlgoRU(), and run().

◆ wideParameters

SegmentParameters ME0SegAlgoRU::wideParameters
private

Definition at line 133 of file ME0SegAlgoRU.h.

Referenced by ME0SegAlgoRU().