CMS 3D CMS Logo

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