#ifndef __JPHYSICS__JNPETABLE__
#define __JPHYSICS__JNPETABLE__
#include "JLang/JSharedPointer.hh"
#include "JLang/JException.hh"
#include "JTools/JConstantFunction1D.hh"
#include "JTools/JMultiFunction.hh"
#include "JTools/JTransformableMultiFunction.hh"
#include "JTools/JToolsToolkit.hh"
/**
* \author mdejong
*/
namespace JPHYSICS {}
namespace JPP { using namespace JPHYSICS; }
namespace JPHYSICS {
using JTOOLS::JConstantFunction1D;
using JTOOLS::JMapList;
using JTOOLS::JMultiFunction;
using JTOOLS::JMultiMapTransformer;
using JTOOLS::JTransformableMultiFunction;
/**
* Custom class for integrated values of the PDF of the arrival time of Cherenkov light.
*
* This class provides for the number of photo-electrons as a function
* of the leading (n - 1) parameter values.
*/
template >
class JNPETable :
public JMultiFunction,
JMaplist_t,
JDistance_t>
{
public:
typedef JMultiFunction,
JMaplist_t,
JDistance_t> multifunction_t;
using multifunction_t::NUMBER_OF_DIMENSIONS;
typedef JConstantFunction1D function_type;
typedef typename multifunction_t::map_type map_type;
typedef typename multifunction_t::value_type value_type;
typedef typename multifunction_t::argument_type argument_type;
typedef typename multifunction_t::supervisor_type supervisor_type;
typedef typename multifunction_t::abscissa_type abscissa_type;
typedef typename multifunction_t::ordinate_type ordinate_type;
typedef typename multifunction_t::result_type result_type;
typedef typename multifunction_t::const_iterator const_iterator;
typedef typename multifunction_t::const_reverse_iterator const_reverse_iterator;
typedef typename multifunction_t::iterator iterator;
typedef typename multifunction_t::reverse_iterator reverse_iterator;
typedef typename multifunction_t::super_iterator super_iterator;
typedef typename multifunction_t::super_const_iterator super_const_iterator;
typedef JMultiMapTransformer transformer_type;
/**
* Default constructor.
*/
JNPETable() :
transformer(transformer_type::getClone())
{}
/**
* Constructor.
*
* \param input multi-dimensional PDF
*/
template
JNPETable(const JTransformableMultiFunction& input) :
transformer(transformer_type::getClone())
{
using namespace JTOOLS;
typedef JTransformableMultiFunction JTransformableMultiFunction_t;
typedef JMultiKey JMultiKey_t;
typedef typename JTransformableMultiFunction_t::transformer_type transformer_type;
this->transformer.reset(input.transformer->clone());
for (typename JTransformableMultiFunction_t::super_const_iterator i = input.super_begin(); i != input.super_end(); ++i) {
const JMultiKey_t& key = (*i).getKey();
const JPDF_t& value = (*i).getValue();
const typename transformer_type::array_type array(key);
const double V = getIntegral(value);
const argument_type z = input.transformer->getXn(array, 1.0) - input.transformer->getXn(array, 0.0);
this->insert(key, function_type(z*V));
}
this->compile();
}
/**
* Add NPE table.
*
* Note that the summation is made via iteration of the elements in this multidimensional table.
*
* \param input NPE table
*/
void add(const JNPETable& input)
{
using namespace JTOOLS;
for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
map_type& f1 = (*i).getValue();
for (typename map_type::iterator j = f1.begin(); j != f1.end(); ++j) {
try {
const JArray buffer((*i).getKey(), j->getX());
const double npe = get_value(input.evaluate(buffer.data()));
const double W = this->transformer->getWeight(buffer);
j->getY() += npe/W;
}
catch(JLANG::JException& error) {}
}
}
}
/**
* Get number of photo-electrons.
*
* \param args comma separated argument list
* \return number of photo-electrons
*/
template
result_type operator()(const Args& ...args) const
{
this->buffer.set(args...);
return this->evaluate(this->buffer.data());
}
/**
* Recursive function value evaluation.
*
* \param pX pointer to abscissa values
* \return function value
*/
virtual result_type evaluate(const argument_type* pX) const override
{
for (int i = 0; i != NUMBER_OF_DIMENSIONS; ++i) {
this->buffer[i] = pX[i];
}
const double W = transformer->getWeight(buffer);
const result_type npe = multifunction_t::evaluate(buffer.data());
return W * npe;
}
/**
* Application of weight function.
*
* \param transformer function transformer
*/
void transform(const transformer_type& transformer)
{
using namespace JTOOLS;
for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
map_type& f1 = (*i).getValue();
for (typename map_type::iterator j = f1.begin(); j != f1.end(); ++j) {
const JArray array((*i).getKey(), j->getX());
j->getY() *= this->transformer->getWeight(array) / transformer.getWeight(array);
}
}
this->transformer.reset(transformer.clone());
this->compile();
}
JLANG::JSharedPointer transformer;
protected:
mutable JTOOLS::JArray buffer;
};
}
#endif