36 return StatusCode::SUCCESS;
48 CHECK(h_allCaloCells.isValid());
50 const auto & allCaloCells = *h_allCaloCells;
56 ATH_MSG_ERROR(
"CaloCellCollection does not contain LAREM cells");
57 return StatusCode::FAILURE;
62 ATH_MSG_DEBUG (
"Size from SubCalo Iters " << std::distance(cellbegin,
65 std::vector<const CaloCell*>
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());
77 constexpr unsigned int LAREMHASH_LO{0};
79 if (front_idhash != LAREMHASH_LO) {
80 ATH_MSG_ERROR(
"front LARM identifier hash != 0, is " << front_idhash);
81 return StatusCode::FAILURE;
84 constexpr unsigned int LAREMHASH_HI{173311};
86 if (back_idhash != LAREMHASH_HI) {
87 ATH_MSG_ERROR(
"back LARM identifier hash != 173311, is " << back_idhash);
88 return StatusCode::FAILURE;
91 if(!std::is_sorted(laremCells.begin(),
95 cc_id->calo_cell_hash(l->ID()) <
96 cc_id->calo_cell_hash(r->ID());
99 ATH_MSG_ERROR(
"LARM CaloCells are not sorted by identifier hash");
100 return StatusCode::FAILURE;
105 front_idhash <<
" " <<
106 back_idhash <<
" " <<
107 back_idhash-front_idhash <<
" " <<
113 std::vector<const CaloCell*> allEMB1Cells;
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;
122 std::back_inserter(allEMB1Cells),
127 if (!totalNoiseHdl.
isValid()) {
return StatusCode::FAILURE;}
128 const CaloNoise* totalNoiseCDO = *totalNoiseHdl;
137 std::vector<std::vector<const CaloCell*>> emb1CellVecs;
143 for (
const auto& cvec : emb1CellVecs) {
144 if (std::find_if_not(cvec.cbegin(),
146 EMB1Selector) != cvec.cend()){
148 return StatusCode::FAILURE;
153 std::vector<const CaloCell*> seeds(emb1CellVecs.size());
155 auto signif = [&totalNoiseCDO,
157 float noise = totalNoiseCDO->
getNoise(c->ID(),
159 auto sfc = c->e()/noise;
160 return sfc < cut ? 0.:sfc;
163 auto findSeed = [&signif](
const auto& cellVec) ->
const CaloCell* {
164 return *std::max_element(cellVec.cbegin(),
166 [&signif](
const auto& c1,
168 return signif(c1) < signif(c2);});};
171 for (
const auto& v: emb1CellVecs) {
172 ATH_MSG_DEBUG(
"Looking for seed in " << v.size() <<
" cells");
175 std::transform(emb1CellVecs.cbegin(),
180 std::size_t iseed{0};
181 for(
const auto& seed : seeds) {
184 <<
" phi " << seed->phi()
185 <<
" significance "<< signif(seed)
196 if (strategy ==
"TWINPEAKS") {
204 }
catch (std::runtime_error& e) {
206 return StatusCode::FAILURE;
208 }
else if (strategy ==
"SORT") {
215 }
else if (strategy ==
"CRAWL") {
224 }
catch (std::runtime_error& e) {
226 return StatusCode::FAILURE;
230 return StatusCode::FAILURE;
236 return StatusCode::SUCCESS;
242 const std::vector<const CaloCell*>& laremCells,
243 const std::vector<const CaloCell*>& allEMB1Cells,
254 if (!seed) {
return StatusCode::SUCCESS;}
255 if (allEMB1Cells.empty()) {
return StatusCode::SUCCESS;}
259 std::vector<const CaloCell*> neigh_cells;
264 ATH_MSG_DEBUG(
"twin peaks - neighborhood cells size " << neigh_cells.size()
265 <<
" input cell collection size " << allEMB1Cells.size());
268 auto signif = [&totalNoiseCDO](
const auto& cell){
269 return cell->e()/totalNoiseCDO->
getNoise(cell->ID(), cell->gain());
277 return signif(ncell) > signif_cut;
280 neigh_cells.resize(new_end - neigh_cells.begin());
282 ATH_MSG_DEBUG(
"twin peaks - neighborhood size after signif cut: "
283 << neigh_cells.size());
289 auto is_local_max = [neigh_cells,
291 &signif](
const auto& center_cell)
mutable {
299 std::vector<IdentifierHash> adj_hashes;
300 auto rc = cc_id->get_neighbours(cc_id->calo_cell_hash(center_cell->ID()),
304 throw std::runtime_error(
"twin peaks - error obtaining cell neighbors");
308 std::vector<Identifier> adj_idents;;
309 std::transform(adj_hashes.cbegin(),
311 std::back_inserter(adj_idents),
312 [&cc_id](
const auto& hash){
313 return cc_id->cell_id(hash);
318 auto id_cell_match = [&adj_idents](
const CaloCell* n_cell)->
bool {
319 return std::find(adj_idents.begin(),
321 n_cell->ID()) != adj_idents.end();};
327 for (
auto iter = neigh_cells.begin();
328 iter != adj_neigh_cell_end;
330 if (signif(*iter) > signif(center_cell)) {
return false;}
339 std::move(is_local_max));
342 auto n_peaks = peaks_end - neigh_cells.begin();
343 ATH_MSG_DEBUG(
"twin peaks - number of local maxima " << n_peaks);
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);
350 <<
" phi " << seed->phi()
351 <<
" signif " <<signif(seed));
352 for (
auto iter = neigh_cells.begin(); iter != peaks_end; ++iter) {
354 <<
" phi " << (*iter)->phi()
355 <<
" signif " <<signif(*iter));
358 << seed->eta() - (*iter)->eta() <<
" dphi "
359 << seed->phi() - (*iter)->phi());
362 ATH_MSG_DEBUG(
"twin peaks: neighborhood size after signif cut "
363 << neigh_cells.size());
366 for (
const auto& c: neigh_cells) {
367 if (!c) {
throw std::runtime_error(
"Neighbor pointer is nullptr");}
371 <<
" phi " << c->phi()
372 <<
" signif " << signif(c));
379 std::vector<const CaloCell*> peaks_cells(neigh_cells.begin(), peaks_end);
381 std::vector<double> peaks_signif;
382 std::transform(neigh_cells.begin(),
384 std::back_inserter(peaks_signif),
397 return StatusCode::SUCCESS;
403 const std::vector<const CaloCell*>& laremCells,
404 const std::vector<const CaloCell*>& allEMB1Cells,
409 if (!seed) {
return StatusCode::SUCCESS;}
410 if (allEMB1Cells.empty()) {
return StatusCode::SUCCESS;}
412 std::vector<const CaloCell*> neigh_cells;
416 "nbhd size :" << neigh_cells.size());
419 return StatusCode::SUCCESS;
424 const std::vector<const CaloCell*>& laremCells,
425 const std::vector<const CaloCell*>& allEMB1Cells,
430 if (!seed) {
return StatusCode::SUCCESS;}
431 if (allEMB1Cells.empty()) {
return StatusCode::SUCCESS;}
446 <<
" phi " << seed->phi());
448 std::vector<std::string> paths(2*
m_er_neta +1);
452 std::vector<IdentifierHash> phi_starts;
455 phi_starts.push_back(seed_hash);
458 std::vector<LArNeighbours::neighbourOption>
463 for (
const auto& dir :
dirs) {
464 auto cur_hash = seed_hash;
466 std::vector<IdentifierHash> v_adj;
470 if (
rc != 0) {
break;}
472 if (v_adj.size() != 1) {
481 for (
const auto& ha : v_adj) {
493 phi_starts.push_back(cur_hash);
498 << phi_starts.size());
499 for (
const auto&
h: phi_starts) {
504 std::vector<std::vector<IdentifierHash>> paths_hash;
508 for (
const auto& dir :
dirs){
510 auto calc_phihashes = [&dir,
513 std::vector<IdentifierHash> path;
514 std::vector<IdentifierHash> adjacent;
515 path.push_back(hash);
516 for (
int i = 0; i<nphi; ++i) {
518 int rc = cc_id->get_neighbours(hash, dir, adjacent);
519 if (
rc != 0) {
break;}
520 auto size = adjacent.size();
522 throw std::runtime_error(
"unexpected number of identifier hashes: " + std::to_string(size));
526 path.push_back(hash);
532 std::transform(phi_starts.cbegin(),
534 std::back_inserter(paths_hash),
535 std::move(calc_phihashes));
539 << paths_hash.size());
544 paths_cell.reserve(paths_hash.size());
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(std::move(path));
563 auto signif = [&totalNoiseCDO,
566 if (e <= 0){
return 0.;}
567 auto signif = cell->e()/totalNoiseCDO->
getNoise(cell->ID(), cell->gain());
568 return signif < signif_min ? 0:signif;
574 paths_signif.reserve(paths_cell.size());
577 for (
const auto& p_c : paths_cell) {
578 std::vector<float> path_signif;
579 std::transform(p_c.cbegin(),
581 std::back_inserter(path_signif),
583 paths_signif.push_back(std::move(path_signif));
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 <<
" ";
596 std::vector<std::string> paths_pat;
597 paths_signif.reserve(paths_signif.size());
599 for (
const auto& p_s: paths_signif) {
600 std::string pat{
"0"};
602 for (std::size_t i = 1; i != p_s.size(); ++i) {
603 if (p_s[i] > p_s[i-1]) {
610 paths_pat.push_back(std::move(pat));
615 ATH_MSG_DEBUG(
"crawl - no of patterns " << paths_pat.size());
617 for(
const auto& p: paths_pat) {
ATH_MSG_DEBUG(
"crawl - pattern " << p);}
619 std::vector<std::regex> peaks_re{
620 std::regex(
"01*(1)0"), std::regex(
"01*(1)$")};
622 std::vector<const CaloCell*> peak_cells;
625 for (
const auto& s : paths_pat) {
627 for (
const auto& regex : peaks_re) {
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]);
640 auto n_peaks = peak_cells.size();
643 <<
" phi " << seed->phi()
644 <<
" signif " <<signif(seed));
645 for (
const auto& pc : peak_cells){
647 <<
" phi " << pc->phi()
648 <<
" signif " <<signif(pc));
651 << seed->eta() - pc->eta() <<
" dphi "
652 << seed->phi() - pc->phi());
664 return StatusCode::SUCCESS;
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() <<
" ";
685 ss <<
"path phis:\n";
686 for (
const auto& path: paths_cell) {
687 for (
const auto& c : path){
688 ss << c->phi() <<
" ";
694 for (
const auto& path: paths_cell) {
695 for (
const auto& c : path){
701 ss <<
"path signifs:\n";
702 for (
const auto& path: signifs) {
703 for (
const auto& sig : path){
709 ss <<
"path patterns:\n";
710 for (
const auto& pat: paths_pat) {
715 std::stringstream fn;
716 fn <<
"crawl_" <<
m_id <<
"_" << i <<
".txt";
717 std::ofstream out(fn.str());
720 return StatusCode::SUCCESS;
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";
737 ss << c->eta() <<
" ";
741 ss <<
"neighborhood phis:\n";
743 ss << c->phi() <<
" ";
747 ss <<
"neighborhood es:\n";
753 ss <<
"peak etas:\n";
754 for (
const auto& c : peaks){
755 ss << c->eta() <<
" ";
759 ss <<
"peak phis:\n";
760 for (
const auto& c : peaks){
761 ss << c->phi() <<
" ";
766 for (
const auto& c : peaks){
772 ss <<
"peak signifs:\n";
773 for (
const auto& s : peak_signifs){
778 std::stringstream fn;
779 fn <<
"twinpeak_" <<
m_id <<
"_" << i <<
".txt";
780 std::ofstream out(fn.str());
783 return StatusCode::SUCCESS;
790 const std::vector<const CaloCell*>& laremCells,
791 std::vector<const CaloCell*>& neigh_cells,
800 auto seedID = seed->ID();
802 auto seed_eta = seed->eta();
803 auto seed_phi = seed->phi();
805 std::queue<Identifier> to_process;
806 to_process.push(seedID);
808 auto accept = [&seed_eta, &seed_phi,
812 &caloMgr](
const auto& c_id){
814 auto c_eta = dde->
eta();
815 auto c_phi = dde->phi();
817 auto hash = calocell_id->calo_cell_hash(c_id);
818 if (calocell_id->calo_sample(hash) != CaloCell_Base_ID::EMB1) {
return false;}
820 auto deta = seed_eta-c_eta;
821 if( std::abs(deta) > neigh_half_eta) {
return false;}
823 auto dphi = seed_phi-c_phi;
824 return std::abs(dphi) < neigh_half_phi;
828 std::vector<Identifier> mask;
829 auto add_neighbors_to_queue = [&to_process,
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,
838 return StatusCode::FAILURE;
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()) {
845 to_process.push(cc_id->cell_id(nh));
848 return StatusCode::SUCCESS;
852 CHECK(add_neighbors_to_queue(seedID));
853 std::vector<Identifier> neigh_idents;
856 while (!to_process.empty()){
857 const auto& ident = to_process.front();
861 auto c_eta = dde->
eta();
862 auto c_phi = dde->phi();
864 <<
" phi " << c_phi);
865 neigh_idents.push_back(ident);
866 add_neighbors_to_queue(ident);
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()};
875 for(;it!= end; ++it){
876 neigh_cells.push_back(laremCells.at(
m_calocell_id->calo_cell_hash(*it)));
878 return StatusCode::SUCCESS;
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
Definition of CaloDetDescrManager.
#define CHECK(...)
Evaluate an expression and check for errors.
const ServiceHandle< StoreGateSvc > & detStore() const
Header file for AthHistogramAlgorithm.
An algorithm that can be simultaneously executed in multiple threads.
Data object for each calorimeter readout cell.
float eta() const
cell eta
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
This class provides the client interface for accessing the detector description information common to...
float getNoise(const IdentifierHash h, const int gain) const
Accessor by IdentifierHash and gain.
Gaudi::Property< int > m_er_neta
Gaudi::Property< float > m_tp_signifcut
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
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
StatusCode neighborhood(const CaloCell *, const std::vector< const CaloCell * > &laremCells, std::vector< const CaloCell * > &neighs, const CaloDetDescrManager *) const
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
Gaudi::Property< int > m_er_nphi
virtual StatusCode initialize() override
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
virtual StatusCode execute(const EventContext &) const override
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
Gaudi::Property< float > m_neigh_half_eta
Gaudi::Property< float > m_neigh_half_phi
Gaudi::Property< std::vector< std::string > > m_strategies
std::vector< std::vector< const CaloCell * > > CellVectors
Gaudi::Property< bool > m_dump
SG::ReadHandleKey< CaloCellContainer > m_allCaloCellsKey
ToolHandle< ICaloCellsProducer > m_cellsProducer
Gaudi::Property< float > m_seed_signifcut
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
SG::ReadCondHandleKey< CaloNoise > m_totalNoiseKey
Gaudi::Property< float > m_crawl_signifcut
std::vector< std::vector< float > > PathsSignif
const CaloCell_ID * m_calocell_id
GepPi0Alg(const std::string &name, ISvcLocator *pSvcLocator)
std::atomic< size_t > m_id
std::map< std::string, int > dirs
list of directories to be explicitly included, together with corresponding depths of subdirectories
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
DataModel_detail::iterator< DVL > partition(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of partition for DataVector/List.