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