ATLAS Offline Software
Loading...
Searching...
No Matches
CaloGPUClusterAndCellDataMonitor Class Reference

Places (matched) cluster and cell properties in monitored variables to enable plotting with the Athena THistSvc instead of the custom solution that was being used previously. Its histograms can be configured as in a MonitoringTool. More...

#include <CaloGPUClusterAndCellDataMonitor.h>

Inheritance diagram for CaloGPUClusterAndCellDataMonitor:

Classes

struct  pair_to_plot
struct  per_tool_storage
struct  sample_comparisons_holder

Public Member Functions

 CaloGPUClusterAndCellDataMonitor (const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode initialize () override
virtual ~CaloGPUClusterAndCellDataMonitor ()=default
virtual StatusCode update_plots_start (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr) const override
virtual StatusCode update_plots_end (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr) const override
virtual StatusCode update_plots (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr, const CaloClusterCollectionProcessor *tool) const override
virtual StatusCode update_plots (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr, const CaloRecGPU::EventDataHolder &event_data, const ICaloClusterGPUInputTransformer *tool) const override
virtual StatusCode update_plots (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr, const CaloRecGPU::EventDataHolder &event_data, const CaloClusterGPUProcessor *tool) const override
virtual StatusCode update_plots (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr, const CaloRecGPU::EventDataHolder &event_data, const ICaloClusterGPUOutputTransformer *tool) const override
virtual StatusCode finalize_plots () const override

Private Member Functions

StatusCode initialize_plotted_variables ()
StatusCode add_data (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr *cell_info, const CaloRecGPU::ClusterInfoArr *clusters, const std::vector< int > &cells_prefix_sum, const std::string &tool_name) const
StatusCode add_combination (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const int index_1, const int index_2, const std::string &prefix, const bool match_in_energy, const bool match_without_shared, const bool match_perfectly) const
bool filter_tool_by_name (const std::string &tool_name) const
 Returns true if this tool should be plotted for.
StatusCode update_cell_representation (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr *cell_info, CaloRecGPU::ClusterInfoArr *clusters, std::vector< int > &cells_prefix_sum) const
 Update the cell representation so the cells-in-clusters are ordered by index and have a prefix sum.
StatusCode match_clusters (sample_comparisons_holder &sch, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr &cell_info_1, const CaloRecGPU::CellInfoArr &cell_info_2, const std::vector< int > &cells_prefix_sum_1, const std::vector< int > &cells_prefix_sum_2, const CaloRecGPU::ClusterInfoArr &cluster_info_1, const CaloRecGPU::ClusterInfoArr &cluster_info_2, const bool match_in_energy, const bool match_without_shared) const
StatusCode match_clusters_perfectly (sample_comparisons_holder &sch, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr &cell_info_1, const CaloRecGPU::CellInfoArr &cell_info_2, const std::vector< int > &cells_prefix_sum_1, const std::vector< int > &cells_prefix_sum_2, const CaloRecGPU::ClusterInfoArr &cluster_info_1, const CaloRecGPU::ClusterInfoArr &cluster_info_2, const bool match_without_shared) const

Private Attributes

Gaudi::Property< float > m_termThreshold {this, "CellThreshold", 0., "Cell (terminal) threshold (in units of noise Sigma)"}
 Cell (terminal) threshold to use for cluster matching.
Gaudi::Property< float > m_growThreshold {this, "NeighborThreshold", 2., "Neighbor (grow) threshold (in units of noise Sigma)"}
 Neighbor (growing) threshold to use for cluster matching.
Gaudi::Property< float > m_seedThreshold {this, "SeedThreshold", 4., "Seed threshold (in units of noise Sigma)"}
 Seed threshold to use for cluster matching.
SG::ReadHandleKey< CaloCellContainerm_cellsKey {this, "CellsName", "", "Name(s) of Cell Containers"}
 vector of names of the cell containers to use as input.
ToolHandle< GenericMonitoringToolm_moniTool { this, "MonitoringTool", "", "Monitoring tool" }
 Monitoring tool.
Gaudi::Property< std::vector< int > > m_missingCellsToFill {this, "MissingCellsToFill", {}, "Force fill these cells as disabled on empty containers."}
 Cell indices to fill as disabled cells (useful if the cell vector is always missing the same cells).
Gaudi::Property< std::vector< SimpleSingleTool > > m_toolsToPlot {this, "ToolsToPlot", {}, "Tools to be plotted individually"}
 Tools to plot individually.
Gaudi::Property< std::vector< SimpleToolPair > > m_pairsToPlot {this, "PairsToPlot", {}, "Pairs of tools to be compared and plotted"}
 Pairs of tools to compare.
Gaudi::Property< MatchingOptionsm_matchingOptions {this, "ClusterMatchingParameters", {}, "Parameters for the cluster matching algorithm"}
 Option for adjusting the parameters for the cluster matching algorithm.
double m_min_similarity = 0.5
 Parameters for the cluster matching algorithm, for easier access.
double m_seed_weight = 5000.
double m_grow_weight = 250.
double m_terminal_weight = 10.
const CaloCell_IDm_calo_id {nullptr}
 Pointer to Calo ID Helper.
std::map< std::string, int > m_toolsToCheckFor
 Map of the strings corresponding to all the tools that will be relevant for plotting (individually or in comparisons) to the index that will be used to identify the tool within the plotter.
std::map< std::string, std::string > m_toolToIdMap
 Maps tools to their respective identifying prefix for variables.
int m_numToolsToKeep = 0
 The number of tools that will actually need to be kept in memory for combined plotting.
std::vector< pair_to_plotm_toolCombinations
std::map< std::string, std::atomic< size_t > > m_numClustersPerTool ATLAS_THREAD_SAFE
 Counts the total number of clusters per tool.
size_t m_numEvents = 0
 Counts the number of events.
CaloRecGPU::Helpers::separate_thread_holder< std::vector< per_tool_storage > > m_storageHolder ATLAS_THREAD_SAFE
 Stores the intermediate results needed for tool-level matching.
std::vector< bool > m_clusterPropertiesToDo
 Control which properties will actually be calculated and stored.
std::vector< bool > m_comparedClusterPropertiesToDo
std::vector< bool > m_extraComparedClusterPropertiesToDo
std::vector< bool > m_cellPropertiesToDo
std::vector< bool > m_comparedCellPropertiesToDo
std::vector< bool > m_cellTypesToDo
std::vector< bool > m_comparedCellTypesToDo
std::vector< bool > m_extraThingsToDo
bool m_doCells = false
 If no properties are asked for, skip the relevant loops entirely...
bool m_doClusters = false
bool m_doCombinedCells = false
bool m_doCombinedClusters = false
std::atomic< bool > m_plottedVariablesInitialized
 A flag to signal that the variables to be monitored have been detected based on the booked histograms.
std::mutex m_mutex
 This mutex is locked to ensure only one thread detects the monotired variables.

Detailed Description

Places (matched) cluster and cell properties in monitored variables to enable plotting with the Athena THistSvc instead of the custom solution that was being used previously. Its histograms can be configured as in a MonitoringTool.

Author
Nuno Fernandes nuno..nosp@m.dos..nosp@m.santo.nosp@m.s.fe.nosp@m.rnand.nosp@m.es@c.nosp@m.ern.c.nosp@m.h
Date
18 March 2023

Definition at line 40 of file CaloGPUClusterAndCellDataMonitor.h.

Constructor & Destructor Documentation

◆ CaloGPUClusterAndCellDataMonitor()

CaloGPUClusterAndCellDataMonitor::CaloGPUClusterAndCellDataMonitor ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 31 of file CaloGPUClusterAndCellDataMonitor.cxx.

31 :
32 base_class(type, name, parent),
34{
35}
std::atomic< bool > m_plottedVariablesInitialized
A flag to signal that the variables to be monitored have been detected based on the booked histograms...

◆ ~CaloGPUClusterAndCellDataMonitor()

virtual CaloGPUClusterAndCellDataMonitor::~CaloGPUClusterAndCellDataMonitor ( )
virtualdefault

Member Function Documentation

◆ add_combination()

StatusCode CaloGPUClusterAndCellDataMonitor::add_combination ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
const int index_1,
const int index_2,
const std::string & prefix,
const bool match_in_energy,
const bool match_without_shared,
const bool match_perfectly ) const
private

Definition at line 1714 of file CaloGPUClusterAndCellDataMonitor.cxx.

