Jpp 20.0.0-rc.2
the software that should make you happy
Loading...
Searching...
No Matches
JEditDetector.cc File Reference

Auxiliary program to modify detector calibration. More...

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <cctype>
#include "TRandom3.h"
#include "JDetector/JDetector.hh"
#include "JDetector/JDetectorToolkit.hh"
#include "JDetector/JDetectorHeader.hh"
#include "JDetector/JModuleStatus.hh"
#include "JDetector/JModuleRouter.hh"
#include "JDetector/JLocationRouter.hh"
#include "JDetector/JPMTIdentifier.hh"
#include "JDetector/JPMTPhysicalAddress.hh"
#include "JDetector/JPMTStatus.hh"
#include "JDetector/JModuleAddressMap.hh"
#include "JDetector/JDetectorAddressMap.hh"
#include "JDetector/JDetectorSupportkit.hh"
#include "JGeometry3D/JVector3D.hh"
#include "JMath/JConstants.hh"
#include "JMath/JMath.hh"
#include "JTools/JRange.hh"
#include "JLang/JException.hh"
#include "JLang/JToken.hh"
#include "JLang/JComparator.hh"
#include "JLang/JComparison.hh"
#include "JSupport/JMeta.hh"
#include "Jeep/JeepToolkit.hh"
#include "Jeep/JPrint.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Auxiliary program to modify detector calibration.

Syntax:

    -M     "<module identifier>     (set|add|sub|randset|randadd|randsub) x0 [x1 x2]"
    -(S|s) "<string number>         (set|add|sub|randset|randadd|randsub) x0 [x1 x2]"
    -M     "<module identifier>     (setx|addx|subx|sety|addy|suby|setz|addz|subz) value"
    -(S|s) "<string number>         (setx|addx|subx|sety|addy|suby|setz|addz|subz) value"
    -M     "<module identifier>     (rot|randrot|lower|upper) phi"
    -(S|s) "<string number>         (rot|randrot) phi"
    -M     "<module identifier>     (mul|randmul) factor"
    -(S|s) "<string number>         (mul|randmul) factor"
    -M     "<module identifier>     (div|randdiv) factor"
    -(S|s) "<string number>         (div|randdiv) factor"
    -M     "<module identifier>     (reset)"
    -(S|s) "<string number>         (reset)"
    -M     "<module identifier>     (assign)  identifier"
    -M     "<module identifier>     (locate)  <string> <floor>"
    -M     "<module identifier>     (swap)    <PMT>    <PMT>"
    -M     "<module identifier>     (SET|ADD|SUB|) x0 [x1 x2 x3]"
    -(S|s) "<string number>         (SET|ADD|SUB|) x0 [x1 x2 x3]"
    -M     "<module identifier>     (ROT) phi"
    -(S|s) "<string number>         (ROT) phi"
    -(S|s) "<string number>         (tilt|randtilt) Tx Ty"
    -R     "<module identifier>     <PMT physical address>"
    -W     "<module identifier>     (set|reset)  (MODULE_DISABLE|COMPASS_DISABLE|HYDROPHONE_DISABLE|PIEZO_DISABLE|MODULE_OUT_OF_SYNC)"
    -P     "<PMT identifier>        (set|reset)  (PMT_DISABLE|HIGH_RATE_VETO_DISABLE|FIFO_FULL_DISABLE|UDP_COUNTER_DISABLE|UDP_TRAILER_DISABLE|OUT_OF_SYNC)"
    -p     "<PMT physical address>  (set|reset)  (PMT_DISABLE|HIGH_RATE_VETO_DISABLE|FIFO_FULL_DISABLE|UDP_COUNTER_DISABLE|UDP_TRAILER_DISABLE|OUT_OF_SYNC)"
    -k     "<string number>[-<string number>]"
    -r     "<string number>[-<string number>]"
    -m     "<module identifier>"
    -D     "<string number> <floor>"
    -F     "<string number> <distance between floor 0 and 1>"
    -@    "<key>=<value>[;<key>=<value>"

