CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
HcalPacker.cc
Go to the documentation of this file.
8 
10  hbhe = nullptr;
11  hoCont = nullptr;
12  hfCont = nullptr;
13  tpCont = nullptr;
14  zdcCont = nullptr;
15  calibCont = nullptr;
16 }
17 
18 template <class Coll, class DetIdClass>
19 int process(const Coll* pt, const DetId& did, unsigned short* buffer, int& presamples, bool& isUS, bool& isMP) {
20  isUS = false;
21  isMP = false;
22  if (pt == nullptr) {
23  return 0;
24  }
25  int size = 0;
26  typename Coll::const_iterator i = pt->find(DetIdClass(did));
27  if (i != pt->end()) {
28  isUS = i->zsUnsuppressed();
29  isMP = i->zsMarkAndPass();
30  presamples = i->presamples();
31  size = i->size();
32  for (int j = 0; j < size; j++) {
33  buffer[j] = (*i)[j].raw();
34  }
35  }
36  return size;
37 }
38 
39 static unsigned char processTrig(const HcalTrigPrimDigiCollection* pt,
40  const HcalTrigTowerDetId& tid,
41  unsigned short* buffer) {
42  if (pt == nullptr) {
43  return 0;
44  }
45  int size = 0;
47  bool any_nonzero = false;
48  if (i != pt->end()) {
49  int presamples = i->presamples();
50  size = i->size();
51 
52  for (int j = 0; j < size; j++) {
53  buffer[j] = (*i)[j].raw();
54  if ((buffer[j] & 0x1FF) != 0)
55  any_nonzero = true;
56  if (j == presamples) {
57  buffer[j] |= 0x0200;
58  }
59  }
60  }
61  return (any_nonzero) ? (size) : (0);
62 }
63 
65  const Collections& inputs,
66  unsigned short* buffer,
67  int& presamples,
68  bool& isUS,
69  bool& isMP) const {
70  if (!(did.det() == DetId::Hcal || (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId))) {
71  return 0;
72  }
73  int size = 0;
74  HcalGenericDetId genId(did);
75 
76  switch (genId.genericSubdet()) {
79  size = process<HBHEDigiCollection, HcalDetId>(inputs.hbhe, did, buffer, presamples, isUS, isMP);
80  break;
82  size = process<HODigiCollection, HcalDetId>(inputs.hoCont, did, buffer, presamples, isUS, isMP);
83  break;
85  size = process<HFDigiCollection, HcalDetId>(inputs.hfCont, did, buffer, presamples, isUS, isMP);
86  break;
88  size = process<ZDCDigiCollection, HcalZDCDetId>(inputs.zdcCont, did, buffer, presamples, isUS, isMP);
89  break;
91  size = process<HcalCalibDigiCollection, HcalCalibDetId>(inputs.calibCont, did, buffer, presamples, isUS, isMP);
92  break;
93  default:
94  size = 0;
95  }
96  return size;
97 }
98 
99 void HcalPacker::pack(int fedid,
100  int dccnumber,
101  int nl1a,
102  int orbitn,
103  int bcn,
104  const Collections& inputs,
105  const HcalElectronicsMap& emap,
106  FEDRawData& output) const {
107  std::vector<unsigned short> precdata(HcalHTRData::CHANNELS_PER_SPIGOT * HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
108  std::vector<unsigned short> trigdata(HcalHTRData::CHANNELS_PER_SPIGOT * HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
109  std::vector<unsigned char> preclen(HcalHTRData::CHANNELS_PER_SPIGOT);
110  std::vector<unsigned char> triglen(HcalHTRData::CHANNELS_PER_SPIGOT);
111  static const int HTRFormatVersion = 5;
112  bool channelIsMP[HcalHTRData::CHANNELS_PER_SPIGOT];
113 
114  HcalHTRData spigots[15];
115  // loop over all valid channels in the given dcc, spigot by spigot.
116  for (int spigot = 0; spigot < 15; spigot++) {
117  spigots[spigot].allocate(HTRFormatVersion);
118  HcalElectronicsId exampleEId;
119  int npresent = 0, npresenttp = 0;
120  int presamples = -1, samples = -1;
121  bool haveUnsuppressed = false;
122  for (int fiber = 1; fiber <= 8; fiber++) {
123  for (int fiberchan = 0; fiberchan < 3; fiberchan++) {
124  int linear = (fiber - 1) * 3 + fiberchan;
125  HcalQIESample chanSample(0, 0, fiber, fiberchan, false, false);
126  unsigned short chanid = chanSample.raw() & 0xF800;
127  preclen[linear] = 0;
128  channelIsMP[linear] = false;
129 
130  HcalElectronicsId partialEid(fiberchan, fiber, spigot, dccnumber);
131  // does this partial id exist?
132  HcalElectronicsId fullEid;
133  HcalGenericDetId genId;
134  if (!emap.lookup(partialEid, fullEid, genId)) {
135  continue;
136  }
137 
138  // next, see if there is a digi with this id
139  unsigned short* database = &(precdata[linear * HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL]);
140  int mypresamples = -1;
141  bool isUS = false, isMP = false;
142  int mysamples = findSamples(genId, inputs, database, mypresamples, isUS, isMP);
143  haveUnsuppressed = haveUnsuppressed || isUS;
144  channelIsMP[linear] = isMP;
145 
146  if (mysamples > 0) {
147  if (samples < 0) {
148  samples = mysamples;
149  } else if (samples != mysamples) {
150  edm::LogError("HCAL") << "Mismatch of samples in a single HTR (unsupported) " << mysamples
151  << " != " << samples;
152  continue;
153  }
154  if (presamples < 0) {
155  presamples = mypresamples;
156  exampleEId = fullEid;
157  } else if (mypresamples != presamples) {
158  edm::LogError("HCAL") << "Mismatch of presamples in a single HTR (unsupported) " << mypresamples
159  << " != " << presamples;
160  continue;
161  }
162  for (int ii = 0; ii < samples; ii++) {
163  database[ii] = (database[ii] & 0x7FF) | chanid;
164  }
165  preclen[linear] = (unsigned char)(samples);
166  npresent++;
167  }
168  }
169  }
170  for (int slb = 1; slb <= 6; slb++) {
171  for (int slbchan = 0; slbchan <= 3; slbchan++) {
172  int linear = (slb - 1) * 4 + slbchan;
173  HcalTriggerPrimitiveSample idCvt(0, false, slb, slbchan);
174  unsigned short chanid = idCvt.raw() & 0xF800;
175  triglen[linear] = 0;
176 
177  HcalElectronicsId partialEid(slbchan, slb, spigot, dccnumber, 0, 0, 0);
178  // does this partial id exist?
179  HcalElectronicsId fullEid;
180  HcalTrigTowerDetId tid;
181  if (!emap.lookup(partialEid, fullEid, tid)) {
182  // std::cout << "TPGPACK : no match for " << partialEid << std::endl;
183  continue;
184  } //else std::cout << "TPGPACK : converted " << partialEid << " to " << fullEid << "/" << tid << std::endl;
185 
186  // finally, what about a trigger channel?
187  if (!tid.null()) {
188  if (presamples < 0) {
189  exampleEId = fullEid;
190  }
191  unsigned short* trigbase = &(trigdata[linear * HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL]);
192  triglen[linear] = processTrig(inputs.tpCont, tid, trigbase);
193  if (triglen[linear]) {
194  npresent++;
195  npresenttp++;
196  }
197 
198  for (unsigned char q = 0; q < triglen[linear]; q++) {
199  trigbase[q] = (trigbase[q] & 0x7FF) | chanid;
200  }
201  }
202  }
203  }
205  if (npresent > 0) {
206  spigots[spigot].pack(&(preclen[0]), &(precdata[0]), &(triglen[0]), &(trigdata[0]), false);
207  static const int pipeline = 0x22;
208  static const int firmwareRev = 0;
209  int submodule = exampleEId.htrTopBottom() & 0x1;
210  submodule |= (exampleEId.htrSlot() & 0x1F) << 1;
211  submodule |= (exampleEId.readoutVMECrateId() & 0x1f) << 6;
212  // Samples and Presamples can't be negative, or the HeaderTrailer will
213  // generate a large large number using them (unsigned int roll over)
214  if (samples < 0) {
215  samples = 0;
216  }
217  if (presamples < 0) {
218  presamples = 0;
219  }
220  spigots[spigot].packHeaderTrailer(nl1a,
221  bcn,
222  submodule,
223  orbitn,
224  pipeline,
225  samples,
226  presamples,
227  firmwareRev,
228  1); // need non-zero falvor
229  if (haveUnsuppressed) {
230  spigots[spigot].packUnsuppressed(channelIsMP);
231  }
232  }
233  }
234  // calculate the total length, and resize the FEDRawData
235  int theSize = 0;
236  for (int spigot = 0; spigot < 15; spigot++) {
237  theSize += spigots[spigot].getRawLength() * sizeof(unsigned short);
238  }
239  theSize += sizeof(HcalDCCHeader) + 8; // 8 for trailer
240  theSize += (8 - (theSize % 8)) % 8; // even number of 64-bit words.
241  output.resize(theSize);
242 
243  // construct the bare DCC Header
244  HcalDCCHeader* dcc = (HcalDCCHeader*)(output.data());
245  dcc->clear();
246  dcc->setHeader(fedid, bcn, nl1a, orbitn);
247 
248  // pack the HTR data into the FEDRawData block using HcalDCCHeader
249  for (int spigot = 0; spigot < 15; spigot++) {
250  if (spigots[spigot].getRawLength() > 0) {
251  dcc->copySpigotData(spigot, spigots[spigot], true, 0);
252  }
253  }
254  // trailer
255  FEDTrailer fedTrailer(output.data() + (output.size() - 8));
256  fedTrailer.set(
257  output.data() + (output.size() - 8), output.size() / 8, evf::compute_crc(output.data(), output.size()), 0, 0);
258 }
static int slb(const HcalTriggerPrimitiveSample &theSample)
void packUnsuppressed(const bool *mp)
pack trailer with Mark and Pass bits
Definition: HcalHTRData.cc:327
void pack(int fedid, int dccnumber, int nl1a, int orbitn, int bcn, const Collections &inputs, const HcalElectronicsMap &emap, FEDRawData &output) const
Definition: HcalPacker.cc:99
constexpr bool null() const
is this a null id ?
Definition: DetId.h:59
std::vector< T >::const_iterator const_iterator
const HcalCalibDigiCollection * calibCont
Definition: HcalPacker.h:19
static const int CHANNELS_PER_SPIGOT
Definition: HcalHTRData.h:18
Log< level::Error, false > LogError
int ii
Definition: cuy.py:589
static const int MAXIMUM_SAMPLES_PER_CHANNEL
Definition: HcalHTRData.h:19
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
void allocate(int version_to_create=0)
Definition: HcalHTRData.cc:25
constexpr int htrTopBottom() const
get the htr top/bottom (1=top/0=bottom), valid for VME
void copySpigotData(unsigned int spigot_id, const HcalHTRData &data, bool valid=true, unsigned char LRB_error_word=0)
Add the given HcalHTRData as the given spigot&#39;s data. This should be done in increasing spigot order!...
static void set(unsigned char *trailer, uint32_t lenght, uint16_t crc, uint8_t evt_stat, uint8_t tts, bool moreTrailers=false)
Set all fields in the trailer.
Definition: FEDTrailer.cc:31
static unsigned char processTrig(const HcalTrigPrimDigiCollection *pt, const HcalTrigTowerDetId &tid, unsigned short *buffer)
Definition: HcalPacker.cc:39
int findSamples(const DetId &did, const Collections &inputs, unsigned short *buffer, int &presamples, bool &zsUS, bool &zsMP) const
Definition: HcalPacker.cc:64
void resize(size_t newsize)
Definition: FEDRawData.cc:28
constexpr int htrSlot() const
get the htr slot
unsigned short compute_crc(unsigned char *buffer, unsigned int bufSize)
Definition: CRC16.h:46
const int getRawLength() const
Get the length of the raw data.
Definition: HcalHTRData.h:42
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
void setHeader(int sourceid, int bcn, int l1aN, int orbN)
uint16_t raw() const
get the raw word
const HcalTrigPrimDigiCollection * tpCont
Definition: HcalPacker.h:21
constexpr int readoutVMECrateId() const
get the readout VME crate number
const ZDCDigiCollection * zdcCont
Definition: HcalPacker.h:20
const HBHEDigiCollection * hbhe
Definition: HcalPacker.h:16
const_iterator end() const
Definition: DetId.h:17
static const int SubdetectorId
Definition: HcalZDCDetId.h:25
void pack(unsigned char *daq_lengths, unsigned short *daq_samples, unsigned char *tp_lengths, unsigned short *tp_samples, bool do_capid=false)
Unpack the HTR data into TP and DAQ data sorted by channel.
Definition: HcalHTRData.cc:233
void packHeaderTrailer(int L1Anumber, int bcn, int submodule, int orbitn, int pipeline, int ndd, int nps, int firmwareRev=0, int firmwareFlav=0)
pack header and trailer (call after pack)
Definition: HcalHTRData.cc:294
iterator find(key_type k)
const HODigiCollection * hoCont
Definition: HcalPacker.h:17
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
constexpr uint16_t raw() const
get the raw word
Definition: HcalQIESample.h:41
const HFDigiCollection * hfCont
Definition: HcalPacker.h:18
float linear(float x)
HcalGenericSubdetector genericSubdet() const
tuple process
Definition: LaserDQM_cfg.py:3
Readout chain identification for Hcal.
tuple size
Write out results.
const DetId lookup(HcalElectronicsId fId) const
lookup the logical detid associated with the given electronics id
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46