CMS 3D CMS Logo

List of all members | Classes | Public Member Functions | Private Attributes
SpikeAndDoubleSpikeCleaner Class Reference
Inheritance diagram for SpikeAndDoubleSpikeCleaner:
RecHitTopologicalCleanerBase

Classes

struct  spike_cleaning
 

Public Member Functions

void clean (const edm::Handle< reco::PFRecHitCollection > &input, std::vector< bool > &mask) override
 
SpikeAndDoubleSpikeCleaneroperator= (const SpikeAndDoubleSpikeCleaner &)=delete
 
 SpikeAndDoubleSpikeCleaner (const edm::ParameterSet &conf, edm::ConsumesCollector &cc)
 
 SpikeAndDoubleSpikeCleaner (const SpikeAndDoubleSpikeCleaner &)=delete
 
- Public Member Functions inherited from RecHitTopologicalCleanerBase
const std::string & name () const
 
RecHitTopologicalCleanerBaseoperator= (const RecHitTopologicalCleanerBase &)=delete
 
 RecHitTopologicalCleanerBase (const edm::ParameterSet &conf, edm::ConsumesCollector &cc)
 
 RecHitTopologicalCleanerBase (const RecHitTopologicalCleanerBase &)=delete
 
virtual void update (const edm::EventSetup &)
 
virtual ~RecHitTopologicalCleanerBase ()=default
 

Private Attributes

const std::unordered_map< std::string, int > _layerMap
 
std::unordered_map< int, spike_cleaning_thresholds
 

Detailed Description

Definition at line 8 of file SpikeAndDoubleSpikeCleaner.cc.

Constructor & Destructor Documentation

◆ SpikeAndDoubleSpikeCleaner() [1/2]

SpikeAndDoubleSpikeCleaner::SpikeAndDoubleSpikeCleaner ( const edm::ParameterSet conf,
edm::ConsumesCollector cc 
)

Definition at line 98 of file SpikeAndDoubleSpikeCleaner.cc.

References PFLayer::ECAL_BARREL, PFLayer::ECAL_ENDCAP, PFLayer::HCAL_BARREL1, PFLayer::HCAL_BARREL2, PFLayer::HCAL_ENDCAP, PFLayer::HF_EM, PFLayer::HF_HAD, createfilelist::int, PFLayer::NONE, PFLayer::PS1, and PFLayer::PS2.

99  : RecHitTopologicalCleanerBase(conf, cc),
100  _layerMap({{"PS2", (int)PFLayer::PS2},
101  {"PS1", (int)PFLayer::PS1},
102  {"ECAL_ENDCAP", (int)PFLayer::ECAL_ENDCAP},
103  {"ECAL_BARREL", (int)PFLayer::ECAL_BARREL},
104  {"NONE", (int)PFLayer::NONE},
105  {"HCAL_BARREL1", (int)PFLayer::HCAL_BARREL1},
106  {"HCAL_BARREL2_RING0", (int)PFLayer::HCAL_BARREL2},
107  // hack to deal with ring1 in HO
108  {"HCAL_BARREL2_RING1", 100 * (int)PFLayer::HCAL_BARREL2},
109  {"HCAL_ENDCAP", (int)PFLayer::HCAL_ENDCAP},
110  {"HF_EM", (int)PFLayer::HF_EM},
111  {"HF_HAD", (int)PFLayer::HF_HAD}}) {
112  const std::vector<edm::ParameterSet>& thresholds = conf.getParameterSetVector("cleaningByDetector");
113  for (const auto& pset : thresholds) {
114  spike_cleaning info;
115  const std::string& det = pset.getParameter<std::string>("detector");
116  info._minS4S1_a = pset.getParameter<double>("minS4S1_a");
117  info._minS4S1_b = pset.getParameter<double>("minS4S1_b");
118  info._doubleSpikeS6S2 = pset.getParameter<double>("doubleSpikeS6S2");
119  info._eneThreshMod = pset.getParameter<double>("energyThresholdModifier");
120  info._fracThreshMod = pset.getParameter<double>("fractionThresholdModifier");
121  info._doubleSpikeThresh = pset.getParameter<double>("doubleSpikeThresh");
122  info._singleSpikeThresh = pset.getParameter<double>("singleSpikeThresh");
123  auto entry = _layerMap.find(det);
124  if (entry == _layerMap.end()) {
125  throw cms::Exception("InvalidDetectorLayer") << "Detector layer : " << det << " is not in the list of recognized"
126  << " detector layers!";
127  }
128  _thresholds.emplace(_layerMap.find(det)->second, info);
129  }
130 }
static const TGPicture * info(bool iBackgroundIsBlack)
const std::unordered_map< std::string, int > _layerMap
std::unordered_map< int, spike_cleaning > _thresholds
VParameterSet const & getParameterSetVector(std::string const &name) const
RecHitTopologicalCleanerBase(const edm::ParameterSet &conf, edm::ConsumesCollector &cc)