Options -M and -S refer to a module and a string, respectively.
The values provided for a string modification coherently apply to the modules of the specified string number.
The option -s is equivalent to option -S except that the action applies only to the optical modules in the string and not the base module.

The options randxxx correspond to a randomisation of the specified option.

If the module identifier or string number is -1, the action is applied to all modules or strings in the detector, respectively.

For options [rand]set, [rand]add and [rand]sub, the number of values apply to position or time calibration in the following way:

  1. time calibration (t = x0)
  2. invalid
  3. position calibration (x = x0, y = x1, z = x2)

For options (set|add|sub)(x|y|z), the value corresponds to last character of the the quoted action.

For options [rand]rot, the angle phi refers to an anti-clockwise rotation around the z-axis.
The options upper and lower refer to a rotation of the PMTs in the upper and lower hemisphere of the module, respectively.
The rotation angle is defined in radians.

For options [rand]mul and [rand]div, the multiplication/division factor (a.k.a. "stretching") applies to the z-coordinates of the modules.
The factor is defined as a fraction; the actual multiplication/division factor is (1 + factor).

For options SET, ADD and SUB, the number of values apply to time or quaternion calibration of the module in the following way:

  1. time calibration of piezo sensor or hydrophone (t = x0)
  2. invalid
  3. invalid
  4. quaternion calibration of compass (qa = x0, qb = x1, qc = x2, qd = x3)

For options ROT, the angle phi refers to an anti-clockwise rotation around the z-axis of the quaternion calibration of the compass.
The rotation angle is defined in radians.

Note that to correct the time calibration for the delay time of the piezo sensor and hydrophone, application JDetectorDB.cc can be used (option -WW).

The units of all positions and time values are m and ns, respectively.

Note that for string modifiers with option randxxx, the action is coherently applied to the modules in the specified string.
Only one type of action (defined by xxx and the number of values) is then allowed per string.

The option -R can be used to rotate the positions of PMTs within a given ring.
In this, the position of the physical address of the PMT corresponds to the number of steps of the rotation.

The option -W can be used to modify the status of a module. The options -P and -p can be used to modify the status of PMTs.

Option -@ refers to the header information.
The list of possible keys can be obtained using JPrintDetector.cc with option -O header.

Multiple options -M, -S, -s or -@ will be processed in order of appearance.

Options -k and -r can be used to keep and remove (a range of) string numbers, respectively.

The options -m and -D can be used to maintain a specific module (and remove all others) and to delete a floor from a string, respectively.

The option -F can be used to fix the distance between floors 0 and 1.

Note finally that if the output file name is the same as the input file name, the original file will be overwritten.

Author
mdejong

Definition in file JEditDetector.cc.

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 949 of file JEditDetector.cc.

