Jpp  master_rocky-40-g5f0272dcd
the software that should make you happy
JConstructDetector.cc
Go to the documentation of this file.
1 #include <string>
2 #include <iostream>
3 #include <iomanip>
4 #include <fstream>
5 #include <vector>
6 #include <map>
7 
8 #include "JDetector/JDetector.hh"
13 #include "JDetector/JPMTRouter.hh"
14 #include "JSupport/JMeta.hh"
15 
16 #include "JSon/JSon.hh"
17 
18 #include "JSystem/JDateAndTime.hh"
19 
20 #include "Jeep/JeepToolkit.hh"
21 #include "Jeep/JPrint.hh"
22 #include "Jeep/JParser.hh"
23 #include "Jeep/JMessage.hh"
24 
25 namespace {
26 
27  using namespace JPP;
28 
29  /**
30  * Join UTC time range.
31  *
32  * \param js calibration input
33  * \param range detector I/O
34  */
35  void from_json(const json& js, JUTCTimeRange& range)
36  {
37  using namespace std;
38 
39  time_t Tmin = (time_t) range.getLowerLimit();
40  time_t Tmax = (time_t) range.getUpperLimit();
41 
42  if (js.contains(ValidFrom_t) && !js[ValidFrom_t] .is_null()) { Tmin = JDateAndTime(js[ValidFrom_t] .get<string>()).getTime(); }
43  if (js.contains(ValidThrough_t) && !js[ValidThrough_t].is_null()) { Tmax = JDateAndTime(js[ValidThrough_t].get<string>()).getTime(); }
44 
45  range.join(JUTCTimeRange(Tmin, Tmax));
46  }
47 }
48 
49 
50 
51 /**
52  * \file
53  *
54  * Auxiliary program to compose detector from separate calibrations.\n
55  * Note that the validity range as specified in the header of the detector data structure is determined by
56  * the maximal date and time value at JSON::ValidFrom_t and
57  * the minimal date and time value at JSON::ValidThrough_t, respectively.
58  *
59  * \author mdejong
60  */
61 int main(int argc, char **argv)
62 {
63  using namespace std;
64  using namespace JPP;
65 
66  string detectorFile;
67  vector<string> inputFile;
68  string outputFile;
69  int debug;
70 
71  try {
72 
73  JParser<> zap("Auxiliary program to compose detector from separate calibrations.");
74 
75  zap['a'] = make_field(detectorFile, "detector file");
76  zap['f'] = make_field(inputFile, "detector calibration files in JSON format "\
77  "(wild card \'" << FILENAME_WILDCARD << "\' will be replaced by corresponding calibration set)");
78  zap['o'] = make_field(outputFile, "detector file") = "";
79  zap['d'] = make_field(debug) = 1;
80 
81  zap(argc, argv);
82  }
83  catch(const exception &error) {
84  FATAL(error.what() << endl);
85  }
86 
87 
89 
90  try {
91  load(detectorFile, detector);
92  }
93  catch(const JException& error) {
94  FATAL(error);
95  }
96 
97  if (!hasDetectorAddressMap(detector.getID())) {
98  FATAL("No detector address map for detector identier " << detector.getID() << endl);
99  }
100 
101  const JDetectorBuilder& demo = getDetectorBuilder(detector.getID());
102 
103  const JModuleRouter moduleRouter(detector);
104  const JPMTRouter pmtRouter (detector);
105 
106  detector.setUTCTimeRange(JUTCTimeRange());
107 
108 
109  enum {
110  UNDEFINED = 0,
111  DEFINED = 1
112  };
113 
114  struct status_type {
115 
116  status_type() :
117  value(UNDEFINED)
118  {}
119 
120  operator int() const { return value; }
121 
122  status_type& operator=(const int value)
123  {
124  this->value = value;
125 
126  return *this;
127  }
128 
129  int value;
130  };
131 
133 
134  map_type tcal;
135  map_type pcal;
136  map_type rcal;
137  map_type acal;
138  map_type ccal;
139  map_type scal[2];
140 
141 
142  for (const auto& file_name : inputFile) {
143 
144  vector<string> buffer;
145 
146  if (hasWildCard(file_name))
147  buffer = { setWildCard(file_name, TCAL),
148  setWildCard(file_name, PCAL),
149  setWildCard(file_name, RCAL),
150  setWildCard(file_name, ACAL),
151  setWildCard(file_name, CCAL),
152  setWildCard(file_name, SCAL) };
153  else
154  buffer = { file_name };
155 
156  for (const auto& file_name : buffer) {
157 
158  const JSon js(file_name);
159 
160  json::const_iterator data;
161 
162  if (is_valid(js) && (data = js.find(Data_t)) != js.end()) {
163 
164  detector.comment.add(MAKE_STRING("calibration=" << (js.contains(Comment_t) ? js[Comment_t] : "?")));
165 
166  for (size_t i = 0; i != data->size(); ++i) {
167 
168  from_json(data->at(i), detector.getUTCTimeRange());
169 
170  if (data->at(i).contains(DetID_t)) {
171  if (data->at(i)[DetID_t].get<int>() != detector.getID()) {
172  FATAL("Detector identifier mismatch " << data->at(i)[DetID_t].get<int>() << " != " << detector.getID() << endl);
173  }
174  }
175 
176  if (data->at(i).contains(PMTT0s_t)) {
177 
178  for (const auto& element : data->at(i)[PMTT0s_t].get<JPMTCalibration>()) {
179 
180  if (pmtRouter.hasPMT(element.getID())) {
181 
182  JPMT& pmt = detector.getPMT(pmtRouter.getAddress(element.getID()));
183 
184  pmt.setCalibration(element.getCalibration());
185 
186  tcal[pmt.getID()] = DEFINED;
187  }
188  }
189  }
190 
191  if (data->at(i).contains(DOMPositions_t)) {
192 
193  for (const auto& element : data->at(i)[DOMPositions_t].get<JModulePosition>()) {
194 
195  if (moduleRouter.hasModule(element.getID())) {
196 
197  JModule& module = detector.getModule(moduleRouter.getAddress(element.getID()));
198 
199  module.set(element.getPosition());
200 
201  pcal[module.getID()] = DEFINED;
202  }
203  }
204  }
205 
206  if (data->at(i).contains(BasePositions_t)) {
207 
208  for (const auto& element : data->at(i)[BasePositions_t].get<JModulePosition>()) {
209 
210  if (moduleRouter.hasModule(element.getID())) {
211 
212  JModule& module = detector.getModule(moduleRouter.getAddress(element.getID()));
213 
214  module.set(element.getPosition());
215 
216  pcal[module.getID()] = DEFINED;
217  }
218  }
219  }
220 
221  if (data->at(i).contains(DOMRotations_t)) {
222 
223  for (const auto& element : data->at(i)[DOMRotations_t].get<JModuleRotation>()) {
224 
225  if (moduleRouter.hasModule(element.getID())) {
226 
227  JModule& module = detector.getModule(moduleRouter.getAddress(element.getID()));
228 
229  const JModule buffer = demo.getModule(module.getID(), module.getLocation());
230 
231  if (module.size() != buffer.size()) {
232  FATAL("Module size " << module.size() << " != " << buffer.size() << endl);
233  }
234 
235  const JPosition3D center = module.getCenter();
236 
237  for (size_t i = 0; i != module.size(); ++i) {
238  module.getPMT(i).setAxis(buffer.getPMT(i).getAxis());
239  }
240 
241  module.rotate(element.getQuaternion());
242 
243  module.setPosition(module.getCenter());
244  module.set(center);
245 
246  rcal[module.getID()] = DEFINED;
247  }
248  }
249  }
250 
251  if (data->at(i).contains(DOMAcousticT0_t)) {
252 
253  for (const auto& element : data->at(i)[DOMAcousticT0_t].get<JModuleCalibration>()) {
254 
255  if (moduleRouter.hasModule(element.getID())) {
256 
257  JModule& module = detector.getModule(moduleRouter.getAddress(element.getID()));
258 
259  module.setCalibration(element.getCalibration());
260 
261  acal[module.getID()] = DEFINED;
262  }
263  }
264  }
265 
266  if (data->at(i).contains(BaseAcousticT0_t)) {
267 
268  for (const auto& element : data->at(i)[BaseAcousticT0_t].get<JModuleCalibration>()) {
269 
270  if (moduleRouter.hasModule(element.getID())) {
271 
272  JModule& module = detector.getModule(moduleRouter.getAddress(element.getID()));
273 
274  module.setCalibration(element.getCalibration());
275 
276  acal[module.getID()] = DEFINED;
277  }
278  }
279  }
280 
281  if (data->at(i).contains(DOMCompassRotations_t)) {
282 
283  for (const auto& element : data->at(i)[DOMCompassRotations_t].get<JCompassRotation>()) {
284 
285  if (moduleRouter.hasModule(element.getID())) {
286 
287  JModule& module = detector.getModule(moduleRouter.getAddress(element.getID()));
288 
289  module.setQuaternion(element.getQuaternion());
290 
291  ccal[module.getID()] = DEFINED;
292  }
293  }
294  }
295 
296  if (data->at(i).contains(BaseCompassRotations_t)) {
297 
298  for (const auto& element : data->at(i)[BaseCompassRotations_t].get<JCompassRotation>()) {
299 
300  if (moduleRouter.hasModule(element.getID())) {
301 
302  JModule& module = detector.getModule(moduleRouter.getAddress(element.getID()));
303 
304  module.setQuaternion(element.getQuaternion());
305 
306  ccal[module.getID()] = DEFINED;
307  }
308  }
309  }
310 
311  if (data->at(i).contains(PMTStatusInfo_t)) {
312 
313  for (const auto& element : data->at(i)[PMTStatusInfo_t].get<JPMTStatus>()) {
314 
315  if (pmtRouter.hasPMT(element.getID())) {
316 
317  JPMT& pmt = detector.getPMT(pmtRouter.getAddress(element.getID()));
318 
319  pmt.setStatus(element.getStatus());
320 
321  scal[0][pmt.getID()] = DEFINED;
322  }
323  }
324  }
325 
326  if (data->at(i).contains(DOMStatusInfo_t)) {
327 
328  for (const auto& element : data->at(i)[DOMStatusInfo_t].get<JModuleStatus>()) {
329 
330  if (moduleRouter.hasModule(element.getID())) {
331 
332  JModule& module = detector.getModule(moduleRouter.getAddress(element.getID()));
333 
334  module.setStatus(element.getStatus());
335 
336  scal[1][module.getID()] = DEFINED;
337  }
338  }
339  }
340 
341  if (data->at(i).contains(BaseStatusInfo_t)) {
342 
343  for (const auto& element : data->at(i)[BaseStatusInfo_t].get<JModuleStatus>()) {
344 
345  if (moduleRouter.hasModule(element.getID())) {
346 
347  JModule& module = detector.getModule(moduleRouter.getAddress(element.getID()));
348 
349  module.setStatus(element.getStatus());
350 
351  scal[1][module.getID()] = DEFINED;
352  }
353  }
354  }
355  }
356  }
357  }
358  }
359 
360  for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
361 
362  if (pcal [module->getID()] != DEFINED) { ERROR("Module " << setw(10) << module->getID() << ' ' << getLabel(module->getLocation()) << " no position calibration." << endl); }
363  if (rcal [module->getID()] != DEFINED &&
364  module->getFloor() != 0) { ERROR("Module " << setw(10) << module->getID() << ' ' << getLabel(module->getLocation()) << " no rotation calibration." << endl); }
365  if (acal [module->getID()] != DEFINED) { ERROR("Module " << setw(10) << module->getID() << ' ' << getLabel(module->getLocation()) << " no acoustics calibration." << endl); }
366  if (ccal [module->getID()] != DEFINED) { ERROR("Module " << setw(10) << module->getID() << ' ' << getLabel(module->getLocation()) << " no compass calibration." << endl); }
367  if (scal[1][module->getID()] != DEFINED) { ERROR("Module " << setw(10) << module->getID() << ' ' << getLabel(module->getLocation()) << " no status calibration." << endl); }
368 
369  for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
370  if (tcal [pmt->getID()] != DEFINED) { ERROR("PMT " << setw(8) << pmt->getID() << " no time calibration." << endl); }
371  if (scal[0][pmt->getID()] != DEFINED) { ERROR("PMT " << setw(8) << pmt->getID() << " no status calibration." << endl); }
372  }
373  }
374 
375 
376  detector.comment.add(JMeta(argc,argv));
377 
378  try {
379  if (outputFile != "")
381  else
382  cout << detector << endl;
383  }
384  catch(const JException& error) {
385  FATAL(error);
386  }
387 
388  return 0;
389 }
int main(int argc, char **argv)
string outputFile
Date and time functions.
Detector support kit.
Data structure for detector geometry and calibration.
General purpose messaging.
#define ERROR(A)
Definition: JMessage.hh:66
#define FATAL(A)
Definition: JMessage.hh:67
int debug
debug level
Definition: JSirene.cc:69
ROOT I/O of application specific meta data.
Direct access to module in detector data structure.
Direct access to PMT in detector data structure.
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_STRING(A)
Make string.
Definition: JPrint.hh:63
nlohmann::json json
Auxiliary methods for handling file names, type names and environment.
void setCalibration(const JCalibration &cal)
Set calibration.
Detector data structure.
Definition: JDetector.hh:96
const JLocation & getLocation() const
Get location.
Definition: JLocation.hh:70
Router for direct addressing of module data in detector data structure.
const JModuleAddress & getAddress(const JObjectID &id) const
Get address of module.
bool hasModule(const JObjectID &id) const
Has module.
Data structure for a composite optical module.
Definition: JModule.hh:75
JVector3D getCenter() const
Get center of module based on crossing point of PMT axes.
Definition: JModule.hh:214
const JPMT & getPMT(const int index) const
Get PMT.
Definition: JModule.hh:172
JModule & set(const JVector3D &pos)
Set position.
Definition: JModule.hh:407
void rotate(const JRotation3D &R)
Rotate module.
Definition: JModule.hh:314
Router for direct addressing of PMT data in detector data structure.
Definition: JPMTRouter.hh:37
bool hasPMT(const JObjectID &id) const
Has PMT.
Definition: JPMTRouter.hh:116
const JPMTAddress & getAddress(const JObjectID &id) const
Get address of PMT.
Definition: JPMTRouter.hh:80
Data structure for PMT geometry, calibration and status.
Definition: JPMT.hh:49
void setAxis(const JAxis3D &axis)
Set axis.
Definition: JAxis3D.hh:109
const JAxis3D & getAxis() const
Get axis.
Definition: JAxis3D.hh:98
Data structure for position in three dimensions.
Definition: JPosition3D.hh:38
void setPosition(const JVector3D &pos)
Set position.
Definition: JPosition3D.hh:152
void setQuaternion(const JQuaternion3D &quaternion)
Set quaternion.
General exception.
Definition: JException.hh:24
int getID() const
Get identifier.
Definition: JObjectID.hh:50
Utility class to parse command line options.
Definition: JParser.hh:1698
range_type & join(const range_type &range)
Join ranges.
Definition: JRange.hh:415
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:202
T getUpperLimit() const
Get upper limit.
Definition: JRange.hh:213
UTC time range [s].
void from_json(const json &js, JDBString &object)
Convert JSon to database string.
std::string getLabel(const JLocation &location)
Get module label for monitoring and other applications.
Definition: JLocation.hh:247
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
JDetectorBuilder & getDetectorBuilder()
Get detector builder.
bool hasDetectorAddressMap(const int id)
Check if detector address map is available.
std::string setWildCard(const std::string &file_name, const std::string &value)
Get file name by setting wild card to given value.
Definition: JeepToolkit.hh:66
bool hasWildCard(const std::string &file_name)
Check presence of wild card.
Definition: JeepToolkit.hh:53
static const char FILENAME_WILDCARD
wild card character for file name substitution
Definition: JeepToolkit.hh:44
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
static const std::string BasePositions_t
static const std::string BaseStatusInfo_t
static const std::string BaseAcousticT0_t
static const std::string TCAL
PMT time offsets.
bool is_valid(const json &js)
Check validity of JSon data.
static const std::string ValidThrough_t
static const std::string PMTT0s_t
static const std::string PCAL
(optical|base) module positions
static const std::string DOMPositions_t
static const std::string SCAL
(module|PMT) status
static const std::string DetID_t
static const std::string RCAL
optical module orientations
static const std::string BaseCompassRotations_t
static const std::string Data_t
static const std::string PMTStatusInfo_t
static const std::string DOMRotations_t
static const std::string ACAL
acoustic time offsets (piezo sensor or hydrophone)
static const std::string DOMAcousticT0_t
static const std::string CCAL
compass alignment (a.k.a. quaternion calibration)
static const std::string DOMStatusInfo_t
static const std::string DOMCompassRotations_t
static const std::string Comment_t
static const std::string ValidFrom_t
std::map< int, range_type > map_type
Definition: JSTDTypes.hh:14
Detector file.
Definition: JHead.hh:227
Auxiliary interface for building detector.
const JModule & getModule(const int id=-1, const JLocation &location=JLocation()) const
Get module.
void setStatus(const JStatus &status)
Set status.
Definition: JStatus.hh:97
Auxiliary class to load json data from file.
Definition: JSon.hh:63
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:72
Auxiliary class for date and time.
Definition: JDateAndTime.hh:80
time_t getTime() const
time