CMS 3D CMS Logo

ZdcUnpacker.cc
Go to the documentation of this file.
12 #include <iostream>
14 #include <map>
15 
16 namespace ZdcUnpacker_impl {
17  template <class DigiClass>
18  const unsigned short* unpack_compact(const unsigned short* startPoint,
19  const unsigned short* limit,
20  DigiClass& digi,
21  int presamples,
22  const HcalElectronicsId& eid,
23  int startSample,
24  int endSample,
25  int expectedTime,
26  const HcalHTRData& hhd) {
27  // set parameters
28  digi.setPresamples(presamples);
29  digi.setReadoutIds(eid);
30  int flavor, error_flags, capid0, channelid;
31 
32  HcalHTRData::unpack_per_channel_header(*startPoint, flavor, error_flags, capid0, channelid);
33  bool isCapRotating = !(error_flags & 0x1);
34  bool fiberErr = (error_flags & 0x2);
35  bool dataValid = !(error_flags & 0x2);
36  int fiberchan = channelid & 0x3;
37  int fiber = ((channelid >> 2) & 0x7) + 1;
38 
39  uint32_t zsmask = hhd.zsBunchMask() >> startSample;
40  digi.setZSInfo(hhd.isUnsuppressed(), hhd.wasMarkAndPassZS(fiber, fiberchan), zsmask);
41 
42  if (expectedTime >= 0 && !hhd.isUnsuppressed()) {
43  digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber) - expectedTime);
44  }
45 
46  // what is my sample number?
47  int ncurr = 0, ntaken = 0;
48  const unsigned short* qie_work = startPoint;
49  // we branch here between normal (flavor=5) and error mode (flavor=6)
50  if (flavor == 5) {
51  for (qie_work++; qie_work != limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
52  int capidn = (isCapRotating) ? ((capid0 + ncurr) % 4) : (capid0);
53  int capidn1 = (isCapRotating) ? ((capid0 + ncurr + 1) % 4) : (capid0);
54  // two samples in one...
55  HcalQIESample s0((*qie_work) & 0x7F, capidn, fiber, fiberchan, dataValid, fiberErr);
56  HcalQIESample s1(((*qie_work) >> 8) & 0x7F, capidn1, fiber, fiberchan, dataValid, fiberErr);
57 
58  if (ncurr >= startSample && ncurr <= endSample) {
59  digi.setSample(ntaken, s0);
60  ++ntaken;
61  }
62  ncurr++;
63  if (ncurr >= startSample && ncurr <= endSample) {
64  digi.setSample(ntaken, s1);
65  ++ntaken;
66  }
67  ncurr++;
68  }
69  digi.setSize(ntaken);
70  } else if (flavor == 6) {
71  for (qie_work++; qie_work != limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
72  if (ncurr >= startSample && ncurr <= endSample) {
73  HcalQIESample sample((*qie_work) & 0x7F,
74  ((*qie_work) >> 8) & 0x3,
75  fiber,
76  fiberchan,
77  ((*qie_work) >> 10) & 0x1,
78  ((*qie_work) >> 11) & 0x1);
79  digi.setSample(ntaken, sample);
80  ++ntaken;
81  }
82  ncurr++;
83  }
84  digi.setSize(ntaken);
85  } else {
86  edm::LogWarning("Bad Data") << "Invalid flavor " << flavor;
87  qie_work = limit;
88  }
89  return qie_work;
90  }
91 
92 } // namespace ZdcUnpacker_impl
93 
94 ZdcUnpacker::ZdcUnpacker(int sourceIdOffset, int beg, int end)
95  : sourceIdOffset_(sourceIdOffset), expectedOrbitMessageTime_(-1) {
96  if (beg >= 0 && beg <= ZDCDataFrame::MAXSAMPLES - 1) {
97  startSample_ = beg;
98  } else {
99  startSample_ = 0;
100  }
101  if (end >= 0 && end <= ZDCDataFrame::MAXSAMPLES - 1 && end >= beg) {
102  endSample_ = end;
103  } else {
105  }
106 }
107 
109  const CastorElectronicsMap& emap,
110  CastorRawCollections& colls,
112  bool silent) {
113  if (raw.size() < 16) {
114  if (!silent)
115  edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
116  return;
117  }
118 
119  // get the DCC header
120  const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
121  int dccid = dccHeader->getSourceId() - sourceIdOffset_;
122 
123  // walk through the HTR data...
124  HcalHTRData htr;
125  const unsigned short *daq_first, *daq_last, *tp_first, *tp_last;
126  std::map<HcalElectronicsId, DetId> myEMap;
127 
129  //PZDC
131  eid.setHTR(18, 8, 1);
132  myEMap[eid] = DetId(0x54000051); //PZDC EM1
133 
134  eid = HcalElectronicsId(1, 1, 0, 3);
135  eid.setHTR(18, 8, 1);
136  myEMap[eid] = DetId(0x54000052); //PZDC EM2
137 
138  eid = HcalElectronicsId(2, 1, 0, 3);
139  eid.setHTR(18, 8, 1);
140  myEMap[eid] = DetId(0x54000053); //PZDC EM3
141 
142  eid = HcalElectronicsId(0, 2, 0, 3);
143  eid.setHTR(18, 8, 1);
144  myEMap[eid] = DetId(0x54000061); //PZDC HAD1
145 
146  eid = HcalElectronicsId(1, 2, 0, 3);
147  eid.setHTR(18, 8, 1);
148  myEMap[eid] = DetId(0x54000054); //PZDC EM4
149 
150  eid = HcalElectronicsId(2, 2, 0, 3);
151  eid.setHTR(18, 8, 1);
152  myEMap[eid] = DetId(0x54000055); //PZDC EM5
153 
154  eid = HcalElectronicsId(0, 3, 0, 3);
155  eid.setHTR(18, 8, 1);
156  myEMap[eid] = DetId(0x54000062); //PZDC HAD2
157 
158  eid = HcalElectronicsId(1, 3, 0, 3);
159  eid.setHTR(18, 8, 1);
160  myEMap[eid] = DetId(0x54000063); //PZDC HAD3
161 
162  eid = HcalElectronicsId(2, 3, 0, 3);
163  eid.setHTR(18, 8, 1);
164  myEMap[eid] = DetId(0x54000064); //PZDC HAD4
165 
166  //NZDC
167  eid = HcalElectronicsId(0, 1, 1, 3);
168  eid.setHTR(18, 8, 0);
169  myEMap[eid] = DetId(0x54000011); //NZDC EM1
170 
171  eid = HcalElectronicsId(1, 1, 1, 3);
172  eid.setHTR(18, 8, 0);
173  myEMap[eid] = DetId(0x54000012); //NZDC EM2
174 
175  eid = HcalElectronicsId(2, 1, 1, 3);
176  eid.setHTR(18, 8, 0);
177  myEMap[eid] = DetId(0x54000013); //NZDC EM3
178 
179  eid = HcalElectronicsId(0, 2, 1, 3);
180  eid.setHTR(18, 8, 0);
181  myEMap[eid] = DetId(0x54000015); //NZDC EM5
182 
183  eid = HcalElectronicsId(1, 2, 1, 3);
184  eid.setHTR(18, 8, 0);
185  myEMap[eid] = DetId(0x54000021); //NZDC HAD1
186 
187  eid = HcalElectronicsId(2, 2, 1, 3);
188  eid.setHTR(18, 8, 0);
189  myEMap[eid] = DetId(0x54000014); //NZDC EM4
190 
191  eid = HcalElectronicsId(0, 3, 1, 3);
192  eid.setHTR(18, 8, 0);
193  myEMap[eid] = DetId(0x54000022); //NZDC HAD2
194 
195  eid = HcalElectronicsId(1, 3, 1, 3);
196  eid.setHTR(18, 8, 0);
197  myEMap[eid] = DetId(0x54000023); //NZDC HAD3
198 
199  eid = HcalElectronicsId(2, 3, 1, 3);
200  eid.setHTR(18, 8, 0);
201  myEMap[eid] = DetId(0x54000024); //NZDC HAD4
202 
203  for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
204  if (!dccHeader->getSpigotPresent(spigot))
205  continue;
206  int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
207  if (retval != 0) {
208  if (retval == -1) {
209  if (!silent)
210  edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot
211  << " of DCC with source id " << dccHeader->getSourceId();
212  report.countSpigotFormatError();
213  }
214  continue;
215  }
216  // check
217  if (dccHeader->getSpigotCRCError(spigot)) {
218  if (!silent)
219  edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot
220  << " of DCC with source id " << dccHeader->getSourceId();
221  report.countSpigotFormatError();
222  continue;
223  }
224  if (!htr.check()) {
225  if (!silent)
226  edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
227  << dccHeader->getSourceId();
228  report.countSpigotFormatError();
229  continue;
230  }
231  if (htr.isHistogramEvent()) {
232  if (!silent)
233  edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot
234  << " of DCC with source id " << dccHeader->getSourceId();
235  continue;
236  }
237  if ((htr.getFirmwareFlavor() & 0xE0) == 0x80) { // some kind of TTP data
238  if (colls.ttp != nullptr) {
239  HcalTTPUnpacker ttpUnpack;
240  colls.ttp->push_back(HcalTTPDigi());
241  ttpUnpack.unpack(htr, colls.ttp->back());
242  } else {
243  LogDebug("ZdcUnpackerHcalTechTrigProcessor")
244  << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
245  << " which is from the TechTrigProcessor (use separate unpacker!)";
246  }
247  continue;
248  }
249  if (htr.getFirmwareFlavor() >= 0x80) {
250  if (!silent)
251  edm::LogWarning("ZdcUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id "
252  << dccHeader->getSourceId() << " which is of unknown flavor "
253  << htr.getFirmwareFlavor();
254  continue;
255  }
256  // calculate "real" number of presamples
257  int nps = htr.getNPS() - startSample_;
258 
259  // get pointers
260  htr.dataPointers(&daq_first, &daq_last, &tp_first, &tp_last);
261  unsigned int smid = htr.getSubmodule();
262  int htr_tb = smid & 0x1;
263  int htr_slot = (smid >> 1) & 0x1F;
264  int htr_cr = (smid >> 6) & 0x1F;
265 
266  const unsigned short* ptr_header = daq_first;
267  const unsigned short* ptr_end = daq_last + 1;
268  int flavor, error_flags, capid0, channelid;
269 
270  while (ptr_header != ptr_end) {
271  if (*ptr_header == 0xFFFF) { // impossible filler word
272  ptr_header++;
273  continue;
274  }
275  // unpack the header word
276  bool isheader = HcalHTRData::unpack_per_channel_header(*ptr_header, flavor, error_flags, capid0, channelid);
277  if (!isheader) {
278  ptr_header++;
279  continue;
280  }
281  int fiberchan = channelid & 0x3;
282  int fiber = ((channelid >> 2) & 0x7) + 1;
283 
284  // lookup the right channel
285  HcalElectronicsId eid(fiberchan, fiber, spigot, dccid);
286  eid.setHTR(htr_cr, htr_slot, htr_tb);
287  auto it = myEMap.find(eid);
288  DetId did;
289  if (it != myEMap.end()) {
290  did = it->second;
291  }
292 
293  if (!did.null()) {
294  if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
295  colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
296  ptr_header = ZdcUnpacker_impl::unpack_compact<ZDCDataFrame>(ptr_header,
297  ptr_end,
298  colls.zdcCont->back(),
299  nps,
300  eid,
301  startSample_,
302  endSample_,
304  htr);
305  }
306  } else {
307  report.countUnmappedDigi(eid);
308  for (ptr_header++; ptr_header != ptr_end && !HcalHTRData::is_channel_header(*ptr_header); ptr_header++)
309  ;
310  }
311  }
312  } //end of loop over spigots
313 }
bool isHistogramEvent() const
Is this event a histogram event? (do not call standard unpack in this case!!!!!)
Definition: HcalHTRData.cc:409
bool wasMarkAndPassZS(int fiber, int fiberchan) const
Was this channel passed as part of Mark&Pass ZS?
Definition: HcalHTRData.cc:379
int getSpigotData(int nspigot, HcalHTRData &decodeTool, int validSize) const
int getNPS() const
Get the number of presamples in daq data.
Definition: HcalHTRData.cc:426
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
int startSample_
first sample from fed raw data to copy
Definition: ZdcUnpacker.h:36
uint32_t zsBunchMask() const
ZS Bunch Mask (if available)
Definition: HcalHTRData.cc:400
static bool unpack_per_channel_header(unsigned short, int &flav, int &error_flags, int &capid0, int &channelid)
Unpack a per-channel header word (compact format)
Definition: HcalHTRData.cc:455
const unsigned short * unpack_compact(const unsigned short *startPoint, const unsigned short *limit, DigiClass &digi, int presamples, const HcalElectronicsId &eid, int startSample, int endSample, int expectedTime, const HcalHTRData &hhd)
Definition: ZdcUnpacker.cc:18
static const int MAXSAMPLES
Definition: ZDCDataFrame.h:54
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46
std::vector< ZDCDataFrame > * zdcCont
int getFirmwareFlavor() const
Get the HTR firmware flavor.
Definition: HcalHTRData.cc:433
void dataPointers(const unsigned short **daq_first, const unsigned short **daq_last, const unsigned short **tp_first, const unsigned short **tp_last) const
Obtain the starting and ending pointers for external unpacking of the data.
Definition: HcalHTRData.cc:161
constexpr bool null() const
is this a null id ?
Definition: DetId.h:59
static bool is_channel_header(unsigned short value)
check top bit to see if this is a compact format channel header word
Definition: HcalHTRData.h:92
int expectedOrbitMessageTime_
Expected orbit bunch time (needed to evaluate time differences)
Definition: ZdcUnpacker.h:38
int getSourceId() const
Definition: HcalDCCHeader.h:33
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
int sourceIdOffset_
number to subtract from the source id to get the dcc id
Definition: ZdcUnpacker.h:35
void unpack(const FEDRawData &raw, const CastorElectronicsMap &emap, CastorRawCollections &conts, HcalUnpackerReport &report, bool silent=false)
For histograms, no begin and end.
Definition: ZdcUnpacker.cc:108
Definition: DetId.h:17
static const int SubdetectorId
Definition: HcalZDCDetId.h:25
bool getSpigotCRCError(unsigned int nspigot) const
Read the "CRC-Mismatch" bit for this spigot.
bool unpack(const HcalHTRData &data, HcalTTPDigi &digi)
int endSample_
last sample from fed raw data to copy (if present)
Definition: ZdcUnpacker.h:37
static const int SPIGOT_COUNT
Definition: HcalDCCHeader.h:20
bool getSpigotPresent(unsigned int nspigot) const
Read the "PRESENT" bit for this spigot.
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
unsigned int getFibOrbMsgBCN(int fiber) const
Get the BCN of the Fiber Orbit Messages.
Definition: HcalHTRData.h:180
unsigned int getSubmodule() const
Get the HTR submodule number.
Definition: HcalHTRData.cc:355
Log< level::Warning, false > LogWarning
Readout chain identification for Hcal.
bool check() const
Check for a good event Requires a minimum length, matching wordcount and length, not an empty event...
Definition: HcalHTRData.cc:63
ZdcUnpacker(int sourceIdOffset, int beg, int end)
for normal data
Definition: ZdcUnpacker.cc:94
#define LogDebug(id)
std::vector< HcalTTPDigi > * ttp
bool isUnsuppressed() const
Is this event an unsuppresed event?
Definition: HcalHTRData.cc:378