1722{
1723
1724 //Note: Part of the work here is superfluous in the case
1725 // where we are monitoring the tools individually too,
1726 // but in the most generic case that is not guaranteed.
1727 // Partially wasted work, but it's cleaner than the alternative...
1728
1729 std::vector<per_tool_storage> & store_vec = m_storageHolder.get_for_thread();
1730
1731 const CaloRecGPU::CellInfoArr & cell_info_1 = store_vec[index_1].cell_info;
1732 const CaloRecGPU::ClusterInfoArr & clusters_1 = store_vec[index_1].clusters;
1733 const std::vector<int> & cells_prefix_sum_1 = store_vec[index_1].cells_prefix_sum;
1734
1735 const CaloRecGPU::CellInfoArr & cell_info_2 = store_vec[index_2].cell_info;
1736 const CaloRecGPU::ClusterInfoArr & clusters_2 = store_vec[index_2].clusters;
1737 const std::vector<int> & cells_prefix_sum_2 = store_vec[index_2].cells_prefix_sum;
1738
1740
1741 if (match_perfectly)
1742 {
1743 ATH_CHECK( match_clusters_perfectly(sch, constant_data,
1744 cell_info_1, cell_info_2,
1745 cells_prefix_sum_1, cells_prefix_sum_2,
1746 clusters_1, clusters_2,
1747 match_without_shared) );
1748 }
1749 else
1750 {
1751 ATH_CHECK( match_clusters(sch, constant_data,
1752 cell_info_1, cell_info_2,
1753 cells_prefix_sum_1, cells_prefix_sum_2,
1754 clusters_1, clusters_2,
1755 match_in_energy, match_without_shared) );
1756 }
1757
1758 std::unordered_map<std::string, std::vector<double>> cluster_properties, cell_properties;
1759
1760 std::unordered_map<std::string, long long int> cell_counts;
1761
1762 std::vector<double> ref_size_vec(clusters_1.number, 0.), test_size_vec(clusters_2.number, 0.),
1763 ref_weighted_size_vec(clusters_1.number, 0.), test_weighted_size_vec(clusters_2.number, 0.),
1764 ref_diff_cells(clusters_1.number, 0.), test_diff_cells(clusters_2.number, 0.),
1765 ref_diff_cells_weight(clusters_1.number, 0.), test_diff_cells_weight(clusters_2.number, 0.);
1766 //We can store integers up to 2^53 on a double...
1767
1768 long long int same_energy_1 = 0, same_energy_2 = 0,
1769 same_abs_energy_1 = 0, same_abs_energy_2 = 0,
1770 same_snr_1 = 0, same_snr_2 = 0,
1771 same_abs_snr_1 = 0, same_abs_snr_2 = 0,
1772 same_cluster_cells_count = 0, diff_cluster_cells_count = 0;
1773
1774 std::set<double> energies_1, energies_2, snrs_1, snrs_2;
1775
1777 {
1778 for (int cell = 0; cell < NCaloCells; ++cell)
1779 //The way the validity is checked means we will
1780 //simply continue for all cells beyond cell_info_N->number.
1781 {
1782 if ( cell >= cell_info_1.number ||
1783 cell >= cell_info_2.number ||
1784 !cell_info_1.is_valid(cell_info_1.hashID[cell]) ||
1785 !cell_info_2.is_valid(cell_info_2.hashID[cell]) )
1786 {
1787 continue;
1788 }
1789
1790 apply_to_multi_class([&](const auto & prop, const size_t i)
1791 {
1793 {
1794 const auto prop_1 = prop.get_property(constant_data, cell_info_1, clusters_1, cells_prefix_sum_1, cell);
1795 const auto prop_2 = prop.get_property(constant_data, cell_info_2, clusters_2, cells_prefix_sum_2, cell);
1796
1797 cell_properties[prop.name() + "_ref"].push_back(prop_1);
1798 cell_properties[prop.name() + "_test"].push_back(prop_2);
1799
1800 cell_properties["delta_" + prop.name()].push_back(prop_2 - prop_1);
1801 cell_properties["delta_" + prop.name() + "_rel_ref"].push_back((prop_2 - prop_1) / protect_from_zero(std::abs(prop_1)));
1802 cell_properties["delta_" + prop.name() + "_rel_test"].push_back((prop_2 - prop_1) / protect_from_zero(std::abs(prop_2)));
1803 }
1804 }, BasicCellProperties{});
1805
1806 apply_to_multi_class([&](const auto & prop, const size_t i)
1807 {
1809 {
1810 const auto is_1 = prop.is_type(constant_data, cell_info_1, clusters_1, cells_prefix_sum_1, cell);
1811 const auto is_2 = prop.is_type(constant_data, cell_info_2, clusters_2, cells_prefix_sum_2, cell);
1812
1813 cell_counts["num_" + prop.name() + "_cells_ref"] += is_1;
1814 cell_counts["num_" + prop.name() + "_cells_test"] += is_2;
1815 cell_counts["delta_num_" + prop.name() + "_cells"] += is_2 - is_1;
1816 }
1817 }, BasicCellTypes{});
1818
1819 const float this_energy_1 = cell_info_1.energy[cell];
1820 const float this_energy_2 = cell_info_2.energy[cell];
1821
1822 if (m_extraThingsToDo[SameECellsCombined])
1823 {
1824 if (energies_1.count(this_energy_1))
1825 {
1826 ++same_energy_1;
1827 ++same_abs_energy_1;
1828 }
1829 else if (energies_1.count(-this_energy_1))
1830 {
1831 ++same_abs_energy_1;
1832 }
1833 energies_1.insert(this_energy_1);
1834
1835 if (energies_2.count(this_energy_2))
1836 {
1837 ++same_energy_2;
1838 ++same_abs_energy_2;
1839 }
1840 else if (energies_2.count(-this_energy_2))
1841 {
1842 ++same_abs_energy_2;
1843 }
1844 energies_2.insert(this_energy_2);
1845 }
1846
1847 if (m_extraThingsToDo[SameSNRCellsCombined])
1848 {
1849 const float this_snr_1 = this_energy_1 / protect_from_zero(constant_data.m_cell_noise->get_noise(cell_info_1.get_hash_ID(cell), cell_info_1.gain[cell]));
1850
1851 if (snrs_1.count(this_snr_1))
1852 {
1853 ++same_snr_1;
1854 ++same_abs_snr_1;
1855 }
1856 else if (snrs_1.count(-this_snr_1))
1857 {
1858 ++same_abs_snr_1;
1859 }
1860 snrs_1.insert(this_snr_1);
1861
1862
1863 const float this_snr_2 = this_energy_2 / protect_from_zero(constant_data.m_cell_noise->get_noise(cell_info_2.get_hash_ID(cell), cell_info_2.gain[cell]));
1864
1865 if (snrs_2.count(this_snr_2))
1866 {
1867 ++same_snr_2;
1868 ++same_abs_snr_2;
1869 }
1870 else if (snrs_2.count(-this_snr_2))
1871 {
1872 ++same_abs_snr_2;
1873 }
1874 snrs_2.insert(this_snr_2);
1875 }
1876
1877 if (m_extraThingsToDo[DiffCells] || m_extraThingsToDo[ClusterComparedSize])
1878 {
1879 bool cell_is_diff = false;
1880
1881 for (int i = cells_prefix_sum_1[cell]; i < cells_prefix_sum_1[cell + 1] && i < cell_info_1.number; ++i)
1882 {
1883 const int this_index = clusters_1.clusterIndices[i];
1884 const float this_weight = clusters_1.cellWeights[i];
1885 bool found_match = false;
1886 for (int j = cells_prefix_sum_2[cell]; j < cells_prefix_sum_2[cell + 1] && j < cell_info_2.number; ++j)
1887 {
1888 if (this_index == sch.t2r(clusters_2.clusterIndices[j]))
1889 {
1890 found_match = true;
1891 break;
1892 }
1893 }
1894 ref_size_vec[this_index] += 1;
1895 ref_weighted_size_vec[this_index] += this_weight;
1896 if (!found_match)
1897 {
1898 ref_diff_cells[this_index] += 1;
1899 ref_diff_cells_weight[this_index] += this_weight;
1900 cell_is_diff = true;
1901 }
1902 }
1903
1904 for (int i = cells_prefix_sum_2[cell]; i < cells_prefix_sum_2[cell + 1] && i < cell_info_2.number; ++i)
1905 {
1906 const int this_index = clusters_2.clusterIndices[i];
1907 const float this_weight = clusters_2.cellWeights[i];
1908 bool found_match = false;
1909 for (int j = cells_prefix_sum_1[cell]; j < cells_prefix_sum_1[cell + 1] && j < cell_info_1.number; ++j)
1910 {
1911 if (this_index == sch.r2t(clusters_1.clusterIndices[j]))
1912 {
1913 found_match = true;
1914 break;
1915 }
1916 }
1917 test_size_vec[this_index] += 1;
1918 test_weighted_size_vec[this_index] += this_weight;
1919 if (!found_match)
1920 {
1921 test_diff_cells[this_index] += 1;
1922 test_diff_cells_weight[this_index] += this_weight;
1923 cell_is_diff = true;
1924 }
1925 }
1926
1927 if (cell_is_diff)
1928 {
1929#if CALORECGPU_DATA_MONITOR_EXTRA_PRINTOUTS
1930 msg(MSG::INFO) << "Diff: " << cell << " |";
1931 for (int i = cells_prefix_sum_1[cell]; i < cells_prefix_sum_1[cell + 1] && i < cell_info_1.number; ++i)
1932 {
1933 msg() << " {" << clusters_1.cellWeights[i] << ", " << clusters_1.clusterIndices[i] << " (" << sch.r2t(clusters_1.clusterIndices[i]) << ")}";
1934 }
1935 msg() << " |";
1936 for (int i = cells_prefix_sum_2[cell]; i < cells_prefix_sum_2[cell + 1] && i < cell_info_2.number; ++i)
1937 {
1938 msg() << " {" << clusters_2.cellWeights[i] << ", " << clusters_2.clusterIndices[i] << " (" << sch.t2r(clusters_2.clusterIndices[i]) << ")}";
1939 }
1940 msg() << endmsg;
1941#endif
1942
1943 ++diff_cluster_cells_count;
1944 }
1945 else if ((cells_prefix_sum_1[cell + 1] > cells_prefix_sum_1[cell]) || (cells_prefix_sum_2[cell + 1] > cells_prefix_sum_2[cell]))
1946 {
1947 ++same_cluster_cells_count;
1948 }
1949 }
1950 }
1951 }
1952
1954 {
1955
1956 for (int cluster = 0; cluster < clusters_1.number; ++cluster)
1957 {
1958 const int match = sch.r2t(cluster);
1959 if (match < 0)
1960 //The cluster isn't matched.
1961 {
1962 continue;
1963 }
1964
1965 apply_to_multi_class([&](const auto & prop, const size_t i)
1966 {
1968 {
1969 const auto prop_1 = prop.get_property(constant_data, cell_info_1, clusters_1, cells_prefix_sum_1, cluster);
1970 const auto prop_2 = prop.get_property(constant_data, cell_info_2, clusters_2, cells_prefix_sum_2, match);
1971
1972 cluster_properties[prop.name() + "_ref"].push_back(prop_1);
1973 cluster_properties[prop.name() + "_test"].push_back(prop_2);
1974
1975 cluster_properties["delta_" + prop.name()].push_back(prop_2 - prop_1);
1976 cluster_properties["delta_" + prop.name() + "_rel_ref"].push_back((prop_2 - prop_1) / protect_from_zero(std::abs(prop_1)));
1977 cluster_properties["delta_" + prop.name() + "_rel_test"].push_back((prop_2 - prop_1) / protect_from_zero(std::abs(prop_2)));
1978 }
1979 }, BasicClusterProperties{});
1980
1981 apply_to_multi_class([&](const auto & prop, const size_t i)
1982 {
1984 {
1985 cluster_properties[prop.name()].push_back(prop.get_property(constant_data, cell_info_1, clusters_1, cells_prefix_sum_1, cluster,
1986 cell_info_2, clusters_2, cells_prefix_sum_2, match));
1987 }
1988 }, ComparedClusterProperties{});
1989
1990 if (m_extraThingsToDo[ClusterComparedSize])
1991 {
1992 cluster_properties["size_ref"].push_back(ref_size_vec[cluster]);
1993 cluster_properties["size_test"].push_back(test_size_vec[match]);
1994 cluster_properties["delta_size"].push_back(ref_size_vec[cluster] - test_size_vec[match]);
1995 cluster_properties["delta_size_rel_ref"].push_back((ref_size_vec[cluster] - test_size_vec[match]) / protect_from_zero(ref_size_vec[cluster]));
1996 cluster_properties["delta_size_rel_test"].push_back((ref_size_vec[cluster] - test_size_vec[match]) / protect_from_zero(test_size_vec[match]));
1997
1998 cluster_properties["weighted_size_ref"].push_back(ref_weighted_size_vec[cluster]);
1999 cluster_properties["weighted_size_test"].push_back(test_weighted_size_vec[match]);
2000 cluster_properties["delta_weighted_size"].push_back(ref_weighted_size_vec[cluster] - test_weighted_size_vec[match]);
2001 cluster_properties["delta_weighted_size_rel_ref"].push_back((ref_weighted_size_vec[cluster] - test_weighted_size_vec[match]) / protect_from_zero(ref_weighted_size_vec[cluster]));
2002 cluster_properties["delta_weighted_size_rel_test"].push_back((ref_weighted_size_vec[cluster] - test_weighted_size_vec[match]) / protect_from_zero(test_weighted_size_vec[match]));
2003 }
2004
2005 if (m_extraThingsToDo[DiffCells])
2006 {
2007 cluster_properties["diff_cells_ref"].push_back(ref_diff_cells[cluster]);
2008 cluster_properties["diff_cells_ref_rel_size"].push_back(ref_diff_cells[cluster] / protect_from_zero(ref_size_vec[cluster]));
2009 cluster_properties["diff_cells_test"].push_back(test_diff_cells[match]);
2010 cluster_properties["diff_cells_test_rel_size"].push_back(test_diff_cells[match] / protect_from_zero(test_size_vec[match]));
2011 cluster_properties["diff_cells"].push_back(ref_diff_cells[cluster] + test_diff_cells[match]);
2012
2013 cluster_properties["weighted_diff_cells_ref"].push_back(ref_diff_cells_weight[cluster]);
2014 cluster_properties["weighted_diff_cells_ref_rel_size"].push_back(ref_diff_cells_weight[cluster] / protect_from_zero(ref_weighted_size_vec[cluster]));
2015 cluster_properties["weighted_diff_cells_test"].push_back(test_diff_cells_weight[match]);
2016 cluster_properties["weighted_diff_cells_test_rel_size"].push_back(test_diff_cells_weight[match] / protect_from_zero(test_weighted_size_vec[match]));
2017 cluster_properties["weighted_diff_cells"].push_back(ref_diff_cells_weight[cluster] + test_diff_cells_weight[match]);
2018 }
2019 }
2020 }
2021
2022 using coll_type = decltype(Monitored::Collection("", std::declval<std::vector<double> &>()));
2023 using scalar_type = decltype(Monitored::Scalar("", std::declval<long long int>()));
2024
2025 std::vector<coll_type> collections;
2026 std::vector<scalar_type> count_scalars;
2027 std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> cluster_group, cell_group, counts_group;
2028
2029 collections.reserve(cluster_properties.size() + cell_properties.size());
2030 count_scalars.reserve(cell_counts.size() + 6 * 3);
2031 cluster_group.reserve(cluster_properties.size());
2032 cell_group.reserve(cell_properties.size());
2033 counts_group.reserve(cell_counts.size() + 3 + 6 * 3);
2034
2035 auto add_count_vars = [&](const std::string & name, const long long int ref_num, const long long int test_num)
2036 {
2037 count_scalars.emplace_back(Monitored::Scalar(prefix + "_" + name + "_ref", ref_num));
2038 counts_group.push_back(std::ref(count_scalars.back()));
2039
2040 count_scalars.emplace_back(Monitored::Scalar(prefix + "_" + name + "_test", test_num));
2041 counts_group.push_back(std::ref(count_scalars.back())); // cppcheck-suppress invalidContainer; reserve used
2042
2043 count_scalars.emplace_back(Monitored::Scalar(prefix + "_delta_" + name, test_num - ref_num));
2044 counts_group.push_back(std::ref(count_scalars.back())); // cppcheck-suppress invalidContainer; reserve used
2045 };
2046
2047 add_count_vars("num_clusters", clusters_1.number, clusters_2.number);
2048 add_count_vars("num_unmatched_clusters", sch.ref_unmatched(), sch.test_unmatched());
2049
2050 add_count_vars("num_same_E_cells", same_energy_1, same_energy_2);
2051 add_count_vars("num_same_abs_E_cells", same_abs_energy_1, same_abs_energy_2);
2052 add_count_vars("num_same_SNR_cells", same_snr_1, same_snr_2);
2053 add_count_vars("num_same_abs_SNR_cells", same_abs_snr_1, same_abs_snr_2);
2054
2055 auto mon_total_unmatched = Monitored::Scalar(prefix + "_num_unmatched_clusters", sch.ref_unmatched() + sch.test_unmatched());
2056 auto mon_same_cluster_cell = Monitored::Scalar(prefix + "_same_cluster_cells", same_cluster_cells_count);
2057 auto mon_diff_cluster_cell = Monitored::Scalar(prefix + "_diff_cluster_cells", diff_cluster_cells_count);
2058
2059 if(m_extraThingsToDo[DiffCells])
2060 {
2061 ATH_MSG_INFO("Different cells: " << diff_cluster_cells_count);
2062 }
2063
2064 counts_group.push_back(std::ref(mon_total_unmatched));
2065 counts_group.push_back(std::ref(mon_same_cluster_cell));
2066 counts_group.push_back(std::ref(mon_diff_cluster_cell));
2067
2068 for (const auto & k_v : cluster_properties)
2069 {
2070 collections.emplace_back(Monitored::Collection(prefix + "_cluster_" + k_v.first, k_v.second));
2071 cluster_group.push_back(std::ref(collections.back()));
2072 }
2073
2074 for (const auto & k_v : cell_properties)
2075 {
2076 collections.emplace_back(Monitored::Collection(prefix + "_cell_" + k_v.first, k_v.second));
2077 cell_group.push_back(std::ref(collections.back()));
2078 }
2079
2080 for (const auto & k_v : cell_counts)
2081 {
2082 count_scalars.emplace_back(Monitored::Scalar(prefix + "_" + k_v.first, k_v.second));
2083 counts_group.push_back(std::ref(count_scalars.back()));
2084 }
2085
2086 // Taking a std::ref of the back() iterator above is safe because the vector
2087 // has been reserved with the correct number of elements.
2088 // cppcheck-suppress invalidContainer
2089 auto monitor_clusters = Monitored::Group(m_moniTool, cluster_group);
2090 auto monitor_cells = Monitored::Group(m_moniTool, cell_group);
2091 auto monitor_counts = Monitored::Group(m_moniTool, counts_group);
2092
2093 return StatusCode::SUCCESS;
2094}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
ToolHandle< GenericMonitoringTool > m_moniTool
Monitoring tool.
StatusCode match_clusters(sample_comparisons_holder &sch, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr &cell_info_1, const CaloRecGPU::CellInfoArr &cell_info_2, const std::vector< int > &cells_prefix_sum_1, const std::vector< int > &cells_prefix_sum_2, const CaloRecGPU::ClusterInfoArr &cluster_info_1, const CaloRecGPU::ClusterInfoArr &cluster_info_2, const bool match_in_energy, const bool match_without_shared) const
StatusCode match_clusters_perfectly(sample_comparisons_holder &sch, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr &cell_info_1, const CaloRecGPU::CellInfoArr &cell_info_2, const std::vector< int > &cells_prefix_sum_1, const std::vector< int > &cells_prefix_sum_2, const CaloRecGPU::ClusterInfoArr &cluster_info_1, const CaloRecGPU::ClusterInfoArr &cluster_info_2, const bool match_without_shared) const
CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellNoiseArr > m_cell_noise
Definition DataHolders.h:34
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357
double protect_from_zero(const double x)
constexpr int NCaloCells
void apply_to_multi_class(F &&f, multi_class_holder< Types... >, Args &... args)
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)
constexpr int get_hash_ID(const int cell, const bool is_complete=false) const
unsigned char gain[NCaloCells]
constexpr bool is_valid(const int hash_ID, const bool is_complete=false, const bool all_cells_are_valid=false) const
MsgStream & msg
Definition testRead.cxx:32

