Skip to content

Commit

Permalink
DPL: Add support for optional origin and description
Browse files Browse the repository at this point in the history
(with @ktf)

clang
  • Loading branch information
chiarazampolli committed Mar 19, 2021
1 parent b372e94 commit 87e94b8
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 8 deletions.
6 changes: 6 additions & 0 deletions Framework/Core/include/Framework/DataSpecUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ struct DataSpecUtils {
/// OutputSpec
static InputSpec matchingInput(OutputSpec const& spec);

/// Get the origin, if available
static std::optional<header::DataOrigin> getOptionalOrigin(InputSpec const& spec);

/// Get the description, if available
static std::optional<header::DataDescription> getOptionalDescription(InputSpec const& spec);

/// Get the subspec, if available
static std::optional<header::DataHeader::SubSpecificationType> getOptionalSubSpec(OutputSpec const& spec);

Expand Down
38 changes: 38 additions & 0 deletions Framework/Core/src/DataSpecUtils.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,44 @@ InputSpec DataSpecUtils::matchingInput(OutputSpec const& spec)
spec.matcher);
}

std::optional<header::DataOrigin> DataSpecUtils::getOptionalOrigin(InputSpec const& spec)
{
// FIXME: try to address at least a few cases.
return std::visit(overloaded{
[](ConcreteDataMatcher const& concrete) -> std::optional<header::DataOrigin> {
return std::make_optional(concrete.origin);
},
[](DataDescriptorMatcher const& matcher) -> std::optional<header::DataOrigin> {
auto state = extractMatcherInfo(matcher);
if (state.hasUniqueDescription) {
return std::make_optional(state.origin);
} else if (state.hasError) {
throw runtime_error("Could not extract origin from query");
}
return {};
}},
spec.matcher);
}

std::optional<header::DataDescription> DataSpecUtils::getOptionalDescription(InputSpec const& spec)
{
// FIXME: try to address at least a few cases.
return std::visit(overloaded{
[](ConcreteDataMatcher const& concrete) -> std::optional<header::DataDescription> {
return std::make_optional(concrete.description);
},
[](DataDescriptorMatcher const& matcher) -> std::optional<header::DataDescription> {
auto state = extractMatcherInfo(matcher);
if (state.hasUniqueDescription) {
return std::make_optional(state.description);
} else if (state.hasError) {
throw runtime_error("Could not extract description from query");
}
return {};
}},
spec.matcher);
}

std::optional<header::DataHeader::SubSpecificationType> DataSpecUtils::getOptionalSubSpec(OutputSpec const& spec)
{
return std::visit(overloaded{
Expand Down
41 changes: 33 additions & 8 deletions Framework/Core/src/WorkflowSerializationHelpers.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Framework/DataDescriptorQueryBuilder.h"
#include "Framework/DataSpecUtils.h"
#include "Framework/VariantJSONHelpers.h"
#include "Framework/DataDescriptorMatcher.h"

#include <rapidjson/reader.h>
#include <rapidjson/prettywriter.h>
Expand All @@ -28,6 +29,7 @@ namespace framework
{

using namespace rapidjson;
using namespace o2::framework::data_matcher;

struct WorkflowImporter : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, WorkflowImporter> {
enum struct State {
Expand Down Expand Up @@ -225,6 +227,7 @@ struct WorkflowImporter : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
dataProcessors.push_back(DataProcessorSpec{});
} else if (in(State::IN_INPUTS)) {
push(State::IN_INPUT);
inputHasDescription = false;
inputHasSubSpec = false;
} else if (in(State::IN_OUTPUTS)) {
push(State::IN_OUTPUT);
Expand All @@ -248,12 +251,29 @@ struct WorkflowImporter : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
{
enter("END_OBJECT");
if (in(State::IN_INPUT)) {
if (!inputHasDescription && !inputHasSubSpec) {

DataDescriptorMatcher expectedMatcher00{
DataDescriptorMatcher::Op::And,
OriginValueMatcher{origin.str},
std::make_unique<DataDescriptorMatcher>(
DataDescriptorMatcher::Op::And,
DescriptionValueMatcher{ContextRef{1}},
std::make_unique<DataDescriptorMatcher>(
DataDescriptorMatcher::Op::And,
SubSpecificationTypeValueMatcher{ContextRef{2}},
std::make_unique<DataDescriptorMatcher>(DataDescriptorMatcher::Op::Just,
StartTimeValueMatcher{ContextRef{0}})))};

dataProcessors.back().inputs.push_back(InputSpec({binding}, std::move(expectedMatcher00)));
}
if (inputHasSubSpec) {
dataProcessors.back().inputs.push_back(InputSpec(binding, origin, description, subspec, lifetime, inputOptions));
} else {
dataProcessors.back().inputs.push_back(InputSpec(binding, {origin, description}, lifetime, inputOptions));
}
inputOptions.clear();
inputHasDescription = false;
inputHasSubSpec = false;
} else if (in(State::IN_OUTPUT)) {
if (outputHasSubSpec) {
Expand Down Expand Up @@ -345,6 +365,7 @@ struct WorkflowImporter : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
push(State::IN_DATAPROCESSORS);
} else if (in(State::IN_INPUTS)) {
push(State::IN_INPUT);
inputHasDescription = false;
inputHasSubSpec = false;
} else if (in(State::IN_INPUT_OPTIONS)) {
push(State::IN_OPTION);
Expand Down Expand Up @@ -387,6 +408,7 @@ struct WorkflowImporter : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
push(State::IN_INPUT_ORIGIN);
} else if (in(State::IN_INPUT) && strncmp(str, "description", length) == 0) {
push(State::IN_INPUT_DESCRIPTION);
inputHasDescription = true;
} else if (in(State::IN_INPUT) && strncmp(str, "subspec", length) == 0) {
push(State::IN_INPUT_SUBSPEC);
inputHasSubSpec = true;
Expand Down Expand Up @@ -589,6 +611,7 @@ struct WorkflowImporter : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
std::string optionHelp;
bool outputHasSubSpec;
bool inputHasSubSpec;
bool inputHasDescription;
};

void WorkflowSerializationHelpers::import(std::istream& s,
Expand Down Expand Up @@ -644,17 +667,19 @@ void WorkflowSerializationHelpers::dump(std::ostream& out,
/// FIXME: this only works for a selected set of InputSpecs...
/// a proper way to fully serialize an InputSpec with
/// a DataDescriptorMatcher is needed.
auto dataType = DataSpecUtils::asConcreteDataTypeMatcher(input);
if (dataType.origin == header::DataOrigin("DPL")) {
continue;
}
w.StartObject();
w.Key("binding");
w.String(input.binding.c_str());
w.Key("origin");
w.String(dataType.origin.str, strnlen(dataType.origin.str, 4));
w.Key("description");
w.String(dataType.description.str, strnlen(dataType.description.str, 16));
auto origin = DataSpecUtils::getOptionalOrigin(input);
if (origin.has_value()) {
w.Key("origin");
w.String(origin->str, strnlen(origin->str, 16));
}
auto description = DataSpecUtils::getOptionalDescription(input);
if (description.has_value()) {
w.Key("description");
w.String(description->str, strnlen(description->str, 16));
}
auto subSpec = DataSpecUtils::getOptionalSubSpec(input);
if (subSpec.has_value()) {
w.Key("subspec");
Expand Down

0 comments on commit 87e94b8

Please sign in to comment.