ATLAS Offline Software
Loading...
Searching...
No Matches
TileCalibDrawerOfc.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef TILECALIBDRAWEROFC_H
6#define TILECALIBDRAWEROFC_H
7
25
29#include "CoralBase/Blob.h"
30#include <stdint.h>
31#include <iostream>
32#include <vector>
33#include <cstdlib>
34#include <algorithm>
35#include <cstring>
36#include <cmath>
37
38#define PHASE_PRECISION 0.1
39
41
42 public:
43
45 enum FIELD{FieldA = 0, FieldB = 1, FieldG = 2, FieldC = 3, FieldDG = 4};
46
49
51 virtual uint16_t getType()const {return TileCalibType::OFC;}
52
64 static TileCalibDrawerOfc* getInstance(coral::Blob& blob
65 , uint16_t objVersion
66 , uint32_t nSamples
67 , int32_t nPhases
68 , uint16_t nChans
69 , uint16_t nGains
70 , const std::string& author = ""
71 , const std::string& comment = ""
72 , uint64_t timeStamp = 0);
73
75 static const TileCalibDrawerOfc* getInstance(const coral::Blob& blob);
76
77
78 //==================================================================
79 //== Accessors to extra header fields
80 //==================================================================
82 uint32_t getNSamples() const;
84 int32_t getNPhases() const;
89 float getPhase(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const;
94 uint32_t getNFields(uint16_t objVersion = 0) const;
95
96 //==================================================================
97 //== Accessors to OFC data
98 //==================================================================
99
109 float getOfc(unsigned int field, unsigned int channel, unsigned int adc, float phase, unsigned int sample) const;
110
118 void fillOfc (unsigned int channel,unsigned int adc, float& phase, float* w_a, float* w_b, float* w_c, float* g, float* dg ) const;
119
120
122 virtual void dump() const { dump(std::cout); }
125 virtual void dump(std::ostream& stm) const;
126
127 //==================================================================
128 //== Setter methods
129 //==================================================================
142 void init(uint16_t objVersion
143 , uint32_t nSamples
144 , int32_t nPhases
145 , uint16_t nChans
146 , uint16_t nGains
147 , const std::string& author=""
148 , const std::string& comment=""
149 , uint64_t timeStamp=0);
150
158 void setOfc(unsigned int field, unsigned int channel, unsigned int adc, float phase, unsigned int sample, float value);
159
164 void setPhases(unsigned int channel, unsigned int adc, const std::vector<float>& phases);
165
166 protected:
168 TileCalibDrawerOfc(const coral::Blob& blob);
170 TileCalibDrawerOfc(coral::Blob& blob);
171
172 private:
173 void initCheck();
174
180 const float* getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const;
181 float* getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase);
182
183 unsigned int getOfcStartOffset(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const;
184
189 const int32_t* getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const;
190 int32_t* getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx);
191
192 unsigned int getPhaseStartOffset(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const;
193
198 unsigned int getPhaseNumber(unsigned int channel, unsigned int adc, float& phase) const;
199};
200
201//
202//______________________________________________________________
203__attribute__((always_inline))
204inline uint32_t TileCalibDrawerOfc::getNSamples() const {
205 return *(static_cast<const uint32_t*>(getAddress(0)));
206}
207
208//
209//______________________________________________________________
210__attribute__((always_inline))
211inline int32_t TileCalibDrawerOfc::getNPhases() const {
212 return *(static_cast<const int32_t*>(getAddress(1)));
213}
214
215//
216//______________________________________________________________
217__attribute__((always_inline))
218inline unsigned int TileCalibDrawerOfc::getPhaseNumber(unsigned int channel, unsigned int adc, float& phase) const {
219
220 if (std::abs(phase) > 1e6F) {
221 // Bad phase is requested (probably, bad value is in the DB)
222 phase = 0.0F;
223 }
224 int db_phase = (int) std::round(phase * (1 / PHASE_PRECISION)); // Phases are stored as int(10*phase) in DB
225 const int32_t* beg = getPhaseStartAddress(channel, adc, 0);
226 const int32_t* end = beg + std::abs(getNPhases());
227 const int32_t* pos = std::lower_bound(beg, end, db_phase);
228
229 if (pos == end || (*pos != db_phase && pos != beg && (*pos - db_phase) > (db_phase - *(pos - 1)))) {
230 --pos;
231 }
232
234 return (pos - beg);
235}
236
237//
238//______________________________________________________________
239__attribute__((always_inline))
240inline float TileCalibDrawerOfc::getPhase(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const {
241 return *(getPhaseStartAddress(channel, adc, phaseIdx)) * PHASE_PRECISION; // Phases are stored as int(10*phase) in DB
242}
243
244//
245//______________________________________________________________
246__attribute__((always_inline))
247inline uint32_t TileCalibDrawerOfc::getNFields(uint16_t objVersion) const {
248 //=== determine objVersion from Blob if default is passed
249 if(objVersion==0) objVersion = getObjVersion();
250
251 if( objVersion == 3){ return 5; }
252 else if(objVersion == 2){ return 4; }
253 else if(objVersion == 1){ return 3; }
254 else{
255 throw TileCalib::VersionConflict("TileCalibDrawerOfc::getNFields", objVersion);
256 }
257}
258
259//
260//______________________________________________________________
261inline float TileCalibDrawerOfc::getOfc(unsigned int field, unsigned int channel, unsigned int adc
262 , float phase, unsigned int sample) const {
263 if(sample >= getNSamples())
264 throw TileCalib::IndexOutOfRange("TileCalibDrawerOfc::getA", sample, getNSamples());
265 return getOfcStartAddress(field, channel, adc, phase)[sample];
266}
267
268inline void TileCalibDrawerOfc::fillOfc (unsigned int channel,unsigned int adc, float& phase
269 , float* w_a, float* w_b, float* w_c, float* g, float* dg) const {
270
271
272 const float* startAddress = getOfcStartAddress(TileCalibDrawerOfc::FieldA, channel, adc, phase);
273 size_t allSamplesSize = getNSamples() * sizeof(float);
274 size_t fieldSize = getObjSizeUint32() * getNSamples();
275
276 memcpy(w_a, startAddress, allSamplesSize);
277 startAddress += fieldSize;
278 memcpy(w_b, startAddress, allSamplesSize);
279 startAddress += fieldSize;
280 memcpy(g, startAddress, allSamplesSize);
281 startAddress += fieldSize;
282 memcpy(w_c, startAddress, allSamplesSize);
283 if (getNFields() > 4) {
284 startAddress += fieldSize;
285 memcpy(dg, startAddress, allSamplesSize);
286 } else {
287 memset(dg, 0, allSamplesSize);
288 }
289}
290
291
292//
293//______________________________________________________________
294inline void TileCalibDrawerOfc::setOfc(unsigned int field,unsigned int channel, unsigned int adc
295 , float phase, unsigned int sample, float value) {
296 if(sample >= getNSamples())
297 throw TileCalib::IndexOutOfRange("TileCalibDrawerOfc::setOfc", sample, getNSamples());
298 getOfcStartAddress(field, channel, adc, phase)[sample] = value;
299}
300
301//
302//______________________________________________________________
303__attribute__((always_inline))
304inline unsigned int TileCalibDrawerOfc::getPhaseStartOffset(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const
305{
306 if(phaseIdx >= static_cast<unsigned int>(std::abs(getNPhases()))){
307 throw TileCalib::IndexOutOfRange("TileCalibDrawerOfc::getPhaseStartAddress", phaseIdx, std::abs(getNPhases()));
308 }
309 //=== use only one phase table for all ADCs
310 if(getNPhases() < 0){
311 channel = 0;
312 adc = 0;
313 }
314 //=== check for out of bounds channel, adc
315 if(channel > getNChans())
316 throw TileCalib::IndexOutOfRange("TileCalibDrawerOfc::getPhaseStartAddress", channel, getNChans());
317 if(adc > getNGains())
318 throw TileCalib::IndexOutOfRange("TileCalibDrawerOfc::getPhaseStartAddress", adc, getNGains());
319
320 //=== extra header
321 unsigned int offset = 2;
322 unsigned int nPhases = std::abs(getNPhases());
323 offset += channel * nPhases * getNGains() + adc * nPhases + phaseIdx;
324 return offset;
325}
326
327//
328//______________________________________________________________
329__attribute__((always_inline))
330inline const int32_t* TileCalibDrawerOfc::getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const
331{
332 return static_cast<const int32_t*>(getAddress(getPhaseStartOffset(channel, adc, phaseIdx)));
333}
334
335//
336//______________________________________________________________
337__attribute__((always_inline))
338inline int32_t* TileCalibDrawerOfc::getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx)
339{
340 return static_cast<int32_t*>(getAddress(getPhaseStartOffset(channel, adc, phaseIdx)));
341}
342
343//
344//______________________________________________________________
345__attribute__((always_inline))
346inline unsigned int TileCalibDrawerOfc::getOfcStartOffset(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const
347{
348 //=== check default policy
349
350 if(channel >= getNChans()) {
351 if (channel <= TileCalibUtils::MAX_CHAN) {
352 channel = 0;
353 } else {
355 if (channel >= getNChans()) channel = 0;
356 }
357 }
358
359
360 if(adc >= getNGains()) {adc = 0;}
361
362 //=== this calculation is only valid for a blob layout according
363 //=== to version 1 or version 2
364 uint16_t objVer = getObjVersion();
365 if(objVer!=1 && objVer!=2 && objVer!=3){
366 throw TileCalib::VersionConflict("TileCalibDrawerOfc::getOfcStartAddress", objVer);
367 }
368
369 //=== number of fields:
370 //=== for Version 1 = OFC1 we have 3 fields: ai, bi, gi
371 //=== for Version 2 = OFC2 we have 4 fields: ai, bi, gi, ci
372 //=== for Version 3 = OFC2 we have 5 fields: ai, bi, gi, ci, dgi
373 unsigned int nField = getNFields(objVer);
374 if(field >= nField){
375 throw TileCalib::IndexOutOfRange("TileCalibDrawerOfc::getOfcStartAddress", field, nField);
376 }
377
378 //=== calculate the offset
379 //=== first get rid of ofc specific header
380 unsigned int nPhaseAbs = std::abs(getNPhases());
381 int nPhaseSgn = getNPhases() < 0 ? -1 : 1;
382 unsigned int offset = 2;
383 if(nPhaseSgn < 0) { offset += nPhaseAbs; }
384 else { offset += nPhaseAbs * getNChans() * getNGains(); }
385
386 //=== add offset for requested field
387 unsigned int iPhase = getPhaseNumber(channel, adc, phase);
388 unsigned int nGain = getNGains();
389 unsigned int nSample = getNSamples();
390 unsigned int lPhase = nSample * nField;
391 unsigned int lAdc = lPhase * nPhaseAbs;
392 unsigned int lChan = lAdc * nGain;
393 offset += channel * lChan + adc * lAdc + iPhase * lPhase + field * nSample;
394
395 return offset;
396}
397
398//
399//______________________________________________________________
400__attribute__((always_inline))
401inline const float* TileCalibDrawerOfc::getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase) const
402{
403 return static_cast<const float*>(getAddress(getOfcStartOffset(field, channel, adc, phase)));
404}
405
406//
407//______________________________________________________________
408__attribute__((always_inline))
409inline float* TileCalibDrawerOfc::getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float& phase)
410{
411 return static_cast<float*>(getAddress(getOfcStartOffset(field, channel, adc, phase)));
412}
413
414#endif
__attribute__((always_inline)) inline uint32_t TileCalibDrawerOfc
#define PHASE_PRECISION
Class for storing Optimal Filtering Coefficients (OFCs) in a coral::Blob.
uint16_t getNChans() const
Returns the number of channels stored in the BLOB.
uint16_t getNGains() const
Returns the number of gains stored for each channel.
TileCalibDrawerBase(const TileCalibDrawerBase &other)
Copy Ctor.
uint16_t getObjVersion() const
Returns the BLOB object version.
uint32_t getObjSizeUint32() const
Returns the size of a data object in units of uint32_t.
const void * getAddress(unsigned int iEle) const
Returns start address of iEle-th basic unit.
TileCalibDrawerOfc(const coral::Blob &blob)
Ctor (const).
unsigned int getPhaseNumber(unsigned int channel, unsigned int adc, float &phase) const
Returns the index for a given phase.
int32_t getNPhases() const
Returns the number of phases (WARNING: Can be negative!)
void setOfc(unsigned int field, unsigned int channel, unsigned int adc, float phase, unsigned int sample, float value)
Sets OFC data.
float getPhase(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const
Returns the stored phase.
virtual void dump() const
Prints out the object content to std::cout.
void fillOfc(unsigned int channel, unsigned int adc, float &phase, float *w_a, float *w_b, float *w_c, float *g, float *dg) const
Fill all OFC for optimazation.
uint32_t getNSamples() const
Returns the number of sample stored.
virtual uint16_t getType() const
Returns TileCalibType::OFC.
unsigned int getOfcStartOffset(unsigned int field, unsigned int channel, unsigned int adc, float &phase) const
void setPhases(unsigned int channel, unsigned int adc, const std::vector< float > &phases)
Sets a phase value.
FIELD
OFC field identifier.
const float * getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float &phase) const
Returns pointer to first data OFC for a given field, ADC & phase.
int32_t * getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx)
void init(uint16_t objVersion, uint32_t nSamples, int32_t nPhases, uint16_t nChans, uint16_t nGains, const std::string &author="", const std::string &comment="", uint64_t timeStamp=0)
Function for initializing a TileCalibDrawerOfc BLOB.
float getOfc(unsigned int field, unsigned int channel, unsigned int adc, float phase, unsigned int sample) const
Returns OFC data.
virtual ~TileCalibDrawerOfc()
Dtor.
float * getOfcStartAddress(unsigned int field, unsigned int channel, unsigned int adc, float &phase)
static TileCalibDrawerOfc * getInstance(coral::Blob &blob, uint16_t objVersion, uint32_t nSamples, int32_t nPhases, uint16_t nChans, uint16_t nGains, const std::string &author="", const std::string &comment="", uint64_t timeStamp=0)
Returns a pointer to a non-const TileCalibDrawerOfc.
const int32_t * getPhaseStartAddress(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const
Returns pointer to the requested phase value.
uint32_t getNFields(uint16_t objVersion=0) const
Returns the number of fields.
unsigned int getPhaseStartOffset(unsigned int channel, unsigned int adc, unsigned int phaseIdx) const
@ OFC
Enum for TileCalibDrawerOfc class.
static const unsigned int MAX_CHAN
Number of channels in drawer.
setWord1 uint16_t
setEventNumber uint32_t