diff --git a/CaloFuture/CaloFutureUtils/CMakeLists.txt b/CaloFuture/CaloFutureUtils/CMakeLists.txt index d1e7cc9c3495f2e9f70cf70e3d578850f13d837f..25a903aa17723a0bd0b3cb532ad7821bcb6b10a4 100644 --- a/CaloFuture/CaloFutureUtils/CMakeLists.txt +++ b/CaloFuture/CaloFutureUtils/CMakeLists.txt @@ -15,7 +15,6 @@ CaloFuture/CaloFutureUtils gaudi_add_library(CaloFutureUtils SOURCES - src/CaloFuture2Dview.cpp src/CaloFutureAlgUtils.cpp src/CaloFutureNeighbours.cpp src/CaloFutureParticle.cpp diff --git a/CaloFuture/CaloFutureUtils/include/CaloFutureUtils/CaloFuture2Dview.h b/CaloFuture/CaloFutureUtils/include/CaloFutureUtils/CaloFuture2Dview.h deleted file mode 100644 index 984dcbe6a736bed77234293242f8fb825b8326fd..0000000000000000000000000000000000000000 --- a/CaloFuture/CaloFutureUtils/include/CaloFutureUtils/CaloFuture2Dview.h +++ /dev/null @@ -1,89 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\*****************************************************************************/ -#ifndef CALOFUTUREDAQ_CALOFUTURE2DVIEW_H -#define CALOFUTUREDAQ_CALOFUTURE2DVIEW_H 1 - -// Include files -// from Gaudi -#include "GaudiAlg/GaudiHistoAlg.h" -// from LHCb -#include "CaloDet/DeCalorimeter.h" -#include "Detector/Calo/CaloCellID.h" -// from Event -#include "Event/CaloAdc.h" -#include "Event/CaloCluster.h" -#include "Event/CaloDigit.h" -#include "Event/MCCaloDigit.h" -#include "Event/MCCaloHit.h" -// from ROOT -#include <TH1.h> -#include <TH2.h> -#include <TProfile2D.h> - -//============================================================================== - -/** @class CaloFuture2Dview CaloFuture2Dview.h - * - * - * @author Olivier Deschamps - * @date 2008-01-18 - */ -class CaloFuture2Dview : public GaudiHistoAlg { -public: - /// Standard constructor - CaloFuture2Dview( const std::string& name, ISvcLocator* pSvcLocator ); - - StatusCode initialize() override; ///< Algorithm initialization - - void bookCaloFuture2D( const HistoID& unit, const std::string title, std::string name, int area = -1 ) const; - void bookCaloFuture2D( const HistoID& unit, const std::string title, LHCb::Detector::Calo::CellCode::Index calo, - int area = -1 ) const; - void fillCaloFuture2D( const HistoID& unit, const LHCb::Detector::Calo::CellID& id, double value, - const DeCalorimeter& calo, const std::string title = "" ) const; - - bool split() const { return m_split; } - const HistoID getUnit( const HistoID& unit, int calo, int area ) const; - - // Container of the subdetector info - struct CaloFutureParams { - int nChan; - int centre; - int reg; - int fCard; - int lCard; - std::vector<LHCb::Detector::Calo::CellID> refCell; - std::vector<float> cellSizes; - }; - -protected: - Gaudi::Property<bool> m_1d{this, "OneDimension", false}; // 1D histo (value versus CaloCellID) default is 2D view - Gaudi::Property<bool> m_profile{this, "Profile", false}; // 1D histo profile type ? - Gaudi::Property<int> m_bin1d{this, "Bin1D", 16384}; // 1D histo binning (default : full 14 bits dynamics) - Gaudi::Property<bool> m_geo{this, "GeometricalView", - true}; // 2D : true : geometrical (x,y) | false : readout (FEB,channel) - Gaudi::Property<float> m_threshold{this, "Threshold", -256.}; // threshold on the input value (bin weight) - Gaudi::Property<float> m_offset{this, "Offset", 0.0}; // bin weight = (value + offset) - Gaudi::Property<bool> m_dim{this, "ActualSize", true}; // true: (x,y) | false : (col,row) (geometrical view only) - Gaudi::Property<bool> m_l0{this, "L0ClusterView", false}; // bin weight on 2x2 cluster (geometrical view only) - Gaudi::Property<bool> m_energyWeighted{this, "EnergyWeighted", true}; // true : bin weight = energy | false : 1 - Gaudi::Property<bool> m_flux{this, "Flux", false}; // bin weight is normalized to the cell area (for both views) - Gaudi::Property<bool> m_split{this, "SplitAreas", false}; // produce one view per area (for geometrical view only) - Gaudi::Property<std::string> m_lab{this, "xLabelOptions", "v"}; // Crate-FEB text label on Xaxis (readout view only) - Gaudi::Property<std::string> m_prof{this, "ProfileError", ""}; - mutable Gaudi::Accumulators::MsgCounter<MSG::ERROR> m_id_error{this, "Cell ID and Calo ID mismatch, skipping cell"}; - -private: - std::string getTitle( std::string title, int calo, int area ) const; - // Container of 4 subdectector params - std::array<CaloFutureParams, 4> m_caloParams; - mutable std::map<HistoID, LHCb::Detector::Calo::CellCode::Index> m_caloViewMap; -}; -#endif // CALOFUTUREDAQ_CALOFUTURE2DVIEW_H diff --git a/CaloFuture/CaloFutureUtils/include/CaloFutureUtils/CellIDHistogram.h b/CaloFuture/CaloFutureUtils/include/CaloFutureUtils/CellIDHistogram.h new file mode 100644 index 0000000000000000000000000000000000000000..869ff9c069f6ed432e4f4e2333bc6b768d20398d --- /dev/null +++ b/CaloFuture/CaloFutureUtils/include/CaloFutureUtils/CellIDHistogram.h @@ -0,0 +1,361 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, CERN does not waive the privileges and immunities * +* granted to it by virtue of its status as an Intergovernmental Organization * +* or submit itself to any jurisdiction. * +\*****************************************************************************/ + +#include <Detector/Calo/CaloCellID.h> + +#include <Gaudi/Accumulators/AxisAsProperty.h> +#include <Gaudi/Accumulators/HistogramWrapper.h> +#include <Gaudi/Accumulators/StaticHistogram.h> + +#include <tuple> + +namespace LHCb::Calo { + + // forward declaration of CellIDHistogramInputTypes + template <unsigned int NIndex, typename... Elements> + class CellIDHistogramInputType; + template <unsigned int NIndex, typename WArithmetic, typename... Elements> + struct WeightedCellIDHistogramInputType; + + namespace { + // Helper instantiating CellIDHistogramInputType with a reduced parameter pack + // by using only the first N items among the ones given in the input Tuple + template <unsigned int NIndex, typename ParamsTuple, typename Seq> + struct ReducedCellIDHistogramInputType_t; + template <unsigned int NIndex, typename ParamsTuple, size_t... I> + struct ReducedCellIDHistogramInputType_t<NIndex, ParamsTuple, std::index_sequence<I...>> { + using type = + CellIDHistogramInputType<NIndex, std::decay_t<decltype( std::get<I>( std::declval<ParamsTuple>() ) )>...>; + }; + template <unsigned int NIndex, typename ParamsTuple, unsigned int N> + using ReducedCellIDHistogramInputType = + typename ReducedCellIDHistogramInputType_t<NIndex, ParamsTuple, std::make_index_sequence<N>>::type; + + template <unsigned int NIndex, typename ParamsTuple> + struct CellIDHistogramInputTypeFromTuple; + template <unsigned int NIndex, typename... Elements> + struct CellIDHistogramInputTypeFromTuple<NIndex, std::tuple<Elements...>> + : CellIDHistogramInputType<NIndex, Elements...> { + using CellIDHistogramInputType<NIndex, Elements...>::CellIDHistogramInputType; + }; + + template <unsigned int NIndex, typename WArithmetic, typename ParamsTuple> + struct WeightedCellIDHistogramInputTypeFromTuple; + template <unsigned int NIndex, typename WArithmetic, typename... Elements> + struct WeightedCellIDHistogramInputTypeFromTuple<NIndex, WArithmetic, std::tuple<Elements...>> + : WeightedCellIDHistogramInputType<NIndex, WArithmetic, Elements...> { + using WeightedCellIDHistogramInputType<NIndex, WArithmetic, Elements...>::WeightedCellIDHistogramInputType; + }; + } // namespace + + /** + * InputType dedicated to CellID based histograms, that is to histograms + * where the first dimension is based on cellID + */ + template <unsigned int NIndex, typename... Elements> + class CellIDHistogramInputType : public std::tuple<Detector::Calo::CellID, Elements...> { + public: + using Parent = std::tuple<Detector::Calo::CellID, Elements...>; + // allow construction from set of values + using Parent::Parent; + using ValueType = ReducedCellIDHistogramInputType<NIndex, std::tuple<Elements...>, NIndex - 1>; + template <class... AxisType, typename = typename std::enable_if_t<( sizeof...( AxisType ) == NIndex )>> + unsigned int computeIndex( std::tuple<AxisType...> const& axis ) const { + return computeIndexInternal<0, std::tuple<AxisType...>>( axis ); + } + auto forInternalCounter() { return 1ul; } + template <class... AxisType, typename = typename std::enable_if_t<( sizeof...( AxisType ) == NIndex )>> + static unsigned int computeTotNBins( std::tuple<AxisType...> const& axis ) { + return computeTotNBinsInternal<0, std::tuple<AxisType...>>( axis ); + } + + private: + template <int N, class Tuple> + unsigned int computeIndexInternal( Tuple const& allAxis ) const { + // compute global index. Bins are stored in a column first manner + auto const& axis = std::get<N>( allAxis ); + int localIndex = -1; + if constexpr ( N == 0 ) { + // special cellId dimension + localIndex = Detector::Calo::denseIndex( std::get<N>( *this ) ); + // if invalid, will be -1 and should go to index 0 (underflow bin) else just shift + localIndex = localIndex < 0 ? 0 : localIndex - axis.minValue() + 1; + } else { + localIndex = axis.index( std::get<N>( *this ) ); + } + if constexpr ( N + 1 == NIndex ) { + return localIndex; + } else { + return localIndex + ( axis.numBins() + 2 ) * computeIndexInternal<N + 1, Tuple>( allAxis ); + } + } + template <int N, class Tuple> + static unsigned int computeTotNBinsInternal( Tuple const& allAxis ) { + auto const& axis = std::get<N>( allAxis ); + unsigned int localNBins = axis.numBins() + 2; + if constexpr ( N + 1 == NIndex ) + return localNBins; + else + return localNBins * computeTotNBinsInternal<N + 1, Tuple>( allAxis ); + } + }; + + /// specialization of CellIDHistogramInputType for ND == 1 in order to have simpler syntax + /// that is, no tuple of one item + template <> + class CellIDHistogramInputType<1> { + public: + using ValueType = Detector::Calo::CellID; + CellIDHistogramInputType( Detector::Calo::CellID a ) : value( a ) {} + template <typename AxisType> + unsigned int computeIndex( std::tuple<AxisType> const& allAxis ) const { + auto const& axis = std::get<0>( allAxis ); + // if invalid, denseindex will be -1 and should go to index 0 (underflow bin) else just shift + int localIndex = Detector::Calo::denseIndex( value ); + return localIndex < 0 ? 0 : localIndex - axis.minValue() + 1; + } + Detector::Calo::CellID& operator[]( int ) { return value; } + auto forInternalCounter() { return 1ul; } + template <typename AxisType> + static unsigned int computeTotNBins( std::tuple<AxisType> allAxis ) { + auto const& axis = std::get<0>( allAxis ); + return axis.nBins + 2; + } + + private: + Detector::Calo::CellID value; + }; + + /** + * InputType dedicated to weighted CellID based histograms, that is to weighted histograms + * where the first dimension is based on cellID + */ + template <unsigned int NIndex, typename WArithmetic, typename... Elements> + struct WeightedCellIDHistogramInputType : std::pair<CellIDHistogramInputType<NIndex, Elements...>, WArithmetic> { + using ValueType = typename CellIDHistogramInputType<NIndex, Elements...>::ValueType; + using std::pair<CellIDHistogramInputType<NIndex, Elements...>, WArithmetic>::pair; + template <class... AxisType, typename = typename std::enable_if_t<( sizeof...( AxisType ) == NIndex )>> + unsigned int computeIndex( std::tuple<AxisType...> const& axis ) const { + return this->first.computeIndex( axis ); + } + auto forInternalCounter() { return std::pair( this->first.forInternalCounter(), this->second ); } + template <class... AxisType, typename = typename std::enable_if_t<( sizeof...( AxisType ) == NIndex )>> + static unsigned int computeTotNBins( std::tuple<AxisType...> const& axis ) { + return CellIDHistogramInputType<NIndex, Elements...>::computeTotNBins( axis ); + } + }; + + /** + * Class implementing a regular cellid based histogram accumulator + */ + template <Gaudi::Accumulators::atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType> + using CellIDHistogramingAccumulator = Gaudi::Accumulators::HistogramingAccumulatorInternal< + Atomicity, CellIDHistogramInputTypeFromTuple<ND::value, AxisToArithmetic_t<AxisTupleType>>, unsigned long, + Gaudi::Accumulators::IntegralAccumulator, AxisTupleType>; + + /** + * Class implementing a weighted cellid based histogram accumulator + */ + template <Gaudi::Accumulators::atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType> + using WeightedCellIDHistogramingAccumulator = Gaudi::Accumulators::HistogramingAccumulatorInternal< + Atomicity, WeightedCellIDHistogramInputTypeFromTuple<ND::value, Arithmetic, AxisToArithmetic_t<AxisTupleType>>, + Arithmetic, Gaudi::Accumulators::WeightedCountAccumulator, AxisTupleType>; + + /** + * Class implementing a profile cellid based histogram accumulator + */ + template <Gaudi::Accumulators::atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType> + using ProfileCellIDHistogramingAccumulator = Gaudi::Accumulators::HistogramingAccumulatorInternal< + Atomicity, CellIDHistogramInputTypeFromTuple<ND::value, ProfileAxisToArithmetic_t<Arithmetic, AxisTupleType>>, + Arithmetic, Gaudi::Accumulators::SigmaAccumulator, AxisTupleType>; + + /** + * Class implementing a weighted profile cellid based histogram accumulator + */ + template <Gaudi::Accumulators::atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType> + using WeightedProfileCellIDHistogramingAccumulator = Gaudi::Accumulators::HistogramingAccumulatorInternal< + Atomicity, + WeightedCellIDHistogramInputTypeFromTuple<ND::value, Arithmetic, + ProfileAxisToArithmetic_t<Arithmetic, AxisTupleType>>, + Arithmetic, Gaudi::Accumulators::SigmaAccumulator, AxisTupleType>; + + namespace naming { + constexpr char cellIDHistogramString[] = "histogram:CellIDHistogram"; + constexpr char weightedCellIDHistogramString[] = "histogram:WeightedCellIDHistogram"; + constexpr char profileCellIDHistogramString[] = "histogram:ProfileCellIDHistogram"; + constexpr char weightedProfileCellIDHistogramString[] = "histogram:WeightedProfileCellIDHistogram"; + } // namespace naming + + /** + * Definition of a generic CellID based Histograms. + * Internal implementation defining the custom constructor where the CellID specialized Axis is created + */ + template <Detector::Calo::CellCode::Index calo, unsigned int ND, Gaudi::Accumulators::atomicity Atomicity, + typename Arithmetic, const char* Type, + template <Gaudi::Accumulators::atomicity, typename, typename, typename> typename Accumulator, + typename AxisTupleType> + struct CellIDHistogramInternal; + template <Detector::Calo::CellCode::Index calo, unsigned int ND, Gaudi::Accumulators::atomicity Atomicity, + typename Arithmetic, const char* Type, + template <Gaudi::Accumulators::atomicity, typename, typename, typename> typename Accumulator, + typename... AxisTypes> + struct CellIDHistogramInternal<calo, ND, Atomicity, Arithmetic, Type, Accumulator, std::tuple<AxisTypes...>> + : Gaudi::Accumulators::HistogramingCounterBase<ND, Atomicity, Arithmetic, Type, Accumulator, + std::tuple<Gaudi::Accumulators::Axis<Arithmetic>, AxisTypes...>> { + using AxisTupleType = std::tuple<AxisTypes...>; + // overwritten constructor to force definition of the first axis + template <typename OWNER> + CellIDHistogramInternal( OWNER* owner, std::string const& name, std::string const& title, AxisTypes... axis ) + : Gaudi::Accumulators::HistogramingCounterBase<ND, Atomicity, Arithmetic, Type, Accumulator, + std::tuple<Gaudi::Accumulators::Axis<Arithmetic>, AxisTypes...>>( + owner, name, title, + // axis for the cellID dimension + {calo == Detector::Calo::CellCode::Index::EcalCalo ? Detector::Calo::Index::nbEcalCells() + : Detector::Calo::Index::nbHcalCells(), + calo == Detector::Calo::CellCode::Index::EcalCalo ? 0 : Detector::Calo::Index::nbEcalCells(), + calo == Detector::Calo::CellCode::Index::EcalCalo ? Detector::Calo::Index::nbEcalCells() + : Detector::Calo::Index::max()}, + // other axis, if any (that is ND > 1) + axis... ) {} + /// This constructor takes the axis as a tuple + template <typename OWNER> + CellIDHistogramInternal( OWNER* owner, std::string const& name, std::string const& title, AxisTupleType allAxis ) + : Gaudi::Accumulators::HistogramingCounterBase<ND, Atomicity, Arithmetic, Type, Accumulator, + std::tuple<Gaudi::Accumulators::Axis<Arithmetic>, AxisTypes...>>( + owner, name, title, + std::tuple_cat( // axis for the cellID dimension + std::tuple<Gaudi::Accumulators::Axis<Arithmetic>>{ + {calo == Detector::Calo::CellCode::Index::EcalCalo ? Detector::Calo::Index::nbEcalCells() + : Detector::Calo::Index::nbHcalCells(), + calo == Detector::Calo::CellCode::Index::EcalCalo ? 0 : Detector::Calo::Index::nbEcalCells(), + calo == Detector::Calo::CellCode::Index::EcalCalo ? Detector::Calo::Index::nbEcalCells() + : Detector::Calo::Index::max()}}, + // other axis, if any (that is ND > 1) + allAxis ) ) {} + }; + + /** + * Definition of a CellID based Histograms + * + * These are histograms for the calorimeter where the first dimension is indexed by cellID. + * Bins are indexed using the denseIndex method of cellID in order + * to be compact despite the change of granularity between regions + * other dimensions are free + */ + template <Detector::Calo::CellCode::Index calo, unsigned int ND = 1, + Gaudi::Accumulators::atomicity Atomicity = Gaudi::Accumulators::atomicity::full, + typename Arithmetic = double, + typename AxisTupleType = make_tuple_t<Gaudi::Accumulators::Axis<Arithmetic>, ND - 1>> + using StaticCellIDHistogram = CellIDHistogramInternal<calo, ND, Atomicity, Arithmetic, naming::cellIDHistogramString, + CellIDHistogramingAccumulator, AxisTupleType>; + + /** + * Definition of a weighted CellID based Histograms + * + * These is a weighted histogram for the calorimeter indexed by cellID. + * Bins are indexed using the denseIndex method of cellID in order + * to be compact despite the change of granularity between regions + */ + template <Detector::Calo::CellCode::Index calo, unsigned int ND = 1, + Gaudi::Accumulators::atomicity Atomicity = Gaudi::Accumulators::atomicity::full, + typename Arithmetic = double, + typename AxisTupleType = make_tuple_t<Gaudi::Accumulators::Axis<Arithmetic>, ND - 1>> + using StaticWeightedCellIDHistogram = + CellIDHistogramInternal<calo, ND, Atomicity, Arithmetic, naming::weightedCellIDHistogramString, + WeightedCellIDHistogramingAccumulator, AxisTupleType>; + + /** + * Definition of a profile CellID based Histograms + * + * These is a profile histogram for the calorimeter indexed by cellID. + * Bins are indexed using the denseIndex method of cellID in order + * to be compact despite the change of granularity between regions + */ + template <Detector::Calo::CellCode::Index calo, unsigned int ND = 1, + Gaudi::Accumulators::atomicity Atomicity = Gaudi::Accumulators::atomicity::full, + typename Arithmetic = double, + typename AxisTupleType = make_tuple_t<Gaudi::Accumulators::Axis<Arithmetic>, ND - 1>> + using StaticProfileCellIDHistogram = + CellIDHistogramInternal<calo, ND, Atomicity, Arithmetic, naming::profileCellIDHistogramString, + ProfileCellIDHistogramingAccumulator, AxisTupleType>; + + /** + * Definition of a weighted profile CellID based Histograms + * + * These is a profile histogram for the calorimeter indexed by cellID. + * Bins are indexed using the denseIndex method of cellID in order + * to be compact despite the change of granularity between regions + */ + template <Detector::Calo::CellCode::Index calo, unsigned int ND = 1, + Gaudi::Accumulators::atomicity Atomicity = Gaudi::Accumulators::atomicity::full, + typename Arithmetic = double, + typename AxisTupleType = make_tuple_t<Gaudi::Accumulators::Axis<Arithmetic>, ND - 1>> + using StaticWeightedProfileCellIDHistogram = + CellIDHistogramInternal<calo, ND, Atomicity, Arithmetic, naming::weightedProfileCellIDHistogramString, + WeightedProfileCellIDHistogramingAccumulator, AxisTupleType>; + + /** + * Customizable versin of StaticCellIDHistogram + * + * properties *_Title, *_Axis<N> can be used to set the title and the axis of the histogram + * "*" here is the name of the histogram and <N> the axis number, starting at 0 and excluding + * the CellID based axis, as it cannot be changed + */ + template <Detector::Calo::CellCode::Index calo, unsigned int ND = 1, + Gaudi::Accumulators::atomicity Atomicity = Gaudi::Accumulators::atomicity::full, + typename Arithmetic = double, + typename AxisTupleType = make_tuple_t<Gaudi::Accumulators::Axis<Arithmetic>, ND - 1>> + using CellIDHistogram = + Gaudi::Accumulators::HistogramWrapper<StaticCellIDHistogram<calo, ND, Atomicity, Arithmetic, AxisTupleType>>; + + /** + * Customizable versin of StaticWeightedCellIDHistogram + * + * properties *_Title, *_Axis<N> can be used to set the title and the axis of the histogram + * "*" here is the name of the histogram and <N> the axis number, starting at 0 and excluding + * the CellID based axis, as it cannot be changed + */ + template <Detector::Calo::CellCode::Index calo, unsigned int ND = 1, + Gaudi::Accumulators::atomicity Atomicity = Gaudi::Accumulators::atomicity::full, + typename Arithmetic = double, + typename AxisTupleType = make_tuple_t<Gaudi::Accumulators::Axis<Arithmetic>, ND - 1>> + using WeightedCellIDHistogram = Gaudi::Accumulators::HistogramWrapper< + StaticWeightedCellIDHistogram<calo, ND, Atomicity, Arithmetic, AxisTupleType>>; + + /** + * Customizable versin of StaticProfileCellIDHistogram + * + * properties *_Title, *_Axis<N> can be used to set the title and the axis of the histogram + * "*" here is the name of the histogram and <N> the axis number, starting at 0 and excluding + * the CellID based axis, as it cannot be changed + */ + template <Detector::Calo::CellCode::Index calo, unsigned int ND = 1, + Gaudi::Accumulators::atomicity Atomicity = Gaudi::Accumulators::atomicity::full, + typename Arithmetic = double, + typename AxisTupleType = make_tuple_t<Gaudi::Accumulators::Axis<Arithmetic>, ND - 1>> + using ProfileCellIDHistogram = Gaudi::Accumulators::HistogramWrapper< + StaticProfileCellIDHistogram<calo, ND, Atomicity, Arithmetic, AxisTupleType>>; + + /** + * Customizable versin of StaticWeightedProfileCellIDHistogram + * + * properties *_Title, *_Axis<N> can be used to set the title and the axis of the histogram + * "*" here is the name of the histogram and <N> the axis number, starting at 0 and excluding + * the CellID based axis, as it cannot be changed + */ + template <Detector::Calo::CellCode::Index calo, unsigned int ND = 1, + Gaudi::Accumulators::atomicity Atomicity = Gaudi::Accumulators::atomicity::full, + typename Arithmetic = double, + typename AxisTupleType = make_tuple_t<Gaudi::Accumulators::Axis<Arithmetic>, ND - 1>> + using WeightedProfileCellIDHistogram = Gaudi::Accumulators::HistogramWrapper< + StaticWeightedProfileCellIDHistogram<calo, ND, Atomicity, Arithmetic, AxisTupleType>>; + +} // namespace LHCb::Calo diff --git a/CaloFuture/CaloFutureUtils/src/CaloFuture2Dview.cpp b/CaloFuture/CaloFutureUtils/src/CaloFuture2Dview.cpp deleted file mode 100644 index fc59453acadf3d709897ee75586fcc561b83c115..0000000000000000000000000000000000000000 --- a/CaloFuture/CaloFutureUtils/src/CaloFuture2Dview.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, CERN does not waive the privileges and immunities * -* granted to it by virtue of its status as an Intergovernmental Organization * -* or submit itself to any jurisdiction. * -\*****************************************************************************/ -// Include files - -// from Gaudi -#include "AIDA/IHistogram1D.h" -#include "AIDA/IHistogram2D.h" -#include "AIDA/IProfile1D.h" -#include "AIDA/IProfile2D.h" -#include "GaudiUtils/Aida2ROOT.h" -// from LHCb -#include "Detector/Calo/CaloCellCode.h" -// local -#include "CaloFutureUtils/CaloFuture2Dview.h" - -//------------------------------------------------------------------------------ -// Implementation file for class : CaloFuture2Dview -// -// 2008-01-17 : Olivier Deschamps -//------------------------------------------------------------------------------ - -// Declaration of the Algorithm Factory -// DECLARE_COMPONENT( CaloFuture2Dview ); - -//============================================================================== -// Standard constructor, initializes variables -//============================================================================== - -CaloFuture2Dview::CaloFuture2Dview( const std::string& name, ISvcLocator* pSvcLocator ) - : GaudiHistoAlg( name, pSvcLocator ) { - setHistoDir( name ); -} - -//============================================================================== - -StatusCode CaloFuture2Dview::initialize() { - return GaudiHistoAlg::initialize().andThen( [&] { - if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Initialize" << endmsg; - - // protection against splitting when non-goemetrical view or 1D is requested. - if ( !m_geo ) m_split = false; - if ( m_1d ) m_split = false; - - // Set up the parameters - // 0 and 1 are SPD and PRS, which don't exist anymore - m_caloParams[2] = { - 32, - 32, - 6, - 128, - 351, - { - LHCb::Detector::Calo::CellID( LHCb::Detector::Calo::CellCode::Index::EcalCalo, 0, 6, 0 ), // outer - LHCb::Detector::Calo::CellID( LHCb::Detector::Calo::CellCode::Index::EcalCalo, 1, 12, 0 ), // middle - LHCb::Detector::Calo::CellID( LHCb::Detector::Calo::CellCode::Index::EcalCalo, 2, 14, 8 ) // inner - }, - { - // FIXME: READ FROM GEOMETRY - but needed at initialization for histo booking - 121.9, // outer [mm] - 121.9 / 2.f, // middle [mm] - 121.9 / 3.f, // inner [mm] - }}; - - m_caloParams[3] = {32, - 16, - 2, - 352, - 415, - {LHCb::Detector::Calo::CellID( LHCb::Detector::Calo::CellCode::Index::HcalCalo, 0, 3, 0 ), - LHCb::Detector::Calo::CellID( LHCb::Detector::Calo::CellCode::Index::HcalCalo, 1, 2, 0 )}, - { - // FIXME: READ FROM GEOMETRY - but needed at initialization for histo booking - 131.3 * 2, // outer [mm] - 131.3, // inner [mm] - }}; - } ); -} - -//============================================================================== - -void CaloFuture2Dview::bookCaloFuture2D( const HistoID& unit, const std::string title, const std::string name, - int area ) const { - const auto calo = LHCb::Detector::Calo::CellCode::CaloNumFromName( name ); - if ( calo < 0 ) { - error() << "Calo name : " << name << "is unknown " << endmsg; - return; - } - bookCaloFuture2D( unit, title, calo, area ); - return; -} - -//============================================================================== - -void CaloFuture2Dview::bookCaloFuture2D( const HistoID& unit, const std::string title, - LHCb::Detector::Calo::CellCode::Index calo, int area ) const { - // Get params - const auto& cp = m_caloParams[calo]; - - // Pre-booking - m_caloViewMap[unit] = calo; - - // 1D view : caloCellID as xAxis - if ( m_1d ) { - if ( m_profile ) - GaudiHistoAlg::bookProfile1D( unit, title, 0., (double)m_bin1d, m_bin1d, m_prof ); - else - GaudiHistoAlg::book1D( unit, title, 0., (double)m_bin1d, m_bin1d ); - return; - } - - // electronics 2D view : FEB vs Channel (include PIN-diode channels) - if ( !m_geo ) { - // Book histo - TH2* th2 = nullptr; - if ( m_profile ) { - const auto p2d = GaudiHistoAlg::bookProfile2D( unit, title, (double)cp.fCard, (double)cp.lCard, - cp.lCard - cp.fCard, 0., (double)cp.nChan, cp.nChan ); - th2 = Gaudi::Utils::Aida2ROOT::aida2root( p2d ); - } else { - const auto h2d = GaudiHistoAlg::book2D( unit, title, (double)cp.fCard, (double)cp.lCard, cp.lCard - cp.fCard, 0., - (double)cp.nChan, cp.nChan ); - th2 = Gaudi::Utils::Aida2ROOT::aida2root( h2d ); - } - // set Xaxis bin labels - th2->GetXaxis()->LabelsOption( m_lab.value().c_str() ); - for ( int bin = 1; bin <= cp.lCard - cp.fCard; ++bin ) { - if ( ( bin - 1 ) % 8 != 0 ) continue; - int code = cp.fCard + bin - 1; - int crate = code / 16; - int feb = code - crate * 16; - std::stringstream loc( "" ); - loc << "c" << format( "%02i", crate ) << "f" << format( "%02i", feb ); - th2->GetXaxis()->SetBinLabel( bin, loc.str().c_str() ); - } - return; - } - - // 2D geometrical view with small bining to simulate variable bin size (separated PMT/PIN histo) - int fArea = 0; - int lArea = m_split ? ( 6 + cp.reg ) / 4 : 1; - if ( m_split && area >= 0 ) { - fArea = area; - lArea = area + 1; - } - int ppcm = m_split ? 1 : cp.reg; - for ( int i = fArea; i < lArea; ++i ) { - double xmin = cp.refCell[i].col(); - double xmax = (double)cp.centre * 2. - xmin; - double ymin = cp.refCell[i].row(); - double ymax = (double)cp.centre * 2. - ymin; - int xbin = ( cp.centre - cp.refCell[i].col() ) * 2 * ppcm; - int ybin = ( cp.centre - cp.refCell[i].row() ) * 2 * ppcm; - if ( m_dim ) { - xmax = cp.cellSizes[i] * ( xmax - xmin ) / 2.; - xmin = -xmax; - ymax = cp.cellSizes[i] * ( ymax - ymin ) / 2.; - ymin = -ymax; - } - const auto lun = getUnit( unit, calo, i ); - const auto tl = getTitle( title, calo, i ); - if ( !m_profile ) - GaudiHistoAlg::book2D( lun, tl, xmin, xmax, xbin, ymin, ymax, ybin ); - else - GaudiHistoAlg::bookProfile2D( lun, tl, xmin, xmax, xbin, ymin, ymax, ybin ); - } - return; -} - -//============================================================================== - -const GaudiHistoAlg::HistoID CaloFuture2Dview::getUnit( const HistoID& unit, int calo, int area ) const { - if ( !m_split ) return unit; - const std::string& nArea = LHCb::Detector::Calo::CellCode::caloArea( calo, area ); - std::string sunit = unit.literalID(); - if ( sunit == "" ) sunit = std::string( unit ); - int index = sunit.find_last_of( "/" ) + 1; - sunit.insert( index, nArea + "/" ); - return (HistoID)sunit; -} - -//============================================================================== - -std::string CaloFuture2Dview::getTitle( std::string title, int calo, int area ) const { - if ( !m_split ) return title; - const std::string& nArea = LHCb::Detector::Calo::CellCode::caloArea( calo, area ); - std::string tit = title + " (" + nArea + " area)"; - return tit; -} - -//============================================================================== -// FILL CALOFUTURE 2D -//============================================================================== - -// The main implementation of fillCaloFuture2D -void CaloFuture2Dview::fillCaloFuture2D( const HistoID& unit, const LHCb::Detector::Calo::CellID& id, double value, - const DeCalorimeter& calo, const std::string title ) const { - - // get calo number - const auto calo_id = id.calo(); - if ( calo_id != calo.index() ) { - ++m_id_error; - return; - } - const unsigned int area = id.area(); - - const auto& cp = m_caloParams[calo_id]; - - // threshold - if ( value < m_threshold ) return; - - // book histo if not found - const HistoID& lun = getUnit( unit, calo_id, area ); - if ( !histoExists( lun ) ) bookCaloFuture2D( unit, title, calo_id, area ); - - // check the cellID is consistent with the calo - if ( m_caloViewMap[unit] != calo_id ) { - if ( msgLevel( MSG::DEBUG ) ) - debug() << "Cannot put the CaloCellID " << id << " in the " << caloName( m_caloViewMap[unit] ) << " view '" - << unit << "'" << endmsg; - return; - } - - // -------------- 1D view - if ( m_1d ) { - if ( m_profile ) - profile1D( lun )->fill( (double)id.index(), value, 1. ); - else - histo1D( lun )->fill( (double)id.index(), value ); - return; - } - - // -------------- Electronics 2D view (crate/feb .vs. channel) - if ( !m_geo ) { - const int feb = calo.cardNumber( id ); - const int code = calo.cardCode( feb ); - const int chan = calo.cardColumn( id ) + nColCaloCard * calo.cardRow( id ); - const double weight = ( value + m_offset ) / ( m_flux ? cp.cellSizes[area] * cp.cellSizes[area] : 1. ); - if ( m_profile ) - profile2D( lun )->fill( (double)code, (double)chan, weight, 1. ); - else - histo2D( lun )->fill( (double)code, (double)chan, weight ); - return; - } - - // -------------- 2D geometrical view with small bining to simulate variable cell sizes - const double xs = cp.cellSizes[area]; - const double ys = cp.cellSizes[area]; - const double xs0 = cp.cellSizes[0]; - const double ys0 = cp.cellSizes[0]; - const double xResize = m_dim ? ( m_split ? xs : xs0 ) : 1.; - const double yResize = m_dim ? ( m_split ? ys : ys0 ) : 1.; - const unsigned int ibox = m_split ? 1 : cp.reg / ( area + 1 ); - const int ppcm = m_split ? 1 : cp.reg; - const double weight = ( value + m_offset ) / ( m_flux ? xs * ys : 1. ); - - // PMT channels - const unsigned int row = id.row(); - const unsigned int col = id.col(); - - // L0-cluster mode (2x2 cells area are filled) - const unsigned int icl = m_l0 ? 2 : 1; - - // loop over cluster area (1x1 or 2x2 cells depending on L0 mode) - for ( unsigned int kr = 0; kr < icl; kr++ ) { - for ( unsigned int kc = 0; kc < icl; kc++ ) { - LHCb::Detector::Calo::CellID temp = id; - if ( m_l0 ) { - temp = LHCb::Detector::Calo::CellID( calo_id, area, row + kr, col + kc ); - if ( !calo.valid( temp ) ) continue; - } - unsigned int theRow = row + kr; - unsigned int theCol = col + kc; - // Fill the standard view for PMT - // loop over cell area ( ibox * ibox bins depending on CaloFuture/Area) - for ( unsigned int ir = 0; ir < ibox; ir++ ) { - for ( unsigned int ic = 0; ic < ibox; ic++ ) { - int iic = ( theCol - cp.centre ) * ibox + ic; - int iir = ( theRow - cp.centre ) * ibox + ir; - if ( !m_dim ) { - iic += ppcm * cp.centre; - iir += ppcm * cp.centre; - } - double x = xResize * ( (double)iic + 0.5 ) / (double)ppcm; - double y = yResize * ( (double)iir + 0.5 ) / (double)ppcm; - if ( m_profile ) - profile2D( lun )->fill( x, y, weight, 1 ); - else - histo2D( lun )->fill( x, y, weight ); - } - } - } - } - return; -}