Kstars

darklibrary.h
1/*
2 SPDX-FileCopyrightText: 2021 Jasem Mutlaq <mutlaqja@ikarustech.com>
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
19class QSqlTableModel;
21class FITSHistogramView;
22
23namespace Ekos
24{
25
26class Capture;
27class 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 */
51class DarkLibrary : public QDialog, public Ui::DarkLibrary
52{
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 * @brief settleSettings Run this function after timeout from debounce timer to update database
273 * and emit settingsChanged signal. This is required so we don't overload output.
274 */
275 void settleSettings();
276
277 ////////////////////////////////////////////////////////////////////////////////////////////////
278 /// Member Variables
279 ////////////////////////////////////////////////////////////////////////////////////////////////
280
281 QList<QVariantMap> m_DarkFramesDatabaseList;
282 QMap<QString, QSharedPointer<FITSData>> m_CachedDarkFrames;
283 QMap<QString, QSharedPointer<DefectMap>> m_CachedDefectMaps;
284
285 ISD::Camera *m_Camera {nullptr};
286 ISD::CameraChip *m_TargetChip {nullptr};
287 bool m_UseGuideHead {false};
288 double GainSpinSpecialValue { INVALID_VALUE };
289
290 Capture *m_CaptureModule {nullptr};
291 QSqlTableModel *darkFramesModel = nullptr;
292 QSortFilterProxyModel *sortFilter = nullptr;
293
294 std::vector<uint32_t> m_DarkMasterBuffer;
295 uint32_t m_DarkImagesCounter {0};
296 bool m_RememberFITSViewer {true};
297 bool m_RememberSummaryView {true};
298 bool m_JobsGenerated {false};
299 QString m_DefectMapFilename, m_MasterDarkFrameFilename;
300 QSharedPointer<DarkView> m_DarkView;
301 QPointer<QStatusBar> m_StatusBar;
302 QPointer<QLabel> m_StatusLabel, m_FileLabel;
303 QSharedPointer<DefectMap> m_CurrentDefectMap;
304 QSharedPointer<FITSData> m_CurrentDarkFrame;
305 QFutureWatcher<bool> m_DarkFrameFutureWatcher;
306
307 // Settings
308 QVariantMap m_Settings;
309 QVariantMap m_GlobalSettings;
310 QVariantMap m_CaptureModuleSettings;
311
312 QTimer m_DebounceTimer;
313
314 // Do not add to cache if system memory falls below 250MB.
315 static constexpr uint16_t CACHE_MEMORY_LIMIT {250};
316};
317}
Captures single or sequence of images from a CCD.
Definition capture.h:92
Handles acquisition & loading of dark frames and defect map for cameras.
Definition darklibrary.h:52
QJsonObject getDefectSettings()
getDefectSettings Return Defect Map settings
bool findDefectMap(ISD::CameraChip *targetChip, double duration, QSharedPointer< DefectMap > &defectMap)
findDefectMap Search for a defect map that matches the passed paramters.
bool findDarkFrame(ISD::CameraChip *targetChip, double duration, QSharedPointer< FITSData > &darkData)
findDarkFrame Search for a dark frame that matches the passed paramters.
void stop()
stop Abort all dark job captures.
CameraChip class controls a particular chip in camera.
Camera class controls an INDI Camera device.
Definition indicamera.h:44
Sequence Job is a container for the details required to capture a series of images.
Ekos is an advanced Astrophotography tool for Linux.
Definition align.cpp:79
CaptureState
Capture states.
Definition ekos.h:92
Q_OBJECTQ_OBJECT
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:48:25 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.