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

Converts between CHAI payload containers and CORAL objects: a specification plus per-channel rows, both directions. More...

#include <ChaiCoralConverter.h>

Collaboration diagram for ChaiCoralConverter:

Static Public Member Functions

static coral::AttributeListSpecification * toCoralSpec (const chai::FieldSpec &fields)
 Build a coral::AttributeListSpecification from a CHAI FieldSpec, one attribute per field in field order.
static chai::FieldSpec toFieldSpec (const coral::AttributeListSpecification &spec)
 Build a chai::FieldSpec from a coral::AttributeListSpecification, one field per attribute in spec order.
static coral::AttributeList toAttributeList (const coral::AttributeListSpecification &spec, const chai::Values &values)
 Convert one channel's CHAI Values to a coral::AttributeList, one attribute per field in spec order.
static std::vector< coral::AttributeList > toAttributeListVec (const coral::AttributeListSpecification &spec, const std::vector< chai::ValuesPtr > &rows)
 Convert one channel's CHAI vector-payload rows to a coral::AttributeList per row, in row order, via toAttributeList().
static chai::ValuesPtr toValues (chai::FieldSpecPtr fields, const coral::AttributeList &attrList)
 Convert one coral::AttributeList to CHAI Values, one value per field in FieldSpec order.
static std::vector< chai::ValuesPtr > toValuesVec (chai::FieldSpecPtr fields, const std::vector< coral::AttributeList > &rows)
 Convert a coral::AttributeList per row, in row order, to CHAI Values sharing one FieldSpecPtr, via toValues().
static std::unique_ptr< AthenaAttributeList > toAthenaAttributeList (const chai::Container &container)
 Convert a chai::Container's single populated channel to an AthenaAttributeList.
static chai::Container toContainer (const AthenaAttributeList &attrList, uint64_t channelId=0, const std::string &channelName="")
 Convert an AthenaAttributeList to a single-channel chai::Container.
static std::unique_ptr< CondAttrListCollection > toCondAttrListCollection (const chai::Container &container, bool hasRunLumiBlockTime)
 Convert a chai::Container to a CondAttrListCollection, one row per populated channel.
static chai::Container toContainer (const CondAttrListCollection &collection)
 Convert a CondAttrListCollection to a chai::Container, one channel per entry with an attribute list.
static unsigned int valuesSize (const chai::Values &values)
 Total byte size of one channel's field values, using the same type mapping as toAttributeList().
static unsigned int payloadSize (const chai::Container &container)
 Total byte size of every populated channel in a scalar payload.
static unsigned int payloadSize (const chai::VectorContainer &container)
 Total byte size of every row of every populated channel in a vector payload.

Detailed Description

Converts between CHAI payload containers and CORAL objects: a specification plus per-channel rows, both directions.

IOV is never read or written, the caller owns that. Container-level conversions only see populated channels (a Values with at least one value pushed). Zero-attribute CORAL specifications are rejected.

Definition at line 44 of file ChaiCoralConverter.h.

Member Function Documentation

◆ payloadSize() [1/2]

unsigned int ChaiCoralConverter::payloadSize ( const chai::Container & container)
static

Total byte size of every populated channel in a scalar payload.

Definition at line 402 of file ChaiCoralConverter.cxx.

402 {
403 unsigned int total = 0;
404 for (const auto channelId : container.channelIds()) {
405 total += valuesSize(container[channelId]);
406 }
407 return total;
408}
static unsigned int valuesSize(const chai::Values &values)
Total byte size of one channel's field values, using the same type mapping as toAttributeList().
const SG::AuxVectorData * container() const
Return the container holding this element.

◆ payloadSize() [2/2]

unsigned int ChaiCoralConverter::payloadSize ( const chai::VectorContainer & container)
static

Total byte size of every row of every populated channel in a vector payload.

Exceptions
std::invalid_argumentif a row is null, naming its channel and index.

Definition at line 410 of file ChaiCoralConverter.cxx.

410 {
411 unsigned int total = 0;
412 for (const auto channelId : container.channelIds()) {
413 const auto& rows = container.rows(channelId);
414 for (std::size_t i = 0; i != rows.size(); ++i) {
415 if (!rows[i]) {
416 throw std::invalid_argument(
417 "ChaiCoralConverter::payloadSize: null row at channel " + std::to_string(channelId)
418 + " index " + std::to_string(i));
419 }
420 total += valuesSize(*rows[i]);
421 }
422 }
423 return total;
424}

