ATLAS Offline Software
BunchLumisCondAlg.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration.
3  */
12 #include "BunchLumisCondAlg.h"
15 #include "CxxUtils/get_unaligned.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 
27 namespace {
28 
29 
30 // Total number of BCIDs in one turn - this must match value used in /TDAQ/OLC/BUNCHLUMIS for storage mode 1
31 const unsigned int TOTAL_LHC_BCIDS = 3564;
32 
33 
34 } // anonymous namespace
35 
36 
42 {
46  return StatusCode::SUCCESS;
47 }
48 
49 
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 
208 BunchLumisCondAlg::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()) {
220  (m_fillParamsInputKey, ctx);
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 
255  (m_bunchLumisOutputKey, ctx);
256  ATH_CHECK( bunchLumisData.record (range, std::move (lumis)) );
257  return StatusCode::SUCCESS;
258 }
BunchLumisCondAlg::m_fillParamsInputKey
SG::ReadCondHandleKey< FillParamsCondData > m_fillParamsInputKey
Fill parameters needed for storage mode 0.
Definition: BunchLumisCondAlg.h:69
BunchLumisCondAlg.h
Conditions algorithm to unpack raw luminosity data from COOL.
plotting.yearwise_efficiency.channel
channel
Definition: yearwise_efficiency.py:24
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
FillParamsCondData::luminousBunches
const std::vector< unsigned int > & luminousBunches() const
Definition: FillParamsCondData.cxx:27
vectorize.h
Helper to enable auto-vectorization.
BunchLumisCondAlg::unpackLumis
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.
Definition: BunchLumisCondAlg.cxx:59
python.subdetectors.tile.Blob
Blob
Definition: tile.py:17
SG::ReadCondHandle::range
bool range(EventIDRange &r)
Definition: ReadCondHandle.h:224
python.PyKernel.AttributeList
AttributeList
Definition: PyKernel.py:36
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
SG::WriteCondHandle::record
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
Definition: WriteCondHandle.h:157
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
ReadCondHandle.h
ATH_RESTRICT
#define ATH_RESTRICT
Definition: restrict.h:31
CxxUtils::get_unaligned_float
float get_unaligned_float(const uint8_t *ATH_RESTRICT &p)
Read little-endian float value from a possibly unaligned pointer.
Definition: get_unaligned.h:122
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::ReadCondHandle::retrieve
const_pointer_type retrieve()
Definition: ReadCondHandle.h:162
BunchLumisCondAlg::execute
virtual StatusCode execute(const EventContext &ctx) const override
Algorithm execute method.
Definition: BunchLumisCondAlg.cxx:208
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
BunchLumisCondAlg::m_bunchLumisOutputKey
SG::WriteCondHandleKey< BunchLumisCondData > m_bunchLumisOutputKey
Output conditions object.
Definition: BunchLumisCondAlg.h:73
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
WriteCondHandle.h
ATH_ENABLE_VECTORIZATION
ATH_ENABLE_VECTORIZATION
Definition: BunchLumisCondAlg.cxx:23
CxxUtils::get_unaligned16
uint16_t get_unaligned16(const uint8_t *ATH_RESTRICT &p)
Read a 2-byte little-endian value from a possibly unaligned pointer.
Definition: get_unaligned.h:62
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CxxUtils::get_unaligned_double
double get_unaligned_double(const uint8_t *ATH_RESTRICT &p)
Read little-endian float value from a possibly unaligned pointer.
Definition: get_unaligned.h:144
get_unaligned.h
Read little-endian values through possibly unaligned pointers.
restrict.h
Macro wrapping the nonstandard restrict keyword.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
COOLRates.luminousBunches
luminousBunches
Definition: COOLRates.py:1245
BunchLumisCondAlg::m_bunchLumisFolderInputKey
SG::ReadCondHandleKey< CondAttrListCollection > m_bunchLumisFolderInputKey
Input conditions object.
Definition: BunchLumisCondAlg.h:65
Amg::intersect
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
Definition: GeoPrimitivesHelpers.h:347
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
SG::WriteCondHandle
Definition: WriteCondHandle.h:26
BunchLumisCondAlg::initialize
virtual StatusCode initialize() override
Gaudi initialize method.
Definition: BunchLumisCondAlg.cxx:41
CaloCondBlobAlgs_fillNoiseFromASCII.blob
blob
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:96