ATLAS Offline Software
Loading...
Searching...
No Matches
CpmSubBlockV2.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6#include "CpmSubBlockV2.h"
7
8namespace LVL1BS
9{
10
11// Constant definitions
12
14
16
30
39
40
45
49
50// Clear all data
51
53{
55 m_ttData.clear();
56 m_chanPresent.assign(m_channels, 0);
57}
58
59// Store CPM header
60
61void CpmSubBlockV2::setCpmHeader(const int version, const int format,
62 const int slice, const int crate,
63 const int module, const int timeslices)
64{
66}
67
68// Store trigger tower data
69
70void CpmSubBlockV2::fillTowerData(const int slice, const int channel,
71 const int em, const int had,
72 const int emErr, const int hadErr)
73{
74 if (channel < m_channels && (em || emErr || had || hadErr))
75 {
77 int dat = em;
78 int err = emErr;
79 for (int pinOffset = 0; pinOffset < 2; ++pinOffset)
80 {
81 if (dat || err)
82 {
83 const int pin = 2 * (channel / s_wordsPerPin) + pinOffset;
84 const int pair = (channel % s_wordsPerPin) / 2;
85 const int pos = pin * s_pairsPerPin + pair;
86 const int ix = index(slice) * m_channels + pos;
87 uint32_t word = m_ttData[ix];
88 if (channel % 2 == 0)
89 {
90 word |= (dat & s_ttDataMask) << s_ttDataABit;
91 word |= (err & 0x1) << s_parityABit;
92 word |= ((err >> 1) & 0x1) << s_linkDownABit;
93 }
94 else
95 {
96 word |= (dat & s_ttDataMask) << s_ttDataBBit;
97 word |= (err & 0x1) << s_parityBBit;
98 word |= ((err >> 1) & 0x1) << s_linkDownBBit;
99 }
100 word |= pair << s_pairBit;
101 word |= pin << s_fpgaBit;
102 word |= s_ttWordId << s_dataIdBit;
103 m_ttData[ix] = word;
104 }
105 dat = had;
106 err = hadErr;
107 }
108 m_chanPresent[channel] = 1;
109 }
110}
111
112// Return Em data for given channel
113
114int CpmSubBlockV2::emData(const int slice, const int channel) const
115{
116 return data(slice, channel, 0);
117}
118
119// Return Had data for given channel
120
121int CpmSubBlockV2::hadData(const int slice, const int channel) const
122{
123 return data(slice, channel, 1);
124}
125
126// Return Em error for given channel
127
128int CpmSubBlockV2::emError(const int slice, const int channel) const
129{
130 return error(slice, channel, 0);
131}
132
133// Return Had error for given channel
134
135int CpmSubBlockV2::hadError(const int slice, const int channel) const
136{
137 return error(slice, channel, 1);
138}
139
140// Return number of timeslices
141
143{
144 int slices = slices1();
145 if (slices == 0 && format() == NEUTRAL)
146 {
147 slices = dataWords() / s_glinkBitsPerSlice;
148 }
149 if (slices == 0) slices = 1;
150 return slices;
151}
152
153// Packing/Unpacking routines
154
156{
157 bool rc = false;
158 switch (version())
159 {
160 case 2: // <<== CHECK
161 switch (format())
162 {
163 case NEUTRAL:
164 rc = packNeutral();
165 break;
166 case UNCOMPRESSED:
168 break;
169 default:
170 break;
171 }
172 break;
173 default:
174 break;
175 }
176 return rc;
177}
178
180{
181 bool rc = false;
182 // TODO: (sasha) We choose version by ROD version, not by sub header
183 // version, so here we don't check sub header version (ask experts)
184 switch (format())
185 {
186 case NEUTRAL:
187 rc = unpackNeutral();
188 break;
189 case UNCOMPRESSED:
191 break;
192 default:
194 break;
195 }
196
197 // setUnpackErrorCode(UNPACK_VERSION);
198 return rc;
199}
200
201// Return data for given channel and pin offset
202
203int CpmSubBlockV2::data(const int slice, const int channel,
204 const int offset) const
205{
206 int dat = 0;
207 if (slice >= 0 && slice < timeslices() &&
208 channel >= 0 && channel < m_channels && !m_ttData.empty())
209 {
210 const int pin = 2 * (channel / s_wordsPerPin) + offset;
211 const int pair = (channel % s_wordsPerPin) / 2;
212 const int pos = pin * s_pairsPerPin + pair;
213 const int ix = index(slice) * m_channels + pos;
214 const uint32_t word = m_ttData[ix];
215 if (channel % 2 == 0)
216 {
217 dat = (word >> s_ttDataABit) & s_ttDataMask;
218 }
219 else dat = (word >> s_ttDataBBit) & s_ttDataMask;
220 }
221 return dat;
222}
223
224// Return error for given channel and pin offset
225
226int CpmSubBlockV2::error(const int slice, const int channel,
227 const int offset) const
228{
229 int err = 0;
230 if (slice >= 0 && slice < timeslices() &&
231 channel >= 0 && channel < m_channels && !m_ttData.empty())
232 {
233 const int pin = 2 * (channel / s_wordsPerPin) + offset;
234 const int pair = (channel % s_wordsPerPin) / 2;
235 const int pos = pin * s_pairsPerPin + pair;
236 const int ix = index(slice) * m_channels + pos;
237 const uint32_t word = m_ttData[ix];
238 if (channel % 2 == 0)
239 {
240 err = (word >> s_parityABit) & 0x1;
241 err |= ((word >> s_linkDownABit) & 0x1) << 1;
242 }
243 else
244 {
245 err = (word >> s_parityBBit) & 0x1;
246 err |= ((word >> s_linkDownBBit) & 0x1) << 1;
247 }
248 }
249 return err;
250}
251
252// Return data index appropriate to format
253
254int CpmSubBlockV2::index(const int slice) const
255{
256 return (format() == NEUTRAL) ? slice : 0;
257}
258
259// Resize a data vector according to format
260
261void CpmSubBlockV2::resize(std::vector<uint32_t> &vec, int channels)
262{
263 if (vec.empty())
264 {
265 int size = channels;
266 if (format() == NEUTRAL) size *= timeslices();
267 vec.resize(size);
268 }
269}
270
271// Pack neutral data
272
274{
276 const int slices = timeslices();
277 for (int slice = 0; slice < slices; ++slice)
278 {
279 for (int pin = 0; pin < s_glinkPins; ++pin)
280 {
281 // Trigger tower data
282 for (int pair = 0; pair < s_pairsPerPin; ++pair)
283 {
284 for (int i = 0; i < 2; ++i)
285 {
286 const int channel = s_wordsPerPin * (pin / 2) + 2 * pair + i;
287 if ((pin & 0x1)) // Odd pins Had, even Em
288 {
289 packerNeutral(pin, hadData(slice, channel), s_ttBits);
290 packerNeutral(pin, hadError(slice, channel), s_errBits);
291 }
292 else
293 {
294 packerNeutral(pin, emData(slice, channel), s_ttBits);
295 packerNeutral(pin, emError(slice, channel), s_errBits);
296 }
297 }
298 }
299 // Padding and Bunch Crossing number
300 if (pin < s_bcnPin)
301 {
302 packerNeutral(pin, 0, s_bcnBits);
303 }
304 else
305 {
307 s_bcnBits);
308 }
309 // G-Link parity
311 }
312 }
313 return true;
314}
315
316// Pack uncompressed data
317
319{
320 // Trigger tower data
321 std::vector<uint32_t>::const_iterator pos;
322 for (pos = m_ttData.begin(); pos != m_ttData.end(); ++pos)
323 {
324 if (*pos) packer(*pos, s_wordLength);
325 }
326 packerFlush();
327 return true;
328}
329
330// Unpack neutral data
331
333{
335 const int slices = timeslices();
336 for (int slice = 0; slice < slices; ++slice)
337 {
338 int bunchCrossing = 0;
339 for (int pin = 0; pin < s_glinkPins; ++pin)
340 {
341 // Trigger tower data
342 for (int pair = 0; pair < s_pairsPerPin; ++pair)
343 {
344 for (int i = 0; i < 2; ++i)
345 {
346 const int channel = s_wordsPerPin * (pin / 2) + 2 * pair + i;
347 int em = 0;
348 int had = 0;
349 int emErr = 0;
350 int hadErr = 0;
351 if ((pin & 0x1)) // Odd pins Had, even Em
352 {
353 em = emData(slice, channel);
354 had = unpackerNeutral(pin, s_ttBits);
355 emErr = emError(slice, channel);
356 hadErr = unpackerNeutral(pin, s_errBits);
357 }
358 else
359 {
360 em = unpackerNeutral(pin, s_ttBits);
361 had = hadData(slice, channel);
362 emErr = unpackerNeutral(pin, s_errBits);
363 hadErr = hadError(slice, channel);
364 }
365 fillTowerData(slice, channel, em, had, emErr, hadErr);
366 }
367 }
368 // Padding and Bunch Crossing number
369 if (pin < s_bcnPin)
370 {
372 }
373 else
374 {
376 << (pin - s_bcnPin) * s_bcnBits;
377 }
378 // G-Link parity error
380 }
382 }
383 const bool rc = unpackerSuccess();
385 return rc;
386}
387
388// Unpack uncompressed data
389
391{
393 unpackerInit();
394 uint32_t word = unpacker(s_wordLength);
395 while (unpackerSuccess())
396 {
397 const int id = dataId(word);
398 bool err = false;
399 // Trigger tower data
400 if (id == s_ttWordId)
401 {
402 const int ix = (word >> s_pairBit) & s_pairPinMask;
403 if (ix < m_channels && m_ttData[ix] == 0)
404 {
405 m_ttData[ix] = word;
406 const int pin = ix / 4;
407 const int pair = ix % 4;
408 const int channel = s_wordsPerPin * (pin / 2) + 2 * pair;
409 m_chanPresent[channel] = 1;
410 m_chanPresent[channel + 1] = 1;
411 }
412 else err = true;
413 }
414 else err = true;
415 if (err)
416 {
418 return false;
419 }
420 word = unpacker(s_wordLength);
421 }
422 return true;
423}
424
425} // end namespace
std::vector< size_t > vec
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t rc
int hadData(int slice, int channel) const
Return Had data for given channel.
bool unpackNeutral()
Unpack neutral data.
static const int s_linkDownBBit
static const int s_wordIdVal
CPM header word ID.
int hadError(int slice, int channel) const
Return Had error for given channel.
int dataId(uint32_t word) const
Return data WordID.
static const int s_glinkBitsPerSlice
int error(int slice, int channel, int offset) const
Return error for given channel and pin offset.
int data(int slice, int channel, int offset) const
Return data for given channel and pin offset.
static const int s_bcnBits
static const int s_fpgaBit
bool pack()
Pack data.
int index(int slice) const
Return data index appropriate to format.
int m_channels
Number of Trigger tower channels per module.
static const int s_linkDownABit
bool unpackUncompressed()
Unpack uncompressed data.
int emError(int slice, int channel) const
Return Em error for given channel.
static const int s_pairBit
bool unpack()
Unpack data.
static const uint32_t s_ttDataMask
static const int s_parityABit
void resize(std::vector< uint32_t > &vec, int channels)
Resize a data vector according to format.
int emData(int slice, int channel) const
Return Em data for given channel.
static const int s_wordLength
Data word length.
static const int s_pairsPerPin
void clear()
Clear all data.
int timeslices() const
Return number of timeslices.
static const int s_ttDataBBit
bool packUncompressed()
Pack uncompressed data.
static const uint32_t s_dataIdMask
std::vector< int > m_chanPresent
Channel present flags vector.
static const int s_parityBBit
void fillTowerData(int slice, int channel, int em, int had, int emErr, int hadErr)
Store trigger tower data.
static const int s_ttWordId
static const int s_glinkPins
std::vector< uint32_t > m_ttData
Trigger tower data.
void setCpmHeader(int version, int format, int slice, int crate, int module, int timeslices)
Store CPM header.
static const int s_ttBits
bool packNeutral()
Pack neutral data.
static const uint32_t s_pairPinMask
static const int s_errBits
static const int s_bcnPin
static const int s_wordsPerPin
static const int s_ttDataABit
static const int s_dataIdBit
void packer(uint32_t datum, int nbits)
Pack given data into given number of bits.
uint32_t unpacker(int nbits)
Unpack given number of bits of data.
void setUnpackErrorCode(int code)
Set the unpacking error code.
bool unpackerSuccess() const
Return unpacker success flag.
void setHeader(int wordId, int version, int format, int seqno, int crate, int module, int slices2, int slices1)
Store header data.
bool unpackerNeutralParityError(int pin)
Unpack and test G-Link parity bit for given pin.
int dataWords() const
Return number of data words.
void clear()
Clear all data.
void packerNeutralParity(int pin)
Pack current G-Link parity bit for given pin.
void packerFlush()
Flush the current data word padded with zeros.
uint32_t unpackerNeutral(int pin, int nbits)
Unpack given number of bits of neutral data for given pin.
int bunchCrossing() const
Return the Bunch Crossing number (neutral format only)
void unpackerInit()
Initialise unpacker.
void packerNeutral(int pin, uint32_t datum, int nbits)
Pack given neutral data from given pin.
void setBunchCrossing(int bc)
Set the Bunch Crossing number (neutral format only)
STL class.
Definition index.py:1
setEventNumber uint32_t