11#include <boost/exception/enable_current_exception.hpp>
12#include <fmt/format.h>
13#include <log4cplus/loggingmacros.h>
52 std::optional<std::string> target_source_name;
55 1 == std::count_if(ctx.
results.begin(),
58 return part.SourceName() == source;
60 auto it = std::find_if(ctx.
results.begin(),
63 return part.SourceName() == source;
65 assert(it != ctx.
results.end());
66 if (std::holds_alternative<std::string>(it->Part())) {
70 auto const& path = std::get<std::string>(it->Part());
72 LOG4CPLUS_DEBUG(logger,
73 fmt::format(
"{}: Heuristics resulted in using the file "
74 "{} from {} as *in-place* merge target.",
77 *target_source_name));
79 source.source_name = it->SourceName();
80 source.location = path;
85 throw boost::enable_current_exception(
86 std::invalid_argument(
"Cannot create data product specification with no results"));
90 if (target_source_name && *target_source_name == r.
SourceName()) {
94 if (std::holds_alternative<fits::KeywordVector>(r.
Part())) {
98 s.keywords = std::get<fits::KeywordVector>(r.
Part());
100 }
else if (std::holds_alternative<std::string>(r.
Part())) {
103 s.location = std::get<std::string>(r.
Part());
122 std::size_t
index = std::numeric_limits<std::size_t>::max();
127std::unordered_map<std::string, CommonSourceSpecifications>
130 std::size_t index = 1;
131 std::unordered_map<std::string, CommonSourceSpecifications> lookup_map;
133 for (
auto const& source : spec.
sources) {
135 common.
index = index++;
136 std::string source_name;
139 source_name = v.source_name;
145 lookup_map.emplace(std::move(source_name), std::move(common));
165 LOG4CPLUS_DEBUG(logger,
166 fmt::format(
"{}: Number of receivers added from StartDaqV2Spec: {}",
170 LOG4CPLUS_DEBUG(logger,
171 fmt::format(
"{}: No receivers added from StartDaqV2Spec: {}",
183 auto it = lookup_map.find(source_name);
184 if (it != std::end(lookup_map)) {
196 LOG4CPLUS_DEBUG(logger,
"Adding DpPart " << r);
201 std::holds_alternative<std::string>(r.
Part())) {
202 LOG4CPLUS_DEBUG(logger,
"Considering merge target " << r);
209 s.location = std::get<std::string>(r.
Part());
212 LOG4CPLUS_DEBUG(logger,
213 fmt::format(
"Added merge target source from {} with file {}",
218 LOG4CPLUS_WARN(logger,
219 fmt::format(
"Multiple source files matched as merge-target! First "
220 "one has been chosen: {}",
226 if (std::holds_alternative<fits::KeywordVector>(r.
Part())) {
229 s.keywords = std::get<fits::KeywordVector>(r.
Part());
230 if (common !=
nullptr) {
231 LOG4CPLUS_INFO(logger,
232 "Has common, and " << (!common->keyword_rules.empty()
233 ?
"has keyword rules"
234 :
"does NOT have keyword rules"));
235 s.initial_keywords = common->initial_keywords;
236 s.keyword_rules = common->keyword_rules;
239 }
else if (std::holds_alternative<std::string>(r.
Part())) {
242 s.location = std::get<std::string>(r.
Part());
243 if (common !=
nullptr) {
244 LOG4CPLUS_INFO(logger,
245 "Has common, and " << (!common->keyword_rules.empty()
246 ?
"has keyword rules"
247 :
"does NOT have keyword rules"));
248 s.initial_keywords = common->initial_keywords;
249 s.keyword_rules = common->keyword_rules;
258 auto const& name = std::visit([](
auto const& t) {
return t.source_name; }, s);
259 if (name == ocm_name) {
263 auto* res = lookup(name);
264 if (res !=
nullptr) {
267 return std::numeric_limits<std::size_t>::max();
271 std::stable_sort(std::begin(dp_spec.
sources),
274 return index_of(a) < index_of(b);
283 LOG4CPLUS_DEBUG(logger,
284 "MakeDataProductSpecification: DaqContext has a specification: "
Provides information of the location and source of a FITS file or keywords produced by a data acquisi...
auto Part() const noexcept -> PartTypes const &
Holds a std::string path [[user]@host:]path or FITS keywords.
auto SourceName() const noexcept -> std::string const &
Source name of the part.
Contains data structure for FITS keywords.
fits::KeywordVector keywords
Target target
Describes target which will become the data produtc.
std::optional< FitsFileSource > source
std::vector< KeywordRuleTypes > KeywordRules
ReceiverList receivers
Ordered container of receivers where to deliver the target data product.
std::vector< SourceTypes > sources
List of sources to create data product from.
std::variant< FitsKeywordsSource, FitsFileSource > SourceTypes
std::string file_prefix
Optioal user chosen file prefix to make it easier to identify the produced file.
std::vector< DataSourceTypes > sources
Close representation of the JSON structure but with stronger types.
Structure with a close mapping from JSON representation in the StartDaqV2 MAL request.
json::DpSpec MakeDataProductSpecification(DaqContext const &ctx, log4cplus::Logger &logger)
std::optional< json::InitialKeywords > initial_keywords
json::KeywordRules keyword_rules
std::unordered_map< std::string, CommonSourceSpecifications > MakeCommonSpecifications(json::StartDaqV2Spec const &spec)
std::size_t index
Position index in original specification, used to order sources.
json::DpSpec MakeDataProductSpecification(DaqContext const &ctx, log4cplus::Logger &logger)
Creates and returns the /sources and /target structures using DaqContext::specification.
Per data source common specification that is only used for more efficient lookup.
json::FitsKeywordsSource MakeOcmKeywords(DaqContext const &ctx, log4cplus::Logger &logger)
Make OCM keywords source.
std::string MakeOcmName(DaqContext const &ctx)
json::DpSpec MakeDataProductSpecification(DaqContext const &ctx, log4cplus::Logger &logger)
Creates a Data Product Specification as serialized JSON from the provided DaqContext.
Structure carrying context needed to start a Data Acquisition and construct a Data Product Specificat...
DpParts results
Results from Data Acquisition (FITS files and keywords).
std::string process_name
User defined process name.
std::vector< daq::fits::KeywordVariant > keywords
Keyword list provided by OCM to Data Product.
std::vector< Source > prim_sources
std::optional< json::StartDaqV2Spec > specification
Optional specification, if DAQ was started using StartDaqV2.
std::string file_id
Data Product FileId as specified by OLAS ICD.
std::string dp_name_prefix
Data product file name prefix.
std::string id
DAQ identfier, possibly provided by user.