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 32 of file CaloGPUClusterAndCellDataMonitor.cxx.

32 :
33 base_class(type, name, parent),
35{
36}
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 1715 of file CaloGPUClusterAndCellDataMonitor.cxx.

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

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

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

◆ finalize_plots()

StatusCode CaloGPUClusterAndCellDataMonitor::finalize_plots ( ) const
overridevirtual

Definition at line 107 of file CaloGPUClusterAndCellDataMonitor.cxx.

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

◆ initialize()

StatusCode CaloGPUClusterAndCellDataMonitor::initialize ( )
overridevirtual

Definition at line 38 of file CaloGPUClusterAndCellDataMonitor.cxx.

39{
40 ATH_CHECK( m_cellsKey.initialize() );
41
42 ATH_CHECK( detStore()->retrieve(m_calo_id, "CaloCell_ID") );
43
44 const std::string this_name = this->name();
45
46 const std::string algorithm_name_prefix = this_name.substr(0, this_name.rfind('.'));
47 //This is so we take into account the fact that tools
48 //are prefixed with the parent algorithm's name.
49
50 auto final_string = [& algorithm_name_prefix](const std::string & unpref_str) -> std::string
51 {
52 return algorithm_name_prefix + "." + unpref_str;
53 };
54
56
57 m_min_similarity = opts.min_similarity;
58 m_seed_weight = opts.seed_w;
59 m_grow_weight = opts.grow_w;
60 m_terminal_weight = opts.term_w;
61
62 for (const auto & tool : m_toolsToPlot)
63 {
64 const std::string tool_name = final_string(tool.tool);
65 m_toolToIdMap[tool_name] = tool.plot_id;
66 m_toolsToCheckFor[tool_name] = -1;
67 }
68
69 auto add_tool_from_pair = [this](const std::string & name) -> int
70 {
71 if (!m_toolsToCheckFor.count(name))
72 {
74 m_toolToIdMap[name] = "";
75 return m_numToolsToKeep++;
76 }
77 else
78 {
79 const int current = m_toolsToCheckFor[name];
80 if (current >= 0)
81 {
82 return current;
83 }
84 else
85 {
87 return m_numToolsToKeep++;
88 }
89 }
90 };
91
92 for (const auto & pair : m_pairsToPlot)
93 {
94 const int first_index = add_tool_from_pair(final_string(pair.tool_ref));
95 const int second_index = add_tool_from_pair(final_string(pair.tool_test));
96 m_toolCombinations.emplace_back(pair_to_plot{first_index, second_index, pair.plot_id,
97 pair.match_in_energy,
98 pair.match_without_shared,
99 pair.match_perfectly});
100 }
101
102 ATH_CHECK( m_moniTool.retrieve() );
103
104 return StatusCode::SUCCESS;
105}
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.)
retrieve(aClass, aKey=None)
Definition PyKernel.py:110

◆ initialize_plotted_variables()

StatusCode CaloGPUClusterAndCellDataMonitor::initialize_plotted_variables ( )
private

Definition at line 1388 of file CaloGPUClusterAndCellDataMonitor.cxx.

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

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

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

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

178{
179 if (filter_tool_by_name(tool->name()))
180 {
181 SG::ReadHandle<CaloCellContainer> cell_collection(m_cellsKey, ctx);
182
183 EventDataHolder ed;
184
185 ed.allocate(false);
186
187 ed.importCells(static_cast<const CaloCellContainer *>(&(*cell_collection)), m_missingCellsToFill);
188
189 ed.importClusters(cluster_collection_ptr, MomentsOptionsArray::all(), false, true, true, true, m_missingCellsToFill);
190
191 std::vector<int> cells_prefix_sum;
192
193 ATH_CHECK(update_cell_representation(ctx, constant_data, ed.m_cell_info, ed.m_clusters, cells_prefix_sum));
194
195 return add_data(ctx, constant_data, ed.m_cell_info, ed.m_clusters, cells_prefix_sum, tool->name());
196 }
197 else
198 {
199 return StatusCode::SUCCESS;
200 }
201}
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 226 of file CaloGPUClusterAndCellDataMonitor.cxx.

231{
232 if (filter_tool_by_name(tool->name()))
233 {
236
237 std::vector<int> cells_prefix_sum;
238
239 ATH_CHECK(update_cell_representation(ctx, constant_data, cell_info, clusters, cells_prefix_sum));
240
241 return add_data(ctx, constant_data, cell_info, clusters, cells_prefix_sum, tool->name());
242 }
243 else
244 {
245 return StatusCode::SUCCESS;
246 }
247}
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 203 of file CaloGPUClusterAndCellDataMonitor.cxx.

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

◆ 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 249 of file CaloGPUClusterAndCellDataMonitor.cxx.

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

◆ 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 146 of file CaloGPUClusterAndCellDataMonitor.cxx.

149{
150 ATH_MSG_INFO("");
151
152 for (const auto & combination : m_toolCombinations)
153 {
154 if (combination.index_ref < 0 || combination.index_test < 0)
155 {
156 ATH_MSG_WARNING("Invalid tool combination, please check your configuration! " << combination.prefix);
157 continue;
158 }
159 ATH_CHECK( add_combination(ctx, constant_data, combination.index_ref, combination.index_test, combination.prefix,
160 combination.match_in_energy, combination.match_without_shared, combination.match_perfectly) );
161 }
162
163 ATH_MSG_INFO("");
164
165 if (m_numToolsToKeep > 0)
166 {
167 m_storageHolder.release_one();
168 //Release the tool storage.
169 }
170
171 return StatusCode::SUCCESS;
172}
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 121 of file CaloGPUClusterAndCellDataMonitor.cxx.

124{
126 {
127 std::lock_guard<std::mutex> lock_guard(m_mutex);
129 {
131 //We have the mutex.
132 //It's safe.
133 ATH_CHECK( dhis->initialize_plotted_variables() );
135 }
136 }
137 if (m_numToolsToKeep > 0)
138 {
139 m_storageHolder.get_one().resize(m_numToolsToKeep);
140 }
141 //Allocate a vector of data holders for this thread and resize it to the necessary size.
142
143 return StatusCode::SUCCESS;
144}
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: