Skip to content

Commit 814cb33

Browse files
authored
Add fmt support for DataHeader (#5819)
1 parent 56d4e95 commit 814cb33

File tree

17 files changed

+150
-29
lines changed

17 files changed

+150
-29
lines changed

DataFormats/Headers/include/Headers/DataHeader.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,14 @@ static_assert(gSizeMagicString == sizeof(BaseHeader::magicStringInt),
839839
static_assert(sizeof(BaseHeader::sMagicString) == sizeof(BaseHeader::magicStringInt),
840840
"Inconsitent size of global magic identifier");
841841

842+
template <typename T>
843+
struct is_descriptor : std::false_type {
844+
};
845+
846+
template <std::size_t S, typename P>
847+
struct is_descriptor<o2::header::Descriptor<S, P>> : std::true_type {
848+
};
849+
842850
} //namespace header
843851

844852
} //namespace o2
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#ifndef O2_BASE_DATA_HEADER_HELPERS_
12+
#define O2_BASE_DATA_HEADER_HELPERS_
13+
14+
#include "Headers/DataHeader.h"
15+
#include <fmt/format.h>
16+
17+
template <typename T>
18+
struct fmt::formatter<T, std::enable_if_t<o2::header::is_descriptor<T>::value, char>> {
19+
// Presentation format: 'f' - fixed, 'e' - exponential.
20+
char presentation = 's';
21+
22+
// Parses format specifications of the form ['f' | 'e'].
23+
constexpr auto parse(format_parse_context& ctx)
24+
{
25+
auto it = ctx.begin(), end = ctx.end();
26+
if (it != end && (*it == 's')) {
27+
presentation = *it++;
28+
}
29+
30+
// Check if reached the end of the range:
31+
if (it != end && *it != '}') {
32+
throw format_error("invalid pick format");
33+
}
34+
35+
// Return an iterator past the end of the parsed range:
36+
return it;
37+
}
38+
39+
template <typename FormatContext>
40+
auto format(const T& p, FormatContext& ctx)
41+
{
42+
return format_to(ctx.out(), "{}", p.template as<std::string>());
43+
}
44+
};
45+
46+
template <>
47+
struct fmt::formatter<o2::header::DataHeader> {
48+
// Presentation format: 'f' - fixed, 'e' - exponential.
49+
char presentation = 's';
50+
51+
// Parses format specifications of the form ['f' | 'e'].
52+
constexpr auto parse(format_parse_context& ctx)
53+
{
54+
auto it = ctx.begin(), end = ctx.end();
55+
if (it != end && (*it == 's')) {
56+
presentation = *it++;
57+
}
58+
59+
// Check if reached the end of the range:
60+
if (it != end && *it != '}') {
61+
throw format_error("invalid format");
62+
}
63+
64+
// Return an iterator past the end of the parsed range:
65+
return it;
66+
}
67+
68+
template <typename FormatContext>
69+
auto format(const o2::header::DataHeader& h, FormatContext& ctx)
70+
{
71+
auto res = fmt::format("Data header version %u, flags: %u\n", h.headerVersion, h.flags) +
72+
fmt::format(" origin : {}\n", h.dataOrigin.str) +
73+
fmt::format(" serialization: {}\n", h.payloadSerializationMethod.str) +
74+
fmt::format(" description : {}\n", h.dataDescription.str) +
75+
fmt::format(" sub spec. : {}\n", (long long unsigned int)h.subSpecification) +
76+
fmt::format(" header size : {}\n", h.headerSize) +
77+
fmt::format(" payloadSize : {}\n", (long long unsigned int)h.payloadSize) +
78+
fmt::format(" firstTFOrbit : {}\n", h.firstTForbit) +
79+
fmt::format(" tfCounter : {}\n", h.tfCounter) +
80+
fmt::format(" runNumber : {}\n", h.runNumber);
81+
return format_to(ctx.out(), "{}", res);
82+
}
83+
};
84+
85+
#endif // O2_BASE_DATA_HEADER_HELPERS_

DataFormats/Headers/test/testDataHeader.cxx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <iostream>
1616
#include <iomanip>
1717
#include "Headers/DataHeader.h"
18+
#include "Headers/DataHeaderHelpers.h"
1819
#include "Headers/NameHeader.h"
1920
#include "Headers/Stack.h"
2021

@@ -247,6 +248,10 @@ BOOST_AUTO_TEST_CASE(DataHeader_test)
247248
BOOST_CHECK(!(dh4 == dh));
248249
dh4 = dh;
249250
BOOST_CHECK(dh4 == dh);
251+
DataHeader dh5{gDataDescriptionAny, gDataOriginAny, DataHeader::SubSpecificationType{1}, 1};
252+
BOOST_REQUIRE_EQUAL(fmt::format("{}", gDataOriginAny), "***");
253+
BOOST_REQUIRE_EQUAL(fmt::format("{}", gDataDescriptionAny), "***************");
254+
BOOST_REQUIRE_EQUAL(fmt::format("{}", DataHeader::SubSpecificationType{1}), "1");
250255
}
251256

252257
BOOST_AUTO_TEST_CASE(headerStack_test)
@@ -345,5 +350,24 @@ BOOST_AUTO_TEST_CASE(Descriptor_benchmark)
345350
std::cout << nrolls << " operation(s): " << duration.count() << " ns" << std::endl;
346351
// there is not really a check at the moment
347352
}
353+
354+
BOOST_AUTO_TEST_CASE(Descriptor_formatting)
355+
{
356+
using TestDescriptor = Descriptor<8>;
357+
TestDescriptor a("TESTDESC");
358+
TestDescriptor b(a);
359+
360+
auto refTime = system_clock::now();
361+
const int nrolls = 1000000;
362+
for (auto count = 0; count < nrolls; ++count) {
363+
if (a == b) {
364+
++a.itg[0];
365+
++b.itg[0];
366+
}
367+
}
368+
auto duration = std::chrono::duration_cast<TimeScale>(std::chrono::system_clock::now() - refTime);
369+
std::cout << nrolls << " operation(s): " << duration.count() << " ns" << std::endl;
370+
// there is not really a check at the moment
371+
}
348372
} // namespace header
349373
} // namespace o2