◆ toAthenaAttributeList()

std::unique_ptr< AthenaAttributeList > ChaiCoralConverter::toAthenaAttributeList ( const chai::Container & container)
static

Convert a chai::Container's single populated channel to an AthenaAttributeList.

Parameters
container- the container to convert, with only one populated channel
Returns
A new AthenaAttributeList built from that channel's row.
Exceptions
std::runtime_errorif the container does not have exactly one populated channel, or under the same conditions as toCoralSpec() or toAttributeList() for that channel's row.

Definition at line 303 of file ChaiCoralConverter.cxx.

303 {
304 const auto ids = container.channelIds();
305 if (ids.size() != 1) {
306 throw std::runtime_error(
307 "ChaiCoralConverter::toAthenaAttributeList: expected exactly one populated channel, found "
308 + std::to_string(ids.size()));
309 }
310 const SpecHolder spec(toCoralSpec(container.fieldSpec()));
311 return std::make_unique<AthenaAttributeList>(toAttributeList(*spec, container[ids[0]]));
312}
static coral::AttributeList toAttributeList(const coral::AttributeListSpecification &spec, const chai::Values &values)
Convert one channel's CHAI Values to a coral::AttributeList, one attribute per field in spec order.
static coral::AttributeListSpecification * toCoralSpec(const chai::FieldSpec &fields)
Build a coral::AttributeListSpecification from a CHAI FieldSpec, one attribute per field in field ord...

◆ toAttributeList()

coral::AttributeList ChaiCoralConverter::toAttributeList ( const coral::AttributeListSpecification & spec,
const chai::Values & values )
static

Convert one channel's CHAI Values to a coral::AttributeList, one attribute per field in spec order.

Null fields map to a null coral::Attribute. Fields are resolved by name, so a payload whose fields are ordered differently than the specification still maps correctly.

Parameters
spec- the CORAL specification the values are converted against
values- the CHAI row to convert
Returns
A CORAL attribute list built from the given specification.
Exceptions
std::runtime_errorif the field counts of spec and values differ, if a field name in the specification is not present in values, or on an unrecognised chai::Type.

Definition at line 116 of file ChaiCoralConverter.cxx.

117 {
118 // The specification is built from a tag's first payload, so a later
119 // payload with a different field count is caught here
120 if (values.size() != spec.size()) {
121 throw std::runtime_error("ChaiCoralConverter::toAttributeList: field count mismatch, payload "
122 + std::to_string(values.size()) + " vs specification " + std::to_string(spec.size()));
123 }
124 coral::AttributeList attr(spec, true);
125 const unsigned int s = attr.size();
126 for (unsigned int i = 0; i != s; ++i) {
127 auto& att = attr[i];
128 // Look up each value by name rather than position
129 const std::string& fieldName = att.specification().name();
130 const std::size_t idx = values.fieldIndex(fieldName);
131 if (values.isNull(idx)) {
132 att.setNull();
133 continue;
134 }
135 switch (values.type(idx)) {
136 case chai::Bool:
137 att.setValue<bool>(values.get<bool>(idx));
138 break;
139 case chai::Int8:
140 att.setValue<char>(values.get<int8_t>(idx));
141 break;
142 case chai::UInt8:
143 att.setValue<unsigned char>(values.get<uint8_t>(idx));
144 break;
145 case chai::Int16:
146 att.setValue<short>(values.get<int16_t>(idx));
147 break;
148 case chai::UInt16:
149 att.setValue<unsigned short>(values.get<uint16_t>(idx));
150 break;
151 case chai::Int32:
152 att.setValue<int>(values.get<int32_t>(idx));
153 break;
154 case chai::UInt32:
155 att.setValue<unsigned int>(values.get<uint32_t>(idx));
156 break;
157 case chai::Int64:
158 att.setValue<long long>(values.get<int64_t>(idx));
159 break;
160 case chai::UInt64:
161 att.setValue<unsigned long long>(values.get<uint64_t>(idx));
162 break;
163 case chai::Float:
164 att.setValue<float>(values.get<float>(idx));
165 break;
166 case chai::Double:
167 att.setValue<double>(values.get<double>(idx));
168 break;
169 case chai::String:
170 att.setValue<std::string>(values.get<std::string>(idx));
171 break;
172 case chai::Blob: {
173 const auto& bytes = values.get<chai::BlobData>(idx).m_bytes;
174 coral::Blob blob(bytes.size());
175 // Skip the memcpy if the blob is empty
176 if (!bytes.empty()) {
177 std::memcpy(blob.startingAddress(), bytes.data(), bytes.size());
178 }
179 att.setValue<coral::Blob>(blob);
180 break;
181 }
182 case chai::Unknown: // Fall-through
183 default:
184 throw std::runtime_error(
185 "ChaiCoralConverter::toAttributeList: unrecognised CHAI type for field '" + fieldName + "'");
186 }
187 }
188 return attr;
189}
setScaleOne setStatusOne setSaturated int16_t
setWord1 uint16_t
setEventNumber uint32_t

