LDMX Software
NtupleManagerTest.cxx File Reference

Test the operation of Framework processing. More...

#include <catch2/catch_approx.hpp>
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_vector.hpp>
#include "Framework/NtupleManager.h"
#include "TFile.h"
#include "TTreeReader.h"

Go to the source code of this file.

Functions

template<typename T >
safe_deref (TTreeReaderValue< T > reader_val)
 Have to avoid dereferencing the value itself since there are no checks within it and so the compiler warns us that we could be dereferencing a nullptr.
 
 TEST_CASE ("Ntuple Manager Functions", "[Framework][functionality]")
 Test for NtupleManager.
 

Detailed Description

Test the operation of Framework processing.

Author
Tom Eichlersmith, University of Minnesota

Definition in file NtupleManagerTest.cxx.

Function Documentation

◆ safe_deref()

template<typename T >
T safe_deref ( TTreeReaderValue< T > reader_val)

Have to avoid dereferencing the value itself since there are no checks within it and so the compiler warns us that we could be dereferencing a nullptr.

This gets the raw pointer value and shows the compiler that we check if its null before dereferencing, returning the default construct if that fails.

Definition at line 26 of file NtupleManagerTest.cxx.

26 {
27 T const* val_ptr{reader_val.Get()};
28 if (val_ptr != nullptr) {
29 return *val_ptr;
30 }
31 return T();
32}

Referenced by TEST_CASE().

◆ TEST_CASE()

TEST_CASE ( "Ntuple Manager Functions" ,
"" [Framework][functionality] )

Test for NtupleManager.

We check that the NtupleManager can fill a TTree with three entries of the following types.

  • bool, short, int, long, float, double
  • vectors of the above types

Definition at line 42 of file NtupleManagerTest.cxx.

