Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-14 08:52:31

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2024 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 <utility>
0018 
0019 namespace Gaudi::Accumulators {
0020 
0021   namespace details {
0022 
0023     /**
0024      * Default formating for histogram names and title, only calling fmt::format
0025      * on the text given at construction and passing the histo index as argument
0026      */
0027     struct FormatHistDefault {
0028       std::string_view text;
0029       FormatHistDefault( std::string_view t ) : text{ t } {}
0030       auto operator()( size_t n ) { return fmt::format( fmt::runtime( text ), n ); }
0031     };
0032 
0033     /**
0034      * internal class implementing an array of histograms
0035      * @see HistogramArray
0036      */
0037     template <typename Histo, std::size_t N>
0038     struct HistogramArrayInternal : std::array<Histo, N> {
0039       /// constructor with callables for FormatName and FormatTitle
0040       template <typename OWNER, typename FormatName, typename FormatTitle, std::size_t... Ns,
0041                 typename = typename std::enable_if_t<std::is_invocable_v<FormatName, int>>,
0042                 typename = typename std::enable_if_t<std::is_invocable_v<FormatTitle, int>>>
0043       HistogramArrayInternal( OWNER* owner, FormatName&& fname, FormatTitle&& ftitle,
0044                               std::integer_sequence<std::size_t, Ns...>, typename Histo::AxisTupleType&& allAxis )
0045           : std::array<Histo, N>{ Histo{ owner, fname( Ns ), ftitle( Ns ), allAxis }... } {
0046         static_assert( sizeof...( Ns ) < 1000, "Using HistogramArray with 1000 arrays or more is prohibited. This "
0047                                                "would lead to very long compilation times" );
0048       }
0049       /// constructor for strings, FormatHistDefault is used as the default callable
0050       template <typename OWNER, std::size_t... Ns>
0051       HistogramArrayInternal( OWNER* owner, std::string_view name, std::string_view title,
0052                               std::integer_sequence<std::size_t, Ns...>, typename Histo::AxisTupleType&& allAxis )
0053           : std::array<Histo, N>{
0054                 Histo{ owner, FormatHistDefault{ name }( Ns ), FormatHistDefault{ title }( Ns ), allAxis }... } {
0055         static_assert( sizeof...( Ns ) < 1000, "Using HistogramArray with 1000 arrays or more is prohibited. This "
0056                                                "would lead to very long compilation times" );
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>
0103     HistogramArray( OWNER* owner, FormatName&& fname, FormatTitle&& ftitle, typename Histo::AxisTupleType&& allAxis )
0104         : details::HistogramArrayInternal<Histo, N>( owner, fname, ftitle, std::make_integer_sequence<std::size_t, N>{},
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