Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:02:24

0001 #include "CondFormats/L1TObjects/interface/LUT.h"
0002 
0003 #include <sstream>
0004 #include <string>
0005 #include <algorithm>
0006 
0007 //reads in the file
0008 //the format is "address payload"
0009 //all commments are ignored (start with '#') except for the header comment (starts with #<header>)
0010 //currently ignores anything else on the line after the "address payload" and assumes they come first
0011 int l1t::LUT::read(std::istream& stream) {
0012   data_.clear();
0013 
0014   int readHeaderCode = readHeader_(stream);
0015   if (readHeaderCode != SUCCESS)
0016     return readHeaderCode;
0017 
0018   std::vector<std::pair<unsigned int, int> > entries;
0019   unsigned int maxAddress = addressMask_;
0020   std::string line;
0021 
0022   while (std::getline(stream, line)) {
0023     line.erase(std::find(line.begin(), line.end(), '#'), line.end());  //ignore comments
0024     std::istringstream lineStream(line);
0025     std::pair<unsigned int, int> entry;
0026     while (lineStream >> entry.first >> entry.second) {
0027       entry.first &= addressMask_;
0028       entry.second &= dataMask_;
0029       entries.push_back(entry);
0030       if (entry.first > maxAddress || maxAddress == addressMask_)
0031         maxAddress = entry.first;
0032     }
0033   }
0034   std::sort(entries.begin(), entries.end());
0035   if (entries.empty()) {
0036     //log the error we read nothing
0037     return NO_ENTRIES;
0038   }
0039   //this check is redundant as dups are also picked up by the next check but might make for easier debugging
0040   if (std::adjacent_find(entries.begin(), entries.end(), [](auto const& a, auto const& b) {
0041         return a.first == b.first;
0042       }) != entries.end()) {
0043     //log the error that we have duplicate addresses once masked
0044     return DUP_ENTRIES;
0045   }
0046   if (entries.front().first != 0 ||
0047       std::adjacent_find(entries.begin(), entries.end(), [](auto const& a, auto const& b) {
0048         return a.first + 1 != b.first;
0049       }) != entries.end()) {
0050     //log the error that we have a missing entry
0051     return MISS_ENTRIES;
0052   }
0053 
0054   if (maxAddress != std::numeric_limits<unsigned int>::max())
0055     data_.resize(maxAddress + 1, 0);
0056   else {
0057     //log the error that we have more addresses than we can deal with (which is 4gb so something probably has gone wrong anyways)
0058     return MAX_ADDRESS_OUTOFRANGE;
0059   }
0060 
0061   std::transform(entries.begin(), entries.end(), data_.begin(), [](auto const& x) { return x.second; });
0062   return SUCCESS;
0063 }
0064 
0065 void l1t::LUT::write(std::ostream& stream) const {
0066   stream << "#<header> V1 " << nrBitsAddress_ << " " << nrBitsData_ << " </header> " << std::endl;
0067   for (unsigned int address = 0; address < data_.size(); address++) {
0068     stream << (address & addressMask_) << " " << data(address) << std::endl;
0069   }
0070 }
0071 
0072 int l1t::LUT::readHeader_(std::istream& stream) {
0073   int startPos = stream.tellg();  //we are going to reset to this position before we exit
0074   std::string line;
0075   while (std::getline(stream, line)) {
0076     if (line.find("#<header>") == 0) {  //line
0077       std::istringstream lineStream(line);
0078 
0079       std::string version;      //currently not doing anything with this
0080       std::string headerField;  //currently not doing anything with this
0081       if (lineStream >> headerField >> version >> nrBitsAddress_ >> nrBitsData_) {
0082         addressMask_ = nrBitsAddress_ != 32 ? (0x1U << nrBitsAddress_) - 1 : ~0x0;
0083         dataMask_ = nrBitsData_ != 32 ? (0x1U << nrBitsData_) - 1 : ~0x0;
0084         stream.seekg(startPos);
0085         return SUCCESS;
0086       }
0087     }
0088   }
0089 
0090   nrBitsAddress_ = 0;
0091   nrBitsData_ = 0;
0092   addressMask_ = (0x1 << nrBitsAddress_) - 1;
0093   dataMask_ = (0x1 << nrBitsData_) - 1;
0094 
0095   stream.seekg(startPos);
0096   return NO_HEADER;
0097 }