Kstars

darklibrary.h
1 /*
2  SPDX-FileCopyrightText: 2021 Jasem Mutlaq <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include "indi/indicamera.h"
10 #include "indi/indidustcap.h"
11 #include "darkview.h"
12 #include "defectmap.h"
13 #include "ekos/ekos.h"
14 
15 #include <QDialog>
16 #include <QPointer>
17 #include "ui_darklibrary.h"
18 
19 class QSqlTableModel;
21 class FITSHistogramView;
22 
23 namespace Ekos
24 {
25 
26 class Capture;
27 class SequenceJob;
28 
29 /**
30  * @class DarkLibrary
31  * @short Handles acquisition & loading of dark frames and defect map for cameras. If a suitable dark frame exists,
32  * it is loaded from disk, otherwise it gets captured and saved for later use.
33  *
34  * Dark Frames:
35  *
36  * The user can generate dark frames from an average combination of the camera dark frames. By default, 5 dark frames
37  * are captured to merged into a single master frame. Frame duration, binning, and temperature are all configurable.
38  * If the user select "Dark" in any of the Ekos module, Dark Library can be queried if a suitable dark frame exists given
39  * the current camera settings (binning, temperature..etc). If a suitable frame exists, it is loaded up and send to /class DarkProcessor
40  * class along with the light frame to perform subtraction or defect map corrections.
41  *
42  * Defect Maps:
43  *
44  * Some CMOS cameras exhibit hot pixels that are better treated with a defect map. A defect map is a collection of "bad" pixels that
45  * are above or below certain threshold controlled by the user. This should isolate the cold and hotpixels in frames so that they are
46  * removed from the light frames once the defect map is applied against it. This is done using 3x3 median filter over the bad pixels.
47  *
48  * @author Jasem Mutlaq
49  * @version 1.0
50  */
51 class DarkLibrary : public QDialog, public Ui::DarkLibrary
52 {
53  Q_OBJECT
54 
55  public:
56  static DarkLibrary *Instance();
57  static void Release();
58 
59  /**
60  * @brief findDarkFrame Search for a dark frame that matches the passed paramters.
61  * @param targetChip Camera chip pointer to lookup for relevant information (binning, ROI..etc).
62  * @param duration Duration is second to match it against the database.
63  * @param darkData If a frame is found, load it from disk and store it in a shared FITSData pointer.
64  * @return True if a suitable frame was found the loaded successfully, false otherwise.
65  */
66  bool findDarkFrame(ISD::CameraChip *targetChip, double duration, QSharedPointer<FITSData> &darkData);
67 
68  /**
69  * @brief findDefectMap Search for a defect map that matches the passed paramters.
70  * @param targetChip Camera chip pointer to lookup for relevant information (binning, ROI..etc).
71  * @param duration Duration is second to match it against the database.
72  * @param defectMap If a frame is found, load it from disk and store it in a shared DefectMap pointer.
73  * @return True if a suitable frame was found the loaded successfully, false otherwise.
74  */
75  bool findDefectMap(ISD::CameraChip *targetChip, double duration, QSharedPointer<DefectMap> &defectMap);
76 
77  void refreshFromDB();
78  bool setCamera(ISD::Camera *device);
79  void removeDevice(const QSharedPointer<ISD::GenericDevice> &device);
80  void checkCamera();
81  //void reset();
82  void setCaptureModule(Capture *instance);
83 
84  void start();
85  void setCameraPresets(const QJsonObject &settings);
86  QJsonObject getCameraPresets();
87  void setDefectPixels(const QJsonObject &payload);
88  QJsonArray getViewMasters();
89  void getloadDarkViewMasterFITS(int index);
90 
91  /**
92  * @brief getDefectSettings Return Defect Map settings
93  * @return JSON Object of defect map settings
94  */
96 
97  void setDefectMapEnabled(bool enabled);
98 
99  // Settings
100  QVariantMap getAllSettings() const;
101  void setAllSettings(const QVariantMap &settings);
102 
103  QString opticalTrain() const
104  {
105  return opticalTrainCombo->currentText();
106  }
107  void setOpticalTrain(const QString &value)
108  {
109  opticalTrainCombo->setCurrentText(value);
110  }
111 
112  /**
113  * @brief stop Abort all dark job captures.
114  */
115  void stop();
116  protected:
117  virtual void closeEvent(QCloseEvent *ev) override;
118 
119  signals:
120  void newLog(const QString &message);
121  void newImage(const QSharedPointer<FITSData> &data);
122  void newFrame(const QSharedPointer<FITSView> &view);
123  // Settings
124  void settingsUpdated(const QVariantMap &settings);
125  void trainChanged();
126 
127  public slots:
128  void processNewImage(SequenceJob *job, const QSharedPointer<FITSData> &data);
129  void updateProperty(INDI::Property prop);
130  void loadIndexInView(int row);
131  void clearRow(int row = -1);
132 
133 
134  private slots:
135  void clearAll();
136  void clearExpired();
137  void openDarksFolder();
138  void saveDefectMap();
139  void setCompleted();
140 
141 
142  private:
143  explicit DarkLibrary(QWidget *parent);
144  ~DarkLibrary() override;
145 
146  static DarkLibrary *_DarkLibrary;
147 
148  ////////////////////////////////////////////////////////////////////////////////////////////////
149  /// Dark Frames Functions
150  ////////////////////////////////////////////////////////////////////////////////////////////////
151  /**
152  * @brief countDarkTotalTime Given current settings, count how many minutes
153  * are required to complete all the darks.
154  */
155  void countDarkTotalTime();
156 
157  /**
158  * @brief generateDarkJobs Check the user frame parameters in the Darks tab and generate the corresponding
159  * capture jobs. Populate capture module with the dark jobs.
160  */
161  void generateDarkJobs();
162 
163  /**
164  * @brief execute Start executing the dark jobs in capture module.
165  */
166  void execute();
167 
168  /**
169  * @brief generateMasterFrameHelper Calls templated generateMasterFrame with the correct data type.
170  * @param data Passed dark frame data to generateMasterFrame
171  * @param metadata passed metadata to generateMasterFrame
172  */
173  void generateMasterFrame(const QSharedPointer<FITSData> &data, const QJsonObject &metadata);
174 
175  /**
176  * @brief generateMasterFrame After data aggregation is done, the selected stacking algorithm is applied and the master dark
177  * frame is saved to disk and user database along with the metadata.
178  * @param data last used data. This is not used for reading, but to simply apply the algorithm to the FITSData buffer
179  * and then save it to disk.
180  * @param metadata information on frame to help in the stacking process.
181  */
182  template <typename T> void generateMasterFrameInternal(const QSharedPointer<FITSData> &data, const QJsonObject &metadata);
183 
184  /**
185  * @brief aggregateHelper Calls tempelated aggregate function with the appropiate data type.
186  * @param data Dark frame data to pass on to aggregate function.
187  */
188  void aggregate(const QSharedPointer<FITSData> &data);
189 
190  /**
191  * @brief aggregate Aggregate the data as per the selected algorithm. Each time a new dark frame is received, this function
192  * adds the frame data to the dark buffer.
193  * @param data Dark frame data.
194  */
195  template <typename T> void aggregateInternal(const QSharedPointer<FITSData> &data);
196 
197  /**
198  * @brief cacheDarkFrameFromFile Load dark frame from disk and saves it in the local dark frames cache
199  * @param filename path of dark frame to load
200  * @return True if file is successfully loaded, false otherwise.
201  */
202  bool cacheDarkFrameFromFile(const QString &filename);
203 
204 
205  ////////////////////////////////////////////////////////////////////////////////////////////////
206  /// Misc Functions
207  ////////////////////////////////////////////////////////////////////////////////////////////////
208  void initView();
209  void setCaptureState(CaptureState state);
210  void reloadDarksFromDatabase();
211  void loadCurrentMasterDefectMap();
212  void clearBuffers();
213 
214  ////////////////////////////////////////////////////////////////////////////////////////////////
215  /// Camera Functions
216  ////////////////////////////////////////////////////////////////////////////////////////////////
217  double getGain();
218 
219  ////////////////////////////////////////////////////////////////////////////////////////////////
220  /// Optical Train
221  ////////////////////////////////////////////////////////////////////////////////////////////////
222  void setupOpticalTrainManager();
223  void refreshOpticalTrain();
224 
225  ////////////////////////////////////////////////////////////////////////////////////////////////
226  /// Defect Map Functions
227  ////////////////////////////////////////////////////////////////////////////////////////////////
228  void refreshDefectMastersList(const QString &camera);
229  void loadCurrentMasterDark(const QString &camera, int masterIndex = -1);
230  void populateMasterMetedata();
231  /**
232  * @brief cacheDefectMapFromFile Load defect map from disk and saves it in the local defect maps cache
233  * @param key dark file name that is used as the key in the defect map cache
234  * @param filename path of dark frame to load
235  * @return True if file is successfully loaded, false otherwise.
236  */
237  bool cacheDefectMapFromFile(const QString &key, const QString &filename);
238 
239  ////////////////////////////////////////////////////////////////////
240  /// Settings
241  ////////////////////////////////////////////////////////////////////
242 
243  /**
244  * @brief Connect GUI elements to sync settings once updated.
245  */
246  void connectSettings();
247  /**
248  * @brief Stop updating settings when GUI elements are updated.
249  */
250  void disconnectSettings();
251  /**
252  * @brief loadSettings Load setting from Options and set them accordingly.
253  */
254  void loadGlobalSettings();
255 
256  /**
257  * @brief syncSettings When checkboxes, comboboxes, or spin boxes are updated, save their values in the
258  * global and per-train settings.
259  */
260  void syncSettings();
261 
262  /**
263  * @brief syncControl Sync setting to widget. The value depends on the widget type.
264  * @param settings Map of all settings
265  * @param key name of widget to sync
266  * @param widget pointer of widget to set
267  * @return True if sync successful, false otherwise
268  */
269  bool syncControl(const QVariantMap &settings, const QString &key, QWidget * widget);
270 
271  ////////////////////////////////////////////////////////////////////////////////////////////////
272  /// Member Variables
273  ////////////////////////////////////////////////////////////////////////////////////////////////
274 
275  QList<QVariantMap> m_DarkFramesDatabaseList;
276  QMap<QString, QSharedPointer<FITSData>> m_CachedDarkFrames;
277  QMap<QString, QSharedPointer<DefectMap>> m_CachedDefectMaps;
278 
279  ISD::Camera *m_Camera {nullptr};
280  ISD::CameraChip *m_TargetChip {nullptr};
281  bool m_UseGuideHead {false};
282  double GainSpinSpecialValue { INVALID_VALUE };
283 
284  Capture *m_CaptureModule {nullptr};
285  QSqlTableModel *darkFramesModel = nullptr;
286  QSortFilterProxyModel *sortFilter = nullptr;
287 
288  std::vector<uint32_t> m_DarkMasterBuffer;
289  uint32_t m_DarkImagesCounter {0};
290  bool m_RememberFITSViewer {true};
291  bool m_RememberSummaryView {true};
292  bool m_JobsGenerated {false};
293  QJsonObject m_PresetSettings, m_FileSettings;
294  QString m_DefectMapFilename, m_MasterDarkFrameFilename;
295  QSharedPointer<DarkView> m_DarkView;
296  QPointer<QStatusBar> m_StatusBar;
297  QPointer<QLabel> m_StatusLabel, m_FileLabel;
298  QSharedPointer<DefectMap> m_CurrentDefectMap;
299  QSharedPointer<FITSData> m_CurrentDarkFrame;
300  QFutureWatcher<bool> m_DarkFrameFutureWatcher;
301 
302  // Settings
303  QVariantMap m_Settings;
304  QVariantMap m_GlobalSettings;
305 
306  // Do not add to cache if system memory falls below 250MB.
307  static constexpr uint16_t CACHE_MEMORY_LIMIT {250};
308 };
309 }
Q_OBJECTQ_OBJECT
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:69
void stop()
stop Abort all dark job captures.
Sequence Job is a container for the details required to capture a series of images.
Definition: sequencejob.h:18
CaptureState
Capture states.
Definition: ekos.h:91
QJsonObject getDefectSettings()
getDefectSettings Return Defect Map settings
Captures single or sequence of images from a CCD. The capture class support capturing single or multi...
Definition: capture.h:98
bool findDarkFrame(ISD::CameraChip *targetChip, double duration, QSharedPointer< FITSData > &darkData)
findDarkFrame Search for a dark frame that matches the passed paramters.
Handles acquisition & loading of dark frames and defect map for cameras. If a suitable dark frame exi...
Definition: darklibrary.h:51
QObject * parent() const const
QString message
bool findDefectMap(ISD::CameraChip *targetChip, double duration, QSharedPointer< DefectMap > &defectMap)
findDefectMap Search for a defect map that matches the passed paramters.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Sep 27 2023 04:02:08 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.