Detectors/DCS/testWorkflow/src/DCStoDPLconverter.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ o2f::InjectorFunction dcs2dpl(std::unordered_map<DPID, o2h::DataDescription>& dp
115115
memcpy(hdMessage->GetData(), headerStack.data(), headerStack.size());
116116
memcpy(plMessage->GetData(), it.second.data(), hdr.payloadSize);
117117
if (verbose) {
118-
LOG(INFO) << "Pushing " << it.second.size() << " DPs to output " << it.first.as<std::string>() << " for TimeSlice " << *timesliceId;
119-
hdr.print();
118+
LOGP(INFO, "Pushing {} DPs to output for TimeSlice", it.second.size(), it.first, *timesliceId, hdr);
120119
}
121120
it.second.clear();
122121
FairMQParts outParts;

Detectors/DCS/testWorkflow/src/dcs-proxy.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "DCStoDPLconverter.h"
2626
#include "CCDB/BasicCCDBManager.h"
2727
#include "CCDB/CcdbApi.h"
28+
#include "Headers/DataHeaderHelpers.h"
2829
#include <vector>
2930
#include <unordered_map>
3031
#include <regex>

Detectors/Raw/test/testRawReaderWriter.cxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "CommonConstants/Triggers.h"
2727
#include "Framework/Logger.h"
2828
#include "Framework/InputRecord.h"
29+
#include "Headers/DataHeaderHelpers.h"
2930
#include "DPLUtils/DPLRawParser.h"
3031
#include "CommonUtils/StringUtils.h"
3132

@@ -337,7 +338,7 @@ BOOST_AUTO_TEST_CASE(RawReaderWriter_CRU)
337338
}
338339
if (RDHUtils::getCRUID(*rdh) == NCRU - 1) {
339340
if (newLink) {
340-
dh->print();
341+
LOGP(INFO, "{}", *dh);
341342
}
342343
RDHUtils::printRDH(rdh);
343344
if (RDHUtils::getMemorySize(*rdh) > sizeof(RDHAny) + RDHUtils::GBTWord) { // special CRU with predefined sizes

Detectors/TPC/workflow/include/TPCWorkflow/TPCSectorCompletionPolicy.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
#include "Framework/InputSpec.h"
2020
#include "Framework/DeviceSpec.h"
2121
#include "DataFormatsTPC/TPCSectorHeader.h"
22+
#include "Headers/DataHeaderHelpers.h"
2223
#include "TPCBase/Sector.h"
24+
#include <fmt/ostream.h>
2325
#include <vector>
2426
#include <string>
2527
#include <stdexcept>
@@ -114,10 +116,10 @@ class TPCSectorCompletionPolicy
114116
inputType = idx;
115117
} else if (inputType != idx) {
116118
std::stringstream error;
117-
error << "routing error, input messages must all be of the same type previously bound to "
118-
<< inputMatchers[inputType]
119-
<< dh->dataOrigin.as<std::string>() + "/"
120-
<< dh->dataDescription.as<std::string>() + "/" + dh->subSpecification;
119+
error << fmt::format("routing error, input messages must all be of the same type previously bound to {} {}/{}/{}",
120+
inputMatchers[inputType],
121+
dh->dataOrigin,
122+
dh->dataDescription, dh->subSpecification);
121123
throw std::runtime_error(error.str());
122124
}
123125
auto const* sectorHeader = framework::DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(ref);

Detectors/TPC/workflow/src/CalibProcessingHelper.cxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "Framework/Logger.h"
1717
#include "DPLUtils/RawParser.h"
1818
#include "DetectorsRaw/RDHUtils.h"
19+
#include "Headers/DataHeaderHelpers.h"
1920
#include "CommonConstants/LHCConstants.h"
2021

2122
#include "TPCBase/RDHUtils.h"
@@ -71,9 +72,9 @@ uint64_t calib_processing_helper::processRawData(o2::framework::InputRecord& inp
7172
rdh_utils::FEEIDType cruID, linkID, endPoint;
7273
rdh_utils::getMapping(feeID, cruID, endPoint, linkID);
7374
const auto globalLinkID = linkID + endPoint * 12;
74-
LOGP(debug, "Specifier: {}/{}/{}", dh->dataOrigin.as<std::string>(), dh->dataDescription.as<std::string>(), subSpecification);
75-
LOGP(debug, "Payload size: {}", dh->payloadSize);
76-
LOGP(debug, "CRU: {}; linkID: {}; endPoint: {}; globalLinkID: {}", cruID, linkID, endPoint, globalLinkID);
75+
LOGP(info, "Specifier: {}/{}/{}", dh->dataOrigin, dh->dataDescription, subSpecification);
76+
LOGP(info, "Payload size: {}", dh->payloadSize);
77+
LOGP(info, "CRU: {}; linkID: {}; endPoint: {}; globalLinkID: {}", cruID, linkID, endPoint, globalLinkID);
7778
// ^^^^^^
7879

7980
// TODO: exception handling needed?

Detectors/TPC/workflow/src/LinkZSToDigitsSpec.cxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "Framework/Logger.h"
1919
#include "DPLUtils/RawParser.h"
2020
#include "Headers/DataHeader.h"
21+
#include "Headers/DataHeaderHelpers.h"
2122
#include "DataFormatsTPC/TPCSectorHeader.h"
2223
#include "DataFormatsTPC/ZeroSuppressionLinkBased.h"
2324
#include "DataFormatsTPC/Digit.h"
@@ -140,7 +141,7 @@ o2::framework::DataProcessorSpec getLinkZSToDigitsSpec(int channel, const std::s
140141

141142
processAttributes->activeSectors |= (0x1 << sector);
142143

143-
LOGP(debug, "Specifier: {}/{}/{}", dh->dataOrigin.as<std::string>(), dh->dataDescription.as<std::string>(), dh->subSpecification);
144+
LOGP(debug, "Specifier: {}/{}/{}", dh->dataOrigin, dh->dataDescription, dh->subSpecification);
144145
LOGP(debug, "Payload size: {}", dh->payloadSize);
145146
LOGP(debug, "CRU: {}; linkID: {}; dataWrapperID: {}; globalLinkID: {}", cruID, linkID, dataWrapperID, globalLinkID);
146147

Detectors/TPC/workflow/src/TrackReaderWorkflow.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "DataFormatsTPC/TPCSectorHeader.h"
2323
#include "Algorithm/RangeTokenizer.h"
2424
#include "CommonUtils/ConfigurableParam.h"
25+
#include "Headers/DataHeaderHelpers.h"
2526

2627
#include "TPCWorkflow/TrackReaderSpec.h"
2728

0 commit comments

Comments
 (0)