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));
164 LOG4CPLUS_DEBUG(logger,
165 fmt::format(
"{}: Number of receivers added from StartDaqV2Spec: {}",
169 LOG4CPLUS_DEBUG(logger,
170 fmt::format(
"{}: No receivers added from StartDaqV2Spec: {}",
182 auto it = lookup_map.find(source_name);
183 if (it != std::end(lookup_map)) {
195 LOG4CPLUS_DEBUG(logger,
"Adding DpPart " << r);
200 std::holds_alternative<std::string>(r.
Part())) {
201 LOG4CPLUS_DEBUG(logger,
"Considering merge target " << r);
208 s.location = std::get<std::string>(r.
Part());
211 LOG4CPLUS_DEBUG(logger,
212 fmt::format(
"Added merge target source from {} with file {}",
217 LOG4CPLUS_WARN(logger,
218 fmt::format(
"Multiple source files matched as merge-target! First "
219 "one has been chosen: {}",
225 if (std::holds_alternative<fits::KeywordVector>(r.
Part())) {
228 s.keywords = std::get<fits::KeywordVector>(r.
Part());
229 if (common !=
nullptr) {
230 LOG4CPLUS_INFO(logger,
231 "Has common, and " << (!common->keyword_rules.empty()
232 ?
"has keyword rules"
233 :
"does NOT have keyword rules"));
234 s.initial_keywords = common->initial_keywords;
235 s.keyword_rules = common->keyword_rules;
238 }
else if (std::holds_alternative<std::string>(r.
Part())) {
241 s.location = std::get<std::string>(r.
Part());
242 if (common !=
nullptr) {
243 LOG4CPLUS_INFO(logger,
244 "Has common, and " << (!common->keyword_rules.empty()
245 ?
"has keyword rules"
246 :
"does NOT have keyword rules"));
247 s.initial_keywords = common->initial_keywords;
248 s.keyword_rules = common->keyword_rules;
257 auto const& name = std::visit([](
auto const& t) {
return t.source_name; }, s);
258 if (name == ocm_name) {
262 auto* res = lookup(name);
263 if (res !=
nullptr) {
266 return std::numeric_limits<std::size_t>::max();
270 std::stable_sort(std::begin(dp_spec.
sources),
273 return index_of(a) < index_of(b);
282 LOG4CPLUS_DEBUG(logger,
283 "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
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.