ifw-daq  1.0.0
IFW Data Acquisition modules
fitsController.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * @ingroup daq_ocm_libdaq
4  * @copyright 2021 ESO - European Southern Observatory
5  *
6  * @brief Contains declaration for for FitsController
7  */
8 #ifndef OCF_DAQ_FITS_CONTROLLER_HPP_
9 #define OCF_DAQ_FITS_CONTROLLER_HPP_
10 #include "config.hpp"
11 
12 #include <functional>
13 #include <memory>
14 #include <optional>
15 #include <string>
16 #include <variant>
17 
18 #include <boost/thread/future.hpp>
19 #include <daq/fits/cfitsio.hpp>
20 #include <daq/fits/keyword.hpp>
21 #include <log4cplus/logger.h>
22 
23 #include "daqProperties.hpp"
24 #include "error.hpp"
25 #include "eventLog.hpp"
26 #include "state.hpp"
27 #include "status.hpp"
28 
29 namespace daq {
30 
31 class FitsController;
32 
33 /**
34  * Print status information to provided ostream.
35  *
36  * @ingroup daq_ocm_libdaq
37  */
38 std::ostream& operator<<(std::ostream& os, FitsController const& ctl);
39 
40 /**
41  * Create FITS file containing keywords from OCM for the Data Acquisition.
42  *
43  * Responsibilities:
44  * - Create FITS file for persistance.
45  * - Accept keywords and keyword changes from user and store them in FITS file.
46  *
47  * @note It is not planned to be responsible for any crash recovery storage.
48  * List of keywords are temporarily stored in daq::Status/daq::ObservableStatus.
49 
50  * Design notes:
51  * - Async interface was not deemed necessary.
52  *
53  * Pending interface:
54  * - AddComment()
55  *
56  * @ingroup daq_ocm_libdaq
57  */
59 public:
60  virtual ~FitsController() = default;
61  /** @name Modifiers
62  * @{
63  */
64  /**
65  * Creates FITS file and pupulates it with initial list of keywords.
66  *
67  * @pre `GetState() == State::NotStarted`.
68  * @throws fits::CfitsioError on errors with cfitsio.
69  * @throws std::runtime_error on error.
70  */
71  virtual void Start() = 0;
72 
73  /**
74  * Finalizes the FITS file.
75  *
76  * If policy ErrorPolicy::Strict the function will throw if there was any error in creating the
77  * FITS file. If policy is ErrorPolicy::Tolerant exception will only be thrown for fatal errors,
78  * not if FITS file failed to be created.
79  *
80  * @param policy Controls the error policy.
81  *
82  * @return Created and closed FITS file if successful.
83  * @return std::nullopt if file could not be created and policy is ErrorPolicy;:Tolerant.
84  *
85  * @throws std::runtime_error if `GetState() != State::Acquiring`.
86  * @throws daq::fits::CfitsioError if no FITS file could be created and policy ==
87  * ErrorPolicy::Strict.
88  */
89  virtual std::optional<DpPart> Stop(ErrorPolicy policy) = 0;
90 
91  /**
92  * Aborts and deletes FITS file.
93  * @pre `GetState() == State::Acquiring`.
94  */
95  virtual void Abort(ErrorPolicy policy) = 0;
96 
97  /**
98  * Updates with provided keywords.
99  *
100  * @param keywords Keywords to add or replace.
101  " @throws std::runtime_error if `GetState() == State::Stopped || GetState() == State::Aborted`.
102  */
103  virtual void UpdateKeywords(std::vector<fits::KeywordVariant> const& keywords) = 0;
104 
105  /**
106  * Add comment.
107  *
108  * @pre `GetState() != State::Stopped && GetState() != State::Aborted`.
109  *
110  * @param comment Comment to add to FITS file.
111  " @throws std::runtime_error if `GetState() == State::Stopped || GetState() == State::Aborted`.
112  */
113  virtual void AddComment(std::string comment) = 0;
114 
115  /** @} */
116 
117  /** @name Accessors
118  * @{
119  */
120  virtual std::string const& GetId() const DAQ_NOEXCEPT = 0;
121 
122  /**
123  * Query FITS file path.
124  *
125  * @return FITS file name.
126  */
127  virtual std::optional<DpPart> GetResult() const DAQ_NOEXCEPT = 0;
128 
129  /**
130  * Query state.
131  *
132  * @return state.
133  */
134  virtual State GetState() const DAQ_NOEXCEPT = 0;
135  /** @} */
136 };
137 
138 class FitsControllerImpl final : public FitsController {
139 public:
141  DaqProperties const& properties,
142  std::shared_ptr<ObservableEventLog> event_log,
143  std::function<fits::UniqueFitsFile(char const*)> fits_create = &fits::CreateEmpty);
144  void Start() override;
145  std::optional<DpPart> Stop(ErrorPolicy policy) override;
146  void Abort(ErrorPolicy policy) override;
147  void UpdateKeywords(std::vector<fits::KeywordVariant>const& ) override;
148  void AddComment(std::string comment) override;
149 
150  std::string const& GetId() const DAQ_NOEXCEPT override;
151  std::optional<DpPart> GetResult() const DAQ_NOEXCEPT override;
152  State GetState() const DAQ_NOEXCEPT override;
153 
154  fitsfile* GetFitsfile() const noexcept {
155  return m_file.get();
156  }
157 
158 private:
159  struct NotStarted {};
160  struct Acquiring {};
161  struct Stopped {};
162  struct Aborted {};
163  using StateVariant = std::variant<NotStarted, Acquiring, Stopped, Aborted>;
164 
165  /**
166  * Write keywords from m_keywords and m_comments to already opened m_file,
167  * formatting them according to dictionary (TODO)
168  */
169  void WriteFitsfile();
170 
171  std::string m_id;
172  std::string m_out_path;
173  std::shared_ptr<ObservableEventLog> m_event_log;
174  std::function<fits::UniqueFitsFile(char const*)> m_fits_create;
175 
176  std::string m_hostname;
177  /** Internal state */
178  StateVariant m_state;
179  /** Internal storage of keywords for easy modification until written to file */
180  std::vector<fits::KeywordVariant> m_keywords;
181  std::vector<std::string> m_comments;
182 
183  /**
184  * FITS absolute file path. Is empty until created in StartAsync().
185  */
186  std::string m_file_path;
187  fits::UniqueFitsFile m_file;
188  DpPart m_result;
189  log4cplus::Logger m_logger;
190 };
191 
192 } // namespace daq
193 
194 #endif // #ifndef OCF_DAQ_FITS_CONTROLLER_HPP_
DAQ_NOEXCEPT
#define DAQ_NOEXCEPT
Definition: config.hpp:16
daq::State
State
Observable states of the data acquisition process.
Definition: state.hpp:41
daq::FitsControllerImpl
Definition: fitsController.hpp:138
daq::fits::CreateEmpty
UniqueFitsFile CreateEmpty(char const *filename)
Creates empty FITS file using fits_create_file and returns a pointer with a deleter that will close t...
Definition: cfitsio.cpp:79
daq::DaqProperties
Structure carrying properties needed to start a DataAcquisition.
Definition: daqProperties.hpp:28
daq::FitsController::UpdateKeywords
virtual void UpdateKeywords(std::vector< fits::KeywordVariant > const &keywords)=0
Updates with provided keywords.
keyword.hpp
Contains data structure for FITS keywords.
daq::FitsController::~FitsController
virtual ~FitsController()=default
daq
Definition: daqController.cpp:18
daq::FitsController::GetId
virtual std::string const & GetId() const DAQ_NOEXCEPT=0
Query FITS file path.
eventLog.hpp
Contains declaration for EventLog, ObservableEventLog and related events.
daq::FitsController::GetState
virtual State GetState() const DAQ_NOEXCEPT=0
Query state.
daq::fits::UniqueFitsFile
std::unique_ptr< fitsfile, void(*)(fitsfile *) noexcept > UniqueFitsFile
Defines unique ownership type to cfitsio fitsfile.
Definition: cfitsio.hpp:46
config.hpp
Config class header file.
daq::FitsController::GetResult
virtual std::optional< DpPart > GetResult() const DAQ_NOEXCEPT=0
Query FITS file path.
daq::FitsController::AddComment
virtual void AddComment(std::string comment)=0
Add comment.
status.hpp
Contains declaration for Status and ObservableStatus.
daq::DpPart
Provides information of the location and origin of a FITS file or keywords produced by a data acquisi...
Definition: dpPart.hpp:26
daq::FitsControllerImpl::GetFitsfile
fitsfile * GetFitsfile() const noexcept
Definition: fitsController.hpp:154
daq::FitsController::Start
virtual void Start()=0
Creates FITS file and pupulates it with initial list of keywords.
cfitsio.hpp
Contains functions and data structures related to cfitsio.
daq::operator<<
std::ostream & operator<<(std::ostream &os, DaqController const &daq)
Definition: daqController.cpp:49
daq::FitsController
Create FITS file containing keywords from OCM for the Data Acquisition.
Definition: fitsController.hpp:58
state.hpp
Declares daq::State and related functions.
daq::State::NotStarted
@ NotStarted
Initial state of data acquisition.
daq::ErrorPolicy
ErrorPolicy
Error policy supported by certain operations.
Definition: error.hpp:25
daqProperties.hpp
Contains declaration of daq::Properties.
daq::FitsController::Stop
virtual std::optional< DpPart > Stop(ErrorPolicy policy)=0
Finalizes the FITS file.
daq::FitsController::Abort
virtual void Abort(ErrorPolicy policy)=0
Aborts and deletes FITS file.
error.hpp
Contains error related declarations for DAQ.