CMS 3D CMS Logo

SiStripDigiToRaw.cc
Go to the documentation of this file.
1 #include <iomanip>
2 #include <iostream>
3 #include <sstream>
4 
5 #include <fmt/format.h>
6 
17 
18 #include "SiStripDigiToRaw.h"
19 
20 namespace sistrip {
21 
22  // -----------------------------------------------------------------------------
24  DigiToRaw::DigiToRaw(FEDReadoutMode mode, uint8_t packetCode, bool useFedKey)
25  : mode_(mode),
26  packetCode_(packetCode),
27  useFedKey_(useFedKey),
28  bufferGenerator_(),
29  warnings_("DigiToRaw", "[sistrip::DigiToRaw::createFedBuffers_]", edm::isDebugEnabled()) {
30  if (edm::isDebugEnabled()) {
31  LogDebug("DigiToRaw") << "[sistrip::DigiToRaw::DigiToRaw]"
32  << " Constructing object...";
33  }
35  }
36 
37  // -----------------------------------------------------------------------------
40  if (edm::isDebugEnabled()) {
41  LogDebug("DigiToRaw") << "[sistrip::DigiToRaw::~DigiToRaw]"
42  << " Destructing object...";
43  }
44  }
45 
46  // -----------------------------------------------------------------------------
58  std::unique_ptr<FEDRawDataCollection>& buffers) {
59  createFedBuffers_(event, cabling, collection, buffers, true);
60  }
61 
65  std::unique_ptr<FEDRawDataCollection>& buffers) {
66  createFedBuffers_(event, cabling, collection, buffers, false);
67  }
68 
69  //with copy of headers from initial raw data collection (raw->digi->raw)
74  std::unique_ptr<FEDRawDataCollection>& buffers) {
75  createFedBuffers_(event, cabling, rawbuffers, collection, buffers, true);
76  }
77 
82  std::unique_ptr<FEDRawDataCollection>& buffers) {
83  createFedBuffers_(event, cabling, rawbuffers, collection, buffers, false);
84  }
85 
86  template <class Digi_t>
90  std::unique_ptr<FEDRawDataCollection>& buffers,
91  bool zeroSuppressed) {
93  //CAMM initialise to some dummy empty buffers??? Or OK like this ?
94  createFedBuffers_(event, cabling, rawbuffers, collection, buffers, zeroSuppressed);
95  }
96 
97  template <class Digi_t>
102  std::unique_ptr<FEDRawDataCollection>& buffers,
103  bool zeroSuppressed) {
104  const bool dataIsAlready8BitTruncated =
105  zeroSuppressed &&
106  (!(
107  //for special mode premix raw, data is zero-suppressed but not converted to 8 bit
109  // the same goes for 10bit ZS modes
113  try {
114  //set the L1ID to use in the buffers
115  bufferGenerator_.setL1ID(0xFFFFFF & event.id().event());
116  auto fed_ids = cabling->fedIds();
117 
118  //copy header if valid rawbuffers handle
119  if (rawbuffers.isValid()) {
120  if (edm::isDebugEnabled()) {
121  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
122  << " Valid raw buffers, getting headers from them..."
123  << " Number of feds: " << fed_ids.size() << " between " << *(fed_ids.begin())
124  << " and " << *(fed_ids.end());
125  }
126 
127  const FEDRawDataCollection& rawDataCollection = *rawbuffers;
128 
129  for (auto ifed = fed_ids.begin(); ifed != fed_ids.end(); ++ifed) {
130  const FEDRawData& rawfedData = rawDataCollection.FEDData(*ifed);
131 
132  if (edm::isDebugEnabled()) {
133  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
134  << "Fed " << *ifed << " : size of buffer = " << rawfedData.size();
135  }
136 
137  //need to construct full object to copy full header
138  if (rawfedData.size() == 0)
139  warnings_.add("Invalid raw data for FED, skipping", fmt::format("id {0}", *ifed));
140  const auto st_buffer = preconstructCheckFEDBuffer(rawfedData, true);
141  if (FEDBufferStatusCode::SUCCESS != st_buffer) {
142  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
143  << " Could not construct FEDBuffer for FED " << *ifed << std::endl;
144  continue;
145  }
146  sistrip::FEDBuffer fedbuffer{rawfedData, true};
147  const auto st_chan = fedbuffer.findChannels();
148  if (FEDBufferStatusCode::SUCCESS != st_chan) {
149  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
150  << " Could not construct FEDBuffer for FED " << *ifed << std::endl;
151  }
152  if (fedbuffer.headerType() == sistrip::HEADER_TYPE_INVALID) {
153  warnings_.add("Invalid header type for FED, skipping", fmt::format("id {0}", *ifed));
154  continue;
155  }
156 
157  if (edm::isDebugEnabled()) {
158  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
159  << " Original header type: " << fedbuffer.headerType();
160  }
161 
163  //fedbuffer.headerType());
164  bufferGenerator_.daqHeader() = fedbuffer.daqHeader();
165  bufferGenerator_.daqTrailer() = fedbuffer.daqTrailer();
166 
167  bufferGenerator_.trackerSpecialHeader() = fedbuffer.trackerSpecialHeader();
169 
170  if (edm::isDebugEnabled()) {
171  std::ostringstream debugStream;
172  if (ifed == fed_ids.begin()) {
174  std::cout << std::endl;
175  }
177  edm::LogWarning("DigiToRaw")
178  << "[sistrip::DigiToRaw::createFedBuffers_]"
179  << " Tracker special header apveAddress: "
180  << static_cast<int>(bufferGenerator_.trackerSpecialHeader().apveAddress())
181  << " - event type = " << bufferGenerator_.getDAQEventType()
182  << " - buffer format = " << bufferGenerator_.getBufferFormat() << "\n"
183  << " - SpecialHeader bufferformat " << bufferGenerator_.trackerSpecialHeader().bufferFormat()
184  << " - headertype " << bufferGenerator_.trackerSpecialHeader().headerType() << " - readoutmode "
185  << bufferGenerator_.trackerSpecialHeader().readoutMode() << " - apvaddrregister " << std::hex
187  << " - feenabledregister " << std::hex
189  << " - feoverflowregister " << std::hex
191  << " - statusregister " << bufferGenerator_.trackerSpecialHeader().fedStatusRegister() << "\n"
192  << " SpecialHeader: " << debugStream.str();
193  }
194 
195  std::unique_ptr<FEDFEHeader> tempFEHeader(fedbuffer.feHeader()->clone());
196  FEDFullDebugHeader* fedFeHeader = dynamic_cast<FEDFullDebugHeader*>(tempFEHeader.get());
197  if (edm::isDebugEnabled()) {
198  std::ostringstream debugStream;
199  if (ifed == fed_ids.begin()) {
200  std::cout << "FEHeader before transfer: " << std::endl;
201  fedFeHeader->print(std::cout);
202  std::cout << std::endl;
203  }
204  fedFeHeader->print(debugStream);
205  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
206  << " length of original feHeader: " << fedFeHeader->lengthInBytes() << "\n"
207  << debugStream.str();
208  }
209  //status registers
210  (bufferGenerator_.feHeader()).setBEStatusRegister(fedFeHeader->beStatusRegister());
211  (bufferGenerator_.feHeader()).setDAQRegister2(fedFeHeader->daqRegister2());
212  (bufferGenerator_.feHeader()).setDAQRegister(fedFeHeader->daqRegister());
213  for (uint8_t iFE = 1; iFE < 6; iFE++) {
215  .set32BitReservedRegister(iFE, fedFeHeader->get32BitWordFrom(fedFeHeader->feWord(iFE) + 10));
216  }
217 
218  std::vector<bool> feEnabledVec;
219  feEnabledVec.resize(FEUNITS_PER_FED, true);
220  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
221  feEnabledVec[iFE] = fedbuffer.trackerSpecialHeader().feEnabled(iFE);
222  (bufferGenerator_.feHeader()).setFEUnitMajorityAddress(iFE, fedFeHeader->feUnitMajorityAddress(iFE));
223  for (uint8_t iFEUnitChannel = 0; iFEUnitChannel < FEDCH_PER_FEUNIT; iFEUnitChannel++) {
225  .setChannelStatus(iFE, iFEUnitChannel, fedFeHeader->getChannelStatus(iFE, iFEUnitChannel));
226  } //loop on channels
227  } //loop on fe units
228  bufferGenerator_.setFEUnitEnables(feEnabledVec);
229 
230  if (edm::isDebugEnabled()) {
231  std::ostringstream debugStream;
232  if (ifed == fed_ids.begin()) {
233  std::cout << "\nFEHeader after transfer: " << std::endl;
235  std::cout << std::endl;
236  }
237  bufferGenerator_.feHeader().print(debugStream);
238  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
239  << " length of feHeader: " << bufferGenerator_.feHeader().lengthInBytes()
240  << "\n"
241  << debugStream.str();
242  }
243  auto conns = cabling->fedConnections(*ifed);
244 
245  FEDStripData fedData(dataIsAlready8BitTruncated);
246 
247  for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
248  // Determine FED key from cabling
249  uint32_t fed_key = ((iconn->fedId() & sistrip::invalid_) << 16) | (iconn->fedCh() & sistrip::invalid_);
250 
251  // Determine whether DetId or FED key should be used to index digi containers
252  uint32_t key = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? fed_key : iconn->detId();
253 
254  // Check key is non-zero and valid
255  if (!key || (key == sistrip::invalid32_)) {
256  continue;
257  }
258 
259  // Determine APV pair number (needed only when using DetId)
260  uint16_t ipair = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? 0 : iconn->apvPairNumber();
261 
262  FEDStripData::ChannelData& chanData = fedData[iconn->fedCh()];
263 
264  // Find digis for DetID in collection
265  if (!collection.isValid()) {
266  if (edm::isDebugEnabled()) {
267  edm::LogWarning("DigiToRaw") << "[DigiToRaw::createFedBuffers] "
268  << "digis collection is not valid...";
269  }
270  break;
271  }
272  typename std::vector<edm::DetSet<Digi_t> >::const_iterator digis = collection->find(key);
273  if (digis == collection->end()) {
274  continue;
275  }
276 
277  typename edm::DetSet<Digi_t>::const_iterator idigi, digis_begin(digis->data.begin());
278  for (idigi = digis_begin; idigi != digis->data.end(); idigi++) {
279  if (STRIP(idigi, digis_begin) < ipair * 256 || STRIP(idigi, digis_begin) > ipair * 256 + 255) {
280  continue;
281  }
282  const unsigned short strip = STRIP(idigi, digis_begin) % 256;
283 
284  if (strip >= STRIPS_PER_FEDCH) {
285  if (edm::isDebugEnabled()) {
286  std::stringstream ss;
287  ss << "[sistrip::DigiToRaw::createFedBuffers]"
288  << " strip >= strips_per_fedCh";
289  edm::LogWarning("DigiToRaw") << ss.str();
290  }
291  continue;
292  }
293 
294  // check if value already exists
295  if (edm::isDebugEnabled()) {
296  const uint16_t value = 0; //chanData[strip];
297  if (value && value != (*idigi).adc()) {
298  std::stringstream ss;
299  ss << "[sistrip::DigiToRaw::createFedBuffers]"
300  << " Incompatible ADC values in buffer!"
301  << " FedId/FedCh: " << *ifed << "/" << iconn->fedCh()
302  << " DetStrip: " << STRIP(idigi, digis_begin) << " FedChStrip: " << strip
303  << " AdcValue: " << (*idigi).adc() << " RawData[" << strip << "]: " << value;
304  edm::LogWarning("DigiToRaw") << ss.str();
305  }
306  }
307 
308  // Add digi to buffer
309  chanData[strip] = (*idigi).adc();
310  }
311  }
312  // if ((*idigi).strip() >= (ipair+1)*256) break;
313 
314  if (edm::isDebugEnabled()) {
315  edm::LogWarning("DigiToRaw") << "DigiToRaw::createFedBuffers] "
316  << "Almost at the end...";
317  }
318  //create the buffer
319  FEDRawData& fedrawdata = buffers->FEDData(*ifed);
320  bufferGenerator_.generateBuffer(&fedrawdata, fedData, *ifed, packetCode_);
321 
322  if (edm::isDebugEnabled()) {
323  std::ostringstream debugStream;
324  bufferGenerator_.feHeader().print(debugStream);
325  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
326  << " length of final feHeader: " << bufferGenerator_.feHeader().lengthInBytes()
327  << "\n"
328  << debugStream.str();
329  }
330  } //loop on fedids
331  if (edm::isDebugEnabled()) {
332  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
333  << "end of first loop on feds";
334  }
335 
336  } //end of workflow for copying header, below is workflow without copying header
337  else {
338  if (edm::isDebugEnabled()) {
339  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
340  << "Now getting the digis..."
341  << " Number of feds: " << fed_ids.size() << " between " << *(fed_ids.begin())
342  << " and " << *(fed_ids.end());
343  }
344 
345  for (auto ifed = fed_ids.begin(); ifed != fed_ids.end(); ++ifed) {
346  auto conns = cabling->fedConnections(*ifed);
347 
348  FEDStripData fedData(dataIsAlready8BitTruncated);
349 
350  for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
351  // Determine FED key from cabling
352  uint32_t fed_key = ((iconn->fedId() & sistrip::invalid_) << 16) | (iconn->fedCh() & sistrip::invalid_);
353 
354  // Determine whether DetId or FED key should be used to index digi containers
355  uint32_t key = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? fed_key : iconn->detId();
356 
357  // Check key is non-zero and valid
358  if (!key || (key == sistrip::invalid32_)) {
359  continue;
360  }
361 
362  // Determine APV pair number (needed only when using DetId)
363  uint16_t ipair = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? 0 : iconn->apvPairNumber();
364 
365  FEDStripData::ChannelData& chanData = fedData[iconn->fedCh()];
366 
367  // Find digis for DetID in collection
368  if (!collection.isValid()) {
369  if (edm::isDebugEnabled()) {
370  edm::LogWarning("DigiToRaw") << "[DigiToRaw::createFedBuffers] "
371  << "digis collection is not valid...";
372  }
373  break;
374  }
375  typename std::vector<edm::DetSet<Digi_t> >::const_iterator digis = collection->find(key);
376  if (digis == collection->end()) {
377  continue;
378  }
379 
380  typename edm::DetSet<Digi_t>::const_iterator idigi, digis_begin(digis->data.begin());
381  for (idigi = digis_begin; idigi != digis->data.end(); idigi++) {
382  if (STRIP(idigi, digis_begin) < ipair * 256 || STRIP(idigi, digis_begin) > ipair * 256 + 255) {
383  continue;
384  }
385  const unsigned short strip = STRIP(idigi, digis_begin) % 256;
386 
387  if (strip >= STRIPS_PER_FEDCH) {
388  if (edm::isDebugEnabled()) {
389  std::stringstream ss;
390  ss << "[sistrip::DigiToRaw::createFedBuffers]"
391  << " strip >= strips_per_fedCh";
392  edm::LogWarning("DigiToRaw") << ss.str();
393  }
394  continue;
395  }
396 
397  // check if value already exists
398  if (edm::isDebugEnabled()) {
399  const uint16_t value = 0; //chanData[strip];
400  if (value && value != (*idigi).adc()) {
401  std::stringstream ss;
402  ss << "[sistrip::DigiToRaw::createFedBuffers]"
403  << " Incompatible ADC values in buffer!"
404  << " FedId/FedCh: " << *ifed << "/" << iconn->fedCh()
405  << " DetStrip: " << STRIP(idigi, digis_begin) << " FedChStrip: " << strip
406  << " AdcValue: " << (*idigi).adc() << " RawData[" << strip << "]: " << value;
407  edm::LogWarning("DigiToRaw") << ss.str();
408  }
409  }
410 
411  // Add digi to buffer
412  chanData[strip] = (*idigi).adc();
413  }
414  }
415  // if ((*idigi).strip() >= (ipair+1)*256) break;
416 
417  if (edm::isDebugEnabled()) {
418  edm::LogWarning("DigiToRaw") << "DigiToRaw::createFedBuffers] "
419  << "Almost at the end...";
420  }
421  //create the buffer
422  FEDRawData& fedrawdata = buffers->FEDData(*ifed);
423  bufferGenerator_.generateBuffer(&fedrawdata, fedData, *ifed, packetCode_);
424 
425  if (edm::isDebugEnabled()) {
426  std::ostringstream debugStream;
427  bufferGenerator_.feHeader().print(debugStream);
428  edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
429  << " length of final feHeader: " << bufferGenerator_.feHeader().lengthInBytes()
430  << "\n"
431  << debugStream.str();
432  }
433  } //loop on feds
434  } //end if-else for copying header
435  } //try
436  catch (const std::exception& e) {
437  if (edm::isDebugEnabled()) {
438  edm::LogWarning("DigiToRaw") << "DigiToRaw::createFedBuffers] "
439  << "Exception caught : " << e.what();
440  }
441  }
442  }
443 
445  const edm::DetSet<SiStripDigi>::const_iterator& begin) const {
446  return it->strip();
447  }
449  const edm::DetSet<SiStripRawDigi>::const_iterator& begin) const {
450  return it - begin;
451  }
452 
453 } // namespace sistrip
bool isDebugEnabled()
virtual size_t lengthInBytes() const =0
DigiToRaw(FEDReadoutMode mode, uint8_t packetCode, bool use_fed_key)
FEDBufferGenerator & setReadoutMode(const FEDReadoutMode newReadoutMode)
static const uint32_t invalid32_
Definition: Constants.h:15
void print(std::ostream &os) const
FEDDAQEventType getDAQEventType() const
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
WarningSummary warnings_
TrackerSpecialHeader & trackerSpecialHeader()
sistrip classes
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED10
FEDBufferGenerator & setFEUnitEnables(const std::vector< bool > &feUnitsEnabled)
static const uint16_t FEUNITS_PER_FED
FEDStatusRegister fedStatusRegister() const
Definition: value.py:1
void createFedBuffers(edm::Event &, edm::ESHandle< SiStripFedCabling > &cabling, edm::Handle< edm::DetSetVector< SiStripDigi > > &digis, std::unique_ptr< FEDRawDataCollection > &buffers)
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
void add(const std::string &message, const std::string &details="")
FEDReadoutMode mode_
uint16_t STRIP(const edm::DetSet< SiStripDigi >::const_iterator &it, const edm::DetSet< SiStripDigi >::const_iterator &begin) const
static const uint16_t STRIPS_PER_FEDCH
FEDBufferGenerator & setHeaderType(const FEDHeaderType newHeaderType)
virtual void print(std::ostream &os) const =0
FEDBufferGenerator & setL1ID(const uint32_t newL1ID)
static const uint16_t FEDCH_PER_FEUNIT
void generateBuffer(FEDRawData *rawDataObject, const FEDStripData &data, uint16_t sourceID, uint8_t packetCode) const
static const uint16_t invalid_
Definition: Constants.h:16
FEDBufferFormat getBufferFormat() const
bool isValid() const
Definition: HandleBase.h:70
collection_type data
Definition: DetSet.h:80
HLT enums.
FEDBufferStatusCode preconstructCheckFEDBuffer(const FEDRawData &fedBuffer, bool allowBadBuffer=false)
Log< level::Warning, false > LogWarning
collection_type::const_iterator const_iterator
Definition: DetSet.h:31
FEDBufferGenerator bufferGenerator_
FedsConstIterRange fedIds() const
void createFedBuffers_(edm::Event &, edm::ESHandle< SiStripFedCabling > &cabling, edm::Handle< edm::DetSetVector< Digi_t > > &digis, std::unique_ptr< FEDRawDataCollection > &buffers, bool zeroSuppressed)
ConnsConstIterRange fedConnections(uint16_t fed_id) const
Definition: event.py:1
#define LogDebug(id)