File indexing completed on 2026-08-06 09:38:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LWH_HistogramFactory_H
0010 #define LWH_HistogramFactory_H
0011
0012
0013
0014
0015 #include "AIHistogramFactory.h"
0016 #include "Histogram1D.h"
0017 #include "Histogram2D.h"
0018 #include "Tree.h"
0019 #include <string>
0020 #include <stdexcept>
0021
0022 namespace LWH {
0023
0024 using namespace AIDA;
0025
0026
0027
0028
0029
0030
0031
0032 class HistogramFactory: public IHistogramFactory {
0033
0034 public:
0035
0036
0037
0038
0039 HistogramFactory(Tree & t)
0040 : tree(&t) {}
0041
0042
0043
0044
0045 virtual ~HistogramFactory() {}
0046
0047
0048
0049
0050
0051
0052 bool destroy(IBaseHistogram * hist) {
0053 IManagedObject * mo = dynamic_cast<IManagedObject *>(hist);
0054 if ( !mo ) return false;
0055 return tree->rm(tree->findPath(*mo));
0056 }
0057
0058
0059
0060
0061 ICloud1D * createCloud1D(const std::string &, const std::string &,
0062 int = -1, const std::string & = "") {
0063 return error<ICloud1D>("ICloud1D");
0064 }
0065
0066
0067
0068
0069 ICloud1D * createCloud1D(const std::string &) {
0070 return error<ICloud1D>("ICloud1D");
0071 }
0072
0073
0074
0075
0076 ICloud1D * createCopy(const std::string &, const ICloud1D &) {
0077 return error<ICloud1D>("ICloud1D");
0078 }
0079
0080
0081
0082
0083 ICloud2D * createCloud2D(const std::string &, const std::string &, int = -1,
0084 const std::string & = "") {
0085 return error<ICloud2D>("ICloud2D");
0086 }
0087
0088
0089
0090
0091
0092 ICloud2D * createCloud2D(const std::string &) {
0093 return error<ICloud2D>("ICloud2D");
0094 }
0095
0096
0097
0098
0099 ICloud2D * createCopy(const std::string &, const ICloud2D &) {
0100 return error<ICloud2D>("ICloud2D");
0101 }
0102
0103
0104
0105
0106 ICloud3D * createCloud3D(const std::string &, const std::string &, int = -1,
0107 const std::string & = "") {
0108 return error<ICloud3D>("ICloud3D");
0109 }
0110
0111
0112
0113
0114 ICloud3D * createCloud3D(const std::string &) {
0115 return error<ICloud3D>("ICloud3D");
0116 }
0117
0118
0119
0120
0121 ICloud3D * createCopy(const std::string &, const ICloud3D &) {
0122 return error<ICloud3D>("ICloud3D");
0123 }
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 IHistogram1D *
0142 createHistogram1D(const std::string & path, const std::string & title,
0143 int nBins, double lowerEdge, double upperEdge,
0144 const std::string & = "") {
0145 Histogram1D * hist = new Histogram1D(nBins, lowerEdge, upperEdge);
0146 hist->setTitle(title);
0147 if ( !tree->insert(path, hist) ) {
0148 delete hist;
0149 hist = 0;
0150 throw std::runtime_error("LWH could not create histogram '"
0151 + title + "'." );
0152 }
0153 return hist;
0154 }
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 IHistogram1D *
0169 createHistogram1D(const std::string & pathAndTitle,
0170 int nBins, double lowerEdge, double upperEdge) {
0171 std::string title = pathAndTitle.substr(pathAndTitle.rfind('/') + 1);
0172 return createHistogram1D(pathAndTitle, title, nBins, lowerEdge, upperEdge);
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 IHistogram1D *
0189 createHistogram1D(const std::string & path, const std::string & title,
0190 const std::vector<double> & binEdges,
0191 const std::string & = "") {
0192 Histogram1D * hist = new Histogram1D(binEdges);
0193 hist->setTitle(title);
0194 if ( !tree->insert(path, hist) ) {
0195 delete hist;
0196 hist = 0;
0197 throw std::runtime_error("LWH could not create histogram '"
0198 + title + "'." );
0199 }
0200 return hist;
0201 }
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 IHistogram1D *
0214 createCopy(const std::string & path, const IHistogram1D & hist) {
0215 Histogram1D * h = new Histogram1D(dynamic_cast<const Histogram1D &>(hist));
0216 h->setTitle(path.substr(path.rfind('/') + 1));
0217 if ( !tree->insert(path, h) ) {
0218 delete h;
0219 h = 0;
0220 throw std::runtime_error("LWH could not create a copy of histogram '"
0221 + hist.title() + "'." );
0222 }
0223 return h;
0224 }
0225
0226
0227
0228
0229 IHistogram2D *
0230 createHistogram2D(const std::string & path, const std::string & title,
0231 int nx, double xlo, double xup,
0232 int ny, double ylo, double yup,
0233 const std::string & = "") {
0234 Histogram2D * hist = new Histogram2D(nx, xlo, xup, ny, ylo, yup);
0235 hist->setTitle(title);
0236 if ( !tree->insert(path, hist) ) {
0237 delete hist;
0238 hist = 0;
0239 throw std::runtime_error("LWH could not create histogram '"
0240 + title + "'." );
0241 }
0242 return hist;
0243 }
0244
0245
0246
0247
0248 IHistogram2D * createHistogram2D(const std::string & pathAndTitle,
0249 int nx, double xlo, double xup,
0250 int ny, double ylo, double yup) {
0251 std::string title = pathAndTitle.substr(pathAndTitle.rfind('/') + 1);
0252 return createHistogram2D(pathAndTitle, title, nx, xlo, xup, ny, ylo, yup);
0253 }
0254
0255
0256
0257
0258 IHistogram2D *
0259 createHistogram2D(const std::string & path, const std::string & title,
0260 const std::vector<double> & xedges,
0261 const std::vector<double> & yedges,
0262 const std::string & = "") {
0263 Histogram2D * hist = new Histogram2D(xedges, yedges);
0264 hist->setTitle(title);
0265 if ( !tree->insert(path, hist) ) {
0266 delete hist;
0267 hist = 0;
0268 throw std::runtime_error("LWH could not create histogram '"
0269 + title + "'." );
0270 }
0271 return hist;
0272 }
0273
0274
0275
0276
0277 IHistogram2D *
0278 createCopy(const std::string & path, const IHistogram2D & hist) {
0279 Histogram2D * h = new Histogram2D(dynamic_cast<const Histogram2D &>(hist));
0280 h->setTitle(path.substr(path.rfind('/') + 1));
0281 if ( !tree->insert(path, h) ) {
0282 delete h;
0283 h = 0;
0284 throw std::runtime_error("LWH could not create a copy of histogram '"
0285 + hist.title() + "'." );
0286 }
0287 return h;
0288 }
0289
0290
0291
0292
0293 IHistogram3D * createHistogram3D(const std::string &, const std::string &,
0294 int, double, double, int, double, double,
0295 int, double, double,
0296 const std::string & = "") {
0297 return error<IHistogram3D>("IHistogram3D");
0298 }
0299
0300
0301
0302
0303 IHistogram3D * createHistogram3D(const std::string &, int, double, double,
0304 int, double, double, int, double, double) {
0305 return error<IHistogram3D>("IHistogram3D");
0306 }
0307
0308
0309
0310
0311 IHistogram3D * createHistogram3D(const std::string &, const std::string &,
0312 const std::vector<double> &,
0313 const std::vector<double> &,
0314 const std::vector<double> &,
0315 const std::string & = "") {
0316 return error<IHistogram3D>("IHistogram3D");
0317 }
0318
0319
0320
0321
0322 IHistogram3D * createCopy(const std::string &, const IHistogram3D &) {
0323 return error<IHistogram3D>("IHistogram3D");
0324 }
0325
0326
0327
0328
0329 IProfile1D * createProfile1D(const std::string &, const std::string &,
0330 int, double, double, const std::string & = "") {
0331 return error<IProfile1D>("IProfile1D");
0332 }
0333
0334
0335
0336
0337 IProfile1D * createProfile1D(const std::string &, const std::string &,
0338 int, double, double, double, double,
0339 const std::string & = "") {
0340 return error<IProfile1D>("IProfile1D");
0341 }
0342
0343
0344
0345
0346 IProfile1D * createProfile1D(const std::string &, const std::string &,
0347 const std::vector<double> &,
0348 const std::string & = "") {
0349 return error<IProfile1D>("IProfile1D");
0350 }
0351
0352
0353
0354
0355 IProfile1D * createProfile1D(const std::string &, const std::string &,
0356 const std::vector<double> &, double, double,
0357 const std::string & = "") {
0358 return error<IProfile1D>("IProfile1D");
0359 }
0360
0361
0362
0363
0364 IProfile1D * createProfile1D(const std::string &, int, double, double) {
0365 return error<IProfile1D>("IProfile1D");
0366 }
0367
0368
0369
0370
0371 IProfile1D * createProfile1D(const std::string &,
0372 int, double, double, double, double) {
0373 return error<IProfile1D>("IProfile1D");
0374 }
0375
0376
0377
0378
0379 IProfile1D * createCopy(const std::string &, const IProfile1D &) {
0380 return error<IProfile1D>("IProfile1D");
0381 }
0382
0383
0384
0385
0386 IProfile2D * createProfile2D(const std::string &, const std::string &,
0387 int, double, double, int, double, double,
0388 const std::string & = "") {
0389 return error<IProfile2D>("IProfile2D");
0390 }
0391
0392
0393
0394
0395 IProfile2D * createProfile2D(const std::string &, const std::string &,
0396 int, double, double, int,
0397 double, double, double, double,
0398 const std::string & = "") {
0399 return error<IProfile2D>("IProfile2D");
0400 }
0401
0402
0403
0404
0405 IProfile2D * createProfile2D(const std::string &, const std::string &,
0406 const std::vector<double> &,
0407 const std::vector<double> &,
0408 const std::string & = "") {
0409 return error<IProfile2D>("IProfile2D");
0410 }
0411
0412
0413
0414
0415 IProfile2D * createProfile2D(const std::string &, const std::string &,
0416 const std::vector<double> &,
0417 const std::vector<double> &,
0418 double, double, const std::string & = "") {
0419 return error<IProfile2D>("IProfile2D");
0420 }
0421
0422
0423
0424
0425 IProfile2D * createProfile2D(const std::string &, int, double, double,
0426 int, double, double) {
0427 return error<IProfile2D>("IProfile2D");
0428 }
0429
0430
0431
0432
0433 IProfile2D * createProfile2D(const std::string &, int, double, double,
0434 int, double, double, double, double) {
0435 return error<IProfile2D>("IProfile2D");
0436 }
0437
0438
0439
0440
0441 IProfile2D * createCopy(const std::string &, const IProfile2D &) {
0442 return error<IProfile2D>("IProfile2D");
0443 }
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456 Histogram1D * add(const std::string & path,
0457 const Histogram1D & hist1, const Histogram1D & hist2) {
0458 if ( !checkBins(hist1, hist2) ) return 0;
0459 Histogram1D * h = new Histogram1D(hist1);
0460 h->setTitle(path.substr(path.rfind('/') + 1));
0461 h->add(hist2);
0462 if ( !tree->insert(path, h) ) return 0;
0463 return h;
0464 }
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477 IHistogram1D * add(const std::string & path,
0478 const IHistogram1D & hist1, const IHistogram1D & hist2) {
0479 return add(path, dynamic_cast<const Histogram1D &>(hist1),
0480 dynamic_cast<const Histogram1D &>(hist2));
0481 }
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494 Histogram1D * subtract(const std::string & path,
0495 const Histogram1D & h1, const Histogram1D & h2) {
0496 if ( !checkBins(h1, h2) ) return 0;
0497 Histogram1D * h = new Histogram1D(h1);
0498 h->setTitle(path.substr(path.rfind('/') + 1));
0499 for ( int i = 0; i < h->ax->bins() + 2; ++i ) {
0500 h->sum[i] += h2.sum[i];
0501 h->sumw[i] -= h2.sumw[i];
0502 h->sumw2[i] += h2.sumw2[i];
0503 }
0504 if ( !tree->insert(path, h) ) return 0;
0505 return h;
0506 }
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519 IHistogram1D * subtract(const std::string & path, const IHistogram1D & hist1,
0520 const IHistogram1D & hist2) {
0521 return subtract(path, dynamic_cast<const Histogram1D &>(hist1),
0522 dynamic_cast<const Histogram1D &>(hist2));
0523 }
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536 Histogram1D * multiply(const std::string & path,
0537 const Histogram1D & h1, const Histogram1D & h2) {
0538 if ( !checkBins(h1, h2) ) return 0;
0539 Histogram1D * h = new Histogram1D(h1);
0540 h->setTitle(path.substr(path.rfind('/') + 1));
0541 for ( int i = 0; i < h->ax->bins() + 2; ++i ) {
0542 h->sumw[i] *= h2.sumw[i];
0543 h->sumw2[i] += h1.sumw[i]*h1.sumw[i]*h2.sumw2[i] +
0544 h2.sumw[i]*h2.sumw[i]*h1.sumw2[i];
0545 }
0546 if ( !tree->insert(path, h) ) return 0;
0547 return h;
0548 }
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561 IHistogram1D * multiply(const std::string & path, const IHistogram1D & hist1,
0562 const IHistogram1D & hist2) {
0563 return multiply(path, dynamic_cast<const Histogram1D &>(hist1),
0564 dynamic_cast<const Histogram1D &>(hist2));
0565 }
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578 Histogram1D * divide(const std::string & path,
0579 const Histogram1D & h1, const Histogram1D & h2) {
0580 if ( !checkBins(h1, h2) ) return 0;
0581 Histogram1D * h = new Histogram1D(h1);
0582 h->setTitle(path.substr(path.rfind('/') + 1));
0583 for ( int i = 0; i < h->ax->bins() + 2; ++i ) {
0584 if ( h2.sum[i] == 0 || h2.sumw[i] == 0.0 ) {
0585 h->sum[i] = 0;
0586 h->sumw[i] = h->sumw2[i] = 0.0;
0587 continue;
0588 }
0589 h->sumw[i] /= h2.sumw[i];
0590 h->sumw2[i] = h1.sumw2[i]/(h2.sumw[i]*h2.sumw[i]) +
0591 h1.sumw[i]*h1.sumw[i]*h2.sumw2[i]/
0592 (h2.sumw[i]*h2.sumw[i]*h2.sumw[i]*h2.sumw[i]);
0593 }
0594 if ( !tree->insert(path, h) ) return 0;
0595 return h;
0596 }
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609 IHistogram1D * divide(const std::string & path, const IHistogram1D & hist1,
0610 const IHistogram1D & hist2) {
0611 return divide(path, dynamic_cast<const Histogram1D &>(hist1),
0612 dynamic_cast<const Histogram1D &>(hist2));
0613 }
0614
0615 inline bool _neq(double a, double b, double eps = 1e-5) const {
0616 using std::abs;
0617 if ( a == 0 && b == 0 ) return false;
0618 if ( abs(a-b) < eps*(abs(a) + abs(b)) ) return false;
0619 return true;
0620 }
0621
0622
0623
0624
0625 bool checkBins(const Histogram1D & h1, const Histogram1D & h2) const {
0626 if ( _neq(h1.ax->upperEdge(), h2.ax->upperEdge()) ||
0627 _neq(h1.ax->lowerEdge(), h2.ax->lowerEdge()) ||
0628 _neq(h1.ax->bins(), h2.ax->bins()) ) return false;
0629 if ( h1.fax && h2.fax ) return true;
0630 for ( int i = 0; i < h1.ax->bins(); ++i ) {
0631 if ( _neq(h1.ax->binUpperEdge(i), h2.ax->binUpperEdge(i)) ||
0632 _neq(h1.ax->binLowerEdge(i), h2.ax->binLowerEdge(i)) ) return false;
0633 }
0634 return true;
0635 }
0636
0637
0638
0639
0640 bool checkBins(const Histogram2D & h1, const Histogram2D & h2) const {
0641 if (_neq( h1.xax->upperEdge(), h2.xax->upperEdge()) ||
0642 _neq( h1.xax->lowerEdge(), h2.xax->lowerEdge()) ||
0643 h1.xax->bins() != h2.xax->bins() ) return false;
0644 if (_neq( h1.yax->upperEdge(), h2.yax->upperEdge()) ||
0645 _neq( h1.yax->lowerEdge(), h2.yax->lowerEdge()) ||
0646 h1.yax->bins() != h2.yax->bins() ) return false;
0647 if ( h1.xfax && h2.xfax && h1.yfax && h2.yfax ) return true;
0648 for ( int i = 0; i < h1.xax->bins(); ++i ) {
0649 if ( _neq(h1.xax->binUpperEdge(i), h2.xax->binUpperEdge(i)) ||
0650 _neq(h1.xax->binLowerEdge(i), h2.xax->binLowerEdge(i)) )
0651 return false;
0652 }
0653 for ( int i = 0; i < h1.yax->bins(); ++i ) {
0654 if ( _neq(h1.yax->binUpperEdge(i), h2.yax->binUpperEdge(i)) ||
0655 _neq(h1.yax->binLowerEdge(i), h2.yax->binLowerEdge(i)) )
0656 return false;
0657 }
0658 return true;
0659 }
0660
0661
0662
0663
0664 IHistogram2D * add(const std::string & path,
0665 const IHistogram2D & hist1, const IHistogram2D & hist2) {
0666 return add(path, dynamic_cast<const Histogram2D &>(hist1),
0667 dynamic_cast<const Histogram2D &>(hist2));
0668 }
0669
0670
0671
0672
0673 Histogram2D * add(const std::string & path,
0674 const Histogram2D & h1, const Histogram2D & h2) {
0675 if ( !checkBins(h1, h2) ) return 0;
0676 Histogram2D * h = new Histogram2D(h1);
0677 h->setTitle(path.substr(path.rfind('/') + 1));
0678 h->add(h2);
0679 if ( !tree->insert(path, h) ) {
0680 delete h;
0681 return 0;
0682 }
0683 return h;
0684 }
0685
0686
0687
0688
0689 Histogram2D * subtract(const std::string & path,
0690 const Histogram2D & h1, const Histogram2D & h2) {
0691 if ( !checkBins(h1, h2) ) {
0692
0693 return 0;
0694 }
0695 Histogram2D * h = new Histogram2D(h1);
0696 h->setTitle(path.substr(path.rfind('/') + 1));
0697 for ( int ix = 0; ix < h->xax->bins() + 2; ++ix )
0698 for ( int iy = 0; iy < h->yax->bins() + 2; ++iy ) {
0699 h->sum[ix][iy] += h2.sum[ix][iy];
0700 h->sumw[ix][iy] -= h2.sumw[ix][iy];
0701 h->sumw2[ix][iy] += h2.sumw2[ix][iy];
0702 h->sumxw[ix][iy] -= h2.sumxw[ix][iy];
0703 h->sumx2w[ix][iy] -= h2.sumx2w[ix][iy];
0704 h->sumyw[ix][iy] -= h2.sumyw[ix][iy];
0705 h->sumy2w[ix][iy] -= h2.sumy2w[ix][iy];
0706 }
0707 if ( !tree->insert(path, h) ) {
0708
0709 delete h;
0710 return 0;
0711 }
0712 return h;
0713 }
0714
0715
0716
0717
0718 IHistogram2D * subtract(const std::string & path,
0719 const IHistogram2D & h1, const IHistogram2D & h2) {
0720 return subtract(path, dynamic_cast<const Histogram2D &>(h1),
0721 dynamic_cast<const Histogram2D &>(h2));
0722 }
0723
0724
0725
0726
0727 IHistogram2D * multiply(const std::string & path,
0728 const IHistogram2D & h1, const IHistogram2D & h2) {
0729 return multiply(path, dynamic_cast<const Histogram2D &>(h1),
0730 dynamic_cast<const Histogram2D &>(h2));
0731 }
0732
0733
0734
0735
0736 Histogram2D * multiply(const std::string & path,
0737 const Histogram2D & h1, const Histogram2D & h2) {
0738 if ( !checkBins(h1, h2) ) return 0;
0739 Histogram2D * h = new Histogram2D(h1);
0740 h->setTitle(path.substr(path.rfind('/') + 1));
0741 for ( int ix = 0; ix < h->xax->bins() + 2; ++ix )
0742 for ( int iy = 0; iy < h->yax->bins() + 2; ++iy ) {
0743 h->sum[ix][iy] *= h2.sum[ix][iy];
0744 h->sumw[ix][iy] *= h2.sumw[ix][iy];
0745 h->sumw2[ix][iy] += h1.sumw[ix][iy]*h1.sumw[ix][iy]*h2.sumw2[ix][iy] +
0746 h2.sumw[ix][iy]*h2.sumw[ix][iy]*h1.sumw2[ix][iy];
0747 }
0748 if ( !tree->insert(path, h) ) {
0749 delete h;
0750 return 0;
0751 }
0752 return h;
0753 }
0754
0755
0756
0757
0758 Histogram2D * divide(const std::string & path,
0759 const Histogram2D & h1, const Histogram2D & h2) {
0760 if ( !checkBins(h1,h2) ) return 0;
0761 Histogram2D * h = new Histogram2D(h1);
0762 h->setTitle(path.substr(path.rfind('/') + 1));
0763 for ( int ix = 0; ix < h->xax->bins() + 2; ++ix )
0764 for ( int iy = 0; iy < h->yax->bins() + 2; ++iy ) {
0765 if ( h2.sum[ix][iy] == 0 || h2.sumw[ix][iy] == 0.0 ) {
0766 h->sum[ix][iy] = 0;
0767 h->sumw[ix][iy] = h->sumw2[ix][iy] = 0.0;
0768 continue;
0769 }
0770 h->sumw[ix][iy] /= h2.sumw[ix][iy];
0771 h->sumw2[ix][iy] = h1.sumw2[ix][iy]/(h2.sumw[ix][iy]*h2.sumw[ix][iy]) +
0772 h1.sumw[ix][iy]*h1.sumw[ix][iy]*h2.sumw2[ix][iy]/
0773 (h2.sumw[ix][iy]*h2.sumw[ix][iy]*h2.sumw[ix][iy]*h2.sumw[ix][iy]);
0774 }
0775 if ( !tree->insert(path, h) ) {
0776 delete h;
0777 return 0;
0778 }
0779 return h;
0780 }
0781
0782
0783
0784
0785
0786 IHistogram2D * divide(const std::string & path,
0787 const IHistogram2D & h1, const IHistogram2D & h2) {
0788 return divide(path, dynamic_cast<const Histogram2D &>(h1),
0789 dynamic_cast<const Histogram2D &>(h2));
0790 }
0791
0792
0793
0794
0795 IHistogram3D * add(const std::string &,
0796 const IHistogram3D &, const IHistogram3D &) {
0797 return error<IHistogram3D>("3D histograms");
0798 }
0799
0800
0801
0802
0803 IHistogram3D * subtract(const std::string &,
0804 const IHistogram3D &, const IHistogram3D &) {
0805 return error<IHistogram3D>("3D histograms");
0806 }
0807
0808
0809
0810
0811 IHistogram3D * multiply(const std::string &,
0812 const IHistogram3D &, const IHistogram3D &) {
0813 return error<IHistogram3D>("3D histograms");
0814 }
0815
0816
0817
0818
0819 IHistogram3D * divide(const std::string &,
0820 const IHistogram3D &, const IHistogram3D &) {
0821 return error<IHistogram3D>("3D histograms");
0822 }
0823
0824
0825
0826
0827
0828 IHistogram1D * projectionX(const std::string & path, const IHistogram2D & h) {
0829 return projectionX(path, dynamic_cast<const Histogram2D &>(h));
0830 }
0831
0832
0833
0834
0835
0836 Histogram1D * projectionX(const std::string & path, const Histogram2D & h) {
0837 return sliceX(path, h, 0, h.yax->bins() - 1);
0838 }
0839
0840
0841
0842
0843
0844 IHistogram1D * projectionY(const std::string & path, const IHistogram2D & h) {
0845 return projectionY(path, dynamic_cast<const Histogram2D &>(h));
0846 }
0847
0848
0849
0850
0851
0852 Histogram1D * projectionY(const std::string & path, const Histogram2D & h) {
0853 return sliceY(path, h, 0, h.xax->bins() - 1);
0854 }
0855
0856
0857
0858
0859
0860 IHistogram1D *
0861 sliceX(const std::string & path, const IHistogram2D & h, int i) {
0862 return sliceX(path, dynamic_cast<const Histogram2D &>(h), i, i);
0863 }
0864
0865
0866
0867
0868
0869 Histogram1D *
0870 sliceX(const std::string & path, const Histogram2D & h, int i) {
0871 return sliceX(path, h, i, i);
0872 }
0873
0874
0875
0876
0877
0878 IHistogram1D *
0879 sliceY(const std::string & path, const IHistogram2D & h, int i) {
0880 return sliceY(path, dynamic_cast<const Histogram2D &>(h), i, i);
0881 }
0882
0883
0884
0885
0886
0887 Histogram1D * sliceY(const std::string & path, const Histogram2D & h, int i) {
0888 return sliceY(path, h, i, i);
0889 }
0890
0891
0892
0893
0894
0895 IHistogram1D *
0896 sliceX(const std::string & path, const IHistogram2D & h, int il, int iu) {
0897 return sliceX(path, dynamic_cast<const Histogram2D &>(h), il, iu);
0898 }
0899
0900
0901
0902
0903
0904 Histogram1D *
0905 sliceX(const std::string & path, const Histogram2D & h2, int il, int iu) {
0906 Histogram1D * h1;
0907 if ( h2.xfax )
0908 h1 = new Histogram1D(h2.xfax->bins(), h2.xfax->lowerEdge(),
0909 h2.xfax->upperEdge());
0910 else {
0911 std::vector<double> edges(h2.xax->bins() + 1);
0912 edges.push_back(h2.xax->lowerEdge());
0913 for ( int i = 0; i < h2.xax->bins(); ++i )
0914 edges.push_back(h2.xax->binLowerEdge(i));
0915 h1 = new Histogram1D(edges);
0916 }
0917 for ( int ix = 0; ix < h2.xax->bins() + 2; ++ix )
0918 for ( int iy = il + 2; iy <= iu + 2; ++iy ) {
0919 h1->sum[ix] += h2.sum[ix][iy];
0920 h1->sumw[ix] += h2.sumw[ix][iy];
0921 h1->sumw2[ix] += h2.sumw2[ix][iy];
0922 h1->sumxw[ix] += h2.sumxw[ix][iy];
0923 h1->sumx2w[ix] += h2.sumx2w[ix][iy];
0924 }
0925 if ( !tree->insert(path, h1) ) {
0926 delete h1;
0927 return 0;
0928 }
0929 return h1;
0930 }
0931
0932
0933
0934
0935
0936 IHistogram1D *
0937 sliceY(const std::string & path, const IHistogram2D & h, int il, int iu) {
0938 return sliceY(path, dynamic_cast<const Histogram2D &>(h), il, iu);
0939 }
0940
0941 Histogram1D *
0942 sliceY(const std::string & path, const Histogram2D & h2, int il, int iu) {
0943 Histogram1D * h1;
0944 if ( h2.yfax )
0945 h1 = new Histogram1D(h2.yfax->bins(), h2.yfax->lowerEdge(),
0946 h2.yfax->upperEdge());
0947 else {
0948 std::vector<double> edges(h2.yax->bins() + 1);
0949 edges.push_back(h2.yax->lowerEdge());
0950 for ( int i = 0; i < h2.yax->bins(); ++i )
0951 edges.push_back(h2.yax->binLowerEdge(i));
0952 h1 = new Histogram1D(edges);
0953 }
0954 for ( int iy = 0; iy < h2.yax->bins() + 2; ++iy )
0955 for ( int ix = il + 2; ix <= iu + 2; ++ix ) {
0956 h1->sum[iy] += h2.sum[ix][iy];
0957 h1->sumw[iy] += h2.sumw[ix][iy];
0958 h1->sumw2[iy] += h2.sumw2[ix][iy];
0959 h1->sumxw[iy] += h2.sumyw[ix][iy];
0960 h1->sumx2w[iy] += h2.sumy2w[ix][iy];
0961 }
0962 if ( !tree->insert(path, h1) ) {
0963 delete h1;
0964 return 0;
0965 }
0966 return h1;
0967 }
0968
0969
0970
0971
0972
0973 IHistogram2D * projectionXY(const std::string &, const IHistogram3D &) {
0974 return error<IHistogram2D>("2D histograms");
0975 }
0976
0977
0978
0979
0980
0981 IHistogram2D * projectionXZ(const std::string &, const IHistogram3D &) {
0982 return error<IHistogram2D>("2D histograms");
0983 }
0984
0985
0986
0987
0988
0989 IHistogram2D * projectionYZ(const std::string &, const IHistogram3D &) {
0990 return error<IHistogram2D>("2D histograms");
0991 }
0992
0993
0994
0995
0996
0997
0998 IHistogram2D * sliceXY(const std::string &, const IHistogram3D &, int, int) {
0999 return error<IHistogram2D>("2D histograms");
1000 }
1001
1002
1003
1004
1005
1006
1007 IHistogram2D * sliceXZ(const std::string &, const IHistogram3D &, int, int) {
1008 return error<IHistogram2D>("2D histograms");
1009 }
1010
1011
1012
1013
1014
1015
1016 IHistogram2D * sliceYZ(const std::string &, const IHistogram3D &, int, int) {
1017 return error<IHistogram2D>("2D histograms");
1018 }
1019
1020
1021 private:
1022
1023
1024 template <typename T>
1025 static T * error(std::string feature) {
1026 throw std::runtime_error("LWH cannot handle " + feature + ".");
1027 }
1028
1029
1030 Tree * tree;
1031
1032 };
1033
1034 }
1035
1036 #endif