◆ SpikeAndDoubleSpikeCleaner() [2/2]

SpikeAndDoubleSpikeCleaner::SpikeAndDoubleSpikeCleaner ( const SpikeAndDoubleSpikeCleaner )
delete

Member Function Documentation

◆ clean()

void SpikeAndDoubleSpikeCleaner::clean ( const edm::Handle< reco::PFRecHitCollection > &  input,
std::vector< bool > &  mask 
)
overridevirtual

Implements RecHitTopologicalCleanerBase.

Definition at line 132 of file SpikeAndDoubleSpikeCleaner.cc.

References _thresholds, funct::abs(), AlCaHLTBitMon_QueryRunRegistry::comp, reco::PFRecHit::detId(), PFLayer::ECAL_BARREL, reco::PFRecHit::energy(), RhoEtaPhi::eta(), PVValHelper::eta, PFLayer::HCAL_BARREL2, HcalForward, PFLayer::HF_EM, PFLayer::HF_HAD, hfClusterShapes_cfi::hits, mps_fire::i, heavyIonCSV_trainingSettings::idx, HcalDetId::ieta(), recoMuon::in, input, createfilelist::int, HcalDetId::iphi(), dqmiolumiharvest::j, dqmdumpme::k, reco::PFRecHit::layer(), SiStripPI::min, reco::PFRecHit::neighbours4(), phi, RhoEtaPhi::phi(), reco::PFRecHit::positionREP(), DetId::rawId(), and jetUpdater_cfi::sort.

