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

KDE's Doxygen guidelines are available online.