CMS 3D CMS Logo

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