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

KDE's Doxygen guidelines are available online.