132  {
133  //need to run over energy sorted rechits
134  auto const& hits = *input;
135  std::vector<unsigned> ordered_hits(hits.size());
136  for (unsigned i = 0; i < hits.size(); ++i)
137  ordered_hits[i] = i;
138  std::sort(ordered_hits.begin(), ordered_hits.end(), [&](unsigned i, unsigned j) {
139  return hits[i].energy() > hits[j].energy();
140  });
141 
142  for (const auto& idx : ordered_hits) {
143  const unsigned i = idx;
144  if (!mask[i])
145  continue; // don't need to re-mask things :-)
146  const reco::PFRecHit& rechit = hits[i];
147  int hitlayer = (int)rechit.layer();
148  if (hitlayer == PFLayer::HCAL_BARREL2 && std::abs(rechit.positionREP().eta()) > 0.34) {
149  hitlayer *= 100;
150  }
151  const spike_cleaning& clean = _thresholds.find(hitlayer)->second;
152  if (rechit.energy() < clean._singleSpikeThresh)
153  continue;
154 
155  //Fix needed for HF. Here, we find the (up to) five companion rechits
156  //to work in conjunction with the neighbours4() implementation below for the full HF surrounding energy
157  float compsumE = 0.0;
158  if ((hitlayer == PFLayer::HF_EM || hitlayer == PFLayer::HF_HAD)) {
159  int comp = 1;
160  if (hitlayer == PFLayer::HF_EM)
161  comp = 2;
162  const HcalDetId& detid = (HcalDetId)rechit.detId();
163  int heta = detid.ieta();
164  int hphi = detid.iphi();
165 
166  //At eta>39, phi segmentation changes
167  int predphi = 2;
168  if (std::abs(heta) > 39)
169  predphi = 4;
170 
171  int curphiL = hphi - predphi;
172  int curphiH = hphi + predphi;
173 
174  //HcalDetId valid phi range (0-72)
175  while (curphiL < 0)
176  curphiL += 72;
177  while (curphiH > 72)
178  curphiH -= 72;
179 
180  std::pair<std::vector<int>, std::vector<int>> phietas({heta, heta + 1, heta - 1, heta, heta},
181  {hphi, hphi, hphi, curphiL, curphiH});
182 
183  std::vector<uint32_t> rawDetIds;
184  for (unsigned in = 0; in < phietas.first.size(); in++) {
185  HcalDetId tempID(HcalForward, phietas.first[in], phietas.second[in], comp);
186  rawDetIds.push_back(tempID.rawId());
187  }
188 
189  for (const auto& jdx : ordered_hits) {
190  const unsigned j = jdx;
191  const reco::PFRecHit& matchrechit = hits[j];
192  for (const auto& iID : rawDetIds)
193  if (iID == matchrechit.detId())
194  compsumE += matchrechit.energy();
195  }
196  }
197  //End of fix needed for HF
198 
199  const double rhenergy = rechit.energy();
200  // single spike cleaning
201  auto const& neighbours4 = rechit.neighbours4();
202  double surroundingEnergy = compsumE;
203  for (auto k : neighbours4) {
204  if (!mask[k])
205  continue;
206  auto const& neighbour = hits[k];
207  const double sum = neighbour.energy(); //energyUp is just rechit energy?
208  surroundingEnergy += sum;
209  }
210  // wannaBeSeed.energyUp()/wannaBeSeed.energy() : 1.;
211  // Fraction 1 is the balance between the hit and its neighbours
212  // from both layers
213  const double fraction1 = surroundingEnergy / rhenergy;
214  // removed spurious comments from old pfcluster algo...
215  // look there if you want more history
216  const double f1Cut = (clean._minS4S1_a * std::log10(rechit.energy()) + clean._minS4S1_b);
217  if (fraction1 < f1Cut) {
218  const double eta = rechit.positionREP().eta();
219  const double aeta = std::abs(eta);
220  const double phi = rechit.positionREP().phi();
221  std::pair<double, double> dcr = dCrack(phi, eta);
222  const double dcrmin = (rechit.layer() == PFLayer::ECAL_BARREL ? std::min(dcr.first, dcr.second) : dcr.second);
223  if (aeta < 5.0 && ((aeta < 2.85 && dcrmin > 1.0) || (rhenergy > clean._eneThreshMod * clean._singleSpikeThresh &&
224  fraction1 < f1Cut / clean._fracThreshMod))) {
225  mask[i] = false;
226  }
227  } //if initial fraction cut (single spike)
228  // double spike removal
229  if (mask[i] && rhenergy > clean._doubleSpikeThresh) {
230  //Determine energy surrounding the seed and the most energetic neighbour
231  double surroundingEnergyi = 0.0;
232  double enmax = -999.0;
233  unsigned int mostEnergeticNeighbour = 0;
234  auto const& neighbours4i = rechit.neighbours4();
235  for (auto k : neighbours4i) {
236  if (!mask[k])
237  continue;
238  auto const& neighbour = hits[k];
239  const double nenergy = neighbour.energy();
240  surroundingEnergyi += nenergy;
241  if (nenergy > enmax) {
242  enmax = nenergy;
243  mostEnergeticNeighbour = k;
244  }
245  }
246  // is there an energetic neighbour
247  if (enmax > 0.0) {
248  double surroundingEnergyj = 0.0;
249  auto const& neighbours4j = hits[mostEnergeticNeighbour].neighbours4();
250  for (auto k : neighbours4j) {
251  //if( !mask[k] && k != i) continue; // leave out?
252  surroundingEnergyj += hits[k].energy();
253  }
254  // The energy surrounding the double spike candidate
255  const double surroundingEnergyFraction =
256  (surroundingEnergyi + surroundingEnergyj) / (rechit.energy() + hits[mostEnergeticNeighbour].energy()) - 1.;
257  if (surroundingEnergyFraction < clean._doubleSpikeS6S2) {
258  const double eta = rechit.positionREP().eta();
259  const double aeta = std::abs(eta);
260  const double phi = rechit.positionREP().phi();
261  std::pair<double, double> dcr = dCrack(phi, eta);
262  const double dcrmin = (rechit.layer() == PFLayer::ECAL_BARREL ? std::min(dcr.first, dcr.second) : dcr.second);
263  if (aeta < 5.0 && ((aeta < 2.85 && dcrmin > 1.0) ||
264  (rhenergy > clean._eneThreshMod * clean._doubleSpikeThresh &&
265  surroundingEnergyFraction < clean._doubleSpikeS6S2 / clean._fracThreshMod))) {
266  mask[i] = false;
267  mask[mostEnergeticNeighbour] = false;
268  }
269  }
270  } // was there an energetic neighbour ?
271  } // if double spike thresh
272  } // rechit loop
273 }
Neighbours neighbours4() const
Definition: PFRecHit.h:81
PFLayer::Layer layer() const
rechit layer
Definition: PFRecHit.h:96
void clean(const edm::Handle< reco::PFRecHitCollection > &input, std::vector< bool > &mask) override
static std::string const input
Definition: EdmProvDump.cc:47
unsigned detId() const
rechit detId
Definition: PFRecHit.h:93
U second(std::pair< T, U > const &p)
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
constexpr int ieta() const
get the cell ieta
Definition: HcalDetId.h:155
float phi() const
momentum azimuthal angle
Definition: PtEtaPhiMass.h:54
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
RhoEtaPhi const & positionREP() const
Definition: PFRecHit.h:119
float eta() const
momentum pseudorapidity
Definition: PtEtaPhiMass.h:52
std::unordered_map< int, spike_cleaning > _thresholds
float energy() const
rechit energy
Definition: PFRecHit.h:99
constexpr int iphi() const
get the cell iphi
Definition: HcalDetId.h:157

◆ operator=()

SpikeAndDoubleSpikeCleaner& SpikeAndDoubleSpikeCleaner::operator= ( const SpikeAndDoubleSpikeCleaner )
delete

Member Data Documentation

◆ _layerMap

const std::unordered_map<std::string, int> SpikeAndDoubleSpikeCleaner::_layerMap
private

Definition at line 27 of file SpikeAndDoubleSpikeCleaner.cc.

◆ _thresholds

std::unordered_map<int, spike_cleaning> SpikeAndDoubleSpikeCleaner::_thresholds
private

Definition at line 28 of file SpikeAndDoubleSpikeCleaner.cc.

Referenced by clean().