ATLAS Offline Software
Loading...
Searching...
No Matches
ZdcLucrodDecoder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#define endreq endmsg
9
11
12 if (msgLevel(MSG::DEBUG)) msg(MSG::DEBUG) << " ZdcLucrodDecoder::decode" << endreq;
13
14 uint32_t ROD_run_no = robFragment->rod_run_no();
15 uint32_t ROD_lvl1_id = robFragment->rod_lvl1_id();
16 uint32_t ROD_bc_id = robFragment->rod_bc_id();
17 uint32_t ROD_lvl1_trigger_type = robFragment->rod_lvl1_trigger_type();
18 uint32_t ROD_detev_type = robFragment->rod_detev_type();
19 uint32_t ROD_marker = robFragment->rod_marker();
20 uint32_t ROD_fragment_size = robFragment->rod_fragment_size_word();
21 uint32_t ROD_header_size = robFragment->rod_header_size_word();
22 uint32_t ROD_trailer_size = robFragment->rod_trailer_size_word();
23 uint32_t ROD_version = robFragment->rod_version() >> 16; // extract the upper 16 bits
24 uint32_t ROD_sourceID = robFragment->rod_source_id();
25 uint32_t ROD_nstatus = robFragment->rod_nstatus();
26 uint32_t ROD_ndata = robFragment->rod_ndata();
27 uint32_t ROD_status_pos = robFragment->rod_status_position();
28
29 uint32_t ROD_sourceID_high = ROD_sourceID >> 16; // extract the upper 16 bits
30
31 if (msgLevel(MSG::DEBUG))
32 msg(MSG::DEBUG)
33 << " ROD_run_no: " << std::dec << ROD_run_no << endreq
34 << " ROD_lvl1_id: 0x" << std::hex << ROD_lvl1_id << endreq
35 << " ROD_bc_id: " << std::dec << ROD_bc_id << endreq
36 << " ROD_lvl1_trigger_type: " << std::dec << ROD_lvl1_trigger_type << endreq
37 << " ROD_detev_type: " << std::dec << ROD_detev_type << endreq
38 << " ROD_marker: 0x" << std::hex << ROD_marker << endreq
39 << " ROD_fragment_size: " << std::dec << ROD_fragment_size << endreq
40 << " ROD_header_size: " << std::dec << ROD_header_size << endreq
41 << " ROD_trailer_size: " << std::dec << ROD_trailer_size << endreq
42 << " ROD_version: 0x" << std::hex << ROD_version << endreq
43 << " ROD_source_ID: 0x" << std::hex << ROD_sourceID << endreq
44 << " ROD_nstatus: " << std::dec << ROD_nstatus << endreq
45 << " ROD_ndata: " << std::dec << ROD_ndata << endreq
46 << " ROD_status_pos: " << std::dec << ROD_status_pos << endreq
47 << std::dec;
48
49 // Check for valid marker
50 //
51 if (ROD_marker != ROD_MARKER) {
52 msg(MSG::ERROR) << " ERROR: Invalid ROD_marker " << std::hex << ROD_marker << endreq;
53 return StatusCode::FAILURE;
54 }
55
56 // Check for expected ROD format version
57 //
58 if (ROD_version != m_rodVersion) {
59 msg(MSG::ERROR) << " ERROR: Incorrect ROD_version, expected " << m_rodVersion
60 << ", found " << (ROD_version>>16) << endreq;
61 return StatusCode::FAILURE;
62 }
63
64 // Check for ZDC detector ID in upper bits
65 //
66 if (ROD_sourceID_high != m_sourceIdHigh)
67 {
68 msg(MSG::ERROR) << " ERROR: invalid source ID detector word, " << ROD_sourceID << endreq;
69 return StatusCode::FAILURE;
70 }
71
72 unsigned int nwordsNoTrig = ROD_ndata - 5; // Five words for per-module amplitudes and per-side sums/4
73
74 // There should be 32 words per bunch crossing: 1/2 word for each of eight samples * 8 channels
75 //
76 if (nwordsNoTrig % 32 != 0) {
77 msg(MSG::WARNING) << " WARNING: incorrect number of words in ROD data: " << ROD_ndata << endreq;
78 return StatusCode::FAILURE;
79 }
80
81 unsigned int numBCRead = ROD_ndata/32;
82
83 if (msgLevel(MSG::DEBUG)) msg(MSG::DEBUG) << " Fill ZdcLucrodData, with " << numBCRead << " bunch crossings" << endreq;
84
85 zld->SetBCID (ROD_bc_id);
86 zld->SetRunNumber(ROD_run_no);
87 zld->SetLevel1ID (ROD_lvl1_id);
88 zld->SetNumBCs(numBCRead);
89
92
93 robFragment->rod_data (vintData);
94 robFragment->rod_status(vintStat);
95
96 uint32_t channel = 0xffff;
97 std::vector<uint16_t> waveform;
98
99 uint32_t wordIt=0;
100 uint32_t word =0;
101
102 while (wordIt<ROD_ndata) {
103
104 word = vintData[wordIt]; wordIt++;
105
106 if ((word & 0xf0000000) >> 28 == 0xc) { // start of trigger data
107
108 if (waveform.size()) {
109 if (!zld->AddChanData(channel, waveform)) {
110 msg(MSG::ERROR) << " ERROR: inconsistency in LUCROD data" << endreq;
111 return StatusCode::FAILURE;
112 }
113 }
114 break;
115 }
116
117 // ADCs are all shorts
118 uint16_t adc1 = word & 0xfff;
119 uint16_t adc2 = (word & 0xfff0000) >> 16;
120 uint16_t cid1 = (word & 0x7000) >> 12;
121 uint16_t cid2 = (word & 0x70000000) >> 28;
122
123 if (msgLevel(MSG::DEBUG))
124 msg(MSG::DEBUG)
125 << " adc1: " << adc1
126 << " adc2: " << adc2
127 << " cid1: " << cid1
128 << " cid2: " << cid2
129 << endreq;
130
131 if (cid1 != cid2) return StatusCode::FAILURE;
132
133 if (channel == cid1) {
134
135 waveform.push_back(adc1);
136 waveform.push_back(adc2);
137 }
138 else { // new channel
139 if (waveform.size()) {
140 if (!zld->AddChanData(channel, waveform)) {
141 msg(MSG::ERROR) << " ERROR: inconsistency in LUCROD data" << endreq;
142 return StatusCode::FAILURE;
143 }
144 }
145
146 channel = cid1; // shouldn't this go before the line above?
147
148 waveform.clear();
149 waveform.push_back(adc1);
150 waveform.push_back(adc2);
151 }
152 }
153
154
155 // this can adapt
156 if ((word & 0xf000) >> 12 != 0xa) return StatusCode::FAILURE;
157
158 uint16_t trigAvgA = (word & 0xfff);
159 uint16_t trigAvgC = ((word & 0xfff0000)>>16);
160
161 if (msgLevel(MSG::DEBUG))
162 msg(MSG::DEBUG)
163 << " trigAvgA: " << trigAvgA
164 << " trigAvgC: " << trigAvgC
165 << endreq;
166
167 zld->SetTrigAvgA(trigAvgA);
168 zld->SetTrigAvgC(trigAvgC);
169
170 // Loop over all data words in the fragment
171 //
172 while (wordIt<ROD_ndata) {
173
174 word = vintData[wordIt]; wordIt++;
175
176 if ((word & 0xf0000000) >> 28 != 0xb) return StatusCode::FAILURE;
177
178 uint16_t amp1 = (word & 0xfff); // 12 bit ADC
179 uint16_t amp2 = (word & 0xfff0000)>>16;
180
181 if (msgLevel(MSG::DEBUG))
182 msg(MSG::DEBUG)
183 << " amp1: " << amp1
184 << " amp2: " << amp2
185 << endreq;
186
187 zld->AddTrigData(amp1);
188 zld->AddTrigData(amp2);
189 }
190
191 if (msgLevel(MSG::DEBUG))
192 msg(MSG::DEBUG)
193 << " ChanDataSize: " << zld->GetChanDataSize()
194 << " TrigDataSize: " << zld->GetTrigDataSize()
195 << endreq;
196
197 if (zld->GetChanDataSize() != ROD_NCHANNELS) { if (msgLevel(MSG::DEBUG)) msg(MSG::DEBUG) << " ERROR: ChanDataSize " << endreq; return StatusCode::FAILURE; }
198 if (zld->GetTrigDataSize() != ROD_NCHANNELS) { if (msgLevel(MSG::DEBUG)) msg(MSG::DEBUG) << " ERROR: TrigDataSize " << endreq; return StatusCode::FAILURE; }
199
200 zld->SetStatus(vintStat[0]);
201
202 return StatusCode::SUCCESS;
203}
#define endreq
MsgStream & msg() const
The standard message stream.
void SetStatus(unsigned int val)
unsigned int GetChanDataSize() const
void SetTrigAvgA(uint16_t val)
bool AddChanData(unsigned int id, const std::vector< uint16_t > &waveform)
unsigned int GetTrigDataSize() const
void AddTrigData(uint16_t val)
void SetLevel1ID(unsigned int val)
void SetRunNumber(unsigned int val)
void SetNumBCs(unsigned int val)
void SetBCID(unsigned int val)
void SetTrigAvgC(uint16_t val)
unsigned short m_rodVersion
bool msgLevel(MSG::Level lvl) const
unsigned short m_sourceIdHigh
StatusCode decode(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment *robFragment, ZdcLucrodData *zld)
const DataType * PointerType
Definition RawEvent.h:25
eformat::ROBFragment< PointerType > ROBFragment
Definition RawEvent.h:27