◆ add_data()

StatusCode CaloGPUClusterAndCellDataMonitor::add_data ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
const CaloRecGPU::CellInfoArr * cell_info,
const CaloRecGPU::ClusterInfoArr * clusters,
const std::vector< int > & cells_prefix_sum,
const std::string & tool_name ) const
private

Definition at line 1531 of file CaloGPUClusterAndCellDataMonitor.cxx.

1537{
1538 m_numClustersPerTool[tool_name].fetch_add(clusters->number);
1539
1540 const std::string prefix = m_toolToIdMap.at(tool_name);
1541
1542 const int index = m_toolsToCheckFor.at(tool_name);
1543
1544 if (index >= 0 && m_numToolsToKeep > 0)
1545 {
1546 std::vector<per_tool_storage> & store_vec = m_storageHolder.get_for_thread();
1547 store_vec[index].cell_info = *cell_info;
1548 store_vec[index].clusters = *clusters;
1549 store_vec[index].cells_prefix_sum = cells_prefix_sum;
1550 }
1551
1552 if (prefix != "")
1553 //Tools that are not meant to be plotted individually
1554 //have the empty string as a prefix.
1555 {
1556 std::unordered_map<std::string, std::vector<double>> cluster_properties, cell_properties;
1557
1558 std::unordered_map<std::string, long long int> cell_counts;
1559
1560 cluster_properties["size"].resize(clusters->number, 0.);
1561 cluster_properties["weighted_size"].resize(clusters->number, 0.);
1562
1563 long long int same_energy = 0, same_abs_energy = 0, same_snr = 0, same_abs_snr = 0;
1564
1565 std::set<double> energies, snrs;
1566
1567 if (m_doCells)
1568 {
1569
1570 for (int cell = 0; cell < cell_info->number; ++cell)
1571 {
1572 if (!cell_info->is_valid(cell_info->hashID[cell]))
1573 {
1574 continue;
1575 }
1576
1577 apply_to_multi_class([&](const auto & prop, const size_t i)
1578 {
1579 if (m_cellPropertiesToDo[i])
1580 {
1581 cell_properties[prop.name()].push_back(prop.get_property(constant_data, *cell_info, *clusters, cells_prefix_sum, cell));
1582 }
1583 }, BasicCellProperties{});
1584
1585 apply_to_multi_class([&](const auto & prop, const size_t i)
1586 {
1587 if (m_cellTypesToDo[i])
1588 {
1589 cell_counts[prop.name()] += prop.is_type(constant_data, *cell_info, *clusters, cells_prefix_sum, cell);
1590 }
1591 }, BasicCellTypes{});
1592
1593 const float this_energy = cell_info->energy[cell];
1594
1595 if (m_extraThingsToDo[SameECells])
1596 {
1597
1598 if (energies.count(this_energy))
1599 {
1600 ++same_energy;
1601 ++same_abs_energy;
1602 }
1603 else if (energies.count(-this_energy))
1604 {
1605 ++same_abs_energy;
1606 }
1607 energies.insert(this_energy);
1608 }
1609
1610 if (m_extraThingsToDo[SameSNRCells])
1611 {
1612
1613 const float this_snr = this_energy / protect_from_zero(constant_data.m_cell_noise->get_noise(cell_info->get_hash_ID(cell), cell_info->gain[cell]));
1614
1615 if (snrs.count(this_snr))
1616 {
1617 ++same_snr;
1618 ++same_abs_snr;
1619 }
1620 else if (snrs.count(-this_snr))
1621 {
1622 ++same_abs_snr;
1623 }
1624 snrs.insert(this_snr);
1625 }
1626 }
1627
1628 if (m_extraThingsToDo[ClusterSize])
1629 {
1630 for (int i = 0; i < clusters->number_cells; ++i)
1631 {
1632 const int this_cluster = clusters->clusterIndices[i];
1633 const float this_weight = clusters->cellWeights[i];
1634
1635 cluster_properties["size"][this_cluster] += 1;
1636 cluster_properties["weighted_size"][this_cluster] += this_weight;
1637 }
1638 }
1639 }
1640
1641 if (m_doClusters)
1642 {
1643 for (int cluster = 0; cluster < clusters->number; ++cluster)
1644 {
1645 apply_to_multi_class([&](const auto & prop, const size_t i)
1646 {
1648 {
1649 cluster_properties[prop.name()].push_back(prop.get_property(constant_data, *cell_info, *clusters, cells_prefix_sum, cluster));
1650 }
1651 }, BasicClusterProperties{});
1652 }
1653 }
1654
1655 using coll_type = decltype(Monitored::Collection("", std::declval<std::vector<double> &>()));
1656 using scalar_type = decltype(Monitored::Scalar("", std::declval<long long int>()));
1657
1658 std::vector<coll_type> collections;
1659 std::vector<scalar_type> count_scalars;
1660 std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> cluster_group, cell_group, counts_group;
1661
1662 collections.reserve(cluster_properties.size() + cell_properties.size());
1663 count_scalars.reserve(cell_counts.size());
1664 cluster_group.reserve(cluster_properties.size());
1665 cell_group.reserve(cell_properties.size());
1666 counts_group.reserve(cell_counts.size() + 5);
1667
1668 auto mon_clus_num = Monitored::Scalar(prefix + "_num_clusters", clusters->number);
1669 auto mon_same_energy = Monitored::Scalar(prefix + "_num_same_E_cells", same_energy);
1670 auto mon_same_abs_energy = Monitored::Scalar(prefix + "_num_same_abs_E_cells", same_abs_energy);
1671 auto mon_same_snr = Monitored::Scalar(prefix + "_num_same_SNR_cells", same_snr);
1672 auto mon_same_abs_snr = Monitored::Scalar(prefix + "_num_same_abs_SNR_cells", same_abs_snr);
1673
1674 counts_group.push_back(std::ref(mon_clus_num));
1675 counts_group.push_back(std::ref(mon_same_energy));
1676 counts_group.push_back(std::ref(mon_same_abs_energy));
1677 counts_group.push_back(std::ref(mon_same_snr));
1678 counts_group.push_back(std::ref(mon_same_abs_snr));
1679
1680 //If we're not doing these plots,
1681 //we're still saving,
1682 //which is slightly inefficient, but.. let's not complicate.
1683
1684 for (const auto & k_v : cluster_properties)
1685 {
1686 collections.emplace_back(Monitored::Collection(prefix + "_cluster_" + k_v.first, k_v.second));
1687 cluster_group.push_back(std::ref(collections.back()));
1688 }
1689
1690 for (const auto & k_v : cell_properties)
1691 {
1692 collections.emplace_back(Monitored::Collection(prefix + "_cell_" + k_v.first, k_v.second));
1693 cell_group.push_back(std::ref(collections.back()));
1694 }
1695
1696 for (const auto & k_v : cell_counts)
1697 {
1698 count_scalars.emplace_back(Monitored::Scalar(prefix + "_num_" + k_v.first + "_cells", k_v.second));
1699 counts_group.push_back(std::ref(count_scalars.back()));
1700 }
1701
1702 // Taking a std::ref of the back() iterator above is safe because the vector
1703 // has been reserved with the correct number of elements.
1704 // cppcheck-suppress invalidContainer
1705 auto monitor_clusters = Monitored::Group(m_moniTool, cluster_group);
1706 auto monitor_cells = Monitored::Group(m_moniTool, cell_group);
1707 auto monitor_counts = Monitored::Group(m_moniTool, counts_group);
1708
1709 }
1710 return StatusCode::SUCCESS;
1711}
std::vector< bool > m_clusterPropertiesToDo
Control which properties will actually be calculated and stored.
bool m_doCells
If no properties are asked for, skip the relevant loops entirely...
int m_numToolsToKeep
The number of tools that will actually need to be kept in memory for combined plotting.
std::map< std::string, std::string > m_toolToIdMap
Maps tools to their respective identifying prefix for variables.
std::map< std::string, int > m_toolsToCheckFor
Map of the strings corresponding to all the tools that will be relevant for plotting (individually or...
str index
Definition DeMoScan.py:362

◆ filter_tool_by_name()

bool CaloGPUClusterAndCellDataMonitor::filter_tool_by_name ( const std::string & tool_name) const
private

Returns true if this tool should be plotted for.

Definition at line 278 of file CaloGPUClusterAndCellDataMonitor.cxx.

279{
280 ATH_MSG_DEBUG("Checking : '" << tool_name << "': " << m_toolsToCheckFor.count(tool_name));
281 return m_toolsToCheckFor.count(tool_name) > 0;
282}
#define ATH_MSG_DEBUG(x)

◆ finalize_plots()

StatusCode CaloGPUClusterAndCellDataMonitor::finalize_plots ( ) const
overridevirtual

Definition at line 106 of file CaloGPUClusterAndCellDataMonitor.cxx.

107{
108 //Well, not do plots, just monitor the number of events and the total number of clusters...
109
110 auto mon_num_events = Monitored::Scalar("num_events", m_numEvents);
111
112 for (const auto & k_v : m_toolToIdMap)
113 {
114 auto mon_num_clust = Monitored::Scalar(k_v.second + "_num_total_clusters", m_numClustersPerTool.at(k_v.first).load());
115 }
116
117 return StatusCode::SUCCESS;
118}
size_t m_numEvents
Counts the number of events.

◆ initialize()

StatusCode CaloGPUClusterAndCellDataMonitor::initialize ( )
overridevirtual

Definition at line 37 of file CaloGPUClusterAndCellDataMonitor.cxx.

38{
39 ATH_CHECK( m_cellsKey.initialize() );
40
41 ATH_CHECK( detStore()->retrieve(m_calo_id, "CaloCell_ID") );
42
43 const std::string this_name = this->name();
44
45 const std::string algorithm_name_prefix = this_name.substr(0, this_name.rfind('.'));
46 //This is so we take into account the fact that tools
47 //are prefixed with the parent algorithm's name.
48
49 auto final_string = [& algorithm_name_prefix](const std::string & unpref_str) -> std::string
50 {
51 return algorithm_name_prefix + "." + unpref_str;
52 };
53
55
56 m_min_similarity = opts.min_similarity;
57 m_seed_weight = opts.seed_w;
58 m_grow_weight = opts.grow_w;
59 m_terminal_weight = opts.term_w;
60
61 for (const auto & tool : m_toolsToPlot)
62 {
63 const std::string tool_name = final_string(tool.tool);
64 m_toolToIdMap[tool_name] = tool.plot_id;
65 m_toolsToCheckFor[tool_name] = -1;
66 }
67
68 auto add_tool_from_pair = [this](const std::string & name) -> int
69 {
70 if (!m_toolsToCheckFor.count(name))
71 {
73 m_toolToIdMap[name] = "";
74 return m_numToolsToKeep++;
75 }
76 else
77 {
78 const int current = m_toolsToCheckFor[name];
79 if (current >= 0)
80 {
81 return current;
82 }
83 else
84 {
86 return m_numToolsToKeep++;
87 }
88 }
89 };
90
91 for (const auto & pair : m_pairsToPlot)
92 {
93 const int first_index = add_tool_from_pair(final_string(pair.tool_ref));
94 const int second_index = add_tool_from_pair(final_string(pair.tool_test));
95 m_toolCombinations.emplace_back(pair_to_plot{first_index, second_index, pair.plot_id,
96 pair.match_in_energy,
97 pair.match_without_shared,
98 pair.match_perfectly});
99 }
100
101 ATH_CHECK( m_moniTool.retrieve() );
102
103 return StatusCode::SUCCESS;
104}
Gaudi::Property< std::vector< SimpleSingleTool > > m_toolsToPlot
Tools to plot individually.
Gaudi::Property< std::vector< SimpleToolPair > > m_pairsToPlot
Pairs of tools to compare.
Gaudi::Property< MatchingOptions > m_matchingOptions
Option for adjusting the parameters for the cluster matching algorithm.
SG::ReadHandleKey< CaloCellContainer > m_cellsKey
vector of names of the cell containers to use as input.
const CaloCell_ID * m_calo_id
Pointer to Calo ID Helper.
double m_min_similarity
Parameters for the cluster matching algorithm, for easier access.
MatchingOptions(min_similarity=0.50, terminal_weight=250., grow_weight=500., seed_weight=1000.)

◆ initialize_plotted_variables()

StatusCode CaloGPUClusterAndCellDataMonitor::initialize_plotted_variables ( )
private

Definition at line 1387 of file CaloGPUClusterAndCellDataMonitor.cxx.

1388{
1389 const std::vector<std::string> histo_strings = m_moniTool->histogramService()->getHists();
1390 //Small problem: other histograms with matching names.
1391 //Mitigated by the fact that we use cell_<property> and cluster_<property>...
1392
1393 m_clusterPropertiesToDo.resize(BasicClusterProperties::size(), false);
1394 m_comparedClusterPropertiesToDo.resize(BasicClusterProperties::size(), false);
1395 m_extraComparedClusterPropertiesToDo.resize(ComparedClusterProperties::size(), false);
1396 m_cellPropertiesToDo.resize(BasicCellProperties::size(), false);
1397 m_comparedCellPropertiesToDo.resize(BasicCellProperties::size(), false);
1398 m_cellTypesToDo.resize(BasicCellTypes::size(), false);
1399 m_comparedCellTypesToDo.resize(BasicCellTypes::size(), false);
1400 m_extraThingsToDo.resize(ExtraThingsSize, false);
1401
1402 auto string_contains = [](std::string_view container, std::string_view contained) -> bool
1403 {
1404 return container.find(contained) != std::string::npos;
1405 };
1406
1407 auto search_lambda = [&](const auto & prop, const size_t count, bool & check,
1408 const std::string & str, std::vector<bool> & to_do,
1409 std::string_view prefix = "", std::string_view suffix = "")
1410 {
1411 if (string_contains(str, std::string(prefix) + prop.name() + std::string(suffix)))
1412 {
1413 to_do[count] = true;
1414 check = true;
1415 }
1416 };
1417
1418 for (const auto & str : histo_strings)
1419 {
1420 bool found = false;
1421
1422 apply_to_multi_class(search_lambda, BasicCellProperties{}, found, str, m_cellPropertiesToDo, "_cell_");
1423 apply_to_multi_class(search_lambda, BasicCellTypes{}, found, str, m_cellTypesToDo, "_", "_cells");
1424
1425 if (found)
1426 {
1427 m_doCells = true;
1428 }
1429
1430 found = false;
1431
1432 apply_to_multi_class(search_lambda, BasicClusterProperties{}, found, str, m_clusterPropertiesToDo, "_cluster_");
1433
1434 if (found)
1435 {
1436 m_doClusters = true;
1437 }
1438
1439 found = false;
1440
1441 apply_to_multi_class(search_lambda, BasicCellProperties{}, found, str, m_comparedCellPropertiesToDo, "_cell_delta_");
1442 apply_to_multi_class(search_lambda, BasicCellProperties{}, found, str, m_comparedCellPropertiesToDo, "_cell_", "_ref");
1443 apply_to_multi_class(search_lambda, BasicCellProperties{}, found, str, m_comparedCellPropertiesToDo, "_cell_", "_test");
1444 apply_to_multi_class(search_lambda, BasicCellTypes{}, found, str, m_comparedCellTypesToDo, "num_ref_", "_cells");
1445 apply_to_multi_class(search_lambda, BasicCellTypes{}, found, str, m_comparedCellTypesToDo, "num_test_", "_cells");
1446 apply_to_multi_class(search_lambda, BasicCellTypes{}, found, str, m_comparedCellTypesToDo, "delta_", "_cells");
1447
1448 if (found)
1449 {
1450 m_doCombinedCells = true;
1451 }
1452
1453 found = false;
1454
1455 apply_to_multi_class(search_lambda, BasicClusterProperties{}, found, str, m_comparedClusterPropertiesToDo, "_cluster_delta_", "");
1456 apply_to_multi_class(search_lambda, BasicClusterProperties{}, found, str, m_comparedClusterPropertiesToDo, "_cluster_", "_ref");
1457 apply_to_multi_class(search_lambda, BasicClusterProperties{}, found, str, m_comparedClusterPropertiesToDo, "_cluster_", "_test");
1458 apply_to_multi_class(search_lambda, ComparedClusterProperties{}, found, str, m_extraComparedClusterPropertiesToDo);
1459
1460 if (found)
1461 {
1462 m_doCombinedClusters = true;
1463 }
1464
1465 if ( string_contains(str, "cluster_size_ref") ||
1466 string_contains(str, "cluster_size_test") ||
1467 string_contains(str, "cluster_delta_size") ||
1468 string_contains(str, "cluster_weighted_size_ref") ||
1469 string_contains(str, "cluster_weighted_size_test") ||
1470 string_contains(str, "cluster_delta_weighted_size") )
1471 {
1472 m_extraThingsToDo[ClusterComparedSize] = true;
1473 m_doCombinedCells = true;
1474 m_doCombinedClusters = true;
1475 }
1476 else if ( string_contains(str, "cluster_size") ||
1477 string_contains(str, "cluster_weighted_size") )
1478 {
1479 m_extraThingsToDo[ClusterSize] = true;
1480 m_doCells = true;
1481 m_doClusters = true;
1482 }
1483
1484 if (string_contains(str, "cluster_diff_cells"))
1485 {
1486 m_extraThingsToDo[DiffCells] = true;
1487 m_doCombinedCells = true;
1488 m_doCombinedClusters = true;
1489 }
1490
1491 if ( string_contains(str, "_num_same_E_cells_ref") ||
1492 string_contains(str, "_num_same_E_cells_test") ||
1493 string_contains(str, "delta_num_same_E_cells") ||
1494 string_contains(str, "_num_same_abs_E_cells_ref") ||
1495 string_contains(str, "_num_same_abs_E_cells_test") ||
1496 string_contains(str, "delta_num_same_abs_E_cells") )
1497 {
1498 m_extraThingsToDo[SameECellsCombined] = true;
1499 m_doCombinedCells = true;
1500 }
1501 else if ( string_contains(str, "_num_same_E_cells") ||
1502 string_contains(str, "_num_same_abs_E_cells") )
1503 {
1504 m_extraThingsToDo[SameECells] = true;
1505 m_doCells = true;
1506 }
1507
1508 if ( string_contains(str, "_num_same_SNR_cells_ref") ||
1509 string_contains(str, "_num_same_SNR_cells_test") ||
1510 string_contains(str, "delta_num_same_SNR_cells") ||
1511 string_contains(str, "_num_same_abs_SNR_cells_ref") ||
1512 string_contains(str, "_num_same_abs_SNR_cells_test") ||
1513 string_contains(str, "delta_num_same_abs_SNR_cells") )
1514 {
1515 m_extraThingsToDo[SameSNRCellsCombined] = true;
1516 m_doCombinedCells = true;
1517 }
1518 else if ( string_contains(str, "_num_same_SNR_cells") ||
1519 string_contains(str, "_num_same_abs_SNR_cells") )
1520 {
1521 m_extraThingsToDo[SameSNRCells] = true;
1522 m_doCells = true;
1523 }
1524 }
1525
1526 return StatusCode::SUCCESS;
1527
1528}
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146

◆ match_clusters()

StatusCode CaloGPUClusterAndCellDataMonitor::match_clusters ( sample_comparisons_holder & sch,
const CaloRecGPU::ConstantDataHolder & constant_data,
const CaloRecGPU::CellInfoArr & cell_info_1,
const CaloRecGPU::CellInfoArr & cell_info_2,
const std::vector< int > & cells_prefix_sum_1,
const std::vector< int > & cells_prefix_sum_2,
const CaloRecGPU::ClusterInfoArr & cluster_info_1,
const CaloRecGPU::ClusterInfoArr & cluster_info_2,
const bool match_in_energy,
const bool match_without_shared ) const
private

Definition at line 490 of file CaloGPUClusterAndCellDataMonitor.cxx.

500{
501 sch.r2t_table.clear();
502 sch.r2t_table.resize(cluster_info_1.number, -1);
503
504 sch.t2r_table.clear();
505 sch.t2r_table.resize(cluster_info_2.number, -1);
506
507 std::vector<double> similarity_map(cluster_info_1.number * cluster_info_2.number, 0.);
508
509 std::vector<double> ref_normalization(cluster_info_1.number, 0.);
510 std::vector<double> test_normalization(cluster_info_2.number, 0.);
511
512 auto calculate_weight = [&](const int cell)
513 {
514 double SNR = 0.00001;
515
516 if (!cell_info_1.is_bad(cell))
517 {
518 const int gain = cell_info_1.gain[cell];
519
520 const double cellNoise = constant_data.m_cell_noise->get_noise(cell_info_1.get_hash_ID(cell), gain);
521 if (std::isfinite(cellNoise) && cellNoise > 0.0f)
522 {
523 SNR = std::abs(cell_info_1.energy[cell] / cellNoise);
524 }
525 }
526
527 const double quantity = ( match_in_energy ? std::abs(cell_info_1.energy[cell]) : SNR );
528 const double weight = (quantity + 1e-7) *
529 ( SNR > m_seedThreshold ? (match_in_energy ? 1000 : m_seed_weight) :
530 (
531 SNR > m_growThreshold ? (match_in_energy ? 950 : m_grow_weight) :
532 (
533 SNR > m_termThreshold ? (match_in_energy ? 900 : m_terminal_weight) : (match_in_energy ? 100 : 1e-8)
534 )
535 )
536 );
537
538 return weight + 1e-8;
539 };
540
541 auto matched_clusters = [&](const int hash_ID, const std::vector<std::pair<int, float>> & v1, const std::vector<std::pair<int, float>> & v2)
542 {
543#if CALORECGPU_DATA_MONITOR_EXTRA_PRINTOUTS && CALORECGPU_DATA_MONITOR_EXTRA_PRINTOUTS > 1
544 msg(MSG::INFO) << "MATCH: " << hash_ID << " " << calculate_weight(cell_info_1.get_cell_with_hash_ID(hash_ID)) << " |";
545 for (const auto & p : v1)
546 {
547 msg() << " (" << p.first << ", " << p.second << ")";
548 }
549 msg() << " |";
550 for (const auto & p : v2)
551 {
552 msg() << " (" << p.first << ", " << p.second << ")";
553 }
554 msg() << endmsg;
555#endif
556
557 if (match_without_shared && (v1.size() > 1 || v2.size() > 1))
558 {
559 return;
560 }
561
562 const float weight = calculate_weight(cell_info_1.get_cell_with_hash_ID(hash_ID));
563
564 for (const auto & p1 : v1)
565 {
566 for (const auto & p2 : v2)
567 {
568 similarity_map[p2.first * cluster_info_1.number + p1.first] += weight * p1.second * p2.second;
569 }
570 }
571
572 for (const auto & p1 : v1)
573 {
574 ref_normalization[p1.first] += weight * p1.second * p1.second;
575 }
576
577 for (const auto & p2 : v2)
578 {
579 test_normalization[p2.first] += weight * p2.second * p2.second;
580 }
581 };
582
583 auto unmatched_clusters = [&](const bool is_test, const int hash_ID, const std::vector<std::pair<int, float>> & v)
584 {
585#if CALORECGPU_DATA_MONITOR_EXTRA_PRINTOUTS
586 msg(MSG::INFO) << "UNMATCH: " << hash_ID << " " << calculate_weight(cell_info_1.get_cell_with_hash_ID(hash_ID)) << " | " << is_test << " |";
587 for (const auto & p : v)
588 {
589 msg() << " (" << p.first << ", " << p.second << ")";
590 }
591 msg() << endmsg;
592#endif
593
594 if (match_without_shared && v.size() > 1)
595 {
596 return;
597 }
598
599 const float weight = calculate_weight(cell_info_1.get_cell_with_hash_ID(hash_ID));
600
601 std::vector<double> & normalization = (is_test ? test_normalization : ref_normalization);
602
603 for (const auto & p : v)
604 {
605 normalization[p.first] += weight * p.second * p.second;
606 }
607 };
608
609 build_similarity_map_helper(cell_info_1, cell_info_2,
610 cells_prefix_sum_1, cells_prefix_sum_2,
611 cluster_info_1, cluster_info_2,
612 matched_clusters, unmatched_clusters);
613
614 for (int testc = 0; testc < cluster_info_2.number; ++testc)
615 {
616 const double test_norm = test_normalization[testc] + double(test_normalization[testc] == 0.);
617 for (int refc = 0; refc < cluster_info_1.number; ++refc)
618 {
619 const double ref_norm = ref_normalization[refc] + double(ref_normalization[refc] == 0.);
620 similarity_map[testc * cluster_info_1.number + refc] /= std::sqrt(ref_norm * test_norm);
621 }
622 }
623
624 //In essence, the Gale-Shapley Algorithm
625
626 std::vector<std::vector<int>> sorted_GPU_matches;
627
628 sorted_GPU_matches.reserve(cluster_info_2.number);
629
630 for (int testc = 0; testc < cluster_info_2.number; ++testc)
631 {
632 std::vector<int> sorter(cluster_info_1.number);
633 std::iota(sorter.begin(), sorter.end(), 0);
634
635 std::sort(sorter.begin(), sorter.end(),
636 [&](const int a, const int b)
637 {
638 const double a_weight = similarity_map[testc * cluster_info_1.number + a];
639 const double b_weight = similarity_map[testc * cluster_info_1.number + b];
640 return a_weight > b_weight;
641 }
642 );
643
644 size_t wanted_size = 0;
645
646 for (; wanted_size < sorter.size(); ++wanted_size)
647 {
648 const double match_weight = similarity_map[testc * cluster_info_1.number + sorter[wanted_size]];
649 if (match_weight < m_min_similarity)
650 {
651 break;
652 }
653 }
654
655 //Yeah, we could do a binary search for best worst-case complexity,
656 //but we are expecting 1~2 similar clusters and the rest garbage,
657 //so we're expecting only 1~2 iterations.
658 //This actually means all that sorting is way way overkill,
659 //but we must make sure in the most general case that this works...
660
661 sorter.resize(wanted_size);
662
663 sorted_GPU_matches.push_back(std::move(sorter));
664 }
665
666 int num_iter = 0;
667
668 constexpr int max_iter = 32;
669
670 std::vector<double> matched_weights(cluster_info_1.number, -1.);
671
672 std::vector<size_t> skipped_matching(cluster_info_2.number, 0);
673
674 for (int stop_counter = 0; stop_counter < cluster_info_2.number && num_iter < max_iter; ++num_iter)
675 {
676 stop_counter = 0;
677 for (int testc = 0; testc < int(sorted_GPU_matches.size()); ++testc)
678 {
679 if (skipped_matching[testc] < sorted_GPU_matches[testc].size())
680 {
681 const int match_c = sorted_GPU_matches[testc][skipped_matching[testc]];
682 const double match_weight = similarity_map[testc * cluster_info_1.number + match_c];
683 if (match_weight >= m_min_similarity && match_weight > matched_weights[match_c])
684 {
685 const int prev_match = sch.r2t_table[match_c];
686 if (prev_match >= 0)
687 {
688 ++skipped_matching[prev_match];
689 --stop_counter;
690 }
691 sch.r2t_table[match_c] = testc;
692 matched_weights[match_c] = match_weight;
693 ++stop_counter;
694 }
695 else
696 {
697 ++skipped_matching[testc];
698 }
699 }
700 else
701 {
702 ++stop_counter;
703 }
704 }
705 }
706
707 sch.unmatched_ref_list.clear();
708 sch.unmatched_test_list.clear();
709
710 for (size_t i = 0; i < sch.r2t_table.size(); ++i)
711 {
712 const int match = sch.r2t_table[i];
713 if (match < 0)
714 {
715 sch.unmatched_ref_list.push_back(i);
716 }
717 else
718 {
719 sch.t2r_table[match] = i;
720 }
721 }
722
723 for (size_t i = 0; i < sch.t2r_table.size(); ++i)
724 {
725 if (sch.t2r_table[i] < 0)
726 {
727 sch.unmatched_test_list.push_back(i);
728 }
729 }
730
731 {
732 char message_buffer[256];
733 snprintf(message_buffer, 256,
734 "%2d: %5d / %5d || %5d / %5d || %3d || %5d | %5d || %5d",
735 num_iter,
736 int(sch.r2t_table.size()) - int(sch.unmatched_ref_list.size()), int(sch.r2t_table.size()),
737 int(sch.t2r_table.size()) - int(sch.unmatched_test_list.size()), int(sch.t2r_table.size()),
738 int(sch.r2t_table.size()) - int(sch.t2r_table.size()),
739 int(sch.unmatched_ref_list.size()),
740 int(sch.unmatched_test_list.size()),
741 int(sch.unmatched_ref_list.size()) - int(sch.unmatched_test_list.size())
742 );
743 ATH_MSG_INFO(message_buffer);
744 }
745
746 return StatusCode::SUCCESS;
747
748}
static void build_similarity_map_helper(const CaloRecGPU::CellInfoArr &, const CaloRecGPU::CellInfoArr &, const std::vector< int > &cells_prefix_sum_1, const std::vector< int > &cells_prefix_sum_2, const CaloRecGPU::ClusterInfoArr &cluster_info_1, const CaloRecGPU::ClusterInfoArr &cluster_info_2, WeighMatch match, WeighNotMatch not_match)
static Double_t a
Gaudi::Property< float > m_seedThreshold
Seed threshold to use for cluster matching.
Gaudi::Property< float > m_termThreshold
Cell (terminal) threshold to use for cluster matching.
Gaudi::Property< float > m_growThreshold
Neighbor (growing) threshold to use for cluster matching.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
constexpr int get_cell_with_hash_ID(const int index, const bool is_complete=false) const
constexpr bool is_bad(const int cell, const bool treat_L1_predicted_as_good=false, const bool is_complete=false) const
GPU version of CaloBadCellHelper::isBad.

◆ match_clusters_perfectly()

StatusCode CaloGPUClusterAndCellDataMonitor::match_clusters_perfectly ( sample_comparisons_holder & sch,
const CaloRecGPU::ConstantDataHolder & constant_data,
const CaloRecGPU::CellInfoArr & cell_info_1,
const CaloRecGPU::CellInfoArr & cell_info_2,
const std::vector< int > & cells_prefix_sum_1,
const std::vector< int > & cells_prefix_sum_2,
const CaloRecGPU::ClusterInfoArr & cluster_info_1,
const CaloRecGPU::ClusterInfoArr & cluster_info_2,
const bool match_without_shared ) const
private

Definition at line 750 of file CaloGPUClusterAndCellDataMonitor.cxx.

759{
760 sch.r2t_table.clear();
761 sch.r2t_table.resize(cluster_info_1.number, -1);
762
763 sch.t2r_table.clear();
764 sch.t2r_table.resize(cluster_info_2.number, -1);
765
766 std::vector<char> match_possibilities(cluster_info_1.number * cluster_info_2.number, 1);
767
768 auto matched_clusters = [&]([[maybe_unused]] const int hash_ID, const std::vector<std::pair<int, float>> & v1, const std::vector<std::pair<int, float>> & v2)
769 {
770#if CALORECGPU_DATA_MONITOR_EXTRA_PRINTOUTS && CALORECGPU_DATA_MONITOR_EXTRA_PRINTOUTS > 1
771 msg(MSG::INFO) << "MATCH: " << hash_ID << " <> |";
772 for (const auto & p : v1)
773 {
774 msg() << " (" << p.first << ", " << p.second << ")";
775 }
776 msg() << " |";
777 for (const auto & p : v2)
778 {
779 msg() << " (" << p.first << ", " << p.second << ")";
780 }
781 msg() << endmsg;
782#endif
783
784 if (match_without_shared && (v1.size() > 1 || v2.size() > 1))
785 {
786 return;
787 }
788
789 for (const auto & t_p : v2)
790 {
791 for (int rc = 0; rc < cluster_info_1.number; ++rc)
792 {
793 bool is_possibility = false;
794
795 for (const auto & p: v1)
796 {
797 if (p.first == rc)
798 {
799 is_possibility = true;
800 break;
801 }
802 }
803
804 if (is_possibility)
805 {
806 continue;
807 }
808
809 match_possibilities[t_p.first * cluster_info_1.number + rc] = 0;
810 }
811 }
812
813 for (const auto & r_p : v1)
814 {
815 for (int tc = 0; tc < cluster_info_2.number; ++tc)
816 {
817 bool is_possibility = false;
818
819 for (const auto & p: v2)
820 {
821 if (p.first == tc)
822 {
823 is_possibility = true;
824 break;
825 }
826 }
827
828 if (is_possibility)
829 {
830 continue;
831 }
832
833 match_possibilities[tc * cluster_info_1.number + r_p.first] = 0;
834 }
835 }
836 };
837
838 auto unmatched_clusters = [&](const bool is_test, [[maybe_unused]] const int hash_ID, const std::vector<std::pair<int, float>> & v)
839 {
840#if CALORECGPU_DATA_MONITOR_EXTRA_PRINTOUTS
841 msg(MSG::INFO) << "UNMATCH: " << hash_ID << " <> | " << is_test << " |";
842 for (const auto & p : v)
843 {
844 msg() << " (" << p.first << ", " << p.second << ")";
845 }
846 msg() << endmsg;
847#endif
848
849 if (match_without_shared && v.size() > 1)
850 {
851 return;
852 }
853
854 const int cluster_number = is_test ? cluster_info_2.number : cluster_info_1.number;
855
856 for (const auto & p : v)
857 {
858 for (int i = 0; i < cluster_number; ++i)
859 {
860 const int this_index = (is_test ? p.first * cluster_info_1.number + i : i * cluster_info_1.number + p.first);
861 match_possibilities[this_index] = 0;
862 }
863 }
864 };
865
866 build_similarity_map_helper(cell_info_1, cell_info_2,
867 cells_prefix_sum_1, cells_prefix_sum_2,
868 cluster_info_1, cluster_info_2,
869 matched_clusters, unmatched_clusters);
870
871 for (int testc = 0; testc < cluster_info_2.number; ++testc)
872 {
873 for (int refc = 0; refc < cluster_info_1.number; ++refc)
874 {
875 if (match_possibilities[testc * cluster_info_1.number + refc] > 0)
876 {
877 sch.r2t_table[refc] = testc;
878 sch.t2r_table[testc] = refc;
879 }
880 }
881 }
882
883 for (int refc = 0; refc < cluster_info_1.number; ++refc)
884 {
885 if (sch.r2t_table[refc] < 0)
886 {
887 sch.unmatched_ref_list.push_back(refc);
888 }
889 }
890
891 for (int testc = 0; testc < cluster_info_2.number; ++testc)
892 {
893 if (sch.t2r_table[testc] < 0)
894 {
895 sch.unmatched_test_list.push_back(testc);
896 }
897 }
898
899 {
900 char message_buffer[256];
901 snprintf(message_buffer, 256,
902 "%2d: %5d / %5d || %5d / %5d || %3d || %5d | %5d || %5d",
903 0,
904 int(sch.r2t_table.size()) - int(sch.unmatched_ref_list.size()), int(sch.r2t_table.size()),
905 int(sch.t2r_table.size()) - int(sch.unmatched_test_list.size()), int(sch.t2r_table.size()),
906 int(sch.r2t_table.size()) - int(sch.t2r_table.size()),
907 int(sch.unmatched_ref_list.size()),
908 int(sch.unmatched_test_list.size()),
909 int(sch.unmatched_ref_list.size()) - int(sch.unmatched_test_list.size())
910 );
911 ATH_MSG_INFO(message_buffer);
912 }
913
914 return StatusCode::SUCCESS;
915
916}
static Double_t tc
static Double_t rc

◆ update_cell_representation()

StatusCode CaloGPUClusterAndCellDataMonitor::update_cell_representation ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
const CaloRecGPU::CellInfoArr * cell_info,
CaloRecGPU::ClusterInfoArr * clusters,
std::vector< int > & cells_prefix_sum ) const
private

