CMS 3D CMS Logo

CTPPSTotemDataFormatter.cc
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * This is a part of PPS offline software.
4  * Authors: D.J.Damiao , M.E.Pol
5  ****************************************************************************/
6 
8 
10 
12 
15 
19 
21 #include <cinttypes>
22 #include <cstdint>
23 
24 #include <iostream>
25 #include <iomanip>
26 
27 using namespace std;
28 using namespace edm;
29 typedef uint64_t word;
30 
31 CTPPSTotemDataFormatter::CTPPSTotemDataFormatter(std::map<TotemFramePosition, TotemVFATInfo> const &mapping)
32  : m_WordCounter(0), m_DigiCounter(0) {
33  int s32 = sizeof(Word32);
34  int s64 = sizeof(Word64);
35  int s8 = sizeof(char);
36  if (s8 != 1 || s32 != 4 * s8 || s64 != 2 * s32) {
37  LogError("UnexpectedSizes") << " unexpected sizes: "
38  << " size of char is: " << s8 << ", size of Word32 is: " << s32
39  << ", size of Word64 is: " << s64 << ", send exception";
40  }
41 }
42 
43 void CTPPSTotemDataFormatter::formatRawData(unsigned int lvl1_ID,
45  const Digis &digis,
46  std::vector<PPSStripIndex> iDdet2fed) {
47  std::map<int, vector<std::array<uint16_t, 12>>> words;
48  for (auto const &itDig : digis) {
49  int fedId;
50  uint32_t rawId = itDig.first;
51  const DetDigis &detDigis = itDig.second;
52  std::array<uint16_t, 12> buf, bufCRC;
53  std::map<uint32_t, vector<int>> mapIdCh;
54  for (auto const &it : detDigis) {
55  m_DigiCounter++;
56  const int nCH = 128;
57  int nStrip = it.stripNumber();
58  int chipPosition = nStrip / nCH;
59  int channel = nStrip - chipPosition * nCH; //channel from DIGI
60  uint32_t newrawId = rawId + 8192 * chipPosition; //8192 - distance between chipIds
61  mapIdCh[newrawId].push_back(channel);
62  }
63  for (auto &pId : mapIdCh) {
64  PPSStripIndex myTest = {pId.first, 0, 0, 0, 0};
65 
66  // the range has always at most one element
67  auto range = std::equal_range(iDdet2fed.begin(), iDdet2fed.end(), myTest, compare);
68  if (range.first != range.second) {
69  auto i = range.first - iDdet2fed.begin();
70  for (int b = 0; b < 12; b++) {
71  buf[b] = 0;
72  bufCRC[b] = 0;
73  }
74  TotemRPDetId chipId(iDdet2fed.at(i).id);
75  for (auto &ch : pId.second) {
76  int chInWord = ch / 16;
77  buf[9 - chInWord] |= (1 << (ch % 16)); //data[8->1]
78  bufCRC[chInWord + 1] = buf[9 - chInWord];
79  }
80  fedId = iDdet2fed.at(i).fedid;
81  int idxInFiber = iDdet2fed.at(i).idxinfiber;
82  int gohId = iDdet2fed.at(i).gohid;
83  unsigned int hFlag = 0x90; //vmRaw
84  buf[0] = (hFlag << 8) | (gohId << 4) | (idxInFiber << 0); //
85  buf[1] = (pId.first >> 15); //data[9]
86  bufCRC[9] = buf[1];
87  Word16 crc_fin = 0xffff;
88  for (int i = 11; i >= 1; i--)
89  crc_fin = VFATFrame::calculateCRC(crc_fin, bufCRC[i]);
90  buf[10] = crc_fin; //data[0]
91  buf[11] = (15 << 12) | (0 << 8) | (12 << 0); //build trailer as RawDataUnpacker
92  m_WordCounter++;
93  words[fedId].push_back(buf);
94  } // range
95  } // mapIdCh
96  } //digis
97 
98  typedef std::map<int, vector<std::array<uint16_t, 12>>>::const_iterator RI;
99  std::map<int, vector<uint16_t>> words16;
100  for (auto &itFed : words) {
101  int fedId = itFed.first;
102  int wordsS = words.find(fedId)->second.size();
103  //due to OrbitCounter block at RawDataUnpacker
104  words16[fedId].emplace_back(0);
105  words16[fedId].emplace_back(0);
106  //writing data in 16-bit words
107  for (int k = 0; k < wordsS; k++) {
108  for (int b = 0; b < 12; b++) {
109  words16[fedId].push_back(words.find(fedId)->second.at(k)[b]);
110  }
111  }
112  // since raw words are written in the form of 64-bit packets
113  // add extra 16-bit words to make number of words even if necessary
114  while (words16.find(fedId)->second.size() % 4 != 0)
115  words16[fedId].emplace_back(0);
116 
117  // size in Bytes; create output structure
118  auto dataSize = (words16.find(fedId)->second.size()) * sizeof(Word16);
119  int nHeaders = 1;
120  int nTrailers = 1;
121  dataSize += (nHeaders + nTrailers) * sizeof(Word64);
122 
123  FEDRawData rawData{dataSize};
124 
125  // get begining of data;
126  Word64 *word = reinterpret_cast<Word64 *>(rawData.data());
127 
128  // write one header
129  FEDHeader::set(reinterpret_cast<unsigned char *>(word), 0, lvl1_ID, 0, fedId, 3);
130  word++;
131 
132  // write data
133  unsigned int nWord16InFed = words16.find(fedId)->second.size();
134  for (unsigned int i = 0; i < nWord16InFed; i += 4) {
135  *word = (Word64(words16.find(fedId)->second[i + 3]) << 48) | (Word64(words16.find(fedId)->second[i + 2]) << 32) |
136  (Word64(words16.find(fedId)->second[i + 1]) << 16) | words16.find(fedId)->second[i];
137  word++;
138  }
139 
140  // write one trailer
141  FEDTrailer::set(reinterpret_cast<unsigned char *>(word), dataSize / sizeof(Word64), 0, 0, 0);
142  word++;
143 
144  // check memory
145  if (word != reinterpret_cast<Word64 *>(rawData.data() + dataSize)) {
146  string s = "** PROBLEM in CTPPSTotemDataFormatter !!!";
147  throw cms::Exception(s);
148  }
150  } // end of rawData
151 }
Detector ID class for TOTEM Si strip detectors.
Definition: TotemRPDetId.h:30
CTPPSTotemDataFormatter(std::map< TotemFramePosition, TotemVFATInfo > const &mapping)
Log< level::Error, false > LogError
std::unordered_map< cms_uint32_t, DetDigis > Digis
uint64_t word
static void set(unsigned char *trailer, uint32_t lenght, uint16_t crc, uint8_t evt_stat, uint8_t tts, bool moreTrailers=false)
Set all fields in the trailer.
Definition: FEDTrailer.cc:31
std::unordered_map< int, FEDRawData > RawData
std::vector< TotemRPDigi > DetDigis
static bool compare(const PPSStripIndex &a, const PPSStripIndex &b)
unsigned long long uint64_t
Definition: Time.h:13
double b
Definition: hdecay.h:120
static word calculateCRC(word crc_in, word dato)
internaly used to check CRC
Definition: VFATFrame.cc:107
HLT enums.
static void set(unsigned char *header, uint8_t triggerType, uint32_t lvl1ID, uint16_t bxID, uint16_t sourceID, uint8_t version=0, bool moreHeaders=false)
Set all fields in the header.
Definition: FEDHeader.cc:25
void formatRawData(unsigned int lvl1_ID, RawData &fedRawData, const Digis &digis, std::vector< PPSStripIndex > v_iDdet2fed)