#ifndef __JMULTIHISTOGRAM__ #define __JMULTIHISTOGRAM__ #include #include "JTools/JArray.hh" #include "JTools/JMixedMultiMap.hh" #include "JTools/JMultiFunction.hh" #include "JIO/JSerialisable.hh" namespace JTOOLS { namespace { using JIO::JSerialisable; using JIO::JReader; using JIO::JWriter; } /** * Mixed multi-dimensional histogram. */ template class JMultiHistogram : public JMixedMultiMap { public: typedef JMixedMultiMap JMultiMap_t; using JMultiMap_t::NUMBER_OF_DIMENSIONS; typedef typename JHistogram1D_t::argument_type argument_type; typedef typename JHistogram1D_t::result_type result_type; typedef typename JHistogram1D_t::value_type value_type; typedef typename JMultiMap_t::key_type key_type; typedef typename JMultiMap_t::mapped_type mapped_type; typedef typename JMultiMap_t::const_iterator const_iterator; typedef typename JMultiMap_t::const_reverse_iterator const_reverse_iterator; typedef typename JMultiMap_t::iterator iterator; typedef typename JMultiMap_t::reverse_iterator reverse_iterator; typedef typename JMultiMap_t::super_iterator super_iterator; typedef typename JMultiMap_t::super_const_iterator super_const_iterator; using JMultiMap_t::Fill; /** * Default constructor. */ JMultiHistogram() : JMultiMap_t() {} /** * Multi-dimensional fill method call. * * \param x comma seperated argument list * \return function value */ void Fill(const argument_type& x, ...) { va_start(ap, x); typename JArray::iterator p = buffer.begin(); *p = x; // first argument while (++p != buffer.end()) *p = va_arg(ap, argument_type); // next argument const result_type y = va_arg(ap, result_type); va_end(ap); this->Fill(buffer.begin(), y); } protected: mutable va_list ap; mutable JArray buffer; }; /** * Mixed multi-dimensional histogram. */ template class JTransformableMultiHistogram : public JMultiHistogram, public JSerialisable { public: typedef JMultiHistogram JMultiMap_t; using JMultiMap_t::NUMBER_OF_DIMENSIONS; typedef typename JHistogram1D_t::argument_type argument_type; typedef typename JHistogram1D_t::result_type result_type; typedef typename JHistogram1D_t::value_type value_type; typedef typename JMultiMap_t::key_type key_type; typedef typename JMultiMap_t::mapped_type mapped_type; typedef typename JMultiMap_t::const_iterator const_iterator; typedef typename JMultiMap_t::const_reverse_iterator const_reverse_iterator; typedef typename JMultiMap_t::iterator iterator; typedef typename JMultiMap_t::reverse_iterator reverse_iterator; typedef typename JMultiMap_t::super_iterator super_iterator; typedef typename JMultiMap_t::super_const_iterator super_const_iterator; typedef JFunctionTransformerInterface transformer_type; typedef JHistogram1D_t histogram_type; using JMultiMap_t::Fill; /** * Default constructor. */ JTransformableMultiHistogram() : JMultiMap_t(), transformer(new transformer_type()) {} /** * Multi-dimensional fill method call. * * \param x comma seperated argument list * \return function value */ void Fill(const argument_type& x, ...) { va_start(ap, x); typename JArray::iterator p = buffer.begin(); *p = x; // first argument while (++p != buffer.end()) *p = va_arg(ap, argument_type); // next argument const result_type y = va_arg(ap, result_type); va_end(ap); this->buffer[NUMBER_OF_DIMENSIONS] = transformer->putXn(this->buffer, this->buffer[NUMBER_OF_DIMENSIONS]); const double z = transformer->putXn(this->buffer, 1.0) - transformer->putXn(this->buffer, 0.0); const double W = transformer->getWeight(this->buffer); this->Fill(buffer.begin(), y * z / W); } /** * Application of weight function and coordinate transformation. * * \param __transformer JFunctionTransformerInterface object */ template void transform(const JFunctionTransformer_t& __transformer) { typedef JArray array_type; for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) { const array_type array = (*i).getKey(); histogram_type& histogram = (*i).getValue(); const JFunctionGetTransformer get( *transformer, array); const JFunctionPutTransformer put(__transformer, array); histogram.transform(get); histogram.transform(put); } transformer.reset(__transformer.clone()); } /** * Read from input. * * \param in JReader * \return JReader */ virtual JReader& read(JReader& in) { in >> (JMultiMap_t&) *this; return transformer->read(in); } /** * Write to output. * * \param out JWriter * \return JWriter */ virtual JWriter& write(JWriter& out) const { out << (JMultiMap_t&) *this; return transformer->write(out); } /** * Read JTransformableMultiHistogram from input. * * \param in JReader * \param buffer JTransformableMultiHistogram * \return JReader */ friend inline JReader& operator>>(JReader& in, JTransformableMultiHistogram& buffer) { return buffer.read(in); } /** * Write JTransformableMultiHistogram to output. * * \param out JWriter * \param buffer JTransformableMultiHistogram * \return JWriter */ friend inline JWriter& operator<<(JWriter& out, const JTransformableMultiHistogram& buffer) { return buffer.write(out); } std::auto_ptr transformer; protected: mutable va_list ap; mutable JArray buffer; }; } #endif