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

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

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

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

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

Definition at line 763 of file CaloGPUClusterAndCellDataMonitor.cxx.

769{
770 sch.r2t_table.clear();
771 sch.r2t_table.resize(cluster_info_1.number, -1);
772
773 sch.t2r_table.clear();
774 sch.t2r_table.resize(cluster_info_2.number, -1);
775
776 std::vector<char> match_possibilities(cluster_info_1.number * cluster_info_2.number, 1);
777
778 auto matched_clusters = [&]([[maybe_unused]] const int cell, const std::vector<std::pair<int, float>> & v1, const std::vector<std::pair<int, float>> & v2)
779 {
780#if CALORECGPU_DATA_MONITOR_EXTRA_PRINTOUTS
781 msg(MSG::INFO) << "MATCH: " << cell << " <> |";
782 for (const auto & p : v1)
783 {
784 msg() << " (" << p.first << ", " << p.second << ")";
785 }
786 msg() << " |";
787 for (const auto & p : v2)
788 {
789 msg() << " (" << p.first << ", " << p.second << ")";
790 }
791 msg() << endmsg;
792#endif
793
794 if (match_without_shared && (v1.size() > 1 || v2.size() > 1))
795 {
796 return;
797 }
798
799 for (const auto & t_p : v2)
800 {
801 for (int rc = 0; rc < cluster_info_1.number; ++rc)
802 {
803 bool is_possibility = false;
804
805 for (const auto & p: v1)
806 {
807 if (p.first == rc)
808 {
809 is_possibility = true;
810 break;
811 }
812 }
813
814 if (is_possibility)
815 {
816 continue;
817 }
818
819 match_possibilities[t_p.first * cluster_info_1.number + rc] = 0;
820 }
821 }
822
823 for (const auto & r_p : v1)
824 {
825 for (int tc = 0; tc < cluster_info_2.number; ++tc)
826 {
827 bool is_possibility = false;
828
829 for (const auto & p: v2)
830 {
831 if (p.first == tc)
832 {
833 is_possibility = true;
834 break;
835 }
836 }
837
838 if (is_possibility)
839 {
840 continue;
841 }
842
843 match_possibilities[tc * cluster_info_1.number + r_p.first] = 0;
844 }
845 }
846 };
847
848 auto unmatched_clusters = [&](const bool is_test, [[maybe_unused]] const int cell, const std::vector<std::pair<int, float>> & v)
849 {
850#if CALORECGPU_DATA_MONITOR_EXTRA_PRINTOUTS
851 msg(MSG::INFO) << "UNMATCH: " << cell << " <> | " << is_test << " |";
852 for (const auto & p : v)
853 {
854 msg() << " (" << p.first << ", " << p.second << ")";
855 }
856 msg() << endmsg;
857#endif
858
859 if (match_without_shared && v.size() > 1)
860 {
861 return;
862 }
863
864 const int cluster_number = is_test ? cluster_info_2.number : cluster_info_1.number;
865
866 for (const auto & p : v)
867 {
868 for (int i = 0; i < cluster_number; ++i)
869 {
870 const int this_index = (is_test ? p.first * cluster_info_1.number + i : i * cluster_info_1.number + p.first);
871 match_possibilities[this_index] = 0;
872 }
873 }
874 };
875
876 build_similarity_map_helper(cluster_info_1, cluster_info_2, matched_clusters, unmatched_clusters);
877
878 for (int testc = 0; testc < cluster_info_2.number; ++testc)
879 {
880 for (int refc = 0; refc < cluster_info_1.number; ++refc)
881 {
882 if (match_possibilities[testc * cluster_info_1.number + refc] > 0)
883 {
884 sch.r2t_table[refc] = testc;
885 sch.t2r_table[testc] = refc;
886 }
887 }
888 }
889
890 for (int refc = 0; refc < cluster_info_1.number; ++refc)
891 {
892 if (sch.r2t_table[refc] < 0)
893 {
894 sch.unmatched_ref_list.push_back(refc);
895 }
896 }
897
898 for (int testc = 0; testc < cluster_info_2.number; ++testc)
899 {
900 if (sch.t2r_table[testc] < 0)
901 {
902 sch.unmatched_test_list.push_back(testc);
903 }
904 }
905
906 {
907 char message_buffer[256];
908 snprintf(message_buffer, 256,
909 "%2d: %5d / %5d || %5d / %5d || %3d || %5d | %5d || %5d",
910 0,
911 int(sch.r2t_table.size()) - int(sch.unmatched_ref_list.size()), int(sch.r2t_table.size()),
912 int(sch.t2r_table.size()) - int(sch.unmatched_test_list.size()), int(sch.t2r_table.size()),
913 int(sch.r2t_table.size()) - int(sch.t2r_table.size()),
914 int(sch.unmatched_ref_list.size()),
915 int(sch.unmatched_test_list.size()),
916 int(sch.unmatched_ref_list.size()) - int(sch.unmatched_test_list.size())
917 );
918 ATH_MSG_INFO(message_buffer);
919 }
920
921 return StatusCode::SUCCESS;
922
923}
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 return clusters->cells.indices[a] < clusters->cells.indices[b];
372 }
373 } );
374
375 auto order_array = [&](auto * ptr)
376 {
377 std::vector<std::decay_t<decltype(ptr[0])>> prev(clusters->number_cells);
378
379 for (int i = 0; i < clusters->number_cells; ++i)
380 {
381 prev[i] = ptr[i];
382 }
383
384 for (int i = 0; i < clusters->number_cells; ++i)
385 {
386 ptr[i] = prev[cell_orderer[i]];
387 }
388 };
389
390 order_array(clusters->cells.indices);
391 order_array(clusters->cellWeights);
392 order_array(clusters->clusterIndices);
393
394 cells_prefix_sum.clear();
395 cells_prefix_sum.resize(NCaloCells + 1, 0);
396
397 int prev_cell = -1;
398 int cell_count = 0;
399
400 for (int i = 0; i < clusters->number_cells; ++i)
401 {
402 const int this_cell = clusters->cells.indices[i];
403
404 if (this_cell != prev_cell)
405 {
406 for (int j = prev_cell + 1; j <= this_cell; ++j)
407 {
408 cells_prefix_sum[j] = cell_count;
409 }
410 }
411
412 ++cell_count;
413
414 prev_cell = this_cell;
415 }
416
417 if (clusters->number_cells > 0)
418 {
419 for (int i = clusters->cells.indices[clusters->number_cells - 1]; i <= NCaloCells; ++i)
420 {
421 cells_prefix_sum[i + 1] = cell_count;
422 }
423 }
424
425 return StatusCode::SUCCESS;
426}
#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 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 262 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 276 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_calo_id

