-
Notifications
You must be signed in to change notification settings - Fork 197
Expand file tree
/
Copy pathDefinitions.h
More file actions
233 lines (168 loc) · 9.93 KB
/
Copy pathDefinitions.h
File metadata and controls
233 lines (168 loc) · 9.93 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#ifndef DEFINITIONS_H
#define DEFINITIONS_H
// podio::DataSource reconstructs the logical EDM4hep EventHeader collection
// from the split ROOT branches. This header defines the input type:
// edm4hep::EventHeaderCollection
#include "edm4hep/EventHeaderCollection.h"
// This header defines ROOT::VecOps::RVec,
// which we will use as the variable-length array of double weights.
#include <ROOT/RVec.hxx>
#include <string>
#include <vector>
#include <cstddef>
//input: EventHeader
//output: weights array
// However, eventheader is split across branches and the weights array is in : "_EventHeader_weights"
//its type: ROOT::VecOps::RVec<double> and I cannot use that as an input, so ->
// This is because eventheader data has a fixed size and cannot hold variable length arrays.
//eventheader column type: ROOT::VecOps::RVec<edm4hep::EventHeaderData>
// Enabling podio::DataSource reconstructs the logical
// edm4hep::EventHeaderCollection from the split ROOT branches.
//
// Therefore:
// input type = edm4hep::EventHeaderCollection
// output type = ROOT::VecOps::RVec<double>
// which is array of double values (weights)
//functor 1 : GetAllWeights
struct GetAllWeights {
//return type: (array of double values (weights) )
ROOT::VecOps::RVec<double>
// creating the function:
//operator() makes struct behave like a function
// first paranthesis is the input, (input type)
// const inside the paranthesis means ->
// const inside the paranthesis means -> This function may read eventHeaders, but it may not modify it.
// const{ } specifies that calling this functor will not modify the functor object itself: (functor object is defined while calling the functor ex: GetAllWeights A; -> A is the object)
operator()(const edm4hep::EventHeaderCollection& eventHeaders)const{
//to prevent errors when trying to reach the elements, if empty -> error
// to prevent errors when trying to reach the elements, if empty -> error
if (eventHeaders.empty()) {
return {};
}
//from the event header collection for an event we need to take the event header.
// With podio::DataSource, EventHeader becomes an edm4hep::EventHeaderCollection; EDM4hep stores objects in collections by default, even if there is normally only one EventHeader per event.
const auto& eventHeader = eventHeaders.at(0);
//eventHeaders.at(0) -> gets the first element (event header is the only object in the collection, so first element is the header for the current event.)
//const since
// auto lets C++ use the type returned by eventHeaders.at(0).
// Create an empty array where the event weights will be stored.
ROOT::VecOps::RVec<double> weights;
//output type = ROOT::VecOps::RVec<double> (a variable-length array whose elements are doubles) (weights -> variable name)
//Now we need to extract the weights from the single eventHeader
const auto eventWeights = eventHeader.getWeights();
//// getWeights() is an EDM4hep function that gets all weights stored in this EventHeader.
//Now copy each value from eventWeights into the output array weights
for (const auto weight : eventWeights) {
// Automatically iterates over all elements without needing the array/vector size.
//For each iteration, the current value is temporarily called weight
weights.push_back(weight);
//push_back() adds the current weight in the iteration to the end of the weights output array.
}
return weights;
}
};
// FUNCTOR 2 : GetWeightByName
//
//Finds a weight by name and returns its value for each event, or -1 if unavailable.
// For each event, uses the weight-name list supplied by the DataSource to find
// the requested label's index, then returns the numerical weight at that index.
// Setup input supplied once when the functor object is created:
// requested weight name: std::string
// Inputs supplied by RDataFrame:
// eventHeaders: edm4hep::EventHeaderCollection
// weightNames: std::vector<std::string>
// supplied through the _EventWeightNames DataSource column
// Output:
// double value or -1.0 if unavailable
// Create one GetWeightByName object and store the requested weight label.
// -> GetWeightByName selectedWeight("rwgt_4");
//object name: selectedweight
//object type: GetWeightByName
// selected weight's label: "rwgt_4"
// The requested label "rwgt_4" is stored in the selectedWeight object.
// The input file is not opened or accessed by this functor.
// RDataFrame calls the object's operator() using the EventHeader collection
// and the _EventWeightNames metadata column.
// Conceptually, RDataFrame calls:
// selectedWeight(EventHeader, _EventWeightNames);
//
// Here, EventHeader and _EventWeightNames are RDataFrame column names.
// The EventHeader is supplied for each event, while _EventWeightNames supplies
// the labels used to identify the requested numerical weight.
struct GetWeightByName {
// Store the name of the requested weight.
// For example, requestedWeightName may contain "rwgt_4".
std::string requestedWeightName;
// Constructor: runs when a GetWeightByName object is created.
// It stores the requested label inside the object.
// Example: GetWeightByName selectedWeight("rwgt_4");
// The constructor allows the functor object to remember which label was requested.
//The constructor defines what happens to that supplied value (requestedWeightName)
// It stores the label, but it does not open the file or read metadata.
GetWeightByName(const std::string& weightName)
: requestedWeightName(weightName) {
}
// operator() receives the label list from the DataSource and uses it to locate
// the stored requestedWeightName.
//Functor operator() that will be called for each event
// Functor 2 returns only one weight value for each event, so the return type is double.
// First input:
// type: edm4hep::EventHeaderCollection
// variable name: eventHeaders
//
// Second input:
// type: std::vector<std::string>
// variable name: weightNames
double operator()(
const edm4hep::EventHeaderCollection& eventHeaders,
const std::vector<std::string>& weightNames
) const {
// The const before each input type means operator() may read eventHeaders
// and weightNames, but it may not modify either of them.
// The final const means operator() does not modify the GetWeightByName object.
// It only reads the stored requestedWeightName.
// If there is no EventHeader for this event, there is no weight to return.
if (eventHeaders.empty()) {
return -1.0;
}
// Create a local variable to store the index of the requested label.
// -1 means that the requested label has not been found.
int weightIndex{-1};
// Loop through all weight labels supplied by the DataSource.
//
// std::size_t is the unsigned integer type normally used for
// vector sizes and vector positions.
for (std::size_t i = 0; i < weightNames.size(); ++i) {
// Compare the current label with the label stored in the functor object.
if (weightNames[i] == requestedWeightName) {
// Save the matching label's position.
// This same position identifies the corresponding numerical weight
// inside EventHeader.getWeights().
weightIndex = static_cast<int>(i);
// The requested label has been found, so the loop can stop.
break;
}
}
// If weightIndex is still -1 after the loop,
// the requested label was not present in weightNames.
if (weightIndex < 0) {
return -1.0;
}
// Get the EventHeader from the EventHeader collection.
// There is normally one EventHeader object per event, so its index is 0.
const auto& eventHeader = eventHeaders.at(0);
// Extract all numerical weights from this event's EventHeader.
const auto eventWeights = eventHeader.getWeights();
// getWeights() is an EDM4hep function that gets all weights stored in this EventHeader.
// Convert the valid weightIndex from int to std::size_t because array positions and .size() use std::size_t, then store it in index. It was initially declared as int
const auto index = static_cast<std::size_t>(weightIndex);
// The label may exist, but the current event may contain fewer numerical
// weights than expected. In that case, the index would be invalid.
if (index >= eventWeights.size()) {
return -1.0;
}
// Return the numerical event weight at the same index as the requested label.
return eventWeights[index];
}
};
#endif