Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:58:36

0001 /****************************************************************************
0002  *
0003  *
0004  * Authors:
0005  * F.Ferro ferro@ge.infn.it
0006  * H. Malbouisson malbouis@cern.ch
0007  *
0008  ****************************************************************************/
0009 
0010 #include "FWCore/Framework/interface/MakerMacros.h"
0011 #include "FWCore/Framework/interface/SourceFactory.h"
0012 #include "FWCore/Framework/interface/ModuleFactory.h"
0013 #include "FWCore/Framework/interface/ESHandle.h"
0014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0015 #include "FWCore/Framework/interface/ESProducer.h"
0016 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0017 #include "FWCore/Framework/interface/ESProducts.h"
0018 #include "FWCore/Framework/interface/SourceFactory.h"
0019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0020 #include "Utilities/Xerces/interface/Xerces.h"
0021 
0022 #include "DataFormats/CTPPSDetId/interface/CTPPSPixelDetId.h"
0023 
0024 #include "CondFormats/DataRecord/interface/CTPPSPixelDAQMappingRcd.h"
0025 #include "CondFormats/DataRecord/interface/CTPPSPixelAnalysisMaskRcd.h"
0026 #include "CondFormats/PPSObjects/interface/CTPPSPixelDAQMapping.h"
0027 #include "CondFormats/PPSObjects/interface/CTPPSPixelAnalysisMask.h"
0028 #include "CondFormats/PPSObjects/interface/CTPPSPixelFramePosition.h"
0029 #include "Utilities/Xerces/interface/XercesStrUtils.h"
0030 
0031 #include <xercesc/parsers/XercesDOMParser.hpp>
0032 #include <xercesc/dom/DOM.hpp>
0033 #include <xercesc/sax/HandlerBase.hpp>
0034 #include <xercesc/util/XMLString.hpp>
0035 #include <xercesc/util/PlatformUtils.hpp>
0036 
0037 #include <memory>
0038 #include <sstream>
0039 
0040 //#define DEBUG 1
0041 
0042 //----------------------------------------------------------------------------------------------------
0043 
0044 using namespace std;
0045 
0046 /**
0047  * \brief Loads CTPPSPixelDAQMapping and CTPPSPixelAnalysisMask from two XML files.
0048  **/
0049 class CTPPSPixelDAQMappingESSourceXML : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder {
0050 public:
0051   static const std::string tagAnalysisMask;
0052   static const std::string tagRPixPlane;
0053   static const std::string tagROC;
0054   static const std::string tagPixel;
0055   /// Common position tags
0056   static const std::string tagArm;
0057 
0058   /// RP XML tags
0059   static const std::string tagRPStation;
0060   static const std::string tagRPPot;
0061 
0062   CTPPSPixelDAQMappingESSourceXML(const edm::ParameterSet &);
0063   ~CTPPSPixelDAQMappingESSourceXML() override;
0064 
0065   std::unique_ptr<CTPPSPixelAnalysisMask> produceCTPPSPixelAnalysisMask(const CTPPSPixelAnalysisMaskRcd &);
0066   std::unique_ptr<CTPPSPixelDAQMapping> produceCTPPSPixelDAQMapping(const CTPPSPixelDAQMappingRcd &);
0067 
0068 private:
0069   unsigned int verbosity;
0070 
0071   /// label of the CTPPS sub-system
0072   string subSystemName;
0073 
0074   /// the mapping files
0075   std::vector<std::string> mappingFileNames;
0076 
0077   struct ConfigBlock {
0078     /// validity interval
0079     edm::EventRange validityRange;
0080 
0081     /// the mapping files
0082     std::vector<std::string> mappingFileNames;
0083 
0084     /// the mask files
0085     std::vector<std::string> maskFileNames;
0086   };
0087 
0088   vector<ConfigBlock> configuration;
0089 
0090   /// index of the current block in 'configuration' array
0091   unsigned int currentBlock;
0092 
0093   /// flag whether the 'currentBlock' index is valid
0094   bool currentBlockValid;
0095 
0096   /// enumeration of XML node types
0097   enum NodeType { nUnknown, nSkip, nTop, nArm, nRPStation, nRPPot, nRPixPlane, nROC, nPixel };
0098 
0099   /// whether to parse a mapping of a mask XML
0100   enum ParseType { pMapping, pMask };
0101 
0102   /// parses XML file
0103   void ParseXML(ParseType,
0104                 const string &file,
0105                 const std::unique_ptr<CTPPSPixelDAQMapping> &,
0106                 const std::unique_ptr<CTPPSPixelAnalysisMask> &);
0107 
0108   /// recursive method to extract Pixel-related information from the DOM tree
0109   void ParseTreePixel(ParseType,
0110                       xercesc::DOMNode *,
0111                       NodeType,
0112                       unsigned int parentID,
0113                       const std::unique_ptr<CTPPSPixelDAQMapping> &,
0114                       const std::unique_ptr<CTPPSPixelAnalysisMask> &);
0115 
0116 private:
0117   /// adds the path prefix, if needed
0118   string CompleteFileName(const string &fn);
0119 
0120   /// returns true iff the node is of the given name
0121   bool Test(xercesc::DOMNode *node, const std::string &name) {
0122     return !(name.compare(cms::xerces::toString(node->getNodeName())));
0123   }
0124 
0125   /// determines node type
0126   NodeType GetNodeType(xercesc::DOMNode *);
0127 
0128   /// returns the content of the node
0129   string GetNodeContent(xercesc::DOMNode *parent) { return cms::xerces::toString(parent->getTextContent()); }
0130 
0131   /// returns the value of the node
0132   string GetNodeValue(xercesc::DOMNode *node) { return cms::xerces::toString(node->getNodeValue()); }
0133 
0134   /// extracts VFAT's DAQ channel from XML attributes
0135   CTPPSPixelFramePosition ChipFramePosition(xercesc::DOMNode *chipnode);
0136 
0137   void GetPixels(xercesc::DOMNode *n, std::set<std::pair<unsigned char, unsigned char>> &pixels);
0138 
0139   bool PixelNode(NodeType type) {
0140     return ((type == nArm) || (type == nRPStation) || (type == nRPPot) || (type == nRPixPlane) || (type == nROC));
0141   }
0142 
0143 protected:
0144   /// sets infinite validity of this data
0145   void setIntervalFor(const edm::eventsetup::EventSetupRecordKey &,
0146                       const edm::IOVSyncValue &,
0147                       edm::ValidityInterval &) override;
0148 };
0149 
0150 //----------------------------------------------------------------------------------------------------
0151 
0152 using namespace std;
0153 using namespace edm;
0154 using namespace xercesc;
0155 
0156 const string CTPPSPixelDAQMappingESSourceXML::tagROC = "roc";
0157 const string CTPPSPixelDAQMappingESSourceXML::tagPixel = "pixel";
0158 const string CTPPSPixelDAQMappingESSourceXML::tagAnalysisMask = "analysisMask";
0159 
0160 // common XML position tags
0161 const string CTPPSPixelDAQMappingESSourceXML::tagArm = "arm";
0162 
0163 // specific RP XML tags
0164 const string CTPPSPixelDAQMappingESSourceXML::tagRPStation = "station";
0165 const string CTPPSPixelDAQMappingESSourceXML::tagRPPot = "rp_detector_set";
0166 const string CTPPSPixelDAQMappingESSourceXML::tagRPixPlane = "rpix_plane";
0167 
0168 static const unsigned int offsetROCinDetId = 13;
0169 //static const unsigned int maskROCinDetId = 0x3;
0170 
0171 CTPPSPixelDAQMappingESSourceXML::CTPPSPixelDAQMappingESSourceXML(const edm::ParameterSet &conf)
0172     : verbosity(conf.getUntrackedParameter<unsigned int>("verbosity", 0)),
0173       subSystemName(conf.getUntrackedParameter<string>("subSystem")),
0174       currentBlock(0),
0175       currentBlockValid(false) {
0176   for (const auto &it : conf.getParameter<vector<ParameterSet>>("configuration")) {
0177     ConfigBlock b;
0178     b.validityRange = it.getParameter<EventRange>("validityRange");
0179     b.mappingFileNames = it.getParameter<vector<string>>("mappingFileNames");
0180     b.maskFileNames = it.getParameter<vector<string>>("maskFileNames");
0181     configuration.push_back(b);
0182   }
0183 
0184   setWhatProduced(this, &CTPPSPixelDAQMappingESSourceXML::produceCTPPSPixelAnalysisMask, es::Label(subSystemName));
0185   findingRecord<CTPPSPixelAnalysisMaskRcd>();
0186 
0187   setWhatProduced(this, &CTPPSPixelDAQMappingESSourceXML::produceCTPPSPixelDAQMapping, es::Label(subSystemName));
0188   findingRecord<CTPPSPixelDAQMappingRcd>();
0189 
0190   LogVerbatim("CTPPSPixelDAQMappingESSourceXML") << " Inside  CTPPSPixelDAQMappingESSourceXML";
0191 }
0192 
0193 void CTPPSPixelDAQMappingESSourceXML::setIntervalFor(const edm::eventsetup::EventSetupRecordKey &key,
0194                                                      const edm::IOVSyncValue &iosv,
0195                                                      edm::ValidityInterval &oValidity) {
0196   LogVerbatim("CTPPSPixelDAQMappingESSourceXML")
0197       << ">> CTPPSPixelDAQMappingESSourceXML::setIntervalFor(" << key.name() << ")";
0198 
0199   LogVerbatim("CTPPSPixelDAQMappingESSourceXML")
0200       << "    run=" << iosv.eventID().run() << ", event=" << iosv.eventID().event();
0201 
0202   currentBlockValid = false;
0203   for (unsigned int idx = 0; idx < configuration.size(); ++idx) {
0204     const auto &bl = configuration[idx];
0205 
0206     EventID startEventID = bl.validityRange.startEventID();
0207     if (startEventID == EventID(1, 0, 1))
0208       startEventID = EventID(1, 0, 0);
0209 
0210     if (startEventID <= iosv.eventID() && iosv.eventID() <= bl.validityRange.endEventID()) {
0211       currentBlockValid = true;
0212       currentBlock = idx;
0213 
0214       const IOVSyncValue begin(startEventID);
0215       const IOVSyncValue end(bl.validityRange.endEventID());
0216       oValidity = ValidityInterval(begin, end);
0217 
0218       LogVerbatim("CTPPSPixelDAQMappingESSourceXML") << "    block found: index=" << currentBlock << ", interval=("
0219                                                      << startEventID << " - " << bl.validityRange.endEventID() << ")";
0220 
0221       return;
0222     }
0223   }
0224 
0225   if (!currentBlockValid) {
0226     throw cms::Exception("CTPPSPixelDAQMappingESSourceXML::setIntervalFor")
0227         << "No configuration for event " << iosv.eventID();
0228   }
0229 }
0230 
0231 CTPPSPixelDAQMappingESSourceXML::~CTPPSPixelDAQMappingESSourceXML() {}
0232 
0233 string CTPPSPixelDAQMappingESSourceXML::CompleteFileName(const string &fn) {
0234   FileInPath fip(fn);
0235   return fip.fullPath();
0236 }
0237 
0238 std::unique_ptr<CTPPSPixelDAQMapping> CTPPSPixelDAQMappingESSourceXML::produceCTPPSPixelDAQMapping(
0239     const CTPPSPixelDAQMappingRcd &) {
0240   assert(currentBlockValid);
0241 
0242   auto mapping = std::make_unique<CTPPSPixelDAQMapping>();
0243   auto mask = std::make_unique<CTPPSPixelAnalysisMask>();
0244 
0245   // initialize Xerces
0246 
0247   cms::concurrency::xercesInitialize();
0248 
0249   // load mapping files
0250   for (const auto &fn : configuration[currentBlock].mappingFileNames)
0251     ParseXML(pMapping, CompleteFileName(fn), mapping, mask);
0252 
0253   // load mask files
0254   for (const auto &fn : configuration[currentBlock].maskFileNames)
0255     ParseXML(pMask, CompleteFileName(fn), mapping, mask);
0256 
0257   // release Xerces
0258   cms::concurrency::xercesTerminate();
0259 
0260   // commit the product
0261   return mapping;
0262 }
0263 
0264 std::unique_ptr<CTPPSPixelAnalysisMask> CTPPSPixelDAQMappingESSourceXML::produceCTPPSPixelAnalysisMask(
0265     const CTPPSPixelAnalysisMaskRcd &) {
0266   assert(currentBlockValid);
0267 
0268   auto mapping = std::make_unique<CTPPSPixelDAQMapping>();
0269   auto mask = std::make_unique<CTPPSPixelAnalysisMask>();
0270 
0271   // initialize Xerces
0272 
0273   cms::concurrency::xercesInitialize();
0274 
0275   // load mapping files
0276   for (const auto &fn : configuration[currentBlock].mappingFileNames)
0277     ParseXML(pMapping, CompleteFileName(fn), mapping, mask);
0278 
0279   // load mask files
0280   for (const auto &fn : configuration[currentBlock].maskFileNames)
0281     ParseXML(pMask, CompleteFileName(fn), mapping, mask);
0282 
0283   // release Xerces
0284   cms::concurrency::xercesTerminate();
0285 
0286   // commit the products
0287   //return edm::es::products(mapping, mask);
0288   return mask;
0289 }
0290 
0291 //----------------------------------------------------------------------------------------------------
0292 
0293 void CTPPSPixelDAQMappingESSourceXML::ParseXML(ParseType pType,
0294                                                const string &file,
0295                                                const std::unique_ptr<CTPPSPixelDAQMapping> &mapping,
0296                                                const std::unique_ptr<CTPPSPixelAnalysisMask> &mask) {
0297   unique_ptr<XercesDOMParser> parser(new XercesDOMParser());
0298   parser->parse(file.c_str());
0299 
0300   DOMDocument *domDoc = parser->getDocument();
0301 
0302   if (!domDoc)
0303     throw cms::Exception("CTPPSPixelDAQMappingESSourceXML::ParseXML")
0304         << "Cannot parse file `" << file << "' (domDoc = NULL)." << endl;
0305 
0306   DOMElement *elementRoot = domDoc->getDocumentElement();
0307 
0308   if (!elementRoot)
0309     throw cms::Exception("CTPPSPixelDAQMappingESSourceXML::ParseXML") << "File `" << file << "' is empty." << endl;
0310 
0311   ParseTreePixel(pType, elementRoot, nTop, 0, mapping, mask);
0312 }
0313 
0314 //-----------------------------------------------------------------------------------------------------------
0315 
0316 void CTPPSPixelDAQMappingESSourceXML::ParseTreePixel(ParseType pType,
0317                                                      xercesc::DOMNode *parent,
0318                                                      NodeType parentType,
0319                                                      unsigned int parentID,
0320                                                      const std::unique_ptr<CTPPSPixelDAQMapping> &mapping,
0321                                                      const std::unique_ptr<CTPPSPixelAnalysisMask> &mask) {
0322 #ifdef DEBUG
0323   printf(">> CTPPSPixelDAQMappingESSourceXML::ParseTreeRP(%s, %u, %u)\n",
0324          cms::xerces::toString(parent->getNodeName()),
0325          parentType,
0326          parentID);
0327 #endif
0328 
0329   DOMNodeList *children = parent->getChildNodes();
0330 
0331   for (unsigned int i = 0; i < children->getLength(); i++) {
0332     DOMNode *n = children->item(i);
0333     if (n->getNodeType() != DOMNode::ELEMENT_NODE)
0334       continue;
0335 
0336     NodeType type = GetNodeType(n);
0337 
0338 #ifdef DEBUG
0339     printf("\tname = %s, type = %u\n", cms::xerces::toString(n->getNodeName()), type);
0340 #endif
0341 
0342     // structure control
0343     if (!PixelNode(type))
0344       continue;
0345 
0346     NodeType expectedParentType;
0347     switch (type) {
0348       case nArm:
0349         expectedParentType = nTop;
0350         break;
0351       case nRPStation:
0352         expectedParentType = nArm;
0353         break;
0354       case nRPPot:
0355         expectedParentType = nRPStation;
0356         break;
0357       case nRPixPlane:
0358         expectedParentType = nRPPot;
0359         break;
0360       case nROC:
0361         expectedParentType = nRPixPlane;
0362         break;
0363       case nPixel:
0364         expectedParentType = nROC;
0365         break;
0366       default:
0367         expectedParentType = nUnknown;
0368         break;
0369     }
0370 
0371     if (expectedParentType != parentType) {
0372       throw cms::Exception("CTPPSPixelDAQMappingESSourceXML")
0373           << "Node " << cms::xerces::toString(n->getNodeName()) << " not allowed within "
0374           << cms::xerces::toString(parent->getNodeName()) << " block.\n";
0375     }
0376 
0377     // parse tag attributes
0378     unsigned int id = 0;
0379     bool id_set = false;
0380     bool fullMask = false;
0381     DOMNamedNodeMap *attr = n->getAttributes();
0382 
0383     for (unsigned int j = 0; j < attr->getLength(); j++) {
0384       DOMNode *a = attr->item(j);
0385 
0386       if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "id")) {
0387         sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%u", &id);
0388         id_set = true;
0389       }
0390 
0391       if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "full_mask"))
0392         fullMask = (strcmp(cms::xerces::toString(a->getNodeValue()).c_str(), "no") != 0);
0393     }
0394 
0395     // content control
0396     if (!id_set)
0397       throw cms::Exception("CTPPSPixelDAQMappingESSourceXML::ParseTreePixel")
0398           << "id not given for element `" << cms::xerces::toString(n->getNodeName()) << "'" << endl;
0399 
0400     if (type == nRPixPlane && id > 5)
0401       throw cms::Exception("CTPPSPixelDAQMappingESSourceXML::ParseTreePixel")
0402           << "Plane IDs range from 0 to 5. id = " << id << " is invalid." << endl;
0403 
0404 #ifdef DEBUG
0405     printf("\tID found: %u\n", id);
0406 #endif
0407 
0408     // store mapping data
0409     if (pType == pMapping && type == nROC) {
0410       const CTPPSPixelFramePosition &framepos = ChipFramePosition(n);
0411       CTPPSPixelROCInfo rocInfo;
0412       rocInfo.roc = id;
0413 
0414       const unsigned int armIdx = (parentID / 1000) % 10;
0415       const unsigned int stIdx = (parentID / 100) % 10;
0416       const unsigned int rpIdx = (parentID / 10) % 10;
0417       const unsigned int plIdx = parentID % 10;
0418 
0419       rocInfo.iD = CTPPSPixelDetId(armIdx, stIdx, rpIdx, plIdx);
0420 
0421       mapping->insert(framepos, rocInfo);
0422 
0423       continue;
0424     }
0425 
0426     // store mask data
0427     if (pType == pMask && type == nROC) {
0428       const unsigned int armIdx = (parentID / 1000) % 10;
0429       const unsigned int stIdx = (parentID / 100) % 10;
0430       const unsigned int rpIdx = (parentID / 10) % 10;
0431       const unsigned int plIdx = parentID % 10;
0432 
0433       uint32_t symbId = (id << offsetROCinDetId);
0434 
0435       symbId |= CTPPSPixelDetId(armIdx, stIdx, rpIdx, plIdx);
0436 
0437       CTPPSPixelROCAnalysisMask am;
0438       am.fullMask = fullMask;
0439       GetPixels(n, am.maskedPixels);
0440 
0441       mask->insert(symbId, am);
0442 
0443       continue;
0444     }
0445 
0446     // recursion (deeper in the tree)
0447     ParseTreePixel(pType, n, type, parentID * 10 + id, mapping, mask);
0448   }
0449 }
0450 
0451 //----------------------------------------------------------------------------------------------------
0452 
0453 CTPPSPixelFramePosition CTPPSPixelDAQMappingESSourceXML::ChipFramePosition(xercesc::DOMNode *chipnode) {
0454   CTPPSPixelFramePosition fp;
0455   unsigned char attributeFlag = 0;
0456 
0457   DOMNamedNodeMap *attr = chipnode->getAttributes();
0458   for (unsigned int j = 0; j < attr->getLength(); j++) {
0459     DOMNode *a = attr->item(j);
0460 
0461     if (fp.setXMLAttribute(
0462             cms::xerces::toString(a->getNodeName()), cms::xerces::toString(a->getNodeValue()), attributeFlag) > 1) {
0463       throw cms::Exception("CTPPSPixelDAQMappingESSourceXML")
0464           << "Unrecognized tag `" << cms::xerces::toString(a->getNodeName()) << "' or incompatible value `"
0465           << cms::xerces::toString(a->getNodeValue()) << "'." << endl;
0466     }
0467   }
0468 
0469   if (!fp.checkXMLAttributeFlag(attributeFlag)) {
0470     throw cms::Exception("CTPPSPixelDAQMappingESSourceXML")
0471         << "Wrong/incomplete DAQ channel specification (attributeFlag = " << attributeFlag << ")." << endl;
0472   }
0473 
0474   return fp;
0475 }
0476 
0477 //----------------------------------------------------------------------------------------------------
0478 
0479 CTPPSPixelDAQMappingESSourceXML::NodeType CTPPSPixelDAQMappingESSourceXML::GetNodeType(xercesc::DOMNode *n) {
0480   // common node types
0481   if (Test(n, tagArm))
0482     return nArm;
0483   if (Test(n, tagROC))
0484     return nROC;
0485 
0486   // RP node types
0487   if (Test(n, tagRPStation))
0488     return nRPStation;
0489   if (Test(n, tagRPPot))
0490     return nRPPot;
0491   if (Test(n, tagRPixPlane))
0492     return nRPixPlane;
0493 
0494   throw cms::Exception("CTPPSPixelDAQMappingESSourceXML::GetNodeType")
0495       << "Unknown tag `" << cms::xerces::toString(n->getNodeName()) << "'.\n";
0496 }
0497 
0498 //----------------------------------------------------------------------------------------------------
0499 
0500 void CTPPSPixelDAQMappingESSourceXML::GetPixels(xercesc::DOMNode *n,
0501                                                 set<std::pair<unsigned char, unsigned char>> &pixels) {
0502   DOMNodeList *children = n->getChildNodes();
0503   for (unsigned int i = 0; i < children->getLength(); i++) {
0504     DOMNode *n = children->item(i);
0505     if (n->getNodeType() != DOMNode::ELEMENT_NODE || !Test(n, "pixel"))
0506       continue;
0507 
0508     DOMNamedNodeMap *attr = n->getAttributes();
0509     bool pixelSet = false;
0510     bool rowSet = false;
0511     bool colSet = false;
0512     std::pair<unsigned int, unsigned int> currentPixel;
0513     for (unsigned int j = 0; j < attr->getLength(); j++) {
0514       DOMNode *a = attr->item(j);
0515 
0516       if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "row")) {
0517         unsigned int row = 0;
0518         sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%u", &row);
0519         currentPixel.first = row;
0520         rowSet = true;
0521       }
0522       if (!strcmp(cms::xerces::toString(a->getNodeName()).c_str(), "col")) {
0523         unsigned int col = 0;
0524         sscanf(cms::xerces::toString(a->getNodeValue()).c_str(), "%u", &col);
0525         currentPixel.second = col;
0526         colSet = true;
0527       }
0528 
0529       pixelSet = rowSet & colSet;
0530       if (pixelSet) {
0531         pixels.insert(currentPixel);
0532         break;
0533       }
0534     }
0535 
0536     if (!pixelSet) {
0537       throw cms::Exception("CTPPSPixelDAQMappingESSourceXML::GetChannels")
0538           << "Channel tags must have a row or col attribute.";
0539     }
0540   }
0541 }
0542 
0543 //----------------------------------------------------------------------------------------------------
0544 
0545 DEFINE_FWK_EVENTSETUP_SOURCE(CTPPSPixelDAQMappingESSourceXML);