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