diff --git a/DFTFringe.pro b/DFTFringe.pro index a84b5c6e..ae8265c5 100644 --- a/DFTFringe.pro +++ b/DFTFringe.pro @@ -155,6 +155,7 @@ SOURCES += SingleApplication/singleapplication.cpp \ astigscatterplot.cpp \ astigstatsdlg.cpp \ astigzoomer.cpp \ + autoinvertdlg.cpp \ averagewavefrontfilesdlg.cpp \ batchigramwizard.cpp \ bathastigdlg.cpp \ @@ -279,6 +280,7 @@ HEADERS += bezier/bezier.h \ astigscatterplot.h \ astigstatsdlg.h \ astigzoomer.h \ + autoinvertdlg.h \ averagewavefrontfilesdlg.h \ batchigramwizard.h \ bathastigdlg.h \ @@ -398,6 +400,7 @@ FORMS += arbitrarywavefronthelp.ui \ annulushelpdlg.ui \ astigpolargraph.ui \ astigstatsdlg.ui \ + autoinvertdlg.ui \ averagewavefrontfilesdlg.ui \ batchigramwizard.ui \ bathastigdlg.ui \ diff --git a/DFTFringe_Dale.pro b/DFTFringe_Dale.pro index b46a68ed..7da7e88b 100644 --- a/DFTFringe_Dale.pro +++ b/DFTFringe_Dale.pro @@ -31,6 +31,7 @@ SOURCES += main.cpp \ arbitrarywavefronthelp.cpp \ arbitrarywavwidget.cpp \ astigpolargraph.cpp \ + autoinvertdlg.cpp \ cpoint.cpp \ defocusdlg.cpp \ edgeplot.cpp \ @@ -154,6 +155,7 @@ HEADERS += mainwindow.h \ arbitrarywavefronthelp.h \ arbitrarywavwidget.h \ astigpolargraph.h \ + autoinvertdlg.h \ cpoint.h \ defocusdlg.h \ edgeplot.h \ @@ -281,6 +283,7 @@ FORMS += mainwindow.ui \ annulushelpdlg.ui \ arbitrarywavefronthelp.ui \ astigpolargraph.ui \ + autoinvertdlg.ui \ defocusdlg.ui \ dfttools.ui \ dftarea.ui \ @@ -388,7 +391,6 @@ LIBS += D:\opencv\opencv-3.4.12\build\bin\libopencv_imgproc3412.dll LIBS += D:\opencv\opencv-3.4.12\build\bin\libopencv_features2d3412.dll LIBS += D:\opencv\opencv-3.4.12\build\bin\libopencv_calib3d3412.dll - #LIBS += D:\armadillo\bin\libarmadillo.dll LIBS += D:\lapack\build64\bin\liblapack.dll LIBS += D:\lapack\build64\bin\libblas.dll diff --git a/DFTFringe_QT5.pro b/DFTFringe_QT5.pro index 2ec59040..d62f24e3 100644 --- a/DFTFringe_QT5.pro +++ b/DFTFringe_QT5.pro @@ -154,6 +154,7 @@ SOURCES += SingleApplication/singleapplication.cpp \ astigscatterplot.cpp \ astigstatsdlg.cpp \ astigzoomer.cpp \ + autoinvertdlg.cpp \ averagewavefrontfilesdlg.cpp \ batchigramwizard.cpp \ bathastigdlg.cpp \ @@ -278,6 +279,7 @@ HEADERS += bezier/bezier.h \ astigscatterplot.h \ astigstatsdlg.h \ astigzoomer.h \ + autoinvertdlg.h \ averagewavefrontfilesdlg.h \ batchigramwizard.h \ bathastigdlg.h \ @@ -397,6 +399,7 @@ FORMS += arbitrarywavefronthelp.ui \ annulushelpdlg.ui \ astigpolargraph.ui \ astigstatsdlg.ui \ + autoinvertdlg.ui \ averagewavefrontfilesdlg.ui \ batchigramwizard.ui \ bathastigdlg.ui \ diff --git a/autoinvertdlg.cpp b/autoinvertdlg.cpp new file mode 100644 index 00000000..50f6c4f7 --- /dev/null +++ b/autoinvertdlg.cpp @@ -0,0 +1,54 @@ +#include "autoinvertdlg.h" +#include "ui_autoinvertdlg.h" +#include "surfacemanager.h" + +autoInvertDlg::autoInvertDlg(QWidget *parent) : + QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint), + ui(new Ui::autoInvertDlg) +{ + ui->setupUi(this); +} + +autoInvertDlg::~autoInvertDlg() +{ + delete ui; +} + +void autoInvertDlg::on_btnUseConic_clicked() +{ + SurfaceManager *sm = SurfaceManager::get_instance(); + sm->m_inverseMode = invCONIC; + accept(); +} + + +void autoInvertDlg::on_btnManual_clicked() +{ + SurfaceManager *sm = SurfaceManager::get_instance(); + sm->m_inverseMode = invMANUAL; + accept(); +} + + +void autoInvertDlg::on_btnInside_clicked() +{ + SurfaceManager *sm = SurfaceManager::get_instance(); + sm->m_inverseMode = invINSIDE; + accept(); +} + + +void autoInvertDlg::on_btnOutside_clicked() +{ + SurfaceManager *sm = SurfaceManager::get_instance(); + sm->m_inverseMode = invOUTSIDE; + accept(); +} + +void autoInvertDlg::setMainLabel(const QString & str) { + ui->lblMain->setText(str); +} + +void autoInvertDlg::enableConic(bool b) { + ui->btnUseConic->setEnabled(b); +} diff --git a/autoinvertdlg.h b/autoinvertdlg.h new file mode 100644 index 00000000..dd41699f --- /dev/null +++ b/autoinvertdlg.h @@ -0,0 +1,34 @@ +#ifndef AUTOINVERTDLG_H +#define AUTOINVERTDLG_H + +#include + +namespace Ui { +class autoInvertDlg; +} + +class autoInvertDlg : public QDialog +{ + Q_OBJECT + +public: + explicit autoInvertDlg(QWidget *parent = nullptr); + ~autoInvertDlg(); + void setMainLabel(const QString & str); + void enableConic(bool b); + + +private slots: + void on_btnUseConic_clicked(); + + void on_btnManual_clicked(); + + void on_btnInside_clicked(); + + void on_btnOutside_clicked(); + +private: + Ui::autoInvertDlg *ui; +}; + +#endif // AUTOINVERTDLG_H diff --git a/autoinvertdlg.ui b/autoinvertdlg.ui new file mode 100644 index 00000000..441e325d --- /dev/null +++ b/autoinvertdlg.ui @@ -0,0 +1,187 @@ + + + autoInvertDlg + + + + 0 + 0 + 678 + 464 + + + + Invert Wavefront Mode + + + true + + + + + 20 + 150 + 111 + 24 + + + + Manual + + + + + + 20 + 80 + 111 + 24 + + + + Match Conic + + + + + + 20 + 200 + 111 + 24 + + + + Inside Focus + + + + + + 20 + 280 + 111 + 24 + + + + Outside Focus + + + + + + 140 + 150 + 521 + 41 + + + + I'll invert the wavefront myself as needed + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + 140 + 80 + 521 + 61 + + + + Most common. This mirror is at least partially figured. DFTFringe will invert the wavefront if S.A. sign doesn't match mirror configuration conic constant sign. This option disabled if CC=0. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + 140 + 200 + 521 + 71 + + + + This and future interferograms of this mirror are inside focus (interferometer closer to mirror). DFTFringe will use that fact to invert as needed. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + 140 + 280 + 521 + 61 + + + + This and future interferograms of this mirror are outside focus (interferometer farther from mirror). DFTFringe will use that fact to invert as needed. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + 20 + 0 + 641 + 61 + + + + + 14 + + + + Your wavefront may be inverted. What do you want to do? + + + true + + + + + + 20 + 350 + 631 + 91 + + + + Once you choose an option you won't be asked again until you restart the program. You can get back to this window from within the mirror configuration window. + + + true + + + + + + diff --git a/mainwindow.cpp b/mainwindow.cpp index 97d33985..8af6b7bc 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -2119,7 +2119,8 @@ void MainWindow::on_actionastig_in_polar_triggered() void MainWindow::on_actionStop_auto_invert_triggered() { - m_surfaceManager->m_askAboutReverse = true; - QMessageBox::information(this, "auto invert", "DFTFringe will now ask if it thinks it needs to invert a wave front."); + m_surfaceManager->m_inverseMode = invNOTSET; + m_mirrorDlg->updateAutoInvertStatus(); + //QMessageBox::information(this, "auto invert", "DFTFringe will now ask if it thinks it needs to invert a wave front."); } diff --git a/mirrordlg.cpp b/mirrordlg.cpp index 6d21d443..95403981 100644 --- a/mirrordlg.cpp +++ b/mirrordlg.cpp @@ -29,6 +29,8 @@ #include #include #include "annulushelpdlg.h" +#include "surfacemanager.h" + QString mirrorDlg::m_projectPath = ""; mirrorDlg *mirrorDlg::get_Instance(){ @@ -52,7 +54,6 @@ mirrorDlg::mirrorDlg(QWidget *parent) : enableAnnular(m_useAnnular); ui->annulusPercent->setValue(settings.value("md annulus percent",0.).toDouble() * 100 ); - ui->nullCB->setChecked(doNull); diameter = settings.value("config diameter", 200.).toDouble(); aperatureReduction = settings.value("config aperatureReduction", 0.).toDouble(); @@ -620,6 +621,12 @@ void mirrorDlg::on_buttonBox_accepted() setclearAp(); updateZ8(); + SurfaceManager * sm = SurfaceManager::get_instance(); + if (sm->m_inverseMode == invCONIC && cc==0) { + sm->m_inverseMode = invNOTSET; // don't allow inverse mode to be conic if conic constant is zero + updateAutoInvertStatus(); + } + settings.setValue("config mirror name", ui->name->text()); settings.setValue("config roc", roc); settings.setValue("config lambda",lambda); @@ -807,3 +814,36 @@ void mirrorDlg::setObsPercent(double obs){ ui->annulusPercent->setValue(obs); } +void mirrorDlg::updateAutoInvertStatus() +{ + switch(SurfaceManager::get_instance()->m_inverseMode) + { + case invNOTSET: + ui->lblAutoInvert->setText("Autoinvert: Not Set"); + break; + case invMANUAL: + ui->lblAutoInvert->setText("Autoinvert: Manual"); + break; + case invCONIC: + ui->lblAutoInvert->setText("Autoinvert: Conic"); + break; + case invINSIDE: + ui->lblAutoInvert->setText("Autoinvert: Inside Focus"); + break; + case invOUTSIDE: + ui->lblAutoInvert->setText("Autoinvert: Outside Focus"); + break; + } + +} + +void mirrorDlg::on_btnChangeAutoInvert_clicked() +{ + autoInvertDlg dlg; + dlg.setMainLabel("How should DFTFringe choose to auto invert?"); + dlg.enableConic(cc != 0); + dlg.exec(); + updateAutoInvertStatus(); +} + + diff --git a/mirrordlg.h b/mirrordlg.h index d05aa072..a810e1e8 100644 --- a/mirrordlg.h +++ b/mirrordlg.h @@ -20,6 +20,7 @@ #include #include +#include "autoinvertdlg.h" namespace Ui { class mirrorDlg; @@ -37,6 +38,7 @@ class mirrorDlg : public QDialog void loadFile(QString & fileName); void updateZ8(); + void updateAutoInvertStatus(); QString m_name; bool mm; @@ -118,6 +120,8 @@ private slots: void on_annularDiameter_valueChanged(double arg1); + void on_btnChangeAutoInvert_clicked(); + signals: void diameterChanged(double); void rocChanged(double); diff --git a/mirrordlg.ui b/mirrordlg.ui index 5bed7ddc..d6bca11d 100644 --- a/mirrordlg.ui +++ b/mirrordlg.ui @@ -6,189 +6,61 @@ 0 0 - 518 - 465 + 757 + 477 Mirror configuration - - - - Artificial Null - - - - - - - Mirror - - - - - - <html><head/><body><p>If set units are displayed in mm. If not then units are in inches. But only for this mirror configurion dialog.</p></body></html> - - - Units in mm - - - - - - - - - Diameter: - - - - - - - <html><head/><body><p>Daimeter of clear apature of the mirror or Horizontal axis of ellipse.</p></body></html> - - - - - - - - - - - Roc: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - <html><head/><body><p>Positive value of Radius of curvature of mirror or 0 if testing a flat. Will be ignored if Artificial Null is checked.</p><p>The Fnumber will be computed from this value and the diameter.</p></body></html> - - - - - - - - - - - FNumber: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Changing this value will compute the Roc value. - - - - - - - - - - - Obstruction: - - - - - - - <html><head/><body><p>Usually the size of the diagonal shadow on the mirror. The surface error in this area will be ignored by the metrics.</p></body></html> - - - - - - - - - - - Conic Constant: - - - - - - - <html><head/><body><p>Desired conic Constant. The actual value will be computed by the analysis.</p><p>This value is used in computing the Artiicial Null value.</p><p>Set to 0 if testing a flat or a sphere.</p><p>Set to -1 if testing a paraboloid.</p></body></html> - - - - - - - - - - - <html><head/><body><p>Enable masking the clear apature at the outside edge of the mirror.</p></body></html> - - - Edge Mask - - - - - - - false - - - <html><head/><body><p>Width of the edge to mask. New SA artificial null will be computed based on the clear aperature of the mirror with this this mask value.</p></body></html> - - - 3 - - - 1000.000000000000000 - - - - - - - - - - - Unmasked Aperature: - - - - - - - false - - - true - - - - - - - - - - + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Autoinvert: not set + + + + + + + Change... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + @@ -222,33 +94,17 @@ - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok + + + + Read Existing File - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + - Save in a File + Flip Interferogram left to right on loading @@ -306,20 +162,6 @@ Wave Length nm - - - - Read Existing File - - - - - - - Flip Interferogram left to right on loading - - - @@ -330,6 +172,9 @@ Wave Length nm + + + @@ -428,6 +273,196 @@ Wave Length nm + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok + + + + + + + Mirror + + + + + + <html><head/><body><p>If set units are displayed in mm. If not, then units are in inches. But only for this mirror configuration dialog.</p></body></html> + + + Units in mm + + + + + + + + + Diameter: + + + + + + + <html><head/><body><p>Diameter of clear aperture of the mirror or Horizontal axis of ellipse.</p></body></html> + + + + + + + + + + + Roc: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Positive value of Radius of curvature of mirror or 0 if testing a flat. Will be ignored if Artificial Null is checked.</p><p>The Fnumber will be computed from this value and the diameter.</p></body></html> + + + + + + + + + + + FNumber: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Changing this value will compute the Roc value. + + + + + + + + + + + Obstruction: + + + + + + + <html><head/><body><p>Usually the size of the diagonal shadow on the mirror. The surface error in this area will be ignored by the metrics.</p></body></html> + + + + + + + + + + + Conic Constant: + + + + + + + <html><head/><body><p>Desired conic Constant. The actual value will be computed by the analysis.</p><p>This value is used in computing the Artiicial Null value.</p><p>Set to 0 if testing a flat or a sphere.</p><p>Set to -1 if testing a paraboloid.</p></body></html> + + + + + + + + + + + <html><head/><body><p>Enable masking the clear apature at the outside edge of the mirror.</p></body></html> + + + Edge Mask + + + + + + + false + + + <html><head/><body><p>Width of the edge to mask. New SA artificial null will be computed based on the clear aperature of the mirror with this this mask value.</p></body></html> + + + 3 + + + 1000.000000000000000 + + + + + + + + + + + Unmasked Aperature: + + + + + + + false + + + true + + + + + + + + + + + + Artificial Null + + + + + + + Save in a File + + + diff --git a/surfaceanalysistools.cpp b/surfaceanalysistools.cpp index 3c368aa9..0dc5aa36 100644 --- a/surfaceanalysistools.cpp +++ b/surfaceanalysistools.cpp @@ -357,3 +357,6 @@ void surfaceAnalysisTools::closeDefocus(int /*result*/){ m_defocus = 0.; emit defocusChanged(); } + + + diff --git a/surfacemanager.cpp b/surfacemanager.cpp index 12833c47..b49e6036 100644 --- a/surfacemanager.cpp +++ b/surfacemanager.cpp @@ -376,31 +376,41 @@ void SurfaceManager::generateSurfacefromWavefront(wavefront * wf){ mirrorDlg *md = mirrorDlg::get_Instance(); zp.unwrap_to_zernikes(*wf); // check for swapped conic value - if (!m_ignoreInverse && (md->cc != 0.0) && md->cc * wf->InputZerns[8] < 0.){ - bool reverse = false; - if (m_askAboutReverse){ + if (!m_ignoreInverse) + { + if (m_inverseMode==invNOTSET) + { // Temporarily restore cursor so QMessageBox does not show waitCursor // QGuiApplication::setOverrideCursor do stack so we will go back to previous state (any state) QGuiApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); - bool msgResult = (QMessageBox::Yes == QMessageBox::question(0,"should invert?","Wavefront seems inverted. Do you want to invert it?")); + autoInvertDlg dlg_ai; + dlg_ai.setMainLabel("Your wavefront may be inverted. What do you want to do?"); + dlg_ai.enableConic(md->cc != 0); + dlg_ai.exec(); QGuiApplication::restoreOverrideCursor(); - if (msgResult) - { - reverse = true; - m_askAboutReverse = false; - }else - { - reverse = false; - } + md->updateAutoInvertStatus(); } - else { - reverse = true; + bool reverse = false; + if (m_inverseMode == invCONIC) + { + if (md->cc != 0.0 && md->cc * wf->InputZerns[8] < 0.) + reverse = true; + } else if (m_inverseMode == invINSIDE) + { + if (wf->InputZerns[3]>0) + reverse = true; + } else if (m_inverseMode == invOUTSIDE) + { + if (wf->InputZerns[3]<0) + reverse = true; } if (reverse){ wf->data *= -1; + zp.unwrap_to_zernikes(*wf); } - zp.unwrap_to_zernikes(*wf); } + + ((MainWindow*)parent())-> zernTablemodel->setValues(wf->InputZerns, !wf->useSANull); ((MainWindow*)parent())-> zernTablemodel->update(); // fill in void from obstruction of igram. @@ -496,9 +506,9 @@ SurfaceManager::SurfaceManager(QObject *parent, surfaceAnalysisTools *tools, ProfilePlot *profilePlot, contourView *contourView, SurfaceGraph *glPlot, metricsDisplay *mets): QObject(parent), m_surfaceTools(tools),m_profilePlot(profilePlot), m_contourView(contourView), - m_SurfaceGraph(glPlot), m_metrics(mets), - m_gbValue(21),m_GB_enabled(false),m_currentNdx(-1),m_standAvg(0),insideOffset(0), - outsideOffset(0),m_askAboutReverse(true),m_ignoreInverse(false), m_standAstigWizard(nullptr), workToDo(0), m_wftStats(0) + m_SurfaceGraph(glPlot), m_metrics(mets),m_gbValue(21), + m_GB_enabled(false),m_currentNdx(-1),m_standAvg(0),insideOffset(0),outsideOffset(0), + m_inverseMode(invNOTSET),m_ignoreInverse(false), m_standAstigWizard(nullptr), workToDo(0), m_wftStats(0) { okToUpdateSurfacesOnGenerateComplete = true; diff --git a/surfacemanager.h b/surfacemanager.h index dd0a0a1f..5f6f1052 100644 --- a/surfacemanager.h +++ b/surfacemanager.h @@ -44,6 +44,7 @@ #include #include "surfacegraph.h" enum configRESPONSE { YES, NO, ASK}; +enum AutoInvertMode {invNOTSET, invMANUAL, invCONIC, invINSIDE, invOUTSIDE}; struct textres { QTextEdit *Edit; QList res; @@ -110,7 +111,7 @@ class SurfaceManager : public QObject void average(QList wfList); void subtractWavefronts(); - bool m_askAboutReverse; + AutoInvertMode m_inverseMode; bool m_ignoreInverse; bool m_surface_finished; configRESPONSE diamResp;