Warning, file /education/kstars/kstars/ekos/focus/aberrationinspector.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2023 John Evans <john.e.evans.email@googlemail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <Q3DSurface> 0010 #include <QCustom3DLabel> 0011 0012 #include "curvefit.h" 0013 #include "ui_aberrationinspector.h" 0014 #include "aberrationinspectorutils.h" 0015 0016 // The AberrationInspector class manages the Aberration Inspector dialog. 0017 // Settings are managed in a global way, rather than per Optical Train which would be overkill. The approach is the same as Focus 0018 // using loadSettings, connectSettings & syncSettings. 0019 // 0020 // Aberration Inspector uses focus position of different parts of the sensor to examine backfocus and tilt. A single Autofocus run can 0021 // be used as the basis for the analysis. 0022 // 0023 // Note, Aberration Inspector assumes all focus differences between different tiles on the sensor are due to Backfocus and sensor tilt. 0024 // In reality many other aberrations (e.g. collimation, coma, etc.) could contribute to focus differences but are assumed to be negligible. 0025 // If other aberrations are significant then the analysis output of Aberration Inspector is likely to be invalid. 0026 // 0027 // Aberration Inspector can have 2 use cases: 0028 // 1. Analysis mode. Run the inspector and look at the output. 0029 // 2. Use the tool to help with adjustment of Backfocus and / or tilt with a device such as a PhotonCage or Octopi. In this mode, use of the 0030 // tool will be iterative. Run the tool, look at the output, make an adjustment for Backfocus and / or tilt, rerun the tool and compare 0031 // the new output. Make a further adjustment and repeat until happy with the output. For this reason, each time Aberration Inspector is 0032 // run, a new Aberration Inspector Dialog (with incrementing Run number) is launched allowing comparision of results. 0033 // 0034 // To invoke Aberration Inspector: 0035 // 1. Setup focus to give the consistently good focus results. Point to a part of the sky with lots of stars. 0036 // 2. Set the Mosaic Mask on and set it up so that there are sufficient stars in each tile. This is important as each tile 0037 // will be focused solved individually so there needs to be enough stars in each tile. Increase the tile size to get each tile to cover 0038 // more of the sensor and therefore contain more stars; but don't overdo it as the bigger the tile the less accurate the results. 0039 // 3. Run Autofocus manually by pressing the Auto Focus button. Note, Aberration Inspector is not run when Focus is run in a sequence. 0040 // 4. Autofocus will run normally but will collect data for Aberration Inspector for each datapoint. If the Focus run isn't good then 0041 // discard and retry. If basic Autofocus isn't good then Aberration Inspector will not be good. 0042 // 5. When Autofocus completes, the Aberration Inspector dialog is launched. 0043 // 6. To run Aberration Inspector again, simply rerun Autofocus. 0044 // 0045 // The Aberration Inspector dialog has 4 components: 0046 // 1. The v-curves. A curve is drawn for each tile dependent on the user setting of TileSelection. So either 5 or 9 curves are drawn. 0047 // Like Focus, the v-curve shows measure (e.g. HFR) on the y-axis versus focuser position on the x-axis 0048 // 2. A table of results from the v-curves. A row is displayed per tile showing v-curve solution and delta from central tile 0049 // 3. Analysis of results table. Here the deltas between the solve position for the central tile is compared with other tiles and used 0050 // to produce numbers for: 0051 // Backfocus - The idea is that if backfocus is perfect then the average of tile deltas from the centre will be zero. 0052 // Tilt - Differences in tile deltas when backfocus is compensated for, are due to tilt. The analyse works on 2 axes of tilt, 0053 // Left-to-Right and Top-to-Bottom. 0054 // 4. 3D Graphic. This helps to orient the user and explain the results. 2 Surfaces can be displayed: 0055 // Sensor - The sensor is drawn as a 3D plane to scale, with the tilt shown on the z-axis. Top, bottom, left and right are labelled. 0056 // Petzval Surface - This is light surface that comes out of the telescope and hits the sensor. The surface is drawn as a simple, 0057 // circularly symmetrical paraboloid. In reality, the light surface coming out of the field flattener may be much more 0058 // complex. 0059 // With the 3D graphic, it is possible to enter simulation mode, and adjust the Backfocus and tilt and see the effect on the Sensor and 0060 // Petzval surface. 0061 // 0062 0063 using namespace QtDataVisualization; 0064 0065 namespace Ekos 0066 { 0067 0068 class SensorGraphic; 0069 class AberrationInspectorPlot; 0070 0071 class AberrationInspector : public QDialog, public Ui::aberrationInspectorDialog 0072 { 0073 Q_OBJECT 0074 0075 public: 0076 0077 typedef enum { TILES_ALL, TILES_OUTER_CORNERS, TILES_INNER_DIAMOND } TileSelection; 0078 typedef struct 0079 { 0080 int run; 0081 CurveFitting::CurveFit curveFit; 0082 bool useWeights; 0083 CurveFitting::OptimisationDirection optDir; 0084 int sensorWidth; 0085 int sensorHeight; 0086 double pixelSize; 0087 int tileWidth; 0088 double focuserStepMicrons; 0089 QString yAxisLabel; 0090 double starUnits; 0091 double cfzSteps; 0092 bool isPositionBased; 0093 } abInsData; 0094 0095 /** 0096 * @brief create an AberrationInspector with the associated data 0097 * @param data is a structure describing the curve fitting methods 0098 * @param positions datapoints 0099 * @param measures datapoints for each tile 0100 * @param weights datapoints for each tile 0101 */ 0102 AberrationInspector(const abInsData &data, const QVector<int> &positions, const QVector<QVector<double>> &measures, 0103 const QVector<QVector<double>> &weights, const QVector<QVector<int>> &numStars, 0104 const QVector<QPoint> &tileCenterOffset); 0105 ~AberrationInspector(); 0106 0107 private slots: 0108 /** 0109 * @brief mouse moved into table event. Used to show sensor graphic widget 0110 * @param row 0111 * @param column 0112 */ 0113 void newMousePos(int row, int column); 0114 0115 /** 0116 * @brief mouse left the table. Used to hide the sensor graphic widget 0117 */ 0118 void leaveTableEvent(); 0119 0120 /** 0121 * @brief checkbox state changed event 0122 * @param new state 0123 */ 0124 void onStateChanged(int state); 0125 0126 /** 0127 * @brief table cell changed 0128 * @param new state 0129 */ 0130 void onCellChanged(int row, int column); 0131 0132 private: 0133 /** 0134 * @brief setup elements of the GUI 0135 */ 0136 void setupGUI(); 0137 0138 /** 0139 * @brief connect settings in order to persist changes 0140 */ 0141 void connectSettings(); 0142 0143 /** 0144 * @brief load persisted settings 0145 */ 0146 void loadSettings(); 0147 0148 /** 0149 * @brief persist settings 0150 */ 0151 void syncSettings(); 0152 0153 /** 0154 * @brief initialise Aberration Inspector 0155 */ 0156 void initAberrationInspector(); 0157 0158 /** 0159 * @brief fit v-curves for each tile and update other widgets with results 0160 */ 0161 void fitCurves(); 0162 0163 /** 0164 * @brief initialise the 3D graphic 0165 */ 0166 void initGraphic(); 0167 0168 /** 0169 * @brief setTileSelection combobox 0170 * @param tileSelection 0171 */ 0172 void setTileSelection(TileSelection tileSelection); 0173 0174 /** 0175 * @brief setup an array of tiles to use / don't use 0176 * @param tileSelection 0177 */ 0178 void setupTiles(TileSelection tileSelection); 0179 0180 /** 0181 * @brief update table widget as per user selection 0182 */ 0183 void updateTable(); 0184 0185 /** 0186 * @brief analyse and display the results for backfocus and tilt 0187 */ 0188 void analyseResults(); 0189 0190 /** 0191 * @brief 3D graphic sim mode toggled by user 0192 * @param sim mode on / off 0193 */ 0194 void simModeToggled(bool setting); 0195 0196 /** 0197 * @brief update 3D graphic based on user selection 0198 * @param tileSelection 0199 */ 0200 void updateGraphic(TileSelection tileSelection); 0201 0202 /** 0203 * @brief draw Sensor on 3D graphic 0204 * @return success 0205 */ 0206 bool processSensor(); 0207 0208 /** 0209 * @brief draw Sensor Labels on 3D graphic 0210 */ 0211 void processSensorLabels(); 0212 0213 /** 0214 * @brief draw Petzval surface (light cone from flattener) on 3D graphic 0215 * @param tileSelection 0216 * @return success 0217 */ 0218 bool processPetzval(TileSelection tileSelection); 0219 0220 /** 0221 * @brief show / hide v-curve solution labels 0222 * @param show / hide setting 0223 */ 0224 void setShowLabels(bool setting); 0225 0226 /** 0227 * @brief show / hide CFZ 0228 * @param show / hide setting 0229 */ 0230 void setShowCFZ(bool setting); 0231 0232 /** 0233 * @brief Optimise tile centres based on weighted star position 0234 * @param setting 0235 */ 0236 void setOptCentres(bool setting); 0237 0238 /** 0239 * @brief resize table based on contents 0240 */ 0241 void tableResize(); 0242 0243 /** 0244 * @brief calculate backfocus based on user selection 0245 * @param tileSelection 0246 * @param calculated backfocusDelta 0247 * @return success = true 0248 */ 0249 bool calcBackfocusDelta(TileSelection tileSelection, double &backfocusDelta); 0250 0251 /** 0252 * @brief calculate tilt based on user selection 0253 * @return success = true 0254 */ 0255 bool calcTilt(); 0256 0257 /** 0258 * @brief calculates average of 3 tile values 0259 * @param tiles to average 0260 * @param retured tile average 0261 * @return success = true 0262 */ 0263 bool avTiles(int tiles[3], double &average); 0264 0265 /** 0266 * @brief set exclude tiles vector 0267 * @param row 0268 * @param checked 0269 * @param tile selection 0270 */ 0271 void setExcludeTile(int row, bool checked, TileSelection tileSelection); 0272 0273 /** 0274 * @brief get tile from table row 0275 * @param tileSelection 0276 * @param row 0277 * @return tile 0278 */ 0279 int getTileFromRow(TileSelection tileSelection, int row); 0280 0281 /** 0282 * @brief get the X,Y centre of the tile 0283 * @param tile 0284 * @return 2D vector of tile centre 0285 */ 0286 QVector2D getXYTileCentre(tileID tile); 0287 0288 /** 0289 * @brief get the label position for the passed in tile 0290 * @param tile 0291 * @return 3D vector of label position 0292 */ 0293 QVector3D getLabelCentre(tileID tile); 0294 0295 /** 0296 * @brief get the sensor vertex nearest the passed in tile 0297 * @param tile 0298 * @return 3D vector of sensor vertex 0299 */ 0300 QVector3D getSensorVertex(tileID tile); 0301 0302 /** 0303 * @brief get backspace adapted delta the passed in tile 0304 * @param tile 0305 * @return backspace adapted delta 0306 */ 0307 double getBSDelta(tileID tile); 0308 QVector3D rotatePoint(QVector3D point); 0309 0310 /** 0311 * @brief simulation of backfocus changed 0312 * @param value of slider 0313 */ 0314 void simBackfocusChanged(int value); 0315 0316 /** 0317 * @brief simulation of L-R tilt changed 0318 * @param value of slider 0319 */ 0320 void simLRTiltChanged(int value); 0321 0322 /** 0323 * @brief simulation of T-B tilt changed 0324 * @param value of slider 0325 */ 0326 void simTBTiltChanged(int value); 0327 0328 abInsData m_data; 0329 QVector<int> m_positions; 0330 QVector<QVector<double>> m_measures; 0331 QVector<QVector<double>> m_weights; 0332 QVector<QVector<int>> m_numStars; 0333 QVector<QPoint> m_tileOffsets; 0334 0335 // Which tiles to use 0336 bool m_useTile[NUM_TILES] = { false, false, false, false, false, false, false, false, false }; 0337 bool m_excludeTile[NUM_TILES] = { false, false, false, false, false, false, false, false, false }; 0338 0339 // Table 0340 SensorGraphic *sensorGraphic { nullptr }; 0341 int m_HighlightedRow { -1 }; 0342 0343 // Curve fitting 0344 std::unique_ptr<CurveFitting> curveFitting; 0345 QVector<int> m_minimum; 0346 QVector<double> m_minMeasure; 0347 QVector<bool> m_fit; 0348 QVector<double> m_R2; 0349 0350 // Analysis - the folowing members are in microns 0351 double m_backfocus = 0.0; 0352 QVector<double> m_deltas; 0353 double m_LRMicrons = 0.0; 0354 double m_TBMicrons = 0.0; 0355 double m_diagonalMicrons = 0.0; 0356 // Tilts are in % slope 0357 double m_LRTilt = 0.0; 0358 double m_TBTilt = 0.0; 0359 double m_diagonalTilt = 0.0; 0360 bool m_resultsOK = false; 0361 0362 // Graphic simulation variables 0363 bool m_simMode { false }; 0364 double m_simBackfocus { 0 }; 0365 double m_simLRTilt { 0 }; 0366 double m_simTBTilt { 0 }; 0367 float m_maxX { 0.0 }; 0368 float m_maxY { 0.0 }; 0369 float m_minZ { 0.0 }; 0370 float m_maxZ { 0.0 }; 0371 0372 // Plot widget 0373 AberrationInspectorPlot *m_plot; 0374 0375 // Graphic 0376 Q3DSurface *m_graphic = nullptr; 0377 QSurface3DSeries *m_sensor = nullptr; 0378 QSurface3DSeries *m_petzval = nullptr; 0379 QSurfaceDataProxy *m_sensorProxy = nullptr; 0380 QSurfaceDataProxy *m_petzvalProxy = nullptr; 0381 QCustom3DLabel *m_label[NUM_TILES] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; 0382 bool m_graphicLabels { true }; 0383 bool m_graphicSensor { true }; 0384 bool m_graphicPetzvalWire { true }; 0385 bool m_graphicPetzvalSurface { false }; 0386 }; 0387 0388 }