CMS 3D CMS Logo

LocalMaximumSeedFinder.cc
Go to the documentation of this file.
2 
3 #include <algorithm>
4 #include <queue>
5 #include <cfloat>
8 
9 namespace {
10  const reco::PFRecHit::Neighbours _noNeighbours(nullptr,0);
11 }
12 
15  SeedFinderBase(conf),
16  _nNeighbours(conf.getParameter<int>("nNeighbours")),
17  _layerMap({ {"PS2",(int)PFLayer::PS2},
18  {"PS1",(int)PFLayer::PS1},
19  {"ECAL_ENDCAP",(int)PFLayer::ECAL_ENDCAP},
20  {"ECAL_BARREL",(int)PFLayer::ECAL_BARREL},
21  {"NONE",(int)PFLayer::NONE},
22  {"HCAL_BARREL1",(int)PFLayer::HCAL_BARREL1},
23  {"HCAL_BARREL2_RING0",(int)PFLayer::HCAL_BARREL2},
24  // hack to deal with ring1 in HO
25  {"HCAL_BARREL2_RING1", 19},
26  {"HCAL_ENDCAP",(int)PFLayer::HCAL_ENDCAP},
27  {"HF_EM",(int)PFLayer::HF_EM},
28  {"HF_HAD",(int)PFLayer::HF_HAD} }) {
29  const std::vector<edm::ParameterSet>& thresholds =
30  conf.getParameterSetVector("thresholdsByDetector");
31  for( const auto& pset : thresholds ) {
32  const std::string& det = pset.getParameter<std::string>("detector");
33 
34  std::vector<int> depths;
35  std::vector<double> thresh_E;
36  std::vector<double> thresh_pT ;
37  std::vector<double> thresh_pT2;
38 
39  if (det==std::string("HCAL_BARREL1") || det==std::string("HCAL_ENDCAP")) {
40  depths = pset.getParameter<std::vector<int> >("depths");
41  thresh_E = pset.getParameter<std::vector<double> >("seedingThreshold");
42  thresh_pT = pset.getParameter<std::vector<double> >("seedingThresholdPt");
43  if(thresh_E.size()!=depths.size() || thresh_pT.size()!=depths.size()) {
44  throw cms::Exception("InvalidGatheringThreshold")
45  << "gatheringThresholds mismatch with the numbers of depths";
46  }
47  } else {
48  depths.push_back(0);
49  thresh_E.push_back(pset.getParameter<double>("seedingThreshold"));
50  thresh_pT.push_back(pset.getParameter<double>("seedingThresholdPt"));
51  }
52 
53  for(unsigned int i=0;i < thresh_pT.size();++i){
54  thresh_pT2.push_back(thresh_pT[i]*thresh_pT[i]);
55  }
56 
57  auto entry = _layerMap.find(det);
58  if( entry == _layerMap.end() ) {
59  throw cms::Exception("InvalidDetectorLayer")
60  << "Detector layer : " << det << " is not in the list of recognized"
61  << " detector layers!";
62  }
63 
64  _thresholds[entry->second+layerOffset]=
65  std::make_tuple(depths,thresh_E,thresh_pT2);
66  }
67 }
68 
69 // the starting state of seedable is all false!
72  const std::vector<bool>& mask,
73  std::vector<bool>& seedable ) {
74 
75  auto nhits = input->size();
76  initDynArray(bool,nhits,usable,true);
77  //need to run over energy sorted rechits
78  declareDynArray(float,nhits,energies);
79  unInitDynArray(int,nhits,qst); // queue storage
80  auto cmp = [&](int i, int j) { return energies[i] < energies[j]; };
81  std::priority_queue<int, DynArray<int>, decltype(cmp)> ordered_hits(cmp,std::move(qst));
82 
83  for( unsigned i = 0; i < nhits; ++i ) {
84  if( !mask[i] ) continue; // cannot seed masked objects
85  auto const & maybeseed = (*input)[i];
86  energies[i]=maybeseed.energy();
87  int seedlayer = (int)maybeseed.layer();
88  if( seedlayer == PFLayer::HCAL_BARREL2 &&
89  std::abs(maybeseed.positionREP().eta()) > 0.34 ) {
90  seedlayer = 19;
91  }
92  auto const & thresholds = _thresholds[seedlayer+layerOffset];
93 
94 
95  double thresholdE=0.;
96  double thresholdPT2=0.;
97 
98  for (unsigned int j=0; j<(std::get<2>(thresholds)).size(); ++j) {
99 
100  int depth=std::get<0>(thresholds)[j];
101  if( ( seedlayer == PFLayer::HCAL_BARREL1 && maybeseed.depth()== depth)
102  || ( seedlayer == PFLayer::HCAL_ENDCAP && maybeseed.depth()== depth)
103  || ( seedlayer != PFLayer::HCAL_BARREL1 && seedlayer != PFLayer::HCAL_ENDCAP)
104  ) { thresholdE=std::get<1>(thresholds)[j]; thresholdPT2=std::get<2>(thresholds)[j]; }
105 
106  }
107 
108  if( maybeseed.energy() < thresholdE ||
109  maybeseed.pt2() < thresholdPT2 ) usable[i] = false;
110  if( !usable[i] ) continue;
111  ordered_hits.push(i);
112 
113  }
114 
115 
116  while(!ordered_hits.empty() ) {
117  auto idx = ordered_hits.top();
118  ordered_hits.pop();
119  if( !usable[idx] ) continue;
120  //get the neighbours of this seed
121  auto const & maybeseed = (*input)[idx];
122  reco::PFRecHit::Neighbours myNeighbours;
123  switch( _nNeighbours ) {
124  case -1:
125  myNeighbours = maybeseed.neighbours();
126  break;
127  case 0: // for HF clustering
128  myNeighbours = _noNeighbours;
129  break;
130  case 4:
131  myNeighbours = maybeseed.neighbours4();
132  break;
133  case 8:
134  myNeighbours = maybeseed.neighbours8();
135  break;
136  default:
137  throw cms::Exception("InvalidConfiguration")
138  << "LocalMaximumSeedFinder only accepts nNeighbors = {-1,0,4,8}";
139  }
140  seedable[idx] = true;
141  for( auto neighbour : myNeighbours ) {
142  if( !mask[neighbour] ) continue;
143  if( energies[neighbour] > energies[idx] ) {
144 // std::cout << "how this can be?" << std::endl;
145  seedable[idx] = false;
146  break;
147  }
148  }
149  if( seedable[idx] ) {
150  for( auto neighbour : myNeighbours ) {
151  usable[neighbour] = false;
152  }
153  }
154  }
155 
156  LogDebug("LocalMaximumSeedFinder") << " found " << std::count(seedable.begin(),seedable.end(),true) << " seeds";
157 
158 }
#define LogDebug(id)
const std::unordered_map< std::string, int > _layerMap
#define initDynArray(T, n, x, i)
Definition: DynArray.h:60
void findSeeds(const edm::Handle< reco::PFRecHitCollection > &input, const std::vector< bool > &mask, std::vector< bool > &seedable) override
LocalMaximumSeedFinder(const edm::ParameterSet &conf)
static std::string const input
Definition: EdmProvDump.cc:48
std::array< I3tuple, 35 > _thresholds
#define unInitDynArray(T, n, x)
Definition: DynArray.h:58
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define declareDynArray(T, n, x)
Definition: DynArray.h:59
def move(src, dest)
Definition: eostools.py:511