00001 #ifndef NPSTAT_HISTOND_HH_
00002 #define NPSTAT_HISTOND_HH_
00003
00014 #include "JetMETCorrections/InterpolationTables/interface/ArrayND.h"
00015 #include "JetMETCorrections/InterpolationTables/interface/HistoAxis.h"
00016
00017 namespace npstat {
00042 template <typename Numeric, class Axis=HistoAxis>
00043 class HistoND
00044 {
00045 template <typename Num2, class Axis2> friend class HistoND;
00046
00047 public:
00048 typedef Numeric value_type;
00049 typedef Axis axis_type;
00050
00052 HistoND(const std::vector<Axis>& axes, const char* title=0,
00053 const char* accumulatedDataLabel=0);
00054
00056 HistoND(const Axis& xAxis, const char* title=0,
00057 const char* accumulatedDataLabel=0);
00058
00060 HistoND(const Axis& xAxis, const Axis& yAxis,
00061 const char* title=0, const char* accumulatedDataLabel=0);
00062
00064 HistoND(const Axis& xAxis, const Axis& yAxis, const Axis& zAxis,
00065 const char* title=0, const char* accumulatedDataLabel=0);
00066
00068 HistoND(const Axis& xAxis, const Axis& yAxis,
00069 const Axis& zAxis, const Axis& tAxis,
00070 const char* title=0, const char* accumulatedDataLabel=0);
00071
00073 HistoND(const Axis& xAxis, const Axis& yAxis,
00074 const Axis& zAxis, const Axis& tAxis, const Axis& vAxis,
00075 const char* title=0, const char* accumulatedDataLabel=0);
00076
00082 HistoND(const ArrayShape& shape, const BoxND<double>& boundingBox,
00083 const char* title=0, const char* accumulatedDataLabel=0);
00084
00091 template <typename Num2, class Functor>
00092 HistoND(const HistoND<Num2,Axis>& h, const Functor& f,
00093 const char* title=0, const char* accumulatedDataLabel=0);
00094
00102 template <typename Num2>
00103 HistoND(const HistoND<Num2,Axis>& h, const unsigned *indices,
00104 unsigned nIndices, const char* title=0);
00105
00115 template <typename Num2>
00116 HistoND(const HistoND<Num2,Axis>& h, const Axis& newAxis,
00117 unsigned newAxisNumber, const char* title=0);
00118
00120 HistoND(const HistoND&);
00121
00126 HistoND& operator=(const HistoND&);
00127
00129 inline unsigned dim() const {return dim_;}
00130
00132 inline const std::string& title() const {return title_;}
00133
00135 inline const std::string& accumulatedDataLabel() const
00136 {return accumulatedDataLabel_;}
00137
00139 inline const ArrayND<Numeric>& binContents() const {return data_;}
00140
00142 inline const ArrayND<Numeric>& overflows() const {return overflow_;}
00143
00145 inline const std::vector<Axis>& axes() const {return axes_;}
00146
00148 inline const Axis& axis(const unsigned i) const
00149 {return axes_.at(i);}
00150
00152 inline unsigned long nBins() const {return data_.length();}
00153
00155 inline unsigned long nFillsTotal() const {return fillCount_;}
00156
00158 inline unsigned long nFillsInRange() const
00159 {return fillCount_ - overCount_;}
00160
00162 inline unsigned long nFillsOver() const {return overCount_;}
00163
00168 bool isUniformlyBinned() const;
00169
00171 inline void setTitle(const char* newtitle)
00172 {title_ = newtitle ? newtitle : ""; ++modCount_;}
00173
00175 inline void setAccumulatedDataLabel(const char* newlabel)
00176 {accumulatedDataLabel_ = newlabel ? newlabel : ""; ++modCount_;}
00177
00179 inline void setAxisLabel(const unsigned axisNum, const char* newlabel)
00180 {axes_.at(axisNum).setLabel(newlabel); ++modCount_;}
00181
00186 double binVolume(unsigned long binNumber=0) const;
00187
00193 void binCenter(unsigned long binNumber,
00194 double* coords, unsigned lenCoords) const;
00195
00203 template <class Point>
00204 void allBinCenters(std::vector<Point>* centers) const;
00205
00207 void binBox(unsigned long binNumber, BoxND<double>* box) const;
00208
00210 BoxND<double> boundingBox() const;
00211
00217 double volume() const;
00218
00220 double integral() const;
00221
00223 void clear();
00224
00226 void clearBinContents();
00227
00229 void clearOverflows();
00230
00232 bool operator==(const HistoND&) const;
00233
00235 bool operator!=(const HistoND&) const;
00236
00241 bool isSameData(const HistoND&) const;
00242
00249 template <typename Num2>
00250 void fill(const double* coords, unsigned coordLength,
00251 const Num2& weight);
00252
00254
00258 template <typename Num2>
00259 void fill(const Num2& weight);
00260
00261 template <typename Num2>
00262 void fill(double x0, const Num2& weight);
00263
00264 template <typename Num2>
00265 void fill(double x0, double x1, const Num2& weight);
00266
00267 template <typename Num2>
00268 void fill(double x0, double x1, double x2, const Num2& weight);
00269
00270 template <typename Num2>
00271 void fill(double x0, double x1, double x2, double x3,
00272 const Num2& weight);
00273
00274 template <typename Num2>
00275 void fill(double x0, double x1, double x2, double x3, double x4,
00276 const Num2& weight);
00277
00278 template <typename Num2>
00279 void fill(double x0, double x1, double x2, double x3, double x4,
00280 double x5, const Num2& weight);
00281
00282 template <typename Num2>
00283 void fill(double x0, double x1, double x2, double x3, double x4,
00284 double x5, double x6, const Num2& weight);
00285
00286 template <typename Num2>
00287 void fill(double x0, double x1, double x2, double x3, double x4,
00288 double x5, double x6, double x7, const Num2& weight);
00289
00290 template <typename Num2>
00291 void fill(double x0, double x1, double x2, double x3, double x4,
00292 double x5, double x6, double x7, double x8,
00293 const Num2& weight);
00294
00295 template <typename Num2>
00296 void fill(double x0, double x1, double x2, double x3, double x4,
00297 double x5, double x6, double x7, double x8, double x9,
00298 const Num2& weight);
00300
00314 template <typename Num2, class Functor>
00315 void dispatch(const double* coords, unsigned coordLength,
00316 Num2& weight, Functor& f);
00317
00319
00323 template <typename Num2, class Functor>
00324 void dispatch(Num2& weight, Functor& f);
00325
00326 template <typename Num2, class Functor>
00327 void dispatch(double x0, Num2& weight, Functor& f);
00328
00329 template <typename Num2, class Functor>
00330 void dispatch(double x0, double x1, Num2& weight, Functor& f);
00331
00332 template <typename Num2, class Functor>
00333 void dispatch(double x0, double x1, double x2, Num2& weight,
00334 Functor& f);
00335
00336 template <typename Num2, class Functor>
00337 void dispatch(double x0, double x1, double x2, double x3,
00338 Num2& weight, Functor& f);
00339
00340 template <typename Num2, class Functor>
00341 void dispatch(double x0, double x1, double x2, double x3, double x4,
00342 Num2& weight, Functor& f);
00343
00344 template <typename Num2, class Functor>
00345 void dispatch(double x0, double x1, double x2, double x3, double x4,
00346 double x5, Num2& weight, Functor& f);
00347
00348 template <typename Num2, class Functor>
00349 void dispatch(double x0, double x1, double x2, double x3, double x4,
00350 double x5, double x6, Num2& weight, Functor& f);
00351
00352 template <typename Num2, class Functor>
00353 void dispatch(double x0, double x1, double x2, double x3, double x4,
00354 double x5, double x6, double x7, Num2& weight,
00355 Functor& f);
00356
00357 template <typename Num2, class Functor>
00358 void dispatch(double x0, double x1, double x2, double x3, double x4,
00359 double x5, double x6, double x7, double x8,
00360 Num2& weight, Functor& f);
00361
00362 template <typename Num2, class Functor>
00363 void dispatch(double x0, double x1, double x2, double x3, double x4,
00364 double x5, double x6, double x7, double x8, double x9,
00365 Num2& weight, Functor& f);
00367
00374 const Numeric& examine(const double* coords,
00375 unsigned coordLength) const;
00376
00378
00382 const Numeric& examine() const;
00383
00384 const Numeric& examine(double x0) const;
00385
00386 const Numeric& examine(double x0, double x1) const;
00387
00388 const Numeric& examine(double x0, double x1, double x2) const;
00389
00390 const Numeric& examine(double x0, double x1, double x2,
00391 double x3) const;
00392
00393 const Numeric& examine(double x0, double x1, double x2, double x3,
00394 double x4) const;
00395
00396 const Numeric& examine(double x0, double x1, double x2, double x3,
00397 double x4, double x5) const;
00398
00399 const Numeric& examine(double x0, double x1, double x2, double x3,
00400 double x4, double x5, double x6) const;
00401
00402 const Numeric& examine(double x0, double x1, double x2, double x3,
00403 double x4, double x5, double x6,
00404 double x7) const;
00405
00406 const Numeric& examine(double x0, double x1, double x2, double x3,
00407 double x4, double x5, double x6, double x7,
00408 double x8) const;
00409
00410 const Numeric& examine(double x0, double x1, double x2, double x3,
00411 double x4, double x5, double x6, double x7,
00412 double x8, double x9) const;
00414
00421 const Numeric& closestBin(const double* coords,
00422 unsigned coordLength) const;
00423
00425
00429 const Numeric& closestBin() const;
00430
00431 const Numeric& closestBin(double x0) const;
00432
00433 const Numeric& closestBin(double x0, double x1) const;
00434
00435 const Numeric& closestBin(double x0, double x1, double x2) const;
00436
00437 const Numeric& closestBin(double x0, double x1, double x2,
00438 double x3) const;
00439
00440 const Numeric& closestBin(double x0, double x1, double x2, double x3,
00441 double x4) const;
00442
00443 const Numeric& closestBin(double x0, double x1, double x2, double x3,
00444 double x4, double x5) const;
00445
00446 const Numeric& closestBin(double x0, double x1, double x2, double x3,
00447 double x4, double x5, double x6) const;
00448
00449 const Numeric& closestBin(double x0, double x1, double x2, double x3,
00450 double x4, double x5, double x6,
00451 double x7) const;
00452
00453 const Numeric& closestBin(double x0, double x1, double x2, double x3,
00454 double x4, double x5, double x6, double x7,
00455 double x8) const;
00456
00457 const Numeric& closestBin(double x0, double x1, double x2, double x3,
00458 double x4, double x5, double x6, double x7,
00459 double x8, double x9) const;
00461
00484 template <typename Num2>
00485 void fillC(const double* coords, unsigned coordLength,
00486 const Num2& weight);
00487
00489
00493 template <typename Num2>
00494 void fillC(const Num2& weight);
00495
00496 template <typename Num2>
00497 void fillC(double x0, const Num2& weight);
00498
00499 template <typename Num2>
00500 void fillC(double x0, double x1, const Num2& weight);
00501
00502 template <typename Num2>
00503 void fillC(double x0, double x1, double x2, const Num2& weight);
00504
00505 template <typename Num2>
00506 void fillC(double x0, double x1, double x2, double x3,
00507 const Num2& weight);
00508
00509 template <typename Num2>
00510 void fillC(double x0, double x1, double x2, double x3, double x4,
00511 const Num2& weight);
00512
00513 template <typename Num2>
00514 void fillC(double x0, double x1, double x2, double x3, double x4,
00515 double x5, const Num2& weight);
00516
00517 template <typename Num2>
00518 void fillC(double x0, double x1, double x2, double x3, double x4,
00519 double x5, double x6, const Num2& weight);
00520
00521 template <typename Num2>
00522 void fillC(double x0, double x1, double x2, double x3, double x4,
00523 double x5, double x6, double x7, const Num2& weight);
00524
00525 template <typename Num2>
00526 void fillC(double x0, double x1, double x2, double x3, double x4,
00527 double x5, double x6, double x7, double x8,
00528 const Num2& weight);
00529
00530 template <typename Num2>
00531 void fillC(double x0, double x1, double x2, double x3, double x4,
00532 double x5, double x6, double x7, double x8, double x9,
00533 const Num2& weight);
00535
00540 template <typename Num2>
00541 HistoND& operator+=(const HistoND<Num2,Axis>& r);
00542
00552 template <typename Num2>
00553 HistoND& operator-=(const HistoND<Num2,Axis>& r);
00554
00556
00557 template <typename Num2>
00558 void setBin(const unsigned *index, unsigned indexLen, const Num2& v);
00559
00560 template <typename Num2>
00561 void setBin(const Num2& v);
00562
00563 template <typename Num2>
00564 void setBin(unsigned i0, const Num2& v);
00565
00566 template <typename Num2>
00567 void setBin(unsigned i0, unsigned i1, const Num2& v);
00568
00569 template <typename Num2>
00570 void setBin(unsigned i0, unsigned i1, unsigned i2, const Num2& v);
00571
00572 template <typename Num2>
00573 void setBin(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00574 const Num2& v);
00575
00576 template <typename Num2>
00577 void setBin(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00578 unsigned i4, const Num2& v);
00579
00580 template <typename Num2>
00581 void setBin(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00582 unsigned i4, unsigned i5, const Num2& v);
00583
00584 template <typename Num2>
00585 void setBin(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00586 unsigned i4, unsigned i5, unsigned i6, const Num2& v);
00587
00588 template <typename Num2>
00589 void setBin(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00590 unsigned i4, unsigned i5, unsigned i6, unsigned i7,
00591 const Num2& v);
00592
00593 template <typename Num2>
00594 void setBin(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00595 unsigned i4, unsigned i5, unsigned i6, unsigned i7,
00596 unsigned i8, const Num2& v);
00597
00598 template <typename Num2>
00599 void setBin(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00600 unsigned i4, unsigned i5, unsigned i6, unsigned i7,
00601 unsigned i8, unsigned i9, const Num2& v);
00602
00603 template <typename Num2>
00604 inline void setLinearBin(const unsigned long index, const Num2& v)
00605 {data_.linearValue(index) = v; ++modCount_;}
00607
00609
00610 template <typename Num2>
00611 void setBinAt(const unsigned *index, unsigned indexLen, const Num2& v);
00612
00613 template <typename Num2>
00614 void setBinAt(const Num2& v);
00615
00616 template <typename Num2>
00617 void setBinAt(unsigned i0, const Num2& v);
00618
00619 template <typename Num2>
00620 void setBinAt(unsigned i0, unsigned i1, const Num2& v);
00621
00622 template <typename Num2>
00623 void setBinAt(unsigned i0, unsigned i1, unsigned i2, const Num2& v);
00624
00625 template <typename Num2>
00626 void setBinAt(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00627 const Num2& v);
00628
00629 template <typename Num2>
00630 void setBinAt(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00631 unsigned i4, const Num2& v);
00632
00633 template <typename Num2>
00634 void setBinAt(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00635 unsigned i4, unsigned i5, const Num2& v);
00636
00637 template <typename Num2>
00638 void setBinAt(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00639 unsigned i4, unsigned i5, unsigned i6, const Num2& v);
00640
00641 template <typename Num2>
00642 void setBinAt(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00643 unsigned i4, unsigned i5, unsigned i6, unsigned i7,
00644 const Num2& v);
00645
00646 template <typename Num2>
00647 void setBinAt(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00648 unsigned i4, unsigned i5, unsigned i6, unsigned i7,
00649 unsigned i8, const Num2& v);
00650
00651 template <typename Num2>
00652 void setBinAt(unsigned i0, unsigned i1, unsigned i2, unsigned i3,
00653 unsigned i4, unsigned i5, unsigned i6, unsigned i7,
00654 unsigned i8, unsigned i9, const Num2& v);
00655
00656 template <typename Num2>
00657 inline void setLinearBinAt(const unsigned long index, const Num2& v)
00658 {data_.linearValueAt(index) = v; ++modCount_;}
00660
00662 template <typename Num2>
00663 void setBinContents(const Num2* data, unsigned long dataLength,
00664 bool clearOverflows=true);
00665
00667 template <typename Num2>
00668 void setOverflows(const Num2* data, unsigned long dataLength);
00669
00674 template <typename Num2>
00675 inline void setBinsToConst(const Num2& value)
00676 {data_.constFill(value); ++modCount_;}
00677
00682 template <typename Num2>
00683 inline void setOverflowsToConst(const Num2& value)
00684 {overflow_.constFill(value); ++modCount_;}
00685
00692 void recalculateNFillsFromData();
00693
00695
00699 inline void setNFillsTotal(const unsigned long i)
00700 {fillCount_ = i; ++modCount_;}
00701 inline void setNFillsOver(const unsigned long i)
00702 {overCount_ = i; ++modCount_;}
00704
00706 template <typename Num2>
00707 HistoND& operator*=(const Num2& r);
00708
00710 template <typename Num2>
00711 HistoND& operator/=(const Num2& r);
00712
00714
00715 template <typename Num2>
00716 void scaleBinContents(const Num2* data, unsigned long dataLength);
00717
00718 template <typename Num2>
00719 void scaleOverflows(const Num2* data, unsigned long dataLength);
00721
00723
00727 template <typename Num2>
00728 void addToBinContents(const Num2& weight);
00729
00730 template <typename Num2>
00731 void addToOverflows(const Num2& weight);
00733
00735
00740 template <typename Num2>
00741 void addToBinContents(const Num2* data, unsigned long dataLength);
00742
00743 template <typename Num2>
00744 void addToOverflows(const Num2* data, unsigned long dataLength);
00746
00755 template <typename Acc>
00756 void accumulateBinsInBox(const BoxND<double>& box, Acc* acc) const;
00757
00759
00769 template <typename Num2, typename Num3>
00770 void addToProjection(HistoND<Num2,Axis>* projection,
00771 AbsArrayProjector<Numeric,Num3>& projector,
00772 const unsigned *projectedIndices,
00773 unsigned nProjectedIndices) const;
00774
00775 template <typename Num2, typename Num3>
00776 void addToProjection(HistoND<Num2,Axis>* projection,
00777 AbsVisitor<Numeric,Num3>& projector,
00778 const unsigned *projectedIndices,
00779 unsigned nProjectedIndices) const;
00781
00783 HistoND transpose(unsigned axisNum1, unsigned axisNum2) const;
00784
00797 inline unsigned long getModCount() const {return modCount_;}
00798
00804 inline void incrModCount() {++modCount_;}
00805
00807
00808 inline gs::ClassId classId() const {return gs::ClassId(*this);}
00809 bool write(std::ostream& of) const;
00811
00812 static const char* classname();
00813 static inline unsigned version() {return 1;}
00814 static HistoND* read(const gs::ClassId& id, std::istream& in);
00815
00816 private:
00817 HistoND();
00818
00819
00820
00821 HistoND(const HistoND& r, unsigned ax1, unsigned ax2);
00822
00823 template <typename Num2>
00824 void fillPreservingCentroid(const Num2& weight);
00825
00826 template <typename Acc>
00827 void accumulateBinsLoop(unsigned level, const BoxND<double>& box,
00828 unsigned* idx, Acc* accumulator,
00829 double overlapFraction) const;
00830 std::string title_;
00831 std::string accumulatedDataLabel_;
00832 ArrayND<Numeric> data_;
00833 ArrayND<Numeric> overflow_;
00834 std::vector<Axis> axes_;
00835 mutable std::vector<double> weightBuf_;
00836 mutable std::vector<unsigned> indexBuf_;
00837 unsigned long fillCount_;
00838 unsigned long overCount_;
00839 unsigned long modCount_;
00840 unsigned dim_;
00841
00842 };
00843
00858 template <typename Histo>
00859 void convertHistoToDensity(Histo* histogram, bool knownNonNegative=false);
00860
00866 template <typename Histo>
00867 std::vector<LinearMapper1d> densityScanHistoMap(const Histo& histo);
00868
00879 template <typename Histo>
00880 std::vector<CircularMapper1d> convolutionHistoMap(const Histo& histo,
00881 bool doubleDataRange);
00882 }
00883
00884 #include <cassert>
00885 #include "JetMETCorrections/InterpolationTables/interface/NpstatException.h"
00886 #include <sstream>
00887 #include <climits>
00888 #include <algorithm>
00889
00890 #include "Alignment/Geners/interface/CPP11_auto_ptr.hh"
00891 #include "Alignment/Geners/interface/binaryIO.hh"
00892
00893 namespace npstat {
00894 namespace Private {
00895 template <class Axis>
00896 ArrayShape makeHistoShape(const std::vector<Axis>& axes)
00897 {
00898 const unsigned n = axes.size();
00899 ArrayShape result;
00900 result.reserve(n);
00901 for (unsigned i=0; i<n; ++i)
00902 result.push_back(axes[i].nBins());
00903 return result;
00904 }
00905
00906 template <class Axis>
00907 ArrayShape makeHistoShape(const Axis& xAxis)
00908 {
00909 ArrayShape result;
00910 result.reserve(1U);
00911 result.push_back(xAxis.nBins());
00912 return result;
00913 }
00914
00915 template <class Axis>
00916 ArrayShape makeHistoShape(const Axis& xAxis, const Axis& yAxis)
00917 {
00918 ArrayShape result;
00919 result.reserve(2U);
00920 result.push_back(xAxis.nBins());
00921 result.push_back(yAxis.nBins());
00922 return result;
00923 }
00924
00925 template <class Axis>
00926 ArrayShape makeHistoShape(const Axis& xAxis,
00927 const Axis& yAxis,
00928 const Axis& zAxis)
00929 {
00930 ArrayShape result;
00931 result.reserve(3U);
00932 result.push_back(xAxis.nBins());
00933 result.push_back(yAxis.nBins());
00934 result.push_back(zAxis.nBins());
00935 return result;
00936 }
00937
00938 template <class Axis>
00939 ArrayShape makeHistoShape(const Axis& xAxis, const Axis& yAxis,
00940 const Axis& zAxis, const Axis& tAxis)
00941 {
00942 ArrayShape result;
00943 result.reserve(4U);
00944 result.push_back(xAxis.nBins());
00945 result.push_back(yAxis.nBins());
00946 result.push_back(zAxis.nBins());
00947 result.push_back(tAxis.nBins());
00948 return result;
00949 }
00950
00951 template <class Axis>
00952 ArrayShape makeHistoShape(const Axis& xAxis, const Axis& yAxis,
00953 const Axis& zAxis, const Axis& tAxis,
00954 const Axis& vAxis)
00955 {
00956 ArrayShape result;
00957 result.reserve(5U);
00958 result.push_back(xAxis.nBins());
00959 result.push_back(yAxis.nBins());
00960 result.push_back(zAxis.nBins());
00961 result.push_back(tAxis.nBins());
00962 result.push_back(vAxis.nBins());
00963 return result;
00964 }
00965
00966 template <class Axis>
00967 std::vector<Axis> axesOfASlice(const std::vector<Axis>& axes,
00968 const unsigned *fixedIndices,
00969 const unsigned nFixedIndices)
00970 {
00971 const unsigned dim = axes.size();
00972 std::vector<Axis> newAxes;
00973 if (nFixedIndices == 0U) throw npstat::NpstatInvalidArgument(
00974 "In npstat::Private::axesOfASlice: "
00975 "at least one fixed index must be specified");
00976 if (nFixedIndices > dim) throw npstat::NpstatInvalidArgument(
00977 "In npstat::Private::axesOfASlice: too many fixed indices");
00978 assert(fixedIndices);
00979 for (unsigned i=0; i<nFixedIndices; ++i)
00980 if (fixedIndices[i] >= dim) throw npstat::NpstatInvalidArgument(
00981 "In npstat::Private::axesOfASlice: fixed index out of range");
00982 newAxes.reserve(dim - nFixedIndices);
00983 for (unsigned i=0; i<dim; ++i)
00984 {
00985 bool fixed = false;
00986 for (unsigned j=0; j<nFixedIndices; ++j)
00987 if (fixedIndices[j] == i)
00988 {
00989 fixed = true;
00990 break;
00991 }
00992 if (!fixed)
00993 newAxes.push_back(axes[i]);
00994 }
00995 if (newAxes.size() != dim - nFixedIndices)
00996 throw npstat::NpstatInvalidArgument(
00997 "In npstat::Private::axesOfASlice: duplicate fixed index");
00998 return newAxes;
00999 }
01000
01001 template <class Axis>
01002 ArrayShape shapeOfASlice(const std::vector<Axis>& axes,
01003 const unsigned *fixedIndices,
01004 const unsigned nFixedIndices)
01005 {
01006 const unsigned dim = axes.size();
01007 if (nFixedIndices == 0U) throw npstat::NpstatInvalidArgument(
01008 "In npstat::Private::shapeOfASlice: "
01009 "at least one fixed index must be specified");
01010 if (nFixedIndices > dim) throw npstat::NpstatInvalidArgument(
01011 "In npstat::Private::shapeOfASlice: too many fixed indices");
01012 assert(fixedIndices);
01013
01014
01015 for (unsigned j=0; j<nFixedIndices; ++j)
01016 if (fixedIndices[j] >= dim) throw npstat::NpstatInvalidArgument(
01017 "In npstat::Private::shapeOfASlice: fixed index out of range");
01018
01019
01020 ArrayShape sh;
01021 if (nFixedIndices < dim)
01022 sh.reserve(dim - nFixedIndices);
01023 for (unsigned i=0; i<dim; ++i)
01024 {
01025 bool fixed = false;
01026 for (unsigned j=0; j<nFixedIndices; ++j)
01027 if (fixedIndices[j] == i)
01028 {
01029 fixed = true;
01030 break;
01031 }
01032 if (!fixed)
01033 sh.push_back(axes[i].nBins());
01034 }
01035 if (sh.size() != dim - nFixedIndices)
01036 throw npstat::NpstatInvalidArgument(
01037 "In npstat::Private::shapeOfASlice: duplicate fixed index");
01038 return sh;
01039 }
01040
01041 template <class Axis>
01042 std::vector<Axis> addAxis(const std::vector<Axis>& axes,
01043 const Axis& newAxis,
01044 const unsigned newAxisNumber)
01045 {
01046 const unsigned dim = axes.size();
01047 std::vector<Axis> newAxes;
01048 newAxes.reserve(dim + 1U);
01049 unsigned iadd = 0;
01050 for (unsigned i=0; i<dim; ++i)
01051 {
01052 if (newAxisNumber == i)
01053 newAxes.push_back(newAxis);
01054 else
01055 newAxes.push_back(axes[iadd++]);
01056 }
01057 if (iadd == dim)
01058 newAxes.push_back(newAxis);
01059 else
01060 newAxes.push_back(axes[iadd]);
01061 return newAxes;
01062 }
01063
01064 template <class Axis>
01065 ArrayShape shapeWithExtraAxis(const std::vector<Axis>& axes,
01066 const Axis& newAxis,
01067 const unsigned newAxisNumber)
01068 {
01069 const unsigned dim = axes.size();
01070 ArrayShape result;
01071 result.reserve(dim + 1U);
01072 unsigned iadd = 0;
01073 for (unsigned i=0; i<dim; ++i)
01074 {
01075 if (newAxisNumber == i)
01076 result.push_back(newAxis.nBins());
01077 else
01078 result.push_back(axes[iadd++].nBins());
01079 }
01080 if (iadd == dim)
01081 result.push_back(newAxis.nBins());
01082 else
01083 result.push_back(axes[iadd].nBins());
01084 return result;
01085 }
01086
01087 inline void h_badargs(const char* method)
01088 {
01089 std::ostringstream os;
01090 os << "In npstat::HistoND::" << method << ": number of arguments"
01091 << " is incompatible with histogram dimensionality";
01092 throw npstat::NpstatInvalidArgument(os.str());
01093 }
01094 }
01095
01096 template <typename Numeric, class Axis>
01097 template <typename Acc>
01098 void HistoND<Numeric,Axis>::accumulateBinsLoop(
01099 const unsigned level, const BoxND<double>& box,
01100 unsigned* idx, Acc* accumulator, const double overlapFraction) const
01101 {
01102 const Interval<double>& boxSide(box[level]);
01103 const Axis& axis(axes_[level]);
01104 const unsigned nbins = axis.nBins();
01105 const bool lastLevel = level == dim_ - 1U;
01106 for (unsigned i=0; i<nbins; ++i)
01107 {
01108 const double over = overlapFraction*
01109 axis.binInterval(i).overlapFraction(boxSide);
01110 if (over > 0.0)
01111 {
01112 idx[level] = i;
01113 if (lastLevel)
01114 *accumulator += over*data_.value(idx, dim_);
01115 else
01116 accumulateBinsLoop(level+1U, box, idx, accumulator, over);
01117 }
01118 }
01119 }
01120
01121 template <typename Numeric, class Axis>
01122 template <typename Acc>
01123 void HistoND<Numeric,Axis>::accumulateBinsInBox(
01124 const BoxND<double>& box, Acc* accumulator) const
01125 {
01126 if (box.size() != dim_) throw npstat::NpstatInvalidArgument(
01127 "In npstat::HistoND::accumulateBinsInBox: "
01128 "incompatible box dimensionality");
01129 assert(accumulator);
01130 if (dim_)
01131 {
01132 for (unsigned i=0; i<dim_; ++i)
01133 indexBuf_[i] = 0U;
01134 accumulateBinsLoop(0U, box, &indexBuf_[0], accumulator, 1.0);
01135 }
01136 else
01137 *accumulator += 1.0*data_();
01138 }
01139
01140 template <typename Numeric, class Axis>
01141 inline void HistoND<Numeric,Axis>::clearBinContents()
01142 {
01143 data_.clear();
01144 fillCount_ = 0UL;
01145 ++modCount_;
01146 }
01147
01148 template <typename Numeric, class Axis>
01149 inline void HistoND<Numeric,Axis>::clearOverflows()
01150 {
01151 overflow_.clear();
01152 overCount_ = 0UL;
01153 ++modCount_;
01154 }
01155
01156 template <typename Numeric, class Axis>
01157 inline void HistoND<Numeric,Axis>::clear()
01158 {
01159 clearBinContents();
01160 clearOverflows();
01161 ++modCount_;
01162 }
01163
01164 template <typename Numeric, class Axis>
01165 HistoND<Numeric,Axis>::HistoND(const std::vector<Axis>& axesIn,
01166 const char* title, const char* label)
01167 : title_(title ? title : ""),
01168 accumulatedDataLabel_(label ? label : ""),
01169 data_(Private::makeHistoShape(axesIn)),
01170 overflow_(ArrayShape(axesIn.size(), 3U)),
01171 axes_(axesIn),
01172 weightBuf_(axesIn.size()),
01173 indexBuf_(2U*axesIn.size()),
01174 modCount_(0UL),
01175 dim_(axesIn.size())
01176 {
01177 if (dim_ >= CHAR_BIT*sizeof(unsigned long))
01178 throw npstat::NpstatInvalidArgument(
01179 "In npstat::HistoND constructor: requested histogram "
01180 "dimensionality is not supported (too large)");
01181 clear();
01182 }
01183
01184 template <typename Numeric, class Axis>
01185 HistoND<Numeric,Axis>::HistoND(const Axis& xAxis,
01186 const char* title, const char* label)
01187 : title_(title ? title : ""),
01188 accumulatedDataLabel_(label ? label : ""),
01189 data_(Private::makeHistoShape(xAxis)),
01190 overflow_(ArrayShape(1U, 3U)),
01191 weightBuf_(1U),
01192 indexBuf_(2U*1U),
01193 modCount_(0UL),
01194 dim_(1U)
01195 {
01196 axes_.reserve(dim_);
01197 axes_.push_back(xAxis);
01198 clear();
01199 }
01200
01201 template <typename Numeric, class Axis>
01202 HistoND<Numeric,Axis>::HistoND(const Axis& xAxis, const Axis& yAxis,
01203 const char* title, const char* label)
01204 : title_(title ? title : ""),
01205 accumulatedDataLabel_(label ? label : ""),
01206 data_(Private::makeHistoShape(xAxis, yAxis)),
01207 overflow_(ArrayShape(2U, 3U)),
01208 weightBuf_(2U),
01209 indexBuf_(2U*2U),
01210 modCount_(0UL),
01211 dim_(2U)
01212 {
01213 axes_.reserve(dim_);
01214 axes_.push_back(xAxis);
01215 axes_.push_back(yAxis);
01216 clear();
01217 }
01218
01219 template <typename Numeric, class Axis>
01220 HistoND<Numeric,Axis>::HistoND(const Axis& xAxis, const Axis& yAxis,
01221 const Axis& zAxis, const char* title,
01222 const char* label)
01223 : title_(title ? title : ""),
01224 accumulatedDataLabel_(label ? label : ""),
01225 data_(Private::makeHistoShape(xAxis, yAxis, zAxis)),
01226 overflow_(ArrayShape(3U, 3U)),
01227 weightBuf_(3U),
01228 indexBuf_(2U*3U),
01229 modCount_(0UL),
01230 dim_(3U)
01231 {
01232 axes_.reserve(dim_);
01233 axes_.push_back(xAxis);
01234 axes_.push_back(yAxis);
01235 axes_.push_back(zAxis);
01236 clear();
01237 }
01238
01239 template <typename Numeric, class Axis>
01240 HistoND<Numeric,Axis>::HistoND(const Axis& xAxis, const Axis& yAxis,
01241 const Axis& zAxis, const Axis& tAxis,
01242 const char* title, const char* label)
01243 : title_(title ? title : ""),
01244 accumulatedDataLabel_(label ? label : ""),
01245 data_(Private::makeHistoShape(xAxis, yAxis, zAxis, tAxis)),
01246 overflow_(ArrayShape(4U, 3U)),
01247 weightBuf_(4U),
01248 indexBuf_(2U*4U),
01249 modCount_(0UL),
01250 dim_(4U)
01251 {
01252 axes_.reserve(dim_);
01253 axes_.push_back(xAxis);
01254 axes_.push_back(yAxis);
01255 axes_.push_back(zAxis);
01256 axes_.push_back(tAxis);
01257 clear();
01258 }
01259
01260 template <typename Numeric, class Axis>
01261 HistoND<Numeric,Axis>::HistoND(const Axis& xAxis, const Axis& yAxis,
01262 const Axis& zAxis, const Axis& tAxis,
01263 const Axis& vAxis,
01264 const char* title, const char* label)
01265 : title_(title ? title : ""),
01266 accumulatedDataLabel_(label ? label : ""),
01267 data_(Private::makeHistoShape(xAxis, yAxis, zAxis, tAxis, vAxis)),
01268 overflow_(ArrayShape(5U, 3U)),
01269 weightBuf_(5U),
01270 indexBuf_(2U*5U),
01271 modCount_(0UL),
01272 dim_(5U)
01273 {
01274 axes_.reserve(dim_);
01275 axes_.push_back(xAxis);
01276 axes_.push_back(yAxis);
01277 axes_.push_back(zAxis);
01278 axes_.push_back(tAxis);
01279 axes_.push_back(vAxis);
01280 clear();
01281 }
01282
01283 template <typename Numeric, class Axis>
01284 HistoND<Numeric,Axis>::HistoND(const ArrayShape& shape,
01285 const BoxND<double>& boundingBox,
01286 const char* title, const char* label)
01287 : title_(title ? title : ""),
01288 accumulatedDataLabel_(label ? label : ""),
01289 data_(shape),
01290 overflow_(ArrayShape(shape.size(), 3U)),
01291 weightBuf_(shape.size()),
01292 indexBuf_(2U*shape.size()),
01293 modCount_(0UL),
01294 dim_(shape.size())
01295 {
01296 if (boundingBox.size() != dim_) throw npstat::NpstatInvalidArgument(
01297 "In npstat::HistoND constructor: "
01298 "incompatible bounding box dimensionality");
01299 if (dim_ >= CHAR_BIT*sizeof(unsigned long))
01300 throw npstat::NpstatInvalidArgument(
01301 "In npstat::HistoND constructor: requested histogram "
01302 "dimensionality is not supported (too large)");
01303 axes_.reserve(dim_);
01304 for (unsigned i=0; i<dim_; ++i)
01305 axes_.push_back(Axis(shape[i],
01306 boundingBox[i].min(),
01307 boundingBox[i].max()));
01308 clear();
01309 }
01310
01311 template <typename Numeric, class Axis>
01312 template <typename Num2, class Functor>
01313 HistoND<Numeric,Axis>::HistoND(
01314 const HistoND<Num2,Axis>& r, const Functor& f,
01315 const char* title, const char* label)
01316 : title_(title ? title : ""),
01317 accumulatedDataLabel_(label ? label : ""),
01318 data_(r.data_, f),
01319 overflow_(r.overflow_, f),
01320 axes_(r.axes_),
01321 weightBuf_(r.dim_),
01322 indexBuf_(2U*r.dim_),
01323 fillCount_(r.fillCount_),
01324 overCount_(r.overCount_),
01325 modCount_(0UL),
01326 dim_(r.dim_)
01327 {
01328 }
01329
01330 template <typename Numeric, class Axis>
01331 template <typename Num2>
01332 HistoND<Numeric,Axis>::HistoND(
01333 const HistoND<Num2,Axis>& h, const unsigned *indices,
01334 const unsigned nIndices, const char* title)
01335 : title_(title ? title : ""),
01336 accumulatedDataLabel_(h.accumulatedDataLabel_),
01337 data_(Private::shapeOfASlice(h.axes_, indices, nIndices)),
01338 overflow_(ArrayShape(data_.rank(), 3U)),
01339 axes_(Private::axesOfASlice(h.axes_, indices, nIndices)),
01340 weightBuf_(data_.rank()),
01341 indexBuf_(2U*data_.rank()),
01342 modCount_(0UL),
01343 dim_(data_.rank())
01344 {
01345 clear();
01346 }
01347
01348 template <typename Numeric, class Axis>
01349 template <typename Num2>
01350 HistoND<Numeric,Axis>::HistoND(
01351 const HistoND<Num2,Axis>& h, const Axis& newAxis,
01352 const unsigned newAxisNumber, const char* title)
01353 : title_(title ? title : ""),
01354 accumulatedDataLabel_(h.accumulatedDataLabel_),
01355 data_(Private::shapeWithExtraAxis(h.axes_, newAxis, newAxisNumber)),
01356 overflow_(data_.rank(), 3U),
01357 axes_(Private::addAxis(h.axes_, newAxis, newAxisNumber)),
01358 weightBuf_(data_.rank()),
01359 indexBuf_(2U*data_.rank()),
01360 modCount_(0UL),
01361 dim_(data_.rank())
01362 {
01363 if (dim_ >= CHAR_BIT*sizeof(unsigned long))
01364 throw npstat::NpstatInvalidArgument(
01365 "In npstat::HistoND constructor: requested histogram "
01366 "dimensionality is not supported (too large)");
01367 clear();
01368 }
01369
01370 template <typename Numeric, class Axis>
01371 bool HistoND<Numeric,Axis>::isUniformlyBinned() const
01372 {
01373 for (unsigned i=0; i<dim_; ++i)
01374 if (!axes_[i].isUniform())
01375 return false;
01376 return true;
01377 }
01378
01379 template <typename Numeric, class Axis>
01380 double HistoND<Numeric,Axis>::integral() const
01381 {
01382 typedef typename PreciseType<Numeric>::type Precise;
01383
01384 if (dim_ == 0U)
01385 return 0.0;
01386 if (isUniformlyBinned())
01387 {
01388 Precise sum = data_.template sum<Precise>();
01389 return static_cast<double>(sum)*binVolume();
01390 }
01391 else
01392 {
01393 Precise sum = Precise();
01394 const Numeric* data = data_.data();
01395 const unsigned long len = data_.length();
01396 for (unsigned long i=0; i<len; ++i)
01397 sum += data[i]*binVolume(i);
01398 return static_cast<double>(sum);
01399 }
01400 }
01401
01402 template <typename Numeric, class Axis>
01403 BoxND<double> HistoND<Numeric,Axis>::boundingBox() const
01404 {
01405 BoxND<double> box;
01406 if (dim_)
01407 {
01408 box.reserve(dim_);
01409 const Axis* ax = &axes_[0];
01410 for (unsigned i=0; i<dim_; ++i)
01411 box.push_back(ax[i].interval());
01412 }
01413 return box;
01414 }
01415
01416 template <typename Numeric, class Axis>
01417 void HistoND<Numeric,Axis>::binCenter(
01418 const unsigned long binNumber,
01419 double* coords, const unsigned lenCoords) const
01420 {
01421 if (dim_ != lenCoords) throw npstat::NpstatInvalidArgument(
01422 "In npstat::HistoND::binCenter: "
01423 "incompatible input point dimensionality");
01424 if (dim_)
01425 {
01426 assert(coords);
01427 data_.convertLinearIndex(binNumber, &indexBuf_[0], dim_);
01428 const Axis* ax = &axes_[0];
01429 for (unsigned i=0; i<dim_; ++i)
01430 coords[i] = ax[i].binCenter(indexBuf_[i]);
01431 }
01432 }
01433
01434 template <typename Numeric, class Axis>
01435 template <class Point>
01436 void HistoND<Numeric,Axis>::allBinCenters(
01437 std::vector<Point>* centers) const
01438 {
01439 assert(centers);
01440 centers->clear();
01441 const unsigned long len = data_.length();
01442 centers->reserve(len);
01443 unsigned* ibuf = &indexBuf_[0];
01444 const Axis* ax = &axes_[0];
01445 Point center;
01446 if (center.size() < dim_) throw npstat::NpstatInvalidArgument(
01447 "In npstat::HistoND::allBinCenters: "
01448 "incompatible point dimensionality (too small)");
01449 typename Point::value_type* cdat = ¢er[0];
01450
01451 for (unsigned long i=0; i<len; ++i)
01452 {
01453 data_.convertLinearIndex(i, ibuf, dim_);
01454 for (unsigned idim=0; idim<dim_; ++idim)
01455 cdat[idim] = ax[idim].binCenter(ibuf[idim]);
01456 centers->push_back(center);
01457 }
01458 }
01459
01460 template <typename Numeric, class Axis>
01461 void HistoND<Numeric,Axis>::binBox(const unsigned long binNumber,
01462 BoxND<double>* box) const
01463 {
01464 assert(box);
01465 box->clear();
01466 if (dim_)
01467 {
01468 box->reserve(dim_);
01469 data_.convertLinearIndex(binNumber, &indexBuf_[0], dim_);
01470 const Axis* ax = &axes_[0];
01471 for (unsigned i=0; i<dim_; ++i)
01472 box->push_back(ax[i].binInterval(indexBuf_[i]));
01473 }
01474 }
01475
01476 template <typename Numeric, class Axis>
01477 inline bool HistoND<Numeric,Axis>::isSameData(const HistoND& r) const
01478 {
01479 return dim_ == r.dim_ &&
01480 overflow_ == r.overflow_ &&
01481 data_ == r.data_;
01482 }
01483
01484 template <typename Numeric, class Axis>
01485 inline bool HistoND<Numeric,Axis>::operator==(const HistoND& r) const
01486 {
01487 return dim_ == r.dim_ &&
01488 fillCount_ == r.fillCount_ &&
01489 overCount_ == r.overCount_ &&
01490 title_ == r.title_ &&
01491 accumulatedDataLabel_ == r.accumulatedDataLabel_ &&
01492 axes_ == r.axes_ &&
01493 overflow_ == r.overflow_ &&
01494 data_ == r.data_;
01495 }
01496
01497 template <typename Numeric, class Axis>
01498 inline bool HistoND<Numeric,Axis>::operator!=(const HistoND& r) const
01499 {
01500 return !(*this == r);
01501 }
01502
01503 template <typename Numeric, class Axis>
01504 double HistoND<Numeric,Axis>::binVolume(
01505 const unsigned long binNumber) const
01506 {
01507 double v = 1.0;
01508 if (dim_)
01509 {
01510 data_.convertLinearIndex(binNumber, &indexBuf_[0], dim_);
01511 const Axis* ax = &axes_[0];
01512 for (unsigned i=0; i<dim_; ++i)
01513 v *= ax[i].binWidth(indexBuf_[i]);
01514 }
01515 return v;
01516 }
01517
01518 template <typename Numeric, class Axis>
01519 double HistoND<Numeric,Axis>::volume() const
01520 {
01521 double v = 1.0;
01522 if (dim_)
01523 {
01524 const Axis* ax = &axes_[0];
01525 for (unsigned i=0; i<dim_; ++i)
01526 v *= (ax[i].max() - ax[i].min());
01527 }
01528 return v;
01529 }
01530
01531 template <typename Numeric, class Axis>
01532 template <typename Num2>
01533 void HistoND<Numeric,Axis>::fill(
01534 const double* coords, const unsigned coordLength, const Num2& w)
01535 {
01536 if (coordLength != dim_) throw npstat::NpstatInvalidArgument(
01537 "In npstat::HistoND::fill: "
01538 "incompatible input point dimensionality");
01539 if (coordLength)
01540 {
01541 assert(coords);
01542 unsigned* idx = &indexBuf_[0];
01543 unsigned* over = idx + dim_;
01544 const Axis* ax = &axes_[0];
01545 unsigned overflown = 0U;
01546 for (unsigned i=0; i<dim_; ++i)
01547 {
01548 over[i] = ax[i].overflowIndex(coords[i], idx + i);
01549 overflown |= (over[i] - 1U);
01550 }
01551 if (overflown)
01552 {
01553 overflow_.value(over, dim_) += w;
01554 ++overCount_;
01555 }
01556 else
01557 data_.value(idx, dim_) += w;
01558 }
01559 else
01560 data_() += w;
01561 ++fillCount_; ++modCount_;
01562 }
01563
01564 template <typename Numeric, class Axis>
01565 template <typename Num2, class Functor>
01566 void HistoND<Numeric,Axis>::dispatch(
01567 const double* coords, const unsigned coordLength, Num2& w, Functor& f)
01568 {
01569 if (coordLength != dim_) throw npstat::NpstatInvalidArgument(
01570 "In npstat::HistoND::dispatch: "
01571 "incompatible input point dimensionality");
01572 if (coordLength)
01573 {
01574 assert(coords);
01575 unsigned* idx = &indexBuf_[0];
01576 unsigned* over = idx + dim_;
01577 const Axis* ax = &axes_[0];
01578 unsigned overflown = 0U;
01579 for (unsigned i=0; i<dim_; ++i)
01580 {
01581 over[i] = ax[i].overflowIndex(coords[i], idx + i);
01582 overflown |= (over[i] - 1U);
01583 }
01584 if (overflown)
01585 f(overflow_.value(over, dim_), w);
01586 else
01587 f(data_.value(idx, dim_), w);
01588 }
01589 else
01590 f(data_(), w);
01591 ++modCount_;
01592 }
01593
01594 template <typename Numeric, class Axis>
01595 const Numeric& HistoND<Numeric,Axis>::examine(
01596 const double* coords, const unsigned coordLength) const
01597 {
01598 if (coordLength != dim_) throw npstat::NpstatInvalidArgument(
01599 "In npstat::HistoND::examine: "
01600 "incompatible input point dimensionality");
01601 if (coordLength)
01602 {
01603 assert(coords);
01604 unsigned* idx = &indexBuf_[0];
01605 unsigned* over = idx + dim_;
01606 const Axis* ax = &axes_[0];
01607 unsigned overflown = 0U;
01608 for (unsigned i=0; i<dim_; ++i)
01609 {
01610 over[i] = ax[i].overflowIndex(coords[i], idx + i);
01611 overflown |= (over[i] - 1U);
01612 }
01613 if (overflown)
01614 return overflow_.value(over, dim_);
01615 else
01616 return data_.value(idx, dim_);
01617 }
01618 else
01619 return data_();
01620 }
01621
01622 template <typename Numeric, class Axis>
01623 const Numeric& HistoND<Numeric,Axis>::closestBin(
01624 const double* coords, const unsigned coordLength) const
01625 {
01626 if (coordLength != dim_) throw npstat::NpstatInvalidArgument(
01627 "In npstat::HistoND::closestBin: "
01628 "incompatible input point dimensionality");
01629 if (coordLength)
01630 {
01631 assert(coords);
01632 unsigned* idx = &indexBuf_[0];
01633 const Axis* ax = &axes_[0];
01634 for (unsigned i=0; i<dim_; ++i)
01635 idx[i] = ax[i].closestValidBin(coords[i]);
01636 return data_.value(idx, dim_);
01637 }
01638 else
01639 return data_();
01640 }
01641
01642 template <typename Numeric, class Axis>
01643 template <typename Num2>
01644 void HistoND<Numeric,Axis>::fillPreservingCentroid(const Num2& value)
01645 {
01646 const double* weights = &weightBuf_[0];
01647 const unsigned* cell = &indexBuf_[0];
01648 const unsigned long* strides = data_.strides();
01649 const unsigned long maxcycle = 1UL << dim_;
01650 for (unsigned long icycle=0; icycle<maxcycle; ++icycle)
01651 {
01652 double w = 1.0;
01653 unsigned long icell = 0UL;
01654 for (unsigned i=0; i<dim_; ++i)
01655 {
01656 if (icycle & (1UL << i))
01657 {
01658 w *= (1.0 - weights[i]);
01659 icell += strides[i]*(cell[i] + 1U);
01660 }
01661 else
01662 {
01663 w *= weights[i];
01664 icell += strides[i]*cell[i];
01665 }
01666 }
01667 data_.linearValue(icell) += (value * w);
01668 }
01669 }
01670
01671 template <typename Numeric, class Axis>
01672 template <typename Num2>
01673 void HistoND<Numeric,Axis>::fillC(
01674 const double* coords, const unsigned coordLength, const Num2& w)
01675 {
01676 if (coordLength != dim_) throw npstat::NpstatInvalidArgument(
01677 "In npstat::HistoND::fillC: "
01678 "incompatible input point dimensionality");
01679 if (coordLength)
01680 {
01681 assert(coords);
01682 double* wg = &weightBuf_[0];
01683 unsigned* idx = &indexBuf_[0];
01684 unsigned* over = idx + dim_;
01685 const Axis* ax = &axes_[0];
01686 unsigned overflown = 0U;
01687 for (unsigned i=0; i<dim_; ++i)
01688 {
01689 over[i] = ax[i].overflowIndexWeighted(coords[i], idx+i, wg+i);
01690 overflown |= (over[i] - 1U);
01691 }
01692 if (overflown)
01693 {
01694 overflow_.value(over, dim_) += w;
01695 ++overCount_;
01696 }
01697 else
01698 fillPreservingCentroid(w);
01699 }
01700 else
01701 data_() += w;
01702 ++fillCount_; ++modCount_;
01703 }
01704
01705 template <typename Numeric, class Axis>
01706 template <typename Num2>
01707 inline void HistoND<Numeric,Axis>::fill(const Num2& w)
01708 {
01709 if (dim_) Private::h_badargs("fill");
01710 data_() += w;
01711 ++fillCount_; ++modCount_;
01712 }
01713
01714 template <typename Numeric, class Axis>
01715 template <typename Num2, class Functor>
01716 inline void HistoND<Numeric,Axis>::dispatch(Num2& w, Functor& f)
01717 {
01718 if (dim_) Private::h_badargs("dispatch");
01719 f(data_(), w);
01720 ++modCount_;
01721 }
01722
01723 template <typename Numeric, class Axis>
01724 template <typename Num2>
01725 inline void HistoND<Numeric,Axis>::fillC(const Num2& w)
01726 {
01727 if (dim_) Private::h_badargs("fillC");
01728 data_() += w;
01729 ++fillCount_; ++modCount_;
01730 }
01731
01732 template <typename Numeric, class Axis>
01733 inline const Numeric& HistoND<Numeric,Axis>::examine() const
01734 {
01735 if (dim_) Private::h_badargs("examine");
01736 return data_();
01737 }
01738
01739 template <typename Numeric, class Axis>
01740 inline const Numeric& HistoND<Numeric,Axis>::closestBin() const
01741 {
01742 if (dim_) Private::h_badargs("closestBin");
01743 return data_();
01744 }
01745
01746 template <typename Numeric, class Axis>
01747 template <typename Num2>
01748 void HistoND<Numeric,Axis>::fill(const double x0, const Num2& w)
01749 {
01750 if (dim_ != 1U) Private::h_badargs("fill");
01751 unsigned i0;
01752 const unsigned ov0 = axes_[0].overflowIndex(x0, &i0);
01753 if (ov0 == 1U)
01754 data_(i0) += w;
01755 else
01756 {
01757 overflow_(ov0) += w;
01758 ++overCount_;
01759 }
01760 ++fillCount_; ++modCount_;
01761 }
01762
01763 template <typename Numeric, class Axis>
01764 template <typename Num2, class Functor>
01765 void HistoND<Numeric,Axis>::dispatch(const double x0, Num2& w, Functor& f)
01766 {
01767 if (dim_ != 1U) Private::h_badargs("dispatch");
01768 unsigned i0;
01769 const unsigned ov0 = axes_[0].overflowIndex(x0, &i0);
01770 if (ov0 == 1U)
01771 f(data_(i0), w);
01772 else
01773 f(overflow_(ov0), w);
01774 ++modCount_;
01775 }
01776
01777 template <typename Numeric, class Axis>
01778 template <typename Num2>
01779 void HistoND<Numeric,Axis>::fillC(const double x0, const Num2& w)
01780 {
01781 if (dim_ != 1U) Private::h_badargs("fillC");
01782 double* wg = &weightBuf_[0];
01783 unsigned* idx = &indexBuf_[0];
01784 const unsigned ov0 = axes_[0].overflowIndexWeighted(x0, idx, wg);
01785 if (ov0 == 1U)
01786 fillPreservingCentroid(w);
01787 else
01788 {
01789 overflow_(ov0) += w;
01790 ++overCount_;
01791 }
01792 ++fillCount_; ++modCount_;
01793 }
01794
01795 template <typename Numeric, class Axis>
01796 inline const Numeric& HistoND<Numeric,Axis>::examine(const double x0) const
01797 {
01798 if (dim_ != 1U) Private::h_badargs("examine");
01799 unsigned i0;
01800 const unsigned ov0 = axes_[0].overflowIndex(x0, &i0);
01801 if (ov0 == 1U)
01802 return data_(i0);
01803 else
01804 return overflow_(ov0);
01805 }
01806
01807 template <typename Numeric, class Axis>
01808 inline const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0) const
01809 {
01810 if (dim_ != 1U) Private::h_badargs("closestBin");
01811 const unsigned i0 = axes_[0].closestValidBin(x0);
01812 return data_(i0);
01813 }
01814
01815 template <typename Numeric, class Axis>
01816 template <typename Num2>
01817 void HistoND<Numeric,Axis>::fill(const double x0, const double x1,
01818 const Num2& w)
01819 {
01820 if (dim_ != 2U) Private::h_badargs("fill");
01821 unsigned i0, i1;
01822 const Axis* ax = &axes_[0];
01823 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
01824 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
01825 if (o0 == 1U && o1 == 1U)
01826 data_(i0, i1) += w;
01827 else
01828 {
01829 overflow_(o0, o1) += w;
01830 ++overCount_;
01831 }
01832 ++fillCount_; ++modCount_;
01833 }
01834
01835 template <typename Numeric, class Axis>
01836 template <typename Num2, class Functor>
01837 void HistoND<Numeric,Axis>::dispatch(const double x0, const double x1,
01838 Num2& w, Functor& f)
01839 {
01840 if (dim_ != 2U) Private::h_badargs("dispatch");
01841 unsigned i0, i1;
01842 const Axis* ax = &axes_[0];
01843 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
01844 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
01845 if (o0 == 1U && o1 == 1U)
01846 f(data_(i0, i1), w);
01847 else
01848 f(overflow_(o0, o1), w);
01849 ++modCount_;
01850 }
01851
01852 template <typename Numeric, class Axis>
01853 template <typename Num2>
01854 void HistoND<Numeric,Axis>::fillC(const double x0, const double x1,
01855 const Num2& w)
01856 {
01857 if (dim_ != 2U) Private::h_badargs("fillC");
01858 double* wg = &weightBuf_[0];
01859 unsigned* idx = &indexBuf_[0];
01860 const Axis* ax = &axes_[0];
01861 const unsigned o0 = ax[0].overflowIndexWeighted(x0, idx+0, wg+0);
01862 const unsigned o1 = ax[1].overflowIndexWeighted(x1, idx+1, wg+1);
01863 if (o0 == 1U && o1 == 1U)
01864 fillPreservingCentroid(w);
01865 else
01866 {
01867 overflow_(o0, o1) += w;
01868 ++overCount_;
01869 }
01870 ++fillCount_; ++modCount_;
01871 }
01872
01873 template <typename Numeric, class Axis>
01874 const Numeric& HistoND<Numeric,Axis>::examine(const double x0,
01875 const double x1) const
01876 {
01877 if (dim_ != 2U) Private::h_badargs("examine");
01878 unsigned i0, i1;
01879 const Axis* ax = &axes_[0];
01880 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
01881 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
01882 if (o0 == 1U && o1 == 1U)
01883 return data_(i0, i1);
01884 else
01885 return overflow_(o0, o1);
01886 }
01887
01888 template <typename Numeric, class Axis>
01889 const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0,
01890 const double x1) const
01891 {
01892 if (dim_ != 2U) Private::h_badargs("closestBin");
01893 const Axis* ax = &axes_[0];
01894 const unsigned i0 = ax[0].closestValidBin(x0);
01895 const unsigned i1 = ax[1].closestValidBin(x1);
01896 return data_(i0, i1);
01897 }
01898
01899 template <typename Numeric, class Axis>
01900 template <typename Num2>
01901 void HistoND<Numeric,Axis>::fill(const double x0, const double x1,
01902 const double x2, const Num2& w)
01903 {
01904 if (dim_ != 3U) Private::h_badargs("fill");
01905 unsigned i0, i1, i2;
01906 const Axis* ax = &axes_[0];
01907 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
01908 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
01909 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
01910 if (o0 == 1U && o1 == 1U && o2 == 1U)
01911 data_(i0, i1, i2) += w;
01912 else
01913 {
01914 overflow_(o0, o1, o2) += w;
01915 ++overCount_;
01916 }
01917 ++fillCount_; ++modCount_;
01918 }
01919
01920 template <typename Numeric, class Axis>
01921 template <typename Num2, class Functor>
01922 void HistoND<Numeric,Axis>::dispatch(const double x0, const double x1,
01923 const double x2, Num2& w, Functor& f)
01924 {
01925 if (dim_ != 3U) Private::h_badargs("dispatch");
01926 unsigned i0, i1, i2;
01927 const Axis* ax = &axes_[0];
01928 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
01929 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
01930 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
01931 if (o0 == 1U && o1 == 1U && o2 == 1U)
01932 f(data_(i0, i1, i2), w);
01933 else
01934 f(overflow_(o0, o1, o2), w);
01935 ++modCount_;
01936 }
01937
01938 template <typename Numeric, class Axis>
01939 template <typename Num2>
01940 void HistoND<Numeric,Axis>::fillC(const double x0, const double x1,
01941 const double x2, const Num2& w)
01942 {
01943 if (dim_ != 3U) Private::h_badargs("fillC");
01944 double* wg = &weightBuf_[0];
01945 unsigned* idx = &indexBuf_[0];
01946 const Axis* ax = &axes_[0];
01947 const unsigned o0 = ax[0].overflowIndexWeighted(x0, idx+0, wg+0);
01948 const unsigned o1 = ax[1].overflowIndexWeighted(x1, idx+1, wg+1);
01949 const unsigned o2 = ax[2].overflowIndexWeighted(x2, idx+2, wg+2);
01950 if (o0 == 1U && o1 == 1U && o2 == 1U)
01951 fillPreservingCentroid(w);
01952 else
01953 {
01954 overflow_(o0, o1, o2) += w;
01955 ++overCount_;
01956 }
01957 ++fillCount_; ++modCount_;
01958 }
01959
01960 template <typename Numeric, class Axis>
01961 const Numeric& HistoND<Numeric,Axis>::examine(const double x0,
01962 const double x1,
01963 const double x2) const
01964 {
01965 if (dim_ != 3U) Private::h_badargs("examine");
01966 unsigned i0, i1, i2;
01967 const Axis* ax = &axes_[0];
01968 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
01969 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
01970 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
01971 if (o0 == 1U && o1 == 1U && o2 == 1U)
01972 return data_(i0, i1, i2);
01973 else
01974 return overflow_(o0, o1, o2);
01975 }
01976
01977 template <typename Numeric, class Axis>
01978 const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0,
01979 const double x1,
01980 const double x2) const
01981 {
01982 if (dim_ != 3U) Private::h_badargs("closestBin");
01983 const Axis* ax = &axes_[0];
01984 const unsigned i0 = ax[0].closestValidBin(x0);
01985 const unsigned i1 = ax[1].closestValidBin(x1);
01986 const unsigned i2 = ax[2].closestValidBin(x2);
01987 return data_(i0, i1, i2);
01988 }
01989
01990 template <typename Numeric, class Axis>
01991 template <typename Num2>
01992 void HistoND<Numeric,Axis>::fill(const double x0, const double x1,
01993 const double x2, const double x3,
01994 const Num2& w)
01995 {
01996 if (dim_ != 4U) Private::h_badargs("fill");
01997 unsigned i0, i1, i2, i3;
01998 const Axis* ax = &axes_[0];
01999 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02000 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02001 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02002 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02003 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U)
02004 data_(i0, i1, i2, i3) += w;
02005 else
02006 {
02007 overflow_(o0, o1, o2, o3) += w;
02008 ++overCount_;
02009 }
02010 ++fillCount_; ++modCount_;
02011 }
02012
02013 template <typename Numeric, class Axis>
02014 template <typename Num2, class Functor>
02015 void HistoND<Numeric,Axis>::dispatch(const double x0, const double x1,
02016 const double x2, const double x3,
02017 Num2& w, Functor& f)
02018 {
02019 if (dim_ != 4U) Private::h_badargs("dispatch");
02020 unsigned i0, i1, i2, i3;
02021 const Axis* ax = &axes_[0];
02022 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02023 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02024 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02025 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02026 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U)
02027 f(data_(i0, i1, i2, i3), w);
02028 else
02029 f(overflow_(o0, o1, o2, o3), w);
02030 ++modCount_;
02031 }
02032
02033 template <typename Numeric, class Axis>
02034 template <typename Num2>
02035 void HistoND<Numeric,Axis>::fillC(const double x0, const double x1,
02036 const double x2, const double x3,
02037 const Num2& w)
02038 {
02039 if (dim_ != 4U) Private::h_badargs("fillC");
02040 double* wg = &weightBuf_[0];
02041 unsigned* idx = &indexBuf_[0];
02042 const Axis* ax = &axes_[0];
02043 const unsigned o0 = ax[0].overflowIndexWeighted(x0, idx+0, wg+0);
02044 const unsigned o1 = ax[1].overflowIndexWeighted(x1, idx+1, wg+1);
02045 const unsigned o2 = ax[2].overflowIndexWeighted(x2, idx+2, wg+2);
02046 const unsigned o3 = ax[3].overflowIndexWeighted(x3, idx+3, wg+3);
02047 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U)
02048 fillPreservingCentroid(w);
02049 else
02050 {
02051 overflow_(o0, o1, o2, o3) += w;
02052 ++overCount_;
02053 }
02054 ++fillCount_; ++modCount_;
02055 }
02056
02057 template <typename Numeric, class Axis>
02058 const Numeric& HistoND<Numeric,Axis>::examine(const double x0,
02059 const double x1,
02060 const double x2,
02061 const double x3) const
02062 {
02063 if (dim_ != 4U) Private::h_badargs("examine");
02064 unsigned i0, i1, i2, i3;
02065 const Axis* ax = &axes_[0];
02066 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02067 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02068 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02069 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02070 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U)
02071 return data_(i0, i1, i2, i3);
02072 else
02073 return overflow_(o0, o1, o2, o3);
02074 }
02075
02076 template <typename Numeric, class Axis>
02077 const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0,
02078 const double x1,
02079 const double x2,
02080 const double x3) const
02081 {
02082 if (dim_ != 4U) Private::h_badargs("closestBin");
02083 const Axis* ax = &axes_[0];
02084 const unsigned i0 = ax[0].closestValidBin(x0);
02085 const unsigned i1 = ax[1].closestValidBin(x1);
02086 const unsigned i2 = ax[2].closestValidBin(x2);
02087 const unsigned i3 = ax[3].closestValidBin(x3);
02088 return data_(i0, i1, i2, i3);
02089 }
02090
02091 template <typename Numeric, class Axis>
02092 template <typename Num2>
02093 void HistoND<Numeric,Axis>::fill(const double x0, const double x1,
02094 const double x2, const double x3,
02095 const double x4, const Num2& w)
02096 {
02097 if (dim_ != 5U) Private::h_badargs("fill");
02098 unsigned i0, i1, i2, i3, i4;
02099 const Axis* ax = &axes_[0];
02100 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02101 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02102 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02103 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02104 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02105 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U)
02106 data_(i0, i1, i2, i3, i4) += w;
02107 else
02108 {
02109 overflow_(o0, o1, o2, o3, o4) += w;
02110 ++overCount_;
02111 }
02112 ++fillCount_; ++modCount_;
02113 }
02114
02115 template <typename Numeric, class Axis>
02116 template <typename Num2, class Functor>
02117 void HistoND<Numeric,Axis>::dispatch(const double x0, const double x1,
02118 const double x2, const double x3,
02119 const double x4, Num2& w, Functor& f)
02120 {
02121 if (dim_ != 5U) Private::h_badargs("dispatch");
02122 unsigned i0, i1, i2, i3, i4;
02123 const Axis* ax = &axes_[0];
02124 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02125 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02126 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02127 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02128 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02129 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U)
02130 f(data_(i0, i1, i2, i3, i4), w);
02131 else
02132 f(overflow_(o0, o1, o2, o3, o4), w);
02133 ++modCount_;
02134 }
02135
02136 template <typename Numeric, class Axis>
02137 template <typename Num2>
02138 void HistoND<Numeric,Axis>::fillC(const double x0, const double x1,
02139 const double x2, const double x3,
02140 const double x4, const Num2& w)
02141 {
02142 if (dim_ != 5U) Private::h_badargs("fillC");
02143 double* wg = &weightBuf_[0];
02144 unsigned* idx = &indexBuf_[0];
02145 const Axis* ax = &axes_[0];
02146 const unsigned o0 = ax[0].overflowIndexWeighted(x0, idx+0, wg+0);
02147 const unsigned o1 = ax[1].overflowIndexWeighted(x1, idx+1, wg+1);
02148 const unsigned o2 = ax[2].overflowIndexWeighted(x2, idx+2, wg+2);
02149 const unsigned o3 = ax[3].overflowIndexWeighted(x3, idx+3, wg+3);
02150 const unsigned o4 = ax[4].overflowIndexWeighted(x4, idx+4, wg+4);
02151 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U)
02152 fillPreservingCentroid(w);
02153 else
02154 {
02155 overflow_(o0, o1, o2, o3, o4) += w;
02156 ++overCount_;
02157 }
02158 ++fillCount_; ++modCount_;
02159 }
02160
02161 template <typename Numeric, class Axis>
02162 const Numeric& HistoND<Numeric,Axis>::examine(
02163 const double x0, const double x1,
02164 const double x2, const double x3,
02165 const double x4) const
02166 {
02167 if (dim_ != 5U) Private::h_badargs("examine");
02168 unsigned i0, i1, i2, i3, i4;
02169 const Axis* ax = &axes_[0];
02170 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02171 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02172 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02173 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02174 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02175 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U)
02176 return data_(i0, i1, i2, i3, i4);
02177 else
02178 return overflow_(o0, o1, o2, o3, o4);
02179 }
02180
02181 template <typename Numeric, class Axis>
02182 const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0,
02183 const double x1,
02184 const double x2,
02185 const double x3,
02186 const double x4) const
02187 {
02188 if (dim_ != 5U) Private::h_badargs("closestBin");
02189 const Axis* ax = &axes_[0];
02190 const unsigned i0 = ax[0].closestValidBin(x0);
02191 const unsigned i1 = ax[1].closestValidBin(x1);
02192 const unsigned i2 = ax[2].closestValidBin(x2);
02193 const unsigned i3 = ax[3].closestValidBin(x3);
02194 const unsigned i4 = ax[4].closestValidBin(x4);
02195 return data_(i0, i1, i2, i3, i4);
02196 }
02197
02198 template <typename Numeric, class Axis>
02199 template <typename Num2>
02200 void HistoND<Numeric,Axis>::fill(const double x0, const double x1,
02201 const double x2, const double x3,
02202 const double x4, const double x5,
02203 const Num2& w)
02204 {
02205 if (dim_ != 6U) Private::h_badargs("fill");
02206 unsigned i0, i1, i2, i3, i4, i5;
02207 const Axis* ax = &axes_[0];
02208 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02209 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02210 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02211 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02212 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02213 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02214 if (o0 == 1U && o1 == 1U && o2 == 1U &&
02215 o3 == 1U && o4 == 1U && o5 == 1U)
02216 data_(i0, i1, i2, i3, i4, i5) += w;
02217 else
02218 {
02219 overflow_(o0, o1, o2, o3, o4, o5) += w;
02220 ++overCount_;
02221 }
02222 ++fillCount_; ++modCount_;
02223 }
02224
02225 template <typename Numeric, class Axis>
02226 template <typename Num2, class Functor>
02227 void HistoND<Numeric,Axis>::dispatch(const double x0, const double x1,
02228 const double x2, const double x3,
02229 const double x4, const double x5,
02230 Num2& w, Functor& f)
02231 {
02232 if (dim_ != 6U) Private::h_badargs("dispatch");
02233 unsigned i0, i1, i2, i3, i4, i5;
02234 const Axis* ax = &axes_[0];
02235 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02236 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02237 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02238 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02239 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02240 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02241 if (o0 == 1U && o1 == 1U && o2 == 1U &&
02242 o3 == 1U && o4 == 1U && o5 == 1U)
02243 f(data_(i0, i1, i2, i3, i4, i5), w);
02244 else
02245 f(overflow_(o0, o1, o2, o3, o4, o5), w);
02246 ++modCount_;
02247 }
02248
02249 template <typename Numeric, class Axis>
02250 template <typename Num2>
02251 void HistoND<Numeric,Axis>::fillC(const double x0, const double x1,
02252 const double x2, const double x3,
02253 const double x4, const double x5,
02254 const Num2& w)
02255 {
02256 if (dim_ != 6U) Private::h_badargs("fillC");
02257 double* wg = &weightBuf_[0];
02258 unsigned* idx = &indexBuf_[0];
02259 const Axis* ax = &axes_[0];
02260 const unsigned o0 = ax[0].overflowIndexWeighted(x0, idx+0, wg+0);
02261 const unsigned o1 = ax[1].overflowIndexWeighted(x1, idx+1, wg+1);
02262 const unsigned o2 = ax[2].overflowIndexWeighted(x2, idx+2, wg+2);
02263 const unsigned o3 = ax[3].overflowIndexWeighted(x3, idx+3, wg+3);
02264 const unsigned o4 = ax[4].overflowIndexWeighted(x4, idx+4, wg+4);
02265 const unsigned o5 = ax[5].overflowIndexWeighted(x5, idx+5, wg+5);
02266 if (o0 == 1U && o1 == 1U && o2 == 1U &&
02267 o3 == 1U && o4 == 1U && o5 == 1U)
02268 fillPreservingCentroid(w);
02269 else
02270 {
02271 overflow_(o0, o1, o2, o3, o4, o5) += w;
02272 ++overCount_;
02273 }
02274 ++fillCount_; ++modCount_;
02275 }
02276
02277 template <typename Numeric, class Axis>
02278 const Numeric& HistoND<Numeric,Axis>::examine(const double x0,
02279 const double x1,
02280 const double x2,
02281 const double x3,
02282 const double x4,
02283 const double x5) const
02284 {
02285 if (dim_ != 6U) Private::h_badargs("examine");
02286 unsigned i0, i1, i2, i3, i4, i5;
02287 const Axis* ax = &axes_[0];
02288 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02289 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02290 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02291 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02292 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02293 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02294 if (o0 == 1U && o1 == 1U && o2 == 1U &&
02295 o3 == 1U && o4 == 1U && o5 == 1U)
02296 return data_(i0, i1, i2, i3, i4, i5);
02297 else
02298 return overflow_(o0, o1, o2, o3, o4, o5);
02299 }
02300
02301 template <typename Numeric, class Axis>
02302 const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0,
02303 const double x1,
02304 const double x2,
02305 const double x3,
02306 const double x4,
02307 const double x5) const
02308 {
02309 if (dim_ != 6U) Private::h_badargs("closestBin");
02310 const Axis* ax = &axes_[0];
02311 const unsigned i0 = ax[0].closestValidBin(x0);
02312 const unsigned i1 = ax[1].closestValidBin(x1);
02313 const unsigned i2 = ax[2].closestValidBin(x2);
02314 const unsigned i3 = ax[3].closestValidBin(x3);
02315 const unsigned i4 = ax[4].closestValidBin(x4);
02316 const unsigned i5 = ax[5].closestValidBin(x5);
02317 return data_(i0, i1, i2, i3, i4, i5);
02318 }
02319
02320 template <typename Numeric, class Axis>
02321 template <typename Num2>
02322 void HistoND<Numeric,Axis>::fill(const double x0, const double x1,
02323 const double x2, const double x3,
02324 const double x4, const double x5,
02325 const double x6, const Num2& w)
02326 {
02327 if (dim_ != 7U) Private::h_badargs("fill");
02328 unsigned i0, i1, i2, i3, i4, i5, i6;
02329 const Axis* ax = &axes_[0];
02330 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02331 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02332 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02333 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02334 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02335 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02336 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02337 if (o0 == 1U && o1 == 1U && o2 == 1U &&
02338 o3 == 1U && o4 == 1U && o5 == 1U && o6 == 1U)
02339 data_(i0, i1, i2, i3, i4, i5, i6) += w;
02340 else
02341 {
02342 overflow_(o0, o1, o2, o3, o4, o5, o6) += w;
02343 ++overCount_;
02344 }
02345 ++fillCount_; ++modCount_;
02346 }
02347
02348 template <typename Numeric, class Axis>
02349 template <typename Num2, class Functor>
02350 void HistoND<Numeric,Axis>::dispatch(const double x0, const double x1,
02351 const double x2, const double x3,
02352 const double x4, const double x5,
02353 const double x6, Num2& w, Functor& f)
02354 {
02355 if (dim_ != 7U) Private::h_badargs("dispatch");
02356 unsigned i0, i1, i2, i3, i4, i5, i6;
02357 const Axis* ax = &axes_[0];
02358 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02359 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02360 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02361 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02362 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02363 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02364 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02365 if (o0 == 1U && o1 == 1U && o2 == 1U &&
02366 o3 == 1U && o4 == 1U && o5 == 1U && o6 == 1U)
02367 f(data_(i0, i1, i2, i3, i4, i5, i6), w);
02368 else
02369 f(overflow_(o0, o1, o2, o3, o4, o5, o6), w);
02370 ++modCount_;
02371 }
02372
02373 template <typename Numeric, class Axis>
02374 template <typename Num2>
02375 void HistoND<Numeric,Axis>::fillC(const double x0, const double x1,
02376 const double x2, const double x3,
02377 const double x4, const double x5,
02378 const double x6, const Num2& w)
02379 {
02380 if (dim_ != 7U) Private::h_badargs("fillC");
02381 double* wg = &weightBuf_[0];
02382 unsigned* idx = &indexBuf_[0];
02383 const Axis* ax = &axes_[0];
02384 const unsigned o0 = ax[0].overflowIndexWeighted(x0, idx+0, wg+0);
02385 const unsigned o1 = ax[1].overflowIndexWeighted(x1, idx+1, wg+1);
02386 const unsigned o2 = ax[2].overflowIndexWeighted(x2, idx+2, wg+2);
02387 const unsigned o3 = ax[3].overflowIndexWeighted(x3, idx+3, wg+3);
02388 const unsigned o4 = ax[4].overflowIndexWeighted(x4, idx+4, wg+4);
02389 const unsigned o5 = ax[5].overflowIndexWeighted(x5, idx+5, wg+5);
02390 const unsigned o6 = ax[6].overflowIndexWeighted(x6, idx+6, wg+6);
02391 if (o0 == 1U && o1 == 1U && o2 == 1U &&
02392 o3 == 1U && o4 == 1U && o5 == 1U && o6 == 1U)
02393 fillPreservingCentroid(w);
02394 else
02395 {
02396 overflow_(o0, o1, o2, o3, o4, o5, o6) += w;
02397 ++overCount_;
02398 }
02399 ++fillCount_; ++modCount_;
02400 }
02401
02402 template <typename Numeric, class Axis>
02403 const Numeric& HistoND<Numeric,Axis>::examine(
02404 const double x0, const double x1,
02405 const double x2, const double x3,
02406 const double x4, const double x5,
02407 const double x6) const
02408 {
02409 if (dim_ != 7U) Private::h_badargs("examine");
02410 unsigned i0, i1, i2, i3, i4, i5, i6;
02411 const Axis* ax = &axes_[0];
02412 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02413 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02414 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02415 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02416 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02417 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02418 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02419 if (o0 == 1U && o1 == 1U && o2 == 1U &&
02420 o3 == 1U && o4 == 1U && o5 == 1U && o6 == 1U)
02421 return data_(i0, i1, i2, i3, i4, i5, i6);
02422 else
02423 return overflow_(o0, o1, o2, o3, o4, o5, o6);
02424 }
02425
02426 template <typename Numeric, class Axis>
02427 const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0,
02428 const double x1,
02429 const double x2,
02430 const double x3,
02431 const double x4,
02432 const double x5,
02433 const double x6) const
02434 {
02435 if (dim_ != 7U) Private::h_badargs("closestBin");
02436 const Axis* ax = &axes_[0];
02437 const unsigned i0 = ax[0].closestValidBin(x0);
02438 const unsigned i1 = ax[1].closestValidBin(x1);
02439 const unsigned i2 = ax[2].closestValidBin(x2);
02440 const unsigned i3 = ax[3].closestValidBin(x3);
02441 const unsigned i4 = ax[4].closestValidBin(x4);
02442 const unsigned i5 = ax[5].closestValidBin(x5);
02443 const unsigned i6 = ax[6].closestValidBin(x6);
02444 return data_(i0, i1, i2, i3, i4, i5, i6);
02445 }
02446
02447 template <typename Numeric, class Axis>
02448 template <typename Num2>
02449 void HistoND<Numeric,Axis>::fill(const double x0, const double x1,
02450 const double x2, const double x3,
02451 const double x4, const double x5,
02452 const double x6, const double x7,
02453 const Num2& w)
02454 {
02455 if (dim_ != 8U) Private::h_badargs("fill");
02456 unsigned i0, i1, i2, i3, i4, i5, i6, i7;
02457 const Axis* ax = &axes_[0];
02458 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02459 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02460 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02461 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02462 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02463 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02464 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02465 const unsigned o7 = ax[7].overflowIndex(x7, &i7);
02466 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U &&
02467 o4 == 1U && o5 == 1U && o6 == 1U && o7 == 1U)
02468 data_(i0, i1, i2, i3, i4, i5, i6, i7) += w;
02469 else
02470 {
02471 overflow_(o0, o1, o2, o3, o4, o5, o6, o7) += w;
02472 ++overCount_;
02473 }
02474 ++fillCount_; ++modCount_;
02475 }
02476
02477 template <typename Numeric, class Axis>
02478 template <typename Num2, class Functor>
02479 void HistoND<Numeric,Axis>::dispatch(const double x0, const double x1,
02480 const double x2, const double x3,
02481 const double x4, const double x5,
02482 const double x6, const double x7,
02483 Num2& w, Functor& f)
02484 {
02485 if (dim_ != 8U) Private::h_badargs("dispatch");
02486 unsigned i0, i1, i2, i3, i4, i5, i6, i7;
02487 const Axis* ax = &axes_[0];
02488 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02489 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02490 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02491 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02492 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02493 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02494 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02495 const unsigned o7 = ax[7].overflowIndex(x7, &i7);
02496 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U &&
02497 o4 == 1U && o5 == 1U && o6 == 1U && o7 == 1U)
02498 f(data_(i0, i1, i2, i3, i4, i5, i6, i7), w);
02499 else
02500 f(overflow_(o0, o1, o2, o3, o4, o5, o6, o7), w);
02501 ++modCount_;
02502 }
02503
02504 template <typename Numeric, class Axis>
02505 template <typename Num2>
02506 void HistoND<Numeric,Axis>::fillC(const double x0, const double x1,
02507 const double x2, const double x3,
02508 const double x4, const double x5,
02509 const double x6, const double x7,
02510 const Num2& w)
02511 {
02512 if (dim_ != 8U) Private::h_badargs("fillC");
02513 double* wg = &weightBuf_[0];
02514 unsigned* idx = &indexBuf_[0];
02515 const Axis* ax = &axes_[0];
02516 const unsigned o0 = ax[0].overflowIndexWeighted(x0, idx+0, wg+0);
02517 const unsigned o1 = ax[1].overflowIndexWeighted(x1, idx+1, wg+1);
02518 const unsigned o2 = ax[2].overflowIndexWeighted(x2, idx+2, wg+2);
02519 const unsigned o3 = ax[3].overflowIndexWeighted(x3, idx+3, wg+3);
02520 const unsigned o4 = ax[4].overflowIndexWeighted(x4, idx+4, wg+4);
02521 const unsigned o5 = ax[5].overflowIndexWeighted(x5, idx+5, wg+5);
02522 const unsigned o6 = ax[6].overflowIndexWeighted(x6, idx+6, wg+6);
02523 const unsigned o7 = ax[7].overflowIndexWeighted(x7, idx+7, wg+7);
02524 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U &&
02525 o4 == 1U && o5 == 1U && o6 == 1U && o7 == 1U)
02526 fillPreservingCentroid(w);
02527 else
02528 {
02529 overflow_(o0, o1, o2, o3, o4, o5, o6, o7) += w;
02530 ++overCount_;
02531 }
02532 ++fillCount_; ++modCount_;
02533 }
02534
02535 template <typename Numeric, class Axis>
02536 const Numeric& HistoND<Numeric,Axis>::examine(
02537 const double x0, const double x1,
02538 const double x2, const double x3,
02539 const double x4, const double x5,
02540 const double x6,
02541 const double x7) const
02542 {
02543 if (dim_ != 8U) Private::h_badargs("examine");
02544 unsigned i0, i1, i2, i3, i4, i5, i6, i7;
02545 const Axis* ax = &axes_[0];
02546 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02547 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02548 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02549 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02550 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02551 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02552 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02553 const unsigned o7 = ax[7].overflowIndex(x7, &i7);
02554 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U &&
02555 o4 == 1U && o5 == 1U && o6 == 1U && o7 == 1U)
02556 return data_(i0, i1, i2, i3, i4, i5, i6, i7);
02557 else
02558 return overflow_(o0, o1, o2, o3, o4, o5, o6, o7);
02559 }
02560
02561 template <typename Numeric, class Axis>
02562 const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0,
02563 const double x1,
02564 const double x2,
02565 const double x3,
02566 const double x4,
02567 const double x5,
02568 const double x6,
02569 const double x7) const
02570 {
02571 if (dim_ != 8U) Private::h_badargs("closestBin");
02572 const Axis* ax = &axes_[0];
02573 const unsigned i0 = ax[0].closestValidBin(x0);
02574 const unsigned i1 = ax[1].closestValidBin(x1);
02575 const unsigned i2 = ax[2].closestValidBin(x2);
02576 const unsigned i3 = ax[3].closestValidBin(x3);
02577 const unsigned i4 = ax[4].closestValidBin(x4);
02578 const unsigned i5 = ax[5].closestValidBin(x5);
02579 const unsigned i6 = ax[6].closestValidBin(x6);
02580 const unsigned i7 = ax[7].closestValidBin(x7);
02581 return data_(i0, i1, i2, i3, i4, i5, i6, i7);
02582 }
02583
02584 template <typename Numeric, class Axis>
02585 template <typename Num2>
02586 void HistoND<Numeric,Axis>::fill(const double x0, const double x1,
02587 const double x2, const double x3,
02588 const double x4, const double x5,
02589 const double x6, const double x7,
02590 const double x8, const Num2& w)
02591 {
02592 if (dim_ != 9U) Private::h_badargs("fill");
02593 unsigned i0, i1, i2, i3, i4, i5, i6, i7, i8;
02594 const Axis* ax = &axes_[0];
02595 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02596 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02597 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02598 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02599 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02600 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02601 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02602 const unsigned o7 = ax[7].overflowIndex(x7, &i7);
02603 const unsigned o8 = ax[8].overflowIndex(x8, &i8);
02604 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U &&
02605 o5 == 1U && o6 == 1U && o7 == 1U && o8 == 1U)
02606 data_(i0, i1, i2, i3, i4, i5, i6, i7, i8) += w;
02607 else
02608 {
02609 overflow_(o0, o1, o2, o3, o4, o5, o6, o7, o8) += w;
02610 ++overCount_;
02611 }
02612 ++fillCount_; ++modCount_;
02613 }
02614
02615 template <typename Numeric, class Axis>
02616 template <typename Num2, class Functor>
02617 void HistoND<Numeric,Axis>::dispatch(const double x0, const double x1,
02618 const double x2, const double x3,
02619 const double x4, const double x5,
02620 const double x6, const double x7,
02621 const double x8, Num2& w, Functor& f)
02622 {
02623 if (dim_ != 9U) Private::h_badargs("dispatch");
02624 unsigned i0, i1, i2, i3, i4, i5, i6, i7, i8;
02625 const Axis* ax = &axes_[0];
02626 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02627 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02628 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02629 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02630 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02631 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02632 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02633 const unsigned o7 = ax[7].overflowIndex(x7, &i7);
02634 const unsigned o8 = ax[8].overflowIndex(x8, &i8);
02635 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U &&
02636 o5 == 1U && o6 == 1U && o7 == 1U && o8 == 1U)
02637 f(data_(i0, i1, i2, i3, i4, i5, i6, i7, i8), w);
02638 else
02639 f(overflow_(o0, o1, o2, o3, o4, o5, o6, o7, o8), w);
02640 ++modCount_;
02641 }
02642
02643 template <typename Numeric, class Axis>
02644 template <typename Num2>
02645 void HistoND<Numeric,Axis>::fillC(const double x0, const double x1,
02646 const double x2, const double x3,
02647 const double x4, const double x5,
02648 const double x6, const double x7,
02649 const double x8, const Num2& w)
02650 {
02651 if (dim_ != 9U) Private::h_badargs("fillC");
02652 double* wg = &weightBuf_[0];
02653 unsigned* idx = &indexBuf_[0];
02654 const Axis* ax = &axes_[0];
02655 const unsigned o0 = ax[0].overflowIndexWeighted(x0, idx+0, wg+0);
02656 const unsigned o1 = ax[1].overflowIndexWeighted(x1, idx+1, wg+1);
02657 const unsigned o2 = ax[2].overflowIndexWeighted(x2, idx+2, wg+2);
02658 const unsigned o3 = ax[3].overflowIndexWeighted(x3, idx+3, wg+3);
02659 const unsigned o4 = ax[4].overflowIndexWeighted(x4, idx+4, wg+4);
02660 const unsigned o5 = ax[5].overflowIndexWeighted(x5, idx+5, wg+5);
02661 const unsigned o6 = ax[6].overflowIndexWeighted(x6, idx+6, wg+6);
02662 const unsigned o7 = ax[7].overflowIndexWeighted(x7, idx+7, wg+7);
02663 const unsigned o8 = ax[8].overflowIndexWeighted(x8, idx+8, wg+8);
02664 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U &&
02665 o5 == 1U && o6 == 1U && o7 == 1U && o8 == 1U)
02666 fillPreservingCentroid(w);
02667 else
02668 {
02669 overflow_(o0, o1, o2, o3, o4, o5, o6, o7, o8) += w;
02670 ++overCount_;
02671 }
02672 ++fillCount_; ++modCount_;
02673 }
02674
02675 template <typename Numeric, class Axis>
02676 const Numeric& HistoND<Numeric,Axis>::examine(
02677 const double x0, const double x1,
02678 const double x2, const double x3,
02679 const double x4, const double x5,
02680 const double x6, const double x7,
02681 const double x8) const
02682 {
02683 if (dim_ != 9U) Private::h_badargs("examine");
02684 unsigned i0, i1, i2, i3, i4, i5, i6, i7, i8;
02685 const Axis* ax = &axes_[0];
02686 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02687 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02688 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02689 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02690 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02691 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02692 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02693 const unsigned o7 = ax[7].overflowIndex(x7, &i7);
02694 const unsigned o8 = ax[8].overflowIndex(x8, &i8);
02695 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U &&
02696 o5 == 1U && o6 == 1U && o7 == 1U && o8 == 1U)
02697 return data_(i0, i1, i2, i3, i4, i5, i6, i7, i8);
02698 else
02699 return overflow_(o0, o1, o2, o3, o4, o5, o6, o7, o8);
02700 }
02701
02702 template <typename Numeric, class Axis>
02703 const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0,
02704 const double x1,
02705 const double x2,
02706 const double x3,
02707 const double x4,
02708 const double x5,
02709 const double x6,
02710 const double x7,
02711 const double x8) const
02712 {
02713 if (dim_ != 9U) Private::h_badargs("closestBin");
02714 const Axis* ax = &axes_[0];
02715 const unsigned i0 = ax[0].closestValidBin(x0);
02716 const unsigned i1 = ax[1].closestValidBin(x1);
02717 const unsigned i2 = ax[2].closestValidBin(x2);
02718 const unsigned i3 = ax[3].closestValidBin(x3);
02719 const unsigned i4 = ax[4].closestValidBin(x4);
02720 const unsigned i5 = ax[5].closestValidBin(x5);
02721 const unsigned i6 = ax[6].closestValidBin(x6);
02722 const unsigned i7 = ax[7].closestValidBin(x7);
02723 const unsigned i8 = ax[8].closestValidBin(x8);
02724 return data_(i0, i1, i2, i3, i4, i5, i6, i7, i8);
02725 }
02726
02727 template <typename Numeric, class Axis>
02728 template <typename Num2>
02729 void HistoND<Numeric,Axis>::fill(const double x0, const double x1,
02730 const double x2, const double x3,
02731 const double x4, const double x5,
02732 const double x6, const double x7,
02733 const double x8, const double x9,
02734 const Num2& w)
02735 {
02736 if (dim_ != 10U) Private::h_badargs("fill");
02737 unsigned i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
02738 const Axis* ax = &axes_[0];
02739 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02740 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02741 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02742 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02743 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02744 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02745 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02746 const unsigned o7 = ax[7].overflowIndex(x7, &i7);
02747 const unsigned o8 = ax[8].overflowIndex(x8, &i8);
02748 const unsigned o9 = ax[9].overflowIndex(x9, &i9);
02749 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U &&
02750 o5 == 1U && o6 == 1U && o7 == 1U && o8 == 1U && o9 == 1U)
02751 data_(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) += w;
02752 else
02753 {
02754 overflow_(o0, o1, o2, o3, o4, o5, o6, o7, o8, o9) += w;
02755 ++overCount_;
02756 }
02757 ++fillCount_; ++modCount_;
02758 }
02759
02760 template <typename Numeric, class Axis>
02761 template <typename Num2, class Functor>
02762 void HistoND<Numeric,Axis>::dispatch(const double x0, const double x1,
02763 const double x2, const double x3,
02764 const double x4, const double x5,
02765 const double x6, const double x7,
02766 const double x8, const double x9,
02767 Num2& w, Functor& f)
02768 {
02769 if (dim_ != 10U) Private::h_badargs("dispatch");
02770 unsigned i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
02771 const Axis* ax = &axes_[0];
02772 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02773 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02774 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02775 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02776 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02777 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02778 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02779 const unsigned o7 = ax[7].overflowIndex(x7, &i7);
02780 const unsigned o8 = ax[8].overflowIndex(x8, &i8);
02781 const unsigned o9 = ax[9].overflowIndex(x9, &i9);
02782 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U &&
02783 o5 == 1U && o6 == 1U && o7 == 1U && o8 == 1U && o9 == 1U)
02784 f(data_(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9), w);
02785 else
02786 f(overflow_(o0, o1, o2, o3, o4, o5, o6, o7, o8, o9), w);
02787 ++modCount_;
02788 }
02789
02790 template <typename Numeric, class Axis>
02791 template <typename Num2>
02792 void HistoND<Numeric,Axis>::fillC(const double x0, const double x1,
02793 const double x2, const double x3,
02794 const double x4, const double x5,
02795 const double x6, const double x7,
02796 const double x8, const double x9,
02797 const Num2& w)
02798 {
02799 if (dim_ != 10U) Private::h_badargs("fillC");
02800 double* wg = &weightBuf_[0];
02801 unsigned* idx = &indexBuf_[0];
02802 const Axis* ax = &axes_[0];
02803 const unsigned o0 = ax[0].overflowIndexWeighted(x0, idx+0, wg+0);
02804 const unsigned o1 = ax[1].overflowIndexWeighted(x1, idx+1, wg+1);
02805 const unsigned o2 = ax[2].overflowIndexWeighted(x2, idx+2, wg+2);
02806 const unsigned o3 = ax[3].overflowIndexWeighted(x3, idx+3, wg+3);
02807 const unsigned o4 = ax[4].overflowIndexWeighted(x4, idx+4, wg+4);
02808 const unsigned o5 = ax[5].overflowIndexWeighted(x5, idx+5, wg+5);
02809 const unsigned o6 = ax[6].overflowIndexWeighted(x6, idx+6, wg+6);
02810 const unsigned o7 = ax[7].overflowIndexWeighted(x7, idx+7, wg+7);
02811 const unsigned o8 = ax[8].overflowIndexWeighted(x8, idx+8, wg+8);
02812 const unsigned o9 = ax[9].overflowIndexWeighted(x9, idx+9, wg+9);
02813 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U &&
02814 o5 == 1U && o6 == 1U && o7 == 1U && o8 == 1U && o9 == 1U)
02815 fillPreservingCentroid(w);
02816 else
02817 {
02818 overflow_(o0, o1, o2, o3, o4, o5, o6, o7, o8, o9) += w;
02819 ++overCount_;
02820 }
02821 ++fillCount_; ++modCount_;
02822 }
02823
02824 template <typename Numeric, class Axis>
02825 const Numeric& HistoND<Numeric,Axis>::examine(
02826 const double x0, const double x1,
02827 const double x2, const double x3,
02828 const double x4, const double x5,
02829 const double x6, const double x7,
02830 const double x8,
02831 const double x9) const
02832 {
02833 if (dim_ != 10U) Private::h_badargs("examine");
02834 unsigned i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
02835 const Axis* ax = &axes_[0];
02836 const unsigned o0 = ax[0].overflowIndex(x0, &i0);
02837 const unsigned o1 = ax[1].overflowIndex(x1, &i1);
02838 const unsigned o2 = ax[2].overflowIndex(x2, &i2);
02839 const unsigned o3 = ax[3].overflowIndex(x3, &i3);
02840 const unsigned o4 = ax[4].overflowIndex(x4, &i4);
02841 const unsigned o5 = ax[5].overflowIndex(x5, &i5);
02842 const unsigned o6 = ax[6].overflowIndex(x6, &i6);
02843 const unsigned o7 = ax[7].overflowIndex(x7, &i7);
02844 const unsigned o8 = ax[8].overflowIndex(x8, &i8);
02845 const unsigned o9 = ax[9].overflowIndex(x9, &i9);
02846 if (o0 == 1U && o1 == 1U && o2 == 1U && o3 == 1U && o4 == 1U &&
02847 o5 == 1U && o6 == 1U && o7 == 1U && o8 == 1U && o9 == 1U)
02848 return data_(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9);
02849 else
02850 return overflow_(o0, o1, o2, o3, o4, o5, o6, o7, o8, o9);
02851 }
02852
02853 template <typename Numeric, class Axis>
02854 const Numeric& HistoND<Numeric,Axis>::closestBin(const double x0,
02855 const double x1,
02856 const double x2,
02857 const double x3,
02858 const double x4,
02859 const double x5,
02860 const double x6,
02861 const double x7,
02862 const double x8,
02863 const double x9) const
02864 {
02865 if (dim_ != 10U) Private::h_badargs("closestBin");
02866 const Axis* ax = &axes_[0];
02867 const unsigned i0 = ax[0].closestValidBin(x0);
02868 const unsigned i1 = ax[1].closestValidBin(x1);
02869 const unsigned i2 = ax[2].closestValidBin(x2);
02870 const unsigned i3 = ax[3].closestValidBin(x3);
02871 const unsigned i4 = ax[4].closestValidBin(x4);
02872 const unsigned i5 = ax[5].closestValidBin(x5);
02873 const unsigned i6 = ax[6].closestValidBin(x6);
02874 const unsigned i7 = ax[7].closestValidBin(x7);
02875 const unsigned i8 = ax[8].closestValidBin(x8);
02876 const unsigned i9 = ax[9].closestValidBin(x9);
02877 return data_(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9);
02878 }
02879
02880 template <typename Numeric, class Axis>
02881 template <typename Num2>
02882 inline void HistoND<Numeric,Axis>::setBin(const unsigned *index,
02883 const unsigned indexLen,
02884 const Num2& v)
02885 {
02886 data_.value(index, indexLen) = v;
02887 ++modCount_;
02888 }
02889
02890 template <typename Numeric, class Axis>
02891 template <typename Num2>
02892 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned *index,
02893 const unsigned indexLen,
02894 const Num2& v)
02895 {
02896 data_.valueAt(index, indexLen) = v;
02897 ++modCount_;
02898 }
02899
02900 template <typename Numeric, class Axis>
02901 template <typename Num2>
02902 inline void HistoND<Numeric,Axis>::setBin(const Num2& v)
02903 {
02904 data_() = v;
02905 ++modCount_;
02906 }
02907
02908 template <typename Numeric, class Axis>
02909 template <typename Num2>
02910 inline void HistoND<Numeric,Axis>::setBinAt(const Num2& v)
02911 {
02912 data_.at() = v;
02913 ++modCount_;
02914 }
02915
02916 template <typename Numeric, class Axis>
02917 template <typename Num2>
02918 inline void HistoND<Numeric,Axis>::setBin(
02919 const unsigned i0, const Num2& v)
02920 {
02921 data_(i0) = v;
02922 ++modCount_;
02923 }
02924
02925 template <typename Numeric, class Axis>
02926 template <typename Num2>
02927 inline void HistoND<Numeric,Axis>::setBinAt(
02928 const unsigned i0, const Num2& v)
02929 {
02930 data_.at(i0) = v;
02931 ++modCount_;
02932 }
02933
02934 template <typename Numeric, class Axis>
02935 template <typename Num2>
02936 inline void HistoND<Numeric,Axis>::setBin(const unsigned i0,
02937 const unsigned i1,
02938 const Num2& v)
02939 {
02940 data_(i0, i1) = v;
02941 ++modCount_;
02942 }
02943
02944 template <typename Numeric, class Axis>
02945 template <typename Num2>
02946 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned i0,
02947 const unsigned i1,
02948 const Num2& v)
02949 {
02950 data_.at(i0, i1) = v;
02951 ++modCount_;
02952 }
02953
02954 template <typename Numeric, class Axis>
02955 template <typename Num2>
02956 inline void HistoND<Numeric,Axis>::setBin(const unsigned i0,
02957 const unsigned i1,
02958 const unsigned i2,
02959 const Num2& v)
02960 {
02961 data_(i0, i1, i2) = v;
02962 ++modCount_;
02963 }
02964
02965 template <typename Numeric, class Axis>
02966 template <typename Num2>
02967 inline void HistoND<Numeric,Axis>::setBin(const unsigned i0,
02968 const unsigned i1,
02969 const unsigned i2,
02970 const unsigned i3,
02971 const Num2& v)
02972 {
02973 data_(i0, i1, i2, i3) = v;
02974 ++modCount_;
02975 }
02976
02977 template <typename Numeric, class Axis>
02978 template <typename Num2>
02979 inline void HistoND<Numeric,Axis>::setBin(const unsigned i0,
02980 const unsigned i1,
02981 const unsigned i2,
02982 const unsigned i3,
02983 const unsigned i4,
02984 const Num2& v)
02985 {
02986 data_(i0, i1, i2, i3, i4) = v;
02987 ++modCount_;
02988 }
02989
02990 template <typename Numeric, class Axis>
02991 template <typename Num2>
02992 inline void HistoND<Numeric,Axis>::setBin(const unsigned i0,
02993 const unsigned i1,
02994 const unsigned i2,
02995 const unsigned i3,
02996 const unsigned i4,
02997 const unsigned i5,
02998 const Num2& v)
02999 {
03000 data_(i0, i1, i2, i3, i4, i5) = v;
03001 ++modCount_;
03002 }
03003
03004 template <typename Numeric, class Axis>
03005 template <typename Num2>
03006 inline void HistoND<Numeric,Axis>::setBin(const unsigned i0,
03007 const unsigned i1,
03008 const unsigned i2,
03009 const unsigned i3,
03010 const unsigned i4,
03011 const unsigned i5,
03012 const unsigned i6,
03013 const Num2& v)
03014 {
03015 data_(i0, i1, i2, i3, i4, i5, i6) = v;
03016 ++modCount_;
03017 }
03018
03019 template <typename Numeric, class Axis>
03020 template <typename Num2>
03021 inline void HistoND<Numeric,Axis>::setBin(const unsigned i0,
03022 const unsigned i1,
03023 const unsigned i2,
03024 const unsigned i3,
03025 const unsigned i4,
03026 const unsigned i5,
03027 const unsigned i6,
03028 const unsigned i7,
03029 const Num2& v)
03030 {
03031 data_(i0, i1, i2, i3, i4, i5, i6, i7) = v;
03032 ++modCount_;
03033 }
03034
03035 template <typename Numeric, class Axis>
03036 template <typename Num2>
03037 inline void HistoND<Numeric,Axis>::setBin(const unsigned i0,
03038 const unsigned i1,
03039 const unsigned i2,
03040 const unsigned i3,
03041 const unsigned i4,
03042 const unsigned i5,
03043 const unsigned i6,
03044 const unsigned i7,
03045 const unsigned i8,
03046 const Num2& v)
03047 {
03048 data_(i0, i1, i2, i3, i4, i5, i6, i7, i8) = v;
03049 ++modCount_;
03050 }
03051
03052 template <typename Numeric, class Axis>
03053 template <typename Num2>
03054 inline void HistoND<Numeric,Axis>::setBin(const unsigned i0,
03055 const unsigned i1,
03056 const unsigned i2,
03057 const unsigned i3,
03058 const unsigned i4,
03059 const unsigned i5,
03060 const unsigned i6,
03061 const unsigned i7,
03062 const unsigned i8,
03063 const unsigned i9,
03064 const Num2& v)
03065 {
03066 data_(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) = v;
03067 ++modCount_;
03068 }
03069
03070 template <typename Numeric, class Axis>
03071 template <typename Num2>
03072 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned i0,
03073 const unsigned i1,
03074 const unsigned i2,
03075 const Num2& v)
03076 {
03077 data_.at(i0, i1, i2) = v;
03078 ++modCount_;
03079 }
03080
03081 template <typename Numeric, class Axis>
03082 template <typename Num2>
03083 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned i0,
03084 const unsigned i1,
03085 const unsigned i2,
03086 const unsigned i3,
03087 const Num2& v)
03088 {
03089 data_.at(i0, i1, i2, i3) = v;
03090 ++modCount_;
03091 }
03092
03093 template <typename Numeric, class Axis>
03094 template <typename Num2>
03095 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned i0,
03096 const unsigned i1,
03097 const unsigned i2,
03098 const unsigned i3,
03099 const unsigned i4,
03100 const Num2& v)
03101 {
03102 data_.at(i0, i1, i2, i3, i4) = v;
03103 ++modCount_;
03104 }
03105
03106 template <typename Numeric, class Axis>
03107 template <typename Num2>
03108 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned i0,
03109 const unsigned i1,
03110 const unsigned i2,
03111 const unsigned i3,
03112 const unsigned i4,
03113 const unsigned i5,
03114 const Num2& v)
03115 {
03116 data_.at(i0, i1, i2, i3, i4, i5) = v;
03117 ++modCount_;
03118 }
03119
03120 template <typename Numeric, class Axis>
03121 template <typename Num2>
03122 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned i0,
03123 const unsigned i1,
03124 const unsigned i2,
03125 const unsigned i3,
03126 const unsigned i4,
03127 const unsigned i5,
03128 const unsigned i6,
03129 const Num2& v)
03130 {
03131 data_.at(i0, i1, i2, i3, i4, i5, i6) = v;
03132 ++modCount_;
03133 }
03134
03135 template <typename Numeric, class Axis>
03136 template <typename Num2>
03137 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned i0,
03138 const unsigned i1,
03139 const unsigned i2,
03140 const unsigned i3,
03141 const unsigned i4,
03142 const unsigned i5,
03143 const unsigned i6,
03144 const unsigned i7,
03145 const Num2& v)
03146 {
03147 data_.at(i0, i1, i2, i3, i4, i5, i6, i7) = v;
03148 ++modCount_;
03149 }
03150
03151 template <typename Numeric, class Axis>
03152 template <typename Num2>
03153 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned i0,
03154 const unsigned i1,
03155 const unsigned i2,
03156 const unsigned i3,
03157 const unsigned i4,
03158 const unsigned i5,
03159 const unsigned i6,
03160 const unsigned i7,
03161 const unsigned i8,
03162 const Num2& v)
03163 {
03164 data_.at(i0, i1, i2, i3, i4, i5, i6, i7, i8) = v;
03165 ++modCount_;
03166 }
03167
03168 template <typename Numeric, class Axis>
03169 template <typename Num2>
03170 inline void HistoND<Numeric,Axis>::setBinAt(const unsigned i0,
03171 const unsigned i1,
03172 const unsigned i2,
03173 const unsigned i3,
03174 const unsigned i4,
03175 const unsigned i5,
03176 const unsigned i6,
03177 const unsigned i7,
03178 const unsigned i8,
03179 const unsigned i9,
03180 const Num2& v)
03181 {
03182 data_.at(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) = v;
03183 ++modCount_;
03184 }
03185
03186 template <typename Numeric, class Axis>
03187 template <typename Num2>
03188 inline HistoND<Numeric,Axis>& HistoND<Numeric,Axis>::operator+=(
03189 const HistoND<Num2,Axis>& r)
03190 {
03191 data_ += r.data_;
03192 overflow_ += r.overflow_;
03193 fillCount_ += r.fillCount_;
03194 overCount_ += r.overCount_;
03195 ++modCount_;
03196 return *this;
03197 }
03198
03199 template <typename Numeric, class Axis>
03200 template <typename Num2>
03201 inline HistoND<Numeric,Axis>& HistoND<Numeric,Axis>::operator-=(
03202 const HistoND<Num2,Axis>& r)
03203 {
03204 data_ -= r.data_;
03205 overflow_ -= r.overflow_;
03206
03207
03208
03209
03210
03211
03212 fillCount_ += r.fillCount_;
03213 overCount_ += r.overCount_;
03214
03215 ++modCount_;
03216 return *this;
03217 }
03218
03219 template <typename Numeric, class Axis>
03220 template <typename Num2>
03221 inline HistoND<Numeric,Axis>&
03222 HistoND<Numeric,Axis>::operator*=(const Num2& r)
03223 {
03224 data_ *= r;
03225 overflow_ *= r;
03226 ++modCount_;
03227 return *this;
03228 }
03229
03230 template <typename Numeric, class Axis>
03231 template <typename Num2>
03232 inline HistoND<Numeric,Axis>&
03233 HistoND<Numeric,Axis>::operator/=(const Num2& r)
03234 {
03235 data_ /= r;
03236 overflow_ /= r;
03237 ++modCount_;
03238 return *this;
03239 }
03240
03241 template <typename Numeric, class Axis>
03242 HistoND<Numeric,Axis>::HistoND(const HistoND& r,
03243 const unsigned ax1,
03244 const unsigned ax2)
03245 : title_(r.title_),
03246 accumulatedDataLabel_(r.accumulatedDataLabel_),
03247 data_(r.data_.transpose(ax1, ax2)),
03248 overflow_(r.overflow_.transpose(ax1, ax2)),
03249 axes_(r.axes_),
03250 weightBuf_(r.weightBuf_),
03251 indexBuf_(r.indexBuf_),
03252 fillCount_(r.fillCount_),
03253 overCount_(r.overCount_),
03254 modCount_(0UL),
03255 dim_(r.dim_)
03256 {
03257 std::swap(axes_[ax1], axes_[ax2]);
03258 }
03259
03260 template <typename Numeric, class Axis>
03261 HistoND<Numeric,Axis>::HistoND(const HistoND& r)
03262 : title_(r.title_),
03263 accumulatedDataLabel_(r.accumulatedDataLabel_),
03264 data_(r.data_),
03265 overflow_(r.overflow_),
03266 axes_(r.axes_),
03267 weightBuf_(r.weightBuf_),
03268 indexBuf_(r.indexBuf_),
03269 fillCount_(r.fillCount_),
03270 overCount_(r.overCount_),
03271 modCount_(0UL),
03272 dim_(r.dim_)
03273 {
03274 }
03275
03276 template <typename Numeric, class Axis>
03277 HistoND<Numeric,Axis>& HistoND<Numeric,Axis>::operator=(const HistoND& r)
03278 {
03279 if (&r != this)
03280 {
03281 title_ = r.title_;
03282 accumulatedDataLabel_ = r.accumulatedDataLabel_;
03283 data_.uninitialize();
03284 data_ = r.data_;
03285 overflow_.uninitialize();
03286 overflow_ = r.overflow_;
03287 axes_ = r.axes_;
03288 weightBuf_ = r.weightBuf_;
03289 indexBuf_ = r.indexBuf_;
03290 fillCount_ = r.fillCount_;
03291 overCount_ = r.overCount_;
03292 dim_ = r.dim_;
03293 ++modCount_;
03294 }
03295 return *this;
03296 }
03297
03298 template <typename Numeric, class Axis>
03299 HistoND<Numeric,Axis> HistoND<Numeric,Axis>::transpose(
03300 const unsigned axisNum1, const unsigned axisNum2) const
03301 {
03302 if (axisNum1 >= dim_ || axisNum2 >= dim_)
03303 throw npstat::NpstatOutOfRange("In npstat::HistoND::transpose: "
03304 "axis number is out of range");
03305 if (axisNum1 == axisNum2)
03306
03307 return *this;
03308 else
03309 return HistoND(*this, axisNum1, axisNum2);
03310 }
03311
03312 template <typename Numeric, class Axis>
03313 template <typename Num2>
03314 void HistoND<Numeric,Axis>::addToBinContents(const Num2& weight)
03315 {
03316 const unsigned long nDat = data_.length();
03317 Numeric* data = const_cast<Numeric*>(data_.data());
03318 for (unsigned long i=0; i<nDat; ++i)
03319 data[i] += weight;
03320 fillCount_ += nDat;
03321 ++modCount_;
03322 }
03323
03324 template <typename Numeric, class Axis>
03325 template <typename Num2>
03326 void HistoND<Numeric,Axis>::addToOverflows(const Num2& weight)
03327 {
03328 const unsigned long nOver = overflow_.length();
03329 Numeric* data = const_cast<Numeric*>(overflow_.data());
03330 for (unsigned long i=0; i<nOver; ++i)
03331 data[i] += weight;
03332 overCount_ += nOver;
03333 fillCount_ += nOver;
03334 ++modCount_;
03335 }
03336
03337 template <typename Numeric, class Axis>
03338 template <typename Num2>
03339 void HistoND<Numeric,Axis>::addToBinContents(
03340 const Num2* data, const unsigned long dataLength)
03341 {
03342 if (dataLength != data_.length()) throw npstat::NpstatInvalidArgument(
03343 "In npstat::HistoND::addToBinContents: incompatible data length");
03344 assert(data);
03345 Numeric* dat = const_cast<Numeric*>(data_.data());
03346 for (unsigned long i=0; i<dataLength; ++i)
03347 dat[i] += data[i];
03348 fillCount_ += dataLength;
03349 ++modCount_;
03350 }
03351
03352 template <typename Numeric, class Axis>
03353 template <typename Num2>
03354 void HistoND<Numeric,Axis>::addToOverflows(
03355 const Num2* data, const unsigned long dataLength)
03356 {
03357 if (dataLength != overflow_.length()) throw npstat::NpstatInvalidArgument(
03358 "In npstat::HistoND::addToOverflows: incompatible data length");
03359 assert(data);
03360 Numeric* dat = const_cast<Numeric*>(overflow_.data());
03361 for (unsigned long i=0; i<dataLength; ++i)
03362 dat[i] += data[i];
03363 overCount_ += dataLength;
03364 fillCount_ += dataLength;
03365 ++modCount_;
03366 }
03367
03368 template <typename Numeric, class Axis>
03369 template <typename Num2>
03370 void HistoND<Numeric,Axis>::scaleBinContents(
03371 const Num2* data, const unsigned long dataLength)
03372 {
03373 if (dataLength != data_.length()) throw npstat::NpstatInvalidArgument(
03374 "In npstat::HistoND::scaleBinContents: incompatible data length");
03375 assert(data);
03376 Numeric* dat = const_cast<Numeric*>(data_.data());
03377 for (unsigned long i=0; i<dataLength; ++i)
03378 dat[i] *= data[i];
03379 ++modCount_;
03380 }
03381
03382 template <typename Numeric, class Axis>
03383 template <typename Num2>
03384 void HistoND<Numeric,Axis>::scaleOverflows(
03385 const Num2* data, const unsigned long dataLength)
03386 {
03387 if (dataLength != overflow_.length()) throw npstat::NpstatInvalidArgument(
03388 "In npstat::HistoND::scaleOverflows: incompatible data length");
03389 assert(data);
03390 Numeric* dat = const_cast<Numeric*>(overflow_.data());
03391 for (unsigned long i=0; i<dataLength; ++i)
03392 dat[i] *= data[i];
03393 ++modCount_;
03394 }
03395
03396 template <typename Numeric, class Axis>
03397 template <typename Num2>
03398 inline void HistoND<Numeric,Axis>::setBinContents(
03399 const Num2* data, const unsigned long dataLength,
03400 const bool clearOverflowsNow)
03401 {
03402 data_.setData(data, dataLength);
03403 if (clearOverflowsNow)
03404 clearOverflows();
03405 ++modCount_;
03406 }
03407
03408 template <typename Numeric, class Axis>
03409 template <typename Num2>
03410 inline void HistoND<Numeric,Axis>::setOverflows(
03411 const Num2* data, const unsigned long dataLength)
03412 {
03413 overflow_.setData(data, dataLength);
03414 ++modCount_;
03415 }
03416
03417 template <typename Numeric, class Axis>
03418 inline void HistoND<Numeric,Axis>::recalculateNFillsFromData()
03419 {
03420 const long double nOver = overflow_.template sum<long double>();
03421 const long double nData = data_.template sum<long double>();
03422 overCount_ = static_cast<unsigned long>(nOver);
03423 fillCount_ = static_cast<unsigned long>(nData + nOver);
03424 ++modCount_;
03425 }
03426
03427 template <typename Numeric, class Axis>
03428 template <typename Num2, typename Num3>
03429 inline void HistoND<Numeric,Axis>::addToProjection(
03430 HistoND<Num2,Axis>* projection,
03431 AbsArrayProjector<Numeric,Num3>& projector,
03432 const unsigned *projectedIndices,
03433 const unsigned nProjectedIndices) const
03434 {
03435 assert(projection);
03436 data_.addToProjection(&projection->data_, projector,
03437 projectedIndices, nProjectedIndices);
03438 projection->fillCount_ += projection->nBins();
03439 projection->modCount_++;
03440 }
03441
03442 template <typename Numeric, class Axis>
03443 template <typename Num2, typename Num3>
03444 inline void HistoND<Numeric,Axis>::addToProjection(
03445 HistoND<Num2,Axis>* projection,
03446 AbsVisitor<Numeric,Num3>& projector,
03447 const unsigned *projectedIndices,
03448 const unsigned nProjectedIndices) const
03449 {
03450 assert(projection);
03451 data_.addToProjection(&projection->data_, projector,
03452 projectedIndices, nProjectedIndices);
03453 projection->fillCount_ += projection->nBins();
03454 projection->modCount_++;
03455 }
03456
03457 template <typename Numeric, class Axis>
03458 const char* HistoND<Numeric,Axis>::classname()
03459 {
03460 static const std::string myClass(gs::template_class_name<Numeric,Axis>(
03461 "npstat::HistoND"));
03462 return myClass.c_str();
03463 }
03464
03465 template<typename Numeric, class Axis>
03466 bool HistoND<Numeric,Axis>::write(std::ostream& of) const
03467 {
03468 gs::write_pod(of, title_);
03469 gs::write_pod(of, accumulatedDataLabel_);
03470 gs::write_pod(of, fillCount_);
03471 gs::write_pod(of, overCount_);
03472
03473 return !of.fail() &&
03474 gs::write_obj_vector(of, axes_) &&
03475 data_.classId().write(of) &&
03476 data_.write(of) &&
03477 overflow_.write(of);
03478 }
03479
03480 template<typename Numeric, class Axis>
03481 HistoND<Numeric,Axis>* HistoND<Numeric,Axis>::read(const gs::ClassId& id,
03482 std::istream& in)
03483 {
03484 static const gs::ClassId current(
03485 gs::ClassId::makeId<HistoND<Numeric,Axis> >());
03486 current.ensureSameId(id);
03487
03488 std::string title;
03489 gs::read_pod(in, &title);
03490
03491 std::string accumulatedDataLabel;
03492 gs::read_pod(in, &accumulatedDataLabel);
03493
03494 unsigned long fillCount = 0, overCount = 0;
03495 gs::read_pod(in, &fillCount);
03496 gs::read_pod(in, &overCount);
03497 if (in.fail()) throw gs::IOReadFailure(
03498 "In npstat::HistoND::read: input stream failure");
03499
03500 std::vector<Axis> axes;
03501 gs::read_heap_obj_vector_as_placed(in, &axes);
03502 gs::ClassId ida(in, 1);
03503 ArrayND<Numeric> data, over;
03504 ArrayND<Numeric>::restore(ida, in, &data);
03505 ArrayND<Numeric>::restore(ida, in, &over);
03506 CPP11_auto_ptr<HistoND<Numeric,Axis> > result(
03507 new HistoND<Numeric,Axis>(axes, title.c_str(),
03508 accumulatedDataLabel.c_str()));
03509 result->data_ = data;
03510 result->overflow_ = over;
03511 result->fillCount_ = fillCount;
03512 result->overCount_ = overCount;
03513 return result.release();
03514 }
03515
03516 template <typename Histo>
03517 void convertHistoToDensity(Histo* h, const bool knownNonNegative)
03518 {
03519 assert(h);
03520 if (!knownNonNegative)
03521 (const_cast<ArrayND<typename
03522 Histo::value_type>&>(h->binContents())).makeNonNegative();
03523 const double integ = h->integral();
03524 *h /= integ;
03525 }
03526
03527 template <typename Histo>
03528 std::vector<LinearMapper1d> densityScanHistoMap(const Histo& histo)
03529 {
03530 std::vector<LinearMapper1d> result;
03531 const unsigned d = histo.dim();
03532 result.reserve(d);
03533 for (unsigned i=0; i<d; ++i)
03534 {
03535 const LinearMapper1d& m = histo.axis(i).binNumberMapper(false);
03536 result.push_back(m.inverse());
03537 }
03538 return result;
03539 }
03540
03541 template <typename Histo>
03542 std::vector<CircularMapper1d> convolutionHistoMap(
03543 const Histo& histo, const bool doubleRange)
03544 {
03545 std::vector<CircularMapper1d> result;
03546 const unsigned d = histo.dim();
03547 result.reserve(d);
03548 for (unsigned i=0; i<d; ++i)
03549 result.push_back(histo.axis(i).kernelScanMapper(doubleRange));
03550 return result;
03551 }
03552 }
03553
03554
03555 #endif // NPSTAT_HISTOND_HH_
03556