Update the cell representation so the cells-in-clusters are ordered by index and have a prefix sum.

Definition at line 287 of file CaloGPUClusterAndCellDataMonitor.cxx.

292{
293 if (!clusters->has_cells_per_cluster())
294 {
295 for (int i = 0; i <= clusters->number; ++i)
296 {
297 clusters->cellsPrefixSum[i] = 0;
298 }
299
300 for (int i = 0; i < clusters->number_cells; ++i)
301 {
302 clusters->get_extra_cell_info(i) = clusters->cells.tags[i];
303 //We overwrite some non-calculated moments that we shouldn't even have
304 //at this point...
305 }
306
307 const int old_num_cells = clusters->number_cells;
308 clusters->number_cells = 0;
309 for (int i = 0; i < old_num_cells; ++i)
310 {
311 ClusterTag this_tag = clusters->get_extra_cell_info(i);
312
313 const int first_cluster = this_tag.is_part_of_cluster() ? this_tag.cluster_index() : -1;
314
315 const int second_cluster = this_tag.is_part_of_cluster() && this_tag.is_shared_between_clusters() ? this_tag.secondary_cluster_index() : -1;
316
317 const float secondary_cluster_weight = (this_tag.is_part_of_cluster() && this_tag.is_shared_between_clusters() ?
318 float_unhack(this_tag.secondary_cluster_weight()) : 0.f);
319
320 if (second_cluster >= 0)
321 {
322 if (second_cluster >= clusters->number)
323 {
324 ATH_MSG_WARNING("Impossible cell assignment: " << i << " " << second_cluster << " (" << std::hex << this_tag << std::dec << ")");
325 }
326 clusters->cells.indices[clusters->number_cells] = i;
327 clusters->cellWeights[clusters->number_cells] = secondary_cluster_weight;
328 clusters->clusterIndices[clusters->number_cells] = second_cluster;
329 clusters->number_cells += 1;
330 clusters->cellsPrefixSum[second_cluster + 1] += 1;
331 }
332
333 if (first_cluster >= 0)
334 {
335 if (first_cluster >= clusters->number)
336 {
337 ATH_MSG_WARNING("Impossible cell assignment: " << i << " " << first_cluster << " (" << std::hex << this_tag << std::dec << ")");
338 }
339 clusters->cells.indices[clusters->number_cells] = i;
340 clusters->cellWeights[clusters->number_cells] = 1.0f - secondary_cluster_weight;
341 clusters->clusterIndices[clusters->number_cells] = first_cluster;
342 clusters->number_cells += 1;
343 clusters->cellsPrefixSum[first_cluster + 1] += 1;
344 }
345 }
346 int prefix = 0;
347 for (int i = 0; i <= clusters->number; ++i)
348 {
349 prefix += clusters->cellsPrefixSum[i];
350
351 clusters->cellsPrefixSum[i] = prefix;
352 }
353 }
354
355 //Do note that, from here on, the assignment between cells and clusters is broken:
356 //we simply have a list of cells in clusters...
357
358 std::vector<int> cell_orderer(clusters->number_cells);
359
360 std::iota(cell_orderer.begin(), cell_orderer.end(), 0);
361
362 std::sort(cell_orderer.begin(), cell_orderer.end(), [&](const int a, const int b)
363 {
364 if (clusters->cells.indices[a] == clusters->cells.indices[b])
365 {
366 return clusters->cellWeights[a] < clusters->cellWeights[b];
367 }
368 else
369 {
370 const int hash_ID_a = cell_info->get_hash_ID(clusters->cells.indices[a]);
371 const int hash_ID_b = cell_info->get_hash_ID(clusters->cells.indices[b]);
372 if (hash_ID_a < 0)
373 {
374 ATH_MSG_WARNING("Attempting to sort impossible cell: " << a << " " << hash_ID_a);
375 }
376 if (hash_ID_b < 0)
377 {
378 ATH_MSG_WARNING("Attempting to sort impossible cell: " << b << " " << hash_ID_b);
379 }
380 return hash_ID_a < hash_ID_b;
381 }
382 } );
383
384 auto order_array = [&](auto * ptr)
385 {
386 std::vector<std::decay_t<decltype(ptr[0])>> prev(clusters->number_cells);
387
388 for (int i = 0; i < clusters->number_cells; ++i)
389 {
390 prev[i] = ptr[i];
391 }
392
393 for (int i = 0; i < clusters->number_cells; ++i)
394 {
395 ptr[i] = prev[cell_orderer[i]];
396 }
397 };
398
399 order_array(clusters->cells.indices);
400 order_array(clusters->cellWeights);
401 order_array(clusters->clusterIndices);
402
403 cells_prefix_sum.clear();
404 cells_prefix_sum.resize(NCaloCells + 1, 0);
405
406 int prev_cell_index = -1;
407 int cell_count = 0;
408
409 for (int i = 0; i < clusters->number_cells; ++i)
410 {
411 const int this_cell_index = clusters->cells.indices[i];
412
413 if (this_cell_index != prev_cell_index)
414 {
415 //prev_cell_index is used directly as an index into a c-style array, so must
416 //not be negative (should also check upper bound?)
417 const int prev_cell_ID = (prev_cell_index < 0 ? -1 : cell_info->get_hash_ID(prev_cell_index));
418 const int this_cell_ID = cell_info->get_hash_ID(this_cell_index);
419
420 for (int j = prev_cell_ID + 1; j <= this_cell_ID; ++j)
421 {
422 cells_prefix_sum[j] = cell_count;
423 }
424 }
425
426 ++cell_count;
427
428 prev_cell_index = this_cell_index;
429 }
430
431 if (clusters->number_cells > 0)
432 {
433 for (int i = cell_info->get_hash_ID(clusters->cells.indices[clusters->number_cells - 1]); i <= NCaloCells; ++i)
434 {
435 cells_prefix_sum[i + 1] = cell_count;
436 }
437 }
438
439 return StatusCode::SUCCESS;
440}
#define ATH_MSG_WARNING(x)
float float_unhack(const unsigned int bits)
void * ptr(T *p)
Definition SGImplSvc.cxx:74
constexpr int32_t secondary_cluster_index() const
constexpr int32_t secondary_cluster_weight() const
constexpr bool is_shared_between_clusters() const
constexpr bool is_part_of_cluster() const
constexpr int32_t cluster_index() const

