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 ****************************************************************************/
8 
10 
16 
21 
22 using namespace std;
23 using namespace edm;
24 
26  : verbosity(conf.getUntrackedParameter<unsigned int>("verbosity", 0)),
27  printErrorSummary(conf.getUntrackedParameter<unsigned int>("printErrorSummary", 1)),
28  printUnknownFrameSummary(conf.getUntrackedParameter<unsigned int>("printUnknownFrameSummary", 1)),
29 
30  testFootprint(conf.getParameter<unsigned int>("testFootprint")),
31  testCRC(conf.getParameter<unsigned int>("testCRC")),
32  testID(conf.getParameter<unsigned int>("testID")),
33  testECMostFrequent(conf.getParameter<unsigned int>("testECMostFrequent")),
34  testBCMostFrequent(conf.getParameter<unsigned int>("testBCMostFrequent")),
35 
36  EC_min(conf.getUntrackedParameter<unsigned int>("EC_min", 10)),
37  BC_min(conf.getUntrackedParameter<unsigned int>("BC_min", 10)),
38 
39  EC_fraction(conf.getUntrackedParameter<double>("EC_fraction", 0.6)),
40  BC_fraction(conf.getUntrackedParameter<double>("BC_fraction", 0.6)) {}
41 
43  const TotemDAQMapping &mapping,
44  map<TotemFramePosition, RawToDigiConverter::Record> &records) {
45  // EC and BC checks (wrt. the most frequent value), BC checks per subsystem
48 
49  // initialise structure merging vfat frame data with the mapping
50  for (auto &p : mapping.VFATMapping) {
51  TotemVFATStatus st;
52  st.setMissing(true);
53  records[p.first] = {&p.second, nullptr, st};
54  }
55 
56  // event error message buffer
57  stringstream ees;
58 
59  // associate data frames with records
60  for (VFATFrameCollection::Iterator fr(&input); !fr.IsEnd(); fr.Next()) {
61  // frame error message buffer
62  stringstream fes;
63 
64  bool problemsPresent = false;
65  bool stopProcessing = false;
66 
67  // skip data frames not listed in the DAQ mapping
68  auto records_it = records.find(fr.Position());
69  if (records_it == records.end()) {
70  unknownSummary[fr.Position()]++;
71  continue;
72  }
73 
74  // update record
75  Record &record = records_it->second;
76  record.frame = fr.Data();
77  record.status.setMissing(false);
78  record.status.setNumberOfClustersSpecified(record.frame->isNumberOfClustersPresent());
79  record.status.setNumberOfClusters(record.frame->getNumberOfClusters());
80 
81  // check footprint
82  if (testFootprint != tfNoTest && !record.frame->checkFootprint()) {
83  problemsPresent = true;
84 
85  if (verbosity > 0)
86  fes << " invalid footprint" << endl;
87 
88  if (testFootprint == tfErr) {
89  record.status.setFootprintError();
90  stopProcessing = true;
91  }
92  }
93 
94  // check CRC
95  if (testCRC != tfNoTest && !record.frame->checkCRC()) {
96  problemsPresent = true;
97 
98  if (verbosity > 0)
99  fes << " CRC failure" << endl;
100 
101  if (testCRC == tfErr) {
102  record.status.setCRCError();
103  stopProcessing = true;
104  }
105  }
106 
107  // check the id mismatch
108  if (testID != tfNoTest && record.frame->isIDPresent() &&
109  (record.frame->getChipID() & 0xFFF) != (record.info->hwID & 0xFFF)) {
110  if (verbosity > 0)
111  fes << " ID mismatch (data: 0x" << hex << record.frame->getChipID() << ", mapping: 0x" << record.info->hwID
112  << dec << ", symbId: " << record.info->symbolicID.symbolicID << ")" << endl;
113 
114  if (testID == tfErr) {
115  record.status.setIDMismatch();
116  stopProcessing = true;
117  }
118  }
119 
120  // if there were errors, put the information to ees buffer
121  if (verbosity > 0 && problemsPresent) {
122  string message = (stopProcessing) ? "(and will be dropped)" : "(but will be used though)";
123  if (verbosity > 2) {
124  ees << " Frame at " << fr.Position() << " seems corrupted " << message << ":" << endl;
125  ees << fes.rdbuf();
126  } else
127  ees << " Frame at " << fr.Position() << " seems corrupted " << message << "." << endl;
128  }
129 
130  // if there were serious errors, do not process this frame
131  if (stopProcessing)
132  continue;
133 
134  // fill EC and BC values to the statistics
135  if (fr.Data()->isECPresent())
136  ECChecker.Fill(fr.Data()->getEC(), fr.Position());
137 
138  if (fr.Data()->isBCPresent())
139  BCChecker.Fill(fr.Data()->getBC(), fr.Position());
140  }
141 
142  // analyze EC and BC statistics
144  ECChecker.Analyze(records, (testECMostFrequent == tfErr), ees);
145 
147  BCChecker.Analyze(records, (testBCMostFrequent == tfErr), ees);
148 
149  // add error message for missing frames
150  if (verbosity > 1) {
151  for (const auto &p : records) {
152  if (p.second.status.isMissing())
153  ees << "Frame for VFAT " << p.first << " is not present in the data." << endl;
154  }
155  }
156 
157  // print error message
158  if (verbosity > 0 && !ees.rdbuf()->str().empty()) {
159  if (verbosity > 1)
160  LogWarning("Totem") << "Error in RawToDigiConverter::runCommon > "
161  << "event contains the following problems:" << endl
162  << ees.rdbuf() << endl;
163  else
164  LogWarning("Totem") << "Error in RawToDigiConverter::runCommon > "
165  << "event contains problems." << endl;
166  }
167 
168  // increase error counters
169  if (printErrorSummary) {
170  for (const auto &it : records) {
171  if (!it.second.status.isOK()) {
172  auto &m = errorSummary[it.first];
173  m[it.second.status]++;
174  }
175  }
176  }
177 }
178 
180  const TotemDAQMapping &mapping,
181  const TotemAnalysisMask &analysisMask,
183  DetSetVector<TotemVFATStatus> &finalStatus) {
184  // structure merging vfat frame data with the mapping
185  map<TotemFramePosition, Record> records;
186 
187  // common processing - frame validation
188  runCommon(input, mapping, records);
189 
190  // second loop over data
191  for (auto &p : records) {
192  Record &record = p.second;
193 
194  // calculate ids
195  TotemRPDetId chipId(record.info->symbolicID.symbolicID);
196  uint8_t chipPosition = chipId.chip();
197  TotemRPDetId detId = chipId.planeId();
198 
199  // update chipPosition in status
200  record.status.setChipPosition(chipPosition);
201 
202  // produce digi only for good frames
203  if (record.status.isOK()) {
204  // find analysis mask (needs a default=no mask, if not in present the mapping)
206  anMa.fullMask = false;
207 
208  auto analysisIter = analysisMask.analysisMask.find(record.info->symbolicID);
209  if (analysisIter != analysisMask.analysisMask.end()) {
210  // if there is some information about masked channels - save it into conversionStatus
211  anMa = analysisIter->second;
212  if (anMa.fullMask)
213  record.status.setFullyMaskedOut();
214  else
215  record.status.setPartiallyMaskedOut();
216  }
217 
218  // create the digi
219  unsigned short offset = chipPosition * 128;
220  const vector<unsigned char> &activeChannels = record.frame->getActiveChannels();
221 
222  for (auto ch : activeChannels) {
223  // skip masked channels
224  if (!anMa.fullMask && anMa.maskedChannels.find(ch) == anMa.maskedChannels.end()) {
225  DetSet<TotemRPDigi> &digiDetSet = rpData.find_or_insert(detId);
226  digiDetSet.emplace_back(offset + ch);
227  }
228  }
229  }
230 
231  // save status
232  DetSet<TotemVFATStatus> &statusDetSet = finalStatus.find_or_insert(detId);
233  statusDetSet.push_back(record.status);
234  }
235 }
236 
238  const TotemDAQMapping &mapping,
239  const TotemAnalysisMask &mask,
242  // structure merging vfat frame data with the mapping
243  map<TotemFramePosition, Record> records;
244 
245  // common processing - frame validation
246  runCommon(coll, mapping, records);
247 
248  // second loop over data
249  for (auto &p : records) {
250  Record &record = p.second;
251 
252  // calculate ids
253  CTPPSDiamondDetId detId(record.info->symbolicID.symbolicID);
254 
255  if (record.status.isOK()) {
256  // update Event Counter in status
257  record.status.setEC(record.frame->getEC() & 0xFF);
258 
259  // create the digi
260  DetSet<CTPPSDiamondDigi> &digiDetSet = digi.find_or_insert(detId);
266  }
267 
268  // save status
269  DetSet<TotemVFATStatus> &statusDetSet = status.find_or_insert(detId);
270  statusDetSet.push_back(record.status);
271  }
272 }
273 
275  const TotemDAQMapping &mapping,
276  const TotemAnalysisMask &mask,
279  // structure merging vfat frame data with the mapping
280  map<TotemFramePosition, Record> records;
281 
282  // common processing - frame validation
283  runCommon(coll, mapping, records);
284 
285  // second loop over data
286  for (auto &p : records) {
287  Record &record = p.second;
288  if (!record.status.isOK())
289  continue;
290 
291  const TotemFramePosition *framepos = &p.first;
292 
293  if (((framepos->getIdxInFiber() % 2) == 0) && (framepos->getIdxInFiber() < 14)) {
294  //corresponding channel data are always in the neighbouring idx in fiber
295 
296  TotemFramePosition frameposdata(framepos->getSubSystemId(),
297  framepos->getTOTFEDId(),
298  framepos->getOptoRxId(),
299  framepos->getGOHId(),
300  (framepos->getIdxInFiber() + 1));
301  TotemFramePosition frameposEvtInfo(
302  framepos->getSubSystemId(), framepos->getTOTFEDId(), framepos->getOptoRxId(), framepos->getGOHId(), 0xe);
303 
304  auto channelwaveformPtr = records.find(frameposdata);
305  auto eventInfoPtr = records.find(frameposEvtInfo);
306 
307  if (channelwaveformPtr != records.end() && eventInfoPtr != records.end()) {
308  Record &channelwaveform = records[frameposdata];
309  Record &eventInfo = records[frameposEvtInfo];
310 
311  // Extract all the waveform information from the raw data
312  TotemSampicFrame totemSampicFrame((const uint8_t *)record.frame->getData(),
313  (const uint8_t *)channelwaveform.frame->getData(),
314  (const uint8_t *)eventInfo.frame->getData());
315 
316  if (totemSampicFrame.valid()) {
317  // create the digi
318  TotemTimingEventInfo eventInfoTmp(totemSampicFrame.getEventHardwareId(),
319  totemSampicFrame.getL1ATimestamp(),
320  totemSampicFrame.getBunchNumber(),
321  totemSampicFrame.getOrbitNumber(),
322  totemSampicFrame.getEventNumber(),
323  totemSampicFrame.getChannelMap(),
324  totemSampicFrame.getL1ALatency(),
325  totemSampicFrame.getNumberOfSentSamples(),
326  totemSampicFrame.getOffsetOfSamples(),
327  totemSampicFrame.getPLLInfo());
328  TotemTimingDigi digiTmp(totemSampicFrame.getHardwareId(),
329  totemSampicFrame.getFPGATimestamp(),
330  totemSampicFrame.getTimestampA(),
331  totemSampicFrame.getTimestampB(),
332  totemSampicFrame.getCellInfo(),
333  totemSampicFrame.getSamples(),
334  eventInfoTmp);
335  // calculate ids
336  TotemTimingDetId detId(record.info->symbolicID.symbolicID);
338  mapping.getTimingChannel(totemSampicFrame.getHardwareId());
339  // for FW Version > 0 plane and channel are encoded in the dataframe
340  if (totemSampicFrame.getFWVersion() == 0) // Mapping not present in HW, read from SW for FW versions == 0
341  {
342  if (SWpair.plane == -1 || SWpair.channel == -1) {
343  if (verbosity > 0)
344  LogWarning("Totem") << "Error in RawToDigiConverter::TotemTiming > "
345  << "HwId not recognized! hwId: " << std::hex
346  << (unsigned int)totemSampicFrame.getHardwareId() << endl;
347  } else {
348  detId.setPlane(SWpair.plane % 4);
349  detId.setChannel(SWpair.channel);
350  }
351  } else // Mapping read from HW, checked by SW
352  {
353  const int HWplane = totemSampicFrame.getDetPlane() % 16;
354  const int HWchannel = totemSampicFrame.getDetChannel() % 16;
355 
356  if (SWpair.plane == -1 || SWpair.channel == -1) {
357  if (verbosity > 0)
358  LogWarning("Totem") << "Warning in RawToDigiConverter::TotemTiming > "
359  << "HwId not recognized! hwId: " << std::hex
360  << (unsigned int)totemSampicFrame.getHardwareId()
361  << "\tUsing plane and ch from HW without check!" << endl;
362  } else {
363  if (verbosity > 0 && (SWpair.plane != HWplane || SWpair.channel != HWchannel))
364  LogWarning("Totem") << "Warning in RawToDigiConverter::TotemTiming > "
365  << "Hw mapping different from SW mapping. hwId: " << std::hex
366  << (unsigned int)totemSampicFrame.getHardwareId() << "HW: " << std::dec << HWplane
367  << ":" << HWchannel << "\tSW " << SWpair.plane << ":" << SWpair.channel
368  << "\tUsing plane and ch from HW!" << endl;
369  }
370  detId.setPlane(HWplane % 4);
371  detId.setChannel(HWchannel);
372  }
373 
374  DetSet<TotemTimingDigi> &digiDetSet = digi.find_or_insert(detId);
375  digiDetSet.push_back(digiTmp);
376  }
377  }
378  }
379  }
380 }
381 
383  const TotemDAQMapping &mapping,
384  const TotemAnalysisMask &mask,
387  // structure merging vfat frame data with the mapping
388  map<TotemFramePosition, Record> records;
389 
390  // common processing - frame validation
391  runCommon(coll, mapping, records);
392 
393  // second loop over data
394  for (auto &p : records) {
395  Record &record = p.second;
396 
397  // calculate ids
398  TotemT2DetId detId(record.info->symbolicID.symbolicID);
399 
400  if (record.status.isOK()) {
401  // update Event Counter in status
402  record.status.setEC(record.frame->getEC() & 0xFF);
403 
404  // create the digi
406  .emplace_back(totem::nt2::vfat::geoId(*record.frame),
411  }
412 
413  // save status
414  DetSet<TotemVFATStatus> &statusDetSet = status.find_or_insert(detId);
415  statusDetSet.push_back(record.status);
416  }
417 }
418 
420  // print error summary
421  if (printErrorSummary) {
422  if (!errorSummary.empty()) {
423  stringstream ees;
424  for (const auto &vit : errorSummary) {
425  ees << vit.first << endl;
426 
427  for (const auto &it : vit.second)
428  ees << " " << it.first << " : " << it.second << endl;
429  }
430 
431  LogWarning("Totem") << "RawToDigiConverter: error summary (error signature : number of such events)\n"
432  << endl
433  << ees.rdbuf();
434  } else {
435  LogInfo("Totem") << "RawToDigiConverter: no errors to be reported.";
436  }
437  }
438 
439  // print summary of unknown frames (found in data but not in the mapping)
441  if (!unknownSummary.empty()) {
442  stringstream ees;
443  for (const auto &it : unknownSummary)
444  ees << " " << it.first << " : " << it.second << endl;
445 
446  LogWarning("Totem")
447  << "RawToDigiConverter: frames found in data, but not in the mapping (frame position : number of events)\n"
448  << endl
449  << ees.rdbuf();
450  } else {
451  LogInfo("Totem") << "RawToDigiConverter: no unknown frames to be reported.";
452  }
453  }
454 }
uint8_t geoId(const VFATFrame &frame)
retrieve the GEO information for this channel
Detector ID class for TOTEM Si strip detectors.
Definition: TotemRPDetId.h:30
uint32_t getLeadingEdgeTime(const VFATFrame &frame)
get timing information for single leading edge
Contains data on masked channels of a VFAT.
void push_back(const T &t)
Definition: DetSet.h:66
unsigned int testECMostFrequent
Channel-mask mapping.
unsigned int printErrorSummary
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
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)
uint32_t chip() const
Definition: TotemRPDetId.h:53
unsigned int testFootprint
flags for which tests to run
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
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
uint8_t channelMarker(const VFATFrame &frame)
retrieve this channel marker
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 int printUnknownFrameSummary
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
uint16_t trailingEdgeTime(const VFATFrame &frame)
get timing information for single trailing edge
unsigned short getTOTFEDId() const
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)
Log< level::Info, false > LogInfo
TotemRPDetId planeId() const
Definition: TotemRPDetId.h:62
unsigned char verbosity
std::map< TotemFramePosition, unsigned int > unknownSummary
uint8_t channelId(const VFATFrame &frame)
retrieve this channel identifier
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
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
double EC_fraction
the minimal required (relative) occupancy of the most frequent counter value to be accepted ...
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.
unsigned int EC_min
the minimal required number of frames to determine the most frequent counter value ...
uint16_t leadingEdgeTime(const VFATFrame &frame)
get timing information for single leading edge
Detector ID class for CTPPS Totem Timing detectors. Bits [19:31] : Assigend in CTPPSDetId Calss Bits ...