Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:30

0001 /****************************************************************************
0002  *
0003  * This is a part of PPS offline software.
0004  * Authors: D.J.Damiao , M.E.Pol
0005  ****************************************************************************/
0006 
0007 #include "EventFilter/CTPPSRawToDigi/interface/CTPPSTotemDataFormatter.h"
0008 
0009 #include "EventFilter/CTPPSRawToDigi/interface/CounterChecker.h"
0010 
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 
0013 #include "DataFormats/CTPPSDetId/interface/TotemRPDetId.h"
0014 #include "DataFormats/CTPPSDetId/interface/CTPPSDiamondDetId.h"
0015 
0016 #include "EventFilter/CTPPSRawToDigi/interface/DiamondVFATFrame.h"
0017 #include "DataFormats/CTPPSDigi/interface/TotemRPDigi.h"
0018 #include "CondFormats/DataRecord/interface/TotemReadoutRcd.h"
0019 
0020 #include "DataFormats/CTPPSDigi/interface/TotemFEDInfo.h"
0021 #include <cinttypes>
0022 #include <cstdint>
0023 
0024 #include <iostream>
0025 #include <iomanip>
0026 
0027 using namespace std;
0028 using namespace edm;
0029 typedef uint64_t word;
0030 
0031 CTPPSTotemDataFormatter::CTPPSTotemDataFormatter(std::map<TotemFramePosition, TotemVFATInfo> const &mapping)
0032     : m_WordCounter(0), m_DigiCounter(0) {
0033   int s32 = sizeof(Word32);
0034   int s64 = sizeof(Word64);
0035   int s8 = sizeof(char);
0036   if (s8 != 1 || s32 != 4 * s8 || s64 != 2 * s32) {
0037     LogError("UnexpectedSizes") << " unexpected sizes: "
0038                                 << "  size of char is: " << s8 << ", size of Word32 is: " << s32
0039                                 << ", size of Word64 is: " << s64 << ", send exception";
0040   }
0041 }
0042 
0043 void CTPPSTotemDataFormatter::formatRawData(unsigned int lvl1_ID,
0044                                             RawData &fedRawData,
0045                                             const Digis &digis,
0046                                             std::vector<PPSStripIndex> iDdet2fed) {
0047   std::map<int, vector<std::array<uint16_t, 12>>> words;
0048   for (auto const &itDig : digis) {
0049     int fedId;
0050     uint32_t rawId = itDig.first;
0051     const DetDigis &detDigis = itDig.second;
0052     std::array<uint16_t, 12> buf, bufCRC;
0053     std::map<uint32_t, vector<int>> mapIdCh;
0054     for (auto const &it : detDigis) {
0055       m_DigiCounter++;
0056       const int nCH = 128;
0057       int nStrip = it.stripNumber();
0058       int chipPosition = nStrip / nCH;
0059       int channel = nStrip - chipPosition * nCH;        //channel from DIGI
0060       uint32_t newrawId = rawId + 8192 * chipPosition;  //8192 - distance between chipIds
0061       mapIdCh[newrawId].push_back(channel);
0062     }
0063     for (auto &pId : mapIdCh) {
0064       PPSStripIndex myTest = {pId.first, 0, 0, 0, 0};
0065 
0066       // the range has always at most one element
0067       auto range = std::equal_range(iDdet2fed.begin(), iDdet2fed.end(), myTest, compare);
0068       if (range.first != range.second) {
0069         auto i = range.first - iDdet2fed.begin();
0070         for (int b = 0; b < 12; b++) {
0071           buf[b] = 0;
0072           bufCRC[b] = 0;
0073         }
0074         TotemRPDetId chipId(iDdet2fed.at(i).id);
0075         for (auto &ch : pId.second) {
0076           int chInWord = ch / 16;
0077           buf[9 - chInWord] |= (1 << (ch % 16));  //data[8->1]
0078           bufCRC[chInWord + 1] = buf[9 - chInWord];
0079         }
0080         fedId = iDdet2fed.at(i).fedid;
0081         int idxInFiber = iDdet2fed.at(i).idxinfiber;
0082         int gohId = iDdet2fed.at(i).gohid;
0083         unsigned int hFlag = 0x90;                                 //vmRaw
0084         buf[0] = (hFlag << 8) | (gohId << 4) | (idxInFiber << 0);  //
0085         buf[1] = (pId.first >> 15);                                //data[9]
0086         bufCRC[9] = buf[1];
0087         Word16 crc_fin = 0xffff;
0088         for (int i = 11; i >= 1; i--)
0089           crc_fin = VFATFrame::calculateCRC(crc_fin, bufCRC[i]);
0090         buf[10] = crc_fin;                            //data[0]
0091         buf[11] = (15 << 12) | (0 << 8) | (12 << 0);  //build trailer as RawDataUnpacker
0092         m_WordCounter++;
0093         words[fedId].push_back(buf);
0094       }  // range
0095     }    // mapIdCh
0096   }      //digis
0097 
0098   typedef std::map<int, vector<std::array<uint16_t, 12>>>::const_iterator RI;
0099   std::map<int, vector<uint16_t>> words16;
0100   for (auto &itFed : words) {
0101     int fedId = itFed.first;
0102     int wordsS = words.find(fedId)->second.size();
0103     //due to OrbitCounter block at RawDataUnpacker
0104     words16[fedId].emplace_back(0);
0105     words16[fedId].emplace_back(0);
0106     //writing data in 16-bit words
0107     for (int k = 0; k < wordsS; k++) {
0108       for (int b = 0; b < 12; b++) {
0109         words16[fedId].push_back(words.find(fedId)->second.at(k)[b]);
0110       }
0111     }
0112     // since raw words are written in the form of 64-bit packets
0113     // add extra 16-bit words to make number of words even if necessary
0114     while (words16.find(fedId)->second.size() % 4 != 0)
0115       words16[fedId].emplace_back(0);
0116 
0117     // size in Bytes; create output structure
0118     auto dataSize = (words16.find(fedId)->second.size()) * sizeof(Word16);
0119     int nHeaders = 1;
0120     int nTrailers = 1;
0121     dataSize += (nHeaders + nTrailers) * sizeof(Word64);
0122 
0123     FEDRawData rawData{dataSize};
0124 
0125     // get begining of data;
0126     Word64 *word = reinterpret_cast<Word64 *>(rawData.data());
0127 
0128     // write one header
0129     FEDHeader::set(reinterpret_cast<unsigned char *>(word), 0, lvl1_ID, 0, fedId, 3);
0130     word++;
0131 
0132     // write data
0133     unsigned int nWord16InFed = words16.find(fedId)->second.size();
0134     for (unsigned int i = 0; i < nWord16InFed; i += 4) {
0135       *word = (Word64(words16.find(fedId)->second[i + 3]) << 48) | (Word64(words16.find(fedId)->second[i + 2]) << 32) |
0136               (Word64(words16.find(fedId)->second[i + 1]) << 16) | words16.find(fedId)->second[i];
0137       word++;
0138     }
0139 
0140     // write one trailer
0141     FEDTrailer::set(reinterpret_cast<unsigned char *>(word), dataSize / sizeof(Word64), 0, 0, 0);
0142     word++;
0143 
0144     // check memory
0145     if (word != reinterpret_cast<Word64 *>(rawData.data() + dataSize)) {
0146       string s = "** PROBLEM in CTPPSTotemDataFormatter !!!";
0147       throw cms::Exception(s);
0148     }
0149     fedRawData[fedId] = rawData;
0150   }  // end of rawData
0151 }