Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:22

0001 #ifndef NPSTAT_STORABLEHISTONDFUNCTOR_HH_
0002 #define NPSTAT_STORABLEHISTONDFUNCTOR_HH_
0003 
0004 /*!
0005 // \file StorableHistoNDFunctor.h
0006 //
0007 // \brief Storable multivariate functor which uses histogram contents for
0008 //        data representation
0009 //
0010 // Author: I. Volobouev
0011 //
0012 // July 2012
0013 */
0014 
0015 #include "JetMETCorrections/InterpolationTables/interface/SimpleFunctors.h"
0016 #include "JetMETCorrections/InterpolationTables/interface/StorableMultivariateFunctor.h"
0017 
0018 #include "JetMETCorrections/InterpolationTables/interface/HistoND.h"
0019 
0020 namespace npstat {
0021   /**
0022     // This class adapts HistoND template together with various histogram
0023     // interpolation functions to the StorableMultivariateFunctor interface
0024     */
0025   template <class Numeric, class Axis = HistoAxis, class Converter = Same<Numeric> >
0026   class StorableHistoNDFunctor : public StorableMultivariateFunctor {
0027     template <typename Num2, typename Axis2, typename Conv2>
0028     friend class StorableHistoNDFunctor;
0029 
0030   public:
0031     typedef HistoND<Numeric, Axis> Table;
0032 
0033     //@{
0034     /**
0035         // Constructor from a pre-existing histogram. The "degree"
0036         // argument specifies the interpolation degree which can be
0037         // 0, 1, or 3.
0038         */
0039     template <class Num2>
0040     inline StorableHistoNDFunctor(const HistoND<Num2, Axis>& table, const unsigned degree = 1)
0041         : StorableMultivariateFunctor(), table_(table), deg_(degree) {
0042       validateInterDegree(degree, table.isUniformlyBinned());
0043     }
0044 
0045     template <class Num2>
0046     inline StorableHistoNDFunctor(const HistoND<Num2, Axis>& table, const unsigned degree, const std::string& descr)
0047         : StorableMultivariateFunctor(descr), table_(table), deg_(degree) {
0048       validateInterDegree(degree, table.isUniformlyBinned());
0049     }
0050     //@}
0051 
0052     /** Converting copy constructor */
0053     template <class Num2, class Conv2>
0054     inline StorableHistoNDFunctor(const StorableHistoNDFunctor<Num2, Axis, Conv2>& tab)
0055         : StorableMultivariateFunctor(tab.description()),
0056           table_(tab.table_, Same<Num2>(), tab.title().c_str(), tab.accumulatedDataLabel().c_str()),
0057           deg_(tab.deg_) {}
0058 
0059     /** Default constructor not implemented **/
0060     StorableHistoNDFunctor() = delete;
0061 
0062     ~StorableHistoNDFunctor() override {}
0063 
0064     unsigned minDim() const override { return table_.dim(); };
0065 
0066     double operator()(const double* point, unsigned dim) const override;
0067 
0068     /** Retrieve interpolation degree */
0069     inline unsigned interpolationDegree() const { return deg_; }
0070 
0071     /** Set interpolation degree (0, 1, or 3) */
0072     void setInterpolationDegree(const unsigned deg);
0073 
0074     //@{
0075     /** Retrieve the underlying HistoND object */
0076     inline Table& interpolator() { return table_; }
0077     inline const Table& interpolator() const { return table_; }
0078     //@}
0079 
0080     //@{
0081     /** Retrieve the tabulated data */
0082     inline ArrayND<Numeric>& table() { return const_cast<ArrayND<Numeric>&>(table_.binContents()); }
0083 
0084     inline const ArrayND<Numeric>& table() const { return table_.binContents(); }
0085     //@}
0086 
0087     /** Change the coordinate converter */
0088     inline void setConverter(const Converter& conv) { conv_ = conv; }
0089 
0090     //@{
0091     // Method related to "geners" I/O
0092     gs::ClassId classId() const override { return gs::ClassId(*this); }
0093     bool write(std::ostream& of) const override;
0094     //@}
0095 
0096     // I/O methods needed for reading
0097     static inline const char* classname();
0098     static inline unsigned version() { return 1; }
0099     static StorableHistoNDFunctor* read(const gs::ClassId& id, std::istream& in);
0100 
0101   protected:
0102     bool isEqual(const StorableMultivariateFunctor& other) const override {
0103       // Note the use of static_cast rather than dynamic_cast below.
0104       // static_cast works faster and it is guaranteed to succeed here.
0105       const StorableHistoNDFunctor& r = static_cast<const StorableHistoNDFunctor&>(other);
0106       return table_ == r.table_ && deg_ == r.deg_ && this->description() == other.description();
0107     }
0108 
0109   private:
0110     Table table_;
0111     unsigned deg_;
0112     Converter conv_;
0113 
0114     static void validateInterDegree(unsigned deg, bool isUniform);
0115   };
0116 }  // namespace npstat
0117 
0118 #include "JetMETCorrections/InterpolationTables/interface/NpstatException.h"
0119 
0120 #include "Alignment/Geners/interface/binaryIO.hh"
0121 #include <memory>
0122 #include "Alignment/Geners/interface/IOException.hh"
0123 
0124 #include "JetMETCorrections/InterpolationTables/interface/interpolateHistoND.h"
0125 
0126 namespace npstat {
0127   template <class Numeric, class Axis, class Converter>
0128   double StorableHistoNDFunctor<Numeric, Axis, Converter>::operator()(const double* point, const unsigned dim) const {
0129     return conv_(interpolateHistoND(table_, point, dim, deg_));
0130   }
0131 
0132   template <class Numeric, class Axis, class Converter>
0133   const char* StorableHistoNDFunctor<Numeric, Axis, Converter>::classname() {
0134     static const std::string myClass(gs::template_class_name<Numeric, Axis>("npstat::StorableHistoNDFunctor"));
0135     return myClass.c_str();
0136   }
0137 
0138   template <class Numeric, class Axis, class Converter>
0139   bool StorableHistoNDFunctor<Numeric, Axis, Converter>::write(std::ostream& of) const {
0140     gs::write_pod(of, this->description());
0141     gs::write_pod(of, deg_);
0142     return table_.classId().write(of) && table_.write(of);
0143   }
0144 
0145   template <class Numeric, class Axis, class Converter>
0146   StorableHistoNDFunctor<Numeric, Axis, Converter>* StorableHistoNDFunctor<Numeric, Axis, Converter>::read(
0147       const gs::ClassId& id, std::istream& in) {
0148     static const gs::ClassId current(gs::ClassId::makeId<StorableHistoNDFunctor<Numeric, Axis> >());
0149     current.ensureSameId(id);
0150 
0151     std::string descr;
0152     gs::read_pod(in, &descr);
0153     unsigned deg;
0154     gs::read_pod(in, &deg);
0155     gs::ClassId tabid(in, 1);
0156     if (in.fail())
0157       throw gs::IOReadFailure(
0158           "In npstat::StorableHistoNDFunctor::read: "
0159           "input stream failure");
0160     std::unique_ptr<Table> tab(Table::read(tabid, in));
0161     return new StorableHistoNDFunctor(*tab, deg, descr);
0162   }
0163 
0164   template <class Numeric, class Axis, class Converter>
0165   inline void StorableHistoNDFunctor<Numeric, Axis, Converter>::setInterpolationDegree(const unsigned deg) {
0166     validateInterDegree(deg, table_.isUniformlyBinned());
0167     deg_ = deg;
0168   }
0169 
0170   template <class Numeric, class Axis, class Converter>
0171   inline void StorableHistoNDFunctor<Numeric, Axis, Converter>::validateInterDegree(const unsigned deg,
0172                                                                                     const bool isUniform) {
0173     const bool ok = isUniform ? (deg == 0 || deg == 1 || deg == 3) : (deg == 0 || deg == 1);
0174     if (!ok)
0175       throw npstat::NpstatInvalidArgument(
0176           "In npstat::StorableHistoNDFunctor::validateInterDegree: "
0177           "unsupported interpolation degree");
0178   }
0179 }  // namespace npstat
0180 
0181 #endif  // NPSTAT_STORABLEHISTONDFUNCTOR_HH_