File indexing completed on 2023-05-11 02:21:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013 #include "FWCore/Framework/interface/SourceFactory.h"
0014 #include "FWCore/Framework/interface/ModuleFactory.h"
0015 #include "FWCore/Framework/interface/ESHandle.h"
0016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0017 #include "FWCore/Framework/interface/ESProducer.h"
0018 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0019 #include "FWCore/Framework/interface/ESProducts.h"
0020 #include "FWCore/Framework/interface/SourceFactory.h"
0021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0022
0023 #include "DataFormats/CTPPSDetId/interface/TotemRPDetId.h"
0024 #include "DataFormats/CTPPSDetId/interface/CTPPSDiamondDetId.h"
0025 #include "DataFormats/CTPPSDetId/interface/TotemTimingDetId.h"
0026 #include "DataFormats/CTPPSDetId/interface/TotemT2DetId.h"
0027
0028 #include "CondFormats/DataRecord/interface/TotemReadoutRcd.h"
0029 #include "CondFormats/PPSObjects/interface/TotemDAQMapping.h"
0030 #include "CondFormats/PPSObjects/interface/TotemAnalysisMask.h"
0031 #include "CondFormats/PPSObjects/interface/TotemFramePosition.h"
0032 #include "Utilities/Xerces/interface/Xerces.h"
0033 #include "Utilities/Xerces/interface/XercesStrUtils.h"
0034
0035 #include <xercesc/parsers/XercesDOMParser.hpp>
0036 #include <xercesc/dom/DOM.hpp>
0037 #include <xercesc/sax/HandlerBase.hpp>
0038 #include <xercesc/util/XMLString.hpp>
0039 #include <xercesc/util/PlatformUtils.hpp>
0040
0041 #include <memory>
0042 #include <sstream>
0043
0044
0045
0046
0047
0048 using namespace std;
0049
0050
0051
0052
0053 class TotemDAQMappingESSourceXML : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder {
0054 public:
0055 static const std::string tagVFAT;
0056 static const std::string tagChannel;
0057 static const std::string tagAnalysisMask;
0058
0059
0060 static const std::string tagArm;
0061
0062
0063 static const std::string tagRPStation;
0064 static const std::string tagRPPot;
0065 static const std::string tagRPPlane;
0066
0067
0068 static const std::string tagChip1;
0069 static const std::string tagChip2;
0070
0071
0072 static const std::string tagDiamondPlane;
0073 static const std::string tagDiamondCh;
0074
0075
0076 static const std::string tagSampicBoard;
0077 static const std::string tagSampicCh;
0078 static const std::string tagTotemTimingCh;
0079 static const std::string tagTotemTimingPlane;
0080
0081
0082 static const std::string tagTotemT2Plane;
0083 static const std::string tagTotemT2Tile;
0084
0085 TotemDAQMappingESSourceXML(const edm::ParameterSet &);
0086 ~TotemDAQMappingESSourceXML() override;
0087
0088 edm::ESProducts<std::unique_ptr<TotemDAQMapping>, std::unique_ptr<TotemAnalysisMask>> produce(const TotemReadoutRcd &);
0089
0090 private:
0091 unsigned int verbosity;
0092
0093
0094 string subSystemName;
0095
0096
0097 unsigned int sampicSubDetId;
0098
0099
0100 bool packedPayload;
0101
0102
0103 std::vector<std::string> mappingFileNames;
0104
0105 struct ConfigBlock {
0106
0107 edm::EventRange validityRange;
0108
0109
0110 std::vector<std::string> mappingFileNames;
0111
0112
0113 std::vector<std::string> maskFileNames;
0114 };
0115
0116 vector<ConfigBlock> configuration;
0117
0118
0119 unsigned int currentBlock;
0120
0121
0122 bool currentBlockValid;
0123
0124
0125 enum NodeType {
0126 nUnknown,
0127 nSkip,
0128 nTop,
0129 nArm,
0130 nRPStation,
0131 nRPPot,
0132 nRPPlane,
0133 nDiamondPlane,
0134 nChip,
0135 nDiamondCh,
0136 nChannel,
0137 nSampicBoard,
0138 nSampicChannel,
0139 nTotemTimingPlane,
0140 nTotemTimingCh,
0141 nTotemT2Plane,
0142 nTotemT2Tile
0143 };
0144
0145
0146 enum ParseType { pMapping, pMask };
0147
0148
0149 void ParseXML(ParseType,
0150 const string &file,
0151 const std::unique_ptr<TotemDAQMapping> &,
0152 const std::unique_ptr<TotemAnalysisMask> &);
0153
0154
0155 void ParseTreeRP(ParseType,
0156 xercesc::DOMNode *,
0157 NodeType,
0158 unsigned int parentID,
0159 const std::unique_ptr<TotemDAQMapping> &,
0160 const std::unique_ptr<TotemAnalysisMask> &);
0161
0162
0163 void ParseTreeDiamond(ParseType,
0164 xercesc::DOMNode *,
0165 NodeType,
0166 unsigned int parentID,
0167 const std::unique_ptr<TotemDAQMapping> &,
0168 const std::unique_ptr<TotemAnalysisMask> &);
0169
0170
0171 void ParseTreeTotemTiming(ParseType,
0172 xercesc::DOMNode *,
0173 NodeType,
0174 unsigned int parentID,
0175 const std::unique_ptr<TotemDAQMapping> &,
0176 const std::unique_ptr<TotemAnalysisMask> &);
0177
0178
0179 void ParseTreeTotemT2(ParseType,
0180 xercesc::DOMNode *,
0181 NodeType,
0182 unsigned int parentID,
0183 const std::unique_ptr<TotemDAQMapping> &,
0184 const std::unique_ptr<TotemAnalysisMask> &);
0185
0186 private:
0187
0188 string CompleteFileName(const string &fn);
0189
0190
0191 bool Test(xercesc::DOMNode *node, const std::string &name) {
0192 return !(name.compare(cms::xerces::toString(node->getNodeName())));
0193 }
0194
0195
0196 NodeType GetNodeType(xercesc::DOMNode *);
0197
0198
0199 string GetNodeContent(xercesc::DOMNode *parent) { return string(cms::xerces::toString(parent->getTextContent())); }
0200
0201
0202 string GetNodeValue(xercesc::DOMNode *node) { return cms::xerces::toString(node->getNodeValue()); }
0203
0204
0205 TotemFramePosition ChipFramePosition(xercesc::DOMNode *chipnode);
0206
0207
0208 TotemT2FramePosition ChipT2FramePosition(xercesc::DOMNode *chipnode);
0209
0210 void GetChannels(xercesc::DOMNode *n, std::set<unsigned char> &channels);
0211
0212 bool RPNode(NodeType type) {
0213 return ((type == nArm) || (type == nRPStation) || (type == nRPPot) || (type == nRPPlane) || (type == nChip));
0214 }
0215
0216 bool DiamondNode(NodeType type) {
0217 return ((type == nArm) || (type == nRPStation) || (type == nRPPot) || (type == nDiamondPlane) ||
0218 (type == nDiamondCh));
0219 }
0220
0221 bool TotemTimingNode(NodeType type) {
0222 return ((type == nArm) || (type == nRPStation) || (type == nRPPot) || (type == nSampicBoard) ||
0223 (type == nSampicChannel) || (type == nTotemTimingPlane) || (type == nTotemTimingCh));
0224 }
0225
0226 bool TotemT2Node(NodeType type) { return type == nArm || type == nTotemT2Plane || type == nTotemT2Tile; }
0227
0228 bool CommonNode(NodeType type) { return ((type == nChip) || (type == nArm)); }
0229
0230 protected:
0231
0232 void setIntervalFor(const edm::eventsetup::EventSetupRecordKey &,
0233 const edm::IOVSyncValue &,
0234 edm::ValidityInterval &) override;
0235 };
0236
0237
0238
0239 using namespace std;
0240 using namespace edm;
0241 using namespace xercesc;
0242
0243 const string TotemDAQMappingESSourceXML::tagVFAT = "vfat";
0244 const string TotemDAQMappingESSourceXML::tagChannel = "channel";
0245 const string TotemDAQMappingESSourceXML::tagAnalysisMask = "analysisMask";
0246
0247
0248 const string TotemDAQMappingESSourceXML::tagArm = "arm";
0249
0250
0251 const string TotemDAQMappingESSourceXML::tagChip1 = "vfat";
0252 const string TotemDAQMappingESSourceXML::tagChip2 = "test_vfat";
0253
0254
0255 const string TotemDAQMappingESSourceXML::tagRPStation = "station";
0256 const string TotemDAQMappingESSourceXML::tagRPPot = "rp_detector_set";
0257 const string TotemDAQMappingESSourceXML::tagRPPlane = "rp_plane";
0258
0259
0260 const string TotemDAQMappingESSourceXML::tagDiamondPlane = "rp_plane_diamond";
0261 const string TotemDAQMappingESSourceXML::tagDiamondCh = "diamond_channel";
0262
0263
0264 const string TotemDAQMappingESSourceXML::tagSampicBoard = "rp_sampic_board";
0265 const string TotemDAQMappingESSourceXML::tagSampicCh = "rp_sampic_channel";
0266 const string TotemDAQMappingESSourceXML::tagTotemTimingCh = "timing_channel";
0267 const string TotemDAQMappingESSourceXML::tagTotemTimingPlane = "timing_plane";
0268
0269
0270 const string TotemDAQMappingESSourceXML::tagTotemT2Plane = "nt2_plane";
0271 const string TotemDAQMappingESSourceXML::tagTotemT2Tile = "nt2_tile";
0272
0273
0274
0275 TotemDAQMappingESSourceXML::TotemDAQMappingESSourceXML(const edm::ParameterSet &conf)
0276 : verbosity(conf.getUntrackedParameter<unsigned int>("verbosity", 0)),
0277 subSystemName(conf.getUntrackedParameter<string>("subSystem")),
0278 sampicSubDetId(conf.getParameter<unsigned int>("sampicSubDetId")),
0279 packedPayload(conf.getUntrackedParameter<bool>("multipleChannelsPerPayload", false)),
0280 currentBlock(0),
0281 currentBlockValid(false) {
0282 for (const auto &it : conf.getParameter<vector<ParameterSet>>("configuration")) {
0283 ConfigBlock b;
0284 b.validityRange = it.getParameter<EventRange>("validityRange");
0285 b.mappingFileNames = it.getParameter<vector<string>>("mappingFileNames");
0286 b.maskFileNames = it.getParameter<vector<string>>("maskFileNames");
0287 configuration.push_back(b);
0288 }
0289
0290 setWhatProduced(this, subSystemName);
0291 findingRecord<TotemReadoutRcd>();
0292 }
0293
0294
0295
0296 void TotemDAQMappingESSourceXML::setIntervalFor(const edm::eventsetup::EventSetupRecordKey &key,
0297 const edm::IOVSyncValue &iosv,
0298 edm::ValidityInterval &oValidity) {
0299 LogVerbatim("TotemDAQMappingESSourceXML") << ">> TotemDAQMappingESSourceXML::setIntervalFor(" << key.name() << ")";
0300
0301 LogVerbatim("TotemDAQMappingESSourceXML")
0302 << " run=" << iosv.eventID().run() << ", event=" << iosv.eventID().event();
0303
0304 currentBlockValid = false;
0305 for (unsigned int idx = 0; idx < configuration.size(); ++idx) {
0306 const auto &bl = configuration[idx];
0307
0308 edm::EventRange range = bl.validityRange;
0309
0310
0311
0312
0313 if (range.startEventID().luminosityBlock() == 0 && range.startEventID().event() == 1)
0314 range = edm::EventRange(edm::EventID(range.startEventID().run(), 0, 0), range.endEventID());
0315
0316 if (edm::contains(range, iosv.eventID())) {
0317 currentBlockValid = true;
0318 currentBlock = idx;
0319
0320 const IOVSyncValue begin(range.startEventID());
0321 const IOVSyncValue end(range.endEventID());
0322 oValidity = edm::ValidityInterval(begin, end);
0323
0324 LogVerbatim("TotemDAQMappingESSourceXML") << " block found: index=" << currentBlock << ", interval=("
0325 << range.startEventID() << " - " << range.endEventID() << ")";
0326
0327 return;
0328 }
0329 }
0330
0331 if (!currentBlockValid) {
0332 throw cms::Exception("TotemDAQMappingESSourceXML::setIntervalFor")
0333 << "No configuration for event " << iosv.eventID();
0334 }
0335 }
0336
0337
0338
0339 TotemDAQMappingESSourceXML::~TotemDAQMappingESSourceXML() {}
0340
0341
0342
0343 string TotemDAQMappingESSourceXML::CompleteFileName(const string &fn) {
0344 FileInPath fip(fn);
0345 return fip.fullPath();
0346 }
0347
0348
0349 static inline std::string to_string(const XMLCh *ch) { return XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(ch); }
0350
0351 edm::ESProducts<std::unique_ptr<TotemDAQMapping>, std::unique_ptr<TotemAnalysisMask>>
0352 TotemDAQMappingESSourceXML::produce(const TotemReadoutRcd &) {
0353 assert(currentBlockValid);
0354
0355 auto mapping = std::make_unique<TotemDAQMapping>();
0356 auto mask = std::make_unique<TotemAnalysisMask>();
0357
0358 try {
0359
0360 cms::concurrency::xercesInitialize();
0361
0362
0363 for (const auto &fn : configuration[currentBlock].mappingFileNames)
0364 ParseXML(pMapping, CompleteFileName(fn), mapping, mask);
0365
0366
0367 for (const auto &fn : configuration[currentBlock].maskFileNames)
0368 ParseXML(pMask, CompleteFileName(fn), mapping, mask);
0369
0370
0371 cms::concurrency::xercesTerminate();
0372 } catch (const XMLException &e) {
0373 throw cms::Exception("XMLDocument") << "cms::concurrency::xercesInitialize failed because of "
0374 << to_string(e.getMessage()) << std::endl;
0375 } catch (const SAXException &e) {
0376 throw cms::Exception("XMLDocument") << "XML parser reported: " << to_string(e.getMessage()) << "." << std::endl;
0377 }
0378
0379
0380 return edm::es::products(std::move(mapping), std::move(mask));
0381 }
0382
0383
0384
0385 void TotemDAQMappingESSourceXML::ParseXML(ParseType pType,
0386 const string &file,
0387 const std::unique_ptr<TotemDAQMapping> &mapping,
0388 const std::unique_ptr<TotemAnalysisMask> &mask) {
0389 unique_ptr<XercesDOMParser> parser(new XercesDOMParser());
0390 parser->parse(file.c_str());
0391
0392 DOMDocument *domDoc = parser->getDocument();
0393
0394 if (!domDoc)
0395 throw cms::Exception("TotemDAQMappingESSourceXML::ParseXML")
0396 << "Cannot parse file `" << file << "' (domDoc = NULL).";
0397
0398 DOMElement *elementRoot = domDoc->getDocumentElement();
0399
0400 if (!elementRoot)
0401 throw cms::Exception("TotemDAQMappingESSourceXML::ParseXML") << "File `" << file << "' is empty.";
0402
0403 ParseTreeRP(pType, elementRoot, nTop, 0, mapping, mask);
0404
0405 ParseTreeDiamond(pType, elementRoot, nTop, 0, mapping, mask);
0406
0407 ParseTreeTotemTiming(pType, elementRoot, nTop, 0, mapping, mask);
0408
0409 ParseTreeTotemT2(pType, elementRoot, nTop, 0, mapping, mask);
0410 }
0411
0412
0413
0414 void TotemDAQMappingESSourceXML::ParseTreeRP(ParseType pType,
0415 xercesc::DOMNode *parent,
0416 NodeType parentType,
0417 unsigned int parentID,
0418 const std::unique_ptr<TotemDAQMapping> &mapping,
0419 const std::unique_ptr<TotemAnalysisMask> &mask) {
0420 #ifdef DEBUG
0421 printf(">> TotemDAQMappingESSourceXML::ParseTreeRP(%s, %u, %u)\n",
0422 cms::xerces::toString(parent->getNodeName()),
0423 parentType,
0424 parentID);
0425 #endif
0426
0427 DOMNodeList *children = parent->getChildNodes();
0428
0429 for (unsigned int i = 0; i < children->getLength(); i++) {
0430 DOMNode *n = children->item(i);
0431 if (n->getNodeType() != DOMNode::ELEMENT_NODE)
0432 continue;
0433
0434 NodeType type = GetNodeType(n);
0435
0436 #ifdef DEBUG
0437 printf("\tname = %s, type = %u\n", cms::xerces::toString(n->getNodeName()), type);
0438 #endif
0439
0440
0441 if (!RPNode(type))
0442 continue;
0443
0444 NodeType expectedParentType;
0445 switch (type) {
0446 case nArm:
0447 expectedParentType = nTop;
0448 break;
0449 case nRPStation:
0450 expectedParentType = nArm;
0451 break;
0452 case nRPPot:
0453 expectedParentType = nRPStation;
0454 break;
0455 case nRPPlane:
0456 expectedParentType = nRPPot;
0457 break;
0458 case nChip:
0459 expectedParentType = nRPPlane;
0460 break;
0461 case nChannel:
0462 expectedParentType = nChip;
0463 break;
0464 default:
0465 expectedParentType = nUnknown;
0466 break;
0467 }
0468
0469 if (expectedParentType != parentType) {
0470 throw cms::Exception("TotemDAQMappingESSourceXML")
0471 << "Node " << cms::xerces::toString(n->getNodeName()) << " not allowed within "
0472 << cms::xerces::toString(parent->getNodeName()) << " block.\n";
0473 }
0474
0475
0476 unsigned int id = 0, hw_id = 0;
0477 bool id_set = false, hw_id_set = false;
0478 bool fullMask = false;
0479 DOMNamedNodeMap *attr = n->getAttributes();
0480
0481 for (unsigned int j = 0; j < attr->getLength(); j++) {
0482 DOMNode *a = attr->item(j);
0483
0484 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "id")) {
0485 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%u", &id);
0486 id_set = true;
0487 }
0488
0489 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "hw_id")) {
0490 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%x", &hw_id);
0491 hw_id_set = true;
0492 }
0493
0494 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "full_mask"))
0495 fullMask = (strcmp(cms::xerces::toString(a->getNodeValue()).c_str(), "no") != 0);
0496 }
0497
0498
0499 if (!id_set)
0500 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeRP")
0501 << "id not given for element `" << cms::xerces::toString(n->getNodeName()) << "'";
0502
0503 if (!hw_id_set && type == nChip && pType == pMapping)
0504 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeRP")
0505 << "hw_id not given for element `" << cms::xerces::toString(n->getNodeName()) << "'";
0506
0507 if (type == nRPPlane && id > 9)
0508 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeRP")
0509 << "Plane IDs range from 0 to 9. id = " << id << " is invalid.";
0510
0511 #ifdef DEBUG
0512 printf("\tID found: 0x%x\n", id);
0513 #endif
0514
0515
0516 if (pType == pMapping && type == nChip) {
0517 const TotemFramePosition &framepos = ChipFramePosition(n);
0518 TotemVFATInfo vfatInfo;
0519 vfatInfo.hwID = hw_id;
0520
0521 const unsigned int armIdx = (parentID / 1000) % 10;
0522 const unsigned int stIdx = (parentID / 100) % 10;
0523 const unsigned int rpIdx = (parentID / 10) % 10;
0524 const unsigned int plIdx = parentID % 10;
0525
0526 vfatInfo.symbolicID.symbolicID = TotemRPDetId(armIdx, stIdx, rpIdx, plIdx, id);
0527
0528 mapping->insert(framepos, vfatInfo);
0529
0530 continue;
0531 }
0532
0533
0534 if (pType == pMask && type == nChip) {
0535 const unsigned int armIdx = (parentID / 1000) % 10;
0536 const unsigned int stIdx = (parentID / 100) % 10;
0537 const unsigned int rpIdx = (parentID / 10) % 10;
0538 const unsigned int plIdx = parentID % 10;
0539
0540 TotemSymbID symbId;
0541 symbId.symbolicID = TotemRPDetId(armIdx, stIdx, rpIdx, plIdx, id);
0542
0543 TotemVFATAnalysisMask am;
0544 am.fullMask = fullMask;
0545 GetChannels(n, am.maskedChannels);
0546
0547 mask->insert(symbId, am);
0548
0549 continue;
0550 }
0551
0552
0553 ParseTreeRP(pType, n, type, parentID * 10 + id, mapping, mask);
0554 }
0555 }
0556
0557
0558
0559 void TotemDAQMappingESSourceXML::ParseTreeDiamond(ParseType pType,
0560 xercesc::DOMNode *parent,
0561 NodeType parentType,
0562 unsigned int parentID,
0563 const std::unique_ptr<TotemDAQMapping> &mapping,
0564 const std::unique_ptr<TotemAnalysisMask> &mask) {
0565 #ifdef DEBUG
0566 printf(">> TotemDAQMappingESSourceXML::ParseTreeDiamond(%s, %u, %u)\n",
0567 cms::xerces::toString(parent->getNodeName()),
0568 parentType,
0569 parentID);
0570 #endif
0571
0572 DOMNodeList *children = parent->getChildNodes();
0573
0574 for (unsigned int i = 0; i < children->getLength(); i++) {
0575 DOMNode *n = children->item(i);
0576 if (n->getNodeType() != DOMNode::ELEMENT_NODE)
0577 continue;
0578
0579 NodeType type = GetNodeType(n);
0580 #ifdef DEBUG
0581 printf("\tname = %s, type = %u\n", cms::xerces::toString(n->getNodeName()), type);
0582 #endif
0583
0584
0585 if (!DiamondNode(type))
0586 continue;
0587
0588 NodeType expectedParentType;
0589 switch (type) {
0590 case nArm:
0591 expectedParentType = nTop;
0592 break;
0593 case nRPStation:
0594 expectedParentType = nArm;
0595 break;
0596 case nRPPot:
0597 expectedParentType = nRPStation;
0598 break;
0599 case nDiamondPlane:
0600 expectedParentType = nRPPot;
0601 break;
0602 case nDiamondCh:
0603 expectedParentType = nDiamondPlane;
0604 break;
0605 default:
0606 expectedParentType = nUnknown;
0607 break;
0608 }
0609
0610 if (expectedParentType != parentType) {
0611 throw cms::Exception("TotemDAQMappingESSourceXML")
0612 << "Node " << cms::xerces::toString(n->getNodeName()) << " not allowed within "
0613 << cms::xerces::toString(parent->getNodeName()) << " block.\n";
0614 }
0615
0616
0617 unsigned int id = 0, hw_id = 0;
0618 bool id_set = false, hw_id_set = false;
0619 DOMNamedNodeMap *attr = n->getAttributes();
0620
0621 for (unsigned int j = 0; j < attr->getLength(); j++) {
0622 DOMNode *a = attr->item(j);
0623
0624 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "id")) {
0625 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%u", &id);
0626 id_set = true;
0627 }
0628
0629 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "hw_id")) {
0630 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%x", &hw_id);
0631 hw_id_set = true;
0632 }
0633 }
0634
0635
0636 if (!id_set)
0637 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeDiamond")
0638 << "id not given for element `" << cms::xerces::toString(n->getNodeName()) << "'";
0639
0640 if (!hw_id_set && type == nDiamondCh && pType == pMapping)
0641 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeDiamond")
0642 << "hw_id not given for element `" << cms::xerces::toString(n->getNodeName()) << "'";
0643
0644 if (type == nDiamondPlane && id > 3)
0645 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeDiamond")
0646 << "Plane IDs range from 0 to 3. id = " << id << " is invalid.";
0647
0648 #ifdef DEBUG
0649 printf("\tID found: 0x%x\n", id);
0650 #endif
0651
0652
0653 if (pType == pMapping && type == nDiamondCh) {
0654 const TotemFramePosition &framepos = ChipFramePosition(n);
0655
0656 TotemVFATInfo vfatInfo;
0657 vfatInfo.hwID = hw_id;
0658
0659 if (type == nDiamondCh) {
0660 unsigned int ArmNum = (parentID / 10000) % 10;
0661 unsigned int StationNum = (parentID / 1000) % 10;
0662 unsigned int RpNum = (parentID / 100) % 10;
0663 unsigned int PlaneNum = (parentID % 100);
0664
0665 vfatInfo.symbolicID.symbolicID = CTPPSDiamondDetId(ArmNum, StationNum, RpNum, PlaneNum, id);
0666 }
0667
0668 mapping->insert(framepos, vfatInfo);
0669
0670 continue;
0671 }
0672
0673 unsigned int childId;
0674 if (pType == pMapping && type == nDiamondPlane)
0675 childId = parentID * 100 + id;
0676 else
0677 childId = parentID * 10 + id;
0678
0679 ParseTreeDiamond(pType, n, type, childId, mapping, mask);
0680 }
0681 }
0682
0683
0684
0685 void TotemDAQMappingESSourceXML::ParseTreeTotemTiming(ParseType pType,
0686 xercesc::DOMNode *parent,
0687 NodeType parentType,
0688 unsigned int parentID,
0689 const std::unique_ptr<TotemDAQMapping> &mapping,
0690 const std::unique_ptr<TotemAnalysisMask> &mask) {
0691 DOMNodeList *children = parent->getChildNodes();
0692
0693
0694 for (unsigned int i = 0; i < children->getLength(); i++) {
0695 DOMNode *child = children->item(i);
0696 if ((child->getNodeType() != DOMNode::ELEMENT_NODE) || (GetNodeType(child) != nTotemTimingCh))
0697 continue;
0698
0699 int plane = -1;
0700 DOMNamedNodeMap *attr = parent->getAttributes();
0701 for (unsigned int j = 0; j < attr->getLength(); j++) {
0702 DOMNode *a = attr->item(j);
0703
0704 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "id"))
0705 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%d", &plane);
0706 }
0707
0708 int channel = -1;
0709 unsigned int hwId = 0;
0710 attr = child->getAttributes();
0711 for (unsigned int j = 0; j < attr->getLength(); j++) {
0712 DOMNode *a = attr->item(j);
0713
0714 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "id"))
0715 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%d", &channel);
0716 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "hwId"))
0717 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%x", &hwId);
0718 }
0719
0720 mapping->totemTimingChannelMap[(uint8_t)hwId] = TotemDAQMapping::TotemTimingPlaneChannelPair(plane, channel);
0721 }
0722
0723 for (unsigned int i = 0; i < children->getLength(); i++) {
0724 DOMNode *n = children->item(i);
0725 if (n->getNodeType() != DOMNode::ELEMENT_NODE)
0726 continue;
0727
0728 NodeType type = GetNodeType(n);
0729
0730
0731 if (!TotemTimingNode(type))
0732 continue;
0733
0734 NodeType expectedParentType;
0735 switch (type) {
0736 case nArm:
0737 expectedParentType = nTop;
0738 break;
0739 case nRPStation:
0740 expectedParentType = nArm;
0741 break;
0742 case nRPPot:
0743 expectedParentType = nRPStation;
0744 break;
0745 case nSampicBoard:
0746 expectedParentType = nRPPot;
0747 break;
0748 case nSampicChannel:
0749 expectedParentType = nSampicBoard;
0750 break;
0751 case nTotemTimingPlane:
0752 expectedParentType = nRPPot;
0753 break;
0754 case nTotemTimingCh:
0755 expectedParentType = nTotemTimingPlane;
0756 break;
0757 default:
0758 expectedParentType = nUnknown;
0759 break;
0760 }
0761
0762 if (expectedParentType != parentType) {
0763 throw cms::Exception("TotemDAQMappingESSourceXML")
0764 << "Node " << cms::xerces::toString(n->getNodeName()) << " not allowed within "
0765 << cms::xerces::toString(parent->getNodeName()) << " block.\n";
0766 }
0767
0768
0769 unsigned int id = 0;
0770 bool id_set = false;
0771 DOMNamedNodeMap *attr = n->getAttributes();
0772
0773 for (unsigned int j = 0; j < attr->getLength(); j++) {
0774 DOMNode *a = attr->item(j);
0775
0776 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "id")) {
0777 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%u", &id);
0778 id_set = true;
0779 }
0780 }
0781
0782
0783 if (!id_set)
0784 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeTotemTiming")
0785 << "id not given for element `" << cms::xerces::toString(n->getNodeName()) << "'";
0786 if (type == nSampicBoard && id > 5)
0787 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeTotemTiming")
0788 << "SampicBoard IDs range from 0 to 5. id = " << id << " is invalid.";
0789
0790
0791 if (pType == pMapping && type == nSampicChannel) {
0792 const TotemFramePosition &framepos = ChipFramePosition(n);
0793
0794 TotemVFATInfo vfatInfo;
0795 unsigned int ArmNum = (parentID / 10000) % 10;
0796 unsigned int StationNum = (parentID / 1000) % 10;
0797 unsigned int RpNum = (parentID / 100) % 10;
0798
0799 vfatInfo.symbolicID.symbolicID = TotemTimingDetId(ArmNum,
0800 StationNum,
0801 RpNum,
0802 0,
0803 TotemTimingDetId::ID_NOT_SET,
0804 sampicSubDetId);
0805
0806 mapping->insert(framepos, vfatInfo);
0807
0808 continue;
0809 }
0810
0811 unsigned int childId;
0812 if (pType == pMapping && type == nSampicBoard)
0813 childId = parentID * 100 + id;
0814 else
0815 childId = parentID * 10 + id;
0816
0817 ParseTreeTotemTiming(pType, n, type, childId, mapping, mask);
0818 }
0819 }
0820
0821
0822
0823 void TotemDAQMappingESSourceXML::ParseTreeTotemT2(ParseType pType,
0824 xercesc::DOMNode *parent,
0825 NodeType parentType,
0826 unsigned int parentID,
0827 const std::unique_ptr<TotemDAQMapping> &mapping,
0828 const std::unique_ptr<TotemAnalysisMask> &mask) {
0829 DOMNodeList *children = parent->getChildNodes();
0830
0831 for (unsigned int i = 0; i < children->getLength(); i++) {
0832 DOMNode *child = children->item(i);
0833 if (child->getNodeType() != DOMNode::ELEMENT_NODE)
0834 continue;
0835
0836 NodeType type = GetNodeType(child);
0837
0838
0839 if (!TotemT2Node(type))
0840 continue;
0841
0842 NodeType expectedParentType;
0843 switch (type) {
0844 case nArm:
0845 expectedParentType = nTop;
0846 break;
0847 case nTotemT2Plane:
0848 expectedParentType = nArm;
0849 break;
0850 case nTotemT2Tile:
0851 expectedParentType = nTotemT2Plane;
0852 break;
0853 default:
0854 expectedParentType = nUnknown;
0855 break;
0856 }
0857
0858 if (expectedParentType != parentType) {
0859 throw cms::Exception("TotemDAQMappingESSourceXML")
0860 << "Node " << cms::xerces::toString(child->getNodeName()) << " not allowed within "
0861 << cms::xerces::toString(parent->getNodeName()) << " block.\n";
0862 }
0863
0864 unsigned int id = 0;
0865 bool id_set = false;
0866 DOMNamedNodeMap *attr = child->getAttributes();
0867
0868 for (unsigned int j = 0; j < attr->getLength(); j++) {
0869 DOMNode *a = attr->item(j);
0870 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "id")) {
0871 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%u", &id);
0872 id_set = true;
0873 }
0874 }
0875 if (pType == pMapping && type == nTotemT2Tile) {
0876
0877 unsigned int hw_id = 0;
0878 bool hw_id_set = false;
0879 unsigned int channel_in_payload = 0;
0880 bool payload_set = false;
0881 DOMNamedNodeMap *attr = child->getAttributes();
0882
0883 for (unsigned int j = 0; j < attr->getLength(); j++) {
0884 DOMNode *a = attr->item(j);
0885 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "hwId")) {
0886 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%x", &hw_id);
0887 hw_id_set = true;
0888 }
0889 if (packedPayload && (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "pay"))) {
0890 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%u", &channel_in_payload);
0891 payload_set = true;
0892 }
0893 }
0894
0895
0896 if (!id_set)
0897 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeTotemT2")
0898 << "id not given for element `" << cms::xerces::toString(child->getNodeName()) << "'";
0899 if (!hw_id_set)
0900 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeTotemT2")
0901 << "hwId not given for element `" << cms::xerces::toString(child->getNodeName()) << "'";
0902 if (packedPayload && (!payload_set))
0903 throw cms::Exception("TotemDAQMappingESSourceXML::ParseTreeTotemT2")
0904 << "Payload position in fibre not given for element `" << cms::xerces::toString(child->getNodeName())
0905 << "'";
0906
0907
0908 const TotemT2FramePosition &framepos = (packedPayload ? ChipT2FramePosition(child) : TotemT2FramePosition());
0909 const TotemFramePosition &frameposSingle = (packedPayload ? TotemFramePosition() : ChipFramePosition(child));
0910 TotemVFATInfo vfatInfo;
0911 vfatInfo.hwID = hw_id;
0912 unsigned int arm = parentID / 10, plane = parentID % 10;
0913 vfatInfo.symbolicID.symbolicID = TotemT2DetId(arm, plane, id);
0914 if (verbosity > 2) {
0915 edm::LogWarning("Totem") << "Print T2 frame pos (payload):" << framepos << " ("
0916 << (packedPayload ? "true" : "false") << ") hw_id / T2 DetID" << hw_id << "/"
0917 << TotemT2DetId(arm, plane, id) << endl;
0918 }
0919
0920 if (packedPayload)
0921 mapping->insert(framepos, vfatInfo);
0922 else
0923 mapping->insert(frameposSingle, vfatInfo);
0924
0925 continue;
0926 }
0927
0928 ParseTreeTotemT2(pType, child, type, parentID * 10 + id, mapping, mask);
0929 }
0930 }
0931
0932
0933
0934 TotemFramePosition TotemDAQMappingESSourceXML::ChipFramePosition(xercesc::DOMNode *chipnode) {
0935 TotemFramePosition fp;
0936 unsigned char attributeFlag = 0;
0937
0938 DOMNamedNodeMap *attr = chipnode->getAttributes();
0939 for (unsigned int j = 0; j < attr->getLength(); j++) {
0940 DOMNode *a = attr->item(j);
0941 if (fp.setXMLAttribute(
0942 cms::xerces::toString(a->getNodeName()), cms::xerces::toString(a->getNodeValue()), attributeFlag) > 1) {
0943 throw cms::Exception("TotemDAQMappingESSourceXML")
0944 << "Unrecognized tag `" << cms::xerces::toString(a->getNodeName()) << "' or incompatible value `"
0945 << cms::xerces::toString(a->getNodeValue()) << "'.";
0946 }
0947 }
0948
0949 if (!fp.checkXMLAttributeFlag(attributeFlag)) {
0950 throw cms::Exception("TotemDAQMappingESSourceXML")
0951 << "Wrong/incomplete DAQ channel specification (attributeFlag = " << attributeFlag << ").";
0952 }
0953
0954 return fp;
0955 }
0956
0957
0958
0959 TotemT2FramePosition TotemDAQMappingESSourceXML::ChipT2FramePosition(xercesc::DOMNode *chipnode) {
0960 TotemT2FramePosition fp;
0961 unsigned char attributeFlag = 0;
0962
0963 DOMNamedNodeMap *attr = chipnode->getAttributes();
0964 for (unsigned int j = 0; j < attr->getLength(); j++) {
0965 DOMNode *a = attr->item(j);
0966 if (fp.setXMLAttribute(
0967 cms::xerces::toString(a->getNodeName()), cms::xerces::toString(a->getNodeValue()), attributeFlag) > 1) {
0968 throw cms::Exception("TotemDAQMappingESSourceXML")
0969 << "Unrecognized T2 tag `" << cms::xerces::toString(a->getNodeName()) << "' or incompatible value `"
0970 << cms::xerces::toString(a->getNodeValue()) << "'.";
0971 }
0972 }
0973
0974 if (!fp.checkXMLAttributeFlag(attributeFlag)) {
0975 throw cms::Exception("TotemDAQMappingESSourceXML")
0976 << "Wrong/incomplete T2 DAQ channel specification (attributeFlag = " << attributeFlag << ").";
0977 }
0978
0979 return fp;
0980 }
0981
0982
0983 TotemDAQMappingESSourceXML::NodeType TotemDAQMappingESSourceXML::GetNodeType(xercesc::DOMNode *n) {
0984
0985 if (Test(n, tagArm))
0986 return nArm;
0987 if (Test(n, tagChip1))
0988 return nChip;
0989 if (Test(n, tagChip2))
0990 return nChip;
0991
0992
0993 if (Test(n, tagRPStation))
0994 return nRPStation;
0995 if (Test(n, tagRPPot))
0996 return nRPPot;
0997 if (Test(n, tagRPPlane))
0998 return nRPPlane;
0999
1000
1001 if (Test(n, tagDiamondCh))
1002 return nDiamondCh;
1003 if (Test(n, tagDiamondPlane))
1004 return nDiamondPlane;
1005
1006
1007 if (Test(n, tagSampicBoard))
1008 return nSampicBoard;
1009 if (Test(n, tagSampicCh))
1010 return nSampicChannel;
1011 if (Test(n, tagTotemTimingCh))
1012 return nTotemTimingCh;
1013 if (Test(n, tagTotemTimingPlane))
1014 return nTotemTimingPlane;
1015
1016
1017 if (Test(n, tagTotemT2Plane))
1018 return nTotemT2Plane;
1019 if (Test(n, tagTotemT2Tile))
1020 return nTotemT2Tile;
1021
1022
1023 if (Test(n, "trigger_vfat"))
1024 return nSkip;
1025
1026 throw cms::Exception("TotemDAQMappingESSourceXML::GetNodeType")
1027 << "Unknown tag `" << cms::xerces::toString(n->getNodeName()) << "'.\n";
1028 }
1029
1030
1031
1032 void TotemDAQMappingESSourceXML::GetChannels(xercesc::DOMNode *n, set<unsigned char> &channels) {
1033 DOMNodeList *children = n->getChildNodes();
1034 for (unsigned int i = 0; i < children->getLength(); i++) {
1035 DOMNode *n = children->item(i);
1036 if (n->getNodeType() != DOMNode::ELEMENT_NODE || !Test(n, "channel"))
1037 continue;
1038
1039 DOMNamedNodeMap *attr = n->getAttributes();
1040 bool idSet = false;
1041 for (unsigned int j = 0; j < attr->getLength(); j++) {
1042 DOMNode *a = attr->item(j);
1043
1044 if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "id")) {
1045 unsigned int id = 0;
1046 sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%u", &id);
1047 channels.insert(id);
1048 idSet = true;
1049 break;
1050 }
1051 }
1052
1053 if (!idSet) {
1054 throw cms::Exception("TotemDAQMappingESSourceXML::GetChannels") << "Channel tags must have an `id' attribute.";
1055 }
1056 }
1057 }
1058
1059
1060
1061 DEFINE_FWK_EVENTSETUP_SOURCE(TotemDAQMappingESSourceXML);