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  /**
78  * @brief cameraHasDefectMaps Check if camera has any defect maps available.
79  * @param name Camera name
80  * @return True if at least one defect maps exists for this camera, false otherwise.
81  */
82  bool cameraHasDefectMaps(const QString &name) const
83  {
84  return m_DefectCameras.contains(name);
85  }
86 
87  void refreshFromDB();
88  void addCamera(ISD::Camera *camera);
89  void removeDevice(ISD::GenericDevice *device);
90  void checkCamera(int ccdNum = -1);
91  //void reset();
92  void setCaptureModule(Capture *instance);
93 
94  void start();
95  void setDarkSettings(const QJsonObject &settings);
96  void setCameraPresets(const QJsonObject &settings);
97  QJsonObject getCameraPresets();
98  QJsonObject getDarkSettings();
99  QJsonObject getDefectSettings();
100  void setDefectPixels(const QJsonObject &payload);
101  QJsonArray getViewMasters();
102  void getloadDarkViewMasterFITS(int index);
103  void setDefectSettings(const QJsonObject row);
104  void setDefectMapEnabled(bool enabled);
105 
106  /**
107  * @brief stop Abort all dark job captures.
108  */
109  void stop();
110  protected:
111  virtual void closeEvent(QCloseEvent *ev) override;
112 
113  signals:
114  void newLog(const QString &message);
115  void newImage(const QSharedPointer<FITSData> &data);
116  void newFrame(const QSharedPointer<FITSView> &view);
117 
118  public slots:
119  void processNewImage(SequenceJob *job, const QSharedPointer<FITSData> &data);
120  void processNewBLOB(IBLOB *bp);
121  void loadIndexInView(int row);
122  void clearRow(int row = -1);
123 
124 
125  private slots:
126  void clearAll();
127  void clearExpired();
128  void openDarksFolder();
129  void saveDefectMap();
130  void setCompleted();
131 
132 
133  private:
134  explicit DarkLibrary(QWidget *parent);
135  ~DarkLibrary() override;
136 
137  static DarkLibrary *_DarkLibrary;
138 
139  ////////////////////////////////////////////////////////////////////////////////////////////////
140  /// Dark Frames Functions
141  ////////////////////////////////////////////////////////////////////////////////////////////////
142  /**
143  * @brief countDarkTotalTime Given current settings, count how many minutes
144  * are required to complete all the darks.
145  */
146  void countDarkTotalTime();
147 
148  /**
149  * @brief generateDarkJobs Check the user frame parameters in the Darks tab and generate the corresponding
150  * capture jobs. Populate capture module with the dark jobs.
151  */
152  void generateDarkJobs();
153 
154  /**
155  * @brief execute Start executing the dark jobs in capture module.
156  */
157  void execute();
158 
159  /**
160  * @brief generateMasterFrameHelper Calls templated generateMasterFrame with the correct data type.
161  * @param data Passed dark frame data to generateMasterFrame
162  * @param metadata passed metadata to generateMasterFrame
163  */
164  void generateMasterFrame(const QSharedPointer<FITSData> &data, const QJsonObject &metadata);
165 
166  /**
167  * @brief generateMasterFrame After data aggregation is done, the selected stacking algorithm is applied and the master dark
168  * frame is saved to disk and user database along with the metadata.
169  * @param data last used data. This is not used for reading, but to simply apply the algorithm to the FITSData buffer
170  * and then save it to disk.
171  * @param metadata information on frame to help in the stacking process.
172  */
173  template <typename T> void generateMasterFrameInternal(const QSharedPointer<FITSData> &data, const QJsonObject &metadata);
174 
175  /**
176  * @brief aggregateHelper Calls tempelated aggregate function with the appropiate data type.
177  * @param data Dark frame data to pass on to aggregate function.
178  */
179  void aggregate(const QSharedPointer<FITSData> &data);
180 
181  /**
182  * @brief aggregate Aggregate the data as per the selected algorithm. Each time a new dark frame is received, this function
183  * adds the frame data to the dark buffer.
184  * @param data Dark frame data.
185  */
186  template <typename T> void aggregateInternal(const QSharedPointer<FITSData> &data);
187 
188  /**
189  * @brief cacheDarkFrameFromFile Load dark frame from disk and saves it in the local dark frames cache
190  * @param filename path of dark frame to load
191  * @return True if file is successfully loaded, false otherwise.
192  */
193  bool cacheDarkFrameFromFile(const QString &filename);
194 
195 
196  ////////////////////////////////////////////////////////////////////////////////////////////////
197  /// Misc Functions
198  ////////////////////////////////////////////////////////////////////////////////////////////////
199  void initView();
200  void setCaptureState(CaptureState state);
201  void reloadDarksFromDatabase();
202  void loadCurrentMasterDefectMap();
203  void clearBuffers();
204 
205  ////////////////////////////////////////////////////////////////////////////////////////////////
206  /// Camera Functions
207  ////////////////////////////////////////////////////////////////////////////////////////////////
208  double getGain();
209 
210  ////////////////////////////////////////////////////////////////////////////////////////////////
211  /// Defect Map Functions
212  ////////////////////////////////////////////////////////////////////////////////////////////////
213  void refreshDefectMastersList(const QString &camera);
214  void loadCurrentMasterDark(const QString &camera, int masterIndex = -1);
215  void populateMasterMetedata();
216  /**
217  * @brief cacheDefectMapFromFile Load defect map from disk and saves it in the local defect maps cache
218  * @param key dark file name that is used as the key in the defect map cache
219  * @param filename path of dark frame to load
220  * @return True if file is successfully loaded, false otherwise.
221  */
222  bool cacheDefectMapFromFile(const QString &key, const QString &filename);
223 
224  ////////////////////////////////////////////////////////////////////////////////////////////////
225  /// Member Variables
226  ////////////////////////////////////////////////////////////////////////////////////////////////
227 
228  QList<QVariantMap> m_DarkFramesDatabaseList;
229  QMap<QString, QSharedPointer<FITSData>> m_CachedDarkFrames;
230  QMap<QString, QSharedPointer<DefectMap>> m_CachedDefectMaps;
231 
232  ISD::Camera *m_CurrentCamera {nullptr};
233  ISD::CameraChip *m_TargetChip {nullptr};
234  QList<ISD::Camera *> m_Cameras;
235  bool m_UseGuideHead {false};
236  double GainSpinSpecialValue { INVALID_VALUE };
237 
238  Capture *m_CaptureModule {nullptr};
239  QSqlTableModel *darkFramesModel = nullptr;
240  QSortFilterProxyModel *sortFilter = nullptr;
241 
242  std::vector<uint32_t> m_DarkMasterBuffer;
243  uint32_t m_DarkImagesCounter {0};
244  bool m_RememberFITSViewer {true};
245  bool m_RememberSummaryView {true};
246  bool m_JobsGenerated {false};
247  QJsonObject m_PresetSettings, m_FileSettings;
248  QString m_DefectMapFilename, m_MasterDarkFrameFilename;
249  QStringList m_DarkCameras, m_DefectCameras;
250  QSharedPointer<DarkView> m_DarkView;
251  QPointer<QStatusBar> m_StatusBar;
252  QPointer<QLabel> m_StatusLabel, m_FileLabel;
253  QSharedPointer<DefectMap> m_CurrentDefectMap;
254  QSharedPointer<FITSData> m_CurrentDarkFrame;
255  QFutureWatcher<bool> m_DarkFrameFutureWatcher;
256 
257  // Do not add to cache if system memory falls below 250MB.
258  static constexpr uint16_t CACHE_MEMORY_LIMIT {250};
259 };
260 }
Q_OBJECTQ_OBJECT
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:70
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
bool cameraHasDefectMaps(const QString &name) const
cameraHasDefectMaps Check if camera has any defect maps available.
Definition: darklibrary.h:82
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
Captures single or sequence of images from a CCD. The capture class support capturing single or multi...
Definition: capture.h:83
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-2022 The KDE developers.
Generated on Sun Aug 14 2022 04:13:55 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.