-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathdump_weights.C
98 lines (69 loc) · 3.18 KB
/
dump_weights.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "WeightHandler.hh"
const std::string INPUT_DIR_NAME = "/uboone/data/users/gardiner/ntuples-stv";
const std::string OUTPUT_DIR_NAME = INPUT_DIR_NAME + "/weight_dumps";
void dump_them( const std::string& input_file_name ) {
TChain events_ch( "stv_tree" );
std::string full_input_file_name = INPUT_DIR_NAME + '/' + input_file_name;
events_ch.Add( full_input_file_name.c_str() );
// Create temporary storage for the systematic variation event weights
WeightHandler wh;
// Sync the branch addresses of the input TChain with the WeightHandler
// object
wh.set_branch_addresses( events_ch );
std::string full_output_file_name = OUTPUT_DIR_NAME + '/'
+ "weights-" + input_file_name;
TFile out_file( full_output_file_name.c_str(), "recreate" );
TTree* out_tree = new TTree( "weight_tree", "weight_tree" );
long events_entry = 0;
bool need_to_create_branches = true;
while ( true ) {
if ( events_entry % 1000 == 0 ) {
std::cout << " Processing event #" << events_entry << '\n';
}
// TChain::LoadTree() returns the entry number that should be used with
// the current TTree object, which (together with the TBranch objects
// that it owns) doesn't know about the other TTrees in the TChain.
// If the return value is negative, there was an I/O error, or we've
// attempted to read past the end of the TChain.
int local_entry = events_ch.LoadTree( events_entry );
// If we've reached the end of the TChain (or encountered an I/O error),
// then terminate the event loop
if ( local_entry < 0 ) break;
events_ch.GetEntry( events_entry );
// Make separate branches for individual systematic variation
// weights in the map. This is hacky and results in tons of branches,
// but it helps to optimize response matrix evaluation downstream.
// NOTE: I cheat here by relying on the branch addresses staying the
// same throughout the entire event loop. Setting the branch addresses
// during every iteration is very slow. This is fragile but appears to
// work thanks to consistent weight vector sizes.
if ( need_to_create_branches ) {
for ( auto& pair : wh.weight_map() ) {
const auto& weight_name = pair.first;
auto& weight_vec = pair.second;
size_t num_weights = weight_vec->size();
for ( size_t w = 0u; w < num_weights; ++w ) {
// Add the universe index to the branch name
std::string weight_branch_name = weight_name + std::to_string( w );
auto* weight_ptr = &weight_vec->at( w );
std::string leaf_spec = weight_branch_name + "/D";
// Set the branch address for this vector of weights
set_output_branch_address( *out_tree, weight_branch_name,
weight_ptr, need_to_create_branches, leaf_spec );
}
}
need_to_create_branches = false;
}
out_tree->Fill();
++events_entry;
}
out_tree->Write();
}
void dump_weights() {
std::ifstream in_file( "weight_dump_list.txt" );
std::string input_file_name;
while ( std::getline(in_file, input_file_name, '\n') ) {
std::cout << "Processing event weights for " << input_file_name << '\n';
dump_them( input_file_name );
}
}