File indexing completed on 2025-12-10 10:18:06
0001 #pragma once
0002
0003 #include <vector>
0004 #include <math.h>
0005
0006 #include <TObject.h>
0007
0008 namespace IRT2 {
0009
0010 class SinglePDF: public TObject {
0011 public:
0012 SinglePDF() {};
0013 ~SinglePDF() {};
0014
0015 virtual double GetValue (double x) const = 0;
0016 virtual double GetAverage(void) const = 0;
0017 virtual bool WithinRange(double x, double dx = 0.0) const = 0;
0018
0019 #ifndef DISABLE_ROOT_IO
0020 ClassDef(SinglePDF, 1);
0021 #endif
0022 };
0023
0024 class UniformPDF: public SinglePDF {
0025 public:
0026 UniformPDF(double x0 = 0.0, double x1 = 0.0, double weight = 1.0, double sigma = 0.0):
0027 m_X0(x0), m_X1(x1), m_Weight(weight), m_Sigma(sigma) {
0028 if (m_X0 > m_X1) std::swap(m_X0, m_X1);
0029
0030
0031 m_Norm = 1.0/(m_X1 - m_X0);
0032 };
0033 ~UniformPDF() {};
0034
0035 inline bool WithinRange(double x, double dx = 0.0) const {
0036 if (!dx) return (x >= m_X0 && x <= m_X1);
0037
0038 double xl = x - dx, xr = x + dx;
0039 if (xl > m_X1 || xr < m_X0) return false;
0040
0041 return true;
0042 };
0043 inline double GetValue(double x) const {
0044 return WithinRange(x) ? m_Norm*m_Weight : 0.0;
0045 };
0046 double GetAverage(void) const {
0047 return (m_X0 + m_X1)/2;
0048 };
0049 double GetWeight(void) const { return m_Weight; };
0050
0051 inline double GetRangeIntegral(double x0, double x1) const {
0052 if (x0 > x1) std::swap(x0, x1);
0053
0054 if (x0 > m_X1) return 0.0;
0055 if (x1 < m_X0) return 0.0;
0056
0057
0058 double l = (x0 > m_X0 ? x0 : m_X0), r = (x1 < m_X1 ? x1 : m_X1);
0059
0060 return m_Norm*m_Weight*(r - l);
0061 };
0062 inline double GetGaussianIntegral(double mu, double sigma) const {
0063
0064 if (m_Sigma) sigma = sqrt(sigma*sigma + m_Sigma*m_Sigma);
0065
0066
0067 double q0 = (1 - erf((m_X0 - mu)/(sqrt(2.)*sigma)))/2;
0068 double q1 = (1 - erf((m_X1 - mu)/(sqrt(2.)*sigma)))/2;
0069
0070 return m_Norm*m_Weight*(q0 - q1);
0071 };
0072
0073 private:
0074 double m_X0, m_X1, m_Weight, m_Norm, m_Sigma;
0075
0076 #ifndef DISABLE_ROOT_IO
0077 ClassDef(UniformPDF, 1);
0078 #endif
0079 };
0080
0081 class VectorPDF: public TObject {
0082 public:
0083 VectorPDF() {};
0084 ~VectorPDF() {
0085 for(auto pdf : m_Members) {
0086 delete pdf;
0087 }
0088 };
0089
0090 void Reset( void ) {
0091 for(auto member: m_Members)
0092 delete member;
0093
0094 m_Members.clear();
0095 };
0096
0097 void AddMember(UniformPDF *pdf) { m_Members.push_back(pdf); };
0098 unsigned GetMemberCount( void ) const { return m_Members.size(); };
0099 unsigned GetWithinRangeCount(double x, double dx = 0.0) const {
0100 unsigned ret = 0;
0101
0102 for(auto member: m_Members)
0103 if (member->WithinRange(x, dx))
0104 ret++;
0105
0106 return ret;
0107 };
0108 double GetValue(double x) const {
0109 double ret = 0.0;
0110
0111 for(auto member: m_Members)
0112 ret += member->GetValue(x);
0113
0114 return ret;
0115 };
0116 double GetAverage( void ) const {
0117 double avg = 0.0, wtsum = 0.0;
0118
0119 for(auto member: m_Members) {
0120 avg += member->GetWeight() * member->GetAverage();
0121 wtsum += member->GetWeight();
0122 }
0123
0124 return (wtsum ? avg / wtsum : 0.0);
0125 };
0126 double GetAverage(double min, double max) const {
0127 double avg = 0.0, wtsum = 0.0;
0128
0129 for(auto member: m_Members) {
0130 double value = member->GetAverage();
0131 if (value < min || value > max) continue;
0132
0133 avg += member->GetWeight() * value;
0134 wtsum += member->GetWeight();
0135 }
0136
0137 return (wtsum ? avg / wtsum : 0.0);
0138 };
0139 inline double GetRangeIntegral(double x0, double x1) const {
0140 double ret = 0.0;
0141
0142 for(auto member: m_Members)
0143 ret += member->GetRangeIntegral(x0, x1);
0144
0145 return ret;
0146 };
0147 inline double GetGaussianIntegral(double mu, double sigma) const {
0148 double ret = 0.0;
0149
0150 for(auto member: m_Members)
0151 ret += member->GetGaussianIntegral(mu, sigma);
0152
0153 return ret;
0154 };
0155
0156 UniformPDF *GetMember(unsigned id) const {
0157 return (id < m_Members.size() ? m_Members[id] : 0);
0158 };
0159 const std::vector<UniformPDF*> &GetMembers( void ) const { return m_Members; };
0160
0161 private:
0162 std::vector<UniformPDF*> m_Members;
0163
0164 #ifndef DISABLE_ROOT_IO
0165 ClassDef(VectorPDF, 1);
0166 #endif
0167 };
0168
0169 }