Kstars

fitsdata.h
1 /*
2  SPDX-FileCopyrightText: 2004 Jasem Mutlaq <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 
6  Some code fragments were adapted from Peter Kirchgessner's FITS plugin
7  SPDX-FileCopyrightText: Peter Kirchgessner <http://members.aol.com/pkirchg>
8 */
9 
10 #pragma once
11 
12 #include "config-kstars.h"
13 
14 // From StellarSolver
15 #ifdef HAVE_STELLARSOLVER
16 #include <structuredefinitions.h>
17 #else
18 #include "structuredefinitions.h"
19 #endif
20 
21 #include "kstarsdatetime.h"
22 #include "bayer.h"
23 #include "skybackground.h"
24 #include "fitscommon.h"
25 #include "fitsstardetector.h"
26 
27 #ifdef WIN32
28 // This header must be included before fitsio.h to avoid compiler errors with Visual Studio
29 #include <windows.h>
30 #endif
31 
32 #include <fitsio.h>
33 
34 #include <QFuture>
35 #include <QObject>
36 #include <QRect>
37 #include <QVariant>
38 #include <QTemporaryFile>
39 
40 #ifndef KSTARS_LITE
41 #include <kxmlguiwindow.h>
42 #ifdef HAVE_WCSLIB
43 #include <wcs.h>
44 #endif
45 #endif
46 
47 #include "fitsskyobject.h"
48 
49 class QProgressDialog;
50 
51 class SkyPoint;
52 class FITSHistogramData;
53 class Edge;
54 
55 class FITSData : public QObject
56 {
57  Q_OBJECT
58 
59  // Name of FITS file
60  Q_PROPERTY(QString filename READ filename)
61  // Size of file in bytes
62  Q_PROPERTY(qint64 size READ size)
63  // Width in pixels
64  Q_PROPERTY(quint16 width READ width)
65  // Height in pixels
66  Q_PROPERTY(quint16 height READ height)
67  // FITS MODE --> Normal, Focus, Guide..etc
68  Q_PROPERTY(FITSMode mode MEMBER m_Mode)
69  // 1 channel (grayscale) or 3 channels (RGB)
70  Q_PROPERTY(quint8 channels READ channels)
71  // Bits per pixel
72  Q_PROPERTY(quint8 bpp READ bpp)
73  // Does FITS have WSC header?
74  Q_PROPERTY(bool hasWCS READ hasWCS)
75  // Does FITS have bayer data?
76  Q_PROPERTY(bool hasDebayer READ hasDebayer)
77 
78  public:
79  explicit FITSData(FITSMode fitsMode = FITS_NORMAL);
80  explicit FITSData(const QSharedPointer<FITSData> &other);
81  ~FITSData() override;
82 
83  /** Object to hold FITS Header records */
84  struct Record
85  {
86  Record() = default;
87  Record(QString k, QString v, QString c) : key(k), value(v), comment(c) {}
88  QString key; /** FITS Header Key */
89  QVariant value; /** FITS Header Value */
90  QString comment; /** FITS Header Comment, if any */
91  };
92 
93  typedef enum
94  {
95  Idle,
96  Busy,
97  Success,
98  Failure
99  } WCSState;
100 
101  ////////////////////////////////////////////////////////////////////////////////////////
102  ////////////////////////////////////////////////////////////////////////////////////////
103  /// Read and Write file/buffer Functions.
104  ////////////////////////////////////////////////////////////////////////////////////////
105  ////////////////////////////////////////////////////////////////////////////////////////
106  /**
107  * @brief loadFITS Loading FITS file asynchronously.
108  * @param inFilename Path to FITS file (or compressed fits.gz)
109  * @return A QFuture that can be watched until the async operation is complete.
110  */
111  QFuture<bool> loadFromFile(const QString &inFilename);
112 
113  /**
114  * @brief loadFITSFromMemory Loading FITS from memory buffer.
115  * @param buffer The memory buffer containing the fits data.
116  * @param extension file extension (e.g. "jpg", "fits", "cr2"...etc)
117  * @param inFilename Set filename metadata, does not load from file.
118  * @return bool indicating success or failure.
119  */
120  bool loadFromBuffer(const QByteArray &buffer, const QString &extension, const QString &inFilename = QString());
121 
122  /**
123  * @brief parseSolution Parse the WCS solution information from the header into the given struct.
124  * @param solution Solution structure to fill out.
125  * @return True if parsing successful, false otherwise.
126  */
127  bool parseSolution(FITSImage::Solution &solution) const;
128 
129  /* Save FITS or JPG/PNG*/
130  bool saveImage(const QString &newFilename);
131 
132  // Access functions
133  void clearImageBuffers();
134  void setImageBuffer(uint8_t *buffer);
135  uint8_t const *getImageBuffer() const;
136  uint8_t *getWritableImageBuffer();
137 
138  ////////////////////////////////////////////////////////////////////////////////////////
139  ////////////////////////////////////////////////////////////////////////////////////////
140  /// Statistics Functions.
141  ////////////////////////////////////////////////////////////////////////////////////////
142  ////////////////////////////////////////////////////////////////////////////////////////
143  // Calculate stats
144  void calculateStats(bool refresh = false, bool roi = false);
145  void saveStatistics(FITSImage::Statistic &other);
146  void restoreStatistics(FITSImage::Statistic &other);
147  FITSImage::Statistic const &getStatistics() const
148  {
149  return m_Statistics;
150  }
151 
152  uint16_t width(bool roi = false) const
153  {
154  return roi ? m_ROIStatistics.width : m_Statistics.width;
155  }
156  uint16_t height(bool roi = false) const
157  {
158  return roi ? m_ROIStatistics.height : m_Statistics.height;
159  }
160  int64_t size(bool roi = false) const
161  {
162  return roi ? m_ROIStatistics.size : m_Statistics.size;
163  }
164  int channels() const
165  {
166  return m_Statistics.channels;
167  }
168  uint32_t samplesPerChannel(bool roi = false) const
169  {
170  return roi ? m_ROIStatistics.samples_per_channel : m_Statistics.samples_per_channel;
171  }
172  uint32_t dataType() const
173  {
174  return m_Statistics.dataType;
175  }
176  double getMin(uint8_t channel = 0, bool roi = false) const
177  {
178  return roi ? m_ROIStatistics.min[channel] : m_Statistics.min[channel];
179  }
180  double getMax(uint8_t channel = 0, bool roi = false) const
181  {
182  return roi ? m_ROIStatistics.max[channel] : m_Statistics.max[channel];
183 
184  }
185  void setMinMax(double newMin, double newMax, uint8_t channel = 0);
186  void getMinMax(double *min, double *max, uint8_t channel = 0) const
187  {
188  *min = m_Statistics.min[channel];
189  *max = m_Statistics.max[channel];
190  }
191  void setStdDev(double value, uint8_t channel = 0)
192  {
193  m_Statistics.stddev[channel] = value;
194  }
195  double getStdDev(uint8_t channel = 0, bool roi = false ) const
196  {
197  return roi ? m_ROIStatistics.stddev[channel] : m_Statistics.stddev[channel];
198  }
199  double getAverageStdDev(bool roi = false) const;
200  void setMean(double value, uint8_t channel = 0)
201  {
202  m_Statistics.mean[channel] = value;
203  }
204  double getMean(uint8_t channel = 0, bool roi = false) const
205  {
206  return roi ? m_ROIStatistics.mean[channel] : m_Statistics.mean[channel];
207  }
208  // for single channel, just return the mean for channel zero
209  // for color, return the average
210  double getAverageMean(bool roi = false) const;
211  void setMedian(double val, uint8_t channel = 0)
212  {
213  m_Statistics.median[channel] = val;
214  }
215  // for single channel, just return the median for channel zero
216  // for color, return the average
217  double getAverageMedian(bool roi = false) const;
218  double getMedian(uint8_t channel = 0, bool roi = false) const
219  {
220  return roi ? m_ROIStatistics.median[channel] : m_Statistics.median[channel];
221  }
222 
223  int getBytesPerPixel() const
224  {
225  return m_Statistics.bytesPerPixel;
226  }
227  void setSNR(double val)
228  {
229  m_Statistics.SNR = val;
230  }
231  double getSNR() const
232  {
233  return m_Statistics.SNR;
234  }
235  uint32_t bpp() const
236  {
237  switch(m_Statistics.dataType)
238  {
239  case TBYTE:
240  return 8;
241  case TSHORT:
242  case TUSHORT:
243  return 16;
244  case TLONG:
245  case TULONG:
246  case TFLOAT:
247  return 32;
248  case TLONGLONG:
249  case TDOUBLE:
250  return 64;
251  default:
252  return 8;
253  }
254  }
255  double getADU() const;
256 
257  ////////////////////////////////////////////////////////////////////////////////////////
258  ////////////////////////////////////////////////////////////////////////////////////////
259  /// FITS Header Functions.
260  ////////////////////////////////////////////////////////////////////////////////////////
261  ////////////////////////////////////////////////////////////////////////////////////////
262  // FITS Record
263  bool getRecordValue(const QString &key, QVariant &value) const;
264  const QList<Record> &getRecords() const
265  {
266  return m_HeaderRecords;
267  }
268 
269  ////////////////////////////////////////////////////////////////////////////////////////
270  ////////////////////////////////////////////////////////////////////////////////////////
271  /// Star Search & HFR Functions.
272  ////////////////////////////////////////////////////////////////////////////////////////
273  ////////////////////////////////////////////////////////////////////////////////////////
274  // Star Detection - Native KStars implementation
275  void setStarAlgorithm(StarAlgorithm algorithm)
276  {
277  starAlgorithm = algorithm;
278  }
279  int getDetectedStars() const
280  {
281  return starCenters.count();
282  }
283  bool areStarsSearched() const
284  {
285  return starsSearched;
286  }
287  void appendStar(Edge *newCenter)
288  {
289  starCenters.append(newCenter);
290  }
291  const QList<Edge *> &getStarCenters() const
292  {
293  return starCenters;
294  }
295  QList<Edge *> getStarCentersInSubFrame(QRect subFrame) const;
296 
297  void setStarCenters(const QList<Edge*> &centers)
298  {
299  qDeleteAll(starCenters);
300  starCenters = centers;
301  }
302  QFuture<bool> findStars(StarAlgorithm algorithm = ALGORITHM_CENTROID, const QRect &trackingBox = QRect());
303 
304  void setSkyBackground(const SkyBackground &bg)
305  {
306  m_SkyBackground = bg;
307  }
308  const SkyBackground &getSkyBackground() const
309  {
310  return m_SkyBackground;
311  }
312  const QVariantMap &getSourceExtractorSettings() const
313  {
314  return m_SourceExtractorSettings;
315  }
316  void setSourceExtractorSettings(const QVariantMap &settings)
317  {
318  m_SourceExtractorSettings = settings;
319  }
320  // Use SEP (Sextractor Library) to find stars
321  template <typename T>
322  void getFloatBuffer(float *buffer, int x, int y, int w, int h) const;
323  //int findSEPStars(QList<Edge*> &, const int8_t &boundary = int8_t()) const;
324 
325  // Apply ring filter to searched stars
326  int filterStars(const float innerRadius, const float outerRadius);
327 
328  // Half Flux Radius
329  const Edge &getSelectedHFRStar() const
330  {
331  return m_SelectedHFRStar;
332  }
333 
334  // Calculates the median star eccentricity.
335  double getEccentricity();
336 
337  double getHFR(HFRType type = HFR_AVERAGE);
338  double getHFR(int x, int y);
339 
340  ////////////////////////////////////////////////////////////////////////////////////////
341  ////////////////////////////////////////////////////////////////////////////////////////
342  /// Date & Time (WCS) Functions.
343  ////////////////////////////////////////////////////////////////////////////////////////
344  ////////////////////////////////////////////////////////////////////////////////////////
345 
346  const KStarsDateTime &getDateTime() const
347  {
348  return m_DateTime;
349  }
350 
351  // Set the time, for testing (doesn't set header field)
352  void setDateTime(const KStarsDateTime &t)
353  {
354  m_DateTime = t;
355  }
356 
357  const QPoint getRoiCenter() const
358  {
359  return roiCenter;
360  }
361 
362  void setRoiCenter(QPoint c)
363  {
364  roiCenter = c;
365  }
366 
367  ////////////////////////////////////////////////////////////////////////////////////////
368  ////////////////////////////////////////////////////////////////////////////////////////
369  /// World Coordinate System (WCS) Functions.
370  ////////////////////////////////////////////////////////////////////////////////////////
371  ////////////////////////////////////////////////////////////////////////////////////////
372  // Check if a particular point exists within the image
373  bool contains(const QPointF &point) const;
374  // Check if image has valid WCS header information and set HasWCS accordingly. Call in loadFITS()
375  bool checkForWCS();
376  // Does image have valid WCS?
377  bool hasWCS()
378  {
379  return HasWCS;
380  }
381  // The WCS can be loaded without pre-computing each pixel's position. This can make certain
382  // operations slow. FullWCS() is true if the pixel positions are pre-calculated.
383  bool fullWCS()
384  {
385  return FullWCS;
386  }
387  // Load WCS data
388  bool loadWCS(bool extras = true);
389  // Get WCS State
390  WCSState getWCSState() const
391  {
392  return m_WCSState;
393  }
394 
395  /**
396  * @brief wcsToPixel Given J2000 (RA0,DE0) coordinates. Find in the image the corresponding pixel coordinates.
397  * @param wcsCoord Coordinates of target
398  * @param wcsPixelPoint Return XY FITS coordinates
399  * @param wcsImagePoint Return XY Image coordinates
400  * @return True if conversion is successful, false otherwise.
401  */
402  bool wcsToPixel(const SkyPoint &wcsCoord, QPointF &wcsPixelPoint, QPointF &wcsImagePoint);
403 
404  /**
405  * @brief pixelToWCS Convert Pixel coordinates to J2000 world coordinates
406  * @param wcsPixelPoint Pixel coordinates in XY Image space.
407  * @param wcsCoord Store back WCS world coordinate in wcsCoord
408  * @return True if successful, false otherwise.
409  */
410  bool pixelToWCS(const QPointF &wcsPixelPoint, SkyPoint &wcsCoord);
411 
412  /**
413  * @brief injectWCS Add WCS keywords
414  * @param orientation Solver orientation, degrees E of N.
415  * @param ra J2000 Right Ascension
416  * @param dec J2000 Declination
417  * @param pixscale Pixel scale in arcsecs per pixel
418  * @param eastToTheRight if true, then when the image is rotated so that north is up, then east would be to the right on the image.
419  */
420  void injectWCS(double orientation, double ra, double dec, double pixscale, bool eastToTheRight);
421 
422  ////////////////////////////////////////////////////////////////////////////////////////
423  ////////////////////////////////////////////////////////////////////////////////////////
424  /// Debayering Functions
425  ////////////////////////////////////////////////////////////////////////////////////////
426  ////////////////////////////////////////////////////////////////////////////////////////
427 
428  // Debayer
429  bool hasDebayer()
430  {
431  return HasDebayer;
432  }
433 
434  /**
435  * @brief debayer the 1-channel data to 3-channel RGB using the default debayer pattern detected in the FITS header.
436  * @param reload If true, it will read the image again from disk before performing debayering. This is necessary to attempt
437  * subsequent debayering processes on an already debayered image.
438  */
439  bool debayer(bool reload = false);
440  bool debayer_8bit();
441  bool debayer_16bit();
442  void getBayerParams(BayerParams *param);
443  void setBayerParams(BayerParams *param);
444 
445  ////////////////////////////////////////////////////////////////////////////////////////
446  ////////////////////////////////////////////////////////////////////////////////////////
447  /// Public Histogram Functions
448  ////////////////////////////////////////////////////////////////////////////////////////
449  ////////////////////////////////////////////////////////////////////////////////////////
450 
451  void resetHistogram()
452  {
453  m_HistogramConstructed = false;
454  }
455  double getHistogramBinWidth(int channel = 0)
456  {
457  return m_HistogramBinWidth[channel];
458  }
459 
460  const QVector<uint32_t> &getCumulativeFrequency(uint8_t channel = 0) const
461  {
462  return m_CumulativeFrequency[channel];
463  }
464  const QVector<double> &getHistogramIntensity(uint8_t channel = 0) const
465  {
466  return m_HistogramIntensity[channel];
467  }
468  const QVector<double> &getHistogramFrequency(uint8_t channel = 0) const
469  {
470  return m_HistogramFrequency[channel];
471  }
472 
473  /**
474  * @brief getJMIndex Overall contrast of the image used in find centeroid algorithm. i.e. is the image diffuse?
475  * @return Value of JMIndex
476  */
477  double getJMIndex() const
478  {
479  return m_JMIndex;
480  }
481 
482  bool isHistogramConstructed()
483  {
484  return m_HistogramConstructed;
485  }
486  void constructHistogram();
487 
488  ////////////////////////////////////////////////////////////////////////////////////////
489  ////////////////////////////////////////////////////////////////////////////////////////
490  /// Filters and Rotations Functions.
491  ////////////////////////////////////////////////////////////////////////////////////////
492  ////////////////////////////////////////////////////////////////////////////////////////
493  // Filter
494  void applyFilter(FITSScale type, uint8_t *image = nullptr, QVector<double> *targetMin = nullptr,
495  QVector<double> *targetMax = nullptr);
496 
497  // Rotation counter. We keep count to rotate WCS keywords on save
498  int getRotCounter() const;
499  void setRotCounter(int value);
500 
501  // Filename
502  const QString &filename() const
503  {
504  return m_Filename;
505  }
506  const QString &compressedFilename() const
507  {
508  return m_compressedFilename;
509  }
510  bool isCompressed() const
511  {
512  return m_isCompressed;
513  }
514 
515  // Horizontal flip counter. We keep count to rotate WCS keywords on save
516  int getFlipHCounter() const;
517  void setFlipHCounter(int value);
518 
519  // Horizontal flip counter. We keep count to rotate WCS keywords on save
520  int getFlipVCounter() const;
521  void setFlipVCounter(int value);
522 
523  ////////////////////////////////////////////////////////////////////////////////////////
524  ////////////////////////////////////////////////////////////////////////////////////////
525  /// Object Search Functions.
526  ////////////////////////////////////////////////////////////////////////////////////////
527  ////////////////////////////////////////////////////////////////////////////////////////
528 #ifndef KSTARS_LITE
529 #ifdef HAVE_WCSLIB
530  bool searchObjects();
531  bool findObjectsInImage(SkyPoint startPoint, SkyPoint endPoint);
532  bool findWCSBounds(double &minRA, double &maxRA, double &minDec, double &maxDec);
533 #endif
534 #endif
535  const QList<FITSSkyObject *> &getSkyObjects() const
536  {
537  return m_SkyObjects;
538  }
539 
540  ////////////////////////////////////////////////////////////////////////////////////////
541  ////////////////////////////////////////////////////////////////////////////////////////
542  /// Image Conversion Functions.
543  ////////////////////////////////////////////////////////////////////////////////////////
544  ////////////////////////////////////////////////////////////////////////////////////////
545  // Create autostretch image from FITS File
546  static QImage FITSToImage(const QString &filename);
547 
548  /**
549  * @brief ImageToFITS Convert an image file with supported format to a FITS file.
550  * @param filename full path to filename without extension
551  * @param format file extension. Supported formats are whatever supported by Qt (e.g. PNG, JPG,..etc)
552  * @param output Output temporary file path. The created file is generated by the function and store in output.
553  * @return True if conversion is successful, false otherwise.
554  */
555  static bool ImageToFITS(const QString &filename, const QString &format, QString &output);
556 
557  QString getLastError() const;
558 
559  signals:
560  void converted(QImage);
561 
562  /**
563  * @brief histogramReady Sends signal when histogram construction is complete.
564  */
565  void histogramReady();
566 
567  /**
568  * @brief dataChanged Send signal when undelying raw data buffer data changed.
569  */
570  void dataChanged();
571  public slots:
572  void makeRoiBuffer(QRect roi);
573 
574  private:
575  void loadCommon(const QString &inFilename);
576  /**
577  * @brief privateLoad Load an image (FITS, RAW, or images supported by Qt like jpeg, png).
578  * @param Buffer pointer to image data. If buffer is emtpy, read from disk (m_Filename).
579  * @return true if successfully loaded, false otherwise.
580  */
581  bool privateLoad(const QByteArray &buffer, const QString &extension);
582 
583  // Load Qt-supported images.
584  bool loadCanonicalImage(const QByteArray &buffer, const QString &extension);
585  // Load FITS images.
586  bool loadFITSImage(const QByteArray &buffer, const QString &extension, const bool isCompressed = false);
587  // Load XISF images.
588  bool loadXISFImage(const QByteArray &buffer);
589  // Save XISF images.
590  bool saveXISFImage(const QString &newFilename);
591  // Load RAW images.
592  bool loadRAWImage(const QByteArray &buffer, const QString &extension);
593 
594  void rotWCSFITS(int angle, int mirror);
595  void calculateMinMax(bool refresh = false, bool roi = false);
596  void calculateMedian(bool refresh = false, bool roi = false);
597  bool checkDebayer();
598  void readWCSKeys();
599 
600  // Record last FITS error
601  void recordLastError(int errorCode);
602  void logOOMError(uint32_t requiredMemory = 0);
603 
604  // FITS Record
605  bool parseHeader();
606  //int getFITSRecord(QString &recordList, int &nkeys);
607 
608  // Templated functions
609  template <typename T>
610  bool debayer();
611 
612  template <typename T>
613  bool rotFITS(int rotate, int mirror);
614 
615  // Apply Filter
616  template <typename T>
617  void applyFilter(FITSScale type, uint8_t *targetImage, QVector<double> * min = nullptr, QVector<double> * max = nullptr);
618 
619  template <typename T>
620  void calculateMinMax(bool roi = false);
621  template <typename T>
622  void calculateMedian(bool roi = false);
623 
624  template <typename T>
625  QPair<T, T> getParitionMinMax(uint32_t start, uint32_t stride, bool roi);
626 
627  /* Calculate the Gaussian blur matrix and apply it to the image using the convolution filter */
628  QVector<double> createGaussianKernel(int size, double sigma);
629  template <typename T>
630  void convolutionFilter(const QVector<double> &kernel, int kernelSize);
631  template <typename T>
632  void gaussianBlur(int kernelSize, double sigma);
633 
634  /* Calculate running average & standard deviation using Welford’s method for computing variance */
635  template <typename T>
636  void runningAverageStdDev( bool roi = false );
637  template <typename T>
638  QPair<double, double> getSquaredSumAndMean(uint32_t start, uint32_t stride, bool roi = false);
639 
640  template <typename T>
641  void convertToQImage(double dataMin, double dataMax, double scale, double zero, QImage &image);
642 
643  ////////////////////////////////////////////////////////////////////////////////////////
644  ////////////////////////////////////////////////////////////////////////////////////////
645  /// Private Histogram Functions.
646  ////////////////////////////////////////////////////////////////////////////////////////
647  ////////////////////////////////////////////////////////////////////////////////////////
648  template <typename T> void constructHistogramInternal();
649 
650  /// Pointer to CFITSIO FITS file struct
651  fitsfile *fptr { nullptr };
652  /// Generic data image buffer
653  uint8_t *m_ImageBuffer { nullptr };
654  /// Above buffer size in bytes
655  uint32_t m_ImageBufferSize { 0 };
656  /// Image Buffer if Selection is to be done
657  uint8_t *m_ImageRoiBuffer { nullptr };
658  /// Above buffer size in bytes
659  uint32_t m_ImageRoiBufferSize { 0 };
660  /// Is this a temporary file or one loaded from disk?
661  bool m_isTemporary { false };
662  /// is this file compress (.fits.fz)?
663  bool m_isCompressed { false };
664  /// Did we search for stars yet?
665  bool starsSearched { false };
666  ///Star Selection Algorithm
667  StarAlgorithm starAlgorithm { ALGORITHM_GRADIENT };
668  /// Do we have WCS keywords in this FITS data?
669  bool HasWCS { false }; /// Do we have WCS keywords in this FITS data?
670  /// we can initialize wcs without computing all the image positions.
671  bool FullWCS { false };
672  /// Is the image debayarable?
673  bool HasDebayer { false };
674  /// Buffer to hold fpack uncompressed data
675  uint8_t *m_PackBuffer {nullptr};
676 
677  /// Our very own file name
678  QString m_Filename, m_compressedFilename;
679  /// FITS Mode (Normal, WCS, Guide, Focus..etc)
680  FITSMode m_Mode;
681  // FITS Observed UTC date time
682  KStarsDateTime m_DateTime;
683 
684  /// How many times the image was rotated? Useful for WCS keywords rotation on save.
685  int rotCounter { 0 };
686  /// How many times the image was flipped horizontally?
687  int flipHCounter { 0 };
688  /// How many times the image was flipped vertically?
689  int flipVCounter { 0 };
690 
691  /// WCS Struct
692  struct wcsprm *m_WCSHandle
693  {
694  nullptr
695  };
696  /// Number of coordinate representations found.
697  int m_nwcs {0};
698  WCSState m_WCSState { Idle };
699  /// All the stars we detected, if any.
700  QList<Edge *> starCenters;
701  QList<Edge *> localStarCenters;
702  /// The biggest fattest star in the image.
703  Edge m_SelectedHFRStar;
704 
705  /// Bayer parameters
706  BayerParams debayerParams;
707  QTemporaryFile m_TemporaryDataFile;
708 
709  /// Data type of fits pixel in the image. Used when saving FITS again.
710  /// There is bit depth and also data type. They're not the same.
711  /// 16bit can be either SHORT_IMG or USHORT_IMG, so m_FITSBITPIX specifies which is
712  int m_FITSBITPIX {USHORT_IMG};
713  FITSImage::Statistic m_Statistics;
714  FITSImage::Statistic m_ROIStatistics;
715 
716  // A list of header records
717  QList<Record> m_HeaderRecords;
718 
719  QList<FITSSkyObject *> m_SkyObjects;
720  bool m_ObjectsSearched {false};
721 
722  QString m_LastError;
723 
724  ////////////////////////////////////////////////////////////////////////////////////////
725  ////////////////////////////////////////////////////////////////////////////////////////
726  /// Histogram Variables
727  ////////////////////////////////////////////////////////////////////////////////////////
728  ////////////////////////////////////////////////////////////////////////////////////////
729  QVector<QVector<uint32_t>> m_CumulativeFrequency;
730  QVector<QVector<double>> m_HistogramIntensity;
731  QVector<QVector<double>> m_HistogramFrequency;
732  QVector<double> m_HistogramBinWidth;
733  uint16_t m_HistogramBinCount { 0 };
734  double m_JMIndex { 1 };
735  bool m_HistogramConstructed { false };
736 
737  ////////////////////////////////////////////////////////////////////////////////////////
738  ////////////////////////////////////////////////////////////////////////////////////////
739  /// Star Detector
740  ////////////////////////////////////////////////////////////////////////////////////////
741  ////////////////////////////////////////////////////////////////////////////////////////
742  // Sky Background
743  SkyBackground m_SkyBackground;
744  // Detector Settings
745  QVariantMap m_SourceExtractorSettings;
746  QFuture<bool> m_StarFindFuture;
748 
749  // Cached values for hfr and eccentricity computations
750  double cacheHFR { -1 };
751  HFRType cacheHFRType { HFR_AVERAGE };
752  double cacheEccentricity { -1 };
753  QPoint roiCenter;
754 };
Q_OBJECTQ_OBJECT
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
Q_PROPERTY(...)
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
int count(const T &value) const const
QString comment
FITS Header Value.
Definition: fitsdata.h:90
QVariant value
FITS Header Key.
Definition: fitsdata.h:89
Object to hold FITS Header records.
Definition: fitsdata.h:84
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon May 8 2023 03:57:30 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.