39 return StatusCode::SUCCESS;
51 CHECK(h_allCaloCells.isValid());
53 const auto & allCaloCells = *h_allCaloCells;
59 ATH_MSG_ERROR(
"CaloCellCollection does not contain LAREM cells");
60 return StatusCode::FAILURE;
65 ATH_MSG_DEBUG (
"Size from SubCalo Iters " << std::distance(cellbegin,
68 std::vector<const CaloCell*>
74 auto front_idhash =
m_calocell_id->calo_cell_hash(laremCells.front()->ID());
75 auto back_idhash =
m_calocell_id->calo_cell_hash(laremCells.back()->ID());
80 constexpr unsigned int LAREMHASH_LO{0};
82 if (front_idhash != LAREMHASH_LO) {
83 ATH_MSG_ERROR(
"front LARM identifier hash != 0, is " << front_idhash);
84 return StatusCode::FAILURE;
87 constexpr unsigned int LAREMHASH_HI{173311};
89 if (back_idhash != LAREMHASH_HI) {
90 ATH_MSG_ERROR(
"back LARM identifier hash != 173311, is " << back_idhash);
91 return StatusCode::FAILURE;
94 if(!std::is_sorted(laremCells.begin(),
98 cc_id->calo_cell_hash(l->ID()) <
99 cc_id->calo_cell_hash(r->ID());
102 ATH_MSG_ERROR(
"LARM CaloCells are not sorted by identifier hash");
103 return StatusCode::FAILURE;
108 front_idhash <<
" " <<
109 back_idhash <<
" " <<
110 back_idhash-front_idhash <<
" " <<
116 std::vector<const CaloCell*> allEMB1Cells;
118 auto EMB1Selector = [&calocell_id=
m_calocell_id](
const auto& cell) {
119 auto ha = calocell_id->calo_cell_hash(cell->ID());
120 return calocell_id->calo_sample(ha) == CaloCell_Base_ID::EMB1;
125 std::back_inserter(allEMB1Cells),
130 if (!totalNoiseHdl.
isValid()) {
return StatusCode::FAILURE;}
131 const CaloNoise* totalNoiseCDO = *totalNoiseHdl;
140 std::vector<std::vector<const CaloCell*>> emb1CellVecs;
146 for (
const auto& cvec : emb1CellVecs) {
147 if (std::find_if_not(cvec.cbegin(),
149 EMB1Selector) != cvec.cend()){
151 return StatusCode::FAILURE;
156 std::vector<const CaloCell*> seeds(emb1CellVecs.size());
158 auto signif = [&totalNoiseCDO,
160 float noise = totalNoiseCDO->
getNoise(c->ID(),
162 auto sfc = c->e()/noise;
163 return sfc < cut ? 0.:sfc;
166 auto findSeed = [&signif](
const auto& cellVec) ->
const CaloCell* {
167 return *std::max_element(cellVec.cbegin(),
169 [&signif](
const auto& c1,
171 return signif(c1) < signif(c2);});};
174 for (
const auto& v: emb1CellVecs) {
175 ATH_MSG_DEBUG(
"Looking for seed in " << v.size() <<
" cells");
178 std::transform(emb1CellVecs.cbegin(),
183 std::size_t iseed{0};
184 for(
const auto& seed : seeds) {
187 <<
" phi " << seed->phi()
188 <<
" significance "<< signif(seed)
199 if (strategy ==
"TWINPEAKS") {
207 }
catch (std::runtime_error& e) {
209 return StatusCode::FAILURE;
211 }
else if (strategy ==
"SORT") {
218 }
else if (strategy ==
"CRAWL") {
227 }
catch (std::runtime_error& e) {
229 return StatusCode::FAILURE;
233 return StatusCode::FAILURE;
239 return StatusCode::SUCCESS;
245 const std::vector<const CaloCell*>& laremCells,
246 const std::vector<const CaloCell*>& allEMB1Cells,
257 if (!seed) {
return StatusCode::SUCCESS;}
258 if (allEMB1Cells.empty()) {
return StatusCode::SUCCESS;}
262 std::vector<const CaloCell*> neigh_cells;
267 ATH_MSG_DEBUG(
"twin peaks - neighborhood cells size " << neigh_cells.size()
268 <<
" input cell collection size " << allEMB1Cells.size());
271 auto signif = [&totalNoiseCDO](
const auto& cell){
272 return cell->e()/totalNoiseCDO->
getNoise(cell->ID(), cell->gain());
280 return signif(ncell) > signif_cut;
283 neigh_cells.resize(new_end - neigh_cells.begin());
285 ATH_MSG_DEBUG(
"twin peaks - neighborhood size after signif cut: "
286 << neigh_cells.size());
292 auto is_local_max = [neigh_cells,
294 &signif](
const auto& center_cell)
mutable {
302 std::vector<IdentifierHash> adj_hashes;
303 auto rc = cc_id->get_neighbours(cc_id->calo_cell_hash(center_cell->ID()),
307 throw std::runtime_error(
"twin peaks - error obtaining cell neighbors");
311 std::vector<Identifier> adj_idents;;
312 std::transform(adj_hashes.cbegin(),
314 std::back_inserter(adj_idents),
315 [&cc_id](
const auto& hash){
316 return cc_id->cell_id(hash);
321 auto id_cell_match = [&adj_idents](
const CaloCell* n_cell)->
bool {
322 return std::find(adj_idents.begin(),
324 n_cell->ID()) != adj_idents.end();};
330 for (
auto iter = neigh_cells.begin();
331 iter != adj_neigh_cell_end;
333 if (signif(*iter) > signif(center_cell)) {
return false;}
342 std::move(is_local_max));
345 auto n_peaks = peaks_end - neigh_cells.begin();
346 ATH_MSG_DEBUG(
"twin peaks - number of local maxima " << n_peaks);
348 auto n_peaks_noseed = n_peaks;
349 if (std::find(neigh_cells.begin(), peaks_end, seed) != peaks_end){--n_peaks_noseed;}
350 ATH_MSG_DEBUG(
"twin peaks - number of local maxima ommiting seed " << n_peaks_noseed);
353 <<
" phi " << seed->phi()
354 <<
" signif " <<signif(seed));
355 for (
auto iter = neigh_cells.begin(); iter != peaks_end; ++iter) {
357 <<
" phi " << (*iter)->phi()
358 <<
" signif " <<signif(*iter));
361 << seed->eta() - (*iter)->eta() <<
" dphi "
362 << seed->phi() - (*iter)->phi());
365 ATH_MSG_DEBUG(
"twin peaks: neighborhood size after signif cut "
366 << neigh_cells.size());
369 for (
const auto& c: neigh_cells) {
370 if (!c) {
throw std::runtime_error(
"Neighbor pointer is nullptr");}
374 <<
" phi " << c->phi()
375 <<
" signif " << signif(c));
382 std::vector<const CaloCell*> peaks_cells(neigh_cells.begin(), peaks_end);
384 std::vector<double> peaks_signif;
385 std::transform(neigh_cells.begin(),
387 std::back_inserter(peaks_signif),
400 return StatusCode::SUCCESS;
406 const std::vector<const CaloCell*>& laremCells,
407 const std::vector<const CaloCell*>& allEMB1Cells,
412 if (!seed) {
return StatusCode::SUCCESS;}
413 if (allEMB1Cells.empty()) {
return StatusCode::SUCCESS;}
415 std::vector<const CaloCell*> neigh_cells;
419 "nbhd size :" << neigh_cells.size());
422 return StatusCode::SUCCESS;
427 const std::vector<const CaloCell*>& laremCells,
428 const std::vector<const CaloCell*>& allEMB1Cells,
433 if (!seed) {
return StatusCode::SUCCESS;}
434 if (allEMB1Cells.empty()) {
return StatusCode::SUCCESS;}
449 <<
" phi " << seed->phi());
451 std::vector<std::string> paths(2*
m_er_neta +1);
455 std::vector<IdentifierHash> phi_starts;
458 phi_starts.push_back(seed_hash);
461 std::vector<LArNeighbours::neighbourOption>
466 for (
const auto& dir :
dirs) {
467 auto cur_hash = seed_hash;
469 std::vector<IdentifierHash> v_adj;
473 if (
rc != 0) {
break;}
475 if (v_adj.size() != 1) {
484 for (
const auto& ha : v_adj) {
496 phi_starts.push_back(cur_hash);
501 << phi_starts.size());
502 for (
const auto&
h: phi_starts) {
507 std::vector<std::vector<IdentifierHash>> paths_hash;
511 for (
const auto& dir :
dirs){
513 auto calc_phihashes = [&dir,
516 std::vector<IdentifierHash> path;
517 std::vector<IdentifierHash> adjacent;
518 path.push_back(hash);
519 for (
int i = 0; i<nphi; ++i) {
521 int rc = cc_id->get_neighbours(hash, dir, adjacent);
522 if (
rc != 0) {
break;}
523 auto size = adjacent.size();
525 throw std::runtime_error(
"unexpected number of identifier hashes: " + std::to_string(size));
529 path.push_back(hash);
535 std::transform(phi_starts.cbegin(),
537 std::back_inserter(paths_hash),
538 std::move(calc_phihashes));
542 << paths_hash.size());
547 paths_cell.reserve(paths_hash.size());
550 for (
const auto& p_h : paths_hash) {
551 std::vector<const CaloCell*> path;
552 path.reserve(p_h.size());
553 std::transform(p_h.cbegin(), p_h.cend(),
554 std::back_inserter(path),
555 [&laremCells](
const auto& hash){
556 return laremCells.at(hash);});
557 paths_cell.push_back(std::move(path));
566 auto signif = [&totalNoiseCDO,
569 if (e <= 0){
return 0.;}
570 auto signif = cell->e()/totalNoiseCDO->
getNoise(cell->ID(), cell->gain());
571 return signif < signif_min ? 0:signif;
577 paths_signif.reserve(paths_cell.size());
580 for (
const auto& p_c : paths_cell) {
581 std::vector<float> path_signif;
582 std::transform(p_c.cbegin(),
584 std::back_inserter(path_signif),
586 paths_signif.push_back(std::move(path_signif));
589 for (
const auto& p_s: paths_signif) {
590 std::stringstream
ss;
591 ss <<
"crawl - path signf ";
592 for (
const auto& s : p_s) {
593 ss << std::setw(7) << std::setprecision(3)<< s <<
" ";
599 std::vector<std::string> paths_pat;
600 paths_pat.reserve(paths_signif.size());
602 for (
const auto& p_s: paths_signif) {
603 std::string pat{
"0"};
605 for (std::size_t i = 1; i != p_s.size(); ++i) {
607 if (p_s[i] > p_s[i-1]) {
614 paths_pat.push_back(std::move(pat));
619 ATH_MSG_DEBUG(
"crawl - no of patterns " << paths_pat.size());
621 for(
const auto& p: paths_pat) {
ATH_MSG_DEBUG(
"crawl - pattern " << p);}
623 std::vector<std::regex> peaks_re{
624 std::regex(
"01*(1)0"), std::regex(
"01*(1)$")};
626 std::vector<const CaloCell*> peak_cells;
629 for (
const auto& s : paths_pat) {
631 for (
const auto& regex : peaks_re) {
633 if(std::regex_search(s, m, regex)){
634 auto pos = m.position(1);
635 ATH_MSG_DEBUG(
"crawl - match at idx " << idx <<
" pos " << pos);
636 peak_cells.push_back(paths_cell[idx][pos]);
644 auto n_peaks = peak_cells.size();
647 <<
" phi " << seed->phi()
648 <<
" signif " <<signif(seed));
649 for (
const auto& pc : peak_cells){
651 <<
" phi " << pc->phi()
652 <<
" signif " <<signif(pc));
655 << seed->eta() - pc->eta() <<
" dphi "
656 << seed->phi() - pc->phi());
668 return StatusCode::SUCCESS;
676 const std::vector<std::vector<float>>& signifs,
677 const std::vector<std::string>& paths_pat)
const {
678 std::stringstream
ss;
679 ss <<
"crawl. cell source " << i <<
'\n';
680 ss <<
"seed " << seed->eta() <<
" " << seed->phi() <<
" "
681 << seed->e() <<
" " << seed_signif <<
'\n';
682 ss <<
"path etas:\n";
683 for (
const auto& path: paths_cell) {
684 for (
const auto& c : path){
685 ss << c->eta() <<
" ";
689 ss <<
"path phis:\n";
690 for (
const auto& path: paths_cell) {
691 for (
const auto& c : path){
692 ss << c->phi() <<
" ";
698 for (
const auto& path: paths_cell) {
699 for (
const auto& c : path){
705 ss <<
"path signifs:\n";
706 for (
const auto& path: signifs) {
707 for (
const auto& sig : path){
713 ss <<
"path patterns:\n";
714 for (
const auto& pat: paths_pat) {
719 std::stringstream fn;
720 fn <<
"crawl_" <<
m_id <<
"_" << i <<
".txt";
721 std::ofstream out(fn.str());
724 return StatusCode::SUCCESS;
733 const std::vector<const CaloCell*>& peaks,
734 const std::vector<double>& peak_signifs)
const {
735 std::stringstream
ss;
736 ss <<
"twinpeaks. cell source " << i <<
'\n';
737 ss <<
"seed " << seed->eta() <<
" " << seed->phi() <<
" "
738 << seed->e() <<
" " << seed_signif <<
'\n';
739 ss <<
"neighborhood etas:\n";
741 ss << c->eta() <<
" ";
745 ss <<
"neighborhood phis:\n";
747 ss << c->phi() <<
" ";
751 ss <<
"neighborhood es:\n";
757 ss <<
"peak etas:\n";
758 for (
const auto& c : peaks){
759 ss << c->eta() <<
" ";
763 ss <<
"peak phis:\n";
764 for (
const auto& c : peaks){
765 ss << c->phi() <<
" ";
770 for (
const auto& c : peaks){
776 ss <<
"peak signifs:\n";
777 for (
const auto& s : peak_signifs){
782 std::stringstream fn;
783 fn <<
"twinpeak_" <<
m_id <<
"_" << i <<
".txt";
784 std::ofstream out(fn.str());
787 return StatusCode::SUCCESS;
794 const std::vector<const CaloCell*>& laremCells,
795 std::vector<const CaloCell*>& neigh_cells,
804 auto seedID = seed->ID();
806 auto seed_eta = seed->eta();
807 auto seed_phi = seed->phi();
809 std::queue<Identifier> to_process;
810 to_process.push(seedID);
812 auto accept = [&seed_eta, &seed_phi,
816 &caloMgr](
const auto& c_id){
818 auto c_eta = dde->
eta();
819 auto c_phi = dde->phi();
821 auto hash = calocell_id->calo_cell_hash(c_id);
822 if (calocell_id->calo_sample(hash) != CaloCell_Base_ID::EMB1) {
return false;}
824 auto deta = seed_eta-c_eta;
825 if( std::abs(deta) > neigh_half_eta) {
return false;}
827 auto dphi = seed_phi-c_phi;
828 return std::abs(dphi) < neigh_half_phi;
832 std::vector<Identifier> mask;
833 auto add_neighbors_to_queue = [&to_process,
835 &mask] (
const auto& desc) {
836 auto hash = cc_id->calo_cell_hash(desc);
837 std::vector<IdentifierHash> neigh_hashes;
838 int rc = cc_id->get_neighbours(hash,
842 return StatusCode::FAILURE;
845 for (
const auto& nh :neigh_hashes) {
846 auto cid = cc_id->cell_id(nh);
847 if (std::find(mask.cbegin(), mask.cend(), cid) == mask.cend()) {
849 to_process.push(cc_id->cell_id(nh));
852 return StatusCode::SUCCESS;
856 CHECK(add_neighbors_to_queue(seedID));
857 std::vector<Identifier> neigh_idents;
860 while (!to_process.empty()){
861 const auto& ident = to_process.front();
865 auto c_eta = dde->
eta();
866 auto c_phi = dde->phi();
868 <<
" phi " << c_phi);
869 neigh_idents.push_back(ident);
870 add_neighbors_to_queue(ident);
875 std::sort(neigh_idents.begin(), neigh_idents.end());
876 auto end =
std::unique(neigh_idents.begin(), neigh_idents.end());
877 auto it{neigh_idents.begin()};
879 for(;it!= end; ++it){
880 neigh_cells.push_back(laremCells.at(
m_calocell_id->calo_cell_hash(*it)));
882 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.