ATLAS Offline Software
Loading...
Searching...
No Matches
CaloBCIDCoeffs Class Reference

Luminosity-dependent pileup offset correction conditions object. More...

#include <CaloBCIDCoeffs.h>

Collaboration diagram for CaloBCIDCoeffs:

Public Member Functions

 CaloBCIDCoeffs (const std::vector< HWIdentifier > &hwids, const LArOnlineID_Base &online_id, const ILArOFC &ofcs, const ILArShape &shapes, const ILArMinBiasAverage &minbias)
 Constructor.
void calc (const float *lumi, CxxUtils::vec_aligned_vector< float > &out) const
 Perform the calculation for a given set of per-bunch luminosities.
size_t nshapes () const
 Return the number of shape points per cell.
size_t nsamples_coeff () const
 Return the number of samples per cell used in the calculation (after padding).

Static Public Attributes

static constexpr size_t CHUNKSIZE = 8
 Number of cells that we calculate at one time.

Private Member Functions

float & coeff (size_t icoeff, size_t icell)
 Indexing into m_coeffs.
void fillCoeffs (const std::vector< HWIdentifier > &hwids, const LArOnlineID_Base &online_id, const ILArOFC &ofcs, const ILArShape &shapes, const ILArMinBiasAverage &minbias)
 Initialize all coefficients.
void findCellCoeffs (const float *ofcs, const float *shapes, bool ishec, std::vector< float > &cell_coeffs) const
 Find coefficients for one cell.

Private Attributes

unsigned int m_ncell
 Number of cells.
unsigned int m_npad
 Number of padding cells we need to add to get a multiple of CHUNKSIZE.
unsigned int m_ncoeff
 Number of coefficients per cell (length of dot product).
unsigned int m_nsamples
 Number of samples per cell (length of OFC vector).
unsigned int m_nsamples_coeff
 Number of samples per cell used in the calculation, after padding.
unsigned int m_nshapes
 Number of shape points per cell.
CxxUtils::vec_aligned_vector< float > m_coeffs
 Storage for coeffients, m_ncoeff per cell, laid out in groups of CHUNKSIZE like this: icoeff0, icell 0 ... icoeff0, icell CHUNKSIZE-1 icoeff1, icell 0 ... icoeff(m_ncoeff-1) icell CHUNKSIZE-1 icoeff0, icell CHUNKSIZE ...

Detailed Description

Luminosity-dependent pileup offset correction conditions object.

This implements the cell-by-cell luminosity-dependent offset correction for adjacent bunches. This was previously implemented as an algorithm (CaloBCIDAvgAlg), but it took too long to be usable in the trigger. We can, however, speed it up drastically by preformatting the constant data and saving it in a conditions object. The pieces of that related to calibration are stored here. The per-bunch luminosity information is stored in a separate conditions object, as it has a different lifetime.

The correction is carried out for each cell. Symmetry is taken into account via LArMCSym, and the calculation is done for only one cell in each symmetry group, which results in a total of 1833 cells. The calculation depends on the per-cell pulse shape S_j (j=0..N_S-1), the per-cell optimial-filter coeffients O_i (i=0..N_O-1), the per-cell average minibias M, and the per-bunch luminosity L_k (k=0..NBCID-1). It can be written as:

Offset = M \Sum_i O_i \Sum_j S_j L_(BCID+i-j)

where the luminosity array L is taken to be circular (i.e., the indexing is mod NBCID). (In cases with four samples, the luminosity index is offset by 1 for HEC cells.)

This can be rewritten grouping together terms which access the same L index:

Offset = \Sum_m (\Sum_l M O_(m+l) S_l ) L_(BCID+m)

Everything inside the parentheses can be precomputed, reducing the calculation to a dot product between a vector of constants and an appropriate subrange of the luminosity vector. The circular nature of the luminosity vector can be handled by padding the beginning and end and duplicating the values there. The special case mentioned above for four samples is handled by treating things as if we actually have five samples and padding the OFC coefficients with a zero at either the beginning or end (depending on whether the cell is HEC).