◆ update_plots() [1/4]

StatusCode CaloGPUClusterAndCellDataMonitor::update_plots ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
const xAOD::CaloClusterContainer * cluster_collection_ptr,
const CaloClusterCollectionProcessor * tool ) const
overridevirtual

Definition at line 173 of file CaloGPUClusterAndCellDataMonitor.cxx.

177{
178 if (filter_tool_by_name(tool->name()))
179 {
180 SG::ReadHandle<CaloCellContainer> cell_collection(m_cellsKey, ctx);
181
182 EventDataHolder ed;
183
184 ed.allocate(false);
185
186 ed.importCells(static_cast<const CaloCellContainer *>(&(*cell_collection)), m_missingCellsToFill);
187
188 ed.importClusters(cluster_collection_ptr, MomentsOptionsArray::all(), false, true, true, true, m_missingCellsToFill);
189
190 std::vector<int> cells_prefix_sum;
191
192 ATH_CHECK(update_cell_representation(ctx, constant_data, ed.m_cell_info, ed.m_clusters, cells_prefix_sum));
193
194 return add_data(ctx, constant_data, ed.m_cell_info, ed.m_clusters, cells_prefix_sum, tool->name());
195 }
196 else
197 {
198 return StatusCode::SUCCESS;
199 }
200}
StatusCode add_data(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr *cell_info, const CaloRecGPU::ClusterInfoArr *clusters, const std::vector< int > &cells_prefix_sum, const std::string &tool_name) const
Gaudi::Property< std::vector< int > > m_missingCellsToFill
Cell indices to fill as disabled cells (useful if the cell vector is always missing the same cells).
bool filter_tool_by_name(const std::string &tool_name) const
Returns true if this tool should be plotted for.
StatusCode update_cell_representation(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr *cell_info, CaloRecGPU::ClusterInfoArr *clusters, std::vector< int > &cells_prefix_sum) const
Update the cell representation so the cells-in-clusters are ordered by index and have a prefix sum.
CaloRecGPU::Helpers::CUDA_pinned_CPU_object< CaloRecGPU::CellInfoArr > m_cell_info
CaloRecGPU::Helpers::CUDA_pinned_CPU_object< CaloRecGPU::ClusterInfoArr > m_clusters
void allocate(const bool also_GPU=true)
static MomentsOptionsArray all()

