CMS 3D CMS Logo

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 
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;
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  }
196 
197  for (unsigned char q = 0; q < triglen[linear]; q++) {
198  trigbase[q] = (trigbase[q] & 0x7FF) | chanid;
199  }
200  }
201  }
202  }
204  if (npresent > 0) {
205  spigots[spigot].pack(&(preclen[0]), &(precdata[0]), &(triglen[0]), &(trigdata[0]), false);
206  static const int pipeline = 0x22;
207  static const int firmwareRev = 0;
208  int submodule = exampleEId.htrTopBottom() & 0x1;
209  submodule |= (exampleEId.htrSlot() & 0x1F) << 1;
210  submodule |= (exampleEId.readoutVMECrateId() & 0x1f) << 6;
211  // Samples and Presamples can't be negative, or the HeaderTrailer will
212  // generate a large large number using them (unsigned int roll over)
213  if (samples < 0) {
214  samples = 0;
215  }
216  if (presamples < 0) {
217  presamples = 0;
218  }
219  spigots[spigot].packHeaderTrailer(nl1a,
220  bcn,
221  submodule,
222  orbitn,
223  pipeline,
224  samples,
225  presamples,
226  firmwareRev,
227  1); // need non-zero falvor
228  if (haveUnsuppressed) {
229  spigots[spigot].packUnsuppressed(channelIsMP);
230  }
231  }
232  }
233  // calculate the total length, and resize the FEDRawData
234  int theSize = 0;
235  for (int spigot = 0; spigot < 15; spigot++) {
236  theSize += spigots[spigot].getRawLength() * sizeof(unsigned short);
237  }
238  theSize += sizeof(HcalDCCHeader) + 8; // 8 for trailer
239  theSize += (8 - (theSize % 8)) % 8; // even number of 64-bit words.
240  output.resize(theSize);
241 
242  // construct the bare DCC Header
243  HcalDCCHeader* dcc = (HcalDCCHeader*)(output.data());
244  dcc->clear();
245  dcc->setHeader(fedid, bcn, nl1a, orbitn);
246 
247  // pack the HTR data into the FEDRawData block using HcalDCCHeader
248  for (int spigot = 0; spigot < 15; spigot++) {
249  if (spigots[spigot].getRawLength() > 0) {
250  dcc->copySpigotData(spigot, spigots[spigot], true, 0);
251  }
252  }
253  // trailer
254  FEDTrailer fedTrailer(output.data() + (output.size() - 8));
255  fedTrailer.set(
256  output.data() + (output.size() - 8), output.size() / 8, evf::compute_crc(output.data(), output.size()), 0, 0);
257 }
size
Write out results.
constexpr int readoutVMECrateId() const
get the readout VME crate number
static int slb(const HcalTriggerPrimitiveSample &theSample)
void packUnsuppressed(const bool *mp)
pack trailer with Mark and Pass bits
Definition: HcalHTRData.cc:327
const DetId lookup(HcalElectronicsId fId) const
lookup the logical detid associated with the given electronics id
std::vector< T >::const_iterator const_iterator
const HcalCalibDigiCollection * calibCont
Definition: HcalPacker.h:19
static const int CHANNELS_PER_SPIGOT
Definition: HcalHTRData.h:18
constexpr int htrSlot() const
get the htr slot
Log< level::Error, false > LogError
static const int MAXIMUM_SAMPLES_PER_CHANNEL
Definition: HcalHTRData.h:19
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46
void allocate(int version_to_create=0)
Definition: HcalHTRData.cc:25
constexpr bool null() const
is this a null id ?
Definition: DetId.h:59
uint16_t raw() const
get the raw word
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
unsigned short compute_crc(unsigned char *buffer, unsigned int bufSize)
Definition: CRC16.h:46
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
void setHeader(int sourceid, int bcn, int l1aN, int orbN)
const HcalTrigPrimDigiCollection * tpCont
Definition: HcalPacker.h:21
const ZDCDigiCollection * zdcCont
Definition: HcalPacker.h:20
int findSamples(const DetId &did, const Collections &inputs, unsigned short *buffer, int &presamples, bool &zsUS, bool &zsMP) const
Definition: HcalPacker.cc:64
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
const HBHEDigiCollection * hbhe
Definition: HcalPacker.h:16
ii
Definition: cuy.py:589
HcalGenericSubdetector genericSubdet() const
Definition: DetId.h:17
static const int SubdetectorId
Definition: HcalZDCDetId.h:25
constexpr uint16_t raw() const
get the raw word
Definition: HcalQIESample.h:41
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
int process(const Coll *pt, const DetId &did, unsigned short *buffer, int &presamples, bool &isUS, bool &isMP)
Definition: HcalPacker.cc:19
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
constexpr int htrTopBottom() const
get the htr top/bottom (1=top/0=bottom), valid for VME
const HODigiCollection * hoCont
Definition: HcalPacker.h:17
const HFDigiCollection * hfCont
Definition: HcalPacker.h:18
float linear(float x)
const int getRawLength() const
Get the length of the raw data.
Definition: HcalHTRData.h:42
Readout chain identification for Hcal.