CMS 3D CMS Logo

CastorUnpacker.cc
Go to the documentation of this file.
9 #include <iostream>
11 
13  template <class DigiClass>
14  const HcalQIESample* unpack(const HcalQIESample* startPoint,
15  const HcalQIESample* limit,
16  DigiClass& digi,
17  int presamples,
18  const CastorElectronicsId& eid,
19  int startSample,
20  int endSample,
21  int expectedTime,
22  const HcalHTRData& hhd) {
23  // set parameters
24  digi.setPresamples(presamples);
25  int fiber = startPoint->fiber();
26  int fiberchan = startPoint->fiberChan();
27  uint32_t zsmask = hhd.zsBunchMask() >> startSample;
28  digi.setZSInfo(hhd.isUnsuppressed(), hhd.wasMarkAndPassZS(fiber, fiberchan), zsmask);
29 
30  // digi.setReadoutIds(eid);
31  // setReadoutIds is missing in CastorDataFrame class digi.setReadoutIds(eid);
32  if (expectedTime >= 0 && !hhd.isUnsuppressed()) {
33  // std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << " fiber="<<fiber<< std::endl;
34  digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber) - expectedTime);
35  }
36  // what is my sample number?
37  int myFiberChan = startPoint->fiberAndChan();
38  int ncurr = 0, ntaken = 0;
39  const HcalQIESample* qie_work = startPoint;
40  while (qie_work != limit && qie_work->fiberAndChan() == myFiberChan) {
41  if (ncurr >= startSample && ncurr <= endSample) {
42  digi.setSample(ntaken, *qie_work);
43  ++ntaken;
44  }
45  ncurr++;
46  qie_work++;
47  }
48  digi.setSize(ntaken);
49  return qie_work;
50  }
51 } // namespace CastorUnpacker_impl
52 
53 namespace {
54  inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) { return (s.raw() & 0x200) != 0; }
55 } // namespace
56 
57 CastorUnpacker::CastorUnpacker(int sourceIdOffset, int beg, int end)
58  : sourceIdOffset_(sourceIdOffset), expectedOrbitMessageTime_(-1) {
59  if (beg >= 0 && beg <= CastorDataFrame::MAXSAMPLES - 1) {
60  startSample_ = beg;
61  } else {
62  startSample_ = 0;
63  }
64  if (end >= 0 && end <= CastorDataFrame::MAXSAMPLES - 1 && end >= beg) {
65  endSample_ = end;
66  } else {
68  }
69 }
70 
71 static int slb(const HcalTriggerPrimitiveSample& theSample) { return ((theSample.raw() >> 13) & 0x7); }
72 static int slbChan(const HcalTriggerPrimitiveSample& theSample) { return (theSample.raw() >> 11) & 0x3; }
73 static int slbAndChan(const HcalTriggerPrimitiveSample& theSample) { return (theSample.raw() >> 11) & 0x1F; }
74 
76  const CastorElectronicsMap& emap,
77  CastorRawCollections& colls,
79  bool silent) {
80  if (raw.size() < 16) {
81  if (!silent)
82  edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
83  return;
84  }
85 
86  // get the DCC header
87  const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
88  int dccid = dccHeader->getSourceId() - sourceIdOffset_;
89 
90  // check the summary status
91 
92  // walk through the HTR data...
93  HcalHTRData htr;
94  const unsigned short *daq_first, *daq_last, *tp_first, *tp_last;
95  const HcalQIESample *qie_begin, *qie_end, *qie_work;
96  const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work;
97  for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
98  if (!dccHeader->getSpigotPresent(spigot))
99  continue;
100 
101  int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
102  if (retval != 0) {
103  if (retval == -1) {
104  if (!silent)
105  edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot
106  << " of DCC with source id " << dccHeader->getSourceId();
107  report.countSpigotFormatError();
108  }
109  continue;
110  }
111  // check
112  if (dccHeader->getSpigotCRCError(spigot)) {
113  if (!silent)
114  edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot
115  << " of DCC with source id " << dccHeader->getSourceId();
116  report.countSpigotFormatError();
117  continue;
118  }
119  if (!htr.check()) {
120  if (!silent)
121  edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
122  << dccHeader->getSourceId();
123  report.countSpigotFormatError();
124  continue;
125  }
126  if (htr.isHistogramEvent()) {
127  if (!silent)
128  edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot
129  << " of DCC with source id " << dccHeader->getSourceId();
130  continue;
131  }
132  if ((htr.getFirmwareFlavor() & 0xE0) == 0x80) { // some kind of TTP data
133  if (colls.ttp != nullptr) {
134  HcalTTPUnpacker ttpUnpack;
135  colls.ttp->push_back(HcalTTPDigi());
136  ttpUnpack.unpack(htr, colls.ttp->back());
137  } else {
138  LogDebug("CastorUnpackerHcalTechTrigProcessor")
139  << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
140  << " which is from the TechTrigProcessor (use separate unpacker!)";
141  }
142  continue;
143  }
144  if (htr.getFirmwareFlavor() >= 0x80) {
145  if (!silent)
146  edm::LogWarning("CastorUnpacker")
147  << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
148  << " which is of unknown flavor " << htr.getFirmwareFlavor();
149  continue;
150  }
151  // calculate "real" number of presamples
152  int nps = htr.getNPS() - startSample_;
153 
154  // get pointers
155  htr.dataPointers(&daq_first, &daq_last, &tp_first, &tp_last);
156  unsigned int smid = htr.getSubmodule();
157  int htr_tb = smid & 0x1;
158  int htr_slot = (smid >> 1) & 0x1F;
159  int htr_cr = (smid >> 6) & 0x1F;
160 
161  tp_begin = (const HcalTriggerPrimitiveSample*)tp_first;
162  tp_end = (const HcalTriggerPrimitiveSample*)(tp_last + 1); // one beyond last..
163 
165  int currFiberChan = 0x3F; // invalid fiber+channel...
166  int ncurr = 0;
167  bool valid = false;
169  bool tpgSOIbitInUse = htr.getFormatVersion() >= 3; // version 3 and later
170  // bool isHOtpg=htr.getFormatVersion()>=3 && htr.getFirmwareFlavor()==0; // HO is flavor zero
171  /*
172  Unpack the trigger primitives
173  */
174  // lookup the right channel
175  bool dotp = true;
176  CastorElectronicsId eid(0, 1, spigot, dccid);
177  eid.setHTR(htr_cr, htr_slot, htr_tb);
178  DetId did = emap.lookup(eid);
179  if (did.null())
180  dotp = false;
181  HcalCastorDetId id1(did);
182  HcalCastorDetId id((id1.zside() == 0), id1.sector(), 1);
183  if (id1.module() > 12)
184  dotp = false;
185  if (dotp) {
186  // std::cout << " tp_first="<< tp_first << " tp_last="<< tp_last<< " tb="<<htr_tb<<" slot="<<htr_slot<<" crate="<<htr_cr<<" dccid="<< dccid<< std::endl;
187  // regular TPs (not HO)
188  for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
189  // std::cout << "raw=0x"<<std::hex<< tp_work->raw()<<std::dec <<std::endl;
190  if (tp_work->raw() == 0xFFFF)
191  continue; // filler word
192  if (slbAndChan(*tp_work) != currFiberChan) { // start new set
193  currFiberChan = slbAndChan(*tp_work);
194 
195  // std::cout<< " NEW SET "<<std::endl;
196  //HcalElectronicsId eid(tp_work->slbChan(),tp_work->slb(),spigot,dccid,htr_cr,htr_slot,htr_tb);
197  //DetId did=emap.lookupTrigger(eid);
198  //if (did.null()) {
199  //report.countUnmappedTPDigi(eid);
200  //if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
201  //if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
202  //unknownIdsTrig_.insert(eid);
203  //}
204  //valid=false;
205  //continue;
206  //} else if (did==HcalTrigTowerDetId::Undefined ||
207  //(did.det()==DetId::Hcal && did.subdetId()==0)) {
209  //valid=false;
210  //continue;
211  //}
212 
213  colls.tpCont->push_back(CastorTriggerPrimitiveDigi(id));
214  // set the various bits
215  if (!tpgSOIbitInUse)
216  colls.tpCont->back().setPresamples(nps);
217  colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),
218  htr.wasMarkAndPassZSTP(slb(*tp_work), slbChan(*tp_work)));
219 
220  // no hits recorded for current
221  ncurr = 0;
222  valid = true;
223  }
224  // add the word (if within settings or recent firmware [recent firmware ignores startSample/endSample])
225  if (valid && ((tpgSOIbitInUse && ncurr < 10) || (ncurr >= startSample_ && ncurr <= endSample_))) {
226  colls.tpCont->back().setSample(colls.tpCont->back().size(), *tp_work);
227  colls.tpCont->back().setSize(colls.tpCont->back().size() + 1);
228  }
229  // set presamples,if SOI
230  if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
231  colls.tpCont->back().setPresamples(ncurr);
232  }
233  ncurr++;
234  }
235  }
236 
238  qie_begin = (const HcalQIESample*)daq_first;
239  qie_end = (const HcalQIESample*)(daq_last + 1); // one beyond last..
240 
242 
243  for (qie_work = qie_begin; qie_work != qie_end;) {
244  if (qie_work->raw() == 0xFFFF) {
245  qie_work++;
246  continue; // filler word
247  }
248 
249  // lookup the right channel
250  CastorElectronicsId eid(qie_work->fiberChan(), qie_work->fiber(), spigot, dccid);
251  eid.setHTR(htr_cr, htr_slot, htr_tb);
252  DetId did = emap.lookup(eid);
253 
254  if (!did.null()) {
255  colls.castorCont->push_back(CastorDataFrame(HcalCastorDetId(did)));
256  qie_work = CastorUnpacker_impl::unpack<CastorDataFrame>(qie_work,
257  qie_end,
258  colls.castorCont->back(),
259  nps,
260  eid,
261  startSample_,
262  endSample_,
264  htr);
265  } else {
266  report.countUnmappedDigi();
267  if (unknownIds_.find(eid) == unknownIds_.end()) {
268  if (!silent)
269  edm::LogWarning("CASTOR") << "CastorUnpacker: No match found for electronics id :" << eid;
270  unknownIds_.insert(eid);
271  }
272  for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
273  qie_work++)
274  ;
275  }
276  }
277  }
278 }
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
static int slb(const HcalTriggerPrimitiveSample &theSample)
constexpr int fiberChan() const
get the fiber channel number
Definition: HcalQIESample.h:55
constexpr int fiberAndChan() const
get the id channel
Definition: HcalQIESample.h:57
static bool isTPGSOI(const HcalTriggerPrimitiveSample &s)
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
static int slbChan(const HcalTriggerPrimitiveSample &theSample)
uint32_t zsBunchMask() const
ZS Bunch Mask (if available)
Definition: HcalHTRData.cc:400
int getFirmwareFlavor() const
Get the HTR firmware flavor.
Definition: HcalHTRData.cc:433
std::set< CastorElectronicsId > unknownIds_
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
void unpack(const FEDRawData &raw, const CastorElectronicsMap &emap, CastorRawCollections &conts, HcalUnpackerReport &report, bool silent=false)
For histograms, no begin and end.
constexpr bool null() const
is this a null id ?
Definition: DetId.h:59
uint16_t raw() const
get the raw word
CastorUnpacker(int sourceIdOffset, int beg, int end)
for normal data
static int slbAndChan(const HcalTriggerPrimitiveSample &theSample)
int getSourceId() const
Definition: HcalDCCHeader.h:32
int getFormatVersion() const
Get the version number of this event.
Definition: HcalHTRData.h:36
bool wasMarkAndPassZSTP(int slb, int slbchan) const
Was this channel passed as part of Mark&Pass ZS?
Definition: HcalHTRData.cc:389
std::vector< CastorDataFrame > * castorCont
std::vector< CastorTriggerPrimitiveDigi > * tpCont
Definition: DetId.h:17
int sourceIdOffset_
number to subtract from the source id to get the dcc id
constexpr uint16_t raw() const
get the raw word
Definition: HcalQIESample.h:41
int expectedOrbitMessageTime_
Expected orbit bunch time (needed to evaluate time differences)
bool getSpigotCRCError(unsigned int nspigot) const
Read the "CRC-Mismatch" bit for this spigot.
constexpr int fiber() const
get the fiber number
Definition: HcalQIESample.h:53
bool unpack(const HcalHTRData &data, HcalTTPDigi &digi)
const DetId lookup(CastorElectronicsId fId) const
lookup the logical detid associated with the given electronics id
static const int SPIGOT_COUNT
Definition: HcalDCCHeader.h:19
const HcalQIESample * unpack(const HcalQIESample *startPoint, const HcalQIESample *limit, DigiClass &digi, int presamples, const CastorElectronicsId &eid, int startSample, int endSample, int expectedTime, const HcalHTRData &hhd)
bool getSpigotPresent(unsigned int nspigot) const
Read the "PRESENT" bit for this spigot.
Readout chain identification for Castor Bits for the readout chain : some names need change! [31:26] ...
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
bool check() const
Check for a good event Requires a minimum length, matching wordcount and length, not an empty event...
Definition: HcalHTRData.cc:63
static const int MAXSAMPLES
int startSample_
first sample from fed raw data to copy
#define LogDebug(id)
int endSample_
last sample from fed raw data to copy (if present)
std::vector< HcalTTPDigi > * ttp
bool isUnsuppressed() const
Is this event an unsuppresed event?
Definition: HcalHTRData.cc:378