◆ toAttributeListVec()

std::vector< coral::AttributeList > ChaiCoralConverter::toAttributeListVec ( const coral::AttributeListSpecification & spec,
const std::vector< chai::ValuesPtr > & rows )
static

Convert one channel's CHAI vector-payload rows to a coral::AttributeList per row, in row order, via toAttributeList().

Parameters
spec- the CORAL specification every row is converted against
rows- the CHAI rows to convert
Returns
One CORAL attribute list per row, in row order.
Exceptions
std::invalid_argumentif a row is null, naming its index.
std::runtime_errorunder the same conditions as toAttributeList().

Definition at line 191 of file ChaiCoralConverter.cxx.

192 {
193 std::vector<coral::AttributeList> result;
194 result.reserve(rows.size());
195 for (std::size_t i = 0; i != rows.size(); ++i) {
196 if (!rows[i]) {
197 throw std::invalid_argument(
198 "ChaiCoralConverter::toAttributeListVec: null row at index " + std::to_string(i));
199 }
200 result.push_back(toAttributeList(spec, *rows[i]));
201 }
202 return result;
203}

◆ toCondAttrListCollection()

std::unique_ptr< CondAttrListCollection > ChaiCoralConverter::toCondAttrListCollection ( const chai::Container & container,
bool hasRunLumiBlockTime )
static

Convert a chai::Container to a CondAttrListCollection, one row per populated channel.

Named channels get their name added.

Parameters
container- the container to convert
hasRunLumiBlockTime- passed through to CondAttrListCollection's constructor
Returns
A new CondAttrListCollection.
Exceptions
std::runtime_errorif a populated channel id exceeds CondAttrListCollection::ChanNum's range, or under the same conditions as toCoralSpec() or toAttributeList() for any channel's row.

Definition at line 326 of file ChaiCoralConverter.cxx.

327 {
328 const SpecHolder spec(toCoralSpec(container.fieldSpec()));
329 auto collection = std::make_unique<CondAttrListCollection>(hasRunLumiBlockTime);
330 const auto names = container.channelSpec().channelNames();
331 for (const auto id : container.channelIds()) {
332 // Catch IDs too wide for ChanNum before the cast truncates them
333 if (id > std::numeric_limits<CondAttrListCollection::ChanNum>::max()) {
334 throw std::runtime_error(
335 "ChaiCoralConverter::toCondAttrListCollection: channel id " + std::to_string(id)
336 + " exceeds ChanNum range");
337 }
338 const auto chan = static_cast<CondAttrListCollection::ChanNum>(id);
339 collection->addShared(chan, toAttributeList(*spec, container[id]));
340 const auto nameIt = names.find(id);
341 if (nameIt != names.end() && !nameIt->second.empty()) {
342 collection->add(chan, nameIt->second);
343 }
344 }
345 return collection;
346}

◆ toContainer() [1/2]

chai::Container ChaiCoralConverter::toContainer ( const AthenaAttributeList & attrList,
uint64_t channelId = 0,
const std::string & channelName = "" )
static

Convert an AthenaAttributeList to a single-channel chai::Container.

Parameters
attrList- the row to convert
channelId- the channel id to assign the row to
channelName- the channel name to assign
Returns
A new container with one populated channel.
Exceptions
std::runtime_errorif attrList's specification has zero attributes, or under the same conditions as toFieldSpec() or toValues().

