Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions DataFormats/Headers/include/Headers/DataHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,14 @@ static_assert(gSizeMagicString == sizeof(BaseHeader::magicStringInt),
static_assert(sizeof(BaseHeader::sMagicString) == sizeof(BaseHeader::magicStringInt),
"Inconsitent size of global magic identifier");

template <typename T>
struct is_descriptor : std::false_type {
};

template <std::size_t S, typename P>
struct is_descriptor<o2::header::Descriptor<S, P>> : std::true_type {
};

} //namespace header

} //namespace o2
Expand Down
85 changes: 85 additions & 0 deletions DataFormats/Headers/include/Headers/DataHeaderHelpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright CERN and copyright holders of ALICE O2. This software is
// distributed under the terms of the GNU General Public License v3 (GPL
// Version 3), copied verbatim in the file "COPYING".
//
// See http://alice-o2.web.cern.ch/license for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#ifndef O2_BASE_DATA_HEADER_HELPERS_
#define O2_BASE_DATA_HEADER_HELPERS_

#include "Headers/DataHeader.h"
#include <fmt/format.h>

template <typename T>
struct fmt::formatter<T, std::enable_if_t<o2::header::is_descriptor<T>::value, char>> {
// Presentation format: 'f' - fixed, 'e' - exponential.
char presentation = 's';

// Parses format specifications of the form ['f' | 'e'].
constexpr auto parse(format_parse_context& ctx)
{
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == 's')) {
presentation = *it++;
}

// Check if reached the end of the range:
if (it != end && *it != '}') {
throw format_error("invalid pick format");
}

// Return an iterator past the end of the parsed range:
return it;
}

template <typename FormatContext>
auto format(const T& p, FormatContext& ctx)
{
return format_to(ctx.out(), "{}", p.template as<std::string>());
}
};

template <>
struct fmt::formatter<o2::header::DataHeader> {
// Presentation format: 'f' - fixed, 'e' - exponential.
char presentation = 's';

// Parses format specifications of the form ['f' | 'e'].
constexpr auto parse(format_parse_context& ctx)
{
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == 's')) {
presentation = *it++;
}

// Check if reached the end of the range:
if (it != end && *it != '}') {
throw format_error("invalid format");
}

// Return an iterator past the end of the parsed range:
return it;
}

template <typename FormatContext>
auto format(const o2::header::DataHeader& h, FormatContext& ctx)
{
auto res = fmt::format("Data header version %u, flags: %u\n", h.headerVersion, h.flags) +
fmt::format(" origin : {}\n", h.dataOrigin.str) +
fmt::format(" serialization: {}\n", h.payloadSerializationMethod.str) +
fmt::format(" description : {}\n", h.dataDescription.str) +
fmt::format(" sub spec. : {}\n", (long long unsigned int)h.subSpecification) +
fmt::format(" header size : {}\n", h.headerSize) +
fmt::format(" payloadSize : {}\n", (long long unsigned int)h.payloadSize) +
fmt::format(" firstTFOrbit : {}\n", h.firstTForbit) +
fmt::format(" tfCounter : {}\n", h.tfCounter) +
fmt::format(" runNumber : {}\n", h.runNumber);
return format_to(ctx.out(), "{}", res);
}
};

#endif // O2_BASE_DATA_HEADER_HELPERS_
24 changes: 24 additions & 0 deletions DataFormats/Headers/test/testDataHeader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <iostream>
#include <iomanip>
#include "Headers/DataHeader.h"
#include "Headers/DataHeaderHelpers.h"
#include "Headers/NameHeader.h"
#include "Headers/Stack.h"

Expand Down Expand Up @@ -247,6 +248,10 @@ BOOST_AUTO_TEST_CASE(DataHeader_test)
BOOST_CHECK(!(dh4 == dh));
dh4 = dh;
BOOST_CHECK(dh4 == dh);
DataHeader dh5{gDataDescriptionAny, gDataOriginAny, DataHeader::SubSpecificationType{1}, 1};
BOOST_REQUIRE_EQUAL(fmt::format("{}", gDataOriginAny), "***");
BOOST_REQUIRE_EQUAL(fmt::format("{}", gDataDescriptionAny), "***************");
BOOST_REQUIRE_EQUAL(fmt::format("{}", DataHeader::SubSpecificationType{1}), "1");
}