◆ update_plots() [2/4]

StatusCode CaloGPUClusterAndCellDataMonitor::update_plots ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
const xAOD::CaloClusterContainer * cluster_collection_ptr,
const CaloRecGPU::EventDataHolder & event_data,
const CaloClusterGPUProcessor * tool ) const
overridevirtual

Definition at line 225 of file CaloGPUClusterAndCellDataMonitor.cxx.

230{
231 if (filter_tool_by_name(tool->name()))
232 {
235
236 std::vector<int> cells_prefix_sum;
237
238 ATH_CHECK(update_cell_representation(ctx, constant_data, cell_info, clusters, cells_prefix_sum));
239
240 return add_data(ctx, constant_data, cell_info, clusters, cells_prefix_sum, tool->name());
241 }
242 else
243 {
244 return StatusCode::SUCCESS;
245 }
246}
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellInfoArr > m_cell_info_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::ClusterInfoArr > m_clusters_dev
SimpleHolder< T, MemoryContext::CPU, true > CPU_object
Holds an object of type T in CPU memory.

◆ update_plots() [3/4]

StatusCode CaloGPUClusterAndCellDataMonitor::update_plots ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
const xAOD::CaloClusterContainer * cluster_collection_ptr,
const CaloRecGPU::EventDataHolder & event_data,
const ICaloClusterGPUInputTransformer * tool ) const
overridevirtual

