CMS 3D CMS Logo

CosmicClusterAlgo.cc
Go to the documentation of this file.
1 
3 
4 #include <vector> //TEMP JHAUPT 4-27
5 
6 // Geometry
13 
14 // Return a vector of clusters from a collection of EcalRecHits:
15 //
16 std::vector<reco::BasicCluster> CosmicClusterAlgo::makeClusters(const EcalRecHitCollection *hits,
17  const EcalUncalibratedRecHitCollection *uncalibhits,
18  const CaloSubdetectorGeometry *geometry_p,
19  const CaloSubdetectorTopology *topology_p,
20  const CaloSubdetectorGeometry *geometryES_p,
21  EcalPart ecalPart,
22  bool regional,
23  const std::vector<RectangularEtaPhiRegion> &regions) {
24  seeds.clear();
25  used_s.clear();
26  canSeed_s.clear();
27  clusters_v.clear();
28 
29  recHits_ = hits;
30  uncalibRecHits_ = uncalibhits;
31 
32  inEB = true;
33  double threshold = 0;
34  std::string ecalPart_string;
35  if (ecalPart == endcap) {
37  ecalPart_string = "EndCap";
38  inEB = false;
39  }
40  if (ecalPart == barrel) {
42  ecalPart_string = "Barrel";
43  inEB = true;
44  }
45 
46  if (verbosity < pINFO) {
47  std::cout << "-------------------------------------------------------------" << std::endl;
48  std::cout << "Island algorithm invoked for ECAL" << ecalPart_string << std::endl;
49  std::cout << "Looking for seeds, threshold used = " << threshold << " ADC" << std::endl;
50  }
51 
52  int nregions = 0;
53  if (regional)
54  nregions = regions.size();
55 
56  if (!regional || nregions) {
58  for (it = recHits_->begin(); it != recHits_->end(); it++) {
59  if (!uncalibRecHits_) {
60  if (verbosity < pINFO) {
61  std::cout << "-------------------------------------------------------------" << std::endl;
62  std::cout << "No Uncalibrated RecHits no Uncalibrated rec hit collection available" << std::endl;
63  }
64  continue;
65  }
66 
67  // if rechit affected by features other than these, do not allow if seeding
68  // features are hard coded, for now; add severity?
69  uint32_t rhFlag = (*it).recoFlag();
70  if (!(rhFlag == EcalRecHit::kGood || rhFlag == EcalRecHit::kOutOfTime || rhFlag == EcalRecHit::kPoorCalib))
71  continue;
72 
74 
75  if (itt == uncalibRecHits_->end()) {
76  if (verbosity < pINFO) {
77  std::cout << "-------------------------------------------------------------" << std::endl;
78  std::cout << "No Uncalibrated RecHit associated with the RecHit Probably no Uncalibrated rec hit collection "
79  "available"
80  << std::endl;
81  }
82  continue;
83  }
84 
85  EcalUncalibratedRecHit uhit_p = *itt;
86 
87  // looking for cluster seeds
89  continue; //
90 
91  auto thisCell = geometry_p->getGeometry(it->id());
92 
93  // Require that RecHit is within clustering region in case
94  // of regional reconstruction
95  bool withinRegion = false;
96  if (regional) {
97  std::vector<RectangularEtaPhiRegion>::const_iterator region;
98  for (region = regions.begin(); region != regions.end(); region++) {
99  if (region->inRegion(thisCell->etaPos(), thisCell->phiPos())) {
100  withinRegion = true;
101  break;
102  }
103  }
104  }
105 
106  if (!regional || withinRegion) {
107  seeds.push_back(
108  *it); // JHaupt 4-27-2008 Et -> energy, most likely not needed as there is already a threshold requirement.
109  }
110  }
111  }
112 
113  sort(seeds.begin(), seeds.end(), [](auto const &x, auto const &y) { return x.energy() > y.energy(); });
114 
115  if (verbosity < pINFO) {
116  std::cout << "JH Total number of seeds found in event = " << seeds.size() << std::endl;
117  for (EcalRecHitCollection::const_iterator ji = seeds.begin(); ji != seeds.end(); ++ji) {
118  //std::cout << "JH Seed Energy " << ji->energy() << " hashed " << ((EBDetId)ji->id()).hashedIndex() << std::endl;
119  }
120  }
121 
122  mainSearch(geometry_p, topology_p, geometryES_p, ecalPart);
123  std::sort(clusters_v.rbegin(), clusters_v.rend(), isClusterEtLess);
124 
125  if (verbosity < pINFO) {
126  std::cout << "---------- end of main search. clusters have been sorted ----" << std::endl;
127  }
128 
129  return clusters_v;
130 }
131 
132 // Search for clusters
133 //
135  const CaloSubdetectorTopology *topology_p,
136  const CaloSubdetectorGeometry *geometryES_p,
137  EcalPart ecalPart) {
138  if (verbosity < pINFO) {
139  std::cout << "Building clusters............" << std::endl;
140  }
141 
142  // Loop over seeds:
143  std::vector<EcalRecHit>::iterator it;
144  for (it = seeds.begin(); it != seeds.end(); it++) {
145  // check if this crystal is able to seed
146  // (event though it is already used)
147  bool usedButCanSeed = false;
148  if (canSeed_s.find(it->id()) != canSeed_s.end())
149  usedButCanSeed = true;
150 
151  // make sure the current seed does not belong to a cluster already.
152  if ((used_s.find(it->id()) != used_s.end()) && (usedButCanSeed == false)) {
153  if (it == seeds.begin()) {
154  if (verbosity < pINFO) {
155  std::cout << "##############################################################" << std::endl;
156  std::cout << "DEBUG ALERT: Highest energy seed already belongs to a cluster!" << std::endl;
157  std::cout << "##############################################################" << std::endl;
158  }
159  }
160 
161  // seed crystal is used or is used and cannot seed a cluster
162  // so continue to the next seed crystal...
163  continue;
164  }
165 
166  // clear the vector of hits in current clusterconst EcalRecHitCollection* hits,
167  current_v9.clear();
168  current_v25.clear();
169  current_v25Sup.clear();
170 
171  // Create a navigator at the seed
172  CaloNavigator<DetId> navigator(it->id(), topology_p);
173  DetId seedId = navigator.pos();
174  navigator.setHome(seedId);
175 
176  // Is the seed a local maximum?
177  bool localMaxima = checkMaxima(navigator);
178 
179  if (localMaxima) {
180  // build the 5x5 taking care over which crystals //JHaupt 4-27-08 3x3 is a good option...
181  // can seed new clusters and which can't
182  prepareCluster(navigator, geometry_p);
183  }
184 
185  // If some crystals in the current vector then
186  // make them into a cluster
187  if (!current_v25.empty()) {
188  makeCluster(geometry_p, geometryES_p, seedId);
189  }
190 
191  } // End loop on seed crystals
192 }
193 
195  const CaloSubdetectorGeometry *geometryES,
196  DetId seedId) {
197  double energy = 0;
198  double energySecond = 0.; //JHaupt 4-27-08 Added for the second crystal stream
199  double energyMax = 0.; //JHaupt 4-27-08 Added for the max crystal stream
200  DetId detFir;
201  DetId detSec;
202  //bool goodCluster = false; //JHaupt 4-27-08 Added so that some can be earased.. used another day Might not be needed as seeds are energy ordered...
203 
204  std::vector<DetId>::iterator it;
205  for (it = current_v9.begin(); it != current_v9.end(); it++) {
206  // Martina - check recoFlag for crystals sorrounding the good one
208  // double-check that iterator can be dereferenced
209  if (itt == recHits_->end())
210  continue;
211  // if rechit affected by features other than these, do not allow 2 crystal seeding either
212  // features are hard coded, for now; add severity?
213  uint32_t rhFlag = (*itt).recoFlag();
214  if (!(rhFlag == EcalRecHit::kGood || rhFlag == EcalRecHit::kOutOfTime || rhFlag == EcalRecHit::kPoorCalib))
215  continue;
216 
218 
220  EcalUncalibratedRecHit uhit_p = *ittu;
221 
222  if (uhit_p.amplitude() > energySecond) {
223  energySecond = uhit_p.amplitude();
224  detSec = uhit_p.id();
225  }
226  if (energySecond > energyMax) {
227  std::swap(energySecond, energyMax);
228  std::swap(detFir, detSec);
229  }
230  }
231 
232  //if ((detFir.det() == DetId::Ecal) && (detFir.subdetId() == EcalEndcap)) inEB = false;
233  //We ignore the possiblity that the cluster may span into the EE
234 
235  if ((energyMax < (inEB ? ecalBarrelSingleThreshold : ecalEndcapSingleThreshold)) &&
237  return;
238 
239  for (it = current_v25.begin(); it != current_v25.end(); it++) {
241  EcalRecHit hit_p = *itt;
242 
244  EcalUncalibratedRecHit uhit_p = *ittu;
245 
247  // energy fraction = 1
248  current_v25Sup.push_back(std::pair<DetId, float>(hit_p.id(), 1.));
249  energy += hit_p.energy(); //Keep the fully corrected energy
250  }
251  }
252 
253  Point position;
255 
256  //don't write empty clusters
257  if (energy == 0 && position == Point(0, 0, 0))
258  return;
259 
260  if (verbosity < pINFO) {
261  std::cout << "JH******** NEW CLUSTER ********" << std::endl;
262  std::cout << "JHNo. of crystals = " << current_v25Sup.size() << std::endl;
263  std::cout << "JH Energy = " << energy << std::endl;
264  std::cout << "JH Phi = " << position.phi() << std::endl;
265  std::cout << "JH Eta = " << position.eta() << std::endl;
266  std::cout << "JH*****************************" << std::endl;
267  // specialize this
268  // std::cout << "JH****Emax**** "<<energyMax << " ieta " <<detFir.ieta() <<" iphi "<<detFir.ieta() << std::endl;
269  // std::cout << "JH****Esec**** "<<energySecond << " ieta " <<detSec.ieta() <<" iphi "<<detSec.ieta() << std::endl;
270  }
271  clusters_v.push_back(
273 }
274 
276  bool maxima = true;
279  double thisEnergy = 0.;
280  double seedEnergy = seedHit->energy();
281 
282  std::vector<DetId> swissCrossVec;
283  swissCrossVec.clear();
284 
285  swissCrossVec.push_back(navigator.west());
286  navigator.home();
287  swissCrossVec.push_back(navigator.east());
288  navigator.home();
289  swissCrossVec.push_back(navigator.north());
290  navigator.home();
291  swissCrossVec.push_back(navigator.south());
292  navigator.home();
293 
294  for (unsigned int i = 0; i < swissCrossVec.size(); ++i) {
295  thisHit = recHits_->find(swissCrossVec[i]);
296  if ((swissCrossVec[i] == DetId(0)) || thisHit == recHits_->end())
297  thisEnergy = 0.0;
298  else
299  thisEnergy = thisHit->energy();
300  if (thisEnergy > seedEnergy) {
301  maxima = false;
302  break;
303  }
304  }
305 
306  return maxima;
307 }
308 
310  DetId thisDet;
311  std::set<DetId>::iterator setItr;
312 
313  // now add the 5x5 taking care to mark the edges
314  // as able to seed and where overlapping in the central
315  // region with crystals that were previously able to seed
316  // change their status so they are not able to seed
317  //std::cout << std::endl;
318  for (int dx = -2; dx < 3; ++dx) //for (int dx = -2; dx < 3; ++dx)
319  {
320  for (int dy = -2; dy < 3; ++dy) //for (int dy = -2; dy < 3; ++ dy)
321  {
322  // navigate in free steps forming
323  // a full 5x5
324  thisDet = navigator.offsetBy(dx, dy);
325  navigator.home();
326 
327  // add the current crystal
328  //std::cout << "adding " << dx << ", " << dy << std::endl;
329 
330  // now consider if we are in an edge (outer 16)
331  // or central (inner 9) region
332  if ((abs(dx) > 1) || (abs(dy) > 1)) {
333  // this is an "edge" so should be allowed to seed
334  // provided it is not already used
335  //std::cout << " setting can seed" << std::endl;
336  addCrystal(thisDet, false); //These are in the V25
337  canSeed_s.insert(thisDet);
338  } // end if "edge"
339  else {
340  // or else we are in the central 3x3
341  // and must remove any of these crystals from the canSeed set
342  setItr = canSeed_s.find(thisDet);
343  addCrystal(thisDet, true); //These are in the V9
344  if (setItr != canSeed_s.end()) {
345  //std::cout << " unsetting can seed" << std::endl;
346  canSeed_s.erase(setItr);
347  }
348  } // end if "centre"
349 
350  } // end loop on dy
351 
352  } // end loop on dx
353 
354  //std::cout << "*** " << std::endl;
355  //std::cout << " current_v contains " << current_v.size() << std::endl;
356  //std::cout << "*** " << std::endl;
357 }
358 
359 void CosmicClusterAlgo::addCrystal(const DetId &det, const bool in9) {
361  if ((thisIt != recHits_->end()) && (thisIt->id() != DetId(0))) {
362  if ((used_s.find(thisIt->id()) == used_s.end())) {
364  used_s.insert(det);
365  if ((thisIt->energy() >= -1.) && !(thisItu->chi2() < -1.)) {
366  if (in9)
367  current_v9.push_back(det);
368  current_v25.push_back(det);
369  }
370  }
371  }
372 }
const EcalUncalibratedRecHitCollection * uncalibRecHits_
double ecalBarrelSingleThreshold
std::vector< std::pair< DetId, float > > current_v25Sup
std::vector< reco::BasicCluster > makeClusters(const EcalRecHitCollection *hits, const EcalUncalibratedRecHitCollection *uncalibhits, const CaloSubdetectorGeometry *geometry, const CaloSubdetectorTopology *topology_p, const CaloSubdetectorGeometry *geometryES_p, EcalPart ecalPart, bool regional=false, const std::vector< RectangularEtaPhiRegion > &regions=std::vector< RectangularEtaPhiRegion >())
std::vector< EcalRecHit >::const_iterator const_iterator
std::vector< DetId > current_v9
std::vector< reco::BasicCluster > clusters_v
void mainSearch(const CaloSubdetectorGeometry *geometry_p, const CaloSubdetectorTopology *topology_p, const CaloSubdetectorGeometry *geometryES_p, EcalPart ecalPart)
double ecalEndcapSingleThreshold
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
double ecalBarrelSecondThreshold
const EcalRecHitCollection * recHits_
void prepareCluster(CaloNavigator< DetId > &navigator, const CaloSubdetectorGeometry *geometry)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
math::XYZPoint Calculate_Location(const HitsAndFractions &iDetIds, const edm::SortedCollection< HitType > *iRecHits, const CaloSubdetectorGeometry *iSubGeom, const CaloSubdetectorGeometry *iESGeom=nullptr)
Definition: PositionCalc.h:65
const_iterator begin() const
bool isClusterEtLess(const reco::CaloCluster &x, const reco::CaloCluster &y)
Definition: ClusterEtLess.h:7
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
const_iterator end() const
std::vector< EcalRecHit > seeds
Definition: DetId.h:17
double ecalEndcapSecondThreshold
void makeCluster(const CaloSubdetectorGeometry *geometry_p, const CaloSubdetectorGeometry *geometryES_p, DetId seedId)
std::vector< DetId > current_v25
DetId id() const
get the id
Definition: EcalRecHit.h:77
VerbosityLevel verbosity
std::set< DetId > canSeed_s
void addCrystal(const DetId &det, const bool in9)
iterator find(key_type k)
Structure Point Contains parameters of Gaussian fits to DMRs.
static int position[264][3]
Definition: ReadPGInfo.cc:289
math::XYZPoint Point
point in the space
bool checkMaxima(CaloNavigator< DetId > &navigator)
float energy() const
Definition: EcalRecHit.h:68
PositionCalc posCalculator_
std::set< DetId > used_s