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{//Set pointers to data blocks (pesuming, they exist)
126 {
128 m_SumBlkPtr=reinterpret_cast<const uint32_t*> (m_FebBlock+LE_getHeader16(SumBlkOffset));
129 else m_SumBlkPtr=reinterpret_cast<const uint32_t*>(m_DummyBitMap);
130
132 m_CounterPtr=reinterpret_cast<const uint16_t*>(m_FebBlock+LE_getHeader16(CounterBlkOffset));
133 else m_CounterPtr=reinterpret_cast<const uint16_t*>(m_DummyBitMap);
134
136 m_EnergyPtr=reinterpret_cast<const uint16_t*>(m_FebBlock+LE_getHeader16(EBlkOffset));
137 else m_EnergyPtr=reinterpret_cast<const uint16_t*>(m_DummyBitMap);
138
140 m_GainPtr=reinterpret_cast<const uint32_t*>(m_FebBlock+LE_getHeader16(GainBlkOffset));
141 else m_GainPtr=reinterpret_cast<const uint32_t*>(m_DummyBitMap);
142
144 m_TimeQualityPtr=reinterpret_cast<const int16_t*>(m_FebBlock+LE_getHeader16(TimeQualityBlkOffset));
145 else m_TimeQualityPtr=reinterpret_cast<const int16_t*>(m_DummyBitMap);
146
148 m_RawDataPtr=reinterpret_cast<const int16_t*>(m_FebBlock+LE_getHeader16(RawDataBlkOffset));
149 else m_RawDataPtr=reinterpret_cast<const int16_t*>(m_DummyBitMap);
150
152 m_FebInfoDataPtr=reinterpret_cast<const int16_t*>(m_FebBlock+LE_getHeader16(FebInfoBlkOffset));
153 else m_FebInfoDataPtr=reinterpret_cast<const int16_t*>(m_DummyBitMap);
154
155#ifdef LARBSDBGOUTPUT
156 m_logstr << MYLEVEL << "***********************************************************************"<< endmsg;
157 m_logstr << MYLEVEL << "Energy Pointed values :"<< endmsg;
158 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
159 m_logstr << MYLEVEL << "LE_getHeader16(SumBlkOffset) = "<< MSG::hex << LE_getHeader16(SumBlkOffset) << endmsg;
160 m_logstr << MYLEVEL << "LE_getHeader16(CounterBlkOffset) = "<< MSG::hex << LE_getHeader16(CounterBlkOffset) << endmsg;
161 m_logstr << MYLEVEL << "LE_getHeader16(GainBlkOffset) = "<< MSG::hex << LE_getHeader16(GainBlkOffset) << endmsg;
162 m_logstr << MYLEVEL << "LE_getHeader16(EBlkOffset) = "<< MSG::hex << LE_getHeader16(EBlkOffset) << endmsg;
163 m_logstr << MYLEVEL << "LE_getHeader16(FebInfoBlkOffset) = "<< MSG::hex << LE_getHeader16(FebInfoBlkOffset) << endmsg;
164 m_logstr << MYLEVEL << "LE_getHeader16(TimeQualityBlkOffset) = "<< MSG::hex << LE_getHeader16(TimeQualityBlkOffset) << endmsg;
165 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
166
167 m_logstr << MYLEVEL << "********************* SumBlck ************************************"<< endmsg;
168 for(int toto=0;toto<4;toto++)
169 m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_SumBlkPtr[toto] << endmsg;
170 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
171
172 m_logstr << MYLEVEL << "********************* CounterBlck ************************************"<< endmsg;
173 for(int toto=0;toto<10;toto++) m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_CounterPtr[toto] << endmsg;
174 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
175
176 m_logstr << MYLEVEL << "********************* FebInfoBlck ************************************"<< endmsg;
177 for(int toto=0;toto<4;toto++) m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_FebInfoDataPtr[toto] << endmsg;
178 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
179
180
181 m_logstr << MYLEVEL << "********************* Energies ************************************"<< endmsg;
182 for(int toto=0;toto<128;toto++)
183 m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_EnergyPtr[toto] << endmsg;
184 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
185
186 m_logstr << MYLEVEL << "********************* Time & Quality ************************************"<< endmsg;
187 for(int toto=0;toto<10;toto++)
188 m_logstr << MYLEVEL << "hexa = 0x" << MSG::hex << m_TimeQualityPtr[toto] << endmsg;
189 m_logstr << MYLEVEL << "************************************************************************"<< endmsg;
190#endif
191
192 }
193 else
194 {
195 m_SumBlkPtr=NULL;
196 m_CounterPtr=NULL;
197 m_EnergyPtr=NULL;
198 m_TimeQualityPtr=NULL;
199 m_GainPtr=NULL;
200 m_FebInfoDataPtr=NULL;
201 m_RawDataPtr=NULL;
202 m_RawDataFlagsPtr=NULL;
203 }
204
205 return true;
206}
207
209{ uint16_t oldword=LE_getVectorHeader16(NGainNSamples);
210 LE_setHeader16(NGainNSamples,(oldword & 0xFF00) | n);
211}
212
214{ uint16_t oldword=LE_getVectorHeader16(NGainNSamples);
215 LE_setHeader16(NGainNSamples,(oldword & 0x00FF) | (n<<8));
216}
217
218
219
220void LArRodBlockPhysicsV3::setNextEnergy(const int channel, const int32_t energy,
221 const int32_t time, const int32_t quality, const uint32_t gain)
222{
223 m_logstr << MYLEVEL << "setNextEnergy-------------------->>>>>********************** new format V3 ***********" << endmsg;
224 m_logstr << MYLEVEL << "Channel=" << channel << " energy =" << energy << endmsg;
225 int rcNb=FebToRodChannel(channel);
226 //rcNb ist supposed to equal or bigger than m_EIndex.
227 //In the latter case, we fill up the missing channels with zero
228 if (rcNb<m_EnergyIndex) {
229 m_logstr << MSG::ERROR << "LArRODBlockStructure Error: Internal error. Channels not ordered correctly. rcNb=" << rcNb
230 << " m_EnergyIndex=" << m_EnergyIndex << endmsg;
231 return;
232 }
233
234 //Fill up missing channels with zeros:
235 while (m_EnergyIndex<rcNb)
236 setNextEnergy((int16_t)0,(int16_t)32767,(int16_t)-32767,(uint32_t)0);
237
238
239 // update if needed the hottest cell info
240 if ((energy>0)&&(energy>(int)m_HottestCellEnergy))
241 {
242 m_HottestCellEnergy = abs(energy);
243 m_HottestCellIndex = channel;
244 }
245
246 // transform 32 bits data into 16 bits data
247
248 uint16_t theenergy;
249 uint32_t abse,EncodedE;
250 int16_t thetime,thequality;
251 int32_t sign;
252
253 thetime = (int16_t) time >> 4;
254 thequality = (int16_t) quality;
255
256 sign=(energy>=0?1:-1); // get sign of energy
257 abse=(uint32_t)abs(energy);
258
259 EncodedE=abse; // range 0
260
261 if ((abse>8192)&&(abse<65536))
262 {
263 EncodedE=((abse>>3)|0x2000); // range 1 : drop last 3 bits and put range bits (bits 14 and 13 = 01)
264 }
265 else if ((abse>65535)&&(abse<524288))
266 {
267 EncodedE=((abse>>6)|0x4000); // range 2 : drop last 6 bits and put range bits (bits 14 and 13 = 10)
268 }
269 else if ((abse>524288))
270 {
271 EncodedE=((abse>>9)|0x6000); // range 3 : drop last 9 bits and put range bits (bits 14 and 13 = 11)
272 }
273
274 // treat sign now :
275
276 if (sign<0) EncodedE |= 0x8000;
277 theenergy = (uint16_t) EncodedE;
278
279
280 // Add data...
281
282 m_logstr << MYLEVEL << "setNextEnergy-------------------->>>>> Energy = "<< energy << " Encoded Energy =" << theenergy << endmsg;
283
284 if (abse> m_EnergyThreshold)
285 {
286 setNextEnergy(theenergy,thetime,thequality,gain);
287 }
288 else
289 {
290 setNextEnergy(theenergy,(int16_t)32767,(int16_t)-32767,gain);
291 }
292 return;
293}
294
295//Private function, expects channel number is rod-style ordering
296void LArRodBlockPhysicsV3::setNextEnergy(const uint16_t energy,const int16_t time, const int16_t quality, const uint32_t gain)
297{
298
299 if (m_EnergyIndex>=m_channelsPerFEB) //Use m_EIndex to count total number of channels
300 {m_logstr << MSG::ERROR << "LArRodBlockStructure Error: Attempt to write Energy for channel "
301 << m_EnergyIndex << " channels into a FEB!" <<endmsg;
302 return;
303 }
304 LARBSDBG("LArRodBlockStructure: Setting Energy for channel " << m_EnergyIndex << ". E=" << energy);
305
306 m_logstr << MYLEVEL << "In setNextEnergy-------------------->>>>> time = " << time << " quality=" << quality << endmsg;
307
308 // write for all cells energy and hardware gain
309
310 // Energy
311
312 m_EnergyIndex++; //Use m_EIndex to count the channels put in the Energy block
313
314 ShortLong twoValues{};
315 if (m_EnergyIndex%2) // m_EIndex-1 is even
316 {
317 twoValues.s[0]= energy;
318 twoValues.s[1]=0;
319 }
320 else
321 { //Even number: Merging with previous block
322 uint32_t oneValue=m_EnergyBlock[m_EnergyBlock.size()-1]; //Take last element of vector
323 m_EnergyBlock.pop_back();
324 uint16_t* valptr=reinterpret_cast<uint16_t*>(&oneValue);
325 twoValues.s[0]=valptr[0];
326 twoValues.s[1]=(uint16_t)energy;
327 }
328
329 LARBSDBG("Writing words: val0= " << twoValues.s[0] << " val1= " << twoValues.s[1]);
330 m_EnergyBlock.push_back(twoValues.l);
331 LARBSDBG("Writing Raw data to E block. E=" << energy);
332
333 // update summary block
334 // Summary block is one bit per cell
335
336 int mylocalBitwiseIndex = (int) (m_EnergyIndex-1)%32; // 1 bits in SB per channel
337 if (mylocalBitwiseIndex==0) // need for a new 32 bits word to store SM info of that cell
338 {
339 uint32_t SB;
340 SB = (quality==-32767?0x00000000:0x00000001);
341 m_SumBlkBlock.push_back(SB);
342 }
343 else
344 {
345 uint32_t SB=m_SumBlkBlock[m_GainBlock.size()-1]; //Take out last element of vector
346 m_SumBlkBlock.pop_back();
347 SB=(SB<<1)|(quality==-32767?0x00000000:0x00000001);
348 m_SumBlkBlock.push_back(SB);
349 }
350
351 // Hardware gain
352
353 mylocalBitwiseIndex = (m_EnergyIndex-1)%16; // 2 bits of gain per channel
354 if (mylocalBitwiseIndex==0) // need for a new 32 bits word to store the gain of that cell
355 {
356 m_GainBlock.push_back(gain&0x00000003);
357 }
358 else
359 {
360 uint32_t encodedgains=m_GainBlock[m_GainBlock.size()-1]; //Take out last element of vector
361 m_GainBlock.pop_back();
362 encodedgains=(encodedgains<<2)|(gain&0x00000003);
363 m_GainBlock.push_back(encodedgains);
364 }
365
366 // write Time and Chi2 for cells above HighEnergyCellCut threshold
367
368 if (quality!=-32767) // Do write Time and Chi2 information
369 {
370 // count the number of hot cells
372 // count the number of cells offtime
373 if (abs(time)>m_OffTimeCut) m_numberHotCellOffTime++;
374
375 mylocalBitwiseIndex = (m_numberHotCell-1)%2; // 16 bits per channel
376 ShortLong twoValues{};
377 if (mylocalBitwiseIndex==0) // need for a new 32 bits word to store the time quality of that cell
378 {
379 twoValues.s[0]=0;
380 twoValues.s[1]=0;
381 twoValues.s[0]=(int16_t)(time)|((quality>>10)&0x003F); // Quality on the first 6 bits and Time on the last 10 bits;
382 }
383 else
384 { //Even number: Merging with previous block
385 uint32_t oneValue=m_TimeQualityBlock[m_TimeQualityBlock.size()-1]; //Take last element of vector
386 m_TimeQualityBlock.pop_back();
387 int16_t* valptr=reinterpret_cast<int16_t*>(&oneValue);
388 twoValues.s[0]=valptr[0];
389 twoValues.s[1]=(int16_t)(time)|((quality>>12)&0x003F); // Quality on the first 4 bits and Time on the last 12 bits;
390 }
391 m_TimeQualityBlock.push_back(twoValues.l);
392 }
393
394}
395
396void LArRodBlockPhysicsV3::setRawData(const int channel, const std::vector<short>& samples, const uint32_t gain) {
397 //Convert Feb to Rod Channel Number:
398 int rcNb=FebToRodChannel(channel);
399 if (rcNb>=m_channelsPerFEB)
400 {m_logstr << MSG::ERROR << "Attempt to write Energy for channel " << rcNb << " channels into a FEB!" << endmsg;
401 return;
402 }
403 unsigned int nsamples = LE_getVectorHeader16(NGainNSamples) & 0x00FF;
404 if(samples.size() != nsamples) {
405 m_logstr << MSG::ERROR << "Number of samples mismatch!\n";
406 m_logstr << " nsamples =" << nsamples;
407 m_logstr << " samples.size() =" << samples.size() << endmsg;
408 std::abort();
409 }
410
411 setBit(&m_RawDataBlock[0],rcNb);
412 //Samples have 12 bit and are shifted to the left by 2 bits.
413 // odd samples in high bits, even samples in low bits
414 if((nsamples/2)*2!=nsamples) { //odd number of samples - gain is alone
415 m_RawDataBlock.push_back((gain<<30) | samples[0]<<2);
416 for (unsigned int i=1;i<nsamples;i+=2)
417 m_RawDataBlock.push_back((samples[i+1]<<18) | samples[i]<<2);
418 }
419 else { //even number of samples - gain is packed with sample 0
420 m_RawDataBlock.push_back((gain<<30) | (samples[1]<<18) | samples[0]<<2);
421 for (unsigned int i=2;i<nsamples;i+=2)
422 m_RawDataBlock.push_back((samples[i+1]<<18) | samples[i]<<2);
423 }
424}
425
426
427//For writing: takes existing Fragment and splits it into Feb-Blocks
428void LArRodBlockPhysicsV3::initializeFragment(std::vector<uint32_t>& fragment)
429{
430 m_pRODblock=&fragment; //remember pointer to fragment
431 if (fragment.size()>m_iHeadBlockSize) { //Got filled fragment
432 unsigned int sizeRead=0;
433 //Store existing data in the FEB-Map
434 while (sizeRead<fragment.size()) {
435 std::vector<uint32_t>::iterator FebIter;
436 FebIter=fragment.begin()+sizeRead; //Store pointer to current Feb-Header
437 m_FebBlock=&(*FebIter); //Set m_FebBlock in order to use getHeader-functions.
438 uint32_t currFEBid=getHeader32(FEBID); //Get this FEB-ID
439 uint16_t currFebSize=getNumberOfWords(); //Size of this FEB-Block
440 if (FebIter+currFebSize>fragment.end()) {
441 fragment.clear(); //Clear existing vector
442 m_logstr << MSG::ERROR << "Got inconsistent ROD-Fragment!" << endmsg;
443 return;
444 }
445 m_mFebBlocks[currFEBid].assign(FebIter,FebIter+currFebSize); //Copy data from ROD-fragment into FEB-Block
446 sizeRead+=currFebSize+m_MiddleHeaderSize; //6 is the middle header size
447 LARBSDBG("Found FEB-id " << currFEBid << " in existing ROD-Fragment");
448 } // end while
449 }
450 fragment.clear(); //Clear existing vector
451 return;
452}
453
454//For writing: Initalizes a single FEB-Block
456{
458 if (m_vFragment->size()<m_iHeadBlockSize) //Got empty or spoiled fragment
459 {
460 m_vFragment->resize(m_iHeadBlockSize,0); //Initialize FEB-Header
461 setHeader32(FEBID,id); //Set Feb ID
462 }
463
464 m_SumBlkBlock.resize(0);
465 m_CounterBlkBlock.resize(0);
466 m_EnergyBlock.resize(0);
467 m_GainBlock.resize(0);
468 m_FebInfoBlock.resize(0);
469 m_RawDataBlock.resize(0);
470
472
473}
474
476{
477//Complete non-complete Energy block
479 setNextEnergy((uint16_t)0,(int16_t)32767,(int32_t)-32767,(uint32_t)0);//E=0,t=32767,q=-32767,G=0
480
481 uint16_t n;
482 uint16_t BlockOffset;
483
484 // Summary block....
485 n = m_SumBlkBlock.size();
487 //Check if Summary Block exists and is not yet part of the fragment
488 LARBSDBG("Checking for Summary Block n=" << n << "BlockOffset=" << BlockOffset);
489 if (n && !BlockOffset)
490 {
493 m_logstr << MSG::DEBUG << "In finalizeFEB-------------------->>>>> " << "Checking for Summary Block : length= " << n << " BlockOffset=" << BlockOffset << endmsg;
494 for (unsigned i=0;i<n;i++)
495 m_vFragment->push_back(m_SumBlkBlock[i]);
496 }
497
498 // Counter block....
499
500 // fill info from counters
501 ShortLong twoValues{};
502 twoValues.s[0]=(uint16_t)m_numberHotCell;
503 twoValues.s[1]=(uint16_t)m_numberHotCellOffTime;
504 m_CounterBlkBlock.push_back(twoValues.l);
505
506 twoValues.s[0]=(uint16_t)m_EnergyThreshold;
507 twoValues.s[1]=(uint16_t)m_OffTimeCut;
508 m_CounterBlkBlock.push_back(twoValues.l);
509
510 // Write the Energy threshold used to determine which cell is a hot cell in the first
511 // 32 bit word of the counters
512 // Write the Energy Ex of the ROD block in a 32 bits word
513 // Write the Energy Ey of the ROD block in a 32 bits word
514 // Ex and Ey have to be 32 bits words as they are sums of multiple 16 bits words
515
516 uint32_t* aux = (uint32_t*)&m_Ex;
517 m_CounterBlkBlock.push_back(*aux);
518 aux = (uint32_t*)&m_Ey;
519 m_CounterBlkBlock.push_back(*aux);
520
521 // write the hottest cell index for that FEB and its energy in MeV
522
523 twoValues.s[0]=(uint16_t)((m_HottestCellIndex<<9)|((uint16_t)((m_HottestCellEnergy>>16))&0x01FF));
524 twoValues.s[1]=(uint16_t)m_HottestCellEnergy;
525 m_CounterBlkBlock.push_back(twoValues.l);
526
527 aux = (uint32_t*)&m_Ez;
528 m_CounterBlkBlock.push_back(*aux);
529
530 n = m_CounterBlkBlock.size();
532 //Check if Counter Block exists and is not yet part of the fragment
533 LARBSDBG("Checking for Counter Block n=" << n << "BlockOffset=" << BlockOffset);
534 if (n && !BlockOffset)
535 {
538 m_logstr << MSG::INFO << "In finalyseFEB-------------------->>>>> " << "Checking for Counter Block : length= " << n << " BlockOffset=" << BlockOffset << endmsg;
539 for (unsigned i=0;i<n;i++)
540 m_vFragment->push_back(m_CounterBlkBlock[i]);
541 }
542
543 // Energy block...
544 n = m_EnergyBlock.size();
545 BlockOffset=LE_getVectorHeader16(EBlkOffset);
546 LARBSDBG("Checking Energy Block n=" << n << "BlockOffset=" << BlockOffset);
547 //Check if Energy-Block exists and is not yet part of the fragment
548 if (n && !BlockOffset)
549 {
551 BlockOffset=LE_getVectorHeader16(EBlkOffset);
552 m_logstr << MSG::DEBUG << "In finalyseFEB-------------------->>>>> " << "Checking for Energy Block : length= " << n << " BlockOffset=" << BlockOffset << endmsg;
553 for(unsigned int i=0;i<n;i++)
554 m_vFragment->push_back(m_EnergyBlock[i]);
555 }
556
557 // Gain block...
558 n = m_GainBlock.size();
560 LARBSDBG("Checking Gain Block n=" << n << "BlockOffset=" << BlockOffset);
561 //Check if Gain-Block exists and is not yet part of the fragment
562 if (n && !BlockOffset)
563 {
566 for(unsigned int i=0;i<n;i++)
567 m_vFragment->push_back(m_GainBlock[i]);
568 }
569
570
571 // FeBInfo Block... // offline encoder just put dummy info there
572 for (int nword=0; nword<m_NFebInfoBlkWords ; nword++)
573 m_FebInfoBlock.push_back(0L);
574
575 n = m_FebInfoBlock.size();
577 LARBSDBG("Checking FebInfo Block n=" << n << "BlockOffset=" << BlockOffset);
578 //Check if Gain-Block exists and is not yet part of the fragment
579 if (n && !BlockOffset)
580 {
583 for(unsigned int i=0;i<n;i++)
584 m_vFragment->push_back(m_FebInfoBlock[i]);
585 }
586
587 // Time and Quality block
588 n = m_TimeQualityBlock.size();
590 LARBSDBG("Checking Time and Quality Block n=" << n << "BlockOffset=" << BlockOffset);
591 //Check if Time and Quality Block exists and is not yet part of the fragment
592 if (n && !BlockOffset)
593 {
596 m_logstr << MSG::DEBUG << "In finalyseFEB-------------------->>>>> " << "Checking for Time and Quality Block : length= " << n << " BlockOffset=" << BlockOffset << endmsg;
597 for(unsigned int i=0;i<n;i++)
598 m_vFragment->push_back(m_TimeQualityBlock[i]);
599 }
600
601 // Raw data
602 LARBSDBG("Checking Raw Data Block");
603 n = m_RawDataBlock.size();
605 LARBSDBG("Checking Raw Data Block. n=" << n << "BlockOffset=" << BlockOffset);
606 //Check if Raw Data block exists and is not yet part of the fragment
607 if ((n>m_NFlaggingWords) && (!BlockOffset))
608 {
610 for(unsigned int i=0;i<n;i++)
611 m_vFragment->push_back(m_RawDataBlock[i]);
612 }
614
615 m_logstr << MYLEVEL << "***********************************************************************"<< endmsg;
616 m_logstr << MYLEVEL << "m_HottestCellIndex : "<< m_HottestCellIndex << endmsg;
617 m_logstr << MYLEVEL << "m_HottestCellEnergy : "<< m_HottestCellEnergy << endmsg;
618 m_logstr << MYLEVEL << "***********************************************************************"<< endmsg;
619 m_logstr << MYLEVEL << "m_Ex : "<< m_Ex << endmsg;
620 m_logstr << MYLEVEL << "m_Ey : "<< m_Ey << endmsg;
621 m_logstr << MYLEVEL << "***********************************************************************"<< endmsg;
622
623
624 clearBlocks();
625 return;
626}
627
628
630{
631 FEBMAPTYPE::const_iterator feb_it_b=m_mFebBlocks.begin();
632 FEBMAPTYPE::const_iterator feb_it_e=m_mFebBlocks.end();
633 FEBMAPTYPE::const_iterator feb_it;
634 for (feb_it=feb_it_b;feb_it!=feb_it_e;++feb_it) {
635 if (feb_it!=feb_it_b) //Not first Feb
637
638 //Add feb data to rod data block
639 m_pRODblock->insert (m_pRODblock->end(),
640 feb_it->second.begin(), feb_it->second.end());
641 } //end for feb_it
642
643 m_mFebBlocks.clear();
644 return;
645}
646
647int LArRodBlockPhysicsV3::getNextRawData(int& channelNumber, std::vector<short>& samples, uint32_t& gain)
648{
649 LARBSDBG("in LArRodBlockPhysicsV3::getNextRawData.");
650 LARBSDBG("m_RawDataCounter=" << m_RawDataCounter << " m_RawDataIndex="<< m_RawDataIndex);
651 LARBSDBG("m_channelsPerFEB=" << m_channelsPerFEB);
652 if(m_FebBlockSize<=m_iHeadBlockSize) return 0;
654
655 const int flags=(int) LE_getHeader16(RawDataBlkOffset);
656 if (!flags)
657 return 0; //Block not existing
658 if (m_RawDataCounter>=m_channelsPerFEB) //Already beyond maximal number of channels
659 return 0;
660
661 LARBSDBG("Flags="<<flags);
662
663 while (!getBit(m_RawDataFlagsPtr,m_RawDataCounter)) //Look for next filled channel
665 LARBSDBG("RawDataCounter ist now " << m_RawDataCounter);
666 if (m_RawDataCounter>=m_channelsPerFEB) //No more channel available
667 return 0;
668 }
669 LARBSDBG("Found filled channel at positon " << m_RawDataCounter);
670 //Found next filled channel
671 channelNumber=m_RawDataCounter;
672 unsigned int nsamples = LE_getHeader16(NGainNSamples) & 0x00FF;
673 LARBSDBG("This run has " << nsamples << " samples");
674 int index = m_RawDataIndex*nsamples;
675 LARBSDBG( "index="<<index);
677 LARBSDBG("In getnextRawData(). index= " << index);
678 gain=3-((m_GainPtr[channelNumber/16] >> (channelNumber%16)*2) & 0x3);
679 if(gain>=CaloGain::LARNGAIN) return 0;
680 for(unsigned int i=0;i<nsamples;i++) {
681 uint16_t x;
682 if((index+i)%2==0)
683 x=m_RawDataPtr[index+i+1];
684 else
685 x=m_RawDataPtr[index+i-1];
686 samples.push_back((short) (x & 0xfff));
687 }
689
690 if (m_rearrangeFirstSample && m_rearrangeFirstSample<samples.size()) //FIXME: Very ugly hack! See explanation in LArRodDecoder.h file
691 {//Change e.g. 3 0 1 2 4 to 0 1 2 3 4
692 short movedSample=samples[0];
693 for (unsigned i=1;i<=m_rearrangeFirstSample;i++)
694 samples[i-1]=samples[i];
695 samples[m_rearrangeFirstSample]=movedSample;
696 }
697
698 return 1;
699}
700
701
702
703
704//Sort functions & ordering relation:
705template<class RAWDATA>
706bool LArRodBlockPhysicsV3::operator ()
707 (const RAWDATA* ch1, const RAWDATA* ch2) const
708{
709 HWIdentifier id1 = ch1->channelID();
710 HWIdentifier id2 = ch2->channelID();
711
712 HWIdentifier febId1= m_onlineHelper->feb_Id(id1);
713 HWIdentifier febId2= m_onlineHelper->feb_Id(id2);
714
715 if(febId1 == febId2 ){
716 int cId1 = m_onlineHelper->channel(id1);
717 int cId2 = m_onlineHelper->channel(id2);
718 return FebToRodChannel(cId1) < FebToRodChannel(cId2);
719 }
720
721 return febId1 < febId2 ;
722}
723
724void LArRodBlockPhysicsV3::sortDataVector(std::vector<const LArRawChannel*>& vRC)
725{std::sort(vRC.begin(),vRC.end(),*this);}
726
727void LArRodBlockPhysicsV3::sortDataVector( std::vector<const LArDigit*>& vDigit)
728{std::sort(vDigit.begin(),vDigit.end(),*this);
729}
730
732{
733 return LE_getHeader16(NGainNSamples)&0xff;
734}
735
737{
738 return LE_getHeader16(NGainNSamples)>>8;
739}
740
741uint32_t LArRodBlockPhysicsV3::getRadd(uint32_t /*adc*/, uint32_t sample) const
742{
743 int index=LE_getHeader16(RawDataBlkOffset)-3+(sample+1)/2;
744 uint32_t x=m_FebBlock[index];
745 x=x&0xffff;
746 return x;
747}
748
749uint16_t LArRodBlockPhysicsV3::getCtrl1(uint32_t /*adc*/) const
750{
752 uint32_t x=m_FebBlock[index];
753 x=x>>16;
754 uint16_t ctrl=x;
755 return ctrl;
756}
757
758uint16_t LArRodBlockPhysicsV3::getCtrl2(uint32_t /*adc*/) const
759{
761 uint32_t x=m_FebBlock[index];
762 x=x&0xffff;
763 uint16_t ctrl=x;
764 return ctrl;
765}
766
767uint16_t LArRodBlockPhysicsV3::getCtrl3(uint32_t /*adc*/) const
768{
770 uint32_t x=m_FebBlock[index];
771 x=x>>16;
772 uint16_t ctrl=x;
773 return ctrl;
774}
775
777{
778 if(getNumberOfWords()<Status2/2) return 0;
779 uint32_t x=getHeader32(Status2);
780 return x;
781}
782
783
785{
786 m_EnergyThreshold=thres;
787}
788
790{
791m_OffTimeCut=TimeCut;
792}
793
795{
796 m_Ex=(int32_t)Ex;
797 return;
798}
800{
801 m_Ey=(int32_t)Ey;
802 return;
803}
804
806{
807 m_Ez=(int32_t)Ez;
808 return;
809}
810
#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