Jpp  16.0.0
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  * Multiple options <tt>-\@</tt>, <tt>-A</tt> and <tt>-M</tt> will be processed in order of appearance.
200  * \author mdejong
201  */
202 int main(int argc, char **argv)
203 {
204  using namespace std;
205  using namespace JPP;
206 
207  typedef JRange<double> JRange_t;
208 
209  string detectorFile;
210  int detectorID;
212  vector< JModifier<> > hdr;
215  double mu;
216  JRange_t T_ns;
217  string outputFile;
218  int debug;
219 
220  try {
221 
222  JParser<> zap("Auxiliary program to edit PMT parameters map.");
223 
224  zap['a'] = make_field(detectorFile, "detector file.") = "";
225  zap['D'] = make_field(detectorID, "detector identifier (in absence of detector file).") = 0;
226  zap['P'] = make_field(parameters, "PMT simulation data (or corresponding file name)") = JPARSER::initialised();
227  zap['@'] = make_field(hdr, "PMT parameter modifier for default values.") = JPARSER::initialised();
228  zap['A'] = make_field(mod, "PMT parameter modifier by physical address (e.g. B1).") = JPARSER::initialised();
229  zap['M'] = make_field(daq, "PMT parameter modifier by DAQ address (e.g. <module> <channel>.") = JPARSER::initialised();
230  zap['E'] = make_field(mu, "expectation value for npe given two-fold coincidence") = 0.0;
231  zap['T'] = make_field(T_ns, "time-over-threshold range.") = JRange_t();
232  zap['o'] = make_field(outputFile, "output file.");
233  zap['d'] = make_field(debug) = 3;
234 
235  zap(argc, argv);
236  }
237  catch(const exception &error) {
238  FATAL(error.what() << endl);
239  }
240 
241 
242  for (vector< JModifier<> >::const_iterator i = hdr.begin(); i != hdr.end(); ++i) {
243 
244  DEBUG("Modifying default PMT parameters " << i->action << ' ' << i->key << ' ' << i->value << endl);
245 
246  if (!i->apply(parameters.getDefaultPMTParameters())) {
247  ERROR("No valid action: " << *i << endl);
248  }
249  }
250 
251  if (detectorFile != "") {
252 
253  // Setting default PMT parameters for given detector.
254 
256 
257  try {
258  load(detectorFile, detector);
259  }
260  catch(const JException& error) {
261  FATAL(error);
262  }
263 
264  if (detectorID == 0) {
265 
266  detectorID = detector.getID();
267 
268  } else if (detectorID != detector.getID()) {
269 
270  FATAL("Inconsistent detector identifier " << detectorID << " != " << detector.getID() << endl);
271  }
272 
273 
274  for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
275 
276  for (unsigned int pmt = 0; pmt != module->size(); ++pmt) {
277 
278  const JPMTIdentifier id(module->getID(), pmt);
279 
280  if (parameters.find(id) == parameters.end()) {
281 
282  DEBUG("Setting default parameters for PMT " << id << endl);
283 
284  parameters[id] = parameters.getDefaultPMTParameters();
285  }
286  }
287  }
288  }
289 
290  if (!mod.empty()) {
291 
292  if (!hasDetectorAddressMap(detectorID)) {
293  FATAL("Invalid detector identifier " << detectorID << endl);
294  }
295 
296  const JDetectorAddressMap& demo = getDetectorAddressMap(detectorID);
297 
298  for (JPMTParametersMap::iterator ps = parameters.begin(); ps != parameters.end(); ++ps) {
299 
300  const JPMTPhysicalAddress& address = demo.get(ps->first);
301 
302  for (vector< JModifier<JPMTPhysicalAddress> >::const_iterator i = mod.begin(); i != mod.end(); ++i) {
303 
304  if (compare(i->address, address)) {
305 
306  DEBUG("Modifying parameters for PMT " << ps->first << ' ' << i->action << ' ' << i->key << ' ' << i->value << endl);
307 
308  if (!i->apply(ps->second)) {
309  ERROR("No valid action: " << *i << endl);
310  }
311  }
312  }
313  }
314  }
315 
316  if (!daq.empty()) {
317 
318  for (JPMTParametersMap::iterator ps = parameters.begin(); ps != parameters.end(); ++ps) {
319 
320  for (vector< JModifier<JPMTIdentifier> >::const_iterator i = daq.begin(); i != daq.end(); ++i) {
321 
322  if (compare(ps->first, i->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 
335  if (mu > 0.0) {
336 
337  DEBUG("Correct measured QE for two-hit probability " << mu << endl);
338 
339  try {
340  parameters.convertHitProbabilityToQE(mu);
341  }
342  catch(const JException& error) {
343  FATAL(error.what());
344  }
345 
346  } else if (mu < 0.0) {
347 
348  FATAL("Invalid expection value for two-hit probability " << mu << endl);
349  }
350 
351 
352  if (T_ns != JRange_t()) {
353 
354  DEBUG("Correct measured QE for time-over-threshold range " << T_ns << endl);
355 
356  const int NPE = 1;
357 
358  for (JPMTParametersMap::iterator i = parameters.begin(); i != parameters.end(); ++i) {
359 
360  const JPMTAnalogueSignalProcessor cpu(i->second);
361 
362  i->second.QE *= (cpu.getIntegralOfChargeProbability(i->second.threshold,
363  cpu.getNPE(T_ns.getUpperLimit()),
364  NPE)
365  /
366  cpu.getIntegralOfChargeProbability(cpu.getNPE(T_ns.getLowerLimit()),
367  cpu.getNPE(T_ns.getUpperLimit()),
368  NPE));
369  }
370  }
371 
372 
373  if (outputFile != "") {
374 
375  parameters.comment.add(JMeta(argc, argv));
376 
377  ofstream out(outputFile.c_str());
378 
379  out << parameters << endl;
380 
381  out.close();
382  }
383 }
384 
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:1500
General exception.
Definition: JException.hh:23
int main(int argc, char *argv[])
Definition: Main.cc:15
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:66
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
const T & getValue(const std::string &key) const
Get value.
Definition: JProperties.hh:974
Type definition of range.
Definition: JHead.hh:39
Detector specific mapping between logical positions and readout channels of PMTs in optical modules...
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1961
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;]
int debug
debug level
Definition: JSirene.cc:63
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:1693
virtual const char * what() const override
Get error message.
Definition: JException.hh:48
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
Auxiliary class to define a range between two values.
Utility class to parse command line options.
int position
position within ring [1,6]
then usage $script< input_file >< detector_file > fi set_variable OUTPUT_DIR set_variable SELECTOR JDAQTimesliceL1 set_variable DEBUG case set_variable DEBUG
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
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY source JAcoustics sh $DETECTOR_ID CHECK_EXIT_CODE typeset A TRIPODS get_tripods $WORKDIR tripod txt TRIPODS for EMITTER in
Definition: JCanberra.sh:42