File indexing completed on 2026-08-06 09:38:18
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LWH_Histogram1D_H
0010 #define LWH_Histogram1D_H
0011
0012
0013
0014
0015 #include "AIHistogram1D.h"
0016 #include "ManagedObject.h"
0017 #include "Axis.h"
0018 #include "VariAxis.h"
0019 #include <vector>
0020 #include <stdexcept>
0021
0022 namespace LWH {
0023
0024 using namespace AIDA;
0025
0026
0027
0028
0029 class Histogram1D: public IHistogram1D, public ManagedObject {
0030
0031 public:
0032
0033
0034 friend class HistogramFactory;
0035
0036 public:
0037
0038
0039
0040
0041 Histogram1D(int n, double lo, double up)
0042 : fax(new Axis(n, lo, up)), vax(0),
0043 sum(n + 2), sumw(n + 2), sumw2(n + 2), sumxw(n + 2), sumx2w(n + 2) {
0044 ax = fax;
0045 }
0046
0047
0048
0049
0050 Histogram1D(const std::vector<double> & edges)
0051 : fax(0), vax(new VariAxis(edges)),
0052 sum(edges.size() + 1), sumw(edges.size() + 1), sumw2(edges.size() + 1),
0053 sumxw(edges.size() + 1), sumx2w(edges.size() + 1) {
0054 ax = vax;
0055 }
0056
0057
0058
0059
0060 Histogram1D(const Histogram1D & h)
0061 : IBaseHistogram(h), IHistogram(h), IHistogram1D(h), ManagedObject(h),
0062 fax(0), vax(0), sum(h.sum), sumw(h.sumw), sumw2(h.sumw2),
0063 sumxw(h.sumxw), sumx2w(h.sumx2w) {
0064 const VariAxis * hvax = dynamic_cast<const VariAxis *>(h.ax);
0065 if ( vax ) ax = vax = new VariAxis(*hvax);
0066 else ax = fax = new Axis(dynamic_cast<const Axis &>(*h.ax));
0067 }
0068
0069
0070 virtual ~Histogram1D() {
0071 delete ax;
0072 }
0073
0074
0075
0076
0077
0078 std::string title() const {
0079 return theTitle;
0080 }
0081
0082
0083
0084
0085
0086 std::string name() const {
0087 return theTitle;
0088 }
0089
0090
0091
0092
0093
0094
0095 bool setTitle(const std::string & title) {
0096 theTitle = title;
0097 return true;
0098 }
0099
0100
0101
0102
0103 IAnnotation & annotation() {
0104 throw std::runtime_error("LWH cannot handle annotations");
0105 }
0106
0107
0108
0109
0110 const IAnnotation & annotation() const {
0111 throw std::runtime_error("LWH cannot handle annotations");
0112 }
0113
0114
0115
0116
0117
0118 int dimension() const {
0119 return 1;
0120 }
0121
0122
0123
0124
0125
0126 bool reset() {
0127 sum = std::vector<int>(ax->bins() + 2);
0128 sumw = std::vector<double>(ax->bins() + 2);
0129 sumxw = std::vector<double>(ax->bins() + 2);
0130 sumx2w = std::vector<double>(ax->bins() + 2);
0131 sumw2 = std::vector<double>(ax->bins() + 2);
0132 return true;
0133 }
0134
0135
0136
0137
0138
0139
0140 int entries() const {
0141 int si = 0;
0142 for ( int i = 2; i < ax->bins() + 2; ++i ) si += sum[i];
0143 return si;
0144 }
0145
0146
0147
0148
0149
0150
0151
0152
0153 int allEntries() const {
0154 return entries() + extraEntries();
0155 }
0156
0157
0158
0159
0160
0161 int extraEntries() const {
0162 return sum[0] + sum[1];
0163 }
0164
0165
0166
0167
0168
0169
0170 double equivalentBinEntries() const {
0171 double sw = 0.0;
0172 double sw2 = 0.0;
0173 for ( int i = 2; i < ax->bins() + 2; ++i ) {
0174 sw += sumw[i];
0175 sw2 += sumw2[i];
0176 }
0177 return sw2/(sw*sw);
0178 }
0179
0180
0181
0182
0183
0184
0185
0186 double sumBinHeights() const {
0187 double sw = 0.0;
0188 for ( int i = 2; i < ax->bins() + 2; ++i ) sw += sumw[i];
0189 return sw;
0190 }
0191
0192
0193
0194
0195
0196
0197 double sumAllBinHeights() const {
0198 return sumBinHeights() + sumExtraBinHeights();
0199 }
0200
0201
0202
0203
0204
0205 double sumExtraBinHeights() const {
0206 return sumw[0] + sumw[1];
0207 }
0208
0209
0210
0211
0212
0213
0214 double minBinHeight() const {
0215 double minw = sumw[2];
0216 for ( int i = 3; i < ax->bins() + 2; ++i ) minw = std::min(minw, sumw[i]);
0217 return minw;
0218 }
0219
0220
0221
0222
0223
0224
0225 double maxBinHeight() const{
0226 double maxw = sumw[2];
0227 for ( int i = 3; i < ax->bins() + 2; ++i ) maxw = std::max(maxw, sumw[i]);
0228 return maxw;
0229 }
0230
0231
0232
0233
0234
0235
0236
0237
0238 bool fill(double x, double weight = 1.) {
0239 int i = ax->coordToIndex(x) + 2;
0240 ++sum[i];
0241 sumw[i] += weight;
0242 sumxw[i] += x*weight;
0243 sumx2w[i] += x*x*weight;
0244 sumw2[i] += weight*weight;
0245 return weight >= 0 && weight <= 1;
0246 }
0247
0248
0249
0250
0251
0252
0253 double binMean(int index) const {
0254 int i = index + 2;
0255 return sumw[i] != 0.0? sumxw[i]/sumw[i]:
0256 ( vax? vax->binMidPoint(index): fax->binMidPoint(index) );
0257 };
0258
0259
0260
0261
0262
0263
0264 double binRms(int index) const {
0265 int i = index + 2;
0266 return sumw[i] == 0.0 || sum[i] < 2? ax->binWidth(index):
0267 std::sqrt(std::max(sumw[i]*sumx2w[i] - sumxw[i]*sumxw[i], 0.0))/sumw[i];
0268 };
0269
0270
0271
0272
0273
0274
0275
0276 int binEntries(int index) const {
0277 return sum[index + 2];
0278 }
0279
0280
0281
0282
0283
0284
0285
0286 double binHeight(int index) const {
0287 return sumw[index + 2];
0288 }
0289
0290
0291
0292
0293
0294
0295
0296 double binError(int index) const {
0297 return std::sqrt(sumw2[index + 2]);
0298 }
0299
0300
0301
0302
0303
0304 double mean() const {
0305 double s = 0.0;
0306 double sx = 0.0;
0307 for ( int i = 2; i < ax->bins() + 2; ++i ) {
0308 s += sumw[i];
0309 sx += sumxw[i];
0310 }
0311 return s != 0.0? sx/s: 0.0;
0312 }
0313
0314
0315
0316
0317
0318 double rms() const {
0319 double s = 0.0;
0320 double sx = 0.0;
0321 double sx2 = 0.0;
0322 for ( int i = 2; i < ax->bins() + 2; ++i ) {
0323 s += sumw[i];
0324 sx += sumxw[i];
0325 sx2 += sumx2w[i];
0326 }
0327 return s != 0.0? std::sqrt(std::max(s*sx2 - sx*sx, 0.0))/s:
0328 ax->upperEdge() - ax->lowerEdge();
0329 }
0330
0331
0332
0333
0334
0335 const IAxis & axis() const {
0336 return *ax;
0337 }
0338
0339
0340
0341
0342
0343
0344
0345
0346 int coordToIndex(double coord) const {
0347 return ax->coordToIndex(coord);
0348 }
0349
0350
0351
0352
0353
0354
0355 bool add(const Histogram1D & h) {
0356 if ( ax->upperEdge() != h.ax->upperEdge() ||
0357 ax->lowerEdge() != h.ax->lowerEdge() ||
0358 ax->bins() != h.ax->bins() ) return false;
0359 for ( int i = 0; i < ax->bins() + 2; ++i ) {
0360 sum[i] += h.sum[i];
0361 sumw[i] += h.sumw[i];
0362 sumxw[i] += h.sumxw[i];
0363 sumx2w[i] += h.sumx2w[i];
0364 sumw2[i] += h.sumw2[i];
0365 }
0366 return true;
0367 }
0368
0369
0370
0371
0372
0373
0374 bool add(const IHistogram1D & hist) {
0375 return add(dynamic_cast<const Histogram1D &>(hist));
0376 }
0377
0378
0379
0380
0381
0382 bool scale(double s) {
0383 for ( int i = 0; i < ax->bins() + 2; ++i ) {
0384 sumw[i] *= s;
0385 sumxw[i] *= s;
0386 sumx2w[i] *= s;
0387 sumw2[i] *= s*s;
0388 }
0389 return true;
0390 }
0391
0392
0393
0394
0395
0396
0397
0398
0399 void normalize(double intg) {
0400 double oldintg = sumAllBinHeights();
0401 if ( oldintg == 0.0 ) return;
0402 for ( int i = 0; i < ax->bins() + 2; ++i ) {
0403 double fac = intg/oldintg;
0404 if ( i >= 2 ) fac /= (ax->binUpperEdge(i - 2) - ax->binLowerEdge(i - 2));
0405 sumw[i] *= fac;
0406 sumxw[i] *= fac;
0407 sumx2w[i] *= fac;
0408 sumw2[i] *= fac*fac;
0409 }
0410 }
0411
0412
0413
0414
0415
0416 double integral() const {
0417 double intg = sumw[0] + sumw[1];
0418 for ( int i = 2; i < ax->bins() + 2; ++i )
0419 intg += sumw[i]*(ax->binUpperEdge(i - 2) - ax->binLowerEdge(i - 2));
0420 return intg;
0421 }
0422
0423
0424
0425
0426
0427 void * cast(const std::string &) const {
0428 return 0;
0429 }
0430
0431
0432
0433
0434 bool writeXML(std::ostream & os, std::string path, std::string name) {
0435 os << " <histogram1d name=\"" << name
0436 << "\"\n title=\"" << title()
0437 << "\" path=\"" << path
0438 << "\">\n <axis max=\"" << ax->upperEdge()
0439 << "\" numberOfBins=\"" << ax->bins()
0440 << "\" min=\"" << ax->lowerEdge()
0441 << "\" direction=\"x\"";
0442 if ( vax ) {
0443 os << ">\n";
0444 for ( int i = 0, N = ax->bins() - 1; i < N; ++i )
0445 os << " <binBorder value=\"" << ax->binUpperEdge(i) << "\"/>\n";
0446 os << " </axis>\n";
0447 } else {
0448 os << "/>\n";
0449 }
0450 os << " <statistics entries=\"" << entries()
0451 << "\">\n <statistic mean=\"" << mean()
0452 << "\" direction=\"x\"\n rms=\"" << rms()
0453 << "\"/>\n </statistics>\n <data1d>\n";
0454 for ( int i = 0; i < ax->bins() + 2; ++i ) if ( sum[i] ) {
0455 os << " <bin1d binNum=\"";
0456 if ( i == 0 ) os << "UNDERFLOW";
0457 else if ( i == 1 ) os << "OVERFLOW";
0458 else os << i - 2;
0459 os << "\" entries=\"" << sum[i]
0460 << "\" height=\"" << sumw[i]
0461 << "\"\n error=\"" << std::sqrt(sumw2[i])
0462 << "\" error2=\"" << sumw2[i]
0463 << "\"\n weightedMean=\"" << binMean(i - 2)
0464 << "\" weightedRms=\"" << binRms(i - 2)
0465 << "\"/>\n";
0466 }
0467 os << " </data1d>\n </histogram1d>" << std::endl;
0468 return true;
0469 }
0470
0471
0472
0473
0474
0475
0476 bool writeFLAT(std::ostream & os, std::string path, std::string name) {
0477 os << "# " << path << "/" << name << " " << ax->lowerEdge()
0478 << " " << ax->bins() << " " << ax->upperEdge()
0479 << " \"" << title() << " \"" << std::endl;
0480 for ( int i = 2; i < ax->bins() + 2; ++i )
0481 os << 0.5*(ax->binLowerEdge(i - 2) + ax->binUpperEdge(i - 2)) << " "
0482 << sumw[i] << " " << sqrt(sumw2[i]) << " " << sum[i] << std::endl;
0483 os << std::endl;
0484 return true;
0485 }
0486
0487 private:
0488
0489
0490 std::string theTitle;
0491
0492
0493 IAxis * ax;
0494
0495
0496 Axis * fax;
0497
0498
0499 VariAxis * vax;
0500
0501
0502 std::vector<int> sum;
0503
0504
0505 std::vector<double> sumw;
0506
0507
0508 std::vector<double> sumw2;
0509
0510
0511 std::vector<double> sumxw;
0512
0513
0514 std::vector<double> sumx2w;
0515
0516 };
0517
0518 }
0519
0520 #endif