Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:13:29

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #pragma once
0012 
0013 #include <Gaudi/Accumulators/Histogram.h>
0014 
0015 #include <fmt/format.h>
0016 
0017 #include <boost/container/static_vector.hpp>
0018 
0019 #include <array>
0020 #include <utility>
0021 
0022 namespace Gaudi::Accumulators {
0023 
0024   namespace details {
0025 
0026     /**
0027      * Default formating for histogram names and title, only calling fmt::format
0028      * on the text given at construction and passing the histo index as argument
0029      */
0030     struct FormatHistDefault {
0031       std::string_view text;
0032       FormatHistDefault( std::string_view t ) : text{ t } {}
0033       auto operator()( size_t n ) { return fmt::format( fmt::runtime( text ), n ); }
0034     };
0035 
0036     /**
0037      * internal class implementing an "array" of histograms
0038      *
0039      * The internal implementation uses boost::container::static_vector
0040      * @see HistogramArray
0041      */
0042     template <typename Histo, std::size_t N>
0043     struct HistogramArrayInternal : boost::container::static_vector<Histo, N> {
0044       /// constructor with callables for FormatName and FormatTitle
0045       template <typename OWNER, std::invocable<int> FormatName, std::invocable<int> FormatTitle>
0046       HistogramArrayInternal( OWNER* owner, FormatName&& fname, FormatTitle&& ftitle,
0047                               typename Histo::AxisTupleType&& allAxis ) {
0048         for ( std::size_t i = 0; i < N; i++ ) { this->emplace_back( owner, fname( i ), ftitle( i ), allAxis ); }
0049       }
0050       /// constructor for strings, FormatHistDefault is used as the default callable
0051       template <typename OWNER>
0052       HistogramArrayInternal( OWNER* owner, std::string_view name, std::string_view title,
0053                               typename Histo::AxisTupleType&& allAxis ) {
0054         for ( std::size_t i = 0; i < N; i++ ) {
0055           this->emplace_back( owner, FormatHistDefault{ name }( i ), FormatHistDefault{ title }( i ), allAxis );
0056         }
0057       }
0058     };
0059   } // namespace details
0060 
0061   /**
0062    * generic class implementing an array of histograms
0063    * The only addition to a raw array is the constructor that allows
0064    * to build names and titles for the histograms automatically from
0065    * the index of the histogram in the array
0066    * There are 2 possibilities :
0067    *   - if 2 string_views are given, they are used in a call to
0068    *      std::format(name/title, n);
0069    *   - if 2 callables are given, they are called on the index
0070    *     they should take a size_t and return some type convertible to string_view
0071    * actual implementation is in HistogramArrayInternal
0072    *
0073    * Typical usage :
0074    *   // Array of 5 1D histograms with simple names and titles
0075    *   // Names will be GaudiH1D-0, GaudiH1D-1, ... and similarly for titles
0076    *   Gaudi::Accumulators::HistogramArray<Gaudi::Accumulators::Histogram<1>, 5> histo1d{
0077    *     &algo, "GaudiH1D-{}", "A Gaudi 1D histogram - number {}", { 21, -10.5, 10.5, "X" } };
0078    *   ++histo1d[3][-10.0];
0079    *   // Array of 5 2D weighted histograms with simple names and titles
0080    *   // Names will be Name0, Name1, ... and similarly for titles
0081    *   Gaudi::Accumulators::HistogramArray<Gaudi::Accumulators::WeightedHistogram<2>, 7> histo2dw{
0082    *     &algo, "Name{}", "Title {}", { 21, -10.5, 10.5, "X" }, { 21, -10.5, 10.5, "Y" } };
0083    *   histo2dw[1][{ -10.0, -10.0 }] += 0.25;
0084    *   // Array of histograms with custom name and titles
0085    *   // Names will be GaudiH1D-0-0, GaudiH1D-1-1, GaudiH1D-2-4, ...
0086    *   // Titles will be "Title 1 of 5", "Title 2 of 5", "Title 3 of 5", ...
0087    *   Gaudi::Accumulators::HistogramArray<Gaudi::Accumulators::Histogram<1>, 5> histoCustom{
0088    *     &algo,
0089    *     []( int n ) { return fmt::format( "GaudiH1D-{}-{}", n, n*n ); },
0090    *     [nb = 5]( int n ) {
0091    *       return fmt::format( "Title {} of {}", n+1, nb );
0092    *     },
0093    *     { 21, -10.5, 10.5, "X" } };
0094    *   ++histoCustom[2][-10.0];
0095    */
0096   template <typename Histo, std::size_t N,
0097             typename Seq = std::make_integer_sequence<unsigned int, std::tuple_size_v<typename Histo::AxisTupleType>>>
0098   struct HistogramArray;
0099   template <typename Histo, std::size_t N, unsigned int... ND>
0100   struct HistogramArray<Histo, N, std::integer_sequence<unsigned int, ND...>>
0101       : details::HistogramArrayInternal<Histo, N> {
0102     template <typename OWNER, typename FormatName, typename FormatTitle, std::size_t M = N>
0103     HistogramArray( OWNER* owner, FormatName&& fname, FormatTitle&& ftitle, typename Histo::AxisTupleType&& allAxis )
0104         : details::HistogramArrayInternal<Histo, N>( owner, fname, ftitle,
0105                                                      std::forward<typename Histo::AxisTupleType>( allAxis ) ) {}
0106 
0107     template <unsigned int I>
0108     using AxisType = std::tuple_element_t<I, typename Histo::AxisTupleType>;
0109 
0110     template <typename OWNER, typename FormatName, typename FormatTitle>
0111     HistogramArray( OWNER* owner, FormatName&& fname, FormatTitle&& ftitle, AxisType<ND>... allAxis )
0112         : HistogramArray( owner, fname, ftitle, std::make_tuple( allAxis... ) ) {}
0113   };
0114 
0115 } // namespace Gaudi::Accumulators