Jpp  debug
the software that should make you happy
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 
31 namespace {
32 
33  using JLANG::JException;
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;
52  typedef JRange<double> JRange_t;
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) {
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,
148  JEvtWeightFileScanner<>& scanner,
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,
209  JEvtWeightFileScanner<>& second,
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  */
360 int 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.
Definition: JException.hh:712
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:2158
TString replace(const TString &target, const TRegexp &regexp, const T &replacement)
Replace regular expression in input by given replacement.
Definition: JPrintResult.cc:63
I/O formatting auxiliaries.
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:136
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:127
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
const JHead & getHeader() const
Get header.
Definition: JHead.hh:1270
JAANET::genvol genvol
Definition: JHead.hh:1600
size_t getNumberOfMatches(const JHead &header) const
Get number of matching fields.
Definition: JHead.hh:1460
General exception.
Definition: JException.hh:24
virtual bool put(const T &object)=0
Object output.
Exception for accessing a value in a collection that is outside of its range.
Definition: JException.hh:180
Utility class to parse command line options.
Definition: JParser.hh:1714
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.
Definition: JeepToolkit.hh:128
T * open(const std::string &file_name)
Open file.
Definition: JeepToolkit.hh:351
std::ostream & separator(std::ostream &out)
Print separator.
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
Definition: JSTDTypes.hh:14
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.
Type list.
Definition: JTypeList.hh:23
Auxiliary class for organising Monte Carlo file scanners associated with event weighters.
std::vector< filescanner_type >::iterator iterator
std::string getUniqueIdentifier(const_iterator p) const
Get unique identifier for a file-scanner contained within this set of event-weighter-associated file-...
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