42 {
43 const char* ntuple_file = "/tmp/test_ntuplemanager.root";
44
45 TFile f(ntuple_file, "recreate");
47 REQUIRE_NOTHROW(n.create("test"));
48 CHECK_THROWS(n.create("test"));
49
50 REQUIRE_NOTHROW(n.addVar<bool>("test", "bool"));
51 REQUIRE_NOTHROW(n.addVar<short>("test", "short"));
52 REQUIRE_NOTHROW(n.addVar<int>("test", "int"));
53 REQUIRE_NOTHROW(n.addVar<long>("test", "long"));
54 REQUIRE_NOTHROW(n.addVar<float>("test", "float"));
55 REQUIRE_NOTHROW(n.addVar<double>("test", "double"));
56 REQUIRE_NOTHROW(n.addVar<std::vector<bool>>("test", "vector_bool"));
57 REQUIRE_NOTHROW(n.addVar<std::vector<short>>("test", "vector_short"));
58 REQUIRE_NOTHROW(n.addVar<std::vector<int>>("test", "vector_int"));
59 REQUIRE_NOTHROW(n.addVar<std::vector<long>>("test", "vector_long"));
60 REQUIRE_NOTHROW(n.addVar<std::vector<float>>("test", "vector_float"));
61 REQUIRE_NOTHROW(n.addVar<std::vector<double>>("test", "vector_double"));
62
63 CHECK_THROWS(n.addVar<float>("test", "float"));
64
65 std::vector<bool> bools = {true, false, true};
66 std::vector<short> shorts = {2, 3, 4};
67 std::vector<int> ints = {2, 3, 4};
68 std::vector<long> longs = {2, 3, 4};
69 std::vector<float> floats = {0.2, 0.3, 0.4};
70 std::vector<double> doubles = {0.2, 0.3, 0.4};
71
72 std::vector<std::vector<bool>> vector_bools = {
73 {true, true, true}, {false, false, false}, {true, false, false}};
74 std::vector<std::vector<short>> vector_shorts = {
75 {1, 2, 3}, {5, 7, 9}, {3, 4, 5}};
76 std::vector<std::vector<int>> vector_ints = {{1, 2, 3}, {5, 7, 9}, {3, 4, 5}};
77 std::vector<std::vector<long>> vector_longs = {
78 {1, 2, 3}, {5, 7, 9}, {3, 4, 5}};
79 std::vector<std::vector<float>> vector_floats = {
80 {0.1, 0.01, 0.001}, {2e4, 3e5, 4e6}, {0.9, 0.99, 0.999}};
81 std::vector<std::vector<double>> vector_doubles = {
82 {0.1, 0.01, 0.001}, {2e4, 3e5, 4e6}, {0.9, 0.99, 0.999}};
83
84 for (size_t i = 0; i < 3; i++) {
85 // to save space, a std::vector<bool>
86 // compresses each bool into a one-bit
87 // type that can be converted back to the
88 // 8-bit bool type.
89 REQUIRE_NOTHROW(n.setVar("bool", bool(bools.at(i))));
90 REQUIRE_NOTHROW(n.setVar("short", shorts.at(i)));
91 REQUIRE_NOTHROW(n.setVar("int", ints.at(i)));
92 REQUIRE_NOTHROW(n.setVar("long", longs.at(i)));
93 REQUIRE_NOTHROW(n.setVar("float", floats.at(i)));
94 REQUIRE_NOTHROW(n.setVar("double", doubles.at(i)));
95 REQUIRE_NOTHROW(n.setVar("vector_bool", vector_bools.at(i)));
96 REQUIRE_NOTHROW(n.setVar("vector_short", vector_shorts.at(i)));
97 REQUIRE_NOTHROW(n.setVar("vector_int", vector_ints.at(i)));
98 REQUIRE_NOTHROW(n.setVar("vector_long", vector_longs.at(i)));
99 REQUIRE_NOTHROW(n.setVar("vector_float", vector_floats.at(i)));
100 REQUIRE_NOTHROW(n.setVar("vector_double", vector_doubles.at(i)));
101 CHECK_THROWS(n.setVar("bool", shorts.at(i)));
102 CHECK_THROWS(n.setVar("bool", vector_bools.at(i)));
103 n.fill();
104 n.clear();
105 }
106
107 f.Write();
108 f.Close();
109
110 TTreeReader r("test", TFile::Open(ntuple_file));
111 TTreeReaderValue<bool> root_bool(r, "bool");
112 TTreeReaderValue<short> root_short(r, "short");
113 TTreeReaderValue<int> root_int(r, "int");
114 // root serializes 'long' (which on some systems is 64-bit)
115 // depending on the number of bits, so we need to read
116 // it in with 'long long' (which is at least 64-bit)
117 // to make sure we don't fail
118 TTreeReaderValue<long long> root_long(r, "long");
119 TTreeReaderValue<float> root_float(r, "float");
120 TTreeReaderValue<double> root_double(r, "double");
121 TTreeReaderValue<std::vector<bool>> root_vector_bool(r, "vector_bool");
122 TTreeReaderValue<std::vector<short>> root_vector_short(r, "vector_short");
123 TTreeReaderValue<std::vector<int>> root_vector_int(r, "vector_int");
124 TTreeReaderValue<std::vector<long>> root_vector_long(r, "vector_long");
125 TTreeReaderValue<std::vector<float>> root_vector_float(r, "vector_float");
126 TTreeReaderValue<std::vector<double>> root_vector_double(r, "vector_double");
127
128 for (size_t i = 0; i < 3; i++) {
129 REQUIRE(r.Next());
130 CHECK(*root_bool == bools.at(i));
131 CHECK(*root_short == shorts.at(i));
132 CHECK(*root_int == ints.at(i));
133 CHECK(*root_long == longs.at(i));
134 CHECK(*root_float == floats.at(i));
135 CHECK(*root_double == doubles.at(i));
136 // root takes the liberty to permut vectors when serializing
137 // in order to try to save space
138 // This means we need to use unordered equals.
139 // Not too much loss in efficiency becuase we keep our vectors short.
140 CHECK_THAT(safe_deref(root_vector_bool),
141 Catch::Matchers::UnorderedEquals(vector_bools.at(i)));
142 CHECK_THAT(safe_deref(root_vector_short),
143 Catch::Matchers::UnorderedEquals(vector_shorts.at(i)));
144 CHECK_THAT(safe_deref(root_vector_int),
145 Catch::Matchers::UnorderedEquals(vector_ints.at(i)));
146 CHECK_THAT(safe_deref(root_vector_long),
147 Catch::Matchers::UnorderedEquals(vector_longs.at(i)));
148 CHECK_THAT(safe_deref(root_vector_float),
149 Catch::Matchers::UnorderedEquals(vector_floats.at(i)));
150 CHECK_THAT(safe_deref(root_vector_double),
151 Catch::Matchers::UnorderedEquals(vector_doubles.at(i)));
152 }
153
154} // process test
T safe_deref(TTreeReaderValue< T > reader_val)
Have to avoid dereferencing the value itself since there are no checks within it and so the compiler ...
Singleton class used to manage the creation and pooling of ntuples.
static NtupleManager & getInstance()

References framework::NtupleManager::getInstance(), and safe_deref().