ATLAS Offline Software
Loading...
Searching...
No Matches
LArRodBlockPhysicsV3.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Implementation of the LArRODBlockStructure_3 class
6// This version contains LArRawChannels (=E,t,Q)
7// and LArDigits (=5 time samples)
8// See .h file for more details.
9
14#include "GaudiKernel/Bootstrap.h"
15#include "GaudiKernel/ISvcLocator.h"
16#include "GaudiKernel/IToolSvc.h"
17#include <stdlib.h>
18#include <cstdio>
19#include <iostream>
20
21#ifdef LARBSDBGOUTPUT
22#define LARBSDBG(text) m_logstr<<MSG::DEBUG<<text<<endmsg
23#else
24#define LARBSDBG(text)
25#endif
26
27namespace {
28union ShortLong {
29 uint16_t s[2];
30 uint32_t l;
31};
32}
33
35
38{
39 // retrieve onlineHelper
40 const LArOnlineID* online_id;
41 SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service("DetectorStore")};
42 if (!detStore) {
43 m_logstr << MSG::ERROR << "Unable to locate DetectorStore" << endmsg;
44 std::abort();
45 }
46 StatusCode sc = detStore->retrieve(online_id, "LArOnlineID");
47 if (sc.isFailure()) {
48 m_logstr << MSG::FATAL << "Could not get LArOnlineID helper !" << endmsg;
49 std::abort();
50 }
51 else {
52 m_onlineHelper=online_id;
53 m_logstr << MSG::DEBUG << " Found the LArOnlineID helper. " << endmsg;
54 }
55
56 m_iHeadBlockSize=endtag/2; // The implicit cast rounds down to the right size
57 m_NSumBlkWords=4; // BL : words of 32 bits here
60 m_NEnergyBlkWords=128*16/32;
61 m_NGainBlkWords=128*2/32;
62
63 // Move this to properties of the algorithm but set default values.
64 m_EnergyThreshold = 100; // MeV
65 m_OffTimeCut = 30; // ns
66
68
70 m_vFragment=NULL;
71 m_FebBlock=NULL;
72 m_pRODblock=NULL;
73
74 m_Ex=0;
75 m_Ey=0;
76 m_Ez=0;
77 m_HottestCellIndex=255; // 255 is unphysical since cells index are between 0 and 127 per FEB.
79
80 m_CounterPtr=NULL;
81 m_EnergyPtr=NULL;
83 m_GainPtr=NULL;
85 m_RawDataPtr=NULL;
86 m_SumBlkPtr=NULL;
88}
89
90// clear temporary block vectors
92{
93 m_SumBlkBlock.clear();
94 m_CounterBlkBlock.clear();
95 m_EnergyBlock.clear();
96 m_GainBlock.clear();
97 m_TimeQualityBlock.clear();
98 m_RawDataBlock.clear();
99 m_FebInfoBlock.clear();
100}
101
103{
108 m_GainIndex=0;
110 m_SumBlkIndex=0;
112
115 m_Ex=0;
116 m_Ey=0;
117 m_Ez=0;
118 m_HottestCellIndex=255; // 255 is unphysical since cells index are between 0 and 127 per FEB.
120}
121
122//For reading (to speed up the process)
124{
125 //Set pointers to data blocks (pesuming, they exist)
127 {
129 m_SumBlkPtr=reinterpret_cast<const uint32_t*> (m_FebBlock+LE_getHeader16(SumBlkOffset));
130 else
131 m_SumBlkPtr=reinterpret_cast<const uint32_t*>(m_DummyBitMap);
132
134 m_CounterPtr=reinterpret_cast<const uint16_t*>(m_FebBlock+LE_getHeader16(CounterBlkOffset));
135 else
136 m_CounterPtr=reinterpret_cast<const uint16_t*>(m_DummyBitMap);
137
139 m_EnergyPtr=reinterpret_cast<const uint16_t*>(m_FebBlock+LE_getHeader16(EBlkOffset));
140 else
141 m_EnergyPtr=reinterpret_cast<const uint16_t*>(m_DummyBitMap);
142
144 m_GainPtr=reinterpret_cast<const uint32_t*>(m_FebBlock+LE_getHeader16(GainBlkOffset));
145 else
146 m_GainPtr=reinterpret_cast<const uint32_t*>(m_DummyBitMap);
147
149 m_TimeQualityPtr=reinterpret_cast<const int16_t*>(m_FebBlock+LE_getHeader16(TimeQualityBlkOffset));
150 else
151 m_TimeQualityPtr=reinterpret_cast<const int16_t*>(m_DummyBitMap);
152
154 m_RawDataPtr=reinterpret_cast<const int16_t*>(m_FebBlock+LE_getHeader16(RawDataBlkOffset));
155 else
156 m_RawDataPtr=reinterpret_cast<const int16_t*>(m_DummyBitMap);
157
159 m_FebInfoDataPtr=reinterpret_cast<const int16_t*>(m_FebBlock+LE_getHeader16(FebInfoBlkOffset));
160 else
161 m_FebInfoDataPtr=reinterpret_cast<const int16_t*>(m_DummyBitMap);
162
163#ifdef LARBSDBGOUTPUT
164 m_logstr << MYLEVEL << "***********************************************************************"<< endmsg;
165 m_logstr << MYLEVEL << "Energy Pointed values :"<< endmsg;
166 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
167 m_logstr << MYLEVEL << "LE_getHeader16(SumBlkOffset) = "<< MSG::hex << LE_getHeader16(SumBlkOffset) << endmsg;
168 m_logstr << MYLEVEL << "LE_getHeader16(CounterBlkOffset) = "<< MSG::hex << LE_getHeader16(CounterBlkOffset) << endmsg;
169 m_logstr << MYLEVEL << "LE_getHeader16(GainBlkOffset) = "<< MSG::hex << LE_getHeader16(GainBlkOffset) << endmsg;
170 m_logstr << MYLEVEL << "LE_getHeader16(EBlkOffset) = "<< MSG::hex << LE_getHeader16(EBlkOffset) << endmsg;
171 m_logstr << MYLEVEL << "LE_getHeader16(FebInfoBlkOffset) = "<< MSG::hex << LE_getHeader16(FebInfoBlkOffset) << endmsg;
172 m_logstr << MYLEVEL << "LE_getHeader16(TimeQualityBlkOffset) = "<< MSG::hex << LE_getHeader16(TimeQualityBlkOffset) << endmsg;
173 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
174
175 m_logstr << MYLEVEL << "********************* SumBlck ************************************"<< endmsg;
176 for(int toto=0;toto<4;toto++)
177 m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_SumBlkPtr[toto] << endmsg;
178 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
179
180 m_logstr << MYLEVEL << "********************* CounterBlck ************************************"<< endmsg;
181 for(int toto=0;toto<10;toto++) m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_CounterPtr[toto] << endmsg;
182 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
183
184 m_logstr << MYLEVEL << "********************* FebInfoBlck ************************************"<< endmsg;
185 for(int toto=0;toto<4;toto++) m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_FebInfoDataPtr[toto] << endmsg;
186 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
187
188
189 m_logstr << MYLEVEL << "********************* Energies ************************************"<< endmsg;
190 for(int toto=0;toto<128;toto++)
191 m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_EnergyPtr[toto] << endmsg;
192 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
193
194 m_logstr << MYLEVEL << "********************* Time & Quality ************************************"<< endmsg;
195 for(int toto=0;toto<10;toto++)
196 m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_TimeQualityPtr[toto] << endmsg;
197 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
198#endif
199
200 }
201 else
202 {
203 m_SumBlkPtr=NULL;
204 m_CounterPtr=NULL;
205 m_EnergyPtr=NULL;
206 m_TimeQualityPtr=NULL;
207 m_GainPtr=NULL;
208 m_FebInfoDataPtr=NULL;
209 m_RawDataPtr=NULL;
211 }
212
213 return true;
214}
215
217{
218 uint16_t oldword=LE_getVectorHeader16(NGainNSamples);
219 LE_setHeader16(NGainNSamples,(oldword & 0xFF00) | n);
220}
221
223{
224 uint16_t oldword=LE_getVectorHeader16(NGainNSamples);
225 LE_setHeader16(NGainNSamples,(oldword & 0x00FF) | (n<<8));
226}
227
228
229
230void LArRodBlockPhysicsV3::setNextEnergy(const int channel, const int32_t energy,
231 const int32_t time, const int32_t quality, const uint32_t gain)
232{
233 m_logstr << MYLEVEL << "setNextEnergy-------------------->>>>>********************** new format V3 ***********" << endmsg;
234 m_logstr << MYLEVEL << "Channel=" << channel << " energy =" << energy << endmsg;
235 int rcNb=FebToRodChannel(channel);
236 //rcNb ist supposed to equal or bigger than m_EIndex.
237 //In the latter case, we fill up the missing channels with zero
238 if (rcNb<m_EnergyIndex) {
239 m_logstr << MSG::ERROR << "LArRODBlockStructure Error: Internal error. Channels not ordered correctly. rcNb=" << rcNb
240 << " m_EnergyIndex=" << m_EnergyIndex << endmsg;
241 return;
242 }
243
244 //Fill up missing channels with zeros:
245 while (m_EnergyIndex<rcNb)
246 setNextEnergy((int16_t)0,(int16_t)32767,(int16_t)-32767,(uint32_t)0);
247
248 // update if needed the hottest cell info
249 if ((energy>0)&&(energy>(int)m_HottestCellEnergy))
250 {
251 m_HottestCellEnergy = abs(energy);
252 m_HottestCellIndex = channel;
253 }
254
255 // transform 32 bits data into 16 bits data
256
257 uint16_t theenergy;
258 uint32_t abse,EncodedE;
259 int16_t thetime,thequality;
260 int32_t sign;
261
262 thetime = (int16_t) time >> 4;
263 thequality = (int16_t) quality;
264
265 sign=(energy>=0?1:-1); // get sign of energy
266 abse=(uint32_t)abs(energy);
267
268 EncodedE=abse; // range 0
269
270 if ((abse>8192)&&(abse<65536))
271 {
272 EncodedE=((abse>>3)|0x2000); // range 1 : drop last 3 bits and put range bits (bits 14 and 13 = 01)
273 }
274 else if ((abse>65535)&&(abse<524288))
275 {
276 EncodedE=((abse>>6)|0x4000); // range 2 : drop last 6 bits and put range bits (bits 14 and 13 = 10)
277 }
278 else if ((abse>524288))
279 {
280 EncodedE=((abse>>9)|0x6000); // range 3 : drop last 9 bits and put range bits (bits 14 and 13 = 11)
281 }
282
283 // treat sign now :
284
285 if (sign<0) EncodedE |= 0x8000;
286 theenergy = (uint16_t) EncodedE;
287
288 // Add data...
289
290 m_logstr << MYLEVEL << "setNextEnergy-------------------->>>>> Energy = "<< energy << " Encoded Energy =" << theenergy << endmsg;
291
292 if (abse> m_EnergyThreshold)
293 {
294 setNextEnergy(theenergy,thetime,thequality,gain);
295 }
296 else
297 {
298 setNextEnergy(theenergy,(int16_t)32767,(int16_t)-32767,gain);
299 }
300}
301
302//Private function, expects channel number is rod-style ordering
303void LArRodBlockPhysicsV3::setNextEnergy(const uint16_t energy,const int16_t time, const int16_t quality, const uint32_t gain)
304{
305 if (m_EnergyIndex>=m_channelsPerFEB) //Use m_EIndex to count total number of channels
306 {
307 m_logstr << MSG::ERROR << "LArRodBlockStructure Error: Attempt to write Energy for channel "
308 << m_EnergyIndex << " channels into a FEB!" <<endmsg;
309 return;
310 }
311 LARBSDBG("LArRodBlockStructure: Setting Energy for channel " << m_EnergyIndex << ". E=" << energy);
312
313 m_logstr << MYLEVEL << "In setNextEnergy-------------------->>>>> time = " << time << " quality=" << quality << endmsg;
314
315 // write for all cells energy and hardware gain
316
317 // Energy
318
319 m_EnergyIndex++; //Use m_EIndex to count the channels put in the Energy block
320
321 ShortLong twoValues{};
322 if (m_EnergyIndex%2) // m_EIndex-1 is even
323 {
324 twoValues.s[0]= energy;
325 twoValues.s[1]=0;
326 }
327 else
328 { //Even number: Merging with previous block
329 uint32_t oneValue=m_EnergyBlock[m_EnergyBlock.size()-1]; //Take last element of vector
330 m_EnergyBlock.pop_back();
331 uint16_t* valptr=reinterpret_cast<uint16_t*>(&oneValue);
332 twoValues.s[0]=valptr[0];
333 twoValues.s[1]=(uint16_t)energy;
334 }
335
336 LARBSDBG("Writing words: val0= " << twoValues.s[0] << " val1= " << twoValues.s[1]);
337 m_EnergyBlock.push_back(twoValues.l);
338 LARBSDBG("Writing Raw data to E block. E=" << energy);
339
340 // update summary block
341 // Summary block is one bit per cell
342
343 int mylocalBitwiseIndex = (int) (m_EnergyIndex-1)%32; // 1 bits in SB per channel
344 if (mylocalBitwiseIndex==0) // need for a new 32 bits word to store SM info of that cell
345 {
346 uint32_t SB;
347 SB = (quality==-32767?0x00000000:0x00000001);
348 m_SumBlkBlock.push_back(SB);
349 }
350 else
351 {
352 uint32_t SB=m_SumBlkBlock[m_GainBlock.size()-1]; //Take out last element of vector
353 m_SumBlkBlock.pop_back();
354 SB=(SB<<1)|(quality==-32767?0x00000000:0x00000001);
355 m_SumBlkBlock.push_back(SB);
356 }
357
358 // Hardware gain
359
360 mylocalBitwiseIndex = (m_EnergyIndex-1)%16; // 2 bits of gain per channel
361 if (mylocalBitwiseIndex==0) // need for a new 32 bits word to store the gain of that cell
362 {
363 m_GainBlock.push_back(gain&0x00000003);
364 }
365 else
366 {
367 uint32_t encodedgains=m_GainBlock[m_GainBlock.size()-1]; //Take out last element of vector
368 m_GainBlock.pop_back();
369 encodedgains=(encodedgains<<2)|(gain&0x00000003);
370 m_GainBlock.push_back(encodedgains);
371 }
372
373 // write Time and Chi2 for cells above HighEnergyCellCut threshold
374
375 if (quality!=-32767) // Do write Time and Chi2 information
376 {
377 // count the number of hot cells
379 // count the number of cells offtime
380 if (abs(time)>m_OffTimeCut) m_numberHotCellOffTime++;
381
382 mylocalBitwiseIndex = (m_numberHotCell-1)%2; // 16 bits per channel
383 ShortLong twoValues{};
384 if (mylocalBitwiseIndex==0) // need for a new 32 bits word to store the time quality of that cell
385 {
386 twoValues.s[0]=0;
387 twoValues.s[1]=0;
388 twoValues.s[0]=(int16_t)(time)|((quality>>10)&0x003F); // Quality on the first 6 bits and Time on the last 10 bits;
389 }
390 else
391 { //Even number: Merging with previous block
392 uint32_t oneValue=m_TimeQualityBlock[m_TimeQualityBlock.size()-1]; //Take last element of vector
393 m_TimeQualityBlock.pop_back();
394 int16_t* valptr=reinterpret_cast<int16_t*>(&oneValue);
395 twoValues.s[0]=valptr[0];
396 twoValues.s[1]=(int16_t)(time)|((quality>>12)&0x003F); // Quality on the first 4 bits and Time on the last 12 bits;
397 }
398 m_TimeQualityBlock.push_back(twoValues.l);
399 }
400}
401
402void LArRodBlockPhysicsV3::setRawData(const int channel, const std::vector<short>& samples, const uint32_t gain) {
403 //Convert Feb to Rod Channel Number:
404 int rcNb=FebToRodChannel(channel);
405 if (rcNb>=m_channelsPerFEB)
406 {
407 m_logstr << MSG::ERROR << "Attempt to write Energy for channel " << rcNb << " channels into a FEB!" << endmsg;
408 return;
409 }
410 unsigned int nsamples = LE_getVectorHeader16(NGainNSamples) & 0x00FF;
411 if(samples.size() != nsamples) {
412 m_logstr << MSG::ERROR << "Number of samples mismatch!\n";
413 m_logstr << " nsamples =" << nsamples;
414 m_logstr << " samples.size() =" << samples.size() << endmsg;
415 std::abort();
416 }
417
418 setBit(&m_RawDataBlock[0],rcNb);
419 //Samples have 12 bit and are shifted to the left by 2 bits.
420 // odd samples in high bits, even samples in low bits
421 if((nsamples/2)*2!=nsamples) { //odd number of samples - gain is alone
422 m_RawDataBlock.push_back((gain<<30) | samples[0]<<2);
423 for (unsigned int i=1;i<nsamples;i+=2)
424 m_RawDataBlock.push_back((samples[i+1]<<18) | samples[i]<<2);
425 }
426 else { //even number of samples - gain is packed with sample 0
427 m_RawDataBlock.push_back((gain<<30) | (samples[1]<<18) | samples[0]<<2);
428 for (unsigned int i=2;i<nsamples;i+=2)
429 m_RawDataBlock.push_back((samples[i+1]<<18) | samples[i]<<2);
430 }
431}
432
433
434//For writing: takes existing Fragment and splits it into Feb-Blocks
435void LArRodBlockPhysicsV3::initializeFragment(std::vector<uint32_t>& fragment)
436{
437 m_pRODblock=&fragment; //remember pointer to fragment
438 if (fragment.size()>m_iHeadBlockSize) { //Got filled fragment
439 unsigned int sizeRead=0;
440 //Store existing data in the FEB-Map
441 while (sizeRead<fragment.size()) {
442 std::vector<uint32_t>::iterator FebIter;
443 FebIter=fragment.begin()+sizeRead; //Store pointer to current Feb-Header
444 m_FebBlock=&(*FebIter); //Set m_FebBlock in order to use getHeader-functions.
445 uint32_t currFEBid=getHeader32(FEBID); //Get this FEB-ID
446 uint16_t currFebSize=getNumberOfWords(); //Size of this FEB-Block
447 if (FebIter+currFebSize>fragment.end()) {
448 fragment.clear(); //Clear existing vector
449 m_logstr << MSG::ERROR << "Got inconsistent ROD-Fragment!" << endmsg;
450 return;
451 }
452 m_mFebBlocks[currFEBid].assign(FebIter,FebIter+currFebSize); //Copy data from ROD-fragment into FEB-Block
453 sizeRead+=currFebSize+m_MiddleHeaderSize; //6 is the middle header size
454 LARBSDBG("Found FEB-id " << currFEBid << " in existing ROD-Fragment");
455 } // end while
456 }
457 fragment.clear(); //Clear existing vector
458 return;
459}
460
461//For writing: Initalizes a single FEB-Block
463{
465 if (m_vFragment->size()<m_iHeadBlockSize) //Got empty or spoiled fragment
466 {
467 m_vFragment->resize(m_iHeadBlockSize,0); //Initialize FEB-Header
468 setHeader32(FEBID,id); //Set Feb ID
469 }
470
471 m_SumBlkBlock.resize(0);
472 m_CounterBlkBlock.resize(0);
473 m_EnergyBlock.resize(0);
474 m_GainBlock.resize(0);
475 m_FebInfoBlock.resize(0);
476 m_RawDataBlock.resize(0);
477
479}
480
482{
483 //Complete non-complete Energy block
485 setNextEnergy((uint16_t)0,(int16_t)32767,(int32_t)-32767,(uint32_t)0);//E=0,t=32767,q=-32767,G=0
486
487 uint16_t n;
488 uint16_t BlockOffset;
489
490 // Summary block....
491 n = m_SumBlkBlock.size();
493 //Check if Summary Block exists and is not yet part of the fragment
494 LARBSDBG("Checking for Summary Block n=" << n << "BlockOffset=" << BlockOffset);
495 if (n && !BlockOffset)
496 {
499 m_logstr << MSG::DEBUG << "In finalizeFEB-------------------->>>>> " << "Checking for Summary Block : length= " << n << " BlockOffset=" << BlockOffset << endmsg;
500 for (unsigned i=0;i<n;i++)
501 m_vFragment->push_back(m_SumBlkBlock[i]);
502 }
503
504 // Counter block....
505
506 // fill info from counters
507 ShortLong twoValues{};
508 twoValues.s[0]=(uint16_t)m_numberHotCell;
509 twoValues.s[1]=(uint16_t)m_numberHotCellOffTime;
510 m_CounterBlkBlock.push_back(twoValues.l);
511
512 twoValues.s[0]=(uint16_t)m_EnergyThreshold;
513 twoValues.s[1]=(uint16_t)m_OffTimeCut;
514 m_CounterBlkBlock.push_back(twoValues.l);
515
516 // Write the Energy threshold used to determine which cell is a hot cell in the first
517 // 32 bit word of the counters
518 // Write the Energy Ex of the ROD block in a 32 bits word
519 // Write the Energy Ey of the ROD block in a 32 bits word
520 // Ex and Ey have to be 32 bits words as they are sums of multiple 16 bits words
521
522 uint32_t* aux = (uint32_t*)&m_Ex;
523 m_CounterBlkBlock.push_back(*aux);
524 aux = (uint32_t*)&m_Ey;
525 m_CounterBlkBlock.push_back(*aux);
526
527 // write the hottest cell index for that FEB and its energy in MeV
528
529 twoValues.s[0]=(uint16_t)((m_HottestCellIndex<<9)|((uint16_t)((m_HottestCellEnergy>>16))&0x01FF));
530 twoValues.s[1]=(uint16_t)m_HottestCellEnergy;
531 m_CounterBlkBlock.push_back(twoValues.l);
532
533 aux = (uint32_t*)&m_Ez;
534 m_CounterBlkBlock.push_back(*aux);
535
536 n = m_CounterBlkBlock.size();
538 //Check if Counter Block exists and is not yet part of the fragment
539 LARBSDBG("Checking for Counter Block n=" << n << "BlockOffset=" << BlockOffset);
540 if (n && !BlockOffset)
541 {
544 m_logstr << MSG::INFO << "In finalizeFEB-------------------->>>>> " << "Checking for Counter Block : length= " << n << " BlockOffset=" << BlockOffset << endmsg;
545 for (unsigned i=0;i<n;i++)
546 m_vFragment->push_back(m_CounterBlkBlock[i]);
547 }
548
549 // Energy block...
550 n = m_EnergyBlock.size();
551 BlockOffset=LE_getVectorHeader16(EBlkOffset);
552 LARBSDBG("Checking Energy Block n=" << n << "BlockOffset=" << BlockOffset);
553 //Check if Energy-Block exists and is not yet part of the fragment
554 if (n && !BlockOffset)
555 {
557 BlockOffset=LE_getVectorHeader16(EBlkOffset);
558 m_logstr << MSG::DEBUG << "In finalyseFEB-------------------->>>>> " << "Checking for Energy Block : length= " << n << " BlockOffset=" << BlockOffset << endmsg;
559 for(unsigned int i=0;i<n;i++)
560 m_vFragment->push_back(m_EnergyBlock[i]);
561 }
562
563 // Gain block...
564 n = m_GainBlock.size();
566 LARBSDBG("Checking Gain Block n=" << n << "BlockOffset=" << BlockOffset);
567 //Check if Gain-Block exists and is not yet part of the fragment
568 if (n && !BlockOffset)
569 {
572 for(unsigned int i=0;i<n;i++)
573 m_vFragment->push_back(m_GainBlock[i]);
574 }
575
576 // FeBInfo Block... // offline encoder just put dummy info there
577 for (int nword=0; nword<m_NFebInfoBlkWords ; nword++)
578 m_FebInfoBlock.push_back(0L);
579
580 n = m_FebInfoBlock.size();
582 LARBSDBG("Checking FebInfo Block n=" << n << "BlockOffset=" << BlockOffset);
583 //Check if Gain-Block exists and is not yet part of the fragment
584 if (n && !BlockOffset)
585 {
588 for(unsigned int i=0;i<n;i++)
589 m_vFragment->push_back(m_FebInfoBlock[i]);
590 }
591
592 // Time and Quality block
593 n = m_TimeQualityBlock.size();
595 LARBSDBG("Checking Time and Quality Block n=" << n << "BlockOffset=" << BlockOffset);
596 //Check if Time and Quality Block exists and is not yet part of the fragment
597 if (n && !BlockOffset)
598 {
601 m_logstr << MSG::DEBUG << "In finalizeFEB-------------------->>>>> " << "Checking for Time and Quality Block : length= " << n << " BlockOffset=" << BlockOffset << endmsg;
602 for(unsigned int i=0;i<n;i++)
603 m_vFragment->push_back(m_TimeQualityBlock[i]);
604 }
605
606 // Raw data
607 LARBSDBG("Checking Raw Data Block");
608 n = m_RawDataBlock.size();
610 LARBSDBG("Checking Raw Data Block. n=" << n << "BlockOffset=" << BlockOffset);
611 //Check if Raw Data block exists and is not yet part of the fragment
612 if ((n>m_NFlaggingWords) && (!BlockOffset))
613 {
615 for(unsigned int i=0;i<n;i++)
616 m_vFragment->push_back(m_RawDataBlock[i]);
617 }
619
620 m_logstr << MYLEVEL << "***********************************************************************"<< endmsg;
621 m_logstr << MYLEVEL << "m_HottestCellIndex : "<< m_HottestCellIndex << endmsg;
622 m_logstr << MYLEVEL << "m_HottestCellEnergy : "<< m_HottestCellEnergy << endmsg;
623 m_logstr << MYLEVEL << "***********************************************************************"<< endmsg;
624 m_logstr << MYLEVEL << "m_Ex : "<< m_Ex << endmsg;
625 m_logstr << MYLEVEL << "m_Ey : "<< m_Ey << endmsg;
626 m_logstr << MYLEVEL << "***********************************************************************"<< endmsg;
627
628 clearBlocks();
629}
630
631
633{
634 FEBMAPTYPE::const_iterator feb_it_b=m_mFebBlocks.begin();
635 FEBMAPTYPE::const_iterator feb_it_e=m_mFebBlocks.end();
636 FEBMAPTYPE::const_iterator feb_it;
637 for (feb_it=feb_it_b;feb_it!=feb_it_e;++feb_it) {
638 if (feb_it!=feb_it_b) //Not first Feb
640
641 //Add feb data to rod data block
642 m_pRODblock->insert (m_pRODblock->end(),
643 feb_it->second.begin(), feb_it->second.end());
644 } //end for feb_it
645
646 m_mFebBlocks.clear();
647}
648
649int LArRodBlockPhysicsV3::getNextRawData(int& channelNumber, std::vector<short>& samples, uint32_t& gain)
650{
651 LARBSDBG("in LArRodBlockPhysicsV3::getNextRawData.");
652 LARBSDBG("m_RawDataCounter=" << m_RawDataCounter << " m_RawDataIndex="<< m_RawDataIndex);
653 LARBSDBG("m_channelsPerFEB=" << m_channelsPerFEB);
654 if(m_FebBlockSize<=m_iHeadBlockSize) return 0;
656
657 const int flags=(int) LE_getHeader16(RawDataBlkOffset);
658 if (!flags)
659 return 0; //Block not existing
660 if (m_RawDataCounter>=m_channelsPerFEB) //Already beyond maximal number of channels
661 return 0;
662
663 LARBSDBG("Flags="<<flags);
664
665 while (!getBit(m_RawDataFlagsPtr,m_RawDataCounter)) //Look for next filled channel
666 {
668 LARBSDBG("RawDataCounter ist now " << m_RawDataCounter);
669 if (m_RawDataCounter>=m_channelsPerFEB) //No more channel available
670 return 0;
671 }
672 LARBSDBG("Found filled channel at positon " << m_RawDataCounter);
673 //Found next filled channel
674 channelNumber=m_RawDataCounter;
675 unsigned int nsamples = LE_getHeader16(NGainNSamples) & 0x00FF;
676 LARBSDBG("This run has " << nsamples << " samples");
677 int index = m_RawDataIndex*nsamples;
678 LARBSDBG( "index="<<index);
680 LARBSDBG("In getnextRawData(). index= " << index);
681 gain=3-((m_GainPtr[channelNumber/16] >> (channelNumber%16)*2) & 0x3);
682 if(gain>=CaloGain::LARNGAIN) return 0;
683 for(unsigned int i=0;i<nsamples;i++) {
684 uint16_t x;
685 if((index+i)%2==0)
686 x=m_RawDataPtr[index+i+1];
687 else
688 x=m_RawDataPtr[index+i-1];
689 samples.push_back((short) (x & 0xfff));
690 }
692
693 if (m_rearrangeFirstSample && m_rearrangeFirstSample<samples.size()) //FIXME: Very ugly hack! See explanation in LArRodDecoder.h file
694 {//Change e.g. 3 0 1 2 4 to 0 1 2 3 4
695 short movedSample=samples[0];
696 for (unsigned i=1;i<=m_rearrangeFirstSample;i++)
697 samples[i-1]=samples[i];
698 samples[m_rearrangeFirstSample]=movedSample;
699 }
700
701 return 1;
702}
703
704
705
706
707//Sort functions & ordering relation:
708template<class RAWDATA>
709bool LArRodBlockPhysicsV3::operator ()
710 (const RAWDATA* ch1, const RAWDATA* ch2) const
711{
712 HWIdentifier id1 = ch1->channelID();
713 HWIdentifier id2 = ch2->channelID();
714
715 HWIdentifier febId1= m_onlineHelper->feb_Id(id1);
716 HWIdentifier febId2= m_onlineHelper->feb_Id(id2);
717
718 if(febId1 == febId2 ){
719 int cId1 = m_onlineHelper->channel(id1);
720 int cId2 = m_onlineHelper->channel(id2);
721 return FebToRodChannel(cId1) < FebToRodChannel(cId2);
722 }
723
724 return febId1 < febId2 ;
725}
726
727void LArRodBlockPhysicsV3::sortDataVector(std::vector<const LArRawChannel*>& vRC)
728{
729 std::sort(vRC.begin(),vRC.end(),*this);
730}
731
732void LArRodBlockPhysicsV3::sortDataVector( std::vector<const LArDigit*>& vDigit)
733{
734 std::sort(vDigit.begin(),vDigit.end(),*this);
735}
736
738{
739 return LE_getHeader16(NGainNSamples)&0xff;
740}
741
743{
744 return LE_getHeader16(NGainNSamples)>>8;
745}
746
747uint32_t LArRodBlockPhysicsV3::getRadd(uint32_t /*adc*/, uint32_t sample) const
748{
749 int index=LE_getHeader16(RawDataBlkOffset)-3+(sample+1)/2;
750 uint32_t x=m_FebBlock[index];
751 x=x&0xffff;
752 return x;
753}
754
755uint16_t LArRodBlockPhysicsV3::getCtrl1(uint32_t /*adc*/) const
756{
758 uint32_t x=m_FebBlock[index];
759 x=x>>16;
760 uint16_t ctrl=x;
761 return ctrl;
762}
763
764uint16_t LArRodBlockPhysicsV3::getCtrl2(uint32_t /*adc*/) const
765{
767 uint32_t x=m_FebBlock[index];
768 x=x&0xffff;
769 uint16_t ctrl=x;
770 return ctrl;
771}
772
773uint16_t LArRodBlockPhysicsV3::getCtrl3(uint32_t /*adc*/) const
774{
776 uint32_t x=m_FebBlock[index];
777 x=x>>16;
778 uint16_t ctrl=x;
779 return ctrl;
780}
781
783{
784 if(getNumberOfWords()<Status2/2) return 0;
785 uint32_t x=getHeader32(Status2);
786 return x;
787}
788
789
791{
792 m_EnergyThreshold=thres;
793}
794
796{
797 m_OffTimeCut=TimeCut;
798}
799
801{
802 m_Ex=(int32_t)Ex;
803 return;
804}
806{
807 m_Ey=(int32_t)Ey;
808 return;
809}
810
812{
813 m_Ez=(int32_t)Ez;
814 return;
815}
816
#define endmsg
static Double_t sc
#define LARBSDBG(text)
This class provides decoding/encoding from/to ROD format.
#define MYLEVEL
int sign(int a)
#define x
virtual uint16_t getCtrl3(uint32_t adc) const
virtual void setOffTimeCut(uint16_t TimeCut)
virtual uint32_t getRadd(uint32_t adc, uint32_t sample) const
virtual uint32_t getNumberOfSamples() const
std::vector< uint32_t > m_EnergyBlock
virtual void setEz(double Ez)
static const uint32_t m_DummyBitMap[4]
std::vector< uint32_t > m_RawDataBlock
std::vector< uint32_t > m_CounterBlkBlock
std::vector< uint32_t > m_SumBlkBlock
virtual void setNextEnergy(const int channel, const int32_t energy, const int32_t time, const int32_t quality, const uint32_t gain)
virtual void setNumberOfSamples(const uint8_t n)
LArRodBlockPhysicsV3(IMessageSvc *msgSvc)
std::vector< uint32_t > m_TimeQualityBlock
virtual void initializeFragment(std::vector< uint32_t > &fragment)
virtual void setEy(double Ey)
virtual void initializeFEB(const uint32_t id)
std::vector< uint32_t > m_GainBlock
const int16_t * m_TimeQualityPtr
virtual void sortDataVector(std::vector< const LArRawChannel * > &)
const LArOnlineID * m_onlineHelper
virtual uint16_t getCtrl1(uint32_t adc) const
const uint16_t * m_CounterPtr
virtual uint32_t getNumberOfGains() const
virtual int getNextRawData(int &channelNumber, std::vector< short > &samples, uint32_t &gain)
const int16_t * m_FebInfoDataPtr
int FebToRodChannel(int ch) const
virtual uint16_t getCtrl2(uint32_t adc) const
const uint32_t * m_RawDataFlagsPtr
std::vector< uint32_t > m_FebInfoBlock
virtual void setEThreshold(uint16_t thres)
virtual uint32_t getStatus() const
virtual void setEx(double Ex)
virtual void setRawData(const int channel, const std::vector< short > &samples, const uint32_t gain)
virtual void setNumberOfGains(const uint8_t n)
int getBit(const uint32_t *const p, const unsigned chan) const
void setHeader32(const unsigned n, const uint32_t w)
uint16_t LE_getVectorHeader16(const unsigned n) const
void LE_setHeader16(const unsigned n, const uint16_t w)
uint32_t getHeader32(const unsigned n) const
void setBit(uint32_t *const p, const unsigned chan)
std::vector< uint32_t > * m_pRODblock
LArRodBlockStructure(IMessageSvc *msgSvc, const std::string &blockType)
std::vector< uint32_t > * m_vFragment
uint16_t LE_getHeader16(const unsigned n) const
uint32_t getNumberOfWords() const
@ LARNGAIN
Definition CaloGain.h:19
Definition index.py:1
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
setEventNumber uint32_t