Jpp  18.6.0-rc.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JEditPMTParameters.cc
Go to the documentation of this file.
1 
2 #include <string>
3 #include <iostream>
4 #include <fstream>
5 #include <iomanip>
6 #include <vector>
7 
8 #include "JLang/JLangToolkit.hh"
9 #include "JDetector/JDetector.hh"
18 #include "JSupport/JMeta.hh"
19 #include "JTools/JRange.hh"
20 
21 #include "Jeep/JParser.hh"
22 #include "Jeep/JMessage.hh"
23 
24 
25 namespace {
26 
27  using namespace JPP;
28 
29  static const char WILDCARD_RING = '*'; //<! Wild card for ring of PMT in optical module.
30  static const int WILDCARD_POSITION = -1; //<! Wild card for position of PMT in ring.
31  static const int WILDCARD = -1; //<! Wild card for PMT identifier.
32 
33 
34  /**
35  * Compare PMT physical addresses taking into account wild cards.
36  *
37  * \param first first PMT physical address
38  * \param second second PMT physical address
39  * \return true if addresses are equal; else false
40  */
41  inline bool compare(const JPMTPhysicalAddress& first, const JPMTPhysicalAddress& second)
42  {
43  return (((first == second)) ||
44 
45  ((first.ring == WILDCARD_RING || second.ring == WILDCARD_RING) && first.position == second.position) ||
46  ((first.position == WILDCARD_POSITION || second.position == WILDCARD_POSITION) && first.ring == second.ring) ||
47 
48  ((first.ring == WILDCARD_RING || second.ring == WILDCARD_RING) &&
49  (first.position == WILDCARD_POSITION || second.position == WILDCARD_POSITION)));
50  }
51 
52 
53  /**
54  * Compare PMT identifiers taking into account wild cards.
55  *
56  * \param first first PMT identifier
57  * \param second second PMT identifier
58  * \return true if addresses are equal; else false
59  */
60  inline bool compare(const JPMTIdentifier& first, const JPMTIdentifier& second)
61  {
62  return (((first == second)) ||
63 
64  ((first.getID() == WILDCARD || second.getID() == WILDCARD) && first.getTDC() == second.getTDC()) ||
65  ((first.getTDC() == WILDCARD || second.getTDC() == WILDCARD) && first.getID() == second.getID()) ||
66 
67  ((first.getID() == WILDCARD || second.getID() == WILDCARD) &&
68  (first.getTDC() == WILDCARD || second.getTDC() == WILDCARD)));
69  }
70 
71 
72  /**
73  * Empty address.
74  */
75  struct JEmptyAddress {
76  friend inline std::istream& operator>>(std::istream& in, JEmptyAddress& object) { return in; }
77  friend inline std::ostream& operator<<(std::ostream& out, const JEmptyAddress& object) { return out; }
78  };
79 
80 
81  /**
82  * Auxiliary class to apply modifications to PMT parameters.
83  */
84  template<class JAddress_t = JEmptyAddress>
85  class JModifier {
86  public:
87  /**
88  * Default constructor.
89  */
90  JModifier()
91  {}
92 
93 
94  /**
95  * Apply modification to given parameters.
96  *
97  * \param parameters PMT parameters
98  * \return true if valid action; else false
99  */
100  bool apply(JPMTParameters& parameters) const
101  {
102  using namespace std;
103 
104  try {
105 
106  if (this->action == "set") {
107 
108  parameters.getProperties().getValue<double>(this->key) = this->value;
109 
110  } else if (this->action == "add") {
111 
112  parameters.getProperties().getValue<double>(this->key) += this->value;
113 
114  } else if (this->action == "sub") {
115 
116  parameters.getProperties().getValue<double>(this->key) -= this->value;
117 
118  } else if (this->action == "mul") {
119 
120  parameters.getProperties().getValue<double>(this->key) *= this->value;
121 
122  } else if (this->action == "div") {
123 
124  parameters.getProperties().getValue<double>(this->key) /= this->value;
125 
126  } else {
127 
128  return false;
129  }
130  }
131  catch(const std::exception& error) {
132  cerr << error.what() << endl;
133  return false;
134  }
135 
136  return true;
137  }
138 
139 
140  /**
141  * Read modifier from input.
142  *
143  * \param in input stream
144  * \param modifier modifier
145  * \return input stream
146  */
147  friend inline std::istream& operator>>(std::istream& in, JModifier& modifier)
148  {
149  return in >> modifier.address
150  >> modifier.action
151  >> modifier.key
152  >> modifier.value;
153  }
154 
155 
156  /**
157  * Write modifier to output.
158  *
159  * \param out output stream
160  * \param modifier modifier
161  * \return output stream
162  */
163  friend inline std::ostream& operator<<(std::ostream& out, const JModifier& modifier)
164  {
165  return out << modifier.address << ' '
166  << modifier.action << ' '
167  << modifier.key << ' '
168  << modifier.value;
169  }
170 
171 
172  JAddress_t address;
173  std::string action;
174  std::string key;
175  double value;
176  };
177 }
178 
179 
180 /**
181  * \file
182  *
183  * Auxiliary program to edit PMT parameters map.
184  *
185  * Syntax:
186  * <pre>
187  * -@ "(set|add|sub|mul|div) <key> <value>"
188  * -A "<PMT physical address> (set|add|sub|mul|div) <key> <value>"
189  * -M "<PMT identifier> (set|add|sub|mul|div) <key> <value>"
190  * </pre>
191  * In this, the PMT physical address corresponds to the data structure JDETECTOR::JPMTPhysicalAddress and
192  * the PMT identifier to JDETECTOR::JPMTIdentifier.\n
193  * The key corresponds to one of the data members of the JDETECTOR::JPMTParameters data structure.\n
194  * The option <tt>-\@</tt> corresponds to the default PMT values.
195  *
196  * Note that in the absence of option <tt>-a</tt>, the detector identifier should be specified
197  * using option <tt>-D</tt> so to obtain the correct PMT address mapping.
198  *
199  * The default value for option <tt>-E</tt> (expectation value for npe given two-fold coincidence)
200  * is taken from Analysis e-log entry <a href="https://elog.km3net.de/Analysis/519">519</a>.\n
201  * The (default) values for option <tt>-T</tt> (time-over-threshold range) should correspond to
202  * the minimal and maximal value at option <tt>-t</tt> of application JCalibrateK40.cc.\n
203  * The values for option <tt>-Q</tt> (QE range) can be used to take into account
204  * the light scaling factor applied in the simulation of the detector response.
205  *
206  * Multiple options <tt>-\@</tt>, <tt>-A</tt> and <tt>-M</tt> will be processed in order of appearance.
207  * \author mdejong
208  */
209 int main(int argc, char **argv)
210 {
211  using namespace std;
212  using namespace JPP;
213 
214  typedef JRange<double> JRange_t;
215 
216  string detectorFile;
217  int detectorID;
219  vector< JModifier<> > hdr;
222  JProxy<double> mu ("?", 2.05644e-01);
223  JProxy<JRange_t> T_ns("?", JRange_t(4, 250));
224  JRange_t QE;
225  string outputFile;
226  bool squash;
227  int debug;
228 
229  try {
230 
231  JParser<> zap("Auxiliary program to edit PMT parameters map.");
232 
233  zap['a'] = make_field(detectorFile, "detector file.") = "";
234  zap['D'] = make_field(detectorID, "detector identifier (in absence of detector file).") = 0;
235  zap['P'] = make_field(parameters, "PMT simulation data (or corresponding file name)") = JPARSER::initialised();
236  zap['@'] = make_field(hdr, "PMT parameter modifier for default values.") = JPARSER::initialised();
237  zap['A'] = make_field(mod, "PMT parameter modifier by physical address (e.g. B1).") = JPARSER::initialised();
238  zap['M'] = make_field(daq, "PMT parameter modifier by DAQ address (e.g. <module> <channel>.") = JPARSER::initialised();
239  zap['E'] = make_field(mu, "expectation value for npe given two-fold coincidence (" << mu .getOption() << " -> " << mu .getCustom() << ")") = 0.0;
240  zap['T'] = make_field(T_ns, "time-over-threshold rang (" << T_ns.getOption() << " -> " << T_ns.getCustom() << ")") = JRange_t();
241  zap['Q'] = make_field(QE, "QE range.") = JRange_t();
242  zap['o'] = make_field(outputFile, "output file.");
243  zap['q'] = make_field(squash, "squash meta data");
244  zap['d'] = make_field(debug, "debug level") = 2;
245 
246  zap(argc, argv);
247  }
248  catch(const exception &error) {
249  FATAL(error.what() << endl);
250  }
251 
252 
253  if (squash) {
254  parameters.comment.clear();
255  }
256 
257  parameters.comment.add(JMeta(argc,argv));
258 
259 
260  for (vector< JModifier<> >::const_iterator i = hdr.begin(); i != hdr.end(); ++i) {
261 
262  DEBUG("Modifying default PMT parameters " << i->action << ' ' << i->key << ' ' << i->value << endl);
263 
264  if (!i->apply(parameters.getDefaultPMTParameters())) {
265  ERROR("No valid action: " << *i << endl);
266  }
267  }
268 
269  if (detectorFile != "") {
270 
271  // Setting default PMT parameters for given detector.
272 
274 
275  try {
276  load(detectorFile, detector);
277  }
278  catch(const JException& error) {
279  FATAL(error);
280  }
281 
282  if (detectorID == 0) {
283 
284  detectorID = detector.getID();
285 
286  } else if (detectorID != detector.getID()) {
287 
288  FATAL("Inconsistent detector identifier " << detectorID << " != " << detector.getID() << endl);
289  }
290 
291 
292  for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
293 
294  for (unsigned int pmt = 0; pmt != module->size(); ++pmt) {
295 
296  const JPMTIdentifier id(module->getID(), pmt);
297 
298  if (parameters.find(id) == parameters.end()) {
299 
300  DEBUG("Setting default parameters for PMT " << id << endl);
301 
302  parameters[id] = parameters.getDefaultPMTParameters();
303  }
304  }
305  }
306  }
307 
308  if (!mod.empty()) {
309 
310  if (!hasDetectorAddressMap(detectorID)) {
311  FATAL("Invalid detector identifier " << detectorID << endl);
312  }
313 
314  const JDetectorAddressMap& demo = getDetectorAddressMap(detectorID);
315 
316  for (JPMTParametersMap::iterator ps = parameters.begin(); ps != parameters.end(); ++ps) {
317 
318  const JPMTPhysicalAddress& address = demo.get(ps->first);
319 
320  for (vector< JModifier<JPMTPhysicalAddress> >::const_iterator i = mod.begin(); i != mod.end(); ++i) {
321 
322  if (compare(i->address, address)) {
323 
324  DEBUG("Modifying parameters for PMT " << ps->first << ' ' << i->action << ' ' << i->key << ' ' << i->value << endl);
325 
326  if (!i->apply(ps->second)) {
327  ERROR("No valid action: " << *i << endl);
328  }
329  }
330  }
331  }
332  }
333 
334  if (!daq.empty()) {
335 
336  for (JPMTParametersMap::iterator ps = parameters.begin(); ps != parameters.end(); ++ps) {
337 
338  for (vector< JModifier<JPMTIdentifier> >::const_iterator i = daq.begin(); i != daq.end(); ++i) {
339 
340  if (compare(ps->first, i->address)) {
341 
342  DEBUG("Modifying parameters for PMT " << ps->first << ' ' << i->action << ' ' << i->key << ' ' << i->value << endl);
343 
344  if (!i->apply(ps->second)) {
345  ERROR("No valid action: " << *i << endl);
346  }
347  }
348  }
349  }
350  }
351 
352 
353  if (mu > 0.0) {
354 
355  DEBUG("Correct measured QE for two-hit probability " << mu << endl);
356 
357  try {
358  parameters.convertHitProbabilityToQE(mu);
359  }
360  catch(const JException& error) {
361  FATAL(error.what());
362  }
363 
364  } else if (mu < 0.0) {
365 
366  FATAL("Invalid expection value for two-hit probability " << mu << endl);
367  }
368 
369 
370  if (T_ns != JRange_t()) {
371 
372  DEBUG("Correct measured QE for time-over-threshold range " << T_ns << endl);
373 
374  const int NPE = 1;
375 
376  for (JPMTParametersMap::iterator i = parameters.begin(); i != parameters.end(); ++i) {
377 
378  const JPMTAnalogueSignalProcessor cpu(i->second);
379 
380  i->second.QE *= (cpu.getIntegralOfChargeProbability(i->second.threshold,
381  cpu.getNPE(T_ns.getUpperLimit()),
382  NPE)
383  /
384  cpu.getIntegralOfChargeProbability(cpu.getNPE(T_ns.getLowerLimit()),
385  cpu.getNPE(T_ns.getUpperLimit()),
386  NPE));
387  }
388  }
389 
390 
391  if (QE != JRange_t()) {
392 
393  for (JPMTParametersMap::iterator i = parameters.begin(); i != parameters.end(); ++i) {
394  i->second.QE = QE.constrain(i->second.QE);
395  }
396  }
397 
398 
399  if (outputFile != "") {
400 
401  parameters.comment.add(JMeta(argc, argv));
402 
403  ofstream out(outputFile.c_str());
404 
405  out << parameters << endl;
406 
407  out.close();
408  }
409 }
410 
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:70
Utility class to parse command line options.
Definition: JParser.hh:1711
General exception.
Definition: JException.hh:24
int main(int argc, char *argv[])
Definition: Main.cc:15
JParserTemplateElement< JType_t > getOption(JType_t &object, const std::string &name, const std::string &help="")
Auxiliary method for creation of template parser element object.
Definition: JParser.hh:2093
double getIntegralOfChargeProbability(const double xmin, const double xmax, const int NPE) const
Get integral of probability.
Detector data structure.
Definition: JDetector.hh:89
bool hasDetectorAddressMap(const int id)
Check if detector address map is available.
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
Definition: diff-Tuna.sh:38
Lookup table for PMT addresses in detector.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:84
JProperties getProperties(const JEquationParameters &equation=JPMTParameters::getEquationParameters())
Get properties of this class.
string outputFile
Data structure for detector geometry and calibration.
const JModuleAddressMap & get(const int id) const
Get module address map.
then echo The file $DIR KM3NeT_00000001_00000000 root already please rename or remove it first
static const char WILDCARD
Definition: JDAQTags.hh:56
const T & getValue(const std::string &key) const
Get value.
Definition: JProperties.hh:976
Type definition of range.
Definition: JHead.hh:41
Detector support kit.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:2158
int getID() const
Get identifier.
Definition: JObjectID.hh:50
ROOT I/O of application specific meta data.
#define ERROR(A)
Definition: JMessage.hh:66
virtual double getNPE(const double tot_ns) const override
Get number of photo-electrons.
Auxiliary class for map of PMT parameters.
char ring
ring number [&#39;A&#39;,&#39;F&#39;]
JDetectorAddressMap & getDetectorAddressMap()
Get detector address map.
General purpose messaging.
#define FATAL(A)
Definition: JMessage.hh:67
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition: JHead.hh:1831
Auxiliary class to assign a custom value following the reading of a specific textual value...
Definition: JParser.hh:124
virtual const char * what() const override
Get error message.
Definition: JException.hh:64
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
Auxiliary class to define a range between two values.
then fatal The output file must have the wildcard in the e g root fi eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:48
Utility class to parse command line options.
int position
position within ring [1,6]
PMT analogue signal processor.
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
Data structure for PMT physical address.
Data structure for PMT parameters.
do set_variable DETECTOR_TXT $WORKDIR detector
int debug
debug level
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62