The S_j values are not positive definite (the shape is normalized to zero). So when we do the sums above, we're adding terms that are both positive and negative. This can result in some loss of precision, and means that when we reorder the sum as above, we shouldn't expect to get exactly the same result.

This calculation vectorizes well. It is better to vectorize over cells, to avoid dependencies between steps. We always do this in groups of 8 (regardless of platform) so that sums are always in the same order. This means that we need to pad things out so that the number of cells is a multiple of 8.

The optimized and vectorized calculation is found to be about a factor of 100 faster than the original naive implementation.

Definition at line 83 of file CaloBCIDCoeffs.h.

Constructor & Destructor Documentation

◆ CaloBCIDCoeffs()

CaloBCIDCoeffs::CaloBCIDCoeffs ( const std::vector< HWIdentifier > & hwids,
const LArOnlineID_Base & online_id,
const ILArOFC & ofcs,
const ILArShape & shapes,
const ILArMinBiasAverage & minbias )

Constructor.

Parameters
hwidsList of cell HWIDs for which we need to do the calculation.
online_idOnline ID helper.
ofcsOFC coefficient conditions object.
shapesPulse shape conditions object.
minbiasMinimum bias conditions object.

Definition at line 138 of file CaloBCIDCoeffs.cxx.

143{
144 // Number of cells we're calculating.
145 m_ncell = hwids.size();
146
147 // Number of cells of padding we need to add to get a multiple of CHUNKSIZE.
149 if (m_npad == CHUNKSIZE) m_npad = 0;
150
151 // Number of shape / samples.
152 if (hwids.empty()) {
153 m_nsamples = 0;
154 m_nshapes = 0;
155 }
156 else {
157 m_nsamples = ofcs.OFC_a (hwids[0], 0).size();
158 m_nshapes = shapes.Shape (hwids[0], 0).size();
159 }
160
161 // Special case for 4 samples: treat this case as if we actually
162 // had 5 samples, just with 0-padding.
164 if (m_nsamples == 4) {
166 }
167
168 // Number of coefficients (length of the dot product).
169 m_ncoeff = (m_nshapes-1) + 1 + (m_nsamples_coeff-1);
170
171 // Initialize coeffients.
172 fillCoeffs (hwids, online_id, ofcs, shapes, minbias);
173}
unsigned int m_nsamples
Number of samples per cell (length of OFC vector).
unsigned int m_ncell
Number of cells.
unsigned int m_npad
Number of padding cells we need to add to get a multiple of CHUNKSIZE.
static constexpr size_t CHUNKSIZE
Number of cells that we calculate at one time.
unsigned int m_nsamples_coeff
Number of samples per cell used in the calculation, after padding.
unsigned int m_nshapes
Number of shape points per cell.
unsigned int m_ncoeff
Number of coefficients per cell (length of dot product).
void fillCoeffs(const std::vector< HWIdentifier > &hwids, const LArOnlineID_Base &online_id, const ILArOFC &ofcs, const ILArShape &shapes, const ILArMinBiasAverage &minbias)
Initialize all coefficients.
virtual OFCRef_t OFC_a(const HWIdentifier &id, int gain, int tbin=0) const =0
access to OFCs by online ID, gain, and tbin (!=0 for testbeam)
virtual ShapeRef_t Shape(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0

Member Function Documentation

◆ calc()

void CaloBCIDCoeffs::calc ( const float * lumi,
CxxUtils::vec_aligned_vector< float > & out ) const

Perform the calculation for a given set of per-bunch luminosities.

Parameters
lumiPer-bunch luminosities. Should be properly offset in the BCID vector. Will access lumi[-(nshapes-1)] to lumi[nsamples-1], inclusive.
outOutput per-cell offsets.
lumPer-bunch luminosities. Should be properly offset in the BCID vector. Will access lumi[-(nshapes-1)] to lumi[nsamples-1], inclusive.
outOutput per-cell offsets.

Definition at line 277 of file CaloBCIDCoeffs.cxx.

279{
280
281 //call the implementation method
282 calcImpl(lumi, m_ncell, m_ncoeff, m_nshapes, m_npad, m_coeffs, out);
283
284}
CxxUtils::vec_aligned_vector< float > m_coeffs
Storage for coeffients, m_ncoeff per cell, laid out in groups of CHUNKSIZE like this: icoeff0,...

◆ coeff()

float & CaloBCIDCoeffs::coeff ( size_t icoeff,
size_t icell )
inlineprivate

Indexing into m_coeffs.

Parameters
icoeffCoeffienct index.
icellCell index.

Definition at line 165 of file CaloBCIDCoeffs.h.

166 {
167 size_t chunk = icell / CHUNKSIZE;
168 size_t ndx = chunk * m_ncoeff * CHUNKSIZE + icoeff * CHUNKSIZE + (icell%CHUNKSIZE);
169 return m_coeffs[ndx];
170 }

◆ fillCoeffs()

void CaloBCIDCoeffs::fillCoeffs ( const std::vector< HWIdentifier > & hwids,
const LArOnlineID_Base & online_id,
const ILArOFC & ofcs,
const ILArShape & shapes,
const ILArMinBiasAverage & minbias )
private

Initialize all coefficients.

Parameters
hwidsList of cell HWIDs for which we need to do the calculation.
online_idOnline ID helper.
ofcsOFC coefficient conditions object.
shapesPulse shape conditions object.
minbiasMinimum bias conditions object.

Definition at line 184 of file CaloBCIDCoeffs.cxx.

189{
190 // Reserve space for all coefficients.
191 m_coeffs.resize (m_ncoeff * (m_ncell + m_npad));
192
193 // Temporary vector to hold coefficients for one cell.
194 // Declare outside the loop to reduce allocations.
195 std::vector<float> cell_coeffs (m_ncoeff);
196
197 for (size_t icell = 0; icell < m_ncell; ++icell) {
198 HWIdentifier hwid = hwids[icell];
199 float cell_minbias = minbias.minBiasAverage (hwid);
200
201 // If cell_minbias <= 0, we want the result to be 0.
202 // So just leave the coefficients as 0 in that case.
203 if (cell_minbias > 0) {
204 // Calculate coefficients for one cell.
205 findCellCoeffs (ofcs.OFC_a (hwid, 0).data(),
206 shapes.Shape (hwid, 0).data(),
207 online_id.isHECchannel (hwid),
208 cell_coeffs);
209
210 // Enter them into the coefficients array in the proper places.
211 // Here, we also multiply everything by minbias.
212 for (size_t icoeff = 0; icoeff < m_ncoeff; ++icoeff) {
213 coeff(icoeff, icell) = cell_coeffs[icoeff] * cell_minbias;
214 }
215 }
216 }
217}
float & coeff(size_t icoeff, size_t icell)
Indexing into m_coeffs.
void findCellCoeffs(const float *ofcs, const float *shapes, bool ishec, std::vector< float > &cell_coeffs) const
Find coefficients for one cell.
virtual const float & minBiasAverage(const HWIdentifier &id) const =0
access to average of E in minimum bias events index by Identifier
virtual bool isHECchannel(const HWIdentifier id) const =0

◆ findCellCoeffs()

void CaloBCIDCoeffs::findCellCoeffs ( const float * ofcs,
const float * shapes,
bool ishec,
std::vector< float > & cell_coeffs ) const
private

Find coefficients for one cell.

Parameters
ofcsArray of OFC coefficients for this cell.
shapesArray of shape points for this cell.
ishecTrue if this is a HEC cell.
cell_coeffsOutput coefficient array.

Definition at line 227 of file CaloBCIDCoeffs.cxx.

231{
232 // Initialize output to zero.
233 std::fill (cell_coeffs.begin(), cell_coeffs.end(), 0);
234
235 const unsigned nsamples_coeff = m_nsamples_coeff;
236 const unsigned nshapes = m_nshapes;
237
238 // Loop over all combinations of sample / shape.
239 for (size_t i = 0; i < nsamples_coeff; ++i) {
240 for (size_t j = 0; j < nshapes; ++j) {
241 // Index of coefficient we're filling.
242 size_t ndx = (nshapes-1) + i - j;
243
244 // Find OFC coefficient.
245 float ofc = 0;
246 if (m_nsamples == 4)
247 {
248 // Special case for 4 samples: we actually calclate with five samples,
249 // but pad with 0 at either the beginning or end (depending on
250 // whether this is a HEC cell).
251 if (ishec) {
252 if (i > 0) ofc = ofcs[i-1];
253 }
254 else {
255 if (i < 4) ofc = ofcs[i];
256 }
257 }
258 else {
259 ofc = ofcs[i];
260 }
261
262 // Do the multiplication and sum.
263 cell_coeffs.at(ndx) += ofc * shapes[j];
264 }
265 }
266}
size_t nsamples_coeff() const
Return the number of samples per cell used in the calculation (after padding).
size_t nshapes() const
Return the number of shape points per cell.

◆ nsamples_coeff()

size_t CaloBCIDCoeffs::nsamples_coeff ( ) const
inline

Return the number of samples per cell used in the calculation (after padding).

Definition at line 224 of file CaloBCIDCoeffs.h.

225{
226 return m_nsamples_coeff;
227}

◆ nshapes()

size_t CaloBCIDCoeffs::nshapes ( ) const
inline

Return the number of shape points per cell.

Definition at line 213 of file CaloBCIDCoeffs.h.

214{
215 return m_nshapes;
216}

Member Data Documentation

◆ CHUNKSIZE

size_t CaloBCIDCoeffs::CHUNKSIZE = 8
staticconstexpr

Number of cells that we calculate at one time.

Definition at line 126 of file CaloBCIDCoeffs.h.

◆ m_coeffs

CxxUtils::vec_aligned_vector<float> CaloBCIDCoeffs::m_coeffs
private

Storage for coeffients, m_ncoeff per cell, laid out in groups of CHUNKSIZE like this: icoeff0, icell 0 ... icoeff0, icell CHUNKSIZE-1 icoeff1, icell 0 ... icoeff(m_ncoeff-1) icell CHUNKSIZE-1 icoeff0, icell CHUNKSIZE ...

Definition at line 157 of file CaloBCIDCoeffs.h.

◆ m_ncell

unsigned int CaloBCIDCoeffs::m_ncell
private

Number of cells.

Definition at line 130 of file CaloBCIDCoeffs.h.

◆ m_ncoeff

unsigned int CaloBCIDCoeffs::m_ncoeff
private

Number of coefficients per cell (length of dot product).

Definition at line 136 of file CaloBCIDCoeffs.h.

◆ m_npad

unsigned int CaloBCIDCoeffs::m_npad
private

Number of padding cells we need to add to get a multiple of CHUNKSIZE.

Definition at line 133 of file CaloBCIDCoeffs.h.

◆ m_nsamples

unsigned int CaloBCIDCoeffs::m_nsamples
private

Number of samples per cell (length of OFC vector).

Definition at line 139 of file CaloBCIDCoeffs.h.

◆ m_nsamples_coeff

unsigned int CaloBCIDCoeffs::m_nsamples_coeff
private

Number of samples per cell used in the calculation, after padding.

Definition at line 142 of file CaloBCIDCoeffs.h.

◆ m_nshapes

unsigned int CaloBCIDCoeffs::m_nshapes
private

Number of shape points per cell.

Definition at line 145 of file CaloBCIDCoeffs.h.


The documentation for this class was generated from the following files: