CMS 3D CMS Logo

RawToDigiConverter.cc
Go to the documentation of this file.
1 /****************************************************************************
2 *
3 * This is a part of TOTEM offline software.
4 * Authors:
5 * Jan Kašpar (jan.kaspar@gmail.com)
6 * Seyed Mohsen Etesami (setesami@cern.ch)
7 * Laurent Forthomme
8 ****************************************************************************/
9 
11 
17 
22 
23 using namespace std;
24 using namespace edm;
25 
27  : verbosity(conf.getUntrackedParameter<unsigned int>("verbosity", 0)),
28  printErrorSummary(conf.getUntrackedParameter<bool>("printErrorSummary")),
29  printUnknownFrameSummary(conf.getUntrackedParameter<bool>("printUnknownFrameSummary")),
30 
31  testFootprint(conf.getParameter<unsigned int>("testFootprint")),
32  testCRC(conf.getParameter<unsigned int>("testCRC")),
33  testID(conf.getParameter<unsigned int>("testID")),
34  testECMostFrequent(conf.getParameter<unsigned int>("testECMostFrequent")),
35  testBCMostFrequent(conf.getParameter<unsigned int>("testBCMostFrequent")),
36 
37  EC_min(conf.getUntrackedParameter<unsigned int>("EC_min", 10)),
38  BC_min(conf.getUntrackedParameter<unsigned int>("BC_min", 10)),
39 
40  EC_fraction(conf.getUntrackedParameter<double>("EC_fraction", 0.6)),
41  BC_fraction(conf.getUntrackedParameter<double>("BC_fraction", 0.6)),
42 
43  olderTotemT2FileTest(conf.getParameter<bool>("useOlderT2TestFile")) {}
44 
46  const TotemDAQMapping &mapping,
47  map<TotemFramePosition, RawToDigiConverter::Record> &records) {
48  // EC and BC checks (wrt. the most frequent value), BC checks per subsystem
51 
52  // initialise structure merging vfat frame data with the mapping
53  for (auto &p : mapping.VFATMapping) {
54  TotemVFATStatus st;
55  st.setMissing(true);
56  records[p.first] = {&p.second, nullptr, st};
57  }
58 
59  // event error message buffer
60  stringstream ees;
61 
62  // associate data frames with records
63  for (VFATFrameCollection::Iterator fr(&input); !fr.IsEnd(); fr.Next()) {
64  // frame error message buffer
65  stringstream fes;
66 
67  bool problemsPresent = false;
68  bool stopProcessing = false;
69 
70  // skip data frames not listed in the DAQ mapping
71  auto records_it = records.find(fr.Position());
72  if (records_it == records.end()) {
73  unknownSummary[fr.Position()]++;
74  continue;
75  }
76 
77  // update record
78  Record &record = records_it->second;
79  record.frame = fr.Data();
80  record.status.setMissing(false);
81  record.status.setNumberOfClustersSpecified(record.frame->isNumberOfClustersPresent());
82  record.status.setNumberOfClusters(record.frame->getNumberOfClusters());
83 
84  // check for T2 payload bits
85  int rawT2 = fr.Position().getRawPosition();
86  bool isT2Frame = (rawT2 >> 18);
87 
88  // check footprint
89  if (((!isT2Frame) && testFootprint != tfNoTest && !record.frame->checkFootprint()) ||
90  (isT2Frame && testFootprint != tfNoTest && !record.frame->checkFootprintT2())) {
91  problemsPresent = true;
92 
93  if (verbosity > 0)
94  fes << " invalid footprint" << endl;
95 
96  if (testFootprint == tfErr) {
97  record.status.setFootprintError();
98  stopProcessing = true;
99  }
100  }
101 
102  // check CRC
103  if (((!isT2Frame) && (testCRC != tfNoTest && !record.frame->checkCRC())) ||
104  (isT2Frame && testCRC != tfNoTest && !record.frame->checkCRCT2())) {
105  problemsPresent = true;
106 
107  if (verbosity > 0)
108  fes << " CRC failure" << endl;
109 
110  if (testCRC == tfErr) {
111  record.status.setCRCError();
112  stopProcessing = true;
113  }
114  }
115 
116  // check the id mismatch
117  if (testID != tfNoTest && record.frame->isIDPresent() &&
118  (record.frame->getChipID() & 0xFFF) != (record.info->hwID & 0xFFF)) {
119  if (verbosity > 0)
120  fes << " ID mismatch (data: 0x" << hex << record.frame->getChipID() << ", mapping: 0x" << record.info->hwID
121  << dec << ", symbId: " << record.info->symbolicID.symbolicID << ")" << endl;
122 
123  if (testID == tfErr) {
124  record.status.setIDMismatch();
125  stopProcessing = true;
126  }
127  }
128 
129  // if there were errors, put the information to ees buffer
130  if (verbosity > 0 && problemsPresent) {
131  string message = (stopProcessing) ? "(and will be dropped)" : "(but will be used though)";
132  if (verbosity > 2) {
133  if (isT2Frame && verbosity > 3)
134  record.frame->PrintT2();
135  ees << " Frame at " << fr.Position() << " seems corrupted " << message << ":" << endl;
136  ees << fes.rdbuf();
137  } else
138  ees << " Frame at " << fr.Position() << " seems corrupted " << message << "." << endl;
139  }
140 
141  // if there were serious errors, do not process this frame
142  if (stopProcessing)
143  continue;
144 
145  // fill EC and BC values to the statistics
146  if (fr.Data()->isECPresent())
147  ECChecker.Fill(fr.Data()->getEC(), fr.Position());
148 
149  if (fr.Data()->isBCPresent())
150  BCChecker.Fill(fr.Data()->getBC(), fr.Position());
151  }
152 
153  // analyze EC and BC statistics
155  ECChecker.Analyze(records, (testECMostFrequent == tfErr), ees);
156 
158  BCChecker.Analyze(records, (testBCMostFrequent == tfErr), ees);
159 
160  // add error message for missing frames
161  if (verbosity > 1) {
162  for (const auto &p : records) {
163  if (p.second.status.isMissing())
164  ees << "Frame for VFAT " << p.first << " is not present in the data." << endl;
165  }
166  }
167 
168  // print error message
169  if (verbosity > 0 && !ees.rdbuf()->str().empty()) {
170  if (verbosity > 1)
171  LogWarning("Totem") << "Error in RawToDigiConverter::runCommon > "
172  << "event contains the following problems:" << endl
173  << ees.rdbuf() << endl;
174  else
175  LogWarning("Totem") << "Error in RawToDigiConverter::runCommon > "
176  << "event contains problems." << endl;
177  }
178 
179  // increase error counters
180  if (printErrorSummary) {
181  for (const auto &it : records) {
182  if (!it.second.status.isOK()) {
183  auto &m = errorSummary[it.first];
184  m[it.second.status]++;
185  }
186  }
187  }
188 }
189 
191  const TotemDAQMapping &mapping,
192  const TotemAnalysisMask &analysisMask,
194  DetSetVector<TotemVFATStatus> &finalStatus) {
195  // structure merging vfat frame data with the mapping
196  map<TotemFramePosition, Record> records;
197 
198  // common processing - frame validation
199  runCommon(input, mapping, records);
200 
201  // second loop over data
202  for (auto &p : records) {
203  Record &record = p.second;
204 
205  // calculate ids
206  TotemRPDetId chipId(record.info->symbolicID.symbolicID);
207  uint8_t chipPosition = chipId.chip();
208  TotemRPDetId detId = chipId.planeId();
209 
210  // update chipPosition in status
211  record.status.setChipPosition(chipPosition);
212 
213  // produce digi only for good frames
214  if (record.status.isOK()) {
215  // find analysis mask (needs a default=no mask, if not in present the mapping)
217  anMa.fullMask = false;
218 
219  auto analysisIter = analysisMask.analysisMask.find(record.info->symbolicID);
220  if (analysisIter != analysisMask.analysisMask.end()) {
221  // if there is some information about masked channels - save it into conversionStatus
222  anMa = analysisIter->second;
223  if (anMa.fullMask)
224  record.status.setFullyMaskedOut();
225  else
226  record.status.setPartiallyMaskedOut();
227  }
228 
229  // create the digi
230  unsigned short offset = chipPosition * 128;
231  const vector<unsigned char> &activeChannels = record.frame->getActiveChannels();
232 
233  for (auto ch : activeChannels) {
234  // skip masked channels
235  if (!anMa.fullMask && anMa.maskedChannels.find(ch) == anMa.maskedChannels.end()) {
236  DetSet<TotemRPDigi> &digiDetSet = rpData.find_or_insert(detId);
237  digiDetSet.emplace_back(offset + ch);
238  }
239  }
240  }
241 
242  // save status
243  DetSet<TotemVFATStatus> &statusDetSet = finalStatus.find_or_insert(detId);
244  statusDetSet.push_back(record.status);
245  }
246 }
247 
249  const TotemDAQMapping &mapping,
250  const TotemAnalysisMask &mask,
253  // structure merging vfat frame data with the mapping
254  map<TotemFramePosition, Record> records;
255 
256  // common processing - frame validation
257  runCommon(coll, mapping, records);
258 
259  // second loop over data
260  for (auto &p : records) {
261  Record &record = p.second;
262 
263  // calculate ids
264  CTPPSDiamondDetId detId(record.info->symbolicID.symbolicID);
265 
266  if (record.status.isOK()) {
267  // update Event Counter in status
268  record.status.setEC(record.frame->getEC() & 0xFF);
269 
270  // create the digi
271  DetSet<CTPPSDiamondDigi> &digiDetSet = digi.find_or_insert(detId);
277  }
278 
279  // save status
280  DetSet<TotemVFATStatus> &statusDetSet = status.find_or_insert(detId);
281  statusDetSet.push_back(record.status);
282  }
283 }
284 
286  const TotemDAQMapping &mapping,
287  const TotemAnalysisMask &mask,
290  // structure merging vfat frame data with the mapping
291  map<TotemFramePosition, Record> records;
292 
293  // common processing - frame validation
294  runCommon(coll, mapping, records);
295 
296  // second loop over data
297  for (auto &p : records) {
298  Record &record = p.second;
299  if (!record.status.isOK())
300  continue;
301 
302  const TotemFramePosition *framepos = &p.first;
303 
304  if (((framepos->getIdxInFiber() % 2) == 0) && (framepos->getIdxInFiber() < 14)) {
305  //corresponding channel data are always in the neighbouring idx in fiber
306 
307  TotemFramePosition frameposdata(framepos->getSubSystemId(),
308  framepos->getTOTFEDId(),
309  framepos->getOptoRxId(),
310  framepos->getGOHId(),
311  (framepos->getIdxInFiber() + 1));
312  TotemFramePosition frameposEvtInfo(
313  framepos->getSubSystemId(), framepos->getTOTFEDId(), framepos->getOptoRxId(), framepos->getGOHId(), 0xe);
314 
315  auto channelwaveformPtr = records.find(frameposdata);
316  auto eventInfoPtr = records.find(frameposEvtInfo);
317 
318  if (channelwaveformPtr != records.end() && eventInfoPtr != records.end()) {
319  Record &channelwaveform = records[frameposdata];
320  Record &eventInfo = records[frameposEvtInfo];
321 
322  // Extract all the waveform information from the raw data
323  TotemSampicFrame totemSampicFrame((const uint8_t *)record.frame->getData(),
324  (const uint8_t *)channelwaveform.frame->getData(),
325  (const uint8_t *)eventInfo.frame->getData());
326 
327  if (totemSampicFrame.valid()) {
328  // create the digi
329  TotemTimingEventInfo eventInfoTmp(totemSampicFrame.getEventHardwareId(),
330  totemSampicFrame.getL1ATimestamp(),
331  totemSampicFrame.getBunchNumber(),
332  totemSampicFrame.getOrbitNumber(),
333  totemSampicFrame.getEventNumber(),
334  totemSampicFrame.getChannelMap(),
335  totemSampicFrame.getL1ALatency(),
336  totemSampicFrame.getNumberOfSentSamples(),
337  totemSampicFrame.getOffsetOfSamples(),
338  totemSampicFrame.getPLLInfo());
339  TotemTimingDigi digiTmp(totemSampicFrame.getHardwareId(),
340  totemSampicFrame.getFPGATimestamp(),
341  totemSampicFrame.getTimestampA(),
342  totemSampicFrame.getTimestampB(),
343  totemSampicFrame.getCellInfo(),
344  totemSampicFrame.getSamples(),
345  eventInfoTmp);
346  // calculate ids
347  TotemTimingDetId detId(record.info->symbolicID.symbolicID);
349  mapping.getTimingChannel(totemSampicFrame.getHardwareId());
350  // for FW Version > 0 plane and channel are encoded in the dataframe
351  if (totemSampicFrame.getFWVersion() == 0) // Mapping not present in HW, read from SW for FW versions == 0
352  {
353  if (SWpair.plane == -1 || SWpair.channel == -1) {
354  if (verbosity > 0)
355  LogWarning("Totem") << "Error in RawToDigiConverter::TotemTiming > "
356  << "HwId not recognized! hwId: " << std::hex
357  << (unsigned int)totemSampicFrame.getHardwareId() << endl;
358  } else {
359  detId.setPlane(SWpair.plane % 4);
360  detId.setChannel(SWpair.channel);
361  }
362  } else // Mapping read from HW, checked by SW
363  {
364  const int HWplane = totemSampicFrame.getDetPlane() % 16;
365  const int HWchannel = totemSampicFrame.getDetChannel() % 16;
366 
367  if (SWpair.plane == -1 || SWpair.channel == -1) {
368  if (verbosity > 0)
369  LogWarning("Totem") << "Warning in RawToDigiConverter::TotemTiming > "
370  << "HwId not recognized! hwId: " << std::hex
371  << (unsigned int)totemSampicFrame.getHardwareId()
372  << "\tUsing plane and ch from HW without check!" << endl;
373  } else {
374  if (verbosity > 0 && (SWpair.plane != HWplane || SWpair.channel != HWchannel))
375  LogWarning("Totem") << "Warning in RawToDigiConverter::TotemTiming > "
376  << "Hw mapping different from SW mapping. hwId: " << std::hex
377  << (unsigned int)totemSampicFrame.getHardwareId() << "HW: " << std::dec << HWplane
378  << ":" << HWchannel << "\tSW " << SWpair.plane << ":" << SWpair.channel
379  << "\tUsing plane and ch from HW!" << endl;
380  }
381  detId.setPlane(HWplane % 4);
382  detId.setChannel(HWchannel);
383  }
384 
385  DetSet<TotemTimingDigi> &digiDetSet = digi.find_or_insert(detId);
386  digiDetSet.push_back(digiTmp);
387  }
388  }
389  }
390  }
391 }
392 
394  const TotemDAQMapping &mapping,
395  const TotemAnalysisMask &mask,
398  // structure merging vfat frame data with the mapping
399  map<TotemFramePosition, Record> records;
400 
401  // common processing - frame validation
402  runCommon(coll, mapping, records);
403 
404  int allT2 = 0;
405  int goodT2 = 0;
406  int foundT2 = 0;
407  const int T2shiftOld = (olderTotemT2FileTest ? 8 : 0); //Run on TOTEM T2 test file (ver 2.1) or final T2 data ver 2.3
408 
409  // second loop over data
410  for (auto &p : records) {
411  Record &record = p.second;
412 
413  allT2++;
414  // calculate ids
415  TotemT2DetId detId(record.info->symbolicID.symbolicID);
416 
417  if (record.status.isOK()) {
418  // update Event Counter in status
419  record.status.setEC(record.frame->getEC() & 0xFF);
420  goodT2++;
421  if (verbosity > 2) {
422  LogWarning("Totem") << "RawToDigiConverter: VFAT frame number " << allT2
423  << " is OK , mapping HW_ID (decimal) is: " << (record.info->hwID)
424  << ", T2DetId arm/plane/channel = " << (detId) << endl;
425  LogWarning("Totem") << "HW_id_16b CH0 (dec), LE CH0, TE CH0, marker CH0, HW_id_16b CH1 (dec), LE CH1,"
426  << " TE CH1, marker CH1 = ";
427  for (size_t y = 0; y < 2; y++) {
428  LogWarning("Totem") << ((unsigned int)totem::nt2::vfat::newChannelId(*record.frame, y)) << "/"
429  << ((unsigned int)totem::nt2::vfat::leadingEdgeTime(*record.frame, y)) << "/"
430  << ((unsigned int)totem::nt2::vfat::trailingEdgeTime(*record.frame, y)) << "/"
431  << ((unsigned int)totem::nt2::vfat::channelMarker(*record.frame, y)) << "/";
432  }
433  }
434  for (size_t frame_id = 0; frame_id < totem::nt2::vfat::num_channels_per_payload; ++frame_id) {
435  if (const uint16_t hw_id = totem::nt2::vfat::newChannelId(*record.frame, frame_id) >> T2shiftOld;
436  hw_id == record.info->hwID) { // only unpack the payload associated to this hardware ID
437  // create the digi
439  .emplace_back(hw_id,
440  totem::nt2::vfat::channelMarker(*record.frame, frame_id),
441  totem::nt2::vfat::leadingEdgeTime(*record.frame, frame_id),
442  totem::nt2::vfat::trailingEdgeTime(*record.frame, frame_id),
444  foundT2++;
445  } else {
446  if (verbosity > 2)
447  LogWarning("Totem") << "HW_ID comparison fail (CH#/Channel HwID/Mapping HwID): " << ((int)frame_id) << "/"
448  << ((unsigned int)hw_id) << "/" << (record.info->hwID) << endl;
449  }
450  }
451  } else {
452  if (verbosity > 1)
453  LogWarning("Totem") << "Bad T2 record, is missing/IDmismatch/footprintError"
454  << "/CRCerror/ECprogressBad/BCprogressBad: " << record.status.isMissing() << "/"
455  << record.status.isIDMismatch() << "/" << record.status.isFootprintError() << "/"
456  << record.status.isCRCError() << "/" << record.status.isECProgressError() << "/"
457  << record.status.isBCProgressError() << "/" << endl;
458  }
459 
460  // save status
461  DetSet<TotemVFATStatus> &statusDetSet = status.find_or_insert(detId);
462  statusDetSet.push_back(record.status);
463  }
464  if (verbosity > 1)
465  LogWarning("Totem") << "RawToDigiConverter:: VFAT frames per event, total/good/matched the xml mapping"
466  << " (T2Digi created): " << allT2 << "/" << goodT2 << "/" << foundT2 << endl;
467 }
468 
470  // print error summary
471  if (printErrorSummary) {
472  if (!errorSummary.empty()) {
473  stringstream ees;
474  for (const auto &vit : errorSummary) {
475  ees << vit.first << endl;
476 
477  for (const auto &it : vit.second)
478  ees << " " << it.first << " : " << it.second << endl;
479  }
480 
481  LogWarning("Totem") << "RawToDigiConverter: error summary (error signature : number of such events)\n"
482  << endl
483  << ees.rdbuf();
484  } else {
485  LogInfo("Totem") << "RawToDigiConverter: no errors to be reported.";
486  }
487  }
488 
489  // print summary of unknown frames (found in data but not in the mapping)
491  if (!unknownSummary.empty()) {
492  stringstream ees;
493  for (const auto &it : unknownSummary)
494  ees << " " << it.first << " : " << it.second << endl;
495 
496  LogWarning("Totem")
497  << "RawToDigiConverter: frames found in data, but not in the mapping (frame position : number of events)\n"
498  << endl
499  << ees.rdbuf();
500  } else {
501  LogInfo("Totem") << "RawToDigiConverter: no unknown frames to be reported.";
502  }
503  }
504 }
Detector ID class for TOTEM Si strip detectors.
Definition: TotemRPDetId.h:30
const unsigned int testID
uint32_t getLeadingEdgeTime(const VFATFrame &frame)
get timing information for single leading edge
Contains data on masked channels of a VFAT.
const unsigned int testCRC
void push_back(const T &t)
Definition: DetSet.h:66
Channel-mask mapping.
VFATFrame::word * getData()
Definition: VFATFrame.h:38
void runCommon(const VFATFrameCollection &input, const TotemDAQMapping &mapping, std::map< TotemFramePosition, Record > &records)
Common processing for all VFAT based sub-systems.
Class for finding the most popular both EC and BC counter, and filling the conversion status &#39;wrong E...
Detector ID class for Totem T2 detectors. Bits [19:31] : Base CTPPSDetId class attributes Bits [16:18...
Definition: TotemT2DetId.h:25
uint16_t leadingEdgeTime(const VFATFrame &frame, size_t ch_id)
get timing information for single leading edge
const double BC_fraction
const unsigned int BC_min
void Analyze(T &status, bool error, std::ostream &es)
summarizes and fill the status (wrong EC and BC progress error for some frames)
RawToDigiConverter(const edm::ParameterSet &conf)
const unsigned int testFootprint
flags for which tests to run
uint32_t chip() const
Definition: TotemRPDetId.h:53
const unsigned char verbosity
std::map< TotemSymbID, TotemVFATAnalysisMask > analysisMask
constexpr uint32_t mask
Definition: gpuClustering.h:26
unsigned short getOptoRxId() const
static std::string const input
Definition: EdmProvDump.cc:50
reference find_or_insert(det_id_type id)
Definition: DetSetVector.h:234
uint16_t trailingEdgeTime(const VFATFrame &frame, size_t ch_id)
get timing information for single trailing edge
VFATFrame::word getMultihit(const VFATFrame &frame)
flag stating whether the HPTDC channel encountered multiple hits
uint32_t getTrailingEdgeTime(const VFATFrame &frame)
get timing information for single trailing edge
const double EC_fraction
the minimal required (relative) occupancy of the most frequent counter value to be accepted ...
const bool printErrorSummary
const unsigned int testECMostFrequent
uint16_t newChannelId(const VFATFrame &frame, size_t ch_id)
retrieve the HW identifier for this channel, in firmware >2.1
VFATFrame::word getHptdcErrorFlag(const VFATFrame &frame)
retrieve the list of error/status flags for the HPTDC when the frame was recorded ...
the VFATFrameCollection interator
unsigned short getSubSystemId() const
the getters and setters below are deprecated
decltype(auto) emplace_back(Args &&... args)
Definition: DetSet.h:68
The mapping between FramePosition and VFATInfo.
uint32_t getThresholdVoltage(const VFATFrame &frame)
retrieve the threshold voltage for this channel
unsigned short getTOTFEDId() const
const unsigned int EC_min
the minimal required number of frames to determine the most frequent counter value ...
const bool olderTotemT2FileTest
bool fullMask
whether all channels of the VFAT shall be masked
unsigned short getGOHId() const
void setMissing(bool val=true)
const int verbosity
Hw Id mapping for Totem Timing (dynamical mapping in Sampic)
uint8_t statusMarker(const VFATFrame &frame)
retrieve the header status flags
Log< level::Info, false > LogInfo
TotemRPDetId planeId() const
Definition: TotemRPDetId.h:62
std::map< TotemFramePosition, unsigned int > unknownSummary
const bool printUnknownFrameSummary
static constexpr size_t num_channels_per_payload
multiplicity of channels combined into a single payload
const unsigned int testBCMostFrequent
unsigned short getIdxInFiber() const
void Fill(word counter, TotemFramePosition fr)
add new value to map, counter takes value of EC or BC number
HLT enums.
void printSummaries() const
Print error summaries.
std::set< unsigned char > maskedChannels
list of channels to be masked
std::map< TotemFramePosition, std::map< TotemVFATStatus, unsigned int > > errorSummary
error summaries
uint8_t channelMarker(const VFATFrame &frame, size_t ch_id)
retrieve this channel marker
Detector ID class for CTPPS Timing Diamond detectors. Bits [19:31] : Assigend in CTPPSDetId Calss Bit...
bool IsEnd()
returns whether the iterator points over the end of the collection
eventInfo
add run, event number and lumi section
Log< level::Warning, false > LogWarning
void run(const VFATFrameCollection &coll, const TotemDAQMapping &mapping, const TotemAnalysisMask &mask, edm::DetSetVector< TotemRPDigi > &digi, edm::DetSetVector< TotemVFATStatus > &status)
Creates RP digi.
Detector ID class for CTPPS Totem Timing detectors. Bits [19:31] : Assigend in CTPPSDetId Calss Bits ...