Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:07:01

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2022 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 #include <utility>
0015 
0016 namespace Gaudi::Accumulators {
0017 
0018   namespace details {
0019 
0020     /**
0021      * Default formating for histogram names and title, only calling fmt::format
0022      * on the text given at construction and passing the histo index as argument
0023      */
0024     struct FormatHistDefault {
0025       std::string_view text;
0026       FormatHistDefault( std::string_view t ) : text{ t } {}
0027       std::string operator()( size_t n );
0028     };
0029 
0030     /**
0031      * internal class implementing an array of histograms
0032      * @see HistogramArray
0033      */
0034     template <typename Histo, std::size_t N>
0035     struct HistogramArrayInternal : std::array<Histo, N> {
0036       /// constructor with callables for FormatName and FormatTitle
0037       template <typename OWNER, typename FormatName, typename FormatTitle, std::size_t... Ns, typename... Axis,
0038                 typename = typename std::enable_if_t<std::is_invocable_v<FormatName, int>>,
0039                 typename = typename std::enable_if_t<std::is_invocable_v<FormatTitle, int>>>
0040       HistogramArrayInternal( OWNER* owner, FormatName&& fname, FormatTitle&& ftitle,
0041                               std::integer_sequence<std::size_t, Ns...>, Axis&&... allAxis )
0042           : std::array<Histo, N>{ Histo{ owner, fname( Ns ), ftitle( Ns ), allAxis... }... } {
0043         static_assert( sizeof...( Ns ) < 1000, "Using HistogramArray with 1000 arrays or more is prohibited. This "
0044                                                "would lead to very long compilation times" );
0045       }
0046       /// constructor for strings, FormatHistDefault is used as the default callable
0047       template <typename OWNER, std::size_t... Ns, typename... Axis>
0048       HistogramArrayInternal( OWNER* owner, std::string_view name, std::string_view title,
0049                               std::integer_sequence<std::size_t, Ns...>, Axis&&... allAxis )
0050           : std::array<Histo, N>{
0051                 Histo{ owner, FormatHistDefault{ name }( Ns ), FormatHistDefault{ title }( Ns ), allAxis... }... } {
0052         static_assert( sizeof...( Ns ) < 1000, "Using HistogramArray with 1000 arrays or more is prohibited. This "
0053                                                "would lead to very long compilation times" );
0054       }
0055     };
0056   } // namespace details
0057 
0058   /**
0059    * generic class implementing an array of histograms
0060    * The only addition to a raw array is the constructor that allows
0061    * to build names and titles for the histograms automatically from
0062    * the index of the histogram in the array
0063    * There are 2 possibilities :
0064    *   - if 2 string_views are given, they are used in a call to
0065    *      std::format(name/title, n);
0066    *   - if 2 callables are given, they are called on the index
0067    *     they should take a size_t and return some type convertible to string_view
0068    * actual implementation is in HistogramArrayInternal
0069    *
0070    * Typical usage :
0071    *   // Array of 5 1D histograms with simple names and titles
0072    *   // Names will be GaudiH1D-0, GaudiH1D-1, ... and similarly for titles
0073    *   Gaudi::Accumulators::HistogramArray<Gaudi::Accumulators::Histogram<1>, 5> histo1d{
0074    *     &algo, "GaudiH1D-{}", "A Gaudi 1D histogram - number {}", { 21, -10.5, 10.5, "X" } };
0075    *   ++histo1d[3][-10.0];
0076    *   // Array of 5 2D weighted histograms with simple names and titles
0077    *   // Names will be Name0, Name1, ... and similarly for titles
0078    *   Gaudi::Accumulators::HistogramArray<Gaudi::Accumulators::WeightedHistogram<2>, 7> histo2dw{
0079    *     &algo, "Name{}", "Title {}", { 21, -10.5, 10.5, "X" }, { 21, -10.5, 10.5, "Y" } };
0080    *   histo2dw[1][{ -10.0, -10.0 }] += 0.25;
0081    *   // Array of histograms with custom name and titles
0082    *   // Names will be GaudiH1D-0-0, GaudiH1D-1-1, GaudiH1D-2-4, ...
0083    *   // Titles will be "Title 1 of 5", "Title 2 of 5", "Title 3 of 5", ...
0084    *   Gaudi::Accumulators::HistogramArray<Gaudi::Accumulators::Histogram<1>, 5> histoCustom{
0085    *     &algo,
0086    *     []( int n ) { return fmt::format( "GaudiH1D-{}-{}", n, n*n ); },
0087    *     [nb = 5]( int n ) {
0088    *       return fmt::format( "Title {} of {}", n+1, nb );
0089    *     },
0090    *     { 21, -10.5, 10.5, "X" } };
0091    *   ++histoCustom[2][-10.0];
0092    */
0093   template <typename Histo, std::size_t N, typename Seq>
0094   struct HistogramArrayBase;
0095   template <typename Histo, std::size_t N, std::size_t... NDs>
0096   struct HistogramArrayBase<Histo, N, std::index_sequence<NDs...>> : details::HistogramArrayInternal<Histo, N> {
0097     template <typename OWNER, typename FormatName, typename FormatTitle>
0098     HistogramArrayBase( OWNER* owner, FormatName&& fname, FormatTitle&& ftitle,
0099                         details::alwaysT<NDs, typename Histo::AxisType>&&... allAxis )
0100         : details::HistogramArrayInternal<Histo, N>( owner, fname, ftitle, std::make_integer_sequence<std::size_t, N>{},
0101                                                      allAxis... ) {}
0102   };
0103   template <typename Histo, std::size_t N>
0104   using HistogramArray = HistogramArrayBase<Histo, N, std::make_index_sequence<Histo::NumberDimensions::value>>;
0105 
0106 } // namespace Gaudi::Accumulators