diff --git a/Framework/CMakeLists.txt b/Framework/CMakeLists.txt index 89be5a43d4..6080440313 100644 --- a/Framework/CMakeLists.txt +++ b/Framework/CMakeLists.txt @@ -98,7 +98,7 @@ add_library(O2QualityControl src/InfrastructureSpecReader.cxx src/Check.cxx src/Aggregator.cxx - src/HashDataDescription.cxx + src/DataHeaderHelpers.cxx src/Triggers.cxx src/TriggerHelpers.cxx src/PostProcessingRunner.cxx @@ -139,6 +139,7 @@ add_library(O2QualityControl src/ObjectMetadataHelpers.cxx src/QCInputsAdapters.cxx src/QCInputsFactory.cxx + src/UserInputOutput.cxx ) target_include_directories( @@ -276,6 +277,7 @@ add_executable(o2-qc-test-core test/testCheckInterface.cxx test/testCheckRunner.cxx test/testCustomParameters.cxx + test/testDataHeaderHelpers.cxx test/testInfrastructureGenerator.cxx test/testMonitorObject.cxx test/testPolicyManager.cxx @@ -293,6 +295,7 @@ add_executable(o2-qc-test-core test/testFlagHelpers.cxx test/testQualitiesToFlagCollectionConverter.cxx test/testQCInputs.cxx + test/testUserInputOutput.cxx ) set_property(TARGET o2-qc-test-core PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests) diff --git a/Framework/include/QualityControl/DataHeaderHelpers.h b/Framework/include/QualityControl/DataHeaderHelpers.h new file mode 100644 index 0000000000..fe1eb2c655 --- /dev/null +++ b/Framework/include/QualityControl/DataHeaderHelpers.h @@ -0,0 +1,57 @@ +// Copyright 2019-2024 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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 QC_DATA_HEADER_HELPERS_H +#define QC_DATA_HEADER_HELPERS_H + +#include +#include + +#include + +#include "QualityControl/DataSourceType.h" + +namespace o2::quality_control::core +{ + +/// \brief Creates DataOrigin for a QC Actor. +/// +/// Creates DataOrigin for a data source and detector code +header::DataOrigin createDataOrigin(DataSourceType, const std::string& detectorCode); + +/// \brief Creates DataDescription from given name for a QC actor +/// +/// If the length of the name is <= 16 (hardcoded in DataDescription) it creates DataDescription from the original name. +/// However, if the length of the name is > 16, it will create hash of the whole name and replace ending hashLength of bytes +/// of the name with hexa representation of computed hash. +/// eg.: name == "veryLongNameThatIsLongerThan16B" with hashLength == 4 will result in "veryLongNameABCD", where ABCD +/// is the hash create inside the function +/// +/// \param name - name which should cut and hashed +/// \param hashLength - number of bytes which will overwrite the end of the name +o2::header::DataDescription createDataDescription(const std::string& name, size_t hashLength); + +/// \brief Creates DataDescription from given name for a QC actor +/// +/// If the length of the name is <= 16 (hardcoded in DataDescription) it creates DataDescription from the original name. +/// However, if the length of the name is > 16, it will create hash of the whole name and replace ending hashLength of bytes +/// of the name with hexa representation of computed hash. +/// eg.: name == "veryLongNameThatIsLongerThan16B" with hashLength == 4 will result in "veryLongNameABCD", where ABCD +/// is the hash create inside the function. +/// This function deduces hash length for the provided data source type. +/// +/// \param name - name which should cut and hashed +/// \param type - data source type associated to an actor +o2::header::DataDescription createDataDescription(const std::string& name, DataSourceType type); + +} // namespace o2::quality_control::core + +#endif diff --git a/Framework/include/QualityControl/DataSourceSpec.h b/Framework/include/QualityControl/DataSourceSpec.h index 61ac4da7cb..fd0629cd00 100644 --- a/Framework/include/QualityControl/DataSourceSpec.h +++ b/Framework/include/QualityControl/DataSourceSpec.h @@ -21,21 +21,11 @@ #include #include +#include "QualityControl/DataSourceType.h" + namespace o2::quality_control::core { -enum class DataSourceType { - DataSamplingPolicy, - Direct, - Task, - TaskMovingWindow, - Check, - Aggregator, - PostProcessingTask, - ExternalTask, - Invalid -}; - // this should allow us to represent all data sources which come from DPL (and maybe CCDB). struct DataSourceSpec { explicit DataSourceSpec(DataSourceType type = DataSourceType::Invalid); diff --git a/Framework/include/QualityControl/DataSourceType.h b/Framework/include/QualityControl/DataSourceType.h new file mode 100644 index 0000000000..8250fdac6b --- /dev/null +++ b/Framework/include/QualityControl/DataSourceType.h @@ -0,0 +1,37 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// +/// \file DataSourceType.h +/// \author Piotr Konopka +/// + +#ifndef QUALITYCONTROL_DATASOURCETYPE_H +#define QUALITYCONTROL_DATASOURCETYPE_H + +namespace o2::quality_control::core +{ + +enum class DataSourceType { + DataSamplingPolicy, + Direct, + Task, + TaskMovingWindow, + Check, + Aggregator, + PostProcessingTask, + ExternalTask, + Invalid +}; + +} + +#endif // QUALITYCONTROL_DATASOURCETYPE_H \ No newline at end of file diff --git a/Framework/include/QualityControl/HashDataDescription.h b/Framework/include/QualityControl/HashDataDescription.h deleted file mode 100644 index 0cd61a6ee7..0000000000 --- a/Framework/include/QualityControl/HashDataDescription.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2019-2024 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// 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 QC_HASH_DATA_DESCRIPTION_H -#define QC_HASH_DATA_DESCRIPTION_H - -#include -#include - -#include - -namespace o2::quality_control::core -{ - -/// \brief Creates DataDescription from given name. -/// -/// If the length of the name is <= 16 (hardcoded in DataDescription) it creates DataDescription from the original name. -/// However, if the length of the name is > 16, it will create hash of the whole name and replace ending hashLength of bytes -/// of the name with hexa representation of computed hash. -/// eg.: name == "veryLongNameThatIsLongerThan16B" with hashLengh == 4 will result in "veryLongNameABCD", where ABCD -/// is the hash create inside the function -/// -/// \param name - name which should cut and hashed -/// \param hashLenght - number of bytes which will overwrite the end of the name -o2::header::DataDescription createDataDescription(const std::string& name, size_t hashLength); - -} // namespace o2::quality_control::core - -#endif diff --git a/Framework/include/QualityControl/UserInputOutput.h b/Framework/include/QualityControl/UserInputOutput.h new file mode 100644 index 0000000000..6087c5e1ad --- /dev/null +++ b/Framework/include/QualityControl/UserInputOutput.h @@ -0,0 +1,46 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// +/// \file UserInputOutput.h +/// \author Piotr Konopka +/// + +#ifndef QUALITYCONTROL_USERINPUTOUTPUT_H +#define QUALITYCONTROL_USERINPUTOUTPUT_H + +#include + +#include +#include +#include + +#include "QualityControl/DataHeaderHelpers.h" +#include "QualityControl/DataSourceType.h" + +namespace o2::quality_control::core +{ + +/// \brief returns a standard ConcreteDataMatcher for QC inputs and outputs +framework::ConcreteDataMatcher + createUserDataMatcher(DataSourceType dataSourceType, const std::string& detectorName, const std::string& userCodeName); + +/// \brief returns a standard InputSpec for QC inputs and outputs +framework::InputSpec + createUserInputSpec(DataSourceType dataSourceType, const std::string& detectorName, const std::string& userCodeName); + +/// \brief returns a standard OutputSpec for QC inputs and outputs +framework::OutputSpec + createUserOutputSpec(DataSourceType dataSourceType, const std::string& detectorName, const std::string& userCodeName); + +} // namespace o2::quality_control::core + +#endif // QUALITYCONTROL_USERINPUTOUTPUT_H \ No newline at end of file diff --git a/Framework/src/Aggregator.cxx b/Framework/src/Aggregator.cxx index 42551ea064..5a6934dd60 100644 --- a/Framework/src/Aggregator.cxx +++ b/Framework/src/Aggregator.cxx @@ -26,7 +26,7 @@ #include "QualityControl/Activity.h" #include #include "QualityControl/CommonSpec.h" -#include "QualityControl/HashDataDescription.h" +#include "QualityControl/DataHeaderHelpers.h" #include #include diff --git a/Framework/src/AggregatorRunner.cxx b/Framework/src/AggregatorRunner.cxx index ddcea3ae4f..09422d4029 100644 --- a/Framework/src/AggregatorRunner.cxx +++ b/Framework/src/AggregatorRunner.cxx @@ -41,7 +41,7 @@ #include "QualityControl/ConfigParamGlo.h" #include "QualityControl/Bookkeeping.h" #include "QualityControl/WorkflowType.h" -#include "QualityControl/HashDataDescription.h" +#include "QualityControl/DataHeaderHelpers.h" using namespace AliceO2::Common; using namespace AliceO2::InfoLogger; diff --git a/Framework/src/Check.cxx b/Framework/src/Check.cxx index f9d12ad2d3..d0f151b314 100644 --- a/Framework/src/Check.cxx +++ b/Framework/src/Check.cxx @@ -29,7 +29,7 @@ #include "QualityControl/RootClassFactory.h" #include "QualityControl/QcInfoLogger.h" #include "QualityControl/Quality.h" -#include "QualityControl/HashDataDescription.h" +#include "QualityControl/DataHeaderHelpers.h" #include "QualityControl/ObjectMetadataHelpers.h" #include diff --git a/Framework/src/HashDataDescription.cxx b/Framework/src/DataHeaderHelpers.cxx similarity index 50% rename from Framework/src/HashDataDescription.cxx rename to Framework/src/DataHeaderHelpers.cxx index 9b62ba4e57..c469bab13f 100644 --- a/Framework/src/HashDataDescription.cxx +++ b/Framework/src/DataHeaderHelpers.cxx @@ -12,12 +12,50 @@ #include #include -#include "QualityControl/HashDataDescription.h" +#include "QualityControl/DataHeaderHelpers.h" #include "QualityControl/QcInfoLogger.h" namespace o2::quality_control::core { +constexpr char CharIdFrom(DataSourceType type) +{ + switch (type) { + case DataSourceType::DataSamplingPolicy: + case DataSourceType::Direct: + case DataSourceType::ExternalTask: + throw std::invalid_argument("Provided data source type is not generated by QC, cannot provide a corresponding character"); + case DataSourceType::Task: + return 'Q'; + case DataSourceType::TaskMovingWindow: + return 'W'; + case DataSourceType::Check: + return 'C'; + case DataSourceType::Aggregator: + return 'A'; + case DataSourceType::PostProcessingTask: + return 'P'; + default: + throw std::invalid_argument("Unrecognized data source type"); + } +} + +header::DataOrigin createDataOrigin(DataSourceType dataSourceType, const std::string& detectorCode) +{ + std::string originStr{ CharIdFrom(dataSourceType) }; + if (detectorCode.empty()) { + throw std::invalid_argument{ "empty detector code for a data source origin" }; + } else if (detectorCode.size() > 3) { + ILOG(Warning, Support) << "too long detector code for a task data origin: " + detectorCode + ", trying to survive with: " + detectorCode.substr(0, 3) << ENDM; + originStr += detectorCode.substr(0, 3); + } else { + originStr += detectorCode; + } + o2::header::DataOrigin origin; + origin.runtimeInit(originStr.c_str()); + return origin; +} + namespace hash { @@ -62,4 +100,29 @@ auto createDataDescription(const std::string& name, size_t hashLength) -> o2::he } } +constexpr size_t descriptionHashLengthFor(DataSourceType type) +{ + size_t hashLength = 0; + switch (type) { + case DataSourceType::DataSamplingPolicy: + case DataSourceType::Direct: + case DataSourceType::ExternalTask: + throw std::invalid_argument("Provided data source type is not generated by QC, cannot provide a hash length"); + case DataSourceType::Task: + case DataSourceType::TaskMovingWindow: + case DataSourceType::Check: + case DataSourceType::Aggregator: + case DataSourceType::PostProcessingTask: + default: + hashLength = 4; + } + assert(hashLength <= o2::header::DataDescription::size); + return hashLength; +} + +auto createDataDescription(const std::string& name, DataSourceType type) -> o2::header::DataDescription +{ + return createDataDescription(name, descriptionHashLengthFor(type)); +} + } // namespace o2::quality_control::core diff --git a/Framework/src/InfrastructureGenerator.cxx b/Framework/src/InfrastructureGenerator.cxx index 31020308b8..8d421c8f0b 100644 --- a/Framework/src/InfrastructureGenerator.cxx +++ b/Framework/src/InfrastructureGenerator.cxx @@ -31,6 +31,7 @@ #include "QualityControl/TaskRunner.h" #include "QualityControl/TaskRunnerFactory.h" #include "QualityControl/Version.h" +#include "QualityControl/UserInputOutput.h" #include #include diff --git a/Framework/src/PostProcessingDevice.cxx b/Framework/src/PostProcessingDevice.cxx index 8c29897a87..4b004357d5 100644 --- a/Framework/src/PostProcessingDevice.cxx +++ b/Framework/src/PostProcessingDevice.cxx @@ -21,7 +21,7 @@ #include "QualityControl/PostProcessingInterface.h" #include "QualityControl/PostProcessingRunnerConfig.h" #include "QualityControl/QcInfoLogger.h" -#include "QualityControl/HashDataDescription.h" +#include "QualityControl/DataHeaderHelpers.h" #include "QualityControl/runnerUtils.h" #include diff --git a/Framework/src/TaskRunner.cxx b/Framework/src/TaskRunner.cxx index 3c16548207..61e19f95b2 100644 --- a/Framework/src/TaskRunner.cxx +++ b/Framework/src/TaskRunner.cxx @@ -49,7 +49,7 @@ #include "QualityControl/TimekeeperFactory.h" #include "QualityControl/ActivityHelpers.h" #include "QualityControl/WorkflowType.h" -#include "QualityControl/HashDataDescription.h" +#include "QualityControl/DataHeaderHelpers.h" #include "QualityControl/runnerUtils.h" #include diff --git a/Framework/src/UserInputOutput.cxx b/Framework/src/UserInputOutput.cxx new file mode 100644 index 0000000000..b9d05b2fc2 --- /dev/null +++ b/Framework/src/UserInputOutput.cxx @@ -0,0 +1,56 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// +/// \file UserInputOutput.cxx +/// \author Piotr Konopka +/// + +#include "QualityControl/UserInputOutput.h" + +namespace o2::quality_control::core +{ + +framework::ConcreteDataMatcher + createUserDataMatcher(DataSourceType dataSourceType, const std::string& detectorName, const std::string& userCodeName) +{ + return { + createDataOrigin(dataSourceType, detectorName), + createDataDescription(userCodeName, dataSourceType), + 0 + }; +} + +framework::InputSpec + createUserInputSpec(DataSourceType dataSourceType, const std::string& detectorName, const std::string& userCodeName) +{ + // currently all of our outputs are Lifetime::Sporadic, so we don't allow for customization, but it could be factored out. + // we assume using `userCodeName` as a binding in all cases + return { + userCodeName, + createUserDataMatcher(dataSourceType, detectorName, userCodeName), + framework::Lifetime::Sporadic + }; +} + +framework::OutputSpec + createUserOutputSpec(DataSourceType dataSourceType, const std::string& detectorName, const std::string& userCodeName) +{ + // currently all of our outputs are Lifetime::Sporadic, so we don't allow for customization, but it could be factored out. + // we assume using `userCodeName` as a binding in all cases + return { + framework::OutputLabel{ userCodeName }, + createUserDataMatcher(dataSourceType, detectorName, userCodeName), + framework::Lifetime::Sporadic + }; +} + +} // namespace o2::quality_control::core \ No newline at end of file diff --git a/Framework/test/testDataHeaderHelpers.cxx b/Framework/test/testDataHeaderHelpers.cxx new file mode 100644 index 0000000000..27e2bc8d65 --- /dev/null +++ b/Framework/test/testDataHeaderHelpers.cxx @@ -0,0 +1,50 @@ +// Copyright 2019-2024 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// +/// \file testDataHeaderHelpers.h +/// \author Piotr Konopka +/// + +#include + +#include + +#include "QualityControl/DataHeaderHelpers.h" +#include "QualityControl/DataSourceType.h" + +using namespace o2::quality_control::core; +using namespace o2::header; + +TEST_CASE("DataOrigin") +{ + CHECK_THROWS(createDataOrigin(DataSourceType::Direct, "TST")); // non-QC data source + CHECK_THROWS(createDataOrigin(DataSourceType::Task, "")); // empty detector is wrong + + CHECK(createDataOrigin(DataSourceType::Task, "TST") == DataOrigin{ "QTST" }); + CHECK(createDataOrigin(DataSourceType::TaskMovingWindow, "TST") == DataOrigin{ "WTST" }); + + CHECK(createDataOrigin(DataSourceType::Task, "TOO_LONG") == DataOrigin{ "QTOO" }); + CHECK(createDataOrigin(DataSourceType::Task, "X") == DataOrigin{ "QX" }); +} + +TEST_CASE("DataDescription") +{ + CHECK(createDataDescription("", 10) == DataDescription("")); + CHECK(createDataDescription("ABC", 10) == DataDescription("ABC")); + CHECK(createDataDescription("ABCDEABCDEABCDEA", 10) == DataDescription("ABCDEABCDEABCDEA")); + CHECK(createDataDescription("LOOOOOOOOOOOOOOONG", 4) != DataDescription("LOOOOOOOOOOOOOON")); + + CHECK_THROWS(createDataDescription("LOOOOOOOOOOOOOOONG", DataDescription::size + 50)); + + CHECK(createDataDescription("LOOOOOOOOOOOOOOONG", DataSourceType::Task) != DataDescription("LOOOOOOOOOOOOOON")); + CHECK_THROWS(createDataDescription("WHATEVER", DataSourceType::ExternalTask)); +} \ No newline at end of file diff --git a/Framework/test/testUserInputOutput.cxx b/Framework/test/testUserInputOutput.cxx new file mode 100644 index 0000000000..d8c3673a57 --- /dev/null +++ b/Framework/test/testUserInputOutput.cxx @@ -0,0 +1,53 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// +/// \file testUserInputOutput.cxx +/// \author Piotr Konopka +/// + +#include + +#include +#include + +#include "QualityControl/UserInputOutput.h" + +using namespace o2::header; + +namespace o2::quality_control::core +{ + +TEST_CASE("ConcreteDataMatcher") +{ + auto dataMatcher = createUserDataMatcher(DataSourceType::Task, "TST", "mytask"); + CHECK(dataMatcher.origin == DataOrigin{ "QTST" }); + CHECK(dataMatcher.description == DataDescription{ "mytask" }); + CHECK(dataMatcher.subSpec == 0); +} + +TEST_CASE("InputSpec") +{ + auto inputSpec = createUserInputSpec(DataSourceType::Task, "TST", "mytask"); + CHECK(inputSpec.binding == "mytask"); + CHECK(inputSpec.lifetime == framework::Lifetime::Sporadic); + CHECK(framework::DataSpecUtils::match(inputSpec, framework::ConcreteDataMatcher{ DataOrigin{ "QTST" }, DataDescription{ "mytask" }, 0 })); +} + +TEST_CASE("OutputSpec") +{ + auto outputSpec = createUserOutputSpec(DataSourceType::Task, "TST", "mytask"); + CHECK(outputSpec.binding.value == "mytask"); + CHECK(outputSpec.lifetime == framework::Lifetime::Sporadic); + CHECK(framework::DataSpecUtils::match(outputSpec, framework::ConcreteDataMatcher{ DataOrigin{ "QTST" }, DataDescription{ "mytask" }, 0 })); +} + +} // namespace o2::quality_control::core