11 #include <fmt/format.h>
12 #include <log4cplus/loggingmacros.h>
51 std::optional<std::string> target_source_name;
54 1 == std::count_if(ctx.
results.begin(),
57 return part.SourceName() == source;
59 auto it = std::find_if(ctx.
results.begin(),
62 return part.SourceName() == source;
64 assert(it != ctx.
results.end());
65 if (std::holds_alternative<std::string>(it->Part())) {
69 auto const& path = std::get<std::string>(it->Part());
71 LOG4CPLUS_DEBUG(logger,
72 fmt::format(
"{}: Heuristics resulted in using the file "
73 "{} from {} as *in-place* merge target.",
76 *target_source_name));
78 source.source_name = it->SourceName();
79 source.location = path;
84 throw boost::enable_current_exception(
85 std::invalid_argument(
"Cannot create data product specification with no results"));
89 if (target_source_name && *target_source_name == r.
SourceName()) {
93 if (std::holds_alternative<fits::KeywordVector>(r.
Part())) {
97 s.keywords = std::get<fits::KeywordVector>(r.
Part());
99 }
else if (std::holds_alternative<std::string>(r.
Part())) {
102 s.location = std::get<std::string>(r.
Part());
121 std::size_t
index = std::numeric_limits<std::size_t>::max();
126 std::unordered_map<std::string, CommonSourceSpecifications>
129 std::size_t index = 1;
130 std::unordered_map<std::string, CommonSourceSpecifications> lookup_map;
132 for (
auto const& source : spec.
sources) {
134 common.
index = index++;
135 std::string source_name;
138 source_name = v.source_name;
144 lookup_map.emplace(std::move(source_name), std::move(common));
168 auto it = lookup_map.find(source_name);
169 if (it != std::end(lookup_map)) {
181 LOG4CPLUS_DEBUG(logger,
"Adding DpPart " << r);
186 std::holds_alternative<std::string>(r.
Part())) {
187 LOG4CPLUS_DEBUG(logger,
"Considering merge target " << r);
194 s.location = std::get<std::string>(r.
Part());
197 LOG4CPLUS_DEBUG(logger,
198 fmt::format(
"Added merge target source from {} with file {}",
203 LOG4CPLUS_WARN(logger,
204 fmt::format(
"Multiple source files matched as merge-target! First "
205 "one has been chosen: {}",
211 if (std::holds_alternative<fits::KeywordVector>(r.
Part())) {
214 s.keywords = std::get<fits::KeywordVector>(r.
Part());
215 if (common !=
nullptr) {
216 LOG4CPLUS_INFO(logger,
217 "Has common, and " << (!common->keyword_rules.empty()
218 ?
"has keyword rules"
219 :
"does NOT have keyword rules"));
220 s.initial_keywords = common->initial_keywords;
221 s.keyword_rules = common->keyword_rules;
224 }
else if (std::holds_alternative<std::string>(r.
Part())) {
227 s.location = std::get<std::string>(r.
Part());
228 if (common !=
nullptr) {
229 LOG4CPLUS_INFO(logger,
230 "Has common, and " << (!common->keyword_rules.empty()
231 ?
"has keyword rules"
232 :
"does NOT have keyword rules"));
233 s.initial_keywords = common->initial_keywords;
234 s.keyword_rules = common->keyword_rules;
243 auto const& name = std::visit([](
auto const& t) {
return t.source_name; }, s);
244 if (name == ocm_name) {
248 auto* res = lookup(name);
249 if (res !=
nullptr) {
252 return std::numeric_limits<std::size_t>::max();
256 std::stable_sort(std::begin(dp_spec.
sources),
259 return index_of(a) < index_of(b);
267 LOG4CPLUS_DEBUG(logger,
268 "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
std::optional< FitsFileSource > source
std::vector< KeywordRuleTypes > KeywordRules
std::vector< SourceTypes > sources
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
std::unordered_map< std::string, CommonSourceSpecifications > MakeCommonSpecifications(json::StartDaqV2Spec const &spec)
json::KeywordRules keyword_rules
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.