npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
NtHistoFill.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_NTHISTOFILL_HH_
2 #define NPSTAT_NTHISTOFILL_HH_
3 
4 /*!
5 // \file NtHistoFill.hh
6 //
7 // \brief Fill a histogram using contents of a homogeneous ntuple
8 //
9 // Author: I. Volobouev
10 //
11 // November 2011
12 */
13 
14 #include <cassert>
15 #include <stdexcept>
16 #include <climits>
17 
18 namespace npstat {
19  /**
20  // This convenience class fills a histogram using ntuple contents.
21  // For use inside "cycleOverRows", "conditionalCycleOverRows", and
22  // other similar methods of AbsNtuple.
23  //
24  // The second template parameter switches between use of "fill"
25  // and "fillC" methods of the Histogram class
26  */
27  template <class Histogram, bool useFillC=false>
29  {
30  public:
31  typedef Histogram histo_type;
32 
33  /**
34  // This constructor assumes that correctness of the
35  // ntuple column numbers has already been verified.
36  // Column numbers "coordColumns" which map ntuple column numbers
37  // into histogram axes are thus best generated with AbsNtuple
38  // methods "columnIndices". Column number coordColumns[0]
39  // will be mapped into the first histogram axis, coordColumns[1]
40  // into the second, etc. Ntuple method "validColumn" can be
41  // used to generate the weight column number. If the weight
42  // column is not specified, 1 will be used as the weight.
43  */
44  inline NtHistoFill(Histogram* histo,
45  const std::vector<unsigned long>& coordColumns,
46  const unsigned long weightColumn = ULONG_MAX)
47  : histo_(histo),
48  coordCols_(coordColumns),
49  coords_(histo_->dim()),
50  weightCol_(weightColumn),
51  dim_(histo_->dim()),
52  one_(static_cast<typename Histogram::value_type>(1))
53  {
54  assert(histo_);
55  if (!dim_) throw std::invalid_argument(
56  "In npstat::NtHistoFill constructor: "
57  "can not fill zero-dimensional histograms");
58  if (dim_ != coordColumns.size()) throw std::invalid_argument(
59  "In npstat::NtHistoFill constructor: "
60  "incompatible number of columns");
61  weightColumnSpecified_ = weightColumn != ULONG_MAX;
62  }
63 
64  static inline bool callsFillC() {return useFillC;}
65 
66  static inline const char* histoClassname()
67  {
68  static const gs::ClassId hid(gs::ClassId::makeId<Histogram>());
69  return hid.name().c_str();
70  }
71 
72  private:
73  template <typename T, bool fillC>
74  struct HFill
75  {
76  inline static void fill(Histogram* h, const double* c,
77  const unsigned dim, const T& weight)
78  {h->fill(c, dim, weight);}
79  };
80 
81  template <typename T>
82  struct HFill<T, true>
83  {
84  inline static void fill(Histogram* h, const double* c,
85  const unsigned dim, const T& weight)
86  {h->fillC(c, dim, weight);}
87  };
88 
89  NtHistoFill();
90 
91  Histogram* histo_;
92  std::vector<unsigned long> coordCols_;
93  mutable std::vector<double> coords_;
94  unsigned long weightCol_;
95  unsigned dim_;
96  bool weightColumnSpecified_;
97  typename Histogram::value_type one_;
98 
99  public:
100  template <typename T>
101  inline void accumulate(const T* rowContents,
102  const unsigned long nCols) const
103  {
104  const unsigned long* idx = &coordCols_[0];
105  double* c = &coords_[0];
106  for (unsigned i=0; i<dim_; ++i)
107  c[i] = static_cast<double>(rowContents[idx[i]]);
108  if (weightColumnSpecified_)
109  {
110  if (weightCol_ >= nCols)
111  throw std::out_of_range(
112  "In npstat::NtHistoFill::accumulate: "
113  "weight column index out of range");
114  HFill<T,useFillC>::fill(
115  histo_, c, dim_, rowContents[weightCol_]);
116  }
117  else
118  HFill<typename Histogram::value_type,useFillC>::fill(
119  histo_, c, dim_, one_);
120  }
121  };
122 }
123 
124 #endif // NPSTAT_NTHISTOFILL_HH_
Definition: NtHistoFill.hh:29
NtHistoFill(Histogram *histo, const std::vector< unsigned long > &coordColumns, const unsigned long weightColumn=ULONG_MAX)
Definition: NtHistoFill.hh:44
Definition: AbsArrayProjector.hh:14