Jpp 19.3.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/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>"
    -@    "<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.

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 945 of file JEditDetector.cc.

946{
947 using namespace std;
948 using namespace JPP;
949
950 typedef JToken<';'> JToken_t;
951
952 string inputFile;
953 string outputFile;
958 vector< pair<int,
959 JModuleModifier> > wip;
961 JPMTModifier> > pmt;
963 JPMTModifier> > alt;
964 multimap<int,
966 vector<JRange_t> keep;
968 vector<int> id;
970 int option;
971 bool squash;
972 int debug;
973
974 try {
975
976 JParser<> zap("Auxiliary program to modify detector.");
977
978 zap['a'] = make_field(inputFile);
979 zap['o'] = make_field(outputFile);
980 zap['@'] = make_field(hdr, "header modification") = JPARSER::initialised();
981 zap['M'] = make_field(mod, "module modification") = JPARSER::initialised();
982 zap['S'] = make_field(str, "string modification (optical modules and base modules)") = JPARSER::initialised();
983 zap['s'] = make_field(dos, "string modification (optical modules only)") = JPARSER::initialised();
984 zap['W'] = make_field(wip, "module status modification") = JPARSER::initialised();
985 zap['P'] = make_field(pmt, "PMT status modification by PMT logical address") = JPARSER::initialised();
986 zap['p'] = make_field(alt, "PMT status modification by PMT physical address") = JPARSER::initialised();
987 zap['R'] = make_field(ring, "rotate positions of PMTs in ring") = JPARSER::initialised();
988 zap['k'] = make_field(keep, "keep string[s] by number") = JPARSER::initialised();
989 zap['r'] = make_field(rm, "remove string[s] by number") = JPARSER::initialised();
990 zap['m'] = make_field(id, "maintain module[s] by identifier") = JPARSER::initialised();
991 zap['D'] = make_field(del, "remove module[s] by location") = JPARSER::initialised();
992 zap['O'] = make_field(option, "sort modules: "\
993 "0 -> no sort; 1 -> module identifier; 2 -> module location") = 0, 1, 2;
994 zap['q'] = make_field(squash, "squash meta data");
995 zap['d'] = make_field(debug, "debug level") = 2;
996
997 zap(argc, argv);
998 }
999 catch(const exception &error) {
1000 FATAL(error.what() << endl);
1001 }
1002
1003 gRandom->SetSeed(0);
1004
1005 const int ns = ((keep.empty() ? 0 : 1) +
1006 (rm .empty() ? 0 : 1) +
1007 (id .empty() ? 0 : 1) +
1008 (del .empty() ? 0 : 1));
1009
1010 if (ns > 1) {
1011 FATAL("Use either option -k, -r, -m or -D." << endl);
1012 }
1013
1015
1016 try {
1017 load(inputFile, detector);
1018 }
1019 catch(const JException& error) {
1020 FATAL(error);
1021 }
1022
1023 if (squash) {
1024 detector.comment.clear();
1025 }
1026
1027 detector.comment.add(JMeta(argc,argv));
1028
1029 if (detector.setToLatestVersion()) {
1030 NOTICE("Set detector version to " << detector.getVersion() << endl);
1031 }
1032
1033
1034 if (!hdr.empty()) {
1035
1036 int id = -1;
1037
1038 JProperties helper = detector.getProperties();
1039
1040 helper["id"] = id;
1041
1042 for (vector<JToken_t>::const_iterator i = hdr.begin(); i != hdr.end(); ++i) {
1043
1044 istringstream is(*i);
1045
1046 is >> helper;
1047 }
1048
1049 if (id != -1) {
1050 detector.setID(id);
1051 }
1052 }
1053
1054
1055 if (ns != 0) {
1056
1057 for (JDetector::iterator module = detector.begin(); module != detector.end(); ) {
1058
1059 bool __rm__ = !keep.empty() && rm.empty();
1060
1061 for (vector<JRange_t>::const_iterator i = keep.begin(); i != keep.end(); ++i) {
1062 if (module->getString() >= i->first && module->getString() <= i->second) {
1063 __rm__ = false;
1064 }
1065 }
1066
1067 for (vector<JRange_t>::const_iterator i = rm.begin(); i != rm.end(); ++i) {
1068 if (module->getString() >= i->first && module->getString() <= i->second) {
1069 __rm__ = true;
1070 }
1071 }
1072
1073 if (!id.empty()) {
1074 __rm__ = find(id.begin(), id.end(), module->getID()) == id.end();
1075 }
1076
1077 const auto range = del.equal_range(module->getString());
1078
1079 for (auto i = range.first; i != range.second; ++i) {
1080 if (i->second == module->getFloor()) {
1081 __rm__ = true;
1082 }
1083 }
1084
1085 if (__rm__)
1086 module = detector.erase(module);
1087 else
1088 ++module;
1089 }
1090 }
1091
1092
1093 for (vector< pair<int, JModifier> >::const_iterator i = mod.begin(); i != mod.end(); ++i) {
1094
1095 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1096
1097 if (module->getID() == i->first || i->first == WILDCARD ){
1098
1099 if (debug >= debug_t) {
1100 print(cout, *module, i->second);
1101 }
1102
1103 if (!i->second.apply(*module)) {
1104 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1105 }
1106 }
1107 }
1108 }
1109
1110
1111 for (vector< pair<int, JModifier> >::const_iterator i = str.begin(); i != str.end(); ++i) {
1112
1113 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1114
1115 if (module->getString() == i->first || i->first == WILDCARD) {
1116
1117 const JModifier modifier = getModifier(module->getString(), i->second);
1118
1119 if (debug >= debug_t) {
1120 print(cout, *module, i->second);
1121 }
1122
1123 if (!modifier.apply(*module)) {
1124 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1125 }
1126 }
1127 }
1128 }
1129
1130
1131 for (vector< pair<int, JModifier> >::const_iterator i = dos.begin(); i != dos.end(); ++i) {
1132
1133 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1134
1135 if (module->getFloor() != 0) {
1136
1137 if (module->getString() == i->first || i->first == WILDCARD) {
1138
1139 const JModifier modifier = getModifier(module->getString(), i->second);
1140
1141 if (debug >= debug_t) {
1142 print(cout, *module, i->second);
1143 }
1144
1145 if (!modifier.apply(*module)) {
1146 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1147 }
1148 }
1149 }
1150 }
1151 }
1152
1153
1154 for (vector< pair<int, JModuleModifier> >::const_iterator i = wip.begin(); i != wip.end(); ++i) {
1155
1156 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1157
1158 if (module->getID() == i->first || i->first == WILDCARD ){
1159
1160 if (debug >= debug_t) {
1161 print(cout, *module, i->second);
1162 }
1163
1164 if (!i->second.apply(*module)) {
1165 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1166 }
1167 }
1168 }
1169 }
1170
1171
1172 for (vector< pair<JPMTIdentifier, JPMTModifier> >::const_iterator i = pmt.begin(); i != pmt.end(); ++i) {
1173
1174 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1175
1176 if (module->getID() == i->first.getModuleID() || i->first.getModuleID() == WILDCARD) {
1177
1178 if (debug >= debug_t) {
1179 print(cout, i->first, i->second);
1180 }
1181
1182 if (i->first.getPMTAddress() == WILDCARD) {
1183
1184 for (int pmt = 0; pmt != getNumberOfPMTs(*module); ++pmt) {
1185 if (!i->second.apply(module->getPMT(pmt))) {
1186 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1187 }
1188 }
1189
1190 } else if (i->first.getPMTAddress() >= 0 &&
1191 i->first.getPMTAddress() < getNumberOfPMTs(*module) &&
1192 !i->second.apply(module->getPMT(i->first.getPMTAddress()))) {
1193 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1194 }
1195 }
1196 }
1197 }
1198
1199
1200 if (!alt.empty() || !ring.empty()) {
1201
1202 if (!hasDetectorAddressMap(detector.getID())) {
1203 FATAL("Invalid detector identifier " << detector.getID() << endl);
1204 }
1205
1206 const JDetectorAddressMap& demo = getDetectorAddressMap(detector.getID());
1207
1208 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1209
1210 const JModuleAddressMap memo = demo.get(module->getID());
1211
1212 for (vector< pair<JPMTPhysicalAddress, JPMTModifier> >::const_iterator i = alt.begin(); i != alt.end(); ++i) {
1213
1214 const JPMTIdentifier id(module->getID(), memo.getAddressTranslator(i->first).tdc);
1215
1216 if (debug >= debug_t) {
1217 print(cout, id, i->second);
1218 }
1219
1220 if (!i->second.apply(module->getPMT(id.getPMTAddress()))) {
1221 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1222 }
1223 }
1224
1225 const auto range = ring.equal_range(module->getID());
1226
1227 for (auto i = range.first; i != range.second; ++i) {
1228
1229 JPMTPhysicalAddress modifier = i->second;
1230
1231 modifier.ring = (char) toupper(modifier.ring);
1232
1233 if (modifier.ring != 'A') {
1234
1236
1237 for (size_t i = 0; i != module->size(); ++i) {
1238
1239 const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i);
1240
1241 if (address.ring == modifier.ring) {
1242 buffer[address] = (*module)[i];
1243 }
1244 }
1245
1246 for (size_t i = 0; i != module->size(); ++i) {
1247
1248 const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i);
1249
1250 if (address.ring == modifier.ring) {
1251
1252 int position = address.position + modifier.position;
1253
1254 while (position > 6) { position -= 6; }
1255 while (position < 1) { position += 6; }
1256
1257 const JPMTPhysicalAddress source(modifier.ring, position);
1258
1259 DEBUG("Module " << setw(10) << module->getID() << ' ' << address << " <= " << source << endl);
1260
1261 (*module)[i] = buffer[source];
1262 }
1263 }
1264 }
1265 }
1266 }
1267 }
1268
1269
1270 switch (option) {
1271 case 1:
1272 sort(detector.begin(), detector.end(), make_comparator(&JModule::getID));
1273 break;
1274
1275 case 2:
1276 sort(detector.begin(), detector.end(), make_comparator(&JModule::getLocation));
1277 break;
1278
1279 default:
1280 break;
1281 };
1282
1283
1284 try {
1286 }
1287 catch(const JException& error) {
1288 FATAL(error);
1289 }
1290}
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
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 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, const char delimiter=' ', const bool useColors=true)
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).
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