ATLAS Offline Software
GepPi0Alg.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 /*
6  This algorithm creates clusters from CaloCells, and writes them out
7  as Caloclusters. The clustering strategy is carried out by helper objects.
8  The strategy used is chosen according to string set at configure time. *
9 */
10 
11 #include "./GepPi0Alg.h"
13 
14 #include <algorithm>
15 #include <queue>
16 #include <regex>
17 #include <sstream>
18 #include <fstream>
19 
20 GepPi0Alg::GepPi0Alg(const std::string& name, ISvcLocator* pSvcLocator ) :
21  AthReentrantAlgorithm(name, pSvcLocator){
22 }
23 
24 
26  ATH_MSG_INFO ("Initializing " << name());
27 
31 
32  CHECK(m_cellsProducer.retrieve());
33 
34  CHECK(detStore()->retrieve (m_calocell_id, "CaloCell_ID"));
35 
36  return StatusCode::SUCCESS;
37 }
38 
39 
40 StatusCode GepPi0Alg::execute(const EventContext& ctx) const {
41  // Read in a CaloCell container. Ask producers to create
42  // vectors of CaloCells to be examined.
43 
44  ATH_MSG_DEBUG ("Executing " << name());
45 
46  // obtain all LAREM CaloCells, then those in EMB1
47  auto h_allCaloCells = SG::makeHandle(m_allCaloCellsKey, ctx);
48  CHECK(h_allCaloCells.isValid());
49 
50  auto allCaloCells = *h_allCaloCells;
51 
52 
53 
54  // obatain LAREM CaloCells
55  if(! allCaloCells.hasCalo(m_calocell_id->LAREM)){
56  ATH_MSG_ERROR("CaloCellCollection does not contain LAREM cells");
57  return StatusCode::FAILURE;
58  }
59 
60  auto cellbegin = allCaloCells.beginConstCalo(CaloCell_ID::LAREM);
61  auto cellend = allCaloCells.endConstCalo(CaloCell_ID::LAREM);
62  ATH_MSG_DEBUG ("Size from SubCalo Iters " << std::distance(cellbegin,
63  cellend));
64 
65  std::vector<const CaloCell*>
66  laremCells(allCaloCells.beginConstCalo(CaloCell_ID::LAREM),
67  allCaloCells.endConstCalo(CaloCell_ID::LAREM));
68 
69  // Simple checks on the LAREM cell hashes. Will use laremCells vector to
70  // obtain CaloCells goven their hashes.
71  auto front_idhash = m_calocell_id->calo_cell_hash(laremCells.front()->ID());
72  auto back_idhash = m_calocell_id->calo_cell_hash(laremCells.back()->ID());
73 
74  // LAREM cell hashes go from 0-173311. check that this is the case
75  // and thar the cells are in hash oeder to allow for indexing.
76 
77  constexpr unsigned int LAREMHASH_LO{0};
78 
79  if (front_idhash != LAREMHASH_LO) {
80  ATH_MSG_ERROR("front LARM identifier hash != 0, is " << front_idhash);
81  return StatusCode::FAILURE;
82  }
83 
84  constexpr unsigned int LAREMHASH_HI{173311};
85 
86  if (back_idhash != LAREMHASH_HI) {
87  ATH_MSG_ERROR("back LARM identifier hash != 173311, is " << back_idhash);
88  return StatusCode::FAILURE;
89  }
90 
91  if(!std::is_sorted(laremCells.begin(),
92  laremCells.end(),
93  [&cc_id=m_calocell_id](const auto& l, const auto& r) {
94  return
95  cc_id->calo_cell_hash(l->ID()) <
96  cc_id->calo_cell_hash(r->ID());
97  })){
98 
99  ATH_MSG_ERROR("LARM CaloCells are not sorted by identifier hash");
100  return StatusCode::FAILURE;
101  }
102 
103 
104  ATH_MSG_DEBUG("LAREM front, back, diff idhash v size " <<
105  front_idhash << " " <<
106  back_idhash << " " <<
107  back_idhash-front_idhash << " " <<
108  laremCells.size()
109  );
110 
111 
112  // Now select the cells in the EMB1 sampling layer from laremCells.
113  std::vector<const CaloCell*> allEMB1Cells;
114 
115  auto EMB1Selector = [&calocell_id=m_calocell_id](const auto& cell) {
116  auto ha = calocell_id->calo_cell_hash(cell->ID());
117  return calocell_id->calo_sample(ha) == CaloCell_Base_ID::EMB1;
118  };
119 
120  std::copy_if(allCaloCells.beginConstCalo(CaloCell_ID::LAREM),
121  allCaloCells.endConstCalo(CaloCell_ID::LAREM),
122  std::back_inserter(allEMB1Cells),
123  EMB1Selector);
124 
125 
127  if (!totalNoiseHdl.isValid()) {return StatusCode::FAILURE;}
128  const CaloNoise* totalNoiseCDO = *totalNoiseHdl;
129 
130 
131  // ask tool for emb1CellVecs. The length of emb1CellVecs varies according
132  // to the concrete tool. Examples: If the tool obtains all cells, then the
133  // length of calCellsVecs is 1. If the tool obtains CellCollections
134  // from clusters, then the number of vectors will be equal to the
135  // number of clusters.
136 
137  std::vector<std::vector<const CaloCell*>> emb1CellVecs;
138 
139  CHECK(m_cellsProducer->cells(emb1CellVecs, ctx));
140 
141  // check cells in the EMB1 layer
142 
143  for (const auto& cvec : emb1CellVecs) {
144  if (std::find_if_not(cvec.cbegin(),
145  cvec.cend(),
146  EMB1Selector) != cvec.cend()){
147  ATH_MSG_ERROR("cell is not in EMB1 ");
148  return StatusCode::FAILURE;
149  }
150  }
151 
152  // one seed cell per emb1Cell collection
153  std::vector<const CaloCell*> seeds(emb1CellVecs.size());
154 
155  auto signif = [&totalNoiseCDO,
156  &cut=m_seed_signifcut](const auto& c) -> float {
157  float noise = totalNoiseCDO->getNoise(c->ID(),
158  c->gain());
159  auto sfc = c->e()/noise;
160  return sfc < cut ? 0.:sfc;
161  };
162 
163  auto findSeed = [&signif](const auto& cellVec) -> const CaloCell* {
164  return *std::max_element(cellVec.cbegin(),
165  cellVec.cend(),
166  [&signif](const auto& c1,
167  const auto& c2) {
168  return signif(c1) < signif(c2);});};
169 
170 
171  for (const auto& v: emb1CellVecs) {
172  ATH_MSG_DEBUG("Looking for seed in " << v.size() << " cells");
173  }
174 
175  std::transform(emb1CellVecs.cbegin(),
176  emb1CellVecs.cend(),
177  seeds.begin(),
178  findSeed);
179 
180  std::size_t iseed{0};
181  for(const auto& seed : seeds) {
182 
183  ATH_MSG_DEBUG("seed: eta "<< seed->eta()
184  << " phi " << seed->phi()
185  << " significance "<< signif(seed)
186  );
187 
189  caloMgrHandle{m_caloMgrKey, ctx};
190 
191  ATH_CHECK(caloMgrHandle.isValid());
192  const CaloDetDescrManager* caloMgr = *caloMgrHandle;
193 
194  // run the requested algorithms
195  for (const auto& strategy : m_strategies) {
196  if (strategy == "TWINPEAKS") {
197  try {
199  laremCells,
200  allEMB1Cells,
201  iseed,
202  totalNoiseCDO,
203  caloMgr));
204  } catch (std::runtime_error& e) {
205  ATH_MSG_ERROR("Error running twin peaks - " << e.what());
206  return StatusCode::FAILURE;
207  }
208  } else if (strategy == "SORT") {
209  CHECK(sort_strategy(seed,
210  laremCells,
211  allEMB1Cells,
212  iseed,
213  totalNoiseCDO,
214  caloMgr));
215  } else if (strategy == "CRAWL") {
216  try {
217  CHECK(crawl_strategy(seed,
218  laremCells,
219  allEMB1Cells,
220  iseed,
221  totalNoiseCDO,
222  caloMgr));
223 
224  } catch (std::runtime_error& e) {
225  ATH_MSG_ERROR("Error running crawl: " << e.what());
226  return StatusCode::FAILURE;
227  }
228  } else {
229  ATH_MSG_ERROR ("Unknown pi0 strategy " << strategy);
230  return StatusCode::FAILURE;
231  }
232  }
233  ++iseed;
234  }
235  ++m_id;
236  return StatusCode::SUCCESS;
237 }
238 
239 
242  const std::vector<const CaloCell*>& laremCells,
243  const std::vector<const CaloCell*>& allEMB1Cells,
244  std::size_t iseed,
245  const CaloNoise* totalNoiseCDO,
246  const CaloDetDescrManager* caloMgr) const {
247 
248  // look for a local maximum in a neighborhood
249  // the siginicance (e/noise) of a maximum must be over a threshold
250  // (for now, set to 2.0)
251  ATH_MSG_DEBUG("twin peaks - start");
252 
253 
254  if (!seed) {return StatusCode::SUCCESS;}
255  if (allEMB1Cells.empty()) {return StatusCode::SUCCESS;}
256 
257 
258  // find the neighborhood as a collection of Identifiers
259  std::vector<const CaloCell*> neigh_cells;
260  CHECK(neighborhood(seed, laremCells, neigh_cells, caloMgr));
261 
262 
263 
264  ATH_MSG_DEBUG("twin peaks - neighborhood cells size " << neigh_cells.size()
265  << " input cell collection size " << allEMB1Cells.size());
266 
267 
268  auto signif = [&totalNoiseCDO](const auto& cell){
269  return cell->e()/totalNoiseCDO->getNoise(cell->ID(), cell->gain());
270  };
271 
272  // apply a cut on the signiificance
273  auto new_end = std::partition(neigh_cells.begin(),
274  neigh_cells.end(),
275  [&signif,
276  &signif_cut=m_tp_signifcut](const auto& ncell){
277  return signif(ncell) > signif_cut;
278  });
279 
280  neigh_cells.resize(new_end - neigh_cells.begin());
281 
282  ATH_MSG_DEBUG("twin peaks - neighborhood size after signif cut: "
283  << neigh_cells.size());
284 
285 
286  // ---------
287  // create a lambda to look for significant cells in the neighborhood
288  // which are adjacent to a choosen cell (center_cell).
289  auto is_local_max = [neigh_cells, // copy
290  &cc_id=m_calocell_id,
291  &signif](const auto& center_cell) mutable {
292 
293  // obtain the hashes of the cells adjacent to center_cell.
294  // some of these will be in the neighborhood. For cells
295  // at the edge of the neighborhood, there may be
296  // adjacent cells not in the neighborhood. For now,
297  // such extra-neighborhood cells will be ignored.
298 
299  std::vector<IdentifierHash> adj_hashes;
300  auto rc = cc_id->get_neighbours(cc_id->calo_cell_hash(center_cell->ID()),
302  adj_hashes);
303  if (rc != 0) {
304  throw std::runtime_error("twin peaks - error obtaining cell neighbors");
305  }
306 
307  // obtain the identifiers of cells immediately adjacent to center_cell
308  std::vector<Identifier> adj_idents;;
309  std::transform(adj_hashes.cbegin(),
310  adj_hashes.cend(),
311  std::back_inserter(adj_idents),
312  [&cc_id](const auto& hash){
313  return cc_id->cell_id(hash);
314  });
315 
316  // obtain neighborhood cells immediately adjacent to center_cell
317 
318  auto id_cell_match = [&adj_idents](const CaloCell* n_cell)->bool {
319  return std::find(adj_idents.begin(),
320  adj_idents.end(),
321  n_cell->ID()) != adj_idents.end();};
322 
323  auto adj_neigh_cell_end = std::partition(neigh_cells.begin(),
324  neigh_cells.end(),
325  id_cell_match);
326 
327  for (auto iter = neigh_cells.begin();
328  iter != adj_neigh_cell_end;
329  ++iter) {
330  if (signif(*iter) > signif(center_cell)) {return false;}
331  }
332 
333  return true;
334  };
335 
336 
337  auto peaks_end = std::partition(neigh_cells.begin(),
338  neigh_cells.end(),
339  is_local_max);
340 
341 
342  auto n_peaks = peaks_end - neigh_cells.begin();
343  ATH_MSG_DEBUG("twin peaks - number of local maxima " << n_peaks);
344 
345  auto n_peaks_noseed = n_peaks;
346  if (std::find(neigh_cells.begin(), peaks_end, seed) != peaks_end){--n_peaks_noseed;}
347  ATH_MSG_DEBUG("twin peaks - number of local maxima ommiting seed " << n_peaks_noseed);
348 
349  ATH_MSG_DEBUG("twin peaks - seed eta " << seed->eta()
350  << " phi " << seed->phi()
351  << " signif " <<signif(seed));
352  for (auto iter = neigh_cells.begin(); iter != peaks_end; ++iter) {
353  ATH_MSG_DEBUG(" twin peaks - peak eta " << (*iter)->eta()
354  << " phi " << (*iter)->phi()
355  << " signif " <<signif(*iter));
356 
357  ATH_MSG_DEBUG(" twin peaks - distance from seed deta "
358  << seed->eta() - (*iter)->eta() << " dphi "
359  << seed->phi() - (*iter)->phi());
360  }
361 
362  ATH_MSG_DEBUG("twin peaks: neighborhood size after signif cut "
363  << neigh_cells.size());
364 
365 
366  for (const auto& c: neigh_cells) {
367  if (!c) {throw std::runtime_error("Neighbor pointer is nullptr");}
368 
369 
370  ATH_MSG_DEBUG("twin peaks - neigh cell eta " << c->eta()
371  << " phi " << c->phi()
372  << " signif " << signif(c));
373  }
374 
375 
376 
377  if (m_dump) {
378 
379  std::vector<const CaloCell*> peaks_cells(neigh_cells.begin(), peaks_end);
380 
381  std::vector<double> peaks_signif;
382  std::transform(neigh_cells.begin(),
383  peaks_end,
384  std::back_inserter(peaks_signif),
385  signif);
386 
387  CHECK(dump_twinpeaks(iseed,
388  seed,
389  signif(seed),
390  neigh_cells,
391  peaks_cells,
392  peaks_signif));
393  }
394 
395  ATH_MSG_DEBUG("twin peaks - finished");
396 
397  return StatusCode::SUCCESS;
398 }
399 
400 
403  const std::vector<const CaloCell*>& laremCells,
404  const std::vector<const CaloCell*>& allEMB1Cells,
405  std::size_t iseed,
406  const CaloNoise*,
407  const CaloDetDescrManager* caloMgr) const {
408 
409  if (!seed) {return StatusCode::SUCCESS;}
410  if (allEMB1Cells.empty()) {return StatusCode::SUCCESS;}
411 
412  std::vector<const CaloCell*> neigh_cells;
413  CHECK(neighborhood(seed, laremCells, neigh_cells, caloMgr));
414 
415  ATH_MSG_DEBUG("sort_strategy seed idx " << iseed <<
416  "nbhd size :" << neigh_cells.size());
417 
418 
419  return StatusCode::SUCCESS;
420 }
421 
424  const std::vector<const CaloCell*>& laremCells,
425  const std::vector<const CaloCell*>& allEMB1Cells,
426  std::size_t iseed,
427  const CaloNoise* totalNoiseCDO,
428  const CaloDetDescrManager* caloMgr) const {
429 
430  if (!seed) {return StatusCode::SUCCESS;}
431  if (allEMB1Cells.empty()) {return StatusCode::SUCCESS;}
432 
433 
434  // path_str is a string composed of '0' and '1' characters.
435  // '0' indicates an energy decreases
436  // '1' indicates the energy increases along the path.
437 
438  // a path is calculated for a number of contiguous eta steps.
439  // for each eta value, a path is formed in the two phi directions.
440  //
441  // The first step is to determine the CaloCell hashes along
442  // the paths, starting from the location of the seed cell.
443 
444  ATH_MSG_DEBUG("crawl: start");
445  ATH_MSG_DEBUG("crawl - seed eta " << seed->eta()
446  << " phi " << seed->phi());
447 
448  std::vector<std::string> paths(2*m_er_neta +1);
449 
450  auto seed_hash = m_calocell_id->calo_cell_hash(seed->ID());
451 
452  std::vector<IdentifierHash> phi_starts;
453 
454  // start point for +- phi paths about the seed eta value
455  phi_starts.push_back(seed_hash);
456 
457 
458  std::vector<LArNeighbours::neighbourOption>
460 
461  // start point for +- phi paths above and below the seed eta
462 
463  for (const auto& dir : dirs) {
464  auto cur_hash = seed_hash;
465  for (int i = 0; i < m_er_neta; ++i){
466  std::vector<IdentifierHash> v_adj;
467  int rc = m_calocell_id->get_neighbours(cur_hash,
468  dir,
469  v_adj);
470  if (rc != 0) {break;} // out of bounds
471 
472  if (v_adj.size() != 1) {
473  // this happens when the the cells no longer form an regular
474  // array. Emprically: at around eta = +- 1.4, the phi spacing
475  // becomes small.
476  // The eta of these cells are almost, but not exactly the same.
477  // The get_neighbours returns multiple cell identifiers in this case.
478  //
479  // When this happens, issue a warning, and break of search in this
480  // eta direction for cells to start the phi crawl.
481  for (const auto& ha : v_adj) {
482  const auto *dde = caloMgr->get_element(m_calocell_id->cell_id(ha));
483  ATH_MSG_DEBUG("cell eta " << dde-> eta() << " phi " << dde->phi() <<
484  " z " << dde->z());
485  }
486  ATH_MSG_WARNING("unexpected number of identifier hashes: "
487  << v_adj.size());
488 
489  break;
490  }
491 
492  cur_hash = v_adj[0];
493  phi_starts.push_back(cur_hash);
494  }
495  }
496 
497  ATH_MSG_DEBUG("crawl - number of 1-dim path start points "
498  << phi_starts.size());
499  for (const auto& h: phi_starts) {
500  auto eta = caloMgr->get_element(m_calocell_id->cell_id(h))->eta();
501  ATH_MSG_DEBUG ("crawl - starting etas " << h << " eta " << eta);
502  }
503 
504  std::vector<std::vector<IdentifierHash>> paths_hash;
507 
508  for (const auto& dir : dirs){
509 
510  auto calc_phihashes = [&dir,
511  &cc_id=m_calocell_id,
512  nphi=m_er_nphi](auto hash){ //hash: pass by value
513  std::vector<IdentifierHash> path;
514  std::vector<IdentifierHash> adjacent;
515  path.push_back(hash);
516  for (int i = 0; i<nphi; ++i) {
517 
518  int rc = cc_id->get_neighbours(hash, dir, adjacent);
519  if (rc != 0) {break;} // out of bounds
520  auto size = adjacent.size();
521  if (size != 1) {
522  throw std::runtime_error("unexpected number of identifier hashes: " + std::to_string(size));
523  }
524 
525  hash = adjacent[0];
526  path.push_back(hash);
527 
528  }
529  return path;
530  };
531 
532  std::transform(phi_starts.cbegin(),
533  phi_starts.cend(),
534  std::back_inserter(paths_hash),
535  calc_phihashes);
536  };
537 
538  ATH_MSG_DEBUG("crawl - number of 1-dim paths (hashes) "
539  << paths_hash.size());
540 
541  // step 2 - obtain the paths in terms of CaloCells
542  // std::vector<std::vector<const CaloCell*>> paths_cell;
543  CellVectors paths_cell;
544  paths_cell.reserve(paths_hash.size());
545 
546 
547  for (const auto& p_h : paths_hash) {
548  std::vector<const CaloCell*> path;
549  path.reserve(p_h.size());
550  std::transform(p_h.cbegin(), p_h.cend(),
551  std::back_inserter(path),
552  [&laremCells](const auto& hash){
553  return laremCells.at(hash);});
554  paths_cell.push_back(path);
555  }
556 
557 
558 
559  // now have paths of cells.
560  // step 3: create strings of energy up-down patterns
561 
562 
563  auto signif = [&totalNoiseCDO,
564  &signif_min = m_crawl_signifcut](const auto& cell){
565  auto e = cell->e();
566  if (e <= 0){return 0.;}
567  auto signif = cell->e()/totalNoiseCDO->getNoise(cell->ID(), cell->gain());
568  return signif < signif_min ? 0:signif;
569  };
570 
571 
572  // std::vector<std::vector<float>> paths_signif;
573  PathsSignif paths_signif;
574  paths_signif.reserve(paths_cell.size());
575 
576  // should probably set signif to 0 if below a threhold (eg 2.)
577  for (const auto& p_c : paths_cell) {
578  std::vector<float> path_signif;
579  std::transform(p_c.cbegin(),
580  p_c.cend(),
581  std::back_inserter(path_signif),
582  signif);
583  paths_signif.push_back(path_signif);
584  }
585 
586  for (const auto& p_s: paths_signif) {
587  std::stringstream ss;
588  ss <<"crawl - path signf ";
589  for (const auto& s : p_s) {
590  ss << std::setw(7) << std::setprecision(3)<< s << " ";
591  }
592  ATH_MSG_DEBUG (ss.str());
593  }
594 
595 
596  std::vector<std::string> paths_pat;
597  paths_signif.reserve(paths_signif.size());
598 
599  for (const auto& p_s: paths_signif) {
600  std::string pat{"0"}; // padding to keep the string size as path size
601  if (!p_s.empty()) {
602  for (std::size_t i = 1; i != p_s.size(); ++i) {
603  if (p_s[i] > p_s[i-1]) {
604  pat += '1';
605  } else {
606  pat += '0';
607  }
608  }
609 
610  paths_pat.push_back(pat);
611  }
612  }
613 
614 
615  ATH_MSG_DEBUG("crawl - no of patterns " << paths_pat.size());
616 
617  for(const auto& p: paths_pat) {ATH_MSG_DEBUG("crawl - pattern " << p);}
618 
619  std::vector<std::regex> peaks_re{
620  std::regex("01*(1)0"), std::regex("01*(1)$")};
621 
622  std::vector<const CaloCell*> peak_cells;
623  std::size_t idx{0};
624 
625  for (const auto& s : paths_pat) {
626 
627  for (const auto& regex : peaks_re) {
628  std::smatch m;
629  if(std::regex_search(s, m, regex)){
630  auto pos = m.position(1);
631  ATH_MSG_DEBUG("crawl - match at idx " << idx << " pos " << pos);
632  peak_cells.push_back(paths_cell[idx][pos]);
633  break;
634  }
635  }
636  ++idx;
637  }
638 
639 
640  auto n_peaks = peak_cells.size();
641  ATH_MSG_DEBUG("crawl - number of local maxima " << n_peaks);
642  ATH_MSG_DEBUG("crawl - seed eta " << seed->eta()
643  << " phi " << seed->phi()
644  << " signif " <<signif(seed));
645  for (const auto& pc : peak_cells){
646  ATH_MSG_DEBUG(" crawl - peak eta " << pc->eta()
647  << " phi " << pc->phi()
648  << " signif " <<signif(pc));
649 
650  ATH_MSG_DEBUG(" crawl - distance from seed deta "
651  << seed->eta() - pc->eta() << " dphi "
652  << seed->phi() - pc->phi());
653  }
654 
655  if (m_dump) {CHECK(dump_crawl(iseed,
656  seed,
657  signif(seed),
658  paths_cell,
659  paths_signif,
660  paths_pat));}
661 
662  ATH_MSG_DEBUG("crawl: finished");
663 
664  return StatusCode::SUCCESS;
665 }
666 
669  const CaloCell* seed,
670  float seed_signif,
671  const CellVectors& paths_cell,
672  const std::vector<std::vector<float>>& signifs,
673  const std::vector<std::string>& paths_pat) const {
674  std::stringstream ss;
675  ss << "crawl. cell source " << i << '\n';
676  ss << "seed " << seed->eta() << " " << seed->phi() << " "
677  << seed->e() << " " << seed_signif << '\n';
678  ss << "path etas:\n";
679  for (const auto& path: paths_cell) {
680  for (const auto& c : path){
681  ss << c->eta() << " ";
682  }
683  ss << '\n';
684  }
685  ss << "path phis:\n";
686  for (const auto& path: paths_cell) {
687  for (const auto& c : path){
688  ss << c->phi() << " ";
689  }
690  ss << '\n';
691  }
692 
693  ss << "path es:\n";
694  for (const auto& path: paths_cell) {
695  for (const auto& c : path){
696  ss << c->e() << " ";
697  }
698  ss << '\n';
699  }
700 
701  ss << "path signifs:\n";
702  for (const auto& path: signifs) {
703  for (const auto& sig : path){
704  ss << sig << " ";
705  }
706  ss << '\n';
707  }
708 
709  ss << "path patterns:\n";
710  for (const auto& pat: paths_pat) {
711  ss << pat << '\n';
712  }
713 
714 
715  std::stringstream fn;
716  fn << "crawl_" << m_id << "_" << i << ".txt";
717  std::ofstream out(fn.str());
718  out << ss.str();
719 
720  return StatusCode::SUCCESS;
721 }
722 
723 
726  const CaloCell* seed,
727  double seed_signif,
728  const std::vector<const CaloCell*>& neighborhood,
729  const std::vector<const CaloCell*>& peaks,
730  const std::vector<double>& peak_signifs) const {
731  std::stringstream ss;
732  ss << "twinpeaks. cell source " << i << '\n';
733  ss << "seed " << seed->eta() << " " << seed->phi() << " "
734  << seed->e() << " " << seed_signif << '\n';
735  ss << "neighborhood etas:\n";
736  for (const auto& c: neighborhood) {
737  ss << c->eta() << " ";
738  }
739  ss << '\n';
740 
741  ss << "neighborhood phis:\n";
742  for (const auto& c : neighborhood){
743  ss << c->phi() << " ";
744  }
745  ss << '\n';
746 
747  ss << "neighborhood es:\n";
748  for (const auto& c : neighborhood){
749  ss << c->e() << " ";
750  }
751  ss << '\n';
752 
753  ss << "peak etas:\n";
754  for (const auto& c : peaks){
755  ss << c->eta() << " ";
756  }
757  ss << '\n';
758 
759  ss << "peak phis:\n";
760  for (const auto& c : peaks){
761  ss << c->phi() << " ";
762  }
763  ss << '\n';
764 
765  ss << "peak es:\n";
766  for (const auto& c : peaks){
767  ss << c->e() << " ";
768  }
769  ss << '\n';
770 
771 
772  ss << "peak signifs:\n";
773  for (const auto& s : peak_signifs){
774  ss << s << " ";
775  }
776  ss << '\n';
777 
778  std::stringstream fn;
779  fn << "twinpeak_" << m_id << "_" << i << ".txt";
780  std::ofstream out(fn.str());
781  out << ss.str();
782 
783  return StatusCode::SUCCESS;
784 }
785 
786 
787 
790  const std::vector<const CaloCell*>& laremCells,
791  std::vector<const CaloCell*>& neigh_cells,
792  const CaloDetDescrManager* caloMgr) const {
793 
794  // find the cells in the neighborhood od a seed cell. The neighborhood
795  // cells are those within a Euclidean distance in eta-phi of the seed.
796  // The algorithm works by iteratively finding immediately adjacent cells
797  // to cells already established as being in the neighborhood. If these
798  // cells are within range, they are added to the neighborhood
799 
800  auto seedID = seed->ID();
801 
802  auto seed_eta = seed->eta();
803  auto seed_phi = seed->phi();
804 
805  std::queue<Identifier> to_process;
806  to_process.push(seedID);
807 
808  auto accept = [&seed_eta, &seed_phi,
809  &calocell_id=m_calocell_id,
810  &neigh_half_eta = m_neigh_half_eta,
811  &neigh_half_phi = m_neigh_half_phi,
812  &caloMgr](const auto& c_id){
813  auto dde = caloMgr->get_element(c_id);
814  auto c_eta = dde->eta();
815  auto c_phi = dde->phi();
816 
817  auto hash = calocell_id->calo_cell_hash(c_id);
818  if (calocell_id->calo_sample(hash) != CaloCell_Base_ID::EMB1) {return false;}
819 
820  auto deta = seed_eta-c_eta;
821  if( std::abs(deta) > neigh_half_eta) {return false;}
822 
823  auto dphi = seed_phi-c_phi;
824  return std::abs(dphi) < neigh_half_phi;
825 
826  };
827 
828  std::vector<Identifier> mask;
829  auto add_neighbors_to_queue = [&to_process,
830  &cc_id=m_calocell_id,
831  &mask] (const auto& desc) {
832  auto hash = cc_id->calo_cell_hash(desc);
833  std::vector<IdentifierHash> neigh_hashes;
834  int rc = cc_id->get_neighbours(hash,
836  neigh_hashes);
837  if (rc != 0) {
838  return StatusCode::FAILURE;
839  }
840 
841  for (const auto& nh :neigh_hashes) {
842  auto cid = cc_id->cell_id(nh);
843  if (std::find(mask.cbegin(), mask.cend(), cid) == mask.cend()) {
844  mask.push_back(cid);
845  to_process.push(cc_id->cell_id(nh));
846  }
847  }
848  return StatusCode::SUCCESS;
849 
850  };
851 
852  CHECK(add_neighbors_to_queue(seedID));
853  std::vector<Identifier> neigh_idents;
854 
855  // iterative procedure:
856  while (!to_process.empty()){
857  const auto& ident = to_process.front();
858  if (accept(ident)){
859  ATH_MSG_DEBUG (" accepting neigh " << ident);
860  const auto *dde = caloMgr->get_element(ident);
861  auto c_eta = dde->eta();
862  auto c_phi = dde->phi();
863  ATH_MSG_DEBUG(" neigh eta: " << c_eta
864  << " phi " << c_phi);
865  neigh_idents.push_back(ident);
866  add_neighbors_to_queue(ident);
867  }
868  to_process.pop();
869  }
870 
871  std::sort(neigh_idents.begin(), neigh_idents.end());
872  auto end = std::unique(neigh_idents.begin(), neigh_idents.end());
873  auto it{neigh_idents.begin()};
874 
875  for(;it!= end; ++it){
876  neigh_cells.push_back(laremCells.at(m_calocell_id->calo_cell_hash(*it)));
877  }
878  return StatusCode::SUCCESS;
879 }
GepPi0Alg::execute
virtual StatusCode execute(const EventContext &) const override
Definition: GepPi0Alg.cxx:40
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::strategy
strategy
Definition: L2CombinedMuon_v1.cxx:107
beamspotman.r
def r
Definition: beamspotman.py:676
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
CaloCell_Base_ID::calo_cell_hash
IdentifierHash calo_cell_hash(const Identifier cellId) const
create hash id from 'global' cell id
constants.EMB1
int EMB1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:53
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:126
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
GepPi0Alg::m_cellsProducer
ToolHandle< ICaloCellsProducer > m_cellsProducer
Definition: GepPi0Alg.h:64
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
GepPi0Alg::m_seed_signifcut
Gaudi::Property< float > m_seed_signifcut
Definition: GepPi0Alg.h:108
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
CutsMETMaker::accept
StatusCode accept(const xAOD::Muon *mu)
Definition: CutsMETMaker.cxx:18
extractSporadic.c1
c1
Definition: extractSporadic.py:134
CaloDetDescrManager_Base::get_element
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
Definition: CaloDetDescrManager.cxx:159
GepPi0Alg::neighborhood
StatusCode neighborhood(const CaloCell *, const std::vector< const CaloCell * > &laremCells, std::vector< const CaloCell * > &neighs, const CaloDetDescrManager *) const
Definition: GepPi0Alg.cxx:789
skel.it
it
Definition: skel.GENtoEVGEN.py:423
InDet::adjacent
bool adjacent(unsigned int strip1, unsigned int strip2)
Definition: SCT_ClusteringTool.cxx:45
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
GepPi0Alg::twinpeaks_strategy
StatusCode twinpeaks_strategy(const CaloCell *seed, const std::vector< const CaloCell * > &laremCells, const std::vector< const CaloCell * > &emb1Cells, std::size_t iseed, const CaloNoise *, const CaloDetDescrManager *) const
Definition: GepPi0Alg.cxx:241
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
GepPi0Alg::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Definition: GepPi0Alg.h:81
CaloNoise::getNoise
float getNoise(const IdentifierHash h, const int gain) const
Accessor by IdentifierHash and gain.
Definition: CaloNoise.h:34
LArNeighbours::prevInPhi
@ prevInPhi
Definition: LArNeighbours.h:12
GepPi0Alg::m_er_neta
Gaudi::Property< int > m_er_neta
Definition: GepPi0Alg.h:119
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
GepPi0Alg::PathsSignif
std::vector< std::vector< float > > PathsSignif
Definition: GepPi0Alg.h:46
GepPi0Alg::m_totalNoiseKey
SG::ReadCondHandleKey< CaloNoise > m_totalNoiseKey
Definition: GepPi0Alg.h:71
GepPi0Alg::dump_crawl
StatusCode dump_crawl(std::size_t iseed, const CaloCell *seed, float seed_signif, const CellVectors &, const PathsSignif &, const std::vector< std::string > &paths_pat) const
Definition: GepPi0Alg.cxx:668
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:270
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
LArNeighbours::nextInPhi
@ nextInPhi
Definition: LArNeighbours.h:13
GepPi0Alg::initialize
virtual StatusCode initialize() override
Definition: GepPi0Alg.cxx:25
python.getCurrentFolderTag.fn
fn
Definition: getCurrentFolderTag.py:65
CaloCondBlobAlgs_fillNoiseFromASCII.desc
desc
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:54
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:92
GepPi0Alg::m_dump
Gaudi::Property< bool > m_dump
Definition: GepPi0Alg.h:126
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
GepPi0Alg::m_allCaloCellsKey
SG::ReadHandleKey< CaloCellContainer > m_allCaloCellsKey
Definition: GepPi0Alg.h:60
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
BindingsTest.cut
cut
This script demonstrates how to call a C++ class from Python Also how to use PyROOT is shown.
Definition: BindingsTest.py:13
GepPi0Alg.h
python.BuildSignatureFlags.sig
sig
Definition: BuildSignatureFlags.py:215
AnalysisUtils::copy_if
Out copy_if(In first, const In &last, Out res, const Pred &p)
Definition: IFilterUtils.h:30
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
GepPi0Alg::m_tp_signifcut
Gaudi::Property< float > m_tp_signifcut
Definition: GepPi0Alg.h:113
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
GepPi0Alg::m_calocell_id
const CaloCell_ID * m_calocell_id
Definition: GepPi0Alg.h:77
GepPi0Alg::m_crawl_signifcut
Gaudi::Property< float > m_crawl_signifcut
Definition: GepPi0Alg.h:116
beamspotman.dir
string dir
Definition: beamspotman.py:623
GepPi0Alg::GepPi0Alg
GepPi0Alg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: GepPi0Alg.cxx:20
CaloNoise
Definition: CaloNoise.h:16
dso-stats.pat
pat
Definition: dso-stats.py:39
ReadCellNoiseFromCool.ncell
ncell
Definition: ReadCellNoiseFromCool.py:197
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
compileRPVLLRates.c2
c2
Definition: compileRPVLLRates.py:361
CaloCell_Base_ID::get_neighbours
int get_neighbours(const IdentifierHash caloHash, const LArNeighbours::neighbourOption &option, std::vector< IdentifierHash > &neighbourList) const
access to hashes for neighbours return == 0 for neighbours found
Definition: CaloCell_Base_ID.cxx:190
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
dirs
std::map< std::string, int > dirs
list of directories to be explicitly included, together with corresponding depths of subdirectories
Definition: hcg.cxx:99
TRT::Hit::ident
@ ident
Definition: HitInfo.h:77
CaloCell_Base_ID::cell_id
Identifier cell_id(const int subCalo, const int barec_or_posneg, const int sampling_or_fcalmodule, const int region_or_dummy, const int eta, const int phi) const
Make a cell (== channel) ID from constituting fields and subCalo index; for (Mini)FCAL,...
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
python.PyAthena.v
v
Definition: PyAthena.py:157
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
h
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
BindingsTest.ha
ha
Definition: BindingsTest.py:22
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
LArNeighbours::nextInEta
@ nextInEta
Definition: LArNeighbours.h:15
StateLessPT_NewConfig.partition
partition
Definition: StateLessPT_NewConfig.py:49
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
CaloDetDescrElement::eta
float eta() const
cell eta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:344
LArNeighbours::prevInEta
@ prevInEta
Definition: LArNeighbours.h:14
GepPi0Alg::sort_strategy
StatusCode sort_strategy(const CaloCell *seed, const std::vector< const CaloCell * > &laremCells, const std::vector< const CaloCell * > &emb1Cells, std::size_t iseed, const CaloNoise *, const CaloDetDescrManager *) const
Definition: GepPi0Alg.cxx:402
GepPi0Alg::CellVectors
std::vector< std::vector< const CaloCell * > > CellVectors
Definition: GepPi0Alg.h:45
GepPi0Alg::m_neigh_half_eta
Gaudi::Property< float > m_neigh_half_eta
Definition: GepPi0Alg.h:88
GepPi0Alg::m_strategies
Gaudi::Property< std::vector< std::string > > m_strategies
Definition: GepPi0Alg.h:101
GepPi0Alg::m_er_nphi
Gaudi::Property< int > m_er_nphi
Definition: GepPi0Alg.h:122
CaloCell_Base_ID::LAREM
@ LAREM
Definition: CaloCell_Base_ID.h:46
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
GepPi0Alg::crawl_strategy
StatusCode crawl_strategy(const CaloCell *seed, const std::vector< const CaloCell * > &laremCells, const std::vector< const CaloCell * > &emb1Cells, std::size_t iseed, const CaloNoise *, const CaloDetDescrManager *) const
Definition: GepPi0Alg.cxx:423
GepPi0Alg::m_neigh_half_phi
Gaudi::Property< float > m_neigh_half_phi
Definition: GepPi0Alg.h:94
python.compressB64.c
def c
Definition: compressB64.py:93
GepPi0Alg::dump_twinpeaks
StatusCode dump_twinpeaks(std::size_t iseed, const CaloCell *seed, double seed_signif, const std::vector< const CaloCell * > &neighborhood, const std::vector< const CaloCell * > &peaks, const std::vector< double > &peak_signifs) const
Definition: GepPi0Alg.cxx:725
python.SystemOfUnits.pc
float pc
Definition: SystemOfUnits.py:99
LArNeighbours::all2D
@ all2D
Definition: LArNeighbours.h:18
WriteCellNoiseToCool.noise
noise
Definition: WriteCellNoiseToCool.py:380
test_athena_ntuple_dumper.paths
paths
Definition: test_athena_ntuple_dumper.py:7
GepPi0Alg::m_id
std::atomic< size_t > m_id
Definition: GepPi0Alg.h:57