Definition at line 314 of file ChaiCoralConverter.cxx.

315 {
316 const coral::AttributeListSpecification& coralSpec = attrList.specification();
317 if (coralSpec.size() == 0) {
318 throw std::runtime_error("ChaiCoralConverter::toContainer: zero-attribute specification");
319 }
320 const auto fields = std::make_shared<const chai::FieldSpec>(toFieldSpec(coralSpec));
321 chai::Container container(chai::PayloadSpec(*fields, chai::ChannelSpec({{channelId, channelName}})));
322 container.add(channelId, toValues(fields, attrList));
323 return container;
324}
static chai::FieldSpec toFieldSpec(const coral::AttributeListSpecification &spec)
Build a chai::FieldSpec from a coral::AttributeListSpecification, one field per attribute in spec ord...
static chai::ValuesPtr toValues(chai::FieldSpecPtr fields, const coral::AttributeList &attrList)
Convert one coral::AttributeList to CHAI Values, one value per field in FieldSpec order.

◆ toContainer() [2/2]

chai::Container ChaiCoralConverter::toContainer ( const CondAttrListCollection & collection)
static

Convert a CondAttrListCollection to a chai::Container, one channel per entry with an attribute list.

Named channels keep their name.

Parameters
collection- the collection to convert
Returns
A new Container.
Exceptions
std::runtime_errorif the collection is empty, if its shared specification has zero attributes, or under the same conditions as toFieldSpec() or toValues() for any channel.

Definition at line 348 of file ChaiCoralConverter.cxx.

348 {
349 if (collection.size() == 0) {
350 throw std::runtime_error("ChaiCoralConverter::toContainer: empty collection");
351 }
352 const coral::AttributeListSpecification& coralSpec = collection.begin()->second.specification();
353 if (coralSpec.size() == 0) {
354 throw std::runtime_error("ChaiCoralConverter::toContainer: zero-attribute specification");
355 }
356 // Container fixes its channel set at construction, so names are collected before building it
357 std::map<uint64_t, std::string> channelNames;
358 for (const auto& pair : collection) {
359 channelNames[static_cast<uint64_t>(pair.first)] = collection.chanName(pair.first);
360 }
361 const auto fields = std::make_shared<const chai::FieldSpec>(toFieldSpec(coralSpec));
362 chai::Container container(chai::PayloadSpec(*fields, chai::ChannelSpec(channelNames)));
363 for (const auto& [chan, attrList] : collection) {
364 const uint64_t id = chan;
365 container.add(id, toValues(fields, attrList));
366 }
367 return container;
368}
const_iterator begin() const
Access to Chan/AttributeList pairs via iterators.
size_type size() const
number of Chan/AttributeList pairs

◆ toCoralSpec()

coral::AttributeListSpecification * ChaiCoralConverter::toCoralSpec ( const chai::FieldSpec & fields)
static

Build a coral::AttributeListSpecification from a CHAI FieldSpec, one attribute per field in field order.

See the type table above toCoralSpec()'s definition for the chai::Type <-> CORAL type mapping.

Parameters
fields- the field specification to convert
Returns
A new specification. CORAL refcounts specifications so the caller must release it
Exceptions
std::runtime_erroron an unrecognised chai::Type.

Definition at line 74 of file ChaiCoralConverter.cxx.

74 {
75 auto* pSpec = new coral::AttributeListSpecification();
76 try {
77 for (const auto& field : fields.fields()) {
78 switch (field.type) {
79 case chai::Bool: pSpec->extend(field.name, typeid(bool)); break;
80 case chai::Int8: pSpec->extend(field.name, typeid(char)); break;
81 case chai::UInt8: pSpec->extend(field.name, typeid(unsigned char)); break;
82 case chai::Int16: pSpec->extend(field.name, typeid(short)); break;
83 case chai::UInt16: pSpec->extend(field.name, typeid(unsigned short)); break;
84 case chai::Int32: pSpec->extend(field.name, typeid(int)); break;
85 case chai::UInt32: pSpec->extend(field.name, typeid(unsigned int)); break;
86 case chai::Int64: pSpec->extend(field.name, typeid(long long)); break;
87 case chai::UInt64: pSpec->extend(field.name, typeid(unsigned long long)); break;
88 case chai::Float: pSpec->extend(field.name, typeid(float)); break;
89 case chai::Double: pSpec->extend(field.name, typeid(double)); break;
90 case chai::String: pSpec->extend(field.name, typeid(std::string)); break;
91 case chai::Blob: pSpec->extend(field.name, typeid(coral::Blob)); break;
92 case chai::Unknown: // Fall-through
93 default:
94 throw std::runtime_error(
95 "ChaiCoralConverter::toCoralSpec: unrecognised CHAI type for field '" + field.name + "'");
96 }
97 }
98 } catch (...) {
99 pSpec->release();
100 throw;
101 }
102 return pSpec;
103}