Definition at line 202 of file CaloGPUClusterAndCellDataMonitor.cxx.

207{
208 if (filter_tool_by_name(tool->name()))
209 {
212
213 std::vector<int> cells_prefix_sum;
214
215 ATH_CHECK(update_cell_representation(ctx, constant_data, cell_info, clusters, cells_prefix_sum));
216
217 return add_data(ctx, constant_data, cell_info, clusters, cells_prefix_sum, tool->name());
218 }
219 else
220 {
221 return StatusCode::SUCCESS;
222 }
223}

◆ update_plots() [4/4]

StatusCode CaloGPUClusterAndCellDataMonitor::update_plots ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
const xAOD::CaloClusterContainer * cluster_collection_ptr,
const CaloRecGPU::EventDataHolder & event_data,
const ICaloClusterGPUOutputTransformer * tool ) const
overridevirtual

Definition at line 248 of file CaloGPUClusterAndCellDataMonitor.cxx.

253{
254 if (filter_tool_by_name(tool->name()))
255 {
256 SG::ReadHandle<CaloCellContainer> cell_collection(m_cellsKey, ctx);
257
258 EventDataHolder ed;
259
260 ed.allocate(false);
261
262 ed.importCells(static_cast<const CaloCellContainer *>(&(*cell_collection)), m_missingCellsToFill);
263
264 ed.importClusters(cluster_collection_ptr, MomentsOptionsArray::all(), false, true, true, true, m_missingCellsToFill);
265
266 std::vector<int> cells_prefix_sum;
267
268 ATH_CHECK(update_cell_representation(ctx, constant_data, ed.m_cell_info, ed.m_clusters, cells_prefix_sum));
269
270 return add_data(ctx, constant_data, ed.m_cell_info, ed.m_clusters, cells_prefix_sum, tool->name());
271 }
272 else
273 {
274 return StatusCode::SUCCESS;
275 }
276}

◆ update_plots_end()

StatusCode CaloGPUClusterAndCellDataMonitor::update_plots_end ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
const xAOD::CaloClusterContainer * cluster_collection_ptr ) const
overridevirtual

Definition at line 145 of file CaloGPUClusterAndCellDataMonitor.cxx.

