Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ConvertToTH3.cxx
Go to the documentation of this file.
1/// \file
2/// \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
3/// Feedback is welcome!
4
7#include <ROOT/RBinIndex.hxx>
8#include <ROOT/RHist.hxx>
10
11#include <TH3.h>
12
13#include <cassert>
14#include <cstddef>
15#include <memory>
16#include <stdexcept>
17#include <type_traits>
18#include <variant>
19#include <vector>
20
21using namespace ROOT::Experimental;
22
23namespace {
24template <typename Hist, typename T>
25std::unique_ptr<Hist> ConvertToTH3Impl(const RHistEngine<T> &engine)
26{
27 if (engine.GetNDimensions() != 3) {
28 throw std::invalid_argument("TH3 requires three dimensions");
29 }
30
31 auto ret = std::make_unique<Hist>();
32 ret->SetDirectory(nullptr);
33
34 const auto &axis0 = engine.GetAxes()[0];
36 const auto &axis1 = engine.GetAxes()[1];
38 const auto &axis2 = engine.GetAxes()[2];
40 ret->SetBinsLength();
41
42 Double_t *sumw2 = nullptr;
44 if constexpr (std::is_same_v<T, RBinWithError>) {
45 if (sumw2 == nullptr) {
46 ret->Sumw2();
47 sumw2 = ret->GetSumw2()->GetArray();
48 }
49 const RBinWithError &c = engine.GetBinContent(index0, index1, index2);
50 ret->GetArray()[i] = c.fSum;
51 sumw2[i] = c.fSum2;
52 } else {
53 (void)sumw2;
54 ret->GetArray()[i] = engine.GetBinContent(index0, index1, index2);
55 }
56 };
57
58 // Copy the bin contents, accounting for TH3 numbering conventions.
59 for (auto index0 : axis0.GetFullRange()) {
60 Int_t i0 = 0;
61 if (index0.IsUnderflow()) {
62 i0 = 0;
63 } else if (index0.IsOverflow()) {
64 i0 = axis0.GetNNormalBins() + 1;
65 } else {
66 assert(index0.IsNormal());
67 i0 = index0.GetIndex() + 1;
68 }
69 Int_t n0 = ret->GetXaxis()->GetNbins() + 2;
70
71 for (auto index1 : axis1.GetFullRange()) {
72 Int_t i1 = 0;
73 if (index1.IsUnderflow()) {
74 i1 = 0;
75 } else if (index1.IsOverflow()) {
76 i1 = axis1.GetNNormalBins() + 1;
77 } else {
78 assert(index1.IsNormal());
79 i1 = index1.GetIndex() + 1;
80 }
81 Int_t n1 = ret->GetYaxis()->GetNbins() + 2;
82
83 for (auto index2 : axis2.GetFullRange()) {
84 Int_t i2 = 0;
85 if (index2.IsUnderflow()) {
86 i2 = 0;
87 } else if (index2.IsOverflow()) {
88 i2 = axis2.GetNNormalBins() + 1;
89 } else {
90 assert(index2.IsNormal());
91 i2 = index2.GetIndex() + 1;
92 }
93
94 Int_t i = i0 + n0 * (i1 + n1 * i2);
96 }
97 }
98 }
99
100 return ret;
101}
102
103template <typename Hist>
104void ConvertGlobalStatistics(Hist &h, const RHistStats &stats)
105{
106 if (stats.IsTainted()) {
107 return;
108 }
109
110 h.SetEntries(stats.GetNEntries());
111
112 Double_t hStats[11] = {
113 stats.GetSumW(),
114 stats.GetSumW2(),
115 0,
116 0,
117 0,
118 0,
119 // We do not have sumwxy
120 0,
121 0,
122 0,
123 // We do not have sumwxz
124 0,
125 // We do not have sumwyz
126 0,
127 };
128 if (stats.IsEnabled(0)) {
129 hStats[2] = stats.GetDimensionStats(0).fSumWX;
130 hStats[3] = stats.GetDimensionStats(0).fSumWX2;
131 }
132 if (stats.IsEnabled(1)) {
133 hStats[4] = stats.GetDimensionStats(1).fSumWX;
134 hStats[5] = stats.GetDimensionStats(1).fSumWX2;
135 }
136 if (stats.IsEnabled(2)) {
137 hStats[7] = stats.GetDimensionStats(2).fSumWX;
138 hStats[8] = stats.GetDimensionStats(2).fSumWX2;
139 }
140 h.PutStats(hStats);
141}
142} // namespace
143
144namespace ROOT {
145namespace Experimental {
146namespace Hist {
147
148std::unique_ptr<TH3C> ConvertToTH3C(const RHistEngine<char> &engine)
149{
150 return ConvertToTH3Impl<TH3C>(engine);
151}
152
153std::unique_ptr<TH3S> ConvertToTH3S(const RHistEngine<short> &engine)
154{
155 return ConvertToTH3Impl<TH3S>(engine);
156}
157
158std::unique_ptr<TH3I> ConvertToTH3I(const RHistEngine<int> &engine)
159{
160 return ConvertToTH3Impl<TH3I>(engine);
161}
162
163std::unique_ptr<TH3L> ConvertToTH3L(const RHistEngine<long> &engine)
164{
165 return ConvertToTH3Impl<TH3L>(engine);
166}
167
168std::unique_ptr<TH3L> ConvertToTH3L(const RHistEngine<long long> &engine)
169{
170 return ConvertToTH3Impl<TH3L>(engine);
171}
172
173std::unique_ptr<TH3F> ConvertToTH3F(const RHistEngine<float> &engine)
174{
175 return ConvertToTH3Impl<TH3F>(engine);
176}
177
178std::unique_ptr<TH3D> ConvertToTH3D(const RHistEngine<double> &engine)
179{
180 return ConvertToTH3Impl<TH3D>(engine);
181}
182
183std::unique_ptr<TH3D> ConvertToTH3D(const RHistEngine<RBinWithError> &engine)
184{
185 return ConvertToTH3Impl<TH3D>(engine);
186}
187
188std::unique_ptr<TH3C> ConvertToTH3C(const RHist<char> &hist)
189{
190 auto ret = ConvertToTH3C(hist.GetEngine());
191 ConvertGlobalStatistics(*ret, hist.GetStats());
192 return ret;
193}
194
195std::unique_ptr<TH3S> ConvertToTH3S(const RHist<short> &hist)
196{
197 auto ret = ConvertToTH3S(hist.GetEngine());
198 ConvertGlobalStatistics(*ret, hist.GetStats());
199 return ret;
200}
201
202std::unique_ptr<TH3I> ConvertToTH3I(const RHist<int> &hist)
203{
204 auto ret = ConvertToTH3I(hist.GetEngine());
205 ConvertGlobalStatistics(*ret, hist.GetStats());
206 return ret;
207}
208
209std::unique_ptr<TH3L> ConvertToTH3L(const RHist<long> &hist)
210{
211 auto ret = ConvertToTH3L(hist.GetEngine());
212 ConvertGlobalStatistics(*ret, hist.GetStats());
213 return ret;
214}
215
216std::unique_ptr<TH3L> ConvertToTH3L(const RHist<long long> &hist)
217{
218 auto ret = ConvertToTH3L(hist.GetEngine());
219 ConvertGlobalStatistics(*ret, hist.GetStats());
220 return ret;
221}
222
223std::unique_ptr<TH3F> ConvertToTH3F(const RHist<float> &hist)
224{
225 auto ret = ConvertToTH3F(hist.GetEngine());
226 ConvertGlobalStatistics(*ret, hist.GetStats());
227 return ret;
228}
229
230std::unique_ptr<TH3D> ConvertToTH3D(const RHist<double> &hist)
231{
232 auto ret = ConvertToTH3D(hist.GetEngine());
233 ConvertGlobalStatistics(*ret, hist.GetStats());
234 return ret;
235}
236
237std::unique_ptr<TH3D> ConvertToTH3D(const RHist<RBinWithError> &hist)
238{
239 auto ret = ConvertToTH3D(hist.GetEngine());
240 ConvertGlobalStatistics(*ret, hist.GetStats());
241 return ret;
242}
243
244} // namespace Hist
245} // namespace Experimental
246} // namespace ROOT
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
A bin index with special values for underflow and overflow bins.
Definition RBinIndex.hxx:23
Histogram statistics of unbinned values.
const RDimensionStats & GetDimensionStats(std::size_t dim=0) const
Get the statistics object for one dimension.
std::uint64_t GetNEntries() const
bool IsEnabled(std::size_t dim) const
void ConvertAxis(TAxis &dst, const RAxisVariant &src)
Convert a single axis object to TAxis.
std::unique_ptr< TH3S > ConvertToTH3S(const RHistEngine< short > &engine)
Convert a three-dimensional histogram to TH3S.
std::unique_ptr< TH3C > ConvertToTH3C(const RHistEngine< char > &engine)
Convert a three-dimensional histogram to TH3C.
std::unique_ptr< TH3F > ConvertToTH3F(const RHistEngine< float > &engine)
Convert a three-dimensional histogram to TH3F.
std::unique_ptr< TH3I > ConvertToTH3I(const RHistEngine< int > &engine)
Convert a three-dimensional histogram to TH3I.
std::unique_ptr< TH3L > ConvertToTH3L(const RHistEngine< long > &engine)
Convert a three-dimensional histogram to TH3L.
std::unique_ptr< TH3D > ConvertToTH3D(const RHistEngine< double > &engine)
Convert a three-dimensional histogram to TH3D.
Namespace for ROOT features in testing.
Definition TROOT.h:100