const CaloCell_ID* CaloGPUClusterAndCellDataMonitor::m_calo_id {nullptr}
private

Pointer to Calo ID Helper.

Definition at line 234 of file CaloGPUClusterAndCellDataMonitor.h.

234{nullptr};

◆ m_cellPropertiesToDo

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

Definition at line 282 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 187 of file CaloGPUClusterAndCellDataMonitor.h.

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

◆ m_cellTypesToDo

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

Definition at line 283 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 281 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_comparedCellPropertiesToDo

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

Definition at line 283 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_comparedCellTypesToDo

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

Definition at line 284 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_comparedClusterPropertiesToDo

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

Definition at line 281 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 288 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_doClusters

bool CaloGPUClusterAndCellDataMonitor::m_doClusters = false
private

Definition at line 288 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_doCombinedCells

bool CaloGPUClusterAndCellDataMonitor::m_doCombinedCells = false
private

Definition at line 288 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_doCombinedClusters

bool CaloGPUClusterAndCellDataMonitor::m_doCombinedClusters = false
private

Definition at line 288 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_extraComparedClusterPropertiesToDo

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

Definition at line 282 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_extraThingsToDo

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

Definition at line 284 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_grow_weight

double CaloGPUClusterAndCellDataMonitor::m_grow_weight = 250.
private

Definition at line 229 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 177 of file CaloGPUClusterAndCellDataMonitor.h.

177{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 217 of file CaloGPUClusterAndCellDataMonitor.h.

218{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 229 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 195 of file CaloGPUClusterAndCellDataMonitor.h.

195{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 191 of file CaloGPUClusterAndCellDataMonitor.h.

191{ 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 299 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_numEvents

size_t CaloGPUClusterAndCellDataMonitor::m_numEvents = 0
private

Counts the number of events.

Definition at line 265 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 248 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 212 of file CaloGPUClusterAndCellDataMonitor.h.

213{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 294 of file CaloGPUClusterAndCellDataMonitor.h.

◆ m_seed_weight

double CaloGPUClusterAndCellDataMonitor::m_seed_weight = 5000.
private

Definition at line 229 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 182 of file CaloGPUClusterAndCellDataMonitor.h.

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

◆ m_terminal_weight

double CaloGPUClusterAndCellDataMonitor::m_terminal_weight = 10.
private

Definition at line 229 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 172 of file CaloGPUClusterAndCellDataMonitor.h.

172{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 259 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 242 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 207 of file CaloGPUClusterAndCellDataMonitor.h.

208{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 245 of file CaloGPUClusterAndCellDataMonitor.h.


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