950{
951 using namespace std;
952 using namespace JPP;
953
954 typedef JToken<';'> JToken_t;
955
956 string inputFile;
957 string outputFile;
962 vector< pair<int,
963 JModuleModifier> > wip;
965 JPMTModifier> > pmt;
967 JPMTModifier> > alt;
968 multimap<int,
970 vector<JRange_t> keep;
972 vector<int> id;
975 int option;
976 bool squash;
977 int debug;
978
979 try {
980
981 JParser<> zap("Auxiliary program to modify detector.");
982
983 zap['a'] = make_field(inputFile);
984 zap['o'] = make_field(outputFile);
985 zap['@'] = make_field(hdr, "header modification") = JPARSER::initialised();
986 zap['M'] = make_field(mod, "module modification") = JPARSER::initialised();
987 zap['S'] = make_field(str, "string modification (optical modules and base modules)") = JPARSER::initialised();
988 zap['s'] = make_field(dos, "string modification (optical modules only)") = JPARSER::initialised();
989 zap['W'] = make_field(wip, "module status modification") = JPARSER::initialised();
990 zap['P'] = make_field(pmt, "PMT status modification by PMT logical address") = JPARSER::initialised();
991 zap['p'] = make_field(alt, "PMT status modification by PMT physical address") = JPARSER::initialised();
992 zap['R'] = make_field(ring, "rotate positions of PMTs in ring") = JPARSER::initialised();
993 zap['k'] = make_field(keep, "keep string[s] by number") = JPARSER::initialised();
994 zap['r'] = make_field(rm, "remove string[s] by number") = JPARSER::initialised();
995 zap['m'] = make_field(id, "maintain module[s] by identifier") = JPARSER::initialised();
996 zap['D'] = make_field(del, "remove module[s] by location") = JPARSER::initialised();
997 zap['F'] = make_field(f01, "fix distance between floor 0 and 1") = JPARSER::initialised();
998 zap['O'] = make_field(option, "sort modules: "\
999 "0 -> no sort; 1 -> module identifier; 2 -> module location") = 0, 1, 2;
1000 zap['q'] = make_field(squash, "squash meta data");
1001 zap['d'] = make_field(debug, "debug level") = 2;
1002
1003 zap(argc, argv);
1004 }
1005 catch(const exception &error) {
1006 FATAL(error.what() << endl);
1007 }
1008
1009 gRandom->SetSeed(0);
1010
1011 const int ns = ((keep.empty() ? 0 : 1) +
1012 (rm .empty() ? 0 : 1) +
1013 (id .empty() ? 0 : 1) +
1014 (del .empty() ? 0 : 1));
1015
1016 if (ns > 1) {
1017 FATAL("Use either option -k, -r, -m or -D." << endl);
1018 }
1019
1021
1022 try {
1023 load(inputFile, detector);
1024 }
1025 catch(const JException& error) {
1026 FATAL(error);
1027 }
1028
1029 if (squash) {
1030 detector.comment.clear();
1031 }
1032
1033 detector.comment.add(JMeta(argc,argv));
1034
1035 if (detector.setToLatestVersion()) {
1036 NOTICE("Set detector version to " << detector.getVersion() << endl);
1037 }
1038
1039
1040 if (!hdr.empty()) {
1041
1042 int id = -1;
1043
1044 JProperties helper = detector.getProperties();
1045
1046 helper["id"] = id;
1047
1048 for (vector<JToken_t>::const_iterator i = hdr.begin(); i != hdr.end(); ++i) {
1049
1050 istringstream is(*i);
1051
1052 is >> helper;
1053 }
1054
1055 if (id != -1) {
1056 detector.setID(id);
1057 }
1058 }
1059
1060
1061 if (ns != 0) {
1062
1063 for (JDetector::iterator module = detector.begin(); module != detector.end(); ) {
1064
1065 bool __rm__ = !keep.empty() && rm.empty();
1066
1067 for (vector<JRange_t>::const_iterator i = keep.begin(); i != keep.end(); ++i) {
1068 if (module->getString() >= i->first && module->getString() <= i->second) {
1069 __rm__ = false;
1070 }
1071 }
1072
1073 for (vector<JRange_t>::const_iterator i = rm.begin(); i != rm.end(); ++i) {
1074 if (module->getString() >= i->first && module->getString() <= i->second) {
1075 __rm__ = true;
1076 }
1077 }
1078
1079 if (!id.empty()) {
1080 __rm__ = find(id.begin(), id.end(), module->getID()) == id.end();
1081 }
1082
1083 const auto range = del.equal_range(module->getString());
1084
1085 for (auto i = range.first; i != range.second; ++i) {
1086 if (i->second == module->getFloor()) {
1087 __rm__ = true;
1088 }
1089 }
1090
1091 if (__rm__)
1092 module = detector.erase(module);
1093 else
1094 ++module;
1095 }
1096 }
1097
1098
1099 for (vector< pair<int, JModifier> >::const_iterator i = mod.begin(); i != mod.end(); ++i) {
1100
1101 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1102
1103 if (module->getID() == i->first || i->first == WILDCARD ){
1104
1105 if (debug >= debug_t) {
1106 print(cout, *module, i->second);
1107 }
1108
1109 if (!i->second.apply(*module)) {
1110 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1111 }
1112 }
1113 }
1114 }
1115
1116
1117 for (vector< pair<int, JModifier> >::const_iterator i = str.begin(); i != str.end(); ++i) {
1118
1119 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1120
1121 if (module->getString() == i->first || i->first == WILDCARD) {
1122
1123 const JModifier modifier = getModifier(module->getString(), i->second);
1124
1125 if (debug >= debug_t) {
1126 print(cout, *module, i->second);
1127 }
1128
1129 if (!modifier.apply(*module)) {
1130 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1131 }
1132 }
1133 }
1134 }
1135
1136
1137 if (!f01.empty()) {
1138
1139 const JLocationRouter router(detector);
1140 const string action("fix distance between floors 0 and 1");
1141
1142 for (map<int, double>::const_iterator i = f01.begin(); i != f01.end(); ++i) {
1143
1144 DEBUG("String " << setw(4) << i->first << ' ' << action << ' ' << FIXED(7,3) << i->second << endl);
1145
1146 const JLocation L0(i->first, 0);
1147 const JLocation L1(i->first, 1);
1148
1149 if (router.hasLocation(L0) && router.hasLocation(L1)) {
1150
1151 const double z1 = detector[router.getAddress(L1).first].getZ();
1152
1153 JModule& module = detector[router.getAddress(L0).first];
1154
1155 module.set(JVector3D(module.getX(), module.getY(), z1 - i->second));
1156
1157 } else {
1158
1159 ERROR("No valid action: " << i->first << ' ' << action << endl);
1160 }
1161 }
1162 }
1163
1164
1165 for (vector< pair<int, JModifier> >::const_iterator i = dos.begin(); i != dos.end(); ++i) {
1166
1167 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1168
1169 if (module->getFloor() != 0) {
1170
1171 if (module->getString() == i->first || i->first == WILDCARD) {
1172
1173 const JModifier modifier = getModifier(module->getString(), i->second);
1174
1175 if (debug >= debug_t) {
1176 print(cout, *module, i->second);
1177 }
1178
1179 if (!modifier.apply(*module)) {
1180 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1181 }
1182 }
1183 }
1184 }
1185 }
1186
1187
1188 for (vector< pair<int, JModuleModifier> >::const_iterator i = wip.begin(); i != wip.end(); ++i) {
1189
1190 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1191
1192 if (module->getID() == i->first || i->first == WILDCARD ){
1193
1194 if (debug >= debug_t) {
1195 print(cout, *module, i->second);
1196 }
1197
1198 if (!i->second.apply(*module)) {
1199 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1200 }
1201 }
1202 }
1203 }
1204
1205
1206 for (vector< pair<JPMTIdentifier, JPMTModifier> >::const_iterator i = pmt.begin(); i != pmt.end(); ++i) {
1207
1208 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1209
1210 if (module->getID() == i->first.getModuleID() || i->first.getModuleID() == WILDCARD) {
1211
1212 if (debug >= debug_t) {
1213 print(cout, i->first, i->second);
1214 }
1215
1216 if (i->first.getPMTAddress() == WILDCARD) {
1217
1218 for (int pmt = 0; pmt != getNumberOfPMTs(*module); ++pmt) {
1219 if (!i->second.apply(module->getPMT(pmt))) {
1220 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1221 }
1222 }
1223
1224 } else if (i->first.getPMTAddress() >= 0 &&
1225 i->first.getPMTAddress() < getNumberOfPMTs(*module) &&
1226 !i->second.apply(module->getPMT(i->first.getPMTAddress()))) {
1227 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1228 }
1229 }
1230 }
1231 }
1232
1233
1234 if (!alt.empty() || !ring.empty()) {
1235
1236 if (!hasDetectorAddressMap(detector.getID())) {
1237 FATAL("Invalid detector identifier " << detector.getID() << endl);
1238 }
1239
1240 const JDetectorAddressMap& demo = getDetectorAddressMap(detector.getID());
1241
1242 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1243
1244 const JModuleAddressMap memo = demo.get(module->getID());
1245
1246 for (vector< pair<JPMTPhysicalAddress, JPMTModifier> >::const_iterator i = alt.begin(); i != alt.end(); ++i) {
1247
1248 const JPMTIdentifier id(module->getID(), memo.getAddressTranslator(i->first).tdc);
1249
1250 if (debug >= debug_t) {
1251 print(cout, id, i->second);
1252 }
1253
1254 if (!i->second.apply(module->getPMT(id.getPMTAddress()))) {
1255 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1256 }
1257 }
1258
1259 const auto range = ring.equal_range(module->getID());
1260
1261 for (auto i = range.first; i != range.second; ++i) {
1262
1263 JPMTPhysicalAddress modifier = i->second;
1264
1265 modifier.ring = (char) toupper(modifier.ring);
1266
1267 if (modifier.ring != 'A') {
1268
1270
1271 for (size_t i = 0; i != module->size(); ++i) {
1272
1273 const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i);
1274
1275 if (address.ring == modifier.ring) {
1276 buffer[address] = (*module)[i];
1277 }
1278 }
1279
1280 for (size_t i = 0; i != module->size(); ++i) {
1281
1282 const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i);
1283
1284 if (address.ring == modifier.ring) {
1285
1286 int position = address.position + modifier.position;
1287
1288 while (position > 6) { position -= 6; }
1289 while (position < 1) { position += 6; }
1290
1291 const JPMTPhysicalAddress source(modifier.ring, position);
1292
1293 DEBUG("Module " << setw(10) << module->getID() << ' ' << address << " <= " << source << endl);
1294
1295 (*module)[i] = buffer[source];
1296 }
1297 }
1298 }
1299 }
1300 }
1301 }
1302
1303
1304 switch (option) {
1305 case 1:
1306 sort(detector.begin(), detector.end(), make_comparator(&JModule::getID));
1307 break;
1308
1309 case 2:
1310 sort(detector.begin(), detector.end(), make_comparator(&JModule::getLocation));
1311 break;
1312
1313 default:
1314 break;
1315 };
1316
1317
1318 try {
1320 }
1321 catch(const JException& error) {
1322 FATAL(error);
1323 }
1324}
string outputFile
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
#define NOTICE(A)
Definition JMessage.hh:64
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:72
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
Lookup table for PMT addresses in detector.
const JModuleAddressMap & get(const int id) const
Get module address map.
Detector data structure.
Definition JDetector.hh:96
Router for direct addressing of location data in detector data structure.
Logical location of module.
Definition JLocation.hh:40
const JLocation & getLocation() const
Get location.
Definition JLocation.hh:70
Lookup table for PMT addresses in optical module.
const JPMTAddressTranslator & getAddressTranslator(const int tdc) const
Get PMT address translator.
const JPMTPhysicalAddress & getPMTPhysicalAddress(const int tdc) const
Get PMT physical address.
Data structure for a composite optical module.
Definition JModule.hh:75
Data structure for PMT physical address.
int position
position within ring [1,6]
Utility class to parse parameter values.
General exception.
Definition JException.hh:24
int getID() const
Get identifier.
Definition JObjectID.hh:50
Wrapper class around string.
Definition JToken.hh:26
Utility class to parse command line options.
Definition JParser.hh:1698
std::ostream & print(std::ostream &out, const JTestSummary &summary, T __begin, T __end, const bool useColors=true, const JFormat_t &formatting=JFormat_t(18, 3, std::ios::fixed))
Print test summary.
int getNumberOfPMTs(const JModule &module)
Get number of PMTs.
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.
JDetectorAddressMap & getDetectorAddressMap()
Get detector address map.
bool hasDetectorAddressMap(const int id)
Check if detector address map is available.
@ debug_t
debug
Definition JMessage.hh:29
JComparator< JResult_t T::*, JComparison::lt > make_comparator(JResult_t T::*member)
Helper method to create comparator between values of data member.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
Detector file.
Definition JHead.hh:227
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition JParser.hh:68
Auxiliary class for ROOT I/O of application specific meta data.
Definition JMeta.hh:72