LDMX Software
HistogramPoolTest.cxx
Go to the documentation of this file.
1
8#include <catch2/catch_approx.hpp>
9#include <catch2/catch_test_macros.hpp>
10#include <catch2/matchers/catch_matchers_vector.hpp>
11
12#include "Framework/HistogramPool.h"
13#include "TFile.h" //to open and check root files
14
16
21TDirectory* cantCreateDir() {
22 throw std::runtime_error("NOFILEGIVEN");
23 return nullptr;
24}
25
34TEST_CASE("HistogramPool Functions", "[Framework][functionality]") {
35 const char* test_file = "/tmp/test_histogram_pool.root";
36
37 SECTION("exception on request") {
39 // raise exception from get_directory
40 REQUIRE_THROWS_WITH(test_pool.create("dne", "foo", 10, 0.0, 1.0),
41 "NOFILEGIVEN");
42 }
43
44 SECTION("creation on request") {
45 TFile* histogram_file{nullptr};
46 auto open_on_request = [&histogram_file, &test_file]() -> TDirectory* {
47 if (histogram_file == nullptr) {
48 histogram_file = TFile::Open(test_file, "recreate");
49 }
50 return histogram_file->mkdir("histo_directory");
51 };
52 HistogramPool test_pool{open_on_request};
53 // test_file has not been opened yet
54 REQUIRE(histogram_file == nullptr);
55 test_pool.create("h", "bla", 10, 0, 1);
56 // test_file exists with histo_directory/ inside of it
57 REQUIRE(histogram_file != nullptr);
58 CHECK(histogram_file->Get("histo_directory") != nullptr);
59 histogram_file->Write();
60 // test_file exists with histo_directory/h inside of it
61 CHECK(histogram_file->Get("histo_directory/h") != nullptr);
62 }
63
64 SECTION("separate pools") {
65 TFile histogram_file{test_file, "recreate"};
66 HistogramPool test_pool_1{[&histogram_file]() {
67 static TDirectory* d{histogram_file.mkdir("p1")};
68 return d;
69 }};
70 HistogramPool test_pool_2{[&histogram_file]() {
71 static TDirectory* d{histogram_file.mkdir("p2")};
72 return d;
73 }};
74 CHECK(histogram_file.Get("p1") == nullptr);
75 CHECK(histogram_file.Get("p2") == nullptr);
76 test_pool_1.create("h", "bar", 10, 0, 1);
77 CHECK(histogram_file.Get("p1") != nullptr);
78 CHECK(histogram_file.Get("p2") == nullptr);
79 test_pool_2.create("h", "buz", 10, 0, 10);
80 CHECK(histogram_file.Get("p1") != nullptr);
81 CHECK(histogram_file.Get("p2") != nullptr);
82 histogram_file.Write();
83 // test_file exists with
84 // p1/h -> 10 bins between 0 and 1
85 // p2/h -> 10 bins between 0 and 10
86 auto h1 = dynamic_cast<TH1F*>(histogram_file.Get("p1/h"));
87 auto h2 = dynamic_cast<TH1F*>(histogram_file.Get("p2/h"));
88 REQUIRE(h1 != nullptr);
89 REQUIRE(h2 != nullptr);
90 CHECK(h1->GetNbinsX() == 10);
91 CHECK(h2->GetNbinsX() == 10);
92 CHECK(h1->GetBinLowEdge(10) == 0.9);
93 CHECK(h2->GetBinLowEdge(10) == 9);
94 }
95
96 // different types of creation
97 SECTION("different types of histograms") {
98 TFile histogram_file{test_file, "recreate"};
99 HistogramPool test_pool{[&histogram_file]() {
100 static TDirectory* d{histogram_file.mkdir("p")};
101 return d;
102 }};
103 std::vector<std::string> cats{"one", "two", "three"};
104
105 test_pool.create("h1_1", "foo", 10, 0, 1);
106 test_pool.create("h1_2", "bar", {0.0, 0.5, 0.8, 1.0}, true);
107 test_pool.create("h1_3", "", cats);
108
109 test_pool.create("h2_1", "baz", 5, -5, 5, "foo", 10, -5, 5);
110 test_pool.create("h2_2", "baz", {-5.0, -1.0, 0.0, 1.0, 5.0}, "foo",
111 {0.0, 1.0, 5.0});
112 test_pool.create("h2_3", "", cats, "", cats);
113
114 test_pool.setWeight(0.75);
115 test_pool.fill("h1_2", 0.75);
116 test_pool.fillw("h1_2", 0.1, 0.5);
117 test_pool.fill("h1_2", 0.75);
118 test_pool.setWeight(1);
119
120 test_pool.fill("h1_3", "one");
121 // "one" again because categories are zero-indexed into bins
122 test_pool.fill("h1_3", 0);
123 // "two" because categories are zero-indexed into bins
124 test_pool.fill("h1_3", 1);
125 // "three" into third bin
126 test_pool.fill("h1_3", "three");
127 // unknown category auto-expands Nbins when
128 // doing categorical axes
129 // test_pool.fill("h1_3", "four");
130
131 test_pool.fill("h2_3", "one", "two");
132
133 histogram_file.Write();
134
135 auto h1_1 = dynamic_cast<TH1F*>(histogram_file.Get("p/h1_1"));
136 REQUIRE(h1_1 != nullptr);
137 CHECK(h1_1->GetNbinsX() == 10);
138 CHECK(h1_1->GetBinLowEdge(1) == 0.0);
139 CHECK(h1_1->GetBinLowEdge(11) == 1.0);
140 REQUIRE(h1_1->GetSumw2() != nullptr);
141 CHECK(h1_1->GetSumw2()->fN == 0);
142
143 auto h1_2 = dynamic_cast<TH1F*>(histogram_file.Get("p/h1_2"));
144 REQUIRE(h1_2 != nullptr);
145 CHECK(h1_2->GetNbinsX() == 3);
146 CHECK(h1_2->GetBinLowEdge(1) == 0.0);
147 CHECK(h1_2->GetBinLowEdge(2) == 0.5);
148 CHECK(h1_2->GetBinLowEdge(3) == 0.8);
149 CHECK(h1_2->GetBinLowEdge(4) == 1.0);
150 CHECK(h1_2->GetBinContent(1) == 0.5);
151 CHECK(h1_2->GetBinContent(2) == 2 * 0.75);
152 REQUIRE(h1_2->GetSumw2() != nullptr);
153 CHECK(h1_2->GetSumw2()->fN == 5);
154 CHECK(h1_2->GetSumw2()->At(1) == 0.25);
155 CHECK(h1_2->GetSumw2()->At(2) == 0.75 * 0.75 * 2);
156
157 auto h1_3 = dynamic_cast<TH1F*>(histogram_file.Get("p/h1_3"));
158 REQUIRE(h1_3 != nullptr);
159 CHECK(h1_3->GetNbinsX() == 3);
160
161 CHECK(h1_3->GetBinContent(0) == 0); // under
162 CHECK(h1_3->GetBinContent(1) == 2); // one
163 CHECK(h1_3->GetBinContent(2) == 1); // two
164 CHECK(h1_3->GetBinContent(3) == 1); // three
165 CHECK(h1_3->GetBinContent(4) == 0); // over
166
167 auto h2_1 = dynamic_cast<TH2F*>(histogram_file.Get("p/h2_1"));
168 REQUIRE(h2_1 != nullptr);
169 CHECK(h2_1->GetNbinsX() == 5);
170 CHECK(h2_1->GetNbinsY() == 10);
171
172 auto h2_2 = dynamic_cast<TH2F*>(histogram_file.Get("p/h2_2"));
173 REQUIRE(h2_2 != nullptr);
174 CHECK(h2_2->GetNbinsX() == 4);
175 CHECK(h2_2->GetNbinsY() == 2);
176
177 auto h2_3 = dynamic_cast<TH2F*>(histogram_file.Get("p/h2_3"));
178 REQUIRE(h2_3 != nullptr);
179 CHECK(h2_3->GetBinContent(1, 2) == 1);
180 }
181}
TEST_CASE("HistogramPool Functions", "[Framework][functionality]")
Test for HistogramPool.
TDirectory * cantCreateDir()
mock exception like the case where configuration did not provide a histogram file
Class for holding an EventProcessor's histogram pointers and making sure that they all end up in the ...
void create(const config::Parameters &p)
Create a histogram from the input configuration parameters.