Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JEditDetector.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <sstream>
3 #include <string>
4 #include <vector>
5 
6 #include "TRandom3.h"
7 
8 #include "JDetector/JDetector.hh"
13 #include "JGeometry3D/JVector3D.hh"
14 #include "JTools/JConstants.hh"
15 #include "JTools/JRange.hh"
16 #include "JLang/JException.hh"
17 #include "JSupport/JMeta.hh"
18 
19 #include "Jeep/JeepToolkit.hh"
20 #include "Jeep/JPrint.hh"
21 #include "Jeep/JParser.hh"
22 #include "Jeep/JMessage.hh"
23 
24 
25 namespace {
26 
27  using namespace JPP;
28 
29  /**
30  * Wild card for string identifier, module identifier or PMT address.
31  */
32  static const int WILD_CARD = -1;
33 
34  static const std::string reset_t = "reset"; //!< Reset time offset, position and orientation or PMT status bit
35  static const std::string set_t = "set"; //!< Set time offset or position or PMT status bit
36  static const std::string add_t = "add"; //!< Add time offset or position
37  static const std::string sub_t = "sub"; //!< Subtract time offset or position
38  static const std::string rot_t = "rot"; //!< Rotate around z-axis by value [rad]
39  static const std::string mul_t = "mul"; //!< Multiply z-position by (1 + value)
40  static const std::string via_t = "via"; //!< Apply time offset by (floor * value)
41  static const std::string assign_t = "="; //!< Assign identifier
42 
43  static const std::string rand_t = "rand"; //!< Random value(s)
44  static const std::string randset_t = rand_t + set_t; //!< Set time offset or position
45  static const std::string randadd_t = rand_t + add_t; //!< Add time offset or position
46  static const std::string randsub_t = rand_t + sub_t; //!< Subtract time offset or position
47  static const std::string randrot_t = rand_t + rot_t; //!< Rotate around z-axis by value [rad]
48  static const std::string randmul_t = rand_t + mul_t; //!< Multiply z-position by (1 + value)
49  static const std::string randvia_t = rand_t + via_t; //!< Apply time offset by (floor * value)
50 
51 
52  /**
53  * Auxiliary class to apply detector modifications.
54  *
55  * Note that the internal identifier may apply to a module as well as a string.
56  */
57  class JModifier {
58  public:
59  /**
60  * Default constructor.
61  */
62  JModifier()
63  {}
64 
65 
66  /**
67  * Check validity.
68  *
69  * \return true if valid modifier; else false
70  */
71  bool is_valid() const
72  {
73  return (action != "" && !data.empty());
74  }
75 
76 
77  /**
78  * Apply modification to given module.
79  *
80  * \param module module
81  * \return true if valid action; else false
82  */
83  bool apply(JModule& module) const
84  {
85  switch (data.size()) {
86 
87  case 0:
88  return apply(module, action); // reset calibration
89 
90  case 1:
91  return apply(module, action, data[0]); // time/position/orientation calibration
92 
93  case 2:
94  return apply(module, action, JVector3D(data[0], data[1], 0.0)); // 2D position calibration
95 
96  case 3:
97  return apply(module, action, JVector3D(data[0], data[1], data[2])); // 3D position calibration
98 
99  default:
100  return false;
101  }
102  }
103 
104 
105  /**
106  * Read modifier from input.
107  *
108  * \param in input stream
109  * \param modifier modifier
110  * \return input stream
111  */
112  friend inline std::istream& operator>>(std::istream& in, JModifier& modifier)
113  {
114  using namespace std;
115 
116  if (in >> modifier.id >> modifier.action) {
117 
118  modifier.data.clear();
119 
120  for (double x; in >> x; ) {
121  modifier.data.push_back(x);
122  }
123 
124  in.clear(ios_base::eofbit);
125  }
126 
127  return in;
128  }
129 
130 
131  /**
132  * Write modifier to output.
133  *
134  * \param out output stream
135  * \param modifier modifier
136  * \return output stream
137  */
138  friend inline std::ostream& operator<<(std::ostream& out, const JModifier& modifier)
139  {
140  out << modifier.id;
141  out << ' ';
142  out << modifier.action;
143 
144  for (std::vector<double>::const_iterator i = modifier.data.begin(); i != modifier.data.end(); ++i) {
145  out << ' ' << *i;
146  }
147 
148  return out;
149  }
150 
151 
152  int id;
153  std::string action;
154  std::vector<double> data;
155 
156  private:
157 
158  /**
159  * Apply time/orientation calibration to given module.
160  *
161  * \param module module
162  * \param action action
163  * \return true if valid action; else false
164  */
165  static bool apply(JModule& module, const std::string& action)
166  {
167  if (action == reset_t) {
168 
170 
171  for (JModule::iterator pmt = module.begin(); pmt != module.end(); ++pmt) {
172  pmt->setCalibration(JCalibration());
173  }
174 
175  } else {
176 
177  return false;
178  }
179 
180  return true;
181  }
182 
183 
184  /**
185  * Apply time/position/orientation calibration to given module.
186  *
187  * \param module module
188  * \param action action
189  * \param value value
190  * \return true if valid action; else false
191  */
192  static bool apply(JModule& module, const std::string& action, const double value)
193  {
194  if (action == set_t) { // actions with fixed values
195 
196  module.set(value);
197 
198  } else if (action == add_t) {
199 
200  module.add(value);
201 
202  } else if (action == sub_t) {
203 
204  module.sub(value);
205 
206  } else if (action == rot_t) {
207 
208  const JVector3D center = module.getPosition();
209 
210  module.sub(center);
211 
212  module.rotate(JRotation3Z(value));
213 
214  module.add(center);
215 
216  } else if (action == mul_t) {
217 
218  const JVector3D center(module.getPosition().getX(),
219  module.getPosition().getY(),
220  module.getPosition().getZ() * (1.0 + value));
221 
222  module.set(center);
223 
224  } else if (action == via_t) {
225 
226  module.add(value * module.getFloor());
227 
228  } else if (action == randadd_t) { // actions with random values
229 
230  module.add(gRandom->Gaus(0.0, value));
231 
232  } else if (action == randsub_t) {
233 
234  module.sub(gRandom->Gaus(0.0, value));
235 
236  } else if (action == randrot_t){
237 
238  const JVector3D center = module.getPosition();
239 
240  module.sub(center);
241 
242  module.rotate(JRotation3Z(gRandom->Gaus(0.0, value)));
243 
244  module.add(center);
245 
246  } else if (action == randmul_t) {
247 
248  const JVector3D center(module.getPosition().getX(),
249  module.getPosition().getY(),
250  module.getPosition().getZ() * gRandom->Gaus(1.0, value));
251 
252  module.set(center);
253 
254  } else if (action == randvia_t) {
255 
256  module.add(gRandom->Gaus(0.0, value) * module.getFloor());
257 
258  } else if (action == assign_t) {
259 
260  module.setID((int) value);
261 
262  } else {
263 
264  return false;
265  }
266 
267  return true;
268  }
269 
270 
271  /**
272  * Apply position calibration to given module.
273  *
274  * \param module module
275  * \param action action
276  * \param pos pos
277  * \return true if valid action; else false
278  */
279  static bool apply(JModule& module, const std::string& action, const JVector3D& pos)
280  {
281  const JVector3D randpos(gRandom->Gaus(0.0, pos.getX()),
282  gRandom->Gaus(0.0, pos.getY()),
283  gRandom->Gaus(0.0, pos.getZ()));
284 
285  if (action == set_t) // actions with fixed values
286  module.set(pos);
287  else if (action == add_t)
288  module.add(pos);
289  else if (action == sub_t)
290  module.sub(pos);
291  else if (action == randset_t) // actions with random values
292  module.set(randpos);
293  else if (action == randadd_t)
294  module.add(randpos);
295  else if (action == randsub_t)
296  module.sub(randpos);
297  else
298  return false;
299 
300  return true;
301  }
302  };
303 
304 
305  /**
306  * Get modifier for given string.
307  *
308  * \param id string identifier
309  * \param modifier modifier
310  * \return modifier
311  */
312  inline const JModifier& getModifier(const int id, const JModifier& modifier)
313  {
314  using namespace std;
315 
317 
318  const string::size_type pos = modifier.action.find(rand_t);
319 
320  if (pos != string::npos) {
321 
322  JModifier& result = buffer[id][modifier.action][modifier.data.size()];
323 
324  if (!result.is_valid()) {
325 
326  result.id = id;
327  result.action = modifier.action.substr(pos + rand_t.length());
328 
329  for (size_t i = 0; i != modifier.data.size(); ++i) {
330  result.data.push_back(gRandom->Gaus(0.0, modifier.data[i]));
331  }
332  }
333 
334  return result;
335 
336  } else {
337 
338  return modifier;
339  }
340  }
341 
342 
343  /**
344  * Auxiliary class to apply PMT status modifications.
345  */
346  class JPMTModifier :
347  public JPMTIdentifier
348  {
349  public:
350  /**
351  * Default constructor.
352  */
353  JPMTModifier()
354  {}
355 
356 
357  /**
358  * Apply modification to given PMT.
359  *
360  * \param pmt PMT
361  * \return true if valid action; else false
362  */
363  bool apply(JPMT& pmt) const
364  {
365  try {
366 
367  if (action == set_t) {
368 
369  pmt.set(getPMTStatusBit(value));
370 
371  } else if (action == reset_t) {
372 
373  pmt.reset(getPMTStatusBit(value));
374 
375  } else {
376 
377  return false;
378  }
379 
380  return true;
381  }
382  catch(const std::exception&) {}
383 
384  return false;
385  }
386 
387 
388  /**
389  * Read PMT modifier from input.
390  *
391  * \param in input stream
392  * \param modifier modifier
393  * \return input stream
394  */
395  friend inline std::istream& operator>>(std::istream& in, JPMTModifier& modifier)
396  {
397  return in >> static_cast<JPMTIdentifier&>(modifier) >> modifier.action >> modifier.value;
398  }
399 
400 
401  /**
402  * Write modifier to output.
403  *
404  * \param out output stream
405  * \param modifier modifier
406  * \return output stream
407  */
408  friend inline std::ostream& operator<<(std::ostream& out, const JPMTModifier& modifier)
409  {
410  out << static_cast<const JPMTIdentifier&>(modifier);
411  out << ' ';
412  out << modifier.action;
413  out << ' ';
414  out << modifier.value;
415 
416  return out;
417  }
418 
419 
420  int id;
421  std::string action;
422  std::string value;
423  };
424 
425 
426  /**
427  * Range of identifiers.
428  */
429  struct JRange_t :
430  public JRange<int> {
431  /**
432  * Separator between two identifier values.
433  */
434  static const char SEPARATOR = '-';
435 
436  /**
437  * Default constructor.
438  */
439  JRange_t() :
440  JRange(-1, -1)
441  {}
442 
443 
444  /**
445  * Read range from input.
446  *
447  * \param in input stream
448  * \param range range
449  * \return input stream
450  */
451  friend inline std::istream& operator>>(std::istream& in, JRange_t& range)
452  {
453  if (in >> range.first) {
454  if (in.get() != (int) JRange_t::SEPARATOR || ! (in >> range.second)) {
455  in.setstate(std::ios::badbit);
456  }
457  }
458 
459  return in;
460  }
461 
462 
463  /**
464  * Write range to output.
465  *
466  * \param out output stream
467  * \param range range
468  * \return output stream
469  */
470  friend inline std::ostream& operator<<(std::ostream& out, const JRange_t& range)
471  {
472  return out << range.first << JRange_t::SEPARATOR << range.second;
473  }
474  };
475 }
476 
477 
478 /**
479  * \file
480  *
481  * Auxiliary program to modify detector calibration.
482  *
483  * Syntax:
484  * <pre>
485  * -M "<module identifier> (set|add|sub|randset|randadd|randsub) x0 [x1 [x2]]"
486  * -S "<string number> (set|add|sub|randset|randadd|randsub) x0 [x1 [x2]]"
487  * -M "<module identifier> (rot|randrot) phi"
488  * -S "<string number> (rot|randrot) phi"
489  * -M "<module identifier> (mul|randmul) factor"
490  * -S "<string number> (mul|randmul) factor"
491  * -M "<module identifier> (via|randvia) factor"
492  * -S "<string number> (via|randvia) factor"
493  * -M "<module identifier> (reset)
494  * -S "<string number> (reset)
495  * -M "<module identifier> = identifier"
496  * -P "<PMT identifier> (set|reset) (PMT_DISABLE|HIGH_RATE_VETO_DISABLE|FIFO_FULL_DISABLE|UDP_COUNTER_DISABLE|UDP_TRAILER_DISABLE)"
497  * -k "<string number>[-<string number>"
498  * -r "<string number>[-<string number>"
499  * -\@ "<key>=<value>[;<key>=<value>"
500  * </pre>
501  * Options <tt>-M</tt> and <tt>-S</tt> refer to a module and a string, respectively.\n
502  * The values provided for a string modification coherently apply to the specified string number.
503  *
504  * The options <tt>randXXX</tt> correspond to a randomisation of the specified option.
505  *
506  * If the module identifier or string number is -1,
507  * the action is applied to all modules or strings in the detector, respectively.
508  *
509  * For options <tt>[rand]set [rand]add [rand]sub</tt>,
510  * the number of values apply to position or time calibration in the following way:
511  * -# time calibration <tt>(t = x0)</tt>
512  * -# position calibration <tt>(x = x0, y = x1, z = 0)</tt>
513  * -# position calibration <tt>(x = x0, y = x1, z = x2)</tt>
514  *
515  * For options <tt>[rand]rot</tt>,
516  * the angle <tt>phi</tt> refers to an anti-clockwise rotation around the z-axis.\n
517  * The rotation angle is defined in radians.
518  *
519  * For options <tt>[rand]mul</tt>,
520  * the multiplication <tt>factor</tt> applies to the z-coordinates.\n
521  * This factor is defined as a fraction; the actual multiplication factor is <tt>(1 + factor)</tt>.
522  *
523  * For options <tt>[rand]via</tt>,
524  * The <tt>factor</tt> applies to the time calibration as a function of floor number.
525  *
526  * Note that for string modifiers with option <tt>randxxx</tt>,
527  * the action is coherently applied to the modules in the specified string.
528  * Only one type of action (defined by <tt>xxx</tt> and the number of values) is then allowed per string.
529  *
530  * Option <tt>-\@</tt> refers to the header information.\n
531  * The list of possible keys can be obtained using JPrintDetector.cc with option <tt>-O header</tt>.
532  *
533  * Multiple options <tt>-M</tt>, <tt>-S</tt> or <tt>-\@</tt> will be processed in order of appearance.
534  *
535  * Options <tt>-k</tt> and <tt>-r</tt> can be used to keep and remove a range of string numbers, respectively.
536  *
537  * Note that if the output file name is the same as the input file name,
538  * the original file will be overwritten.
539  * \author mdejong
540  */
541 int main(int argc, char **argv)
542 {
543  using namespace std;
544  using namespace JPP;
545 
546  string inputFile;
547  string outputFile;
548  vector<JModifier> mod;
549  vector<JModifier> str;
550  vector<string> hdr;
552  vector<JRange_t> keep;
553  vector<JRange_t> rm;
554  int debug;
555 
556  try {
557 
558  JParser<> zap("Auxiliary program to modify detector.");
559 
560  zap['a'] = make_field(inputFile);
561  zap['M'] = make_field(mod) = JPARSER::initialised();
562  zap['S'] = make_field(str) = JPARSER::initialised();
563  zap['@'] = make_field(hdr) = JPARSER::initialised();
564  zap['P'] = make_field(pmt) = JPARSER::initialised();
565  zap['o'] = make_field(outputFile);
566  zap['k'] = make_field(keep) = JPARSER::initialised();
567  zap['r'] = make_field(rm) = JPARSER::initialised();
568  zap['d'] = make_field(debug) = 2;
569 
570  zap(argc, argv);
571  }
572  catch(const exception &error) {
573  FATAL(error.what() << endl);
574  }
575 
577 
578  try {
579  load(inputFile, detector);
580  }
581  catch(const JException& error) {
582  FATAL(error);
583  }
584 
585 
586  gRandom->SetSeed(0);
587 
588 
589  if (!keep.empty() && !rm.empty()) {
590  FATAL("Use either option -k or -r." << endl);
591  }
592 
593 
594  detector.comment.add(JMeta(argc,argv));
595 
596  if (!pmt.empty()) {
597 
598  if (detector.setVersion(JDetectorVersion::V3)) {
599  NOTICE("Set detector version to " << JDetectorVersion::V3 << endl);
600  }
601  }
602 
603  if (!hdr.empty()) {
604 
605  JProperties helper = detector.getProperties();
606 
607  for (vector<string>::const_iterator i = hdr.begin(); i != hdr.end(); ++i) {
608 
609  istringstream is(*i);
610 
611  is >> helper;
612  }
613  }
614 
615 
616  for (JDetector::iterator module = detector.begin(); module != detector.end(); ) {
617 
618  bool __rm__ = !keep.empty() && rm.empty();
619 
620  for (vector<JRange_t>::const_iterator i = keep.begin(); i != keep.end(); ++i) {
621  if (module->getString() >= i->first && module->getString() <= i->second) {
622  __rm__ = false;
623  }
624  }
625 
626  for (vector<JRange_t>::const_iterator i = rm.begin(); i != rm.end(); ++i) {
627  if (module->getString() >= i->first && module->getString() <= i->second) {
628  __rm__ = true;
629  }
630  }
631 
632  if (__rm__)
633  module = detector.erase(module);
634  else
635  ++module;
636  }
637 
638 
639  for (vector<JModifier>::const_iterator i = mod.begin(); i != mod.end(); ++i) {
640 
641  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
642 
643  if (module->getID() == i->id || i->id == WILD_CARD ){
644 
645  DEBUG("Modifier" << ' '
646  << "(" << setw(3) << module->getString() << "," << setw(2) << module->getFloor() << ")" << ' '
647  << setw(8) << module->getID() << ' '
648  << "action" << ' ' << i->action << JEEPZ() << i->data << endl);
649 
650  if (!i->apply(*module)) {
651  ERROR("No valid action: " << *i << endl);
652  }
653  }
654  }
655  }
656 
657 
658  for (vector<JModifier>::const_iterator i = str.begin(); i != str.end(); ++i) {
659 
660  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
661 
662  if (module->getString() == i->id || i->id == WILD_CARD) {
663 
664  const JModifier& modifier = getModifier(module->getString(), *i);
665 
666  DEBUG("Modifier" << ' '
667  << "(" << setw(3) << module->getString() << "," << setw(2) << module->getFloor() << ")" << ' '
668  << setw(8) << module->getID() << ' '
669  << "action" << ' ' << modifier.action << JEEPZ() << modifier.data << endl);
670 
671  if (!modifier.apply(*module)) {
672  ERROR("No valid action: " << *i << endl);
673  }
674  }
675  }
676  }
677 
678 
679  for (vector<JPMTModifier>::const_iterator i = pmt.begin(); i != pmt.end(); ++i) {
680 
681  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
682 
683  if (module->getID() == i->getModuleID() || i->getModuleID() == WILD_CARD) {
684 
685  DEBUG("PMT modifier" << ' '
686  << "(" << setw(8) << module->getID() << "," << setw(2) << i->getPMTAddress() << ")" << ' '
687  << "action" << ' ' << i->action << ' '
688  << "value" << ' ' << i->value << endl);
689 
690  if (i->getPMTAddress() == WILD_CARD) {
691 
692  for (int pmt = 0; pmt != getNumberOfPMTs(*module); ++pmt) {
693  if (!i->apply(module->getPMT(pmt))) {
694  ERROR("No valid action: " << *i << endl);
695  }
696  }
697 
698  } else if (i->getPMTAddress() < 0 ||
699  i->getPMTAddress() >= getNumberOfPMTs(*module) ||
700  !i->apply(module->getPMT(i->getPMTAddress()))) {
701  ERROR("No valid action: " << *i << endl);
702  }
703  }
704  }
705  }
706 
707  try {
709  }
710  catch(const JException& error) {
711  FATAL(error);
712  }
713 }
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:71
Utility class to parse command line options.
Definition: JParser.hh:1493
General exception.
Definition: JException.hh:23
static const JGetPMTStatusBit getPMTStatusBit
Function object to map key to PMT status bit.
Definition: JStatus.hh:292
Exceptions.
int getFloor() const
Get floor number.
Definition: JLocation.hh:145
Data structure for a composite optical module.
Definition: JModule.hh:50
Detector data structure.
Definition: JDetector.hh:80
void reset(const JPMTStatusBits_t bit)
Reset PMT status.
Definition: JStatus.hh:147
void set(const JPMTStatusBits_t bit)
Set PMT status.
Definition: JStatus.hh:136
esac print_variable DETECTOR INPUT_FILE OUTPUT_FILE CDF for TYPE in
Definition: JSirene.sh:45
Utility class to parse parameter values.
Definition: JProperties.hh:496
int getNumberOfPMTs(const JModule &module)
Get number of PMTs.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:63
Data structure for PMT calibration.
string outputFile
is
Definition: JDAQCHSM.chsm:167
Data structure for detector geometry and calibration.
esac $JPP_DIR examples JDetector JTransitTime o $OUTPUT_FILE n N $NPE T $TTS_NS d $DEBUG for HISTOGRAM in tts tt2 pmt
Definition: JTransitTime.sh:36
Rotation around Z-axis.
Definition: JRotation3D.hh:85
JModule & sub(const JVector3D &pos)
Subtract position.
Definition: JModule.hh:365
Constants.
I/O formatting auxiliaries.
Detector file.
Definition: JHead.hh:130
Version with PMT status field and comments.
Data structure for vector in three dimensions.
Definition: JVector3D.hh:33
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1954
Auxiliary methods for handling file names, type names and environment.
return result
Definition: JPolint.hh:695
int getID() const
Get identifier.
Definition: JObjectID.hh:55
bool is_valid(const json &js)
Check validity of JSon data.
Data structure for PMT geometry and calibration.
Definition: JPMT.hh:47
ROOT I/O of application specific meta data.
#define NOTICE(A)
Definition: JMessage.hh:64
#define ERROR(A)
Definition: JMessage.hh:66
double getY() const
Get y position.
Definition: JVector3D.hh:103
void load(const JString &file_name, JDetector &detector)
Load detector from input file.
int debug
debug level
Definition: JSirene.cc:61
Auxiliary data structure for streaming of STL containers.
Definition: JPrint.hh:558
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:129
static const JModule & getInstance()
Get reference to unique instance of this class object.
Definition: JModule.hh:90
const JPMT & getPMT(const int index) const
Get PMT.
Definition: JModule.hh:174
void rotate(const JRotation3D &R)
Rotate module.
Definition: JModule.hh:242
Range of values.
Definition: JRange.hh:34
General purpose messaging.
#define FATAL(A)
Definition: JMessage.hh:67
Direct access to module in detector data structure.
JRange< Double_t > JRange_t
Definition: JFitToT.hh:34
int getString() const
Get string number.
Definition: JLocation.hh:134
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition: JHead.hh:1278
Auxiliary class to define a range between two values.
Utility class to parse command line options.
static const char WILD_CARD
Definition: JDAQTags.hh:34
void setID(const int id)
Set identifier.
Definition: JObjectID.hh:66
double getX() const
Get x position.
Definition: JVector3D.hh:93
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
void store(const JString &file_name, const JDetector &detector)
Store detector to output file.
JModule & set(const JVector3D &pos)
Set position.
Definition: JModule.hh:335
double getZ() const
Get z position.
Definition: JVector3D.hh:114
JModule & add(const JVector3D &pos)
Add position.
Definition: JModule.hh:347
void setPosition(const JVector3D &pos)
Set position.
Definition: JPosition3D.hh:151
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
JPosition3D getPosition(const Vec &v)
Get position.
int main(int argc, char *argv[])
Definition: Main.cpp:15