Jpp master_rocky-44-g75b7c4f75
the software that should make you happy
Loading...
Searching...
No Matches
JSeparateCuts.cc
Go to the documentation of this file.
1#include <iostream>
2#include <iomanip>
3#include <string>
4#include <vector>
5#include <set>
6#include <stdio.h>
7
11
12#include "Jeep/JPrint.hh"
13#include "Jeep/JParser.hh"
14#include "Jeep/JMessage.hh"
15#include "Jeep/JeepToolkit.hh"
16
17#include "JLang/JException.hh"
18
19#include "JTools/JRange.hh"
20
21#include "JSupport/JMeta.hh"
22#include "JSupport/JSupport.hh"
27
28#include "JAAnet/JHead.hh"
29
30
31namespace {
32
35
36 using JTOOLS::JRange;
37
38 using JAANET::cut;
39
43
44
45 /**
46 * Auxiliary class containing methods for separating a collection of Monte-Carlo files\n
47 * into output files which are disjoint with respect to a specifiable JAANET::cut header-field.
48 */
49 struct JSeparateCuts
50 {
51 typedef typename JTYPELIST<Head, JMeta, Evt>::typelist typelist;
53
54 /**
55 * Default constructor.
56 */
57 JSeparateCuts() :
58 filenameTemplate("cut%.root"),
59 wildcard ('%')
60 {
61 pos = filenameTemplate.find(wildcard);
62 }
63
64
65 /**
66 * Constructor.
67 *
68 * \param templateName file-name template; must contain wildcard
69 * \param wc wildcard character
70 * \param metaInfo meta-information
71 */
72 JSeparateCuts(const std::string& templateName,
73 const char wc,
74 const JMeta& metaInfo = JMeta()) :
75 meta (metaInfo),
76 filenameTemplate(templateName),
77 wildcard (wc)
78 {
79 if (filenameTemplate.find(wildcard) == std::string::npos) {
80 THROW(JException,
81 "JSeparateCuts::JSeparateCuts(): Given file-name template \"" << filenameTemplate <<
82 "\" does not contain specified wildcard \'" << wildcard << "\'.");
83 }
84
85 pos = filenameTemplate.find(wildcard);
86 }
87
88
89 /*
90 * Separate two cuts into a vector of fully disjoint, non-overlapping cuts.
91 *
92 * \param first first cut
93 * \param second second cut
94 * \return vector of disjoint cuts
95 */
96 std::vector<cut> separate(const cut& first, const cut& second) const {
97
98 using namespace std;
99 using namespace JPP;
100
101 vector<cut> out;
102
103 const set<double> Ebounds { first .E.getLowerLimit(), first .E.getUpperLimit(),
104 second.E.getLowerLimit(), second.E.getUpperLimit() };
105
106 const set<double> cosTbounds{ first .cosT.getLowerLimit(), first .cosT.getUpperLimit(),
107 second.cosT.getLowerLimit(), second.cosT.getUpperLimit() };
108
109 for (set<double>::const_iterator Ebound = next(Ebounds.cbegin()); Ebound != Ebounds.cend(); ++Ebound) {
110
111 const JRange_t E(*prev(Ebound), *Ebound);
112
113 // Check if given energy range appears in only one or in both cuts
114
115 const bool overlap1 = overlap(E, first .E);
116 const bool overlap2 = overlap(E, second.E);
117
118 if (overlap1 && overlap2) { // Loop through all disjoint cosine zenith angle ranges
119
120 for (set<double>::const_iterator cosTbound = next(cosTbounds.cbegin()); cosTbound != cosTbounds.cend(); ++cosTbound) {
121 out.push_back(cut(*prev(Ebound), *Ebound, *prev(cosTbound), *cosTbound));
122 }
123
124 } else if (overlap1) { // Use first cosine zenith angle range
125
126 out.push_back(cut(*prev(Ebound), *Ebound, first.cosT.getLowerLimit(), first.cosT.getUpperLimit()));
127
128 } else if (overlap2) { // Use second cosine zenith angle range
129
130 out.push_back(cut(*prev(Ebound), *Ebound, second.cosT.getLowerLimit(), second.cosT.getUpperLimit()));
131 }
132 }
133
134 return out;
135 }
136
137
138 /**
139 * Extract all events in the given file corresponding to a given cut\n
140 * and append them to the given file-recorder.
141 *
142 * \param recorder file-recorder
143 * \param scanner file-scanner
144 * \param cut JAANET::cut object
145 * \return number of extracted events
146 */
147 size_t extract(JFileRecorder<typelist>& recorder,
149 const cut& cut) const
150 {
151 using namespace std;
152
153 const bool open = recorder.is_open();
154 if (!open) { recorder.open(); }
155 scanner.rewind();
156
157 size_t n = 0;
158
159 while (scanner.hasNext()) {
160
161 const Evt* event = scanner.next();
162
163 if (event != NULL && !event->mc_trks.empty()) {
164
165 double E = 0.0;
166 double costh = 0.0;
167 double Nprimaries = 0.0;
168
169 for (vector<Trk>::const_iterator trk = event->mc_trks.cbegin(); trk != event->mc_trks.cend(); ++trk) {
170
171 if (trk->status == TRK_ST_PRIMARYNEUTRINO ||
172 trk->status == TRK_ST_PRIMARYCOSMIC) {
173
174 E += trk->E;
175 costh += trk->dir.z;
176
177 ++Nprimaries;
178 }
179 }
180
181 costh /= Nprimaries;
182
183 if (cut.E(E) && cut.cosT(costh)) {
184 recorder.put(*event);
185 ++n;
186 }
187 }
188 }
189
190 if (!open) { recorder.close(); }
191 scanner.rewind();
192
193 return n;
194 }
195
196
197 /**
198 * Separate two file-scanners into disjoint output files which do not overlap in the given cut data member.\n
199 * The separation will only proceed if the given cut data member is the only other mismatching header-field\n
200 * other than JHead::spectrum.
201 *
202 * \param first first file-scanner
203 * \param second second file-scanner
204 * \param pd pointer to JAANET::JHead data member derived from JAANET::cut
205 * \return number of extracted disjoing output files
206 */
207 template<class T>
208 size_t separate(JEvtWeightFileScanner<>& first,
210 T JHead::* pd)
211 {
212 using namespace std;
213
214 typedef typename JTYPELIST<Head, JMeta, Evt>::typelist typelist;
215
216 const JHead& header0 = first .getHeader();
217 const JHead& header1 = second.getHeader();
218
219 // Check if given data member and the spectrum data member correspond to the only mismatching header-fields
220
221 const size_t N = JHead::getMaximumNumberOfMatches() - (header0.spectrum.match(header1.spectrum) ? 1 : 2);
222
223 if (!((header0.*pd).match(header1.*pd)) && header0.getNumberOfMatches(header1) == N) {
224
225 vector<cut> cuts = separate(header0.*pd, header1.*pd);
226
227 for (vector<cut>::iterator cut = cuts.begin(); cut != cuts.end(); ++cut) {
228
229 // Open new file-recorder
230
231 const string outputFilename = string(filenameTemplate).replace(pos, 1, MAKE_CSTRING(distance(cuts.begin(), cut)));
232
233 JFileRecorder<typelist> recorder(outputFilename.c_str());
234
235 // Write header and meta-information
236
237 JHead header2(header0);
238
239 (header2.*pd).E = cut->E;
240 (header2.*pd).cosT = cut->cosT;
241
242 header2.genvol.numberOfEvents += header1.genvol.numberOfEvents;
243
244 Head head;
245 copy(header2, head);
246
247 recorder.open();
248 recorder.put(head);
249 recorder.put(meta);
250
251 for (JMultipleFileScanner<JMeta> in(first.getFilelist()); in.hasNext(); ) {
252 recorder.put(*in.next());
253 }
254
255 for (JMultipleFileScanner<JMeta> in(second.getFilelist()); in.hasNext(); ) {
256 recorder.put(*in.next());
257 }
258
259 // Write events that are compatible with the cut
260
261 extract(recorder, first, *cut);
262 extract(recorder, second, *cut);
263
264 recorder.close();
265 }
266
267 return cuts.size();
268
269 } else {
270
271 return 0;
272 }
273 }
274
275
276 /**
277 * Set filename template.
278 *
279 * \param _filenameTemplate
280 */
281 void setFilenameTemplate(const std::string& _filenameTemplate)
282 {
283 std::size_t p = _filenameTemplate.find(wildcard);
284
285 if (p != std::string::npos) {
286
287 this->filenameTemplate = _filenameTemplate;
288 this->pos = p;
289
290 } else {
291
292 THROW(JValueOutOfRange, "JSeparateCuts::setFilenameTemplate(): Given filename template " << filenameTemplate << " does not contain wildcard " << wildcard);
293 }
294 }
295
296
297 /**
298 * Set wildcard character.
299 *
300 * \param wildcard wildcard character
301 */
302 void setWildcard(const char wc)
303 {
304 std::size_t p = this->filenameTemplate.find(wc);
305
306 if (p != std::string::npos) {
307
308 this->wildcard = wc;
309 this->pos = p;
310
311 } else {
312
313 THROW(JValueOutOfRange, "JSeparateCuts::setWildcard(): Given wildcard character " << wildcard << " is not contained in current filename template " << this->filenameTemplate);
314 }
315 }
316
317
318 /**
319 * Get filename template.
320 *
321 * \return filename template
322 */
323 const std::string& getFilenameTemplate()
324 {
325 return filenameTemplate;
326 }
327
328
329 /**
330 * Get wildcard character.
331 *
332 * \return wildcard character
333 */
334 const char getWildcard()
335 {
336 return wildcard;
337 }
338
339
340 JMeta meta; ///!< Meta-data
341
342 private:
343
344 std::string filenameTemplate; ///!< file-name template
345 char wildcard; ///!< wildcard character
346 size_t pos; ///!< position of wildcard in file-name template
347 };
348}
349
350
351/**
352 * \file
353 * Program for extracting disjoint output files without overlapping cuts\n
354 * from a list of Monte-Carlo files with overlapping cuts.
355 *
356 * Note: Already existing disjoint output files which have been extracted previously will be overwritten.
357 *
358 * \author bjung
359 */
360int main(int argc, char **argv)
361{
362 using namespace std;
363 using namespace JPP;
364
365 JMultipleFileScanner_t inputFiles;
366 string outputFile;
367 char wildcard;
368 bool replace;
369
370 int debug;
371
372 try {
373
374 JParser<> zap;
375
376 zap['f'] = make_field(inputFiles);
377 zap['o'] = make_field(outputFile) = "%.root";
378 zap['w'] = make_field(wildcard) = '%';
379 zap['r'] = make_field(replace);
380 zap['d'] = make_field(debug) = 1;
381
382 zap(argc, argv);
383 }
384 catch(const exception& error) {
385 FATAL(error.what() << endl);
386 }
387
388 const size_t pos = outputFile.find(wildcard);
389
390 if (pos == string::npos) {
391 FATAL("Valid wildcard must be specified (<" << outputFile << "> does not contain \'" << wildcard << "\').");
392 }
393
394
395 // Create set of files ordered based on header-info
396
397 JEvtWeightFileScannerSet<> scanners(inputFiles);
398
399 // Split files with overlapping cuts into separate files with disjoint cuts.
400
401 set<string> buffer;
402 JSeparateCuts separator(outputFile, wildcard, JMeta(argc, argv));
403
404 for (JEvtWeightFileScannerSet<>::iterator scanner1 = next(scanners.begin()); scanner1 != scanners.end(); ++scanner1) {
405
406 JEvtWeightFileScannerSet<>::iterator scanner0 = prev(scanner1);
407
408 if (scanner0->hasNext() && scanner1->hasNext()) {
409
410 const string identifier = scanners.getUniqueIdentifier(scanner0) + MAKE_STRING(".cut" << wildcard);
411 const string name = string(outputFile).replace(pos, 1, identifier.c_str());
412
413 separator.setFilenameTemplate(name);
414
415 const size_t N = (separator.separate(*scanner0, *scanner1, &JHead::cut_primary) +
416 separator.separate(*scanner0, *scanner1, &JHead::cut_seamuon) +
417 separator.separate(*scanner0, *scanner1, &JHead::cut_in) +
418 separator.separate(*scanner0, *scanner1, &JHead::cut_nu));
419
420 STATUS("\rExtracted " << N << " output files with" <<
421 " disjoint cuts for " << getFilename(scanner0->getFilename()) <<
422 " and " << getFilename(scanner1->getFilename())); DEBUG(endl);
423
424 if (N > 0) {
425
426 buffer.insert(scanner0->getFilename());
427 buffer.insert(scanner1->getFilename());
428 }
429 }
430 }
431
432 for (set<string>::const_iterator i = buffer.begin(); replace && i != buffer.end(); ++i) {
433
434 if (remove(i->c_str()) != 0) {
435 FATAL(endl << "Error removing file " << *i);
436 } else {
437 NOTICE(endl << "Removing file " << *i);
438 }
439 }
440
441 return 0;
442}
string outputFile
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Recording of objects on file according a format that follows from the file name extension.
General purpose messaging.
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
#define STATUS(A)
Definition JMessage.hh:63
#define NOTICE(A)
Definition JMessage.hh:64
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:69
ROOT I/O of application specific meta data.
Scanning of objects from multiple files according a format that follows from the extension of each fi...
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
I/O formatting auxiliaries.
#define MAKE_CSTRING(A)
Make C-string.
Definition JPrint.hh:72
#define MAKE_STRING(A)
Make string.
Definition JPrint.hh:63
Auxiliary class to define a range between two values.
int main(int argc, char **argv)
ROOT TTree parameter settings of various packages.
Auxiliary methods for handling file names, type names and environment.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Monte Carlo run header.
Definition JHead.hh:1236
JAANET::spectrum spectrum
Definition JHead.hh:1597
JAANET::cut_in cut_in
Definition JHead.hh:1595
JAANET::cut_nu cut_nu
Definition JHead.hh:1596
const JHead & getHeader() const
Get header.
Definition JHead.hh:1270
JAANET::genvol genvol
Definition JHead.hh:1600
JAANET::cut_seamuon cut_seamuon
Definition JHead.hh:1594
static const size_t getMaximumNumberOfMatches()
Get maximum number of matching header fields.
Definition JHead.hh:1621
size_t getNumberOfMatches(const JHead &header) const
Get number of matching fields.
Definition JHead.hh:1460
JAANET::cut_primary cut_primary
Definition JHead.hh:1593
General exception.
Definition JException.hh:24
Exception for accessing a value in a collection that is outside of its range.
Utility class to parse command line options.
Definition JParser.hh:1698
Object writing to file.
virtual void open(const char *file_name) override
Open file.
General purpose class for object reading from a list of file names.
virtual void rewind() override
Rewind.
virtual bool hasNext() override
Check availability of next element.
virtual const pointer_type & next() override
Get next element.
Range of values.
Definition JRange.hh:42
T getLowerLimit() const
Get lower limit.
Definition JRange.hh:202
T getUpperLimit() const
Get upper limit.
Definition JRange.hh:213
void copy(const Head &from, JHead &to)
Copy header from from to to.
Definition JHead.cc:162
std::string getFilename(const std::string &file_name)
Get file name part, i.e. part after last JEEP::PATHNAME_SEPARATOR if any.
T * open(const std::string &file_name)
Open file.
std::ostream & separator(std::ostream &out)
Print separator.
std::string replace(const std::string &input, const std::string &target, const std::string &replacement)
Replace tokens in string.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
bool overlap(const JRange< T, JComparator_t > &first, const JRange< T, JComparator_t > &second)
Test overlap between ranges.
Definition JRange.hh:641
const int n
Definition JPolint.hh:786
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition Evt.hh:21
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
Definition Head.hh:65
Type definition of range.
Definition JHead.hh:43
General purpose class of phase space generation.
Definition JHead.hh:341
JRange_t cosT
Cosine zenith angle range
Definition JHead.hh:420
JRange_t E
Energy range [GeV].
Definition JHead.hh:419
double numberOfEvents
Number of events.
Definition JHead.hh:721
bool match(const spectrum &object) const
Test match.
Definition JHead.hh:561
virtual void close() override
Close device.
virtual bool is_open() const override
Check is device is open.
virtual bool put(const T &object) override
Object output.
Type list.
Definition JTypeList.hh:23
Auxiliary class for organising Monte Carlo file scanners associated with event weighters.
std::string getUniqueIdentifier(const_iterator p) const
Get unique identifier for a file-scanner contained within this set of event-weighter-associated file-...
std::vector< filescanner_type >::iterator iterator
Template event-weighter-associated file scanner.
Auxiliary class for ROOT I/O of application specific meta data.
Definition JMeta.hh:72
Auxiliary base class for list of file names.
static const int TRK_ST_PRIMARYCOSMIC
initial state cosmic ray ('track_primary' tag in evt files from corant).
Definition trkmembers.hh:17
static const int TRK_ST_PRIMARYNEUTRINO
initial state neutrino ('neutrino' tag in evt files from gseagen and genhen).
Definition trkmembers.hh:16