148{
149 ATH_MSG_INFO("");
150
151 for (const auto & combination : m_toolCombinations)
152 {
153 if (combination.index_ref < 0 || combination.index_test < 0)
154 {
155 ATH_MSG_WARNING("Invalid tool combination, please check your configuration! " << combination.prefix);
156 continue;
157 }
158 ATH_CHECK( add_combination(ctx, constant_data, combination.index_ref, combination.index_test, combination.prefix,
159 combination.match_in_energy, combination.match_without_shared, combination.match_perfectly) );
160 }
161
162 ATH_MSG_INFO("");
163
164 if (m_numToolsToKeep > 0)
165 {
166 m_storageHolder.release_one();
167 //Release the tool storage.
168 }
169
170 return StatusCode::SUCCESS;
171}
StatusCode add_combination(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const int index_1, const int index_2, const std::string &prefix, const bool match_in_energy, const bool match_without_shared, const bool match_perfectly) const

◆ update_plots_start()

StatusCode CaloGPUClusterAndCellDataMonitor::update_plots_start ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
const xAOD::CaloClusterContainer * cluster_collection_ptr ) const
overridevirtual

Definition at line 120 of file CaloGPUClusterAndCellDataMonitor.cxx.

123{
125 {
126 std::lock_guard<std::mutex> lock_guard(m_mutex);
128 {
130 //We have the mutex.
131 //It's safe.
132 ATH_CHECK( dhis->initialize_plotted_variables() );
134 }
135 }
136 if (m_numToolsToKeep > 0)
137 {
138 m_storageHolder.get_one().resize(m_numToolsToKeep);
139 }
140 //Allocate a vector of data holders for this thread and resize it to the necessary size.
141
142 return StatusCode::SUCCESS;
143}
std::map< std::string, std::atomic< size_t > > m_numClustersPerTool ATLAS_THREAD_SAFE
Counts the total number of clusters per tool.
CaloGPUClusterAndCellDataMonitor(const std::string &type, const std::string &name, const IInterface *parent)
std::mutex m_mutex
This mutex is locked to ensure only one thread detects the monotired variables.

Member Data Documentation

◆ ATLAS_THREAD_SAFE [1/2]

std::map<std::string, std::atomic<size_t> > m_numClustersPerTool CaloGPUClusterAndCellDataMonitor::ATLAS_THREAD_SAFE
mutableprivate

Counts the total number of clusters per tool.

Definition at line 268 of file CaloGPUClusterAndCellDataMonitor.h.

◆ ATLAS_THREAD_SAFE [2/2]

CaloRecGPU::Helpers::separate_thread_holder<std::vector<per_tool_storage> > m_storageHolder CaloGPUClusterAndCellDataMonitor::ATLAS_THREAD_SAFE
mutableprivate

Stores the intermediate results needed for tool-level matching.

Definition at line 282 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_calo_id

const CaloCell_ID* CaloGPUClusterAndCellDataMonitor::m_calo_id {nullptr}
private

Pointer to Calo ID Helper.

Definition at line 240 of file CaloGPUClusterAndCellDataMonitor.h.

240{nullptr};

◆ m_cellPropertiesToDo

std::vector<bool> CaloGPUClusterAndCellDataMonitor::m_cellPropertiesToDo
private

Definition at line 288 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_cellsKey

SG::ReadHandleKey<CaloCellContainer> CaloGPUClusterAndCellDataMonitor::m_cellsKey {this, "CellsName", "", "Name(s) of Cell Containers"}
private

vector of names of the cell containers to use as input.

Definition at line 193 of file CaloGPUClusterAndCellDataMonitor.h.

193{this, "CellsName", "", "Name(s) of Cell Containers"};

◆ m_cellTypesToDo

std::vector<bool> CaloGPUClusterAndCellDataMonitor::m_cellTypesToDo
private

Definition at line 289 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_clusterPropertiesToDo

std::vector<bool> CaloGPUClusterAndCellDataMonitor::m_clusterPropertiesToDo
private

Control which properties will actually be calculated and stored.

In principle, should be automagically filled based on the booked histograms.

Definition at line 287 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_comparedCellPropertiesToDo

std::vector<bool> CaloGPUClusterAndCellDataMonitor::m_comparedCellPropertiesToDo
private

Definition at line 289 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_comparedCellTypesToDo

std::vector<bool> CaloGPUClusterAndCellDataMonitor::m_comparedCellTypesToDo
private

Definition at line 290 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_comparedClusterPropertiesToDo

std::vector<bool> CaloGPUClusterAndCellDataMonitor::m_comparedClusterPropertiesToDo
private

Definition at line 287 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_doCells

bool CaloGPUClusterAndCellDataMonitor::m_doCells = false
private

If no properties are asked for, skip the relevant loops entirely...

Definition at line 294 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_doClusters

bool CaloGPUClusterAndCellDataMonitor::m_doClusters = false
private

Definition at line 294 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_doCombinedCells

bool CaloGPUClusterAndCellDataMonitor::m_doCombinedCells = false
private

Definition at line 294 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_doCombinedClusters

bool CaloGPUClusterAndCellDataMonitor::m_doCombinedClusters = false
private

Definition at line 294 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_extraComparedClusterPropertiesToDo

std::vector<bool> CaloGPUClusterAndCellDataMonitor::m_extraComparedClusterPropertiesToDo
private

Definition at line 288 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_extraThingsToDo

std::vector<bool> CaloGPUClusterAndCellDataMonitor::m_extraThingsToDo
private

Definition at line 290 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_grow_weight

double CaloGPUClusterAndCellDataMonitor::m_grow_weight = 250.
private

Definition at line 235 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_growThreshold

Gaudi::Property<float> CaloGPUClusterAndCellDataMonitor::m_growThreshold {this, "NeighborThreshold", 2., "Neighbor (grow) threshold (in units of noise Sigma)"}
private

Neighbor (growing) threshold to use for cluster matching.

Definition at line 183 of file CaloGPUClusterAndCellDataMonitor.h.

183{this, "NeighborThreshold", 2., "Neighbor (grow) threshold (in units of noise Sigma)"};

◆ m_matchingOptions

Gaudi::Property<MatchingOptions> CaloGPUClusterAndCellDataMonitor::m_matchingOptions {this, "ClusterMatchingParameters", {}, "Parameters for the cluster matching algorithm"}
private

Option for adjusting the parameters for the cluster matching algorithm.

Definition at line 223 of file CaloGPUClusterAndCellDataMonitor.h.

224{this, "ClusterMatchingParameters", {}, "Parameters for the cluster matching algorithm"};

◆ m_min_similarity

double CaloGPUClusterAndCellDataMonitor::m_min_similarity = 0.5
private

Parameters for the cluster matching algorithm, for easier access.

Definition at line 235 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_missingCellsToFill

Gaudi::Property<std::vector<int> > CaloGPUClusterAndCellDataMonitor::m_missingCellsToFill {this, "MissingCellsToFill", {}, "Force fill these cells as disabled on empty containers."}
private

Cell indices to fill as disabled cells (useful if the cell vector is always missing the same cells).

Definition at line 201 of file CaloGPUClusterAndCellDataMonitor.h.

201{this, "MissingCellsToFill", {}, "Force fill these cells as disabled on empty containers."};

◆ m_moniTool

ToolHandle< GenericMonitoringTool > CaloGPUClusterAndCellDataMonitor::m_moniTool { this, "MonitoringTool", "", "Monitoring tool" }
private

Monitoring tool.

Definition at line 197 of file CaloGPUClusterAndCellDataMonitor.h.

197{ this, "MonitoringTool", "", "Monitoring tool" };

◆ m_mutex

std::mutex CaloGPUClusterAndCellDataMonitor::m_mutex
mutableprivate

This mutex is locked to ensure only one thread detects the monotired variables.

Definition at line 305 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_numEvents

size_t CaloGPUClusterAndCellDataMonitor::m_numEvents = 0
private

Counts the number of events.

Definition at line 271 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_numToolsToKeep

int CaloGPUClusterAndCellDataMonitor::m_numToolsToKeep = 0
private

The number of tools that will actually need to be kept in memory for combined plotting.

Definition at line 254 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_pairsToPlot

Gaudi::Property< std::vector<SimpleToolPair> > CaloGPUClusterAndCellDataMonitor::m_pairsToPlot {this, "PairsToPlot", {}, "Pairs of tools to be compared and plotted"}
private

Pairs of tools to compare.

Definition at line 218 of file CaloGPUClusterAndCellDataMonitor.h.

219{this, "PairsToPlot", {}, "Pairs of tools to be compared and plotted"};

◆ m_plottedVariablesInitialized

std::atomic<bool> CaloGPUClusterAndCellDataMonitor::m_plottedVariablesInitialized
mutableprivate

A flag to signal that the variables to be monitored have been detected based on the booked histograms.

Definition at line 300 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_seed_weight

double CaloGPUClusterAndCellDataMonitor::m_seed_weight = 5000.
private

Definition at line 235 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_seedThreshold

Gaudi::Property<float> CaloGPUClusterAndCellDataMonitor::m_seedThreshold {this, "SeedThreshold", 4., "Seed threshold (in units of noise Sigma)"}
private

Seed threshold to use for cluster matching.

Definition at line 188 of file CaloGPUClusterAndCellDataMonitor.h.

188{this, "SeedThreshold", 4., "Seed threshold (in units of noise Sigma)"};

◆ m_terminal_weight

double CaloGPUClusterAndCellDataMonitor::m_terminal_weight = 10.
private

Definition at line 235 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_termThreshold

Gaudi::Property<float> CaloGPUClusterAndCellDataMonitor::m_termThreshold {this, "CellThreshold", 0., "Cell (terminal) threshold (in units of noise Sigma)"}
private

Cell (terminal) threshold to use for cluster matching.

Definition at line 178 of file CaloGPUClusterAndCellDataMonitor.h.

178{this, "CellThreshold", 0., "Cell (terminal) threshold (in units of noise Sigma)"};

◆ m_toolCombinations

std::vector<pair_to_plot> CaloGPUClusterAndCellDataMonitor::m_toolCombinations
private

Definition at line 265 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_toolsToCheckFor

std::map<std::string, int> CaloGPUClusterAndCellDataMonitor::m_toolsToCheckFor
private

Map of the strings corresponding to all the tools that will be relevant for plotting (individually or in comparisons) to the index that will be used to identify the tool within the plotter.

(Indices of -1 signal tools that are only plotted individually, no need to keep them.)

Definition at line 248 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_toolsToPlot

Gaudi::Property<std::vector<SimpleSingleTool> > CaloGPUClusterAndCellDataMonitor::m_toolsToPlot {this, "ToolsToPlot", {}, "Tools to be plotted individually"}
private

Tools to plot individually.

Warning
If a tool appears more than once with different identifiers, the last one is used.

Definition at line 213 of file CaloGPUClusterAndCellDataMonitor.h.

214{this, "ToolsToPlot", {}, "Tools to be plotted individually"};

◆ m_toolToIdMap

std::map<std::string, std::string> CaloGPUClusterAndCellDataMonitor::m_toolToIdMap
private

Maps tools to their respective identifying prefix for variables.

Definition at line 251 of file CaloGPUClusterAndCellDataMonitor.h.


The documentation for this class was generated from the following files: