ifw-daq 3.1.0
IFW Data Acquisition modules
Loading...
Searching...
No Matches
json.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup daq_common_libdaq
4 * @copyright (c) Copyright ESO 2022
5 * All Rights Reserved
6 * ESO (eso.org) is an Intergovernmental Organisation, and therefore special legal conditions apply.
7 *
8 * @brief Declares JSON support for serialization
9 */
10#include <daq/json.hpp>
11
12#include <fmt/format.h>
13
14#include <daq/daqContext.hpp>
15#include <daq/fits/json.hpp>
16#include <daq/status.hpp>
17
18namespace daq {
19
20namespace {
21template <class Clock, class Duration>
22double MakeTimestamp(std::chrono::time_point<Clock, Duration> const& ts) {
23 using Seconds = std::chrono::duration<double, std::ratio<1>>;
24 return std::chrono::time_point_cast<Seconds>(ts).time_since_epoch().count();
25}
26
27template <class Clock, class Duration>
28void MakeTimepoint(std::chrono::time_point<Clock, Duration>& ts, double time) {
29 using Seconds = std::chrono::duration<double, std::ratio<1>>;
30 ts = std::chrono::time_point<Clock, Duration>(
31 std::chrono::duration_cast<Duration>(Seconds(time)));
32}
33
34} // namespace
35
36// NOLINTNEXTLINE
37void to_json(nlohmann::json& j, Status const& p) {
38 j = nlohmann::json{{"id", p.id},
39 {"fileId", p.file_id},
40 {"state", p.state},
41 {"alerts", p.alerts},
42 {"receivers", p.receivers},
43 {"result", p.result},
44 {"timestamp", MakeTimestamp(p.timestamp)}};
45}
46
47// NOLINTNEXTLINE
48void to_json(nlohmann::json& j, Alert const& p) {
49 j = nlohmann::json{{"category", p.id.category},
50 {"key", p.id.key},
51 {"description", p.description},
52 {"timestamp", MakeTimestamp(p.timestamp)}};
53}
54
55// NOLINTNEXTLINE
56void to_json(nlohmann::json& j, ReceiverStatus const& p) {
57 j = nlohmann::json{{"state", p.state}};
58}
59
60// NOLINTNEXTLINE
61void to_json(nlohmann::json& j, DaqContext const& p) {
63 j = nlohmann::json{
64 {"id", p.id},
65 {"fileId", p.file_id},
66 {"creationTime", std::chrono::nanoseconds(p.creation_time.time_since_epoch()).count()},
67 {"processName", p.process_name},
68 {"dpNamePrefix", p.dp_name_prefix},
69 {"primSources", p.prim_sources},
70 {"metaSources", p.meta_sources},
71 {"keywords", std::move(kws)},
72 {"awaitInterval", p.await_interval.count()},
73 {"dpParts", p.results}};
74
75 // Optional specification
76 if (p.specification) {
77 j["specification"] = *p.specification;
78 }
79}
80//
81// NOLINTNEXTLINE
82void to_json(nlohmann::json& j, DaqContext::Source const& p) {
83 j = nlohmann::json{{"name", p.name}, {"rrUri", p.rr_uri}};
84}
85
86// NOLINTNEXTLINE
87void to_json(nlohmann::json& j, DpPart const& p) {
88 if (std::holds_alternative<fits::KeywordVector>(p.Part())) {
89 // keywords
90 auto kws = fits::SerializeJsonKeywords(std::get<fits::KeywordVector>(p.Part()));
91 j = nlohmann::json::object(
92 {{"type", "fitsKeywords"}, {"sourceName", p.SourceName()}, {"keywords", std::move(kws)}});
93 } else if (std::holds_alternative<std::string>(p.Part())) {
94 auto const& path = std::get<std::string>(p.Part());
95 j = nlohmann::json::object(
96 {{"type", "fitsFile"}, {"sourceName", p.SourceName()}, {"location", path}});
97 }
98}
99
100// NOLINTNEXTLINE
101void from_json(nlohmann::json const& j, Status& p) {
102 j.at("id").get_to(p.id);
103 j.at("fileId").get_to(p.file_id);
104 j.at("state").get_to(p.state);
105 j.at("alerts").get_to(p.alerts);
106 j.at("receivers").get_to(p.receivers);
107 j.at("result").get_to(p.result);
108 double ts;
109 j.at("timestamp").get_to(ts);
110 MakeTimepoint(p.timestamp, ts);
111}
112
113// NOLINTNEXTLINE
114void from_json(nlohmann::json const& j, Alert& p) {
115 j.at("category").get_to(p.id.category);
116 j.at("key").get_to(p.id.key);
117 j.at("description").get_to(p.description);
118 double ts;
119 j.at("timestamp").get_to(ts);
120 MakeTimepoint(p.timestamp, ts);
121}
122
123// NOLINTNEXTLINE
124void from_json(nlohmann::json const& j, ReceiverStatus& p) {
125 j.at("state").get_to(p.state);
126}
127
128// NOLINTNEXTLINE
129void from_json(nlohmann::json const& j, DaqContext& p) {
130 j.at("id").get_to(p.id);
131 j.at("fileId").get_to(p.file_id);
132 j.at("processName").get_to(p.process_name);
133 j.at("dpNamePrefix").get_to(p.dp_name_prefix);
134 j.at("primSources").get_to(p.prim_sources);
135 j.at("metaSources").get_to(p.meta_sources);
136 unsigned interval;
137 j.at("awaitInterval").get_to(interval);
138 p.await_interval = decltype(p.await_interval)(interval);
139 j.at("dpParts").get_to(p.results);
140 p.keywords = fits::ParseJsonKeywords(j["keywords"]);
141 int64_t time_since_epoch_ns;
142 j.at("creationTime").get_to(time_since_epoch_ns);
143 using Time = std::chrono::system_clock::time_point;
144 p.creation_time = Time(std::chrono::nanoseconds(time_since_epoch_ns));
145
146 if (j.contains("specification")) {
147 p.specification = json::ParseStartDaqV2Spec(j.at("specification"));
148 }
149}
150
151// NOLINTNEXTLINE
152void from_json(nlohmann::json const& j, DaqContext::Source& p) {
153 j.at("name").get_to(p.name);
154 j.at("rrUri").get_to(p.rr_uri);
155}
156
157// NOLINTNEXTLINE
158void from_json(nlohmann::json const& j, DpPart& p) {
159 std::string type;
160 std::string name;
161 j.at("type").get_to(type);
162 j.at("sourceName").get_to(p.SourceName());
163
164 if (type == "fitsKeywords") {
165 p.Part() = fits::ParseJsonKeywords(j.at("keywords"));
166 } else if (type == "fitsFile") {
167 std::string path;
168 j.at("location").get_to(path);
169 p.Part() = path;
170 } else {
171 throw std::invalid_argument(fmt::format("Invalid type: {}", type));
172 }
173}
174
175} // namespace daq
Provides information of the location and source of a FITS file or keywords produced by a data acquisi...
Definition: dpPart.hpp:26
auto Part() const noexcept -> PartTypes const &
Holds a std::string path [[user]@host:]path or FITS keywords.
Definition: dpPart.hpp:54
auto SourceName() const noexcept -> std::string const &
Source name of the part.
Definition: dpPart.hpp:44
Declares JSON support for serialization.
Contains data structure for FITS keywords.
Contains declaration of daq::Context.
nlohmann::json SerializeJsonKeywords(std::vector< KeywordVariant > const &keywords)
SerializeJsons keyword to JSON.
Definition: json.cpp:200
std::vector< KeywordVariant > ParseJsonKeywords(char const *keywords)
Parse and return FITS keywords.
Definition: json.cpp:124
StartDaqV2Spec ParseStartDaqV2Spec(nlohmann::json const &json)
Parse StartDaqSpec.
Definition: startDaqV2.cpp:46
AlertId id
Definition: status.hpp:99
std::string key
Unique key for each alert.
Definition: status.hpp:76
std::string description
Definition: status.hpp:100
TimePoint timestamp
Definition: status.hpp:101
void from_json(nlohmann::json const &j, Status &p)
Definition: json.cpp:101
std::string category
Standardized category.
Definition: status.hpp:72
void to_json(nlohmann::json &j, Status const &p)
Definition: json.cpp:37
Describes an active Data Acquisition alert.
Definition: status.hpp:95
Contains declaration for Status and ObservableStatus.
Structure carrying context needed to start a Data Acquisition and construct a Data Product Specificat...
Definition: daqContext.hpp:42
std::vector< Source > meta_sources
Definition: daqContext.hpp:75
DpParts results
Results from Data Acquisition (FITS files and keywords).
Definition: daqContext.hpp:100
std::string process_name
User defined process name.
Definition: daqContext.hpp:68
std::vector< daq::fits::KeywordVariant > keywords
Keyword list provided by OCM to Data Product.
Definition: daqContext.hpp:85
std::vector< Source > prim_sources
Definition: daqContext.hpp:74
std::chrono::milliseconds await_interval
Interval (and thus duration) of the requests sent to primary sources to await end of recording.
Definition: daqContext.hpp:92
std::optional< json::StartDaqV2Spec > specification
Optional specification, if DAQ was started using StartDaqV2.
Definition: daqContext.hpp:114
std::string file_id
Data Product FileId as specified by OLAS ICD.
Definition: daqContext.hpp:63
std::string dp_name_prefix
Data product file name prefix.
Definition: daqContext.hpp:73
std::chrono::system_clock::time_point creation_time
Time when DAQ was created.
Definition: daqContext.hpp:106
std::string id
DAQ identfier, possibly provided by user.
Definition: daqContext.hpp:58
Persistent status for receiver delivery.
Definition: status.hpp:145
Non observable status object that keeps stores status of data acquisition.
Definition: status.hpp:164
State state
Definition: status.hpp:186
std::string id
Definition: status.hpp:184
std::string result
Path to resulting data product.
Definition: status.hpp:202
std::map< std::size_t, ReceiverStatus > receivers
Receiver processing (e.g.
Definition: status.hpp:197
std::string file_id
Definition: status.hpp:185
std::vector< Alert > alerts
Active alerts.
Definition: status.hpp:190
TimePoint timestamp
Timestamp of last update.
Definition: status.hpp:207