BOOST_AUTO_TEST_CASE(headerStack_test)
Expand Down Expand Up @@ -345,5 +350,24 @@ BOOST_AUTO_TEST_CASE(Descriptor_benchmark)
std::cout << nrolls << " operation(s): " << duration.count() << " ns" << std::endl;
// there is not really a check at the moment
}

BOOST_AUTO_TEST_CASE(Descriptor_formatting)
{
using TestDescriptor = Descriptor<8>;
TestDescriptor a("TESTDESC");
TestDescriptor b(a);

auto refTime = system_clock::now();
const int nrolls = 1000000;
for (auto count = 0; count < nrolls; ++count) {
if (a == b) {
++a.itg[0];
++b.itg[0];
}
}
auto duration = std::chrono::duration_cast<TimeScale>(std::chrono::system_clock::now() - refTime);
std::cout << nrolls << " operation(s): " << duration.count() << " ns" << std::endl;
// there is not really a check at the moment
}
} // namespace header
} // namespace o2
3 changes: 1 addition & 2 deletions Detectors/DCS/testWorkflow/src/DCStoDPLconverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ o2f::InjectorFunction dcs2dpl(std::unordered_map<DPID, o2h::DataDescription>& dp
memcpy(hdMessage->GetData(), headerStack.data(), headerStack.size());
memcpy(plMessage->GetData(), it.second.data(), hdr.payloadSize);
if (verbose) {
LOG(INFO) << "Pushing " << it.second.size() << " DPs to output " << it.first.as<std::string>() << " for TimeSlice " << *timesliceId;
hdr.print();
LOGP(INFO, "Pushing {} DPs to output for TimeSlice", it.second.size(), it.first, *timesliceId, hdr);
}
it.second.clear();
FairMQParts outParts;
Expand Down
1 change: 1 addition & 0 deletions Detectors/DCS/testWorkflow/src/dcs-proxy.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "DCStoDPLconverter.h"
#include "CCDB/BasicCCDBManager.h"
#include "CCDB/CcdbApi.h"
#include "Headers/DataHeaderHelpers.h"
#include <vector>
#include <unordered_map>
#include <regex>
Expand Down
3 changes: 2 additions & 1 deletion Detectors/Raw/test/testRawReaderWriter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "CommonConstants/Triggers.h"
#include "Framework/Logger.h"
#include "Framework/InputRecord.h"
#include "Headers/DataHeaderHelpers.h"
#include "DPLUtils/DPLRawParser.h"
#include "CommonUtils/StringUtils.h"

Expand Down Expand Up @@ -337,7 +338,7 @@ BOOST_AUTO_TEST_CASE(RawReaderWriter_CRU)
}
if (RDHUtils::getCRUID(*rdh) == NCRU - 1) {
if (newLink) {
dh->print();
LOGP(INFO, "{}", *dh);
}
RDHUtils::printRDH(rdh);
if (RDHUtils::getMemorySize(*rdh) > sizeof(RDHAny) + RDHUtils::GBTWord) { // special CRU with predefined sizes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
#include "Framework/InputSpec.h"
#include "Framework/DeviceSpec.h"
#include "DataFormatsTPC/TPCSectorHeader.h"
#include "Headers/DataHeaderHelpers.h"
#include "TPCBase/Sector.h"
#include <fmt/ostream.h>
#include <vector>
#include <string>
#include <stdexcept>
Expand Down Expand Up @@ -114,10 +116,10 @@ class TPCSectorCompletionPolicy
inputType = idx;
} else if (inputType != idx) {
std::stringstream error;
error << "routing error, input messages must all be of the same type previously bound to "
<< inputMatchers[inputType]
<< dh->dataOrigin.as<std::string>() + "/"
<< dh->dataDescription.as<std::string>() + "/" + dh->subSpecification;
error << fmt::format("routing error, input messages must all be of the same type previously bound to {} {}/{}/{}",
inputMatchers[inputType],
dh->dataOrigin,
dh->dataDescription, dh->subSpecification);
throw std::runtime_error(error.str());
}
auto const* sectorHeader = framework::DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(ref);
Expand Down
7 changes: 4 additions & 3 deletions Detectors/TPC/workflow/src/CalibProcessingHelper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Framework/Logger.h"
#include "DPLUtils/RawParser.h"
#include "DetectorsRaw/RDHUtils.h"
#include "Headers/DataHeaderHelpers.h"
#include "CommonConstants/LHCConstants.h"

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

// TODO: exception handling needed?
Expand Down
3 changes: 2 additions & 1 deletion Detectors/TPC/workflow/src/LinkZSToDigitsSpec.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "Framework/Logger.h"
#include "DPLUtils/RawParser.h"
#include "Headers/DataHeader.h"
#include "Headers/DataHeaderHelpers.h"
#include "DataFormatsTPC/TPCSectorHeader.h"
#include "DataFormatsTPC/ZeroSuppressionLinkBased.h"
#include "DataFormatsTPC/Digit.h"
Expand Down Expand Up @@ -140,7 +141,7 @@ o2::framework::DataProcessorSpec getLinkZSToDigitsSpec(int channel, const std::s

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

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

Expand Down
1 change: 1 addition & 0 deletions Detectors/TPC/workflow/src/TrackReaderWorkflow.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "DataFormatsTPC/TPCSectorHeader.h"
#include "Algorithm/RangeTokenizer.h"
#include "CommonUtils/ConfigurableParam.h"
#include "Headers/DataHeaderHelpers.h"

#include "TPCWorkflow/TrackReaderSpec.h"

Expand Down
6 changes: 3 additions & 3 deletions Detectors/ZDC/raw/src/raw-parser.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Framework/ConfigParamSpec.h"
#include "DPLUtils/DPLRawParser.h"
#include "Headers/DataHeader.h"
#include "Headers/DataHeaderHelpers.h"
#include "DataFormatsZDC/RawEventData.h"
#include "ZDCSimulation/Digits2Raw.h"
#include "ZDCRaw/DumpRaw.h"
Expand Down Expand Up @@ -67,9 +68,8 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config)
if (dh != lastDataHeader) {
// print the DataHeader information only for the first part or if we have high verbosity
if (loglevel > 1 || dh->splitPayloadIndex == 0) {
rdhprintout << dh->dataOrigin.as<std::string>() << "/"
<< dh->dataDescription.as<std::string>() << "/"
<< dh->subSpecification << " ";
rdhprintout << fmt::format("{}/{}/{}", dh->dataOrigin, dh->dataDescription, dh->subSpecification)
<< " ";
// at high verbosity print part number, otherwise only the total number of parts
if (loglevel > 1) {
rdhprintout << "part " + std::to_string(dh->splitPayloadIndex) + " of " + std::to_string(dh->splitPayloadParts);
Expand Down
2 changes: 1 addition & 1 deletion Framework/Core/src/DataProcessingDevice.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ bool DataProcessingDevice::tryDispatchComputation(DataProcessorContext& context,
if (header.get() == nullptr) {
// FIXME: this should not happen, however it's actually harmless and
// we can simply discard it for the moment.
// LOG(ERROR) << "Missing header! " << dh->dataDescription.as<std::string>();
// LOG(ERROR) << "Missing header! " << dh->dataDescription;
continue;
}
auto fdph = o2::header::get<DataProcessingHeader*>(header.get()->GetData());
Expand Down
5 changes: 4 additions & 1 deletion Framework/Core/src/DataRelayer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
#include "DataProcessingStatus.h"
#include "DataRelayerHelpers.h"

#include "Headers/DataHeaderHelpers.h"

#include <Monitoring/Monitoring.h>

#include <fmt/format.h>
#include <gsl/span>
#include <numeric>
#include <string>
Expand Down Expand Up @@ -345,7 +348,7 @@ DataRelayer::RelayChoice
std::string error;
const auto* dh = o2::header::get<o2::header::DataHeader*>(header->GetData());
if (dh) {
error += dh->dataOrigin.as<std::string>() + "/" + dh->dataDescription.as<std::string>() + "/" + dh->subSpecification;
error += fmt::format("{}/{}/{}", dh->dataOrigin, dh->dataDescription, dh->subSpecification);
} else {
error += "invalid header";
}
Expand Down
3 changes: 2 additions & 1 deletion Framework/Core/test/test_InputRecordWalker.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "Framework/WorkflowSpec.h" // o2::framework::select
#include "Framework/DataRefUtils.h"
#include "Headers/DataHeader.h"
#include "Headers/DataHeaderHelpers.h"
#include "Headers/Stack.h"
#include <boost/test/unit_test.hpp>
#include <vector>
Expand Down Expand Up @@ -81,7 +82,7 @@ DataSet createData()
DataSet::Messages messages;

auto createMessage = [&messages, &checkValues](DataHeader dh) {
checkValues.emplace_back(dh.dataOrigin.as<std::string>() + "_" + dh.dataDescription.as<std::string>() + "_" + std::to_string(dh.subSpecification));
checkValues.emplace_back(fmt::format("{}_{}_{}", dh.dataOrigin, dh.dataDescription, dh.subSpecification));
std::string const& data = checkValues.back();
dh.payloadSize = data.size();
DataProcessingHeader dph{0, 1};
Expand Down
5 changes: 2 additions & 3 deletions Framework/TestWorkflows/src/flpQualification.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ void customize(std::vector<ConfigParamSpec>& workflowOptions)
#include "Framework/ReadoutAdapter.h"

#include "Framework/Logger.h"
#include "Headers/DataHeaderHelpers.h"

#include <vector>

Expand Down Expand Up @@ -65,9 +66,7 @@ DataProcessorSpec templateProcessor(std::string const& inputType)
size_t index = parallelInfo.index1D();
const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(values);
if (dh) {
LOG(INFO) << "some-processor" << index << ": "
<< dh->dataOrigin.as<std::string>() << "/" << dh->dataDescription.as<std::string>() << "/"
<< dh->subSpecification << " payload size " << dh->payloadSize;
LOGP(INFO, "some-processor {}: {}/{}/{} payload size {}", index, dh->dataOrigin, dh->dataDescription, dh->subSpecification, dh->payloadSize);
}
auto aData =
outputs.make<int>(Output{"TST", "P", static_cast<o2::header::DataHeader::SubSpecificationType>(index)}, 1);
Expand Down
6 changes: 2 additions & 4 deletions Framework/Utils/src/raw-parser.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Framework/ConfigParamSpec.h"
#include "DPLUtils/DPLRawParser.h"
#include "Headers/DataHeader.h"
#include "Headers/DataHeaderHelpers.h"
#include <vector>
#include <sstream>

Expand Down Expand Up @@ -66,10 +67,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config)
}
// print the DataHeader information only for the first part or if we have high verbosity
if (loglevel > 1 || dh->splitPayloadIndex == 0) {
rdhprintout << "DH: "
<< dh->dataOrigin.as<std::string>() << "/"
<< dh->dataDescription.as<std::string>() << "/"
<< dh->subSpecification << " "
rdhprintout << fmt::format("DH: {}/{}/{}", dh->dataOrigin, dh->dataDescription, dh->subSpecification) << " "
<< " TF " << dh->tfCounter << " Run " << dh->runNumber << " |";

// at high verbosity print part number, otherwise only the total number of parts
Expand Down
7 changes: 2 additions & 5 deletions Framework/Utils/test/test_RootTreeWriterWorkflow.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "DPLUtils/RootTreeWriter.h"
#include "DPLUtils/MakeRootTreeWriterSpec.h"
#include "Headers/DataHeader.h"
#include "Headers/DataHeaderHelpers.h"
#include "../../Core/test/TestClasses.h"
#include "Framework/Logger.h"
#include <TSystem.h>
Expand Down Expand Up @@ -195,11 +196,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const&)
auto preprocessor = [](ProcessingContext& ctx) {
for (auto const& ref : InputRecordWalker(ctx.inputs())) {
auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
std::cout << "got data: "
<< dh->dataOrigin.as<std::string>() << "/"
<< dh->dataDescription.as<std::string>() << "/"
<< dh->subSpecification << " "
<< std::endl;
LOGP(INFO, "got data: {}/{}/{}", dh->dataOrigin, dh->dataDescription, dh->subSpecification);
}
};

Expand Down