ATLAS Offline Software
Loading...
Searching...
No Matches
LArRodBlockTransparentV0.icc
Go to the documentation of this file.
1//Dear emacs, this is -*- c++ -*-
2
3/*
4 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
5*/
6
7// Implementation of a LArRODBlockStructure class
8// This version contains LArDigits in fixed gain.
9// See .h file for more details.
10
11#include "AthenaKernel/getMessageSvc.h"
12#include <iostream>
13
14//#define LARBSDBGOUTPUT
15#ifdef LARBSDBGOUTPUT
16#define LARBSDBG(text) logstr<<MSG::DEBUG<<text<<endmsg
17#else
18#define LARBSDBG(text)
19#endif
20
21template<class DSPHEADER>
22LArRodBlockTransparentV0<DSPHEADER>::LArRodBlockTransparentV0() : LArRodBlockStructure()
23{ m_iHeadBlockSize=DSPHEADER::endtag/2; // The implicit cast rounds down to the right size
24 //Fill array of offset to enable for-loops
25 m_BlkOffset=DSPHEADER::RawDataBlkOffset; //RawDataOffset
26 m_fixedGain=CaloGain::LARNGAIN;
27 LArRodBlockTransparentV0::resetPointers();
28}
29
30// clear temporary block vectors
31template<class DSPHEADER>
32void LArRodBlockTransparentV0<DSPHEADER>::clearBlocks()
33{
34 m_RawDataBlock.clear();
35}
36
37template<class DSPHEADER>
38void LArRodBlockTransparentV0<DSPHEADER>::resetPointers()
39{
40 m_RawDataCounter=0;
41 m_RawDataIndex=0;
42}
43
44template<class DSPHEADER>
45void LArRodBlockTransparentV0<DSPHEADER>::setNumberOfSamples(const uint8_t n)
46{ uint16_t value=getVectorHeader16(DSPHEADER::NSamples);
47 setHeader16(DSPHEADER::NSamples, (value & 0xff00) | n);
48}
49
50template<class DSPHEADER>
51void LArRodBlockTransparentV0<DSPHEADER>::setTDCPhase(const uint8_t n)
52{ uint16_t value=getVectorHeader16(DSPHEADER::NSamples);
53 setHeader16(DSPHEADER::NSamples, (value & 0xff) | ((uint16_t) n<<8));
54}
55
56template<class DSPHEADER>
57uint8_t LArRodBlockTransparentV0<DSPHEADER>::getTDCPhase() const
58{
59 return (getHeader16(DSPHEADER::NSamples)>>8);
60}
61
62
63
64
65template<class DSPHEADER>
66void LArRodBlockTransparentV0<DSPHEADER>::setNumberOfGains(const uint8_t n)
67{
68 setHeader16(DSPHEADER::NGains,n);
69}
70
71template<class DSPHEADER>
72void
73LArRodBlockTransparentV0<DSPHEADER>::initializeFragment(std::vector<uint32_t>& fragment)
74{MsgStream logstr(Athena::getMessageSvc(), BlockType());
75 m_pRODblock=&fragment; //remember pointer to fragment
76 if (fragment.size()>m_iHeadBlockSize) { //Got filled fragment
77 unsigned int sizeRead=0;
78 //Store existing data in the FEB-Map
79 while (sizeRead<fragment.size()) {
80 std::vector<uint32_t>::iterator FebIter;
81 FebIter=fragment.begin()+sizeRead; //Store pointer to current Feb-Header
82 m_FebBlock=&(*FebIter); //Set m_FebBlock in order to use getHeader-functions.
83 uint32_t currFEBid=getHeader32(DSPHEADER::FEBID); //Get this FEB-ID
84 uint16_t currFebSize=getHeader32(DSPHEADER::NWTot); //Size of this FEB-Block
85 if (FebIter+currFebSize>fragment.end()) {
86 fragment.clear(); //Clear existing vector
87 logstr << MSG::ERROR << "initializeFragment: Got inconsistent ROD-Fragment!" << endmsg;
88 return;
89 }
90 m_mFebBlocks[currFEBid].assign(FebIter,FebIter+currFebSize); //Copy data from ROD-fragment into FEB-Block
91 sizeRead+=currFebSize+m_MiddleHeaderSize;
92 LARBSDBG("Found FEB-id "<< currFEBid << "in existing ROD-Fragment");
93 } // end while
94 }
95 fragment.clear(); //Clear existing vector
96 return;
97}
98
99template<class DSPHEADER>
100void LArRodBlockTransparentV0<DSPHEADER>::initializeFEB(const uint32_t id)
101{m_vFragment=&(m_mFebBlocks[id]);
102 //m_FebHeaderIter=m_vFragment->begin();
103 if (m_vFragment->size()<m_iHeadBlockSize) //Got empty or spoiled fragment
104 {m_vFragment->resize(m_iHeadBlockSize,0); //Initialize FEB-Header
105 setHeader32(DSPHEADER::FEBID,id); //Set Feb ID
106 }
107}
108
109template<class DSPHEADER>
110void LArRodBlockTransparentV0<DSPHEADER>::setRawDataFixed(const int channel, const std::vector<short>& samples, const uint32_t gain)
111{
112 MsgStream logstr(Athena::getMessageSvc(), BlockType());
113 if (channel>=m_channelsPerFEB) {
114 logstr << MSG::ERROR << "Attempt to write Raw Data for channel "<< channel << endmsg;
115 return; //Return error
116 }
117 // Expected Gain values:
118 //0..high gain
119 //1..medium gain
120 //2..low gain
121 if (gain>2)
122 {logstr << MSG::ERROR << "Attempt to write raw data with gain "<< gain << endmsg;
123 return;
124 }
125 unsigned int nsamples = getVectorHeader16(DSPHEADER::NSamples) & 0xff;
126 LARBSDBG("Nsamples= " << nsamples);
127 if(samples.size() != nsamples) {
128 logstr << MSG::ERROR << "Number of samples mismatch!\n";
129 logstr << " nsamples =" << nsamples;
130 logstr << " samples.size() =" << samples.size() << endmsg;
131 std::abort();
132 }
133 //std::cout << "Size of Raw Data block # " << febgain << " = " << m_RawDataBlock.size();
134
135 // m_RawDataBlock
136
137
138 // Save data as is, we will arrange it later...
139 m_RawDataBlock.push_back(channel);
140 if(channel>=64) { // high channel number on lower 16 bits
141 m_RawDataBlock.push_back(OfflineToRawGain(gain)<<12);
142 for (unsigned int i=0;i<nsamples;i++)
143 m_RawDataBlock.push_back(samples[i]&0xffff);
144 } else { //low channel number
145 m_RawDataBlock.push_back(OfflineToRawGain(gain)<<28);
146 for (unsigned int i=0;i<nsamples;i++)
147 m_RawDataBlock.push_back(samples[i]<<16);
148 }
149}
150
151template<class DSPHEADER>
152void LArRodBlockTransparentV0<DSPHEADER>::finalizeFEB()
153{
154#ifdef LARBSDBGOUTPUT
155 MsgStream logstr(Athena::getMessageSvc(), BlockType());
156#endif
157
158 uint16_t nsamples = getVectorHeader16(DSPHEADER::NSamples) & 0xff;
159 uint16_t ngains = 1;
160 uint16_t size = 0;
161 uint16_t s_size = 0;
162
163 // Set fragment size to FEB raw data + header
164 s_size = 8 + 64 * ngains; // Size of one sample block 16 RADD of 16 bit + 128 channels (16 bit data)
165 size = m_iHeadBlockSize + nsamples*s_size; // Total fragment size;
166
167 //m_vFragment->resize( m_iHeadBlockSize);
168 m_vFragment->resize(size,0);
169
170 LARBSDBG("Size of block (in 32bit words) = " << size);
171 // Now fill the RADD structures
172 for(int i=0; i<nsamples;i++) {
173 uint32_t offset = (m_iHeadBlockSize + i*s_size);
174 for(int j=0;j<8;j++) {
175 // Put a dummy code for RADDs (A | adc nb | sample nb)
176 uint32_t index = offset+j;
177 (*m_vFragment)[index] = 0xA000A000 | ((2*j)<<24) | (i << 16) | ((2*j+1)<<8) | i;
178 }
179 }
180 // And now the data itself
181 for (int igain=0;igain<ngains;igain++) {
182 int n = m_RawDataBlock.size();
183 for(int j=0; j<n;j+=nsamples+2) {
184 uint32_t ichannel = m_RawDataBlock[j];
185 uint32_t febgain = m_RawDataBlock[j+1];
186 uint32_t offset;
187 offset=m_iHeadBlockSize + 8 + ((ichannel&0x3F)>>3) + ((ichannel& 0x7)<<3) + 64*igain;
188 LARBSDBG("Processing channel #" << ichannel << ".Writing samples to offset " << offset);
189 for (int s=0;s<nsamples;s++) {
190 // samples are already on the right higher/lower bits of the 32 bit word
191 uint32_t index = offset + s*s_size;
192 uint32_t feb_data = (*m_vFragment)[index];
193 uint32_t sample = m_RawDataBlock[j+2+s];
194 feb_data = feb_data | sample | febgain;
195 (*m_vFragment)[index] = feb_data;
196 }
197 }
198 }
199 // Set header words
200 LARBSDBG("FINAL Nsamples= " << nsamples);
201 //setHeader16(DSPHEADER::NSamples,nsamples);
202 //setNumberOfSamples(nsamples);
203 setHeader16(DSPHEADER::NGains,ngains);
204 setHeader32(DSPHEADER::RawDataBlkOffset, m_iHeadBlockSize);
205 setHeader32(DSPHEADER::NWTot,m_vFragment->size());
206 // clear memory
207 clearBlocks();
208 return;
209}
210
211template<class DSPHEADER>
212void LArRodBlockTransparentV0<DSPHEADER>::concatinateFEBs( )
213{
214 // std::cout << "Concatinating FEBs. Have "<< m_mFebBlocks.size() <<" febs." << std::endl;
215 FEBMAPTYPE::const_iterator feb_it_b=m_mFebBlocks.begin();
216 FEBMAPTYPE::const_iterator feb_it_e=m_mFebBlocks.end();
217 FEBMAPTYPE::const_iterator feb_it;
218 for (feb_it=feb_it_b;feb_it!=feb_it_e;++feb_it) {
219 if (feb_it!=feb_it_b) //Not first Feb
220/*
221 if (fullHeader) {//Add middle header
222 m_pRODblock->push_back(fullHeader->version().full());//Format Version number
223 m_pRODblock->push_back(fullHeader->source_id()); //Source identifer
224 m_pRODblock->push_back(fullHeader->run_no());
225 m_pRODblock->push_back(fullHeader->lvl1_id()); //Level 1 identifer
226 m_pRODblock->push_back(fullHeader->bc_id()); //Bunch Crossing identifer
227 m_pRODblock->push_back(fullHeader->lvl1_type()); //Level 1 trigger type
228 m_pRODblock->push_back(fullHeader->detev_type()); //Detector event type
229 }
230 else //No ROD-Header
231*/
232 m_pRODblock->resize( m_pRODblock->size()+m_MiddleHeaderSize);
233
234 //Add feb data to rod data block
235 for (uint32_t data : feb_it->second)
236 m_pRODblock->push_back(data);
237 } //end for feb_it
238
239 m_mFebBlocks.clear();
240 return;
241}
242
243template<class DSPHEADER>
244int LArRodBlockTransparentV0<DSPHEADER>::getNextRawData(int& channelNumber, std::vector<short>& samples, uint32_t& gain)
245{
246#ifdef LARBSDBGOUTPUT
247 MsgStream logstr(Athena::getMessageSvc(), BlockType());
248#endif
249 //Debug output
250 LARBSDBG("GetNextRawData for FEB 0x" << MSG::hex << (uint32_t)getHeader32(DSPHEADER::FEBID) << MSG::dec);
251 LARBSDBG("m_RawDataCounter=" << m_RawDataCounter << " m_RawDataIndex="<< m_RawDataIndex
252 << " m_channelsPerFEB=" << m_channelsPerFEB);
253 LARBSDBG("requested gain= " << m_fixedGain);
254 if (m_RawDataCounter>=m_channelsPerFEB) { //Already beyond maximal number of channels
255 LARBSDBG("Maximum number of channels reached");
256 return 0;
257 }
258 const uint16_t block = getHeader32(m_BlkOffset);//Position of the raw FEB data block
259 if (!block) { //Block does not exist
260 LARBSDBG("No Raw Data Block in this FEB");
261 return 0;
262 }
263 //The m_RawDataChannel keeps track of the last read channel
264 //std::cout << "endtag=" << DSPHEADER::endtag << " m_iHeadBlockSize=" << m_iHeadBlockSize << std::endl;
265
266 // Get next channel
267 channelNumber=m_RawDataCounter;
268 uint32_t febgain;
269 const unsigned int nsamples = getHeader16(DSPHEADER::NSamples) & 0xff;
270 const unsigned int ngains = getHeader16(DSPHEADER::NGains);
271 LARBSDBG("This FEB has " << nsamples << " samples");
272 LARBSDBG("This FEB has " << ngains << " gains");
273 if(ngains==0 || nsamples==0) return 0;
274 // Loop over gains to look for m_fixedGain
275 unsigned int this_gain=0;
276 int offset;
277 if (m_fixedGain!=CaloGain::LARNGAIN) { //Fixed gain: Search for gain
278 offset=block + 8 + ((channelNumber&0x3F)>>3) + ((channelNumber & 0x7)<<3);
279 for(this_gain=0;this_gain<ngains;this_gain++) {
280 int index = offset + 64*this_gain;
281 uint32_t x = m_FebBlock[index];
282 if(channelNumber>=64)
283 x = (x & 0x3000) >> 12;
284 else
285 x = (x & 0x30000000) >> 28;
286 int data_gain = RawToOfflineGain(x);
287 if(data_gain==m_fixedGain) break;
288 }
289 }
290 if (this_gain<ngains) { //Gain found in this fragment
291 int s_size = 8 + 64 * ngains; // Size of one sample block 16 RADD of 16 bit + 128 channels (16 bit data)
292 offset = block + 8 + ((channelNumber&0x3F)>>3) + ((channelNumber & 0x7)<<3) + 64*this_gain;
293 int index = offset;
294 uint32_t x = m_FebBlock[index];
295 if(channelNumber>=64) { //low channels on lower bits
296 // First decode gain
297 febgain = (x & 0x3000) >> 12; // gain on bits 12 and 13
298 // Than samples
299 for(unsigned int s=0;s<nsamples;s++) {
300 index = offset + s*s_size;
301 x = m_FebBlock[index];
302 samples.push_back((short) (x & 0x0fff)); // sample on bits 0 to 11
303 }
304 } else { //high channels on higher bits
305 // First decode gain
306 febgain = (x & 0x30000000) >> 28; // gain on bits 12 and 13
307 // Than samples
308 for(unsigned int s=0;s<nsamples;s++) {
309 index = offset + s*s_size;
310 x = (m_FebBlock[index]) >> 16;
311 samples.push_back((short) (x & 0x0fff)); // sample on bits 0 to 11
312 }
313 }
314 gain=RawToOfflineGain(febgain);
315 }
316 //std::cout << "Gain= " << gain << " Febgain=" << febgain << std::endl;
317 ++m_RawDataCounter;
318 if (m_rearrangeFirstSample && m_rearrangeFirstSample<samples.size()) //FIXME: Very ugly hack! See explanation in LArRodDecoder.h file
319 {//Change e.g. 3 0 1 2 4 to 0 1 2 3 4
320 short movedSample=samples[0];
321 for (unsigned i=1;i<=m_rearrangeFirstSample;i++)
322 samples[i-1]=samples[i];
323 samples[m_rearrangeFirstSample]=movedSample;
324 }
325 return 1;
326}
327
328template<class DSPHEADER>
329uint32_t LArRodBlockTransparentV0<DSPHEADER>::getNumberOfSamples() const
330{
331 return getHeader16(DSPHEADER::NSamples);
332}
333
334template<class DSPHEADER>
335uint32_t LArRodBlockTransparentV0<DSPHEADER>::getNumberOfGains() const
336{
337 return getHeader16(DSPHEADER::NGains);
338}
339
340template<class DSPHEADER>
341uint32_t LArRodBlockTransparentV0<DSPHEADER>::getRadd(uint32_t adc, uint32_t sample) const
342{
343 int ngain=getHeader16(DSPHEADER::NGains);
344 int index=getHeader32(m_BlkOffset);
345 index+=(8+64*ngain)*sample+adc/2;
346 uint32_t x=m_FebBlock[index];
347 if(adc&0x1) return x>>16;
348 return x&0xffff;
349}
350
351template<class DSPHEADER>
352uint16_t LArRodBlockTransparentV0<DSPHEADER>::getCtrl1(uint32_t adc) const
353{
354 int index=getHeader32(m_BlkOffset)-16+adc/2;
355 uint32_t x=m_FebBlock[index];
356 if(adc&0x1) x=x>>16;
357 else x=x&0xffff;
358 uint16_t ctrl=x;
359 return ctrl;
360}
361
362template<class DSPHEADER>
363uint16_t LArRodBlockTransparentV0<DSPHEADER>::getCtrl2(uint32_t adc) const
364{
365 int index=getHeader32(m_BlkOffset)-8+adc/2;
366 uint32_t x=m_FebBlock[index];
367 if(adc&0x1) x=x>>16;
368 else x=x&0xffff;
369 uint16_t ctrl=x;
370 return ctrl;
371}
372
373template<class DSPHEADER>
374uint16_t LArRodBlockTransparentV0<DSPHEADER>::getCtrl3(uint32_t adc) const
375{
376 int nsamples = getHeader16(DSPHEADER::NSamples);
377 int ngains = getHeader16(DSPHEADER::NGains);
378 int offset=nsamples*(8+64*ngains)+adc/2;
379 int index=getHeader32(m_BlkOffset)+offset;
380 uint32_t x=m_FebBlock[index];
381 if(adc&0x1) x=x>>16;
382 else x=x&0xffff;
383 uint16_t ctrl=x;
384 return ctrl;
385}
386
387template<class DSPHEADER>
388uint32_t LArRodBlockTransparentV0<DSPHEADER>::getStatus() const
389{
390 int nsamples = getHeader16(DSPHEADER::NSamples);
391 int ngains = getHeader16(DSPHEADER::NGains);
392 int offset=nsamples*(8+64*ngains)+8;
393 int index=getHeader32(m_BlkOffset)+offset;
394 uint32_t x=m_FebBlock[index];
395 return x;
396}
397
398
399#ifdef LARBSDBGOUTPUT
400#undef LARBSDBGOUTPUT
401#endif
402#undef LARBSDBG