CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CastorUnpacker.cc
Go to the documentation of this file.
9 #include <iostream>
11 
12 namespace CastorUnpacker_impl {
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  int npre = 0;
172  /*
173  Unpack the trigger primitives
174  */
175  // lookup the right channel
176  bool dotp = true;
177  CastorElectronicsId eid(0, 1, spigot, dccid);
178  eid.setHTR(htr_cr, htr_slot, htr_tb);
179  DetId did = emap.lookup(eid);
180  if (did.null())
181  dotp = false;
182  HcalCastorDetId id1(did);
183  HcalCastorDetId id((id1.zside() == 0), id1.sector(), 1);
184  if (id1.module() > 12)
185  dotp = false;
186  if (dotp) {
187  // std::cout << " tp_first="<< tp_first << " tp_last="<< tp_last<< " tb="<<htr_tb<<" slot="<<htr_slot<<" crate="<<htr_cr<<" dccid="<< dccid<< std::endl;
188  // regular TPs (not HO)
189  for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
190  // std::cout << "raw=0x"<<std::hex<< tp_work->raw()<<std::dec <<std::endl;
191  if (tp_work->raw() == 0xFFFF)
192  continue; // filler word
193  if (slbAndChan(*tp_work) != currFiberChan) { // start new set
194  npre = 0;
195  currFiberChan = slbAndChan(*tp_work);
196 
197  // std::cout<< " NEW SET "<<std::endl;
198  //HcalElectronicsId eid(tp_work->slbChan(),tp_work->slb(),spigot,dccid,htr_cr,htr_slot,htr_tb);
199  //DetId did=emap.lookupTrigger(eid);
200  //if (did.null()) {
201  //report.countUnmappedTPDigi(eid);
202  //if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
203  //if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
204  //unknownIdsTrig_.insert(eid);
205  //}
206  //valid=false;
207  //continue;
208  //} else if (did==HcalTrigTowerDetId::Undefined ||
209  //(did.det()==DetId::Hcal && did.subdetId()==0)) {
211  //valid=false;
212  //continue;
213  //}
214 
215  colls.tpCont->push_back(CastorTriggerPrimitiveDigi(id));
216  // set the various bits
217  if (!tpgSOIbitInUse)
218  colls.tpCont->back().setPresamples(nps);
219  colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),
220  htr.wasMarkAndPassZSTP(slb(*tp_work), slbChan(*tp_work)));
221 
222  // no hits recorded for current
223  ncurr = 0;
224  valid = true;
225  }
226  // add the word (if within settings or recent firmware [recent firmware ignores startSample/endSample])
227  if (valid && ((tpgSOIbitInUse && ncurr < 10) || (ncurr >= startSample_ && ncurr <= endSample_))) {
228  colls.tpCont->back().setSample(colls.tpCont->back().size(), *tp_work);
229  colls.tpCont->back().setSize(colls.tpCont->back().size() + 1);
230  }
231  // set presamples,if SOI
232  if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
233  colls.tpCont->back().setPresamples(ncurr);
234  }
235  ncurr++;
236  npre++;
237  }
238  }
239 
241  qie_begin = (const HcalQIESample*)daq_first;
242  qie_end = (const HcalQIESample*)(daq_last + 1); // one beyond last..
243 
245 
246  for (qie_work = qie_begin; qie_work != qie_end;) {
247  if (qie_work->raw() == 0xFFFF) {
248  qie_work++;
249  continue; // filler word
250  }
251 
252  // lookup the right channel
253  CastorElectronicsId eid(qie_work->fiberChan(), qie_work->fiber(), spigot, dccid);
254  eid.setHTR(htr_cr, htr_slot, htr_tb);
255  DetId did = emap.lookup(eid);
256 
257  if (!did.null()) {
258  colls.castorCont->push_back(CastorDataFrame(HcalCastorDetId(did)));
259  qie_work = CastorUnpacker_impl::unpack<CastorDataFrame>(qie_work,
260  qie_end,
261  colls.castorCont->back(),
262  nps,
263  eid,
264  startSample_,
265  endSample_,
267  htr);
268  } else {
269  report.countUnmappedDigi();
270  if (unknownIds_.find(eid) == unknownIds_.end()) {
271  if (!silent)
272  edm::LogWarning("CASTOR") << "CastorUnpacker: No match found for electronics id :" << eid;
273  unknownIds_.insert(eid);
274  }
275  for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
276  qie_work++)
277  ;
278  }
279  }
280  }
281 }
bool check() const
Check for a good event Requires a minimum length, matching wordcount and length, not an empty event...
Definition: HcalHTRData.cc:63
uint16_t *__restrict__ id
static int slb(const HcalTriggerPrimitiveSample &theSample)
int sector() const
get the sector (1-16)
constexpr bool null() const
is this a null id ?
Definition: DetId.h:59
bool getSpigotCRCError(unsigned int nspigot) const
Read the &quot;CRC-Mismatch&quot; bit for this spigot.
void setHTR(int crate, int slot, int tb)
static bool isTPGSOI(const HcalTriggerPrimitiveSample &s)
constexpr int fiberChan() const
get the fiber channel number
Definition: HcalQIESample.h:55
int module() const
get the module (1-2 for EM, 1-12 for HAD)
bool wasMarkAndPassZS(int fiber, int fiberchan) const
Was this channel passed as part of Mark&amp;Pass ZS?
Definition: HcalHTRData.cc:379
unsigned int getFibOrbMsgBCN(int fiber) const
Get the BCN of the Fiber Orbit Messages.
Definition: HcalHTRData.h:180
static int slbChan(const HcalTriggerPrimitiveSample &theSample)
int getSpigotData(int nspigot, HcalHTRData &decodeTool, int validSize) const
int getFormatVersion() const
Get the version number of this event.
Definition: HcalHTRData.h:36
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
std::set< CastorElectronicsId > unknownIds_
void unpack(const FEDRawData &raw, const CastorElectronicsMap &emap, CastorRawCollections &conts, HcalUnpackerReport &report, bool silent=false)
For histograms, no begin and end.
bool isUnsuppressed() const
Is this event an unsuppresed event?
Definition: HcalHTRData.cc:378
tuple report
Definition: zeeHLT_cff.py:9
const DetId lookup(CastorElectronicsId fId) const
lookup the logical detid associated with the given electronics id
CastorUnpacker(int sourceIdOffset, int beg, int end)
for normal data
static int slbAndChan(const HcalTriggerPrimitiveSample &theSample)
int zside() const
get the z-side of the cell (1/-1)
uint16_t raw() const
get the raw word
bool getSpigotPresent(unsigned int nspigot) const
Read the &quot;PRESENT&quot; bit for this spigot.
std::vector< CastorDataFrame > * castorCont
std::vector< CastorTriggerPrimitiveDigi > * tpCont
int getSourceId() const
Definition: HcalDCCHeader.h:32
Definition: DetId.h:17
int sourceIdOffset_
number to subtract from the source id to get the dcc id
int expectedOrbitMessageTime_
Expected orbit bunch time (needed to evaluate time differences)
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
bool unpack(const HcalHTRData &data, HcalTTPDigi &digi)
int getNPS() const
Get the number of presamples in daq data.
Definition: HcalHTRData.cc:426
int getFirmwareFlavor() const
Get the HTR firmware flavor.
Definition: HcalHTRData.cc:433
static const int SPIGOT_COUNT
Definition: HcalDCCHeader.h:19
bool wasMarkAndPassZSTP(int slb, int slbchan) const
Was this channel passed as part of Mark&amp;Pass ZS?
Definition: HcalHTRData.cc:389
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)
uint32_t zsBunchMask() const
ZS Bunch Mask (if available)
Definition: HcalHTRData.cc:400
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
string end
Definition: dataset.py:937
constexpr uint16_t raw() const
get the raw word
Definition: HcalQIESample.h:41
Readout chain identification for Castor Bits for the readout chain : some names need change! [31:26] ...
unsigned int getSubmodule() const
Get the HTR submodule number.
Definition: HcalHTRData.cc:355
Log< level::Warning, false > LogWarning
static const int MAXSAMPLES
bool isHistogramEvent() const
Is this event a histogram event? (do not call standard unpack in this case!!!!!)
Definition: HcalHTRData.cc:409
int startSample_
first sample from fed raw data to copy
constexpr int fiber() const
get the fiber number
Definition: HcalQIESample.h:53
#define LogDebug(id)
int endSample_
last sample from fed raw data to copy (if present)
constexpr int fiberAndChan() const
get the id channel
Definition: HcalQIESample.h:57
std::vector< HcalTTPDigi > * ttp