◆ toFieldSpec()

chai::FieldSpec ChaiCoralConverter::toFieldSpec ( const coral::AttributeListSpecification & spec)
static

Build a chai::FieldSpec from a coral::AttributeListSpecification, one field per attribute in spec order.

See the type table above toCoralSpec()'s definition for the chai::Type <-> CORAL type mapping.

Parameters
spec- the CORAL specification to convert
Returns
An equivalent CHAI field specification
Exceptions
std::runtime_errorif an attribute's CORAL type has no CHAI equivalent

Definition at line 105 of file ChaiCoralConverter.cxx.

105 {
106 std::vector<chai::Field> fields;
107 fields.reserve(spec.size());
108 const unsigned int s = spec.size();
109 for (unsigned int i = 0; i != s; ++i) {
110 const auto& attrSpec = spec[i];
111 fields.push_back({attrSpec.name(), chaiTypeFor(attrSpec)});
112 }
113 return chai::FieldSpec(std::move(fields));
114}

◆ toValues()

chai::ValuesPtr ChaiCoralConverter::toValues ( chai::FieldSpecPtr fields,
const coral::AttributeList & attrList )
static

Convert one coral::AttributeList to CHAI Values, one value per field in FieldSpec order.

Null attributes map to a null CHAI value. Fields are resolved by name, so an attribute list whose fields are ordered differently than the FieldSpec still maps correctly.

Parameters
fields- the field specification the row shares with its siblings
attrList- the CORAL row to convert
Returns
A CHAI row built against the given field specification.
Exceptions
std::invalid_argumentif fields is null.
std::runtime_errorif the field counts of fields and attrList differ, if a field name in fields is not present in attrList, if a field's CORAL type doesn't match its chai::Type, or on an unrecognised CORAL type.

Definition at line 205 of file ChaiCoralConverter.cxx.

205 {
206 if (!fields) {
207 throw std::invalid_argument("ChaiCoralConverter::toValues: null field specification");
208 }
209 if (fields->size() != attrList.size()) {
210 throw std::runtime_error("ChaiCoralConverter::toValues: field count mismatch, specification "
211 + std::to_string(fields->size()) + " vs payload " + std::to_string(attrList.size()));
212 }
213 auto values = std::make_shared<chai::Values>(fields);
214 const std::size_t n = fields->size();
215 for (std::size_t i = 0; i != n; ++i) {
216 const chai::Field& field = (*fields)[i];
217 const int idx = attrList.specification().index(field.name);
218 if (idx < 0) {
219 throw std::runtime_error(
220 "ChaiCoralConverter::toValues: field '" + field.name + "' not found in payload");
221 }
222 const auto& att = attrList[static_cast<unsigned int>(idx)];
223 const chai::Type payloadType = chaiTypeFor(att.specification());
224 if (payloadType != field.type) {
225 throw std::runtime_error(
226 "ChaiCoralConverter::toValues: type mismatch for field '" + field.name + "': specification "
227 + field.typeString() + " vs payload " + chai::typeToString(payloadType));
228 }
229 if (att.isNull()) {
230 values->push();
231 continue;
232 }
233 // Have to cast to the exact fixed-width types for integers since push is templated
234 switch (field.type) {
235 case chai::Bool:
236 values->push(att.data<bool>());
237 break;
238 case chai::Int8:
239 values->push(static_cast<int8_t>(att.data<char>()));
240 break;
241 case chai::UInt8:
242 values->push(static_cast<uint8_t>(att.data<unsigned char>()));
243 break;
244 case chai::Int16:
245 values->push(static_cast<int16_t>(att.data<short>()));
246 break;
247 case chai::UInt16:
248 values->push(static_cast<uint16_t>(att.data<unsigned short>()));
249 break;
250 case chai::Int32:
251 values->push(static_cast<int32_t>(att.data<int>()));
252 break;
253 case chai::UInt32:
254 values->push(static_cast<uint32_t>(att.data<unsigned int>()));
255 break;
256 case chai::Int64:
257 values->push(static_cast<int64_t>(att.data<long long>()));
258 break;
259 case chai::UInt64:
260 values->push(static_cast<uint64_t>(att.data<unsigned long long>()));
261 break;
262 case chai::Float:
263 values->push(att.data<float>());
264 break;
265 case chai::Double:
266 values->push(att.data<double>());
267 break;
268 case chai::String:
269 values->push(att.data<std::string>());
270 break;
271 case chai::Blob: {
272 const coral::Blob& blob = att.data<coral::Blob>();
273 std::vector<uint8_t> bytes(blob.size());
274 // Skip the memcpy if the blob is empty
275 if (blob.size() != 0) {
276 std::memcpy(bytes.data(), blob.startingAddress(), blob.size());
277 }
278 values->push(chai::BlobData(std::move(bytes)));
279 break;
280 }
281 case chai::Unknown: // Fall-through
282 default:
283 throw std::runtime_error(
284 "ChaiCoralConverter::toValues: unrecognised CHAI type for field '" + field.name + "'");
285 }
286 }
287 return values;
288}

