CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GctFormatTranslateMCLegacy.cc
Go to the documentation of this file.
2 
3 // C++ headers
4 #include <iostream>
5 #include <cassert>
6 
7 // Framework headers
9 
10 // Namespace resolution
11 using std::cout;
12 using std::endl;
13 using std::pair;
14 using std::make_pair;
15 using std::vector;
16 
17 // INITIALISE STATIC VARIABLES
24 
25 
26 // PUBLIC METHODS
27 
28 GctFormatTranslateMCLegacy::GctFormatTranslateMCLegacy(bool hltMode, bool unpackSharedRegions):
29  GctFormatTranslateBase(hltMode, unpackSharedRegions)
30 {
31  static bool initClass = true;
32 
33  if(initClass)
34  {
35  initClass = false;
36 
37  /*** Setup BlockID to BlockLength Map ***/
38  // Miscellaneous Blocks
39  m_blockLength.insert(make_pair(0x000,0)); // NULL
40  m_blockLength.insert(make_pair(0x0ff,198)); // Temporary hack: All RCT Calo Regions for CMSSW pack/unpack
41  // ConcJet FPGA
42  m_blockLength.insert(make_pair(0x583,8)); // ConcJet: Jet Cands and Counts Output to GT
43  // ConcElec FPGA
44  m_blockLength.insert(make_pair(0x683,6)); // ConcElec: EM Cands and Energy Sums Output to GT
45  // Electron Leaf FPGAs
46  m_blockLength.insert(make_pair(0x804,15)); // Leaf0ElecPosEtaU1: Raw Input
47  m_blockLength.insert(make_pair(0x884,12)); // Leaf0ElecPosEtaU2: Raw Input
48  m_blockLength.insert(make_pair(0xc04,15)); // Leaf0ElecNegEtaU1: Raw Input
49  m_blockLength.insert(make_pair(0xc84,12)); // Leaf0ElecNegEtaU2: Raw Input
50 
51 
52  /*** Setup BlockID to BlockName Map ***/
53  // Miscellaneous Blocks
54  m_blockName.insert(make_pair(0x000,"NULL"));
55  m_blockName.insert(make_pair(0x0ff,"All RCT Calo Regions")); // Temporary hack: All RCT Calo Regions for CMSSW pack/unpack
56  // ConcJet FPGA
57  m_blockName.insert(make_pair(0x583,"ConcJet: Jet Cands and Counts Output to GT"));
58  // ConcElec FPGA
59  m_blockName.insert(make_pair(0x683,"ConcElec: EM Cands and Energy Sums Output to GT"));
60  // Electron Leaf FPGAs
61  m_blockName.insert(make_pair(0x804,"Leaf0ElecPosEtaU1: Raw Input"));
62  m_blockName.insert(make_pair(0x884,"Leaf0ElecPosEtaU2: Raw Input"));
63  m_blockName.insert(make_pair(0xc04,"Leaf0ElecNegEtaU1: Raw Input"));
64  m_blockName.insert(make_pair(0xc84,"Leaf0ElecNegEtaU2: Raw Input"));
65 
66 
67  /*** Setup BlockID to Unpack-Function Map ***/
68  // Miscellaneous Blocks
70  m_blockUnpackFn[0x0ff] = &GctFormatTranslateMCLegacy::blockToAllRctCaloRegions; // Temporary hack: All RCT Calo Regions for CMSSW pack/unpack
71  // ConcJet FPGA
72  m_blockUnpackFn[0x583] = &GctFormatTranslateMCLegacy::blockToGctJetCandsAndCounts; // ConcJet: Jet Cands and Counts Output to GT
73  // ConcElec FPGA
74  m_blockUnpackFn[0x683] = &GctFormatTranslateMCLegacy::blockToGctEmCandsAndEnergySums; // ConcElec: EM Cands and Energy Sums Output to GT
75  // Electron Leaf FPGAs
76  m_blockUnpackFn[0x804] = &GctFormatTranslateMCLegacy::blockToFibresAndToRctEmCand; // Leaf0ElecPosEtaU1: Raw Input
77  m_blockUnpackFn[0x884] = &GctFormatTranslateMCLegacy::blockToFibresAndToRctEmCand; // Leaf0ElecPosEtaU2: Raw Input
78  m_blockUnpackFn[0xc04] = &GctFormatTranslateMCLegacy::blockToFibresAndToRctEmCand; // Leaf0ElecNegEtaU1: Raw Input
79  m_blockUnpackFn[0xc84] = &GctFormatTranslateMCLegacy::blockToFibresAndToRctEmCand; // Leaf0ElecNegEtaU2: Raw Input
80 
81 
82  /*** Setup RCT Em Crate Map ***/
83  m_rctEmCrate[0x804] = 13;
84  m_rctEmCrate[0x884] = 9;
85  m_rctEmCrate[0xc04] = 4;
86  m_rctEmCrate[0xc84] = 0;
87 
88 
89  /*** Setup RCT jet crate map. ***/
90  // No entries required!
91 
92 
93  /*** Setup Block ID map for pipeline payload positions of isolated Internal EM Cands. ***/
94  // No entries required!
95  }
96 }
97 
99 {
100 }
101 
103 {
104  // Turn the four 8-bit header words into the full 32-bit header.
105  uint32_t hdr = data[0] + (data[1]<<8) + (data[2]<<16) + (data[3]<<24);
106 
107  // Bit mapping of header:
108  // ----------------------
109  // 11:0 => block_id Unique pipeline identifier.
110  // - 3:0 =>> pipe_id There can be up to 16 different pipelines per FPGA.
111  // - 6:4 =>> reserved Do not use yet. Set to zero.
112  // - 11:7 =>> fpga geograpical add The VME geographical address of the FPGA.
113  // 15:12 => event_id Determined locally. Not reset by Resync.
114  // 19:16 => number_of_time_samples If time samples 15 or more then value = 15.
115  // 31:20 => event_bxId The bunch crossing the data was recorded.
116 
117  uint32_t blockId = hdr & 0xfff;
118  uint32_t blockLength = 0; // Set to zero until we know it's a valid block
119  uint32_t nSamples = (hdr>>16) & 0xf;
120  uint32_t bxId = (hdr>>20) & 0xfff;
121  uint32_t eventId = (hdr>>12) & 0xf;
122  bool valid = (blockLengthMap().find(blockId) != blockLengthMap().end());
123 
124  if(valid) { blockLength = blockLengthMap().find(blockId)->second; }
125 
126  return GctBlockHeader(blockId, blockLength, nSamples, bxId, eventId, valid);
127 }
128 
129 // conversion
130 bool GctFormatTranslateMCLegacy::convertBlock(const unsigned char * data, const GctBlockHeader& hdr)
131 {
132  // if the block has no time samples, don't bother with it.
133  if ( hdr.nSamples() < 1 ) { return true; }
134 
135  if(!checkBlock(hdr)) { return false; } // Check the block to see if it's possible to unpack.
136 
137  // The header validity check above will protect against
138  // the map::find() method returning the end of the map,
139  // assuming the block header definitions are up-to-date.
140  (this->*m_blockUnpackFn.find(hdr.blockId())->second)(data, hdr); // Calls the correct unpack function, based on block ID.
141 
142  return true;
143 }
144 
145 // Output EM Candidates and energy sums packing
147  const L1GctEmCandCollection* iso,
148  const L1GctEmCandCollection* nonIso,
149  const L1GctEtTotalCollection* etTotal,
150  const L1GctEtHadCollection* etHad,
151  const L1GctEtMissCollection* etMiss)
152 {
153  // Set up a vector of the collections for easy iteration.
154  vector<const L1GctEmCandCollection*> emCands(NUM_EM_CAND_CATEGORIES);
155  emCands.at(NON_ISO_EM_CANDS)=nonIso;
156  emCands.at(ISO_EM_CANDS)=iso;
157 
158  /* To hold the offsets within the EM candidate collections for the bx=0 candidates.
159  * The capture index doesn't seem to get set properly by the emulator, so take the
160  * first bx=0 cand as the highest energy EM cand, and the fourth as the lowest. */
161  vector<unsigned> bx0EmCandOffsets(NUM_EM_CAND_CATEGORIES);
162 
163  // Loop over the different catagories of EM cands to find the bx=0 offsets.
164  for(unsigned int iCat = 0 ; iCat < NUM_EM_CAND_CATEGORIES ; ++iCat)
165  {
166  const L1GctEmCandCollection * cands = emCands.at(iCat);
167  unsigned& offset = bx0EmCandOffsets.at(iCat);
168  if(!findBx0OffsetInCollection(offset, cands)) { LogDebug("GCT") << "No EM candidates with bx=0!\nAborting packing of GCT EM Cand and Energy Sum Output!"; return; }
169  if((cands->size()-offset) < 4) { LogDebug("GCT") << "Insufficient EM candidates with bx=0!\nAborting packing of GCT EM Cand and Energy Sum Output!"; return; }
170  }
171 
172  unsigned bx0EtTotalOffset, bx0EtHadOffset, bx0EtMissOffset;
173  if(!findBx0OffsetInCollection(bx0EtTotalOffset, etTotal)) { LogDebug("GCT") << "No Et Total value for bx=0!\nAborting packing of GCT EM Cand and Energy Sum Output!"; return; }
174  if(!findBx0OffsetInCollection(bx0EtHadOffset, etHad)) { LogDebug("GCT") << "No Et Hadronic value for bx=0!\nAborting packing of GCT EM Cand and Energy Sum Output!"; return; }
175  if(!findBx0OffsetInCollection(bx0EtMissOffset, etMiss)) { LogDebug("GCT") << "No Et Miss value for bx=0!\nAborting packing of GCT EM Cand and Energy Sum Output!"; return; }
176 
177  // We should now have all requisite data, so we can get on with packing
178 
179  unsigned nSamples = 1; // ** NOTE can only currenly do 1 timesample! **
180 
181  // write header
182  writeRawHeader(d, 0x683, nSamples);
183 
184  d=d+4; // move to the block payload.
185 
186  // FIRST DO EM CANDS
187 
188  // re-interpret payload pointer to 16 bit.
189  uint16_t * p16 = reinterpret_cast<uint16_t *>(d);
190 
191  for (unsigned iCat=0; iCat < NUM_EM_CAND_CATEGORIES; ++iCat) // loop over non-iso/iso candidates categories
192  {
193  const L1GctEmCandCollection * em = emCands.at(iCat); // The current category of EM cands.
194  const unsigned bx0Offset = bx0EmCandOffsets.at(iCat); // The offset in the EM cand collection to the bx=0 cands.
195 
196  uint16_t * cand = p16 + (iCat*4);
197 
198  *cand = em->at(bx0Offset).raw();
199  cand++;
200  *cand = em->at(bx0Offset + 2).raw();
201  cand += nSamples;
202  *cand = em->at(bx0Offset + 1).raw();
203  cand++;
204  *cand = em->at(bx0Offset + 3).raw();
205  }
206 
207  // NOW DO ENERGY SUMS
208  // assumes these are all 1-object collections, ie. central BX only
209  p16+=8; // Move past EM cands
210  *p16 = etTotal->at(bx0EtTotalOffset).raw(); // Et Total - 16 bits.
211  p16++;
212  *p16 = etHad->at(bx0EtHadOffset).raw(); // Et Hadronic - next 16 bits
213  p16++;
214  uint32_t * p32 = reinterpret_cast<uint32_t *>(p16); // For writing Missing Et (32-bit raw data)
215  *p32 = etMiss->at(bx0EtMissOffset).raw(); // Et Miss on final 32 bits of block payload.
216 }
217 
219  const L1GctJetCandCollection* cenJets,
220  const L1GctJetCandCollection* forJets,
221  const L1GctJetCandCollection* tauJets,
222  const L1GctHFRingEtSumsCollection* hfRingSums,
223  const L1GctHFBitCountsCollection* hfBitCounts,
224  const L1GctHtMissCollection* htMiss)
225 {
226  // Set up a vector of the collections for easy iteration.
227  vector<const L1GctJetCandCollection*> jets(NUM_JET_CATEGORIES);
228  jets.at(CENTRAL_JETS)=cenJets;
229  jets.at(FORWARD_JETS)=forJets;
230  jets.at(TAU_JETS)=tauJets;
231 
232  /* To hold the offsets within the three jet cand collections for the bx=0 jets.
233  * The capture index doesn't seem to get set properly by the emulator, so take the
234  * first bx=0 jet as the highest energy jet, and the fourth as the lowest. */
235  vector<unsigned> bx0JetCandOffsets(NUM_JET_CATEGORIES);
236 
237  // Loop over the different catagories of jets to find the bx=0 offsets.
238  for(unsigned int iCat = 0 ; iCat < NUM_JET_CATEGORIES ; ++iCat)
239  {
240  const L1GctJetCandCollection * jetCands = jets.at(iCat);
241  unsigned& offset = bx0JetCandOffsets.at(iCat);
242  if(!findBx0OffsetInCollection(offset, jetCands)) { LogDebug("GCT") << "No jet candidates with bx=0!\nAborting packing of GCT Jet Output!"; return; }
243  if((jetCands->size()-offset) < 4) { LogDebug("GCT") << "Insufficient jet candidates with bx=0!\nAborting packing of GCT Jet Output!"; return; }
244  }
245 
246  // Now find the collection offsets for the HfRingSums, HfBitCounts, and HtMiss with bx=0
247  unsigned bx0HfRingSumsOffset, bx0HfBitCountsOffset, bx0HtMissOffset;
248  if(!findBx0OffsetInCollection(bx0HfRingSumsOffset, hfRingSums)) { LogDebug("GCT") << "No ring sums with bx=0!\nAborting packing of GCT Jet Output!"; return; }
249  if(!findBx0OffsetInCollection(bx0HfBitCountsOffset, hfBitCounts)) { LogDebug("GCT") << "No bit counts with bx=0!\nAborting packing of GCT Jet Output!"; return; }
250  if(!findBx0OffsetInCollection(bx0HtMissOffset, htMiss)) { LogDebug("GCT") << "No missing Ht with bx=0!\nAborting packing of GCT Jet Output!"; return; }
251 
252  // Now write the header, as we should now have all requisite data.
253  writeRawHeader(d, 0x583, 1); // ** NOTE can only currenly do 1 timesample! **
254 
255  d=d+4; // move forward past the block header to the block payload.
256 
257  // FIRST DO JET CANDS
258  // re-interpret pointer to 16 bits - the space allocated for each Jet candidate.
259  uint16_t * p16 = reinterpret_cast<uint16_t *>(d);
260 
261  const unsigned categoryOffset = 4; // Offset to jump from one jet category to the next.
262  const unsigned nextCandPairOffset = 2; // Offset to jump to next candidate pair.
263 
264  // Loop over the different catagories of jets
265  for(unsigned iCat = 0 ; iCat < NUM_JET_CATEGORIES ; ++iCat)
266  {
267  const L1GctJetCandCollection * jetCands = jets.at(iCat); // The current category of jet cands.
268  const unsigned cand0Offset = iCat*categoryOffset; // the offset on p16 to get the rank 0 Jet Cand of the correct category.
269  const unsigned bx0Offset = bx0JetCandOffsets.at(iCat); // The offset in the jet cand collection to the bx=0 jets.
270 
271  p16[cand0Offset] = jetCands->at(bx0Offset).raw(); // rank 0 jet in bx=0
272  p16[cand0Offset + nextCandPairOffset] = jetCands->at(bx0Offset + 1).raw(); // rank 1 jet in bx=0
273  p16[cand0Offset + 1] = jetCands->at(bx0Offset + 2).raw(); // rank 2 jet in bx=0
274  p16[cand0Offset + nextCandPairOffset + 1] = jetCands->at(bx0Offset + 3).raw(); // rank 3 jet in bx=0.
275  }
276 
277  // NOW DO JET COUNTS
278  d=d+24; // move forward past the jet cands to the jet counts section
279 
280  // re-interpret pointer to 32 bit.
281  uint32_t * p32 = reinterpret_cast<uint32_t *>(d);
282 
283  uint32_t tmp = hfBitCounts->at(bx0HfBitCountsOffset).raw() & 0xfff;
284  tmp |= hfRingSums->at(bx0HfRingSumsOffset).etSum(0)<<12;
285  tmp |= hfRingSums->at(bx0HfRingSumsOffset).etSum(1)<<16;
286  tmp |= hfRingSums->at(bx0HfRingSumsOffset).etSum(2)<<19;
287  tmp |= hfRingSums->at(bx0HfRingSumsOffset).etSum(3)<<22;
288  p32[0] = tmp;
289 
290  const L1GctHtMiss& bx0HtMiss = htMiss->at(bx0HtMissOffset);
291  uint32_t htMissRaw = 0x5555c000 |
292  (bx0HtMiss.overFlow() ? 0x1000 : 0x0000) |
293  ((bx0HtMiss.et() & 0x7f) << 5) |
294  ((bx0HtMiss.phi() & 0x1f));
295 
296  p32[1] = htMissRaw;
297 }
298 
300 {
301  // This method is one giant "temporary" hack for CMSSW_1_8_X and CMSSW_2_0_0.
302 
303  if(rctEm->size() == 0 || rctEm->size()%144 != 0) // Should be 18 crates * 2 types (iso/noniso) * 4 electrons = 144 for 1 bx.
304  {
305  LogDebug("GCT") << "Block pack error: bad L1CaloEmCollection size detected!\n"
306  << "Aborting packing of RCT EM Cand data!";
307  return;
308  }
309 
310  // Need 18 sets of EM fibre data, since 18 RCT crates
311  SourceCardRouting::EmuToSfpData emuToSfpData[18];
312 
313  // Fill in the input arrays with the data from the digi
314  for(unsigned i=0, size=rctEm->size(); i < size ; ++i)
315  {
316  const L1CaloEmCand &cand = rctEm->at(i);
317  if(cand.bx() != 0) { continue; } // Only interested in bunch crossing zero for now!
318  unsigned crateNum = cand.rctCrate();
319  unsigned index = cand.index();
320 
321  // Some error checking.
322  assert(crateNum < 18); // Only 18 RCT crates!
323  assert(index < 4); // Should only be 4 cands of each type per crate!
324 
325  if(cand.isolated())
326  {
327  emuToSfpData[crateNum].eIsoRank[index] = cand.rank();
328  emuToSfpData[crateNum].eIsoCardId[index] = cand.rctCard();
329  emuToSfpData[crateNum].eIsoRegionId[index] = cand.rctRegion();
330  }
331  else
332  {
333  emuToSfpData[crateNum].eNonIsoRank[index] = cand.rank();
334  emuToSfpData[crateNum].eNonIsoCardId[index] = cand.rctCard();
335  emuToSfpData[crateNum].eNonIsoRegionId[index] = cand.rctRegion();
336  }
337  // Note doing nothing with the MIP bit and Q bit arrays as we are not
338  // interested in them; these arrays will contain uninitialised junk
339  // and so you will get out junk for sourcecard output 0 - I.e. don't
340  // trust sfp[0][0] or sfp[1][0] output!.
341  }
342 
343  // Now run the conversion
344  for(unsigned c = 0 ; c < 18 ; ++c)
345  {
346  srcCardRouting().EMUtoSFP(emuToSfpData[c].eIsoRank, emuToSfpData[c].eIsoCardId, emuToSfpData[c].eIsoRegionId,
347  emuToSfpData[c].eNonIsoRank, emuToSfpData[c].eNonIsoCardId, emuToSfpData[c].eNonIsoRegionId,
348  emuToSfpData[c].mipBits, emuToSfpData[c].qBits, emuToSfpData[c].sfp);
349  }
350 
351  // Now pack up the data into the RAW format.
352  BlkToRctCrateMap::iterator blockStartCrateIter;
353  for(blockStartCrateIter = rctEmCrateMap().begin() ; blockStartCrateIter != rctEmCrateMap().end() ; ++blockStartCrateIter)
354  {
355  unsigned blockId = blockStartCrateIter->first;
356  unsigned startCrate = blockStartCrateIter->second;
357  unsigned blockLength_32bit = blockLengthMap()[blockId];
358 
359  writeRawHeader(d, blockId, 1);
360  d+=4; // move past header.
361 
362  // Want a 16 bit pointer to push the 16 bit data in.
363  uint16_t * p16 = reinterpret_cast<uint16_t *>(const_cast<unsigned char *>(d));
364 
365  for(unsigned iCrate=startCrate, end=startCrate + blockLength_32bit/3 ; iCrate < end ; ++iCrate)
366  {
367  for(unsigned iOutput = 1 ; iOutput < 4 ; ++iOutput) // skipping output 0 as that is Q-bit/MIP-bit data.
368  {
369  for(unsigned iCycle = 0 ; iCycle < 2 ; ++iCycle)
370  {
371  *p16 = emuToSfpData[iCrate].sfp[iCycle][iOutput];
372  ++p16;
373  }
374  }
375  }
376 
377  // Now move d onto the location of the next block header
378  d+=(blockLength_32bit*4);
379  }
380 }
381 
383 {
384  // This method is one giant "temporary" hack for CMSSW_1_8_X and CMSSW_2_0_0.
385 
386  if(rctCalo->size() == 0 || rctCalo->size()%396 != 0) // Should be 396 calo regions for 1 bx.
387  {
388  LogDebug("GCT") << "Block pack error: bad L1CaloRegionCollection size detected!\n"
389  << "Aborting packing of RCT Calo Region data!";
390  return;
391  }
392 
393  writeRawHeader(d, 0x0ff, 1);
394  d+=4; // move past header.
395 
396  // Want a 16 bit pointer to push the 16 bit data in.
397  uint16_t * p16 = reinterpret_cast<uint16_t *>(const_cast<unsigned char *>(d));
398 
399  for(unsigned i=0, size=rctCalo->size(); i < size ; ++i)
400  {
401  const L1CaloRegion &reg = rctCalo->at(i);
402  if(reg.bx() != 0) { continue; } // Only interested in bunch crossing zero for now!
403  const unsigned crateNum = reg.rctCrate();
404  const unsigned regionIndex = reg.rctRegionIndex();
405  assert(crateNum < 18); // Only 18 RCT crates!
406 
407  // Gotta make the raw data as there currently isn't a method of getting raw from L1CaloRegion
408  const uint16_t raw = reg.et() |
409  (reg.overFlow() ? 0x400 : 0x0) |
410  (reg.fineGrain() ? 0x800 : 0x0) |
411  (reg.mip() ? 0x1000 : 0x0) |
412  (reg.quiet() ? 0x2000 : 0x0);
413 
414  unsigned offset = 0; // for storing calculated raw data offset.
415  if(reg.isHbHe()) // Is a barrel/endcap region
416  {
417  const unsigned cardNum = reg.rctCard();
418  assert(cardNum < 7); // 7 RCT cards per crate for the barrel/endcap
419  assert(regionIndex < 2); // regionIndex less than 2 for barrel/endcap
420 
421  // Calculate position in the raw data from crateNum, cardNum, and regionIndex
422  offset = crateNum*22 + cardNum*2 + regionIndex;
423  }
424  else // Must be forward region
425  {
426  assert(regionIndex < 8); // regionIndex less than 8 for forward calorimeter.
427  offset = crateNum*22 + 14 + regionIndex;
428  }
429  p16[offset] = raw; // Write raw data in correct place!
430  }
431 }
432 
433 
434 // PROTECTED METHODS
435 
436 uint32_t GctFormatTranslateMCLegacy::generateRawHeader(const uint32_t blockId,
437  const uint32_t nSamples,
438  const uint32_t bxId,
439  const uint32_t eventId) const
440 {
441  // Bit mapping of header:
442  // ----------------------
443  // 11:0 => block_id Unique pipeline identifier.
444  // - 3:0 =>> pipe_id There can be up to 16 different pipelines per FPGA.
445  // - 6:4 =>> reserved Do not use yet. Set to zero.
446  // - 11:7 =>> fpga geograpical add The VME geographical address of the FPGA.
447  // 15:12 => event_id Determined locally. Not reset by Resync.
448  // 19:16 => number_of_time_samples If time samples 15 or more then value = 15.
449  // 31:20 => event_bxId The bunch crossing the data was recorded.
450 
451  return ((bxId & 0xfff) << 20) | ((nSamples & 0xf) << 16) | ((eventId & 0xf) << 12) | (blockId & 0xfff);
452 }
453 
454 
455 // PRIVATE METHODS
456 
457 // Output EM Candidates unpacking
459 {
460  const unsigned int id = hdr.blockId();
461  const unsigned int nSamples = hdr.nSamples();
462 
463  // Re-interpret pointer. p16 will be pointing at the 16 bit word that
464  // contains the rank0 non-isolated electron of the zeroth time-sample.
465  const uint16_t * p16 = reinterpret_cast<const uint16_t *>(d);
466 
467  // UNPACK EM CANDS
468 
469  const unsigned int emCandCategoryOffset = nSamples * 4; // Offset to jump from the non-iso electrons to the isolated ones.
470  const unsigned int timeSampleOffset = nSamples * 2; // Offset to jump to next candidate pair in the same time-sample.
471 
472  unsigned int samplesToUnpack = 1;
473  if(!hltMode()) { samplesToUnpack = nSamples; } // Only if not running in HLT mode do we want more than 1 timesample.
474 
475  for (unsigned int iso=0; iso<2; ++iso) // loop over non-iso/iso candidate pairs
476  {
477  bool isoFlag = (iso==1);
478 
479  // Get the correct collection to put them in.
481  if (isoFlag) { em = colls()->gctIsoEm(); }
482  else { em = colls()->gctNonIsoEm(); }
483 
484  for (unsigned int bx=0; bx<samplesToUnpack; ++bx) // loop over time samples
485  {
486  // cand0Offset will give the offset on p16 to get the rank 0 candidate
487  // of the correct category and timesample.
488  const unsigned int cand0Offset = iso*emCandCategoryOffset + bx*2;
489 
490  em->push_back(L1GctEmCand(p16[cand0Offset], isoFlag, id, 0, bx)); // rank0 electron
491  em->push_back(L1GctEmCand(p16[cand0Offset + timeSampleOffset], isoFlag, id, 1, bx)); // rank1 electron
492  em->push_back(L1GctEmCand(p16[cand0Offset + 1], isoFlag, id, 2, bx)); // rank2 electron
493  em->push_back(L1GctEmCand(p16[cand0Offset + timeSampleOffset + 1], isoFlag, id, 3, bx)); // rank3 electron
494  }
495  }
496 
497  p16 += emCandCategoryOffset * 2; // Move the pointer over the data we've already unpacked.
498 
499  // UNPACK ENERGY SUMS
500  // NOTE: we are only unpacking one timesample of these currently!
501 
502  colls()->gctEtTot()->push_back(L1GctEtTotal(p16[0])); // Et total (timesample 0).
503  colls()->gctEtHad()->push_back(L1GctEtHad(p16[1])); // Et hadronic (timesample 0).
504 
505  // 32-bit pointer for getting Missing Et.
506  const uint32_t * p32 = reinterpret_cast<const uint32_t *>(p16);
507 
508  colls()->gctEtMiss()->push_back(L1GctEtMiss(p32[nSamples])); // Et Miss (timesample 0).
509 }
510 
512 {
513  const unsigned int id = hdr.blockId(); // Capture block ID.
514  const unsigned int nSamples = hdr.nSamples(); // Number of time-samples.
515 
516  // Re-interpret block payload pointer to 16 bits so it sees one candidate at a time.
517  // p16 points to the start of the block payload, at the rank0 tau jet candidate.
518  const uint16_t * p16 = reinterpret_cast<const uint16_t *>(d);
519 
520  // UNPACK JET CANDS
521 
522  const unsigned int jetCandCategoryOffset = nSamples * 4; // Offset to jump from one jet category to the next.
523  const unsigned int timeSampleOffset = nSamples * 2; // Offset to jump to next candidate pair in the same time-sample.
524 
525  unsigned int samplesToUnpack = 1;
526  if(!hltMode()) { samplesToUnpack = nSamples; } // Only if not running in HLT mode do we want more than 1 timesample.
527 
528  // Loop over the different catagories of jets
529  for(unsigned int iCat = 0 ; iCat < NUM_JET_CATEGORIES ; ++iCat)
530  {
531  L1GctJetCandCollection * const jets = gctJets(iCat);
532  assert(jets->empty()); // The supplied vector should be empty.
533 
534  bool tauflag = (iCat == TAU_JETS);
535  bool forwardFlag = (iCat == FORWARD_JETS);
536 
537  // Loop over the different timesamples (bunch crossings).
538  for(unsigned int bx = 0 ; bx < samplesToUnpack ; ++bx)
539  {
540  // cand0Offset will give the offset on p16 to get the rank 0 Jet Cand of the correct category and timesample.
541  const unsigned int cand0Offset = iCat*jetCandCategoryOffset + bx*2;
542 
543  // Rank 0 Jet.
544  jets->push_back(L1GctJetCand(p16[cand0Offset], tauflag, forwardFlag, id, 0, bx));
545  // Rank 1 Jet.
546  jets->push_back(L1GctJetCand(p16[cand0Offset + timeSampleOffset], tauflag, forwardFlag, id, 1, bx));
547  // Rank 2 Jet.
548  jets->push_back(L1GctJetCand(p16[cand0Offset + 1], tauflag, forwardFlag, id, 2, bx));
549  // Rank 3 Jet.
550  jets->push_back(L1GctJetCand(p16[cand0Offset + timeSampleOffset + 1], tauflag, forwardFlag, id, 3, bx));
551  }
552  }
553 
554  p16 += NUM_JET_CATEGORIES * jetCandCategoryOffset; // Move the pointer over the data we've already unpacked.
555 
556  // NOW UNPACK: HFBitCounts, HFRingEtSums and Missing Ht
557  // NOTE: we are only unpacking one timesample of these currently!
558 
559  // Re-interpret block payload pointer to 32 bits so it sees six jet counts at a time.
560  const uint32_t * p32 = reinterpret_cast<const uint32_t *>(p16);
561 
562  // Channel 0 carries both HF counts and sums
563  colls()->gctHfBitCounts()->push_back(L1GctHFBitCounts::fromConcHFBitCounts(id,6,0,p32[0]));
564  colls()->gctHfRingEtSums()->push_back(L1GctHFRingEtSums::fromConcRingSums(id,6,0,p32[0]));
565 
566  // Channel 1 carries Missing HT.
567  colls()->gctHtMiss()->push_back(L1GctHtMiss(p32[nSamples], 0));
568 }
569 
570 // Input EM Candidates unpacking
571 // this is the last time I deal the RCT bit assignment travesty!!!
572 void GctFormatTranslateMCLegacy::blockToRctEmCand(const unsigned char * d, const GctBlockHeader& hdr)
573 {
574  // Don't want to do this in HLT optimisation mode!
575  if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of RCT EM Cands"; return; }
576 
577  unsigned int id = hdr.blockId();
578  unsigned int nSamples = hdr.nSamples();
579  unsigned int length = hdr.blockLength();
580 
581  // re-interpret pointer
582  uint16_t * p = reinterpret_cast<uint16_t *>(const_cast<unsigned char *>(d));
583 
584  // arrays of source card data
585  uint16_t sfp[2][4]; // [ cycle ] [ SFP ]
586  uint16_t eIsoRank[4];
587  uint16_t eIsoCard[4];
588  uint16_t eIsoRgn[4];
589  uint16_t eNonIsoRank[4];
590  uint16_t eNonIsoCard[4];
591  uint16_t eNonIsoRgn[4];
592  uint16_t MIPbits[7][2];
593  uint16_t QBits[7][2];
594 
595  unsigned int bx = 0;
596 
597  // loop over crates
598  for (unsigned int crate=rctEmCrateMap()[id]; crate<rctEmCrateMap()[id]+length/3; ++crate) {
599 
600  // read SC SFP words
601  for (unsigned short iSfp=0 ; iSfp<4 ; ++iSfp) {
602  for (unsigned short cyc=0 ; cyc<2 ; ++cyc) {
603  if (iSfp==0) { sfp[cyc][iSfp] = 0; } // muon bits
604  else { // EM candidate
605  sfp[cyc][iSfp] = *p;
606  ++p;
607  }
608  }
609  p = p + 2*(nSamples-1);
610  }
611 
612  // fill SC arrays
613  srcCardRouting().SFPtoEMU(eIsoRank, eIsoCard, eIsoRgn, eNonIsoRank, eNonIsoCard, eNonIsoRgn, MIPbits, QBits, sfp);
614 
615  // create EM cands
616  for (unsigned short int i=0; i<4; ++i) {
617  colls()->rctEm()->push_back( L1CaloEmCand( eIsoRank[i], eIsoRgn[i], eIsoCard[i], crate, true, i, bx) );
618  }
619  for (unsigned short int i=0; i<4; ++i) {
620  colls()->rctEm()->push_back( L1CaloEmCand( eNonIsoRank[i], eNonIsoRgn[i], eNonIsoCard[i], crate, false, i, bx) );
621  }
622  }
623 }
624 
625 // Fibre unpacking
626 void GctFormatTranslateMCLegacy::blockToFibres(const unsigned char * d, const GctBlockHeader& hdr)
627 {
628  // Don't want to do this in HLT optimisation mode!
629  if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of GCT Fibres"; return; }
630 
631  unsigned int id = hdr.blockId();
632  unsigned int nSamples = hdr.nSamples();
633  unsigned int length = hdr.blockLength();
634 
635  // re-interpret pointer
636  uint32_t * p = reinterpret_cast<uint32_t *>(const_cast<unsigned char *>(d));
637 
638  for (unsigned int i=0; i<length; ++i) {
639  for (unsigned int bx=0; bx<nSamples; ++bx) {
640  colls()->gctFibres()->push_back( L1GctFibreWord(*p, id, i, bx) );
641  ++p;
642  }
643  }
644 }
645 
647 {
648  this->blockToRctEmCand(d, hdr);
649  this->blockToFibres(d, hdr);
650 }
651 
653 {
654  // Don't want to do this in HLT optimisation mode!
655  if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of RCT Calo Regions"; return; }
656 
657  // This method is one giant "temporary" hack whilst waiting for proper
658  // pipeline formats for the RCT calo region data.
659 
660  const int nSamples = hdr.nSamples(); // Number of time-samples.
661 
662  // Re-interpret block payload pointer to 16 bits
663  const uint16_t * p16 = reinterpret_cast<const uint16_t *>(d);
664 
665  for(unsigned iCrate = 0 ; iCrate < 18 ; ++iCrate)
666  {
667  // Barrel and endcap regions
668  for(unsigned iCard = 0 ; iCard < 7 ; ++iCard)
669  {
670  // Samples
671  for(int16_t iSample = 0 ; iSample < nSamples ; ++iSample)
672  {
673  // Two regions per card (and per 32-bit word).
674  for(unsigned iRegion = 0 ; iRegion < 2 ; ++iRegion)
675  {
676  L1CaloRegionDetId id(iCrate, iCard, iRegion);
677  colls()->rctCalo()->push_back(L1CaloRegion(*p16, id.ieta(), id.iphi(), iSample));
678  ++p16; //advance pointer
679  }
680  }
681  }
682  // Forward regions (8 regions numbered 0 through 7, packed in 4 sets of pairs)
683  for(unsigned iRegionPairNum = 0 ; iRegionPairNum < 4 ; ++iRegionPairNum)
684  {
685  // Samples
686  for(int16_t iSample = 0 ; iSample < nSamples ; ++iSample)
687  {
688  // two regions in a pair
689  for(unsigned iPair = 0 ; iPair < 2 ; ++iPair)
690  {
691  // For forward regions, RCTCard=999
692  L1CaloRegionDetId id(iCrate, 999, iRegionPairNum*2 + iPair);
693  colls()->rctCalo()->push_back(L1CaloRegion(*p16, id.ieta(), id.iphi(), iSample));
694  ++p16; //advance pointer
695  }
696  }
697  }
698  }
699 }
700 
701 template <typename Collection>
702 bool GctFormatTranslateMCLegacy::findBx0OffsetInCollection(unsigned& bx0Offset, const Collection* coll)
703 {
704  bool foundBx0 = false;
705  unsigned size = coll->size();
706  for(bx0Offset = 0 ; bx0Offset < size ; ++bx0Offset)
707  {
708  if(coll->at(bx0Offset).bx() == 0) { foundBx0 = true; break; }
709  }
710  return foundBx0;
711 }
#define LogDebug(id)
int16_t bx() const
get bunch-crossing index
Definition: L1CaloRegion.h:192
void writeGctOutEmAndEnergyBlock(unsigned char *d, const L1GctEmCandCollection *iso, const L1GctEmCandCollection *nonIso, const L1GctEtTotalCollection *etTotal, const L1GctEtHadCollection *etHad, const L1GctEtMissCollection *etMiss)
Writes GCT output EM and energy sums block into an unsigned char array, starting at the position poin...
L1GctHFBitCountsCollection *const gctHfBitCounts() const
GCT output: Hadronic-Forward bit-counts collection.
int i
Definition: DBlmapReader.cc:9
std::vector< L1CaloEmCand > L1CaloEmCollection
unsigned et() const
get Et
Definition: L1CaloRegion.h:116
L1GctEmCandCollection *const gctNonIsoEm() const
GCT output: Non-isolated EM candidate collection.
void writeAllRctCaloRegionBlock(unsigned char *d, const L1CaloRegionCollection *rctCalo)
Writes the giant hack that is the RCT Calo Regions block.
Global Calorimeter Trigger SC -&gt; CC fibre data word.
bool overFlow() const
get overflow
Definition: L1CaloRegion.h:122
bool checkBlock(const GctBlockHeader &hdr) const
Performs checks on the block header to see if the block is possible to unpack or not.
L1CaloEmCollection *const rctEm() const
Input electrons from the RCT to the GCT.
std::vector< L1GctEtMiss > L1GctEtMissCollection
unsigned rctCrate() const
get RCT crate ID
Definition: L1CaloRegion.h:165
L1GctHtMissCollection *const gctHtMiss() const
GCT output: Missing Ht collection.
std::vector< L1GctHFRingEtSums > L1GctHFRingEtSumsCollection
unsigned rctCard() const
get RCT reciever card ID (valid output for HB/HE)
Definition: L1CaloRegion.h:168
void blockToFibresAndToRctEmCand(const unsigned char *d, const GctBlockHeader &hdr)
unpack Fibres and RCT EM Candidates
void SFPtoEMU(unsigned short(&eIsoRank)[4], unsigned short(&eIsoCardId)[4], unsigned short(&eIsoRegionId)[4], unsigned short(&eNonIsoRank)[4], unsigned short(&eNonIsoCardId)[4], unsigned short(&eNonIsoRegionId)[4], unsigned short(&MIPbits)[7][2], unsigned short(&Qbits)[7][2], unsigned short(&SFP)[2][4]) const
Struct of all data needed for running the emulator to SFP (sourcecard optical output) conversion...
std::vector< L1GctEtHad > L1GctEtHadCollection
static BlkToRctCrateMap m_rctJetCrate
Map to relate capture block ID to the RCT crate the data originated from (for jets).
void writeRctEmCandBlocks(unsigned char *d, const L1CaloEmCollection *rctEm)
Writes the 4 RCT EM Candidate blocks.
Level-1 Trigger jet candidate.
Definition: L1GctJetCand.h:18
Abstract interface for RawToDigi/DigiToRaw conversions of GCT data.
Level-1 Region Calorimeter Trigger EM candidate.
Definition: L1CaloEmCand.h:18
void writeRawHeader(unsigned char *data, uint32_t blockId, uint32_t nSamples) const
Writes a raw block header into the raw data array for a given block ID and number of time-samples...
Persistable copy of missing Et measured at Level-1.
Definition: L1GctEtMiss.h:18
const SourceCardRouting & srcCardRouting() const
Protected interface to the unpackSharedRegions commissioning option.
unsigned rctRegionIndex() const
get RCT region index
Definition: L1CaloRegion.h:171
Level-1 Trigger EM candidate at output of GCT.
Definition: L1GctEmCand.h:22
void writeGctOutJetBlock(unsigned char *d, const L1GctJetCandCollection *cenJets, const L1GctJetCandCollection *forJets, const L1GctJetCandCollection *tauJets, const L1GctHFRingEtSumsCollection *hfRingSums, const L1GctHFBitCountsCollection *hfBitCounts, const L1GctHtMissCollection *htMiss)
Writes GCT output jet cands and counts into an unsigned char array, starting at the position pointed ...
void blockToGctEmCandsAndEnergySums(const unsigned char *d, const GctBlockHeader &hdr)
unpack GCT EM Candidates and energy sums.
std::vector< L1GctEtTotal > L1GctEtTotalCollection
bool quiet() const
get quiet bit
Definition: L1CaloRegion.h:134
void EMUtoSFP(unsigned short(&eIsoRank)[4], unsigned short(&eIsoCardId)[4], unsigned short(&eIsoRegionId)[4], unsigned short(&eNonIsoRank)[4], unsigned short(&eNonIsoCardId)[4], unsigned short(&eNonIsoRegionId)[4], unsigned short(&MIPbits)[7][2], unsigned short(&Qbits)[7][2], unsigned short(&SFP)[2][4]) const
std::vector< L1GctHFBitCounts > L1GctHFBitCountsCollection
U second(std::pair< T, U > const &p)
std::vector< L1GctJetCand > L1GctJetCandCollection
GctFormatTranslateMCLegacy(bool hltMode=false, bool unpackSharedRegions=false)
Constructor.
virtual BlockLengthMap & blockLengthMap()
get the static block ID to block-length map.
L1GctEtTotalCollection *const gctEtTot() const
GCT output: Total Et collection.
GctUnpackCollections *const colls() const
Protected access to the GCT Unpack Collections.
static BlockLengthMap m_blockLength
Map to translate block number to fundamental size of a block (i.e. for 1 time-sample).
bool overFlow() const
get the overflow
Definition: L1GctHtMiss.h:63
Persistable copy of total Et measured at Level-1.
Definition: L1GctEtTotal.h:18
unsigned rctCrate() const
get RCT crate
Definition: L1CaloEmCand.h:53
Simple class for holding the basic attributes of an 32-bit block header.
bool isolated() const
which stream did this come from
Definition: L1CaloEmCand.h:56
vector< PseudoJet > jets
int16_t bx() const
get bunch-crossing index
Definition: L1CaloEmCand.h:62
bool mip() const
get MIP bit
Definition: L1CaloRegion.h:131
unsigned rank() const
get rank bits
Definition: L1CaloEmCand.h:44
unsigned rctCard() const
get RCT receiver card
Definition: L1CaloEmCand.h:47
virtual uint32_t generateRawHeader(const uint32_t blockId, const uint32_t nSamples, const uint32_t bxId, const uint32_t eventId) const
Returns a raw 32-bit header word generated from the blockId, number of time samples, bunch-crossing and event IDs.
void blockToRctEmCand(const unsigned char *d, const GctBlockHeader &hdr)
unpack RCT EM Candidates
unsigned et() const
get the magnitude
Definition: L1GctHtMiss.h:60
L1GctEtMissCollection *const gctEtMiss() const
GCT output: Missing Et collection.
bool isHbHe() const
Definition: L1CaloRegion.h:162
#define end
Definition: vmac.h:38
std::map< unsigned int, unsigned int > BlockLengthMap
Block ID to Block Length map.
unsigned int offset(bool)
void blockDoNothing(const unsigned char *d, const GctBlockHeader &hdr)
The null unpack function - obviously common to all formats.
bool hltMode() const
Protected interface to get HLT optimisation mode flag.
Persistable copy of total Ht measured at Level-1.
Definition: L1GctEtHad.h:18
uint32_t blockLength() const
Get the fundamental block length (for 1 time sample)
static L1GctHFRingEtSums fromConcRingSums(const uint16_t capBlock, const uint16_t capIndex, const int16_t bx, const uint32_t data)
std::vector< L1GctHtMiss > L1GctHtMissCollection
static BlkToRctCrateMap m_rctEmCrate
Map to relate capture block ID to the RCT crate the data originated from (for electrons).
virtual GctBlockHeader generateBlockHeader(const unsigned char *data) const
Generate a block header from four 8-bit values.
L1GctJetCandCollection *const gctJets(const unsigned cat) const
Get a specific jet candandiate collection using the JetCandCategory enumeration.
void blockToGctJetCandsAndCounts(const unsigned char *d, const GctBlockHeader &hdr)
Unpack GCT Jet Candidates and jet counts.
JetCorrectorParametersCollection coll
Definition: classes.h:16
L1GctHFRingEtSumsCollection *const gctHfRingEtSums() const
GCT output: Hadronic-Forward ring-sums collection.
Persistable copy of missing Et measured at Level-1.
Definition: L1GctHtMiss.h:16
static BlockIdToEmCandIsoBoundMap m_internEmIsoBounds
bool fineGrain() const
get fine grain bit
Definition: L1CaloRegion.h:128
unsigned index() const
get index on cable
Definition: L1CaloEmCand.h:59
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
L1GctFibreCollection *const gctFibres() const
Raw fibre input to the GCT.
L1GctEmCandCollection *const gctIsoEm() const
GCT output: Isolated EM candidate collection.
#define begin
Definition: vmac.h:31
unsigned rctRegion() const
get RCT region ID
Definition: L1CaloEmCand.h:50
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
virtual BlkToRctCrateMap & rctEmCrateMap()
get the static block ID to RCT crate map for electrons.
virtual bool convertBlock(const unsigned char *d, const GctBlockHeader &hdr)
Get digis from the block - will return true if it succeeds, false otherwise.
L1GctEtHadCollection *const gctEtHad() const
GCT output: Hadronic transverse-energy (Ht) collection.
A calorimeter trigger region (sum of 4x4 trigger towers)
Definition: L1CaloRegion.h:22
static L1GctHFBitCounts fromConcHFBitCounts(const uint16_t capBlock, const uint16_t capIndex, const int16_t bx, const uint32_t data)
tuple cout
Definition: gather_cfg.py:121
void blockToFibres(const unsigned char *d, const GctBlockHeader &hdr)
unpack Fibres
std::map< unsigned int, IsoBoundaryPair > BlockIdToEmCandIsoBoundMap
A typdef for mapping Block IDs to IsoBoundaryPairs.
std::vector< L1CaloRegion > L1CaloRegionCollection
uint32_t blockId() const
Get the block ID.
std::map< unsigned int, unsigned int > BlkToRctCrateMap
Typedef for mapping block ID to RCT crate.
std::map< unsigned int, std::string > BlockNameMap
Block ID to Block Description map.
virtual ~GctFormatTranslateMCLegacy()
Destructor.
static BlockNameMap m_blockName
Map to hold a description for each block number.
std::map< unsigned int, PtrToUnpackFn > BlockIdToUnpackFnMap
Typedef for a block ID to unpack function map.
bool findBx0OffsetInCollection(unsigned &bx0Offset, const Collection *coll)
Template function (used in packing) that will find the offset to first item in a collection vector wh...
uint32_t nSamples() const
Get the number of time samples.
void blockToAllRctCaloRegions(const unsigned char *d, const GctBlockHeader &hdr)
Unpack All RCT Calo Regions (&#39;orrible hack for DigiToRaw use)
tuple size
Write out results.
unsigned phi() const
get the Et
Definition: L1GctHtMiss.h:66
L1CaloRegionCollection *const rctCalo() const
Input calo regions from the RCT to the GCT.
static BlockIdToUnpackFnMap m_blockUnpackFn
Block ID to unpack function map.
std::vector< L1GctEmCand > L1GctEmCandCollection