CMS 3D CMS Logo

Phase2TrackerFEDBuffer.cc
Go to the documentation of this file.
5 
6 namespace Phase2Tracker {
7 
8  // implementation of Phase2TrackerFEDBuffer
9  Phase2TrackerFEDBuffer::Phase2TrackerFEDBuffer(const uint8_t* fedBuffer, const size_t fedBufferSize)
10  : buffer_(fedBuffer), bufferSize_(fedBufferSize) {
11  LogTrace("Phase2TrackerFEDBuffer") << "content of buffer with size: " << int(fedBufferSize) << std::endl;
12  for (size_t i = 0; i < fedBufferSize; i += 8) {
14  LogTrace("Phase2TrackerFEDBuffer") << " word " << std::setfill(' ') << std::setw(2) << i / 8 << " | " << std::hex
15  << std::setw(16) << std::setfill('0') << word << std::dec << std::endl;
16  }
17  LogTrace("Phase2TrackerFEDBuffer") << std::endl;
18 
19  // reserve all channels (should be 16x16 in our case)
21  // first 64 bits word is for DAQ header
23  // last 64 bit word is daq trailer
25  // tracker header follows daq header
27  // get pointer to payload
29  // fill list of Phase2TrackerFEDChannels and get pointers to trigger and comissioning data
30  findChannels();
31  }
32 
34 
36  // each FED can be connectd to up to 16 frontends (read from header)
37  // each fronted can be connected to up to 16 CBC
38  // in raw mode, a header of 16bits tells which CBC are activated on this FE
39  // in ZS mode, one byte is used to tell how many clusters are present in the current CBC
40  // one channel corresponds to one CBC chip, undependently of the mode
41 
42  // offset of beginning of current channel
43  size_t offsetBeginningOfChannel = 0;
44 
45  // iterate over all FEs to see if they are active
46  std::vector<bool>::iterator FE_it;
47  std::vector<bool> status = trackerHeader_.frontendStatus();
48 
50  for (FE_it = status.begin(); FE_it < status.end(); FE_it++) {
51  // if the current fronted is on, fill channels and advance pointer to end of channel
52  if (*FE_it) {
53  // read first FEDCH_PER_FEUNIT bits to know which CBC are on
54  uint16_t cbc_status = static_cast<uint16_t>(*(payloadPointer_ + (offsetBeginningOfChannel ^ 7)) << 8);
55  cbc_status += static_cast<uint16_t>(*(payloadPointer_ + ((offsetBeginningOfChannel + 1) ^ 7)));
56 
57  // advance pointer by FEDCH_PER_FEUNIT bits
58  offsetBeginningOfChannel += MAX_CBC_PER_FE / 8;
59  for (int i = 0; i < MAX_CBC_PER_FE; i++) {
60  // if CBC is ON, fill channel and advance pointer. else, push back empty channel
61  if ((cbc_status >> i) & 0x1) {
62  // Warning: STRIPS_PADDING+STRIPS_PER_CBC should always be an entire number of bytes
64  payloadPointer_, offsetBeginningOfChannel, (STRIPS_PADDING + STRIPS_PER_CBC) / 8));
65  offsetBeginningOfChannel += (STRIPS_PADDING + STRIPS_PER_CBC) / 8;
66  } else {
67  channels_.push_back(Phase2TrackerFEDChannel(nullptr, 0, 0));
68  }
69  }
70  } else {
71  // else fill with FEDCH_PER_FEUNIT null channels, don't advance the channel pointer
73  }
74  }
75  } else if (readoutMode() == READOUT_MODE_ZERO_SUPPRESSED) {
76  for (FE_it = status.begin(); FE_it < status.end(); FE_it++) {
77  if (*FE_it) {
78  for (int i = 0; i < MAX_CBC_PER_FE; i++) {
79  // read first byte to get number of clusters and skip it
80  uint8_t n_clusters = static_cast<uint8_t>(*(payloadPointer_ + offsetBeginningOfChannel));
81  offsetBeginningOfChannel += 1;
82  // each channel contains 2 bytes per cluster
83  channels_.push_back(Phase2TrackerFEDChannel(payloadPointer_, offsetBeginningOfChannel, 2 * n_clusters));
84  // skip clusters
85  offsetBeginningOfChannel += 2 * n_clusters;
86  }
87  } else {
88  // else fill with FEDCH_PER_FEUNIT null channels, don't advance the channel pointer
90  }
91  }
92  } else {
93  // TODO: throw exception for unrecognised readout mode
94  // check done at Phase2TrackerFEDHeader::readoutMode()
95  }
96  // round the offset to the next 64 bits word
97  int words64 = (offsetBeginningOfChannel + 8 - 1) / 8; // size in 64 bit
98  int payloadSize = words64 * 8; // size in bytes
99  triggerPointer_ = payloadPointer_ + payloadSize;
100 
101  // get diff size in bytes:
102  // fedBufferSize - (DAQHeader+TrackHeader+PayloadSize+TriggerSize+DAQTrailer)
103  int bufferDiff = bufferSize_ - 8 - trackerHeader_.getTrackerHeaderSize() - payloadSize - TRIGGER_SIZE - 8;
104 
105  // check if condition data is supposed to be there:
108  // diff must be equal to condition data size
109  if (bufferDiff <= 0) {
110  std::ostringstream ss;
111  ss << "[Phase2Tracker::Phase2TrackerFEDBuffer::" << __func__ << "] "
112  << "\n";
113  ss << "FED Buffer Size does not match data => missing condition data? : "
114  << "\n";
115  ss << "Expected Buffer Size " << bufferSize_ << " bytes"
116  << "\n";
117  ss << "Computed Buffer Size " << bufferSize_ + bufferDiff << " bytes"
118  << "\n";
119  throw cms::Exception("Phase2TrackerFEDBuffer") << ss.str();
120  }
121  } else {
122  // put a null pointer to indicate lack of condition data
123  condDataPointer_ = nullptr;
124  // check buffer size :
125  if (bufferDiff != 0) {
126  std::ostringstream ss;
127  ss << "[Phase2Tracker::Phase2TrackerFEDBuffer::" << __func__ << "] "
128  << "\n";
129  ss << "FED Buffer Size does not match data => corrupted buffer? : "
130  << "\n";
131  ss << "Expected Buffer Size " << bufferSize_ << " bytes"
132  << "\n";
133  ss << "Computed Buffer Size " << bufferSize_ + bufferDiff << " bytes"
134  << "\n";
135  throw cms::Exception("Phase2TrackerFEDBuffer") << ss.str();
136  }
137  }
138  }
139 
140  std::map<uint32_t, uint32_t> Phase2TrackerFEDBuffer::conditionData() const {
141  std::map<uint32_t, uint32_t> cdata;
142  // check if there is condition data
143  if (condDataPointer_) {
144  const uint8_t* pointer = condDataPointer_;
145  const uint8_t* stop = buffer_ + bufferSize_ - 8;
146  // first read the size
147  uint32_t size = 0;
148  // somehow the size is not inverted
149  //for (int i=0;i<4;++i) size += *(pointer-4+(i^7)) << (i*8);
150  size = *reinterpret_cast<const uint32_t*>(pointer);
151  LogTrace("Phase2TrackerFEDBuffer") << "Condition Data size = " << size << std::endl;
152  pointer += 8;
153  // now the conditions
154  while (pointer < stop) {
155  // somehow the data is not inverted
156  uint32_t data = 0;
157  //for (int i = 0, j=3 ; i<4; i++,j--)
158  //{ data += (*(pointer+i) << j*8); }
159  data = *reinterpret_cast<const uint32_t*>(pointer);
160  pointer += 4;
161 
162  uint32_t key = 0;
163  for (int i = 0, j = 3; i < 4; i++, j--) {
164  key += (*(pointer + i) << j * 8);
165  }
166  pointer += 4;
167 
168  cdata[key] = data;
169  }
170  // final check: cdata size == size
171  if (cdata.size() != size) {
172  std::ostringstream ss;
173  ss << "[Phase2Tracker::Phase2TrackerFEDBuffer::" << __func__ << "] "
174  << "\n";
175  ss << "Number of condition data does not match the announced value!"
176  << "\n";
177  ss << "Expected condition data Size " << size << " entries"
178  << "\n";
179  ss << "Computed condition data Size " << cdata.size() << " entries"
180  << "\n";
181  throw cms::Exception("Phase2TrackerFEDBuffer") << ss.str();
182  }
183  }
184  // REMOVE THIS : inject fake cond data for tests
185  /*
186  cdata[0x0011] = 0x0001;
187  cdata[0x0012] = 0x0002;
188  */
189  // add trigger data
190  cdata[0x0B0000FF] = (TRIGGER_SIZE > 0) ? (*triggerPointer_) : 0x00000000;
191  return cdata;
192  }
193 
195 
196 } // namespace Phase2Tracker
static const int TRIGGER_SIZE
Definition: utils.h:29
#define LogTrace(id)
uint64_t word
static const int MAX_CBC_PER_FE
Definition: utils.h:26
FEDReadoutMode
Definition: utils.h:96
key
prepare the HTCondor submission files and eventually submit them
std::vector< Phase2TrackerFEDChannel > channels_
unsigned long long uint64_t
Definition: Time.h:13
Phase2TrackerFEDBuffer(const uint8_t *fedBuffer, const size_t fedBufferSize)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
std::map< uint32_t, uint32_t > conditionData() const
static const int STRIPS_PER_CBC
Definition: utils.h:27
static const int MAX_FE_PER_FED
Definition: utils.h:25
static const int STRIPS_PADDING
Definition: utils.h:28
uint64_t read64(int offset, const uint8_t *buffer)
Definition: utils.h:187