◆ toValuesVec()

std::vector< chai::ValuesPtr > ChaiCoralConverter::toValuesVec ( chai::FieldSpecPtr fields,
const std::vector< coral::AttributeList > & rows )
static

Convert a coral::AttributeList per row, in row order, to CHAI Values sharing one FieldSpecPtr, via toValues().

Parameters
fields- the field specification every row is converted against
rows- the CORAL rows to convert
Returns
One CHAI row per input row, in row order.
Exceptions
std::invalid_argumentif fields is null.
std::runtime_errorunder the same conditions as toValues().

Definition at line 290 of file ChaiCoralConverter.cxx.

291 {
292 if (!fields) {
293 throw std::invalid_argument("ChaiCoralConverter::toValuesVec: null field specification");
294 }
295 std::vector<chai::ValuesPtr> result;
296 result.reserve(rows.size());
297 for (std::size_t i = 0; i != rows.size(); ++i) {
298 result.push_back(toValues(fields, rows[i]));
299 }
300 return result;
301}

◆ valuesSize()

unsigned int ChaiCoralConverter::valuesSize ( const chai::Values & values)
static

Total byte size of one channel's field values, using the same type mapping as toAttributeList().

Fixed-width for scalar types; the actual length for String/Blob. Null fields count as zero bytes.

Definition at line 370 of file ChaiCoralConverter.cxx.

370 {
371 unsigned int total = 0;
372 const std::size_t n = values.size();
373 for (std::size_t i = 0; i != n; ++i) {
374 if (values.isNull(i)) continue;
375 switch (values.type(i)) {
376 case chai::Bool: total += sizeof(bool); break;
377 case chai::Int8: total += sizeof(int8_t); break;
378 case chai::UInt8: total += sizeof(uint8_t); break;
379 case chai::Int16: total += sizeof(int16_t); break;
380 case chai::UInt16: total += sizeof(uint16_t); break;
381 case chai::Int32: total += sizeof(int32_t); break;
382 case chai::UInt32: total += sizeof(uint32_t); break;
383 case chai::Int64: total += sizeof(int64_t); break;
384 case chai::UInt64: total += sizeof(uint64_t); break;
385 case chai::Float: total += sizeof(float); break;
386 case chai::Double: total += sizeof(double); break;
387 case chai::String:
388 total += values.get<std::string>(i).size();
389 break;
390 case chai::Blob:
391 total += values.get<chai::BlobData>(i).m_bytes.size();
392 break;
393 case chai::Unknown: // Fall-through
394 default:
395 throw std::runtime_error(
396 "ChaiCoralConverter::valuesSize: unrecognised CHAI type at field index " + std::to_string(i));
397 }
398 }
399 return total;
400}
size_t size() const
Number of registered mappings.
setBGCode setTAP setLVL2ErrorBits bool

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