ATLAS Offline Software
Loading...
Searching...
No Matches
BunchLumisCondAlg.cxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration.
3 */
10
11
12#include "BunchLumisCondAlg.h"
16#include "CxxUtils/restrict.h"
17#include "CxxUtils/vectorize.h"
18#include "CoralBase/Blob.h"
19#include "CoolKernel/IObject.h"
20#include <stdint.h>
21
22
24
25
26
27namespace {
28
29
30// Total number of BCIDs in one turn - this must match value used in /TDAQ/OLC/BUNCHLUMIS for storage mode 1
31const unsigned int TOTAL_LHC_BCIDS = 3564;
32
33
34} // anonymous namespace
35
36
40StatusCode
42{
45 ATH_CHECK( m_bunchLumisOutputKey.initialize() );
46 return StatusCode::SUCCESS;
47}
48
49
58StatusCode
59BunchLumisCondAlg::unpackLumis (const coral::Blob& blob,
60 const std::vector<unsigned int>& luminousBunches,
61 float avgRawLumi,
62 std::vector<float>& rawLumiOut) const
63{
64 // Figure out Mika's blob packing mode (should really have a utility for this)
65 // See description: https://twiki.cern.ch/twiki/bin/viewauth/Atlas/CoolOnlineData#Folder_TDAQ_OLC_BUNCHLUMIS
66
67 const uint8_t* ATH_RESTRICT pchar = static_cast<const uint8_t*>(blob.startingAddress()); // First byte holds storage size and mode
68 unsigned int bss = ((*pchar) % 100) / 10; // Byte storage size
69 unsigned int smod = ((*pchar) % 10); // Storage mode
70
71 ATH_MSG_DEBUG( "BunchRawInstLumi blob found with storage mode " << smod << " and byte storage size " << bss );
72
73 // Check blob length and point pchar to start of raw lumi data
74 unsigned int bloblength = 0;
75 unsigned int nbcids = 0;
76
77 ++pchar;
78 const uint8_t* ATH_RESTRICT pbcids = nullptr;
79
80 // Treat different storage modes independently
81 switch (smod) {
82 case 0:
83 // Packed according to luminousBunches
84 // Make sure tool is configured
85 if (luminousBunches.empty()) {
86 ATH_MSG_ERROR("Can't unpack using luminousBunches!");
87 return StatusCode::SUCCESS;
88 }
89
90 nbcids = luminousBunches.size();
91 bloblength = bss * nbcids + 1;
92 break;
93
94 case 1:
95 // Full orbit stored
96 nbcids = TOTAL_LHC_BCIDS;
97 bloblength = bss * nbcids + 1;
98 break;
99
100 case 2:
101 // Self describing length, with 2-byte length followed by 2-byte BCID vector, then data
102 nbcids = CxxUtils::get_unaligned16 (pchar);
103 pbcids = pchar;
104 bloblength = (2+bss)*nbcids + 3; // 2-bytes for vector plus bss plus 2 bytes for vector length, plus one byte for packing
105 pchar += 2*nbcids; // Advance pchar past bicd vector list to raw data
106 // ATH_MSG_DEBUG( "Found mode 2 with " << nbcids << " BCIDs" );
107 break;
108
109 default:
110 ATH_MSG_ERROR( "BunchRawInstLumi blob found with unknown storage mode " << smod << "!" );
111 return StatusCode::FAILURE;
112 }
113
114 // Check blob size against needed length. Give up if these don't match
115 if (static_cast<cool::UInt32>(blob.size()) != bloblength) {
116 ATH_MSG_ERROR( "BunchRawInstLumi blob found with length " << blob.size() <<
117 " in storage mode " << smod << " with size " << bss <<
118 ", expecting " << bloblength << "!" );
119 return StatusCode::FAILURE;
120 }
121
122 // Length is correct, read raw data according to packing scheme
123 // Some schemes are relative and must be renormalized, while the float/double schemes are absolute values - *pay attention!*
124 std::vector<float> rawLumi;
125 rawLumi.clear();
126 rawLumi.reserve (nbcids);
127
128 // Different depending upon bytes allocated (this is ugly, but it works)
129 // pchar is pointing to the start of the data (past first byte of blob)
130 switch (bss) {
131
132 case 1: { // 1-byte integers, just use pchar
133 float scale = avgRawLumi / 100;
134 for (unsigned int i=0; i<nbcids; i++) {
135 float val = (*pchar++) * scale;
136 rawLumi.push_back(val);
137 }
138 break;
139 }
140
141 case 2: { // 2-byte integers
142 float scale = avgRawLumi / (100*100);
143 for (unsigned int i=0; i<nbcids; i++) {
144 float val = CxxUtils::get_unaligned16(pchar) * scale;
145 rawLumi.push_back(val);
146 }
147 break;
148 }
149
150 case 4: // 4-byte floats
151 for (unsigned int i=0; i<nbcids; i++) {
152 rawLumi.push_back (CxxUtils::get_unaligned_float(pchar));
153 }
154 break;
155
156 case 8: // 8-byte doubles
157 for (unsigned int i=0; i<nbcids; i++) {
158 rawLumi.push_back (CxxUtils::get_unaligned_double(pchar));
159 }
160 break;
161
162 default:
163 ATH_MSG_ERROR( "BunchRawInstLumi blob found with unknown byte storage size " << bss << "!" );
164 return StatusCode::FAILURE;
165 }
166
167 // Now figure which BCIDs these values belong to and fill into vector indexed by BCID
168
169 rawLumiOut.clear();
170 // Remember, nbcids was set before and the blob size was checked
171 switch (smod) {
172 case 0:
173 // Packed according to luminous bunches, fill accordingly
174 // Checked before that FillParamsTool is configured, don't need to check again
175 rawLumiOut.resize (TOTAL_LHC_BCIDS, 0);
176 for (unsigned int i=0; i<nbcids; i++)
177 rawLumiOut[luminousBunches[i]] = rawLumi[i];
178 break;
179
180 case 1:
181 // Packed according to full turn, just copy
182 rawLumiOut = std::move (rawLumi);
183 break;
184
185 case 2:
186 // Packed according to private list, must read here. pbcids points to start of this data
187 rawLumiOut.resize (TOTAL_LHC_BCIDS, 0);
188 for (unsigned int i=0; i<nbcids; i++) {
189 rawLumiOut[CxxUtils::get_unaligned16(pbcids)] = rawLumi[i];
190 // ATH_MSG_DEBUG( "BCID: " << *p16 << " Lumi= " << rawLumi[i] );
191 }
192 break;
193
194 // This error condition was dealt with before
195 //default:
196 }
197
198 return StatusCode::SUCCESS;
199}
200
201
202
207StatusCode
208BunchLumisCondAlg::execute (const EventContext& ctx) const
209{
210 auto lumis = std::make_unique<BunchLumisCondData>();
211
214 EventIDRange range;
215 ATH_CHECK( bunchLumisFolder.range (range) );
216
217 std::vector<unsigned int> luminousBunches;
218 if (!m_fillParamsInputKey.empty()) {
221 luminousBunches = fillParams->luminousBunches();
222 EventIDRange fpRange;
223 ATH_CHECK( fillParams.range (fpRange) );
224 range = EventIDRange::intersect (range, fpRange);
225 }
226
227 for (const auto& p : *bunchLumisFolder.retrieve()) {
228 unsigned int channel = p.first;
229 const coral::AttributeList& attrList = p.second;
230
231 if (attrList["BunchRawInstLum"].isNull()) {
232 ATH_MSG_ERROR( "BunchRawInstLum blob not found for channel " << channel << "!" );
233 return StatusCode::FAILURE;
234 }
235
236 const coral::Blob& blob = attrList["BunchRawInstLum"].data<coral::Blob>();
237 if (blob.size() == 0) {
238 ATH_MSG_DEBUG( "BunchRawInstLumi blob found with zero size for channel " << channel << "!" );
239 continue;
240 }
241
242 // Make sure the scale factor exists (needed below to unpack integer blob schemes)
243 if (attrList["AverageRawInstLum"].isNull()) {
244 ATH_MSG_ERROR( "AverageRawInstLum value not found for channel " << channel << "!" );
245 return StatusCode::FAILURE;
246 }
247 float avgRawLumi = attrList["AverageRawInstLum"].data<cool::Float>();
248
249 std::vector<float> rawLumis;
250 ATH_CHECK( unpackLumis (blob, luminousBunches, avgRawLumi, rawLumis) );
251 lumis->addChannel (channel, std::move (rawLumis));
252 }
253
256 ATH_CHECK( bunchLumisData.record (range, std::move (lumis)) );
257 return StatusCode::SUCCESS;
258}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
Conditions algorithm to unpack raw luminosity data from COOL.
Helper to enable (more agressive) auto-vectorization.
#define ATH_ENABLE_TREE_VECTORIZATION
SG::ReadCondHandleKey< FillParamsCondData > m_fillParamsInputKey
Fill parameters needed for storage mode 0.
SG::WriteCondHandleKey< BunchLumisCondData > m_bunchLumisOutputKey
Output conditions object.
SG::ReadCondHandleKey< CondAttrListCollection > m_bunchLumisFolderInputKey
Input conditions object.
virtual StatusCode execute(const EventContext &ctx) const override
Algorithm execute method.
virtual StatusCode initialize() override
Gaudi initialize method.
StatusCode unpackLumis(const coral::Blob &blob, const std::vector< unsigned int > &luminousBunches, float avgRawLumi, std::vector< float > &rawLumiOut) const
Unpack raw luminosity data for one channel.
const_pointer_type retrieve()
bool range(EventIDRange &r)
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
Read little-endian values through possibly unaligned pointers.
double get_unaligned_double(const uint8_t *ATH_RESTRICT &p)
Read a little-endian double value from a possibly unaligned pointer.
uint16_t get_unaligned16(const uint8_t *ATH_RESTRICT &p)
Read a 2-byte little-endian value from a possibly unaligned pointer.
float get_unaligned_float(const uint8_t *ATH_RESTRICT &p)
Read a little-endian float value from a possibly unaligned pointer.
Macro wrapping the nonstandard restrict keyword.
#define ATH_RESTRICT
Definition restrict.h:31