#include #include #include #include #include #include #include #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" namespace { using namespace JPP; /** * Wild card for string identifier, module identifier or PMT address. */ static const int WILDCARD = -1; static const std::string reset_t = "reset"; //!< Reset time offset, position and PMT status bit static const std::string set_t = "set"; //!< Set time offset, position or PMT status bit static const std::string setx_t = "setx"; //!< Set x-position static const std::string sety_t = "sety"; //!< Set y-position static const std::string setz_t = "setz"; //!< Set z-position static const std::string addx_t = "addx"; //!< Add x-position static const std::string addy_t = "addy"; //!< Add y-position static const std::string addz_t = "addz"; //!< Add z-position static const std::string subx_t = "subx"; //!< Subtract x-position static const std::string suby_t = "suby"; //!< Subtract y-position static const std::string subz_t = "subz"; //!< Subtract z-position static const std::string add_t = "add"; //!< Add time offset or position static const std::string sub_t = "sub"; //!< Subtract time offset or position static const std::string rot_t = "rot"; //!< Rotate around z-axis by value [rad] static const std::string lower_t = "lower"; //!< Rotate lower hemisphere around z-axis by value [rad] static const std::string upper_t = "upper"; //!< Rotate upper hemisphere around z-axis by value [rad] static const std::string mul_t = "mul"; //!< Multiply z-position by (1 + value) static const std::string div_t = "div"; //!< Divide z-position by (1 + value) static const std::string tilt_t = "tilt"; //!< Tilt string static const std::string swap_t = "swap"; //!< Swap PMTs static const std::string assign_t = "assign"; //!< Assign module identifier static const std::string locate_t = "locate"; //!< Locate module identifier static const std::string string_t = "string"; //!< Assign string number static const std::string rand_t = "rand"; //!< Random value(s) static const std::string randset_t = rand_t + set_t; //!< Set time offset or position static const std::string randadd_t = rand_t + add_t; //!< Add time offset or position static const std::string randsub_t = rand_t + sub_t; //!< Subtract time offset or position static const std::string randrot_t = rand_t + rot_t; //!< Rotate around z-axis by value [rad] static const std::string randmul_t = rand_t + mul_t; //!< Multiply z-position by (1 + value) static const std::string randdiv_t = rand_t + div_t; //!< Divide z-position by (1 + value) static const std::string randtilt_t = rand_t + tilt_t; //!< Tilt string static const std::string RESET_t = "RESET"; //!< Reset time offset of piezo/hydrophone and quaternion calibration of compass static const std::string SET_t = "SET"; //!< Set time offset of piezo/hydrophone or quaternion calibration of compass static const std::string ADD_t = "ADD"; //!< Add time offset of piezo/hydrophone or quaternion calibration of compass static const std::string SUB_t = "SUB"; //!< Subtract time offset of piezo/hydrophone or quaternion calibration of compass static const std::string ROT_t = "ROT"; //!< Rotate quaternion calibration of compass around z-axis by value [rad] /** * Apply action to given module. * * \param module module (I/O) * \param action action * \return true if valid action; else false */ inline bool apply(JModule& module, const std::string& action) { if (action == reset_t) { // position does not depend on module but may not exactly be at origin module.setCalibration(JCalibration()); module.setStatus(JStatus()); module.setQuaternion(JQuaternion3D()); module.set(getModule(1).getPosition()); for (JModule::iterator pmt = module.begin(); pmt != module.end(); ++pmt) { pmt->setCalibration(JCalibration()); pmt->setStatus(JStatus()); } } else if (action == RESET_t) { module.setCalibration(JCalibration()); module.setQuaternion(JQuaternion3D()); module.setCalibration(getAverage(make_array(module.begin(), module.end(), &JPMT::getT0), 0.0)); } else { return false; } return true; } /** * Apply action to given module. * * \param module module (I/O) * \param action action * \param value value * \return true if valid action; else false */ inline bool apply(JModule& module, const std::string& action, const double value) { if (action == set_t) { // actions with fixed values module.set(value); } else if (action == setx_t) { module.set(JVector3D(value, module.getY(), module.getZ())); } else if (action == addx_t) { module.add(JVector3D(value, 0.0, 0.0)); } else if (action == subx_t) { module.sub(JVector3D(value, 0.0, 0.0)); } else if (action == sety_t) { module.set(JVector3D(module.getX(), value, module.getZ())); } else if (action == addy_t) { module.add(JVector3D(0.0, value, 0.0)); } else if (action == suby_t) { module.sub(JVector3D(0.0, value, 0.0)); } else if (action == setz_t) { module.set(JVector3D(module.getX(), module.getY(), value)); } else if (action == addz_t) { module.add(JVector3D(0.0, 0.0, value)); } else if (action == subz_t) { module.sub(JVector3D(0.0, 0.0, value)); } else if (action == add_t) { module.add(value); } else if (action == sub_t) { module.sub(value); } else if (action == rot_t) { const JVector3D center = module.getPosition(); module.sub(center); module.rotate(JRotation3Z(value)); module.add(center); } else if (action == lower_t || action == upper_t) { const JVector3D center = module.getPosition(); module.sub(center); const JRotation3Z R(value); for (JModule::iterator pmt = module.begin(); pmt != module.end(); ++pmt) { if ((action == upper_t && pmt->getDZ() > 0.0) || (action == lower_t && pmt->getDZ() < 0.0)) { pmt->rotate(R); } } module.add(center); } else if (action == mul_t) { JVector3D center; if (value > 0.0) center = JVector3D(module.getPosition().getX(), module.getPosition().getY(), module.getPosition().getZ() * (1.0 + value)); else center = JVector3D(module.getPosition().getX(), module.getPosition().getY(), module.getPosition().getZ() / (1.0 - value)); module.set(center); } else if (action == div_t) { JVector3D center; if (value > 0.0) center = JVector3D(module.getPosition().getX(), module.getPosition().getY(), module.getPosition().getZ() / (1.0 + value)); else center = JVector3D(module.getPosition().getX(), module.getPosition().getY(), module.getPosition().getZ() * (1.0 - value)); module.set(center); } else if (action == SET_t) { module.getCalibration().setT0(value); } else if (action == ADD_t) { module.getCalibration().addT0(value); } else if (action == SUB_t) { module.getCalibration().subT0(value); } else if (action == ROT_t) { module.setQuaternion(JQuaternion3Z(value) * module.getQuaternion()); } else if (action == randadd_t) { // actions with random values module.add(gRandom->Gaus(0.0, value)); } else if (action == randsub_t) { module.sub(gRandom->Gaus(0.0, value)); } else if (action == randrot_t){ const JVector3D center = module.getPosition(); module.sub(center); module.rotate(JRotation3Z(gRandom->Gaus(0.0, value))); module.add(center); } else if (action == randmul_t) { const JVector3D center(module.getPosition().getX(), module.getPosition().getY(), module.getPosition().getZ() * gRandom->Gaus(1.0, value)); module.set(center); } else if (action == randdiv_t) { const JVector3D center(module.getPosition().getX(), module.getPosition().getY(), module.getPosition().getZ() / gRandom->Gaus(1.0, value)); module.set(center); } else if (action == assign_t) { // action with assigments module.setID((int) value); } else if (action == string_t) { module.setLocation(JLocation((int) value, module.getFloor())); } else { // return false; } return true; } /** * Apply action to given module. * * \param module module (I/O) * \param action action * \param first first value * \param second second value * \return true if valid action; else false */ inline bool apply(JModule& module, const std::string& action, const double first, const double second) { if (action == tilt_t) { // actions with fixed values const double Tx = first; const double Ty = second; const double Tz = sqrt(1.0 - Tx*Tx - Ty*Ty); const double x = Tx * module.getZ() + module.getX(); const double y = Ty * module.getZ() + module.getY(); const double z = Tz * module.getZ(); module.set(JPosition3D(x,y,z)); } else if (action == locate_t) { module.setLocation(JLocation((int) first, (int) second)); } else if (action == swap_t) { std::swap(module[(int) first], module[(int) second]); } else { // return false; } return true; } /** * Apply action to given module. * * \param module module (I/O) * \param action action * \param pos pos * \return true if valid action; else false */ inline bool apply(JModule& module, const std::string& action, const JVector3D& pos) { const JVector3D randpos(gRandom->Gaus(0.0, pos.getX()), gRandom->Gaus(0.0, pos.getY()), gRandom->Gaus(0.0, pos.getZ())); if (action == set_t) // actions with fixed values module.set(pos); else if (action == add_t) module.add(pos); else if (action == sub_t) module.sub(pos); else if (action == randset_t) // actions with random values module.set(randpos); else if (action == randadd_t) module.add(randpos); else if (action == randsub_t) module.sub(randpos); else return false; return true; } /** * Apply action to given module. * * \param module module (I/O) * \param action action * \param Q quaternion * \return true if valid action; else false */ inline bool apply(JModule& module, const std::string& action, const JQuaternion3D& Q) { if (action == SET_t) module.setQuaternion(Q); else if (action == ADD_t) module.setQuaternion(Q * module.getQuaternion()); else if (action == SUB_t) module.setQuaternion(Q.getConjugate() * module.getQuaternion()); else return false; module.getQuaternion().normalise(); return true; } /** * Apply action to given module. * * \param module module (I/O) * \param action action * \param value value * \return true if valid action; else false */ inline bool apply(JModule& module, const std::string& action, const std::string& value) { try { if (action == set_t) module.getStatus().set (getModuleStatusBit(value)); else if (action == reset_t) module.getStatus().reset(getModuleStatusBit(value)); else return false; return true; } catch(const std::exception&) { return false; } } /** * Apply action to given PMT. * * \param pmt PMT (I/O) * \param action action * \param value value * \return true if valid action; else false */ inline bool apply(JPMT& pmt, const std::string& action, const std::string& value) { try { if (action == set_t) pmt.getStatus().set (getPMTStatusBit(value)); else if (action == reset_t) pmt.getStatus().reset(getPMTStatusBit(value)); else return false; return true; } catch(const std::exception&) { return false; } } /** * Auxiliary class for module modifications. */ struct JModifier { /** * Default constructor. */ JModifier() {} /** * Check validity. * * \return true if valid modifier; else false */ bool is_valid() const { return (action != "" && !data.empty()); } /** * Apply action to given module depending on number of values. * * \param module module * \return true if valid action; else false */ bool apply(JModule& module) const { switch (data.size()) { case 0: return ::apply(module, action); case 1: return ::apply(module, action, data[0]); case 2: return ::apply(module, action, data[0], data[1]); case 3: return ::apply(module, action, JVector3D(data[0], data[1], data[2])); case 4: return ::apply(module, action, JQuaternion3D(data[0], data[1], data[2], data[3])); default: return false; } } /** * Read modifier from input. * * \param in input stream * \param modifier modifier * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JModifier& modifier) { if (in >> modifier.action) { modifier.data.clear(); for (double x; in >> x; ) { modifier.data.push_back(x); } in.clear(std::ios_base::eofbit); } return in; } /** * Write modifier to output. * * \param out output stream * \param modifier modifier * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JModifier& modifier) { out << modifier.action; for (std::vector::const_iterator i = modifier.data.begin(); i != modifier.data.end(); ++i) { out << ' ' << *i; } return out; } std::string action; std::vector data; }; /** * Get modifier for given string. * * For actions ranXXX, the corresponding action XXX is made the same for all modules in the given string.\n * For all other options, the input action is maintained. * * \param id string number * \param modifier modifier * \return modifier */ inline const JModifier& getModifier(const int id, const JModifier& modifier) { using namespace std; static map > > buffer; const string::size_type pos = modifier.action.find(rand_t); if (pos != string::npos) { JModifier& result = buffer[id][modifier.action][modifier.data.size()]; if (!result.is_valid()) { result.action = modifier.action.substr(pos + rand_t.length()); for (size_t i = 0; i != modifier.data.size(); ++i) { result.data.push_back(gRandom->Gaus(0.0, modifier.data[i])); } } return result; } else { return modifier; } } /** * Auxiliary class for module status modifications. */ struct JModuleModifier { /** * Default constructor. */ JModuleModifier() {} /** * Apply action to given module. * * \param module module * \return true if valid action; else false */ bool apply(JModule& module) const { return ::apply(module, action, value); } /** * Read module modifier from input. * * \param in input stream * \param modifier modifier * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JModuleModifier& modifier) { return in >> modifier.action >> modifier.value; } /** * Write module modifier to output. * * \param out output stream * \param modifier modifier * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JModuleModifier& modifier) { out << modifier.action; out << ' '; out << modifier.value; return out; } std::string action; std::string value; }; /** * Auxiliary class for PMT status modifications. */ struct JPMTModifier { /** * Default constructor. */ JPMTModifier() {} /** * Apply action to given PMT. * * \param pmt PMT * \return true if valid action; else false */ bool apply(JPMT& pmt) const { return ::apply(pmt, action, value); } /** * Read PMT modifier from input. * * \param in input stream * \param modifier modifier * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JPMTModifier& modifier) { return in >> modifier.action >> modifier.value; } /** * Write PMT modifier to output. * * \param out output stream * \param modifier modifier * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JPMTModifier& modifier) { out << modifier.action; out << ' '; out << modifier.value; return out; } std::string action; std::string value; }; /** * Range of string numbers. * * The input format could be a single number or two numbers separated by JRange_t::SEPARATOR. */ struct JRange_t : public JRange { /** * Separator between two identifier values. */ static const char SEPARATOR = '-'; /** * Default constructor. */ JRange_t() : JRange(-1, -1) {} /** * Read range from input. * * \param in input stream * \param range range * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JRange_t& range) { if (in >> range.first) { range.second = range.first; if (in.peek() == (int) JRange_t::SEPARATOR) { in.get(); in >> range.second; } else { in.clear(); } } return in; } /** * Write range to output. * * \param out output stream * \param range range * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JRange_t& range) { return out << range.first << JRange_t::SEPARATOR << range.second; } }; /** * Print module modification. * * \param out output stream * \param module module * \param modifier modifier */ inline void print(std::ostream& out, const JModule& module, const JModifier& modifier) { using namespace std; using namespace JPP; out << "Modifier" << ' ' << getLabel(module.getLocation()) << ' ' << setw(10) << module.getID() << ' ' << "action " << modifier << endl; } /** * Print module modification. * * \param out output stream * \param id module identifier * \param modifier modifier */ inline void print(std::ostream& out, const JModuleIdentifier& id, const JModuleModifier& modifier) { using namespace std; using namespace JPP; out << "module modifier" << ' ' << "(" << setw(10) << id.getID() << ")" << ' ' << "action" << ' ' << modifier.action << ' ' << "value" << ' ' << modifier.value << endl; } /** * Print PMT modification. * * \param out output stream * \param pmt PMT identifier * \param modifier modifier */ inline void print(std::ostream& out, const JPMTIdentifier& pmt, const JPMTModifier& modifier) { using namespace std; using namespace JPP; out << "PMT modifier" << ' ' << "(" << setw(10) << pmt.getID() << "," << setw(2) << pmt.getPMTAddress() << ")" << ' ' << "action" << ' ' << modifier.action << ' ' << "value" << ' ' << modifier.value << endl; } } /** * \file * * Auxiliary program to modify detector calibration. * * Syntax: *
 *     -M     "     (set|add|sub|randset|randadd|randsub) x0 [x1 x2]"
 *     -(S|s) "         (set|add|sub|randset|randadd|randsub) x0 [x1 x2]"
 *     -M     "     (setx|addx|subx|sety|addy|suby|setz|addz|subz) value"
 *     -(S|s) "         (setx|addx|subx|sety|addy|suby|setz|addz|subz) value"
 *     -M     "     (rot|randrot|lower|upper) phi"
 *     -(S|s) "         (rot|randrot) phi"
 *     -M     "     (mul|randmul) factor"
 *     -(S|s) "         (mul|randmul) factor"
 *     -M     "     (div|randdiv) factor"
 *     -(S|s) "         (div|randdiv) factor"
 *     -M     "     (reset)"
 *     -(S|s) "         (reset)"
 *     -M     "     (assign)  identifier"
 *     -M     "     (locate)   "
 *     -M     "     (swap)        "
 *     -M     "     (SET|ADD|SUB|) x0 [x1 x2 x3]"
 *     -(S|s) "         (SET|ADD|SUB|) x0 [x1 x2 x3]"
 *     -M     "     (ROT) phi"
 *     -(S|s) "         (ROT) phi"
 *     -(S|s) "         (tilt|randtilt) Tx Ty"
 *     -R     "     "
 *     -W     "     (set|reset)  (MODULE_DISABLE|COMPASS_DISABLE|HYDROPHONE_DISABLE|PIEZO_DISABLE|MODULE_OUT_OF_SYNC)"
 *     -P     "        (set|reset)  (PMT_DISABLE|HIGH_RATE_VETO_DISABLE|FIFO_FULL_DISABLE|UDP_COUNTER_DISABLE|UDP_TRAILER_DISABLE|OUT_OF_SYNC)"
 *     -p     "  (set|reset)  (PMT_DISABLE|HIGH_RATE_VETO_DISABLE|FIFO_FULL_DISABLE|UDP_COUNTER_DISABLE|UDP_TRAILER_DISABLE|OUT_OF_SYNC)"
 *     -k     "[-]"
 *     -r     "[-]"
 *     -m     ""
 *     -D     " "
 *     -\@    "=[;="
 * 
* Options -M and -S refer to a module and a string, respectively.\n * The values provided for a string modification coherently apply to the modules of the specified string number.\n * 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: * -# time calibration (t = x0) * -# invalid * -# 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.\n * The options upper and lower refer to a rotation of the PMTs in the upper and lower hemisphere of the module, respectively.\n * 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.\n * 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: * -# time calibration of piezo sensor or hydrophone (t = x0) * -# invalid * -# invalid * -# 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.\n * 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.\n * 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.\n * 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.\n * 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 */ int main(int argc, char **argv) { using namespace std; using namespace JPP; typedef JToken<';'> JToken_t; string inputFile; string outputFile; vector hdr; vector< pair > mod; vector< pair > str; vector< pair > dos; vector< pair > wip; vector< pair > pmt; vector< pair > alt; multimap ring; vector keep; vector rm; vector id; multimap del; int option; bool squash; int debug; try { JParser<> zap("Auxiliary program to modify detector."); zap['a'] = make_field(inputFile); zap['o'] = make_field(outputFile); zap['@'] = make_field(hdr, "header modification") = JPARSER::initialised(); zap['M'] = make_field(mod, "module modification") = JPARSER::initialised(); zap['S'] = make_field(str, "string modification (optical modules and base modules)") = JPARSER::initialised(); zap['s'] = make_field(dos, "string modification (optical modules only)") = JPARSER::initialised(); zap['W'] = make_field(wip, "module status modification") = JPARSER::initialised(); zap['P'] = make_field(pmt, "PMT status modification by PMT logical address") = JPARSER::initialised(); zap['p'] = make_field(alt, "PMT status modification by PMT physical address") = JPARSER::initialised(); zap['R'] = make_field(ring, "rotate positions of PMTs in ring") = JPARSER::initialised(); zap['k'] = make_field(keep, "keep string[s]") = JPARSER::initialised(); zap['r'] = make_field(rm, "remove string[s]") = JPARSER::initialised(); zap['m'] = make_field(id, "maintain module by identifier") = JPARSER::initialised(); zap['D'] = make_field(del, "remove module by location") = JPARSER::initialised(); zap['O'] = make_field(option, "sort modules: "\ "0 -> no sort; 1 -> module identifier; 2 -> module location") = 0, 1, 2; zap['q'] = make_field(squash, "squash meta data"); zap['d'] = make_field(debug, "debug level") = 2; zap(argc, argv); } catch(const exception &error) { FATAL(error.what() << endl); } gRandom->SetSeed(0); const int ns = ((keep.empty() ? 0 : 1) + (rm .empty() ? 0 : 1) + (id .empty() ? 0 : 1) + (del .empty() ? 0 : 1)); if (ns > 1) { FATAL("Use either option -k, -r, -m or -D." << endl); } JDetector detector; try { load(inputFile, detector); } catch(const JException& error) { FATAL(error); } if (squash) { detector.comment.clear(); } detector.comment.add(JMeta(argc,argv)); if (detector.setToLatestVersion()) { NOTICE("Set detector version to " << detector.getVersion() << endl); } if (!hdr.empty()) { int id = -1; JProperties helper = detector.getProperties(); helper["id"] = id; for (vector::const_iterator i = hdr.begin(); i != hdr.end(); ++i) { istringstream is(*i); is >> helper; } if (id != -1) { detector.setID(id); } } if (ns != 0) { for (JDetector::iterator module = detector.begin(); module != detector.end(); ) { bool __rm__ = !keep.empty() && rm.empty(); for (vector::const_iterator i = keep.begin(); i != keep.end(); ++i) { if (module->getString() >= i->first && module->getString() <= i->second) { __rm__ = false; } } for (vector::const_iterator i = rm.begin(); i != rm.end(); ++i) { if (module->getString() >= i->first && module->getString() <= i->second) { __rm__ = true; } } if (!id.empty()) { __rm__ = find(id.begin(), id.end(), module->getID()) == id.end(); } const auto range = del.equal_range(module->getString()); for (auto i = range.first; i != range.second; ++i) { if (i->second == module->getFloor()) { __rm__ = true; } } if (__rm__) module = detector.erase(module); else ++module; } } for (vector< pair >::const_iterator i = mod.begin(); i != mod.end(); ++i) { for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) { if (module->getID() == i->first || i->first == WILDCARD ){ if (debug >= debug_t) { print(cout, *module, i->second); } if (!i->second.apply(*module)) { ERROR("No valid action: " << i->first << ' ' << i->second << endl); } } } } for (vector< pair >::const_iterator i = str.begin(); i != str.end(); ++i) { for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) { if (module->getString() == i->first || i->first == WILDCARD) { const JModifier modifier = getModifier(module->getString(), i->second); if (debug >= debug_t) { print(cout, *module, i->second); } if (!modifier.apply(*module)) { ERROR("No valid action: " << i->first << ' ' << i->second << endl); } } } } for (vector< pair >::const_iterator i = dos.begin(); i != dos.end(); ++i) { for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) { if (module->getFloor() != 0) { if (module->getString() == i->first || i->first == WILDCARD) { const JModifier modifier = getModifier(module->getString(), i->second); if (debug >= debug_t) { print(cout, *module, i->second); } if (!modifier.apply(*module)) { ERROR("No valid action: " << i->first << ' ' << i->second << endl); } } } } } for (vector< pair >::const_iterator i = wip.begin(); i != wip.end(); ++i) { for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) { if (module->getID() == i->first || i->first == WILDCARD ){ if (debug >= debug_t) { print(cout, *module, i->second); } if (!i->second.apply(*module)) { ERROR("No valid action: " << i->first << ' ' << i->second << endl); } } } } for (vector< pair >::const_iterator i = pmt.begin(); i != pmt.end(); ++i) { for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) { if (module->getID() == i->first.getModuleID() || i->first.getModuleID() == WILDCARD) { if (debug >= debug_t) { print(cout, i->first, i->second); } if (i->first.getPMTAddress() == WILDCARD) { for (int pmt = 0; pmt != getNumberOfPMTs(*module); ++pmt) { if (!i->second.apply(module->getPMT(pmt))) { ERROR("No valid action: " << i->first << ' ' << i->second << endl); } } } else if (i->first.getPMTAddress() >= 0 && i->first.getPMTAddress() < getNumberOfPMTs(*module) && !i->second.apply(module->getPMT(i->first.getPMTAddress()))) { ERROR("No valid action: " << i->first << ' ' << i->second << endl); } } } } if (!alt.empty() || !ring.empty()) { if (!hasDetectorAddressMap(detector.getID())) { FATAL("Invalid detector identifier " << detector.getID() << endl); } const JDetectorAddressMap& demo = getDetectorAddressMap(detector.getID()); for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) { const JModuleAddressMap memo = demo.get(module->getID()); for (vector< pair >::const_iterator i = alt.begin(); i != alt.end(); ++i) { const JPMTIdentifier id(module->getID(), memo.getAddressTranslator(i->first).tdc); if (debug >= debug_t) { print(cout, id, i->second); } if (!i->second.apply(module->getPMT(id.getPMTAddress()))) { ERROR("No valid action: " << i->first << ' ' << i->second << endl); } } const auto range = ring.equal_range(module->getID()); for (auto i = range.first; i != range.second; ++i) { JPMTPhysicalAddress modifier = i->second; modifier.ring = (char) toupper(modifier.ring); if (modifier.ring != 'A') { map buffer; for (size_t i = 0; i != module->size(); ++i) { const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i); if (address.ring == modifier.ring) { buffer[address] = (*module)[i]; } } for (size_t i = 0; i != module->size(); ++i) { const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i); if (address.ring == modifier.ring) { int position = address.position + modifier.position; while (position > 6) { position -= 6; } while (position < 1) { position += 6; } const JPMTPhysicalAddress source(modifier.ring, position); DEBUG("Module " << setw(10) << module->getID() << ' ' << address << " <= " << source << endl); (*module)[i] = buffer[source]; } } } } } } switch (option) { case 1: sort(detector.begin(), detector.end(), make_comparator(&JModule::getID)); break; case 2: sort(detector.begin(), detector.end(), make_comparator(&JModule::getLocation)); break; default: break; }; try { store(outputFile, detector); } catch(const JException& error) { FATAL(error); } }