ATLAS Offline Software
Loading...
Searching...
No Matches
LArRodBlockPhysicsV5.cxx
Go to the documentation of this file.
1//Dear emacs, this is -*- c++ -*-
2
3/*
4 Copyright (C) 2002-2026 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 "GaudiKernel/MsgStream.h"
16#include "GaudiKernel/Bootstrap.h"
17#include "GaudiKernel/ISvcLocator.h"
18#include <iostream>
19
20
21
22
25 m_onlineHelper(nullptr)
26{
27 m_iHeadBlockSize=endtag/2; // The implicit cast rounds down to the right size
33 m_OffTimeCut=0; //FIXME: Nowhere set to a sensible value ???
35 // retrieve onlineHelper
36 SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service("DetectorStore")};
37 if (!detStore) {
38 m_logstr << MSG::ERROR << "Unable to locate DetectorStore" << endmsg;
39 std::abort();
40 }
41 StatusCode sc = detStore->retrieve(m_onlineHelper, "LArOnlineID");
42 if (sc.isFailure()) {
43 m_logstr << MSG::ERROR << "Could not get LArOnlineID helper !" << endmsg;
44 std::abort();
45 }
46}
47
48
68
70{
72 {
73 int off = -8;
74 int ns = getHeader16(NSamples) & 0xff;
75 if (m_requiredNSamples > 0 && m_requiredNSamples != ns) return false;
76 int radd = (ns+1)/2;
77 int dim1 = getHeader16(ResultsDim1);
78 int off1 = getHeader16(ResultsOff1);
79 int off2 = getHeader16(ResultsOff2);
80 int dim2 = getHeader16(ResultsDim2);
81 int off3 = getHeader16(RawDataBlkOff);
82 int dim3 = getHeader16(RawDataBlkDim);
83
84 if (off1 && dim1+off1+off<m_FebBlockSize) {
85 off1 += off;
86 if (dim1>=8)
87 m_GainPointer=reinterpret_cast<const uint32_t*>(m_FebBlock+off1);
88 if (dim1>=12)
89 m_MaskTimeQualityPointer=reinterpret_cast<const uint32_t*>(m_FebBlock+off1+8);
90 if (dim1>=16)
91 m_MaskDigitsPointer=reinterpret_cast<const uint32_t*>(m_FebBlock+off1+12);
92 if (dim1>=16+radd)
93 m_RaddPointer=reinterpret_cast<const uint16_t*>(m_FebBlock+off1+16);
94 if (dim1>=80+radd)
95 m_EnergyPointer=reinterpret_cast<const uint16_t*> (m_FebBlock+off1+16+radd);
96 if (dim1>=83+radd)
97 m_SumPointer=reinterpret_cast<const int32_t*>(m_FebBlock+off1+80+radd);
98 if (dim1>83+radd)
99 m_TimeQualityPointer=reinterpret_cast<const uint16_t*>(m_FebBlock+off1+83+radd);
100 off1 -= off;
101 }
102 if (off2 && dim2+off2+off<m_FebBlockSize) {
103 m_DigitsPointer=reinterpret_cast<const uint16_t*>(m_FebBlock+off2+off);
104 }
105 if (off3 && dim3+off3+off<m_FebBlockSize) {
106 m_RawDataPointer=reinterpret_cast<const uint16_t*>(m_FebBlock+off3+off);
107 }
108
109 // Check for offsets problems
110 uint32_t problem = 0;
111 int n1, n2;
112 int n1_tmp, n2_tmp;
113 int off1_tmp, dim1_tmp;
114 int off2_tmp, dim2_tmp;
115 int off3_tmp, dim3_tmp;
116 if(off1==0) {
117 n1 = n2 = 0;
118 n1_tmp = n2_tmp =0;
119 off1_tmp = dim1_tmp = 0;
120 off2_tmp = dim2_tmp = 0;
121 off3_tmp = dim3_tmp = 0;
122 }
123 else {
124 m_RaddPointer=reinterpret_cast<const uint16_t*>(m_FebBlock+26);
125 m_MaskTimeQualityPointer=reinterpret_cast<const uint32_t*>(m_FebBlock+18);
126 m_MaskDigitsPointer=reinterpret_cast<const uint32_t*>(m_FebBlock+22);
127 n1 = getNbSweetCells1();
128 n2 = getNbSweetCells2();
129 n1_tmp = getNbSweetCells1FromMask();
130 n2_tmp = getNbSweetCells2FromMask();
131 off1_tmp = 10-off;
132 dim1_tmp = 83+(ns+1)/2+n1;
133 if ( m_requiredNSamples > 0 )
134 dim1_tmp = 83 +(m_requiredNSamples+1)/2+n1;
135 off2_tmp = off1_tmp+dim1_tmp;
136 dim2_tmp = (n2*ns+1)/2;
137 off3_tmp = off2_tmp+dim2_tmp;
138 dim3_tmp = getNumberOfWords()-3-off3_tmp-off;
139 if(dim2_tmp==0) off2_tmp = 0;
140 if(dim3_tmp==0) off3_tmp = 0;
141 }
142
143 if(off1 != off1_tmp) problem=1;
144 if(dim1 != dim1_tmp) problem=2;
145 if(off2 != off2_tmp) problem=3;
146 if(dim2 != dim2_tmp) problem=4;
147 if(off3 != off3_tmp) problem=5;
148 if(dim3 != dim3_tmp) problem=6;
149 if(n1 != n1_tmp) problem=7;
150 if(n2 != n2_tmp) problem=8;
151 if (m_requiredNSamples > 0 &&
152 getHeader32(NGains) != (uint32_t)0x10000 + m_requiredNSamples) problem=9;
153 if(problem) { // Try to recompute offsets
154 m_logstr << MSG::ERROR << "LArByteStreamProblem " << problem << endmsg;
155 m_logstr << MSG::ERROR << "NSamples = " << std::dec << ns << endmsg;
156 m_logstr << MSG::ERROR << "getHeader32(NGains) = " << std::hex << getHeader32(NGains) << endmsg;
157 m_logstr << MSG::ERROR << "NWTot: " << std::hex << getNumberOfWords() << " n1=" << n1 << " (" << n1_tmp << ") n2=" << n2 << " (" << n2_tmp << ")" << endmsg;
158 m_logstr << MSG::ERROR << "Found 1: " << off1 << " " << dim1 << endmsg;
159 m_logstr << MSG::ERROR << "Found 2: " << off2 << " " << dim2 << endmsg;
160 m_logstr << MSG::ERROR << "Found 3: " << off3 << " " << dim3 << std::dec << endmsg;
161
162 if(n1==n1_tmp && n2==n2_tmp) { // Check consistency of cells above threshold
163 off1 = off1_tmp;
164 dim1 = dim1_tmp;
165 off2 = off2_tmp;
166 dim2 = dim2_tmp;
167 off3 = off3_tmp;
168 dim3 = dim3_tmp;
169 m_logstr << MSG::ERROR << "Recomputed 1: " << std::hex << off1 << " " << dim1 << endmsg;
170 m_logstr << MSG::ERROR << "Recomputed 2: " << off2 << " " << dim2 << endmsg;
171 m_logstr << MSG::ERROR << "Recomputed 3: " << off3 << " " << dim3 << std::dec << endmsg;
172
173 if (off1 && dim1+off1+off<m_FebBlockSize) {
174 off1 += off;
175 if (dim1>=8)
176 m_GainPointer=reinterpret_cast<const uint32_t*>(m_FebBlock+off1);
177 if (dim1>=12)
178 m_MaskTimeQualityPointer=reinterpret_cast<const uint32_t*>(m_FebBlock+off1+8);
179 if (dim1>=16)
180 m_MaskDigitsPointer=reinterpret_cast<const uint32_t*>(m_FebBlock+off1+12);
181 if (dim1>=16+radd)
182 m_RaddPointer=reinterpret_cast<const uint16_t*>(m_FebBlock+off1+16);
183 if (dim1>=80+radd)
184 m_EnergyPointer=reinterpret_cast<const uint16_t*> (m_FebBlock+off1+16+radd);
185 if (dim1>=83+radd)
186 m_SumPointer=reinterpret_cast<const int32_t*>(m_FebBlock+off1+80+radd);
187 if (dim1>83+radd)
188 m_TimeQualityPointer=reinterpret_cast<const uint16_t*>(m_FebBlock+off1+83+radd);
189 }
190 if (off2 && dim2+off2+off<m_FebBlockSize) {
191 m_DigitsPointer=reinterpret_cast<const uint16_t*>(m_FebBlock+off2+off);
192 }
193 if (off3 && dim3+off3+off<m_FebBlockSize) {
194 m_RawDataPointer=reinterpret_cast<const uint16_t*>(m_FebBlock+off3+off);
195 }
196 }
197 }
198
199 problem=0;
200 // Recheck offsets
201 if(off1< off2 && off1 + dim1 > off2) problem = 1;
202 if(off1< off3 && off1 + dim1 > off3) problem = 2;
203 if(off2< off1 && off2 + dim2 > off1) problem = 3;
204 if(off2< off3 && off2 + dim2 > off3) problem = 4;
205 if(off3< off1 && off3 + dim3 > off1) problem = 5;
206 if(off3< off2 && off3 + dim3 > off2) problem = 6;
207
208 if(problem) {
210 m_logstr << MSG::ERROR << "LArByteStreamProblem " << problem << endmsg;
211 m_logstr << MSG::ERROR << "Unrecoverable problem" << endmsg;
212 }
213 }
214
215 return true;
216}
217
218int LArRodBlockPhysicsV5::getNextRawData(int& channelNumber, std::vector<short>& samples, uint32_t& gain)
219{
220#ifdef LARBSDBGOUTPUT
221 //Debug output
222 m_logstr << MSG::DEBUG << "Let s go in getNextRawData..." << endmsg;
223 m_logstr << MSG::DEBUG << "GetNextRawData for FEB 0x" << MSG::hex << (uint32_t)getHeader32(FEBID) << MSG::dec << endmsg;
224 m_logstr << MSG::DEBUG << "m_RawDataPointer=" << m_RawDataPointer << " m_RawDataIndex="<< m_RawDataIndex
225 << " m_channelsPerFEB=" << m_channelsPerFEB << endmsg;
226#endif
227
228 if (m_RawDataIndex>=m_channelsPerFEB) { //Already beyond maximal number of channels
229#ifdef LARBSDBGOUTPUT
230 m_logstr << MSG::DEBUG << "Maximum number of channels reached" << endmsg;
231#endif
232 return 0;
233 }
234 if (!m_RawDataPointer) { //Block does not exist
235 // Try to get samples and gain from getNextDigits
236 return getNextDigits(channelNumber,samples,gain);
237 }
238
239 // Get next channel
240 unsigned rodChannelNumber=m_RawDataIndex; // Index of Channel in ROD-Block
241 channelNumber=((rodChannelNumber&0xe)<<2) + ((rodChannelNumber&0x1)<<6) + (rodChannelNumber>>4); //channel number of the FEB
242 uint32_t febgain;
243 const unsigned int nsamples = getHeader16(NSamples) & 0xff;
244 const unsigned int ngains = getHeader16(NGains);
245
246#ifdef LARBSDBGOUTPUT
247 m_logstr << MSG::DEBUG << "This FEB has " << nsamples << " samples" << endmsg;
248 m_logstr << MSG::DEBUG << "This FEB has " << ngains << " gains" << endmsg;
249#endif
250
251 if(ngains==0 || nsamples==0) return 0;
252 int s_size = nsamples+1;
253 int offset = (10+nsamples)&0xfffc;
254 int index;
255 index = s_size*m_RawDataIndex + offset;
256 uint16_t s[2];
257 if((nsamples+1)&0x7) {
258 s[0] = m_RawDataPointer[index++]>>2;
259 febgain = m_RawDataPointer[index++];
260 samples.push_back(s[0]);
261 for(unsigned int i=0;i<nsamples/2;i++) {
262 s[1] = m_RawDataPointer[index++]>>2;
263 s[0] = m_RawDataPointer[index++]>>2;
264 samples.push_back(s[0]);
265 samples.push_back(s[1]);
266 }
267 } // End of check for 5 samples
268 else {
269 if (!(m_RawDataIndex%2)) {
270 s[0] = m_RawDataPointer[index++]>>2;
271 febgain = m_RawDataPointer[index++];
272 samples.push_back(s[0]);
273 for(unsigned int i=0;i<nsamples/2;i++) {
274 s[1] = m_RawDataPointer[index++]>>2;
275 s[0] = m_RawDataPointer[index++]>>2;
276 samples.push_back(s[0]);
277 samples.push_back(s[1]);
278 }
279 } else {
280 for(unsigned int i=0;i<nsamples/2;i++) {
281 s[1] = m_RawDataPointer[index++]>>2;
282 s[0] = m_RawDataPointer[index++]>>2;
283 samples.push_back(s[0]);
284 samples.push_back(s[1]);
285 }
286 febgain = m_RawDataPointer[index++];
287 s[0] = m_RawDataPointer[index++]>>2;
288 samples.push_back(s[0]);
289 }
290 } // End of >5 check
291 gain=RawToOfflineGain(febgain);
292
293#ifdef LARBSDBGOUTPUT
294 m_logstr << MSG::DEBUG << " ===> ROD Channel = " << m_RawDataIndex << endmsg;
295 m_logstr << MSG::DEBUG << " ===> FEB Channel = " << channelNumber << endmsg;
296 m_logstr << MSG::DEBUG << " ===> Gain = " << gain << endmsg;
297 for(int i=0;i<nsamples;i++)
298 m_logstr << MSG::DEBUG << " ===> sample " << i << " = " << samples[i] << endmsg;
299 int n = m_RawDataIndex;
300 int32_t e,t,q;
301 uint32_t g;
303#endif
305 unsigned rearrangeFirstSample=0;
307 rearrangeFirstSample=m_rearrangeFirstSample; //Overwrite by jobOptions
308 else
309 rearrangeFirstSample=getFirstSampleIndex();
310 if (rearrangeFirstSample && rearrangeFirstSample<samples.size()) //FIXME: Very ugly hack! See explanation in LArRodDecoder.h file
311 {//Change e.g. 3 0 1 2 4 to 0 1 2 3 4
312 short movedSample=samples[0];
313 for (unsigned i=1;i<=rearrangeFirstSample;i++)
314 samples[i-1]=samples[i];
315 samples[rearrangeFirstSample]=movedSample;
316 }
317#ifdef LARBSDBGOUTPUT
318 m_logstr << MSG::DEBUG << "GetNextRawData for FEB finished 0x" << MSG::hex << (uint32_t)getHeader32(FEBID) << MSG::dec << endmsg;
319#endif
320 return 1;
321}
322
323int LArRodBlockPhysicsV5::getNextDigits(int& channelNumber, std::vector<short>& samples, uint32_t& gain)
324{
325#ifdef LARBSDBGOUTPUT
326 //Debug output
327 m_logstr << MSG::DEBUG << "Let s go in getNextDigits..." << endmsg;
328 m_logstr << MSG::DEBUG << "GetNextDigits for FEB 0x" << MSG::hex << (uint32_t)getHeader32(FEBID) << MSG::dec << endmsg;
329 m_logstr << MSG::DEBUG << "m_DigitsPointer=" << m_DigitsPointer << " m_DigitsIndex="<< m_DigitsIndex
330 << " m_DigitsChannel="<< m_DigitsChannel
331 << " m_channelsPerFEB=" << m_channelsPerFEB << endmsg;
332#endif
333
334 if (m_DigitsChannel>=m_channelsPerFEB) { //Already beyond maximal number of channels
335#ifdef LARBSDBGOUTPUT
336 m_logstr << MSG::DEBUG << "Maximum number of channels reached" << endmsg;
337#endif
338 return 0;
339 }
340 if (!m_DigitsPointer) { //Block does not exist
341#ifdef LARBSDBGOUTPUT
342 m_logstr << MSG::DEBUG << "No Digits Block in this FEB" << endmsg;
343#endif
344 return 0;
345 }
346 if (!m_MaskDigitsPointer) { //Block does not exist
347#ifdef LARBSDBGOUTPUT
348 m_logstr << MSG::DEBUG << "No Mask Digits Block in this FEB" << endmsg;
349#endif
350 return 0;
351 }
352
353 // Get Digits if the information is present according to summary block
354 uint32_t hasDigits;
355
356 hasDigits = (uint32_t) ((m_MaskDigitsPointer[m_DigitsChannel>>5] >> (m_DigitsChannel&0x1f)) &0x1);
357 // Increment channel number until digits are found
358 while(hasDigits==0) {
360 if (m_DigitsChannel>=m_channelsPerFEB) { //Already beyond maximal number of channels
361#ifdef LARBSDBGOUTPUT
362 m_logstr << MSG::DEBUG << "Maximum number of channels reached" << endmsg;
363#endif
364 return 0;
365 }
366 hasDigits = (uint32_t) ((m_MaskDigitsPointer[m_DigitsChannel>>5] >> (m_DigitsChannel&0x1f)) &0x1);
367 }
368
369 // Get next channel
370 unsigned rodChannelNumber=m_DigitsChannel; // Index of Channel in ROD-Block
371 channelNumber=((rodChannelNumber&0xe)<<2) + ((rodChannelNumber&0x1)<<6) + (rodChannelNumber>>4); //channel number of the FEB
372 const unsigned int nsamples = getHeader16(NSamples) & 0xff;
373
374 // gain in 2 bits of a 32 bits word
375 if(m_GainPointer) {
376 gain = (uint32_t) ((m_GainPointer[m_DigitsChannel>>4] >> (m_DigitsChannel&0xf)*2) & 0x3);
377 gain=RawToOfflineGain(gain);
378 } else gain=0xffffffff;
379
380#ifdef LARBSDBGOUTPUT
381 m_logstr << MSG::DEBUG << "This FEB has " << nsamples << " samples" << endmsg;
382#endif
383
384 if(nsamples==0) return 0;
385 int s_size = nsamples;
386 int index;
387 index = s_size*m_DigitsIndex;
388 if(m_DigitsIndex&0x1) {
389 samples.push_back(m_DigitsPointer[index-1]>>2);
390 samples.push_back(m_DigitsPointer[index+2]>>2);
391 samples.push_back(m_DigitsPointer[index+1]>>2);
392 samples.push_back(m_DigitsPointer[index+4]>>2);
393 samples.push_back(m_DigitsPointer[index+3]>>2);
394 if(nsamples==7) {
395 samples.push_back(m_DigitsPointer[index+6]>>2);
396 samples.push_back(m_DigitsPointer[index+5]>>2);
397 }
398 } else {
399 samples.push_back(m_DigitsPointer[index+1]>>2);
400 samples.push_back(m_DigitsPointer[index+0]>>2);
401 samples.push_back(m_DigitsPointer[index+3]>>2);
402 samples.push_back(m_DigitsPointer[index+2]>>2);
403 samples.push_back(m_DigitsPointer[index+5]>>2);
404 if(nsamples==7) {
405 samples.push_back(m_DigitsPointer[index+4]>>2);
406 samples.push_back(m_DigitsPointer[index+7]>>2);
407 }
408 }
409
410#ifdef LARBSDBGOUTPUT
411 m_logstr << MSG::DEBUG << " ===> ROD Channel = " << m_DigitsChannel << endmsg;
412 m_logstr << MSG::DEBUG << " ===> FEB Channel = " << channelNumber << endmsg;
413 m_logstr << MSG::DEBUG << " ===> Gain = " << gain << endmsg;
414 for(int i=0;i<nsamples;i++)
415 m_logstr << MSG::DEBUG << " ===> sample " << i << " = " << samples[i] << endmsg;
416#endif
419 unsigned rearrangeFirstSample=0;
421 rearrangeFirstSample=m_rearrangeFirstSample; //Overwrite by jobOptions
422 else
423 rearrangeFirstSample=getFirstSampleIndex();
424 if (rearrangeFirstSample && rearrangeFirstSample<samples.size()) //FIXME: Very ugly hack! See explanation in LArRodDecoder.h file
425 {//Change e.g. 3 0 1 2 4 to 0 1 2 3 4
426 short movedSample=samples[0];
427 for (unsigned i=1;i<=rearrangeFirstSample;i++)
428 samples[i-1]=samples[i];
429 samples[rearrangeFirstSample]=movedSample;
430 }
431#ifdef LARBSDBGOUTPUT
432 m_logstr << MSG::DEBUG << "GetNextDigits for FEB finished 0x" << MSG::hex << (uint32_t)getHeader32(FEBID) << MSG::dec << endmsg;
433#endif
434 return 1;
435}
436
438{
439 if(!m_RaddPointer) return 0;
440 return m_RaddPointer[1]>>8;
441}
442
444{
445 if(!m_RaddPointer) return 0;
446 return m_RaddPointer[1] & 0xff;
447}
448
450{
451 if(!m_MaskTimeQualityPointer) return 0;
452 int n=0;
453 for(int i=0;i<4;i++)
454 for(int j=0;j<32;j++)
455 if((m_MaskTimeQualityPointer[i] >> j) &0x1) n++;
456 return n;
457}
458
460{
461 if(!m_MaskDigitsPointer) return 0;
462 int n=0;
463 for(int i=0;i<4;i++)
464 for(int j=0;j<32;j++)
465 if((m_MaskDigitsPointer[i] >> j) &0x1) n++;
466 return n;
467}
468
470{
471 return getHeader16(NSamples);
472}
473
475{
476 return getHeader16(NGains);
477}
478
480{
481 return getHeader16(ResultsDim1);
482}
483
485{
486 return getHeader16(ResultsDim2);
487}
488
490{
492}
493
494uint32_t LArRodBlockPhysicsV5::getRadd(uint32_t adc, uint32_t sample) const
495{
496 if(!m_RawDataPointer) {
497 if(!m_RaddPointer) return 0;
498 if(sample%2) sample+=2;
499 return m_RaddPointer[sample];
500 }
501 int index;
502 if(sample==0) index=6;
503 else if(sample & 0x1) index=7+sample-1;
504 else index=7+sample+1;
505 uint32_t x=m_RawDataPointer[index];
506 if(adc>=8) return x>>8;
507 return x&0xff;
508}
509
510uint16_t LArRodBlockPhysicsV5::getCtrl1(uint32_t /*adc*/) const
511{
512 if(!m_RawDataPointer) return 0;
513 int index=5;
514 uint16_t x=m_RawDataPointer[index];
515 return x;
516}
517
518uint16_t LArRodBlockPhysicsV5::getCtrl2(uint32_t /*adc*/) const
519{
520 if(!m_RawDataPointer) return 0;
521 int index=4;
522 uint16_t x=m_RawDataPointer[index];
523 return x;
524}
525
526uint16_t LArRodBlockPhysicsV5::getCtrl3(uint32_t /*adc*/) const
527{
528 if(!m_RawDataPointer) return 0;
529 int index=7;
530 uint16_t x=m_RawDataPointer[index];
531 return x;
532}
533
535{
536 if(getNumberOfWords()<EventStatus/2) return 0;
537 uint32_t x=getHeader32(EventStatus);
538 return x;
539}
540
541// start of encoding methods
542void LArRodBlockPhysicsV5::initializeFragment(std::vector<uint32_t>& fragment ){
543 m_pRODblock=&fragment; //remember pointer to fragment
544 if (fragment.size()>m_iHeadBlockSize) { //Got filled fragment
545 unsigned int sizeRead=0;
546 //Store existing data in the FEB-Map
547 while (sizeRead<fragment.size()) {
548 std::vector<uint32_t>::iterator FebIter;
549 FebIter=fragment.begin()+sizeRead; //Store pointer to current Feb-Header
550 m_FebBlock=&(*FebIter); //Set m_FebBlock in order to use getHeader-functions.
551 uint32_t currFEBid=getHeader32(FEBID); //Get this FEB-ID
552 uint16_t currFebSize=getNumberOfWords(); //Size of this FEB-Block
553 if (FebIter+currFebSize>fragment.end()) {
554 fragment.clear(); //Clear existing vector
555 return;
556 }
557 m_mFebBlocks[currFEBid].assign(FebIter,FebIter+currFebSize); //Copy data from ROD-fragment into FEB-Block
558 sizeRead+=currFebSize+m_MiddleHeaderSize; //6 is the middle header size
559 } // end while
560 }
561 fragment.clear(); //Clear existing vector
562}
563
564//For writing: Initalizes a single FEB-Block
566{
568 if (m_vFragment->size()<m_iHeadBlockSize) //Got empty or spoiled fragment
569 {
570 m_vFragment->resize(m_iHeadBlockSize,0); //Initialize FEB-Header
571 setHeader32(FEBID,id); //Set Feb ID
572 // At least 10 (head) + 16 (gain/sumblks) + 64 (energies)
573 m_vFragment->reserve(90);
574 }
575
576 m_SumBlkBlockE1.resize(4);
577 for(unsigned int i=0;i<4;i++) m_SumBlkBlockE1[i]=0x0;
578 m_SumBlkBlockE2.resize(4);
579 for(unsigned int i=0;i<4;i++) m_SumBlkBlockE2[i]=0x0;
580 m_GainBlock.resize(8);
581 for(unsigned int i=0;i<8;i++) m_GainBlock[i]=0x0;
582 m_TimeQualityBlock.resize(6);
583 for(unsigned int i=0;i<6;i++) m_TimeQualityBlock[i]=0x0;
584 m_EnergyBlockEncode.resize(128);
585 for(unsigned int i=0;i<128;i++) m_EnergyBlockEncode[i]=0x0;
586 m_DigitsEncode.clear();
587
589}
590
591void LArRodBlockPhysicsV5::setNextEnergy(const int channel, const int32_t energy,
592 const int32_t time, const int32_t quality, const uint32_t gain)
593{
594 int rcNb=FebToRodChannel(channel);
595 //rcNb is supposed to be equal or bigger than m_EIndex.
596 //In the latter case, we fill up the missing channels with zero
597 if (rcNb<m_EnergyIndex) {
598 return;
599 }
600
601 //Fill up missing channels with zeros:
602 while (m_EnergyIndex<rcNb)
603 setNextEnergy((int16_t)0,(int16_t)32767,(int16_t)-32767,(uint32_t)0);
604
605 // transform 32 bits data into 16 bits data
606
607 uint16_t theenergy;
608 uint32_t abse,EncodedE;
609 int16_t thetime,thequality;
610 int32_t sign;
611
612 //Time is in 10 ps in ByteStream, hence the factor 10 to convert from ps
613 thetime = (int16_t) time/10;
614 thequality = (int16_t) quality;
615
616 sign=(energy>=0?1:-1); // get sign of energy
617 abse=(uint32_t)abs(energy);
618
619 EncodedE=abse; // range 0
620
621 if ((abse>8192)&&(abse<65536))
622 {
623 EncodedE=((abse>>3)|0x4000); // range 1 : drop last 3 bits and put range bits (bits 14 and 13 = 01)
624 }
625 else if ((abse>65535)&&(abse<524288))
626 {
627 EncodedE=((abse>>6)|0x8000); // range 2 : drop last 6 bits and put range bits (bits 14 and 13 = 10)
628 }
629 else if ((abse>524288))
630 {
631 EncodedE=((abse>>9)|0xc000); // range 3 : drop last 9 bits and put range bits (bits 14 and 13 = 11)
632 }
633
634 // treat sign now :
635
636 if (sign<0) EncodedE |= 0x2000;
637 theenergy = (uint16_t) EncodedE;
638
639 // Add data...
640
641 if (abse> m_EnergyThreshold1)
642 {
643 setNextEnergy(theenergy,thetime,thequality,gain);
644 }
645 else
646 {
647 setNextEnergy(theenergy,(int16_t)32767,(int16_t)-32767,gain);
648 }
649}
650
651//Private function, expects channel number is rod-style ordering
652void LArRodBlockPhysicsV5::setNextEnergy(const uint16_t energy,const int16_t time, const int16_t quality, const uint32_t gain)
653{
654 if (m_EnergyIndex>=m_channelsPerFEB) //Use m_EIndex to count total number of channels
655 {
656 return;
657 }
658
659 // Energy
660 int endianindex;
661 if (m_EnergyIndex & 0x1) endianindex = m_EnergyIndex-1;
662 else endianindex = m_EnergyIndex+1;
663 m_EnergyBlockEncode[endianindex] = energy;
664
665 // Find correct position
666
667 // update summary block
668 // Gain is composed of two bits per cell
669 uint16_t gain_idx=m_EnergyIndex>>4;
670 uint16_t gain_bit=(m_EnergyIndex&0xf)*2;
671 uint32_t gain1 = OfflineToRawGain(gain);
672 m_GainBlock[gain_idx] |= (gain1 << gain_bit);
673
674 // write Time and Chi2 for cells above HighEnergyCellCut threshold
675
676 if (quality!=-32767) // Do write Time and Chi2 information
677 {
678 // count the number of hot cells
680 // count the number of cells offtime
681 if (abs(time)>m_OffTimeCut) m_numberHotCellOffTime++;
682 uint16_t mask_idx=m_EnergyIndex>>5;
683 uint16_t mask_bit=(m_EnergyIndex&0x1f);
684 m_SumBlkBlockE1[mask_idx] |= (0x1 << mask_bit);
685
686 m_TimeQualityBlock.push_back(*((uint16_t*)&time));
687 m_TimeQualityBlock.push_back(*((uint16_t*)&quality));
688 }
689 m_EnergyIndex++; //Use m_EIndex to count the channels put in the Energy block
690
691}
692
693void LArRodBlockPhysicsV5::setRawData(const int chIdx, const std::vector<short>& samples , const uint32_t /* gain_not_used */ ){
694
695 // First of all, set the bits
696 int cchIdx = FebToRodChannel(chIdx);
697 uint16_t mask_idx=cchIdx>>5;
698 uint16_t mask_bit=(cchIdx&0x1f);
699 m_SumBlkBlockE2[mask_idx] |= (0x1 << mask_bit);
700 for(std::vector<short>::const_iterator i=samples.begin();i!=samples.end();++i){
701 m_DigitsEncode.push_back((*i)<<2);
702 }
703}
704
706{
707 //Complete non-complete Energy block
709 setNextEnergy((uint16_t)0,(int16_t)32767,(int32_t)-32767,(uint32_t)0);//E=0,t=32767,q=-32767,G=0
710
711 uint16_t n;
712 uint16_t nsamples=5;
713 // checkSum value
714 uint32_t sum=0;
715
716 // Will Hardcode here for the moment FIXME. Minimal 1 sample
718 setHeader16(NSamples,nsamples);
719 // These will never be used form MC. Nice to put in here thought
720 setHeader16(FEB_SN,0xfefe);
721 setHeader16(FEB_SN_h,0xdede);
724
725 // Gain block...
726 n = m_GainBlock.size();
727 //Check if Gain-Block exists and is not yet part of the fragment
728 if (n)
729 {
730 for(unsigned int i=0;i<n;i++){
731 m_vFragment->push_back(m_GainBlock[i]);
732 sum+=m_GainBlock[i];
733 }
734 }
735
736 // Cells above energy threshold E1
737 n = m_SumBlkBlockE1.size();
738 //Check if Summary Block exists and is not yet part of the fragment
739 if (n)
740 {
741 for (unsigned i=0;i<n;i++){
742 m_vFragment->push_back(m_SumBlkBlockE1[i]);
743 sum+=m_SumBlkBlockE1[i];
744 }
745 }
746
747 // Cells above energy threshold E2 (not included so far)
748 n = m_SumBlkBlockE2.size();
749 //Check if Summary Block exists and is not yet part of the fragment
750 if (n)
751 {
752 for (unsigned i=0;i<n;i++){
753 m_vFragment->push_back(m_SumBlkBlockE2[i]);
754 sum+=m_SumBlkBlockE2[i];
755 }
756 }
757
758 // fill info from counters
759 // for moment just include 1 fake words (32 bits) to put radd
760 uint32_t radd_nANC=0x0;
761 // Second threshold missing (FIXME)
762 radd_nANC = ((m_numberHotCell<<8))+(m_DigitsEncode.size()/nsamples);
763 radd_nANC = (radd_nANC<<16);
764 m_vFragment->push_back(radd_nANC);
765 sum+=radd_nANC;
766 // Need to include radd nsamples-1
767 // No need to include in sum's for now
768 for( int i=0; i < (nsamples-1)/2; i++)
769 m_vFragment->push_back(0x0);
770
771 // Energy block...
772 n = 128 ; // Fixed size m_EnergyBlock.size();
773 // Block also include time, whenever necessary
774 int size_of_block=80+(nsamples+1)/2+(m_TimeQualityBlock.size())/2;
775 //Check if Energy-Block exists and is not yet part of the fragment
776 if (n)
777 {
779 setHeader16(ResultsDim1,size_of_block);
780 for(unsigned int i=0;i<n/2;i++) {
781 // WARNING which one should be >>16 2*i or 2*i+1? To be tested
782 uint32_t Encode = m_EnergyBlockEncode[2*i]+(m_EnergyBlockEncode[2*i+1]<<16);
783 m_vFragment->push_back(Encode);
784 sum+=Encode;
785 }
786 }
787
788 // Magic numbers (3 or 6) for Ex, Ey and Ez
789 n = m_TimeQualityBlock.size();
790 //Check if Time and Quality Block exists and is not yet part of the fragment
791 if (n){
792 unsigned int imax = n/2;
793 for (unsigned int i=0;i<imax;i++) {
794 const auto low = static_cast<std::uint32_t>(m_TimeQualityBlock[i * 2]);
795 const auto high = static_cast<std::uint32_t>(m_TimeQualityBlock[i * 2 + 1]);
796 const std::uint32_t to_push = low | (high << 16);
797 m_vFragment->push_back(to_push);
798 sum += to_push;
799 }
800 }
801 // Now include digits
802 n = m_DigitsEncode.size();
803 if ( n ) {
804 // First make sure it is not and odd number to store
805 if ( m_DigitsEncode.size() & 0x1 ) m_DigitsEncode.push_back(0x0);
806 unsigned int imax=m_DigitsEncode.size()/2;
807 for (unsigned int i=0;i<imax;i++) {
808 const auto low = static_cast<std::uint32_t>(m_DigitsEncode[i * 2 + 1]);
809 const auto high = static_cast<std::uint32_t>(m_DigitsEncode[i * 2]);
810 const std::uint32_t to_push = low | (high << 16);
811 m_vFragment->push_back(to_push);
812 sum += to_push;
813 }
815 setHeader16(ResultsOff2,18+size_of_block);
816 } // End of check for format
817
818 // Need to add header to check sum
819 for(size_t ii=0;ii<endtag/2;ii++){
820 sum+=((*m_vFragment)[ii]);
821 }
822 // Three final magic words
823 m_vFragment->push_back(0x0); // For the moment
824 m_vFragment->push_back(0x12345678); // For the moment
825 m_vFragment->push_back(sum& 0x7fffffff);
826
828}
829
830
832{
833 FEBMAPTYPE::const_iterator feb_it_b=m_mFebBlocks.begin();
834 FEBMAPTYPE::const_iterator feb_it_e=m_mFebBlocks.end();
835 FEBMAPTYPE::const_iterator feb_it;
836 for (feb_it=feb_it_b;feb_it!=feb_it_e;++feb_it) {
837 if (feb_it!=feb_it_b) //Not first Feb
839
840 //Add feb data to rod data block
841 m_pRODblock->insert (m_pRODblock->end(),
842 feb_it->second.begin(), feb_it->second.end());
843 } //end for feb_it
844
845 m_mFebBlocks.clear();
846}
847
848//Sort functions & ordering relation:
849template<class RAWDATA>
850bool LArRodBlockPhysicsV5::operator ()
851 (const RAWDATA* ch1, const RAWDATA* ch2) const
852{
853 HWIdentifier id1 = ch1->channelID();
854 HWIdentifier id2 = ch2->channelID();
855
856 HWIdentifier febId1= m_onlineHelper->feb_Id(id1);
857 HWIdentifier febId2= m_onlineHelper->feb_Id(id2);
858
859 if(febId1 == febId2 ){
860 int cId1 = m_onlineHelper->channel(id1);
861 int cId2 = m_onlineHelper->channel(id2);
862 return FebToRodChannel(cId1) < FebToRodChannel(cId2);
863 }
864
865 return febId1 < febId2 ;
866}
#define endmsg
static Double_t sc
int sign(int a)
int imax(int i, int j)
#define x
virtual uint16_t getRawDataSize() const
const LArOnlineID * m_onlineHelper
const uint32_t * m_GainPointer
std::vector< uint16_t > m_EnergyBlockEncode
unsigned short m_requiredNSamples
virtual uint16_t getResults2Size() const
virtual int getNextRawData(int &channelNumber, std::vector< short > &samples, uint32_t &gain)
virtual int FebToRodChannel(int ch) const
void initializeFragment(std::vector< uint32_t > &fragment)
virtual uint16_t getCtrl2(uint32_t adc) const
virtual uint16_t getNbSweetCells2() const
virtual uint16_t getCtrl1(uint32_t adc) const
virtual uint32_t getNumberOfSamples() const
std::vector< uint32_t > m_SumBlkBlockE1
LArRodBlockPhysicsV5(IMessageSvc *msgSvc)
uint16_t getNbSweetCells1FromMask() const
std::vector< uint32_t > m_SumBlkBlockE2
const uint16_t * m_RawDataPointer
const uint16_t * m_DigitsPointer
const uint32_t * m_MaskDigitsPointer
virtual uint32_t getRadd(uint32_t adc, uint32_t sample) const
virtual uint16_t getResults1Size() const
int getNextDigits(int &channelNumber, std::vector< short > &samples, uint32_t &gain)
uint16_t getNbSweetCells2FromMask() const
uint16_t getFirstSampleIndex() const
std::vector< uint32_t > m_GainBlock
const uint32_t * m_MaskTimeQualityPointer
const uint16_t * m_TimeQualityPointer
virtual uint16_t getCtrl3(uint32_t adc) const
virtual uint16_t getNbSweetCells1() const
virtual uint32_t getStatus() const
void initializeFEB(const uint32_t id)
static std::string BlockType()
const uint16_t * m_RaddPointer
void setNextEnergy(const int channel, const int32_t energy, const int32_t time, const int32_t quality, const uint32_t gain)
void setRawData(const int, const std::vector< short > &, const uint32_t)
const uint16_t * m_EnergyPointer
virtual uint32_t getNumberOfGains() const
std::vector< uint16_t > m_DigitsEncode
virtual int getNextEnergy(int &channelNumber, int32_t &energy, int32_t &time, int32_t &quality, uint32_t &gain)
std::vector< uint16_t > m_TimeQualityBlock
uint16_t getHeader16(const unsigned n) const
void setHeader32(const unsigned n, const uint32_t w)
uint32_t getHeader32(const unsigned n) const
void setHeader16(const unsigned n, const uint16_t w)
std::vector< uint32_t > * m_pRODblock
LArRodBlockStructure(IMessageSvc *msgSvc, const std::string &blockType)
uint32_t OfflineToRawGain(const uint32_t gain) const
std::vector< uint32_t > * m_vFragment
uint32_t RawToOfflineGain(const uint32_t gain) const
uint32_t getNumberOfWords() const
singleton-like access to IMessageSvc via open function and helper
@ LARNGAIN
Definition CaloGain.h:19
Definition index.py:1