diff --git a/DFTFringe.pro b/DFTFringe.pro index e94e9cab..d781a12c 100644 --- a/DFTFringe.pro +++ b/DFTFringe.pro @@ -265,6 +265,8 @@ SOURCES += SingleApplication/singleapplication.cpp \ zernikepolar.cpp \ zernikeprocess.cpp \ zernikes.cpp \ + settingsfacade.cpp \ + settingsstores.cpp \ zernikesmoothingdlg.cpp HEADERS += bezier/bezier.h \ @@ -356,6 +358,8 @@ HEADERS += bezier/bezier.h \ settingsGeneral2.h \ settingsigram.h \ settingsigramimportconfig.h \ + settingsfacade.h \ + settingsstores.h \ settingsprofile.h \ showaliasdlg.h \ showallcontoursdlg.h \ @@ -550,8 +554,5 @@ DISTFILES += buildingDFTFringe64.txt \ COPYING.LESSER.txt \ COPYING.txt \ README.md \ - RevisionHistory.html - - - - + RevisionHistory.html \ + settingsstores_fields.inc diff --git a/DFTFringe_Dale.pro b/DFTFringe_Dale.pro index 76fd813f..36b6e654 100644 --- a/DFTFringe_Dale.pro +++ b/DFTFringe_Dale.pro @@ -141,6 +141,8 @@ SOURCES += main.cpp \ outlinedialog.cpp \ psitiltoptions.cpp \ contourrulerparams.cpp \ + settingsfacade.cpp \ + settingsstores.cpp \ zernikesmoothingdlg.cpp \ zernike/zapm.cpp \ SingleApplication/singleapplication.cpp \ @@ -262,6 +264,8 @@ HEADERS += mainwindow.h \ outlinedialog.h \ psitiltoptions.h \ contourrulerparams.h \ + settingsfacade.h \ + settingsstores.h \ zernikesmoothingdlg.h \ bezier/bezier.h \ zernike/zapm_interface.h \ @@ -498,6 +502,7 @@ DISTFILES += \ COPYING.txt \ RevisionHistory.html \ README.md \ + settingsstores_fields.inc TRANSLATIONS = dftfringe_fr.ts diff --git a/DFTFringe_QT5.pro b/DFTFringe_QT5.pro index 65573323..58d60aac 100644 --- a/DFTFringe_QT5.pro +++ b/DFTFringe_QT5.pro @@ -264,6 +264,8 @@ SOURCES += SingleApplication/singleapplication.cpp \ zernikepolar.cpp \ zernikeprocess.cpp \ zernikes.cpp \ + settingsfacade.cpp \ + settingsstores.cpp \ zernikesmoothingdlg.cpp HEADERS += bezier/bezier.h \ @@ -355,6 +357,8 @@ HEADERS += bezier/bezier.h \ settingsGeneral2.h \ settingsigram.h \ settingsigramimportconfig.h \ + settingsfacade.h \ + settingsstores.h \ settingsprofile.h \ showaliasdlg.h \ showallcontoursdlg.h \ @@ -549,8 +553,5 @@ DISTFILES += buildingDFTFringe64.txt \ COPYING.LESSER.txt \ COPYING.txt \ README.md \ - RevisionHistory.html - - - - + RevisionHistory.html \ + settingsstores_fields.inc diff --git a/astigstatsdlg.cpp b/astigstatsdlg.cpp index 9992af56..1301e2f9 100644 --- a/astigstatsdlg.cpp +++ b/astigstatsdlg.cpp @@ -1,5 +1,6 @@ #include "astigstatsdlg.h" #include "ui_astigstatsdlg.h" +#include "settingsfacade.h" #include "circleutils.h" #include "circle.h" #include @@ -489,8 +490,7 @@ void astigStatsDlg::showItem(const QVariant &item, bool on, int /*ndx*/){ void astigStatsDlg::on_zernikePB_pressed() { - QSettings set; - QString path = set.value("mirrorConfigFile").toString(); + QString path = SettingsFacade::instance().appStore().load().mirrorConfigFile; QFile fn(path); QFileInfo info(fn.fileName()); QString dd = info.dir().absolutePath(); diff --git a/averagewavefrontfilesdlg.cpp b/averagewavefrontfilesdlg.cpp index 7fc615f0..4b7b6f5d 100644 --- a/averagewavefrontfilesdlg.cpp +++ b/averagewavefrontfilesdlg.cpp @@ -66,7 +66,7 @@ void averageWaveFrontFilesDlg::on_process_clicked() sm->generateSurfacefromWavefront(wf); cv::Scalar mean,std; cv::meanStdDev(wf->workData,mean,std,wf->workMask); - double stdVal = std.val[0]* md->lambda/outputLambda; + double stdVal = std.val[0]* md->currentSettings().lambda/outputLambda; if (stdVal > filterRMS){ QFileInfo info(name); QString item = QString("%1 RMS:%2").arg(info.baseName()).arg(stdVal, 0, 'f'); diff --git a/bathastigdlg.cpp b/bathastigdlg.cpp index c8aaba0e..d5162f5b 100644 --- a/bathastigdlg.cpp +++ b/bathastigdlg.cpp @@ -8,9 +8,9 @@ bathAstigDlg::bathAstigDlg(QWidget *parent) : { ui->setupUi(this); mirrorDlg &md = *mirrorDlg::get_Instance(); - ui->diamSb->setValue(md.diameter); - ui->rocsb->setValue(md.roc); - ui->lambdaSb->setValue(md.lambda); + ui->diamSb->setValue(md.currentSettings().diameter); + ui->rocsb->setValue(md.currentSettings().roc); + ui->lambdaSb->setValue(md.currentSettings().lambda); ui->sepSb->setValue(5.); compute(); } diff --git a/defocusdlg.cpp b/defocusdlg.cpp index 0bbd223c..11c35d03 100644 --- a/defocusdlg.cpp +++ b/defocusdlg.cpp @@ -86,7 +86,7 @@ void defocusDlg::on_defocusSlider_valueChanged(int value) ui->defocusVal->setValue(val); ui->defocusVal->blockSignals(false); - double f = mirrorDlg::get_Instance()->FNumber; + double f = mirrorDlg::get_Instance()->getFNumber(); double mm = f * f * 8. * value * .00055; //mmeters m_defocusInmm = mm; qDebug() << "defocus offset" << mm; diff --git a/dftarea.cpp b/dftarea.cpp index fa7d9962..f08b2270 100644 --- a/dftarea.cpp +++ b/dftarea.cpp @@ -40,7 +40,7 @@ cv::Mat makeMask(const CircleOutline &outside, const CircleOutline ¢er, con double rady = radm; mirrorDlg &md = *mirrorDlg::get_Instance(); if (md.isEllipse()) - rady = radm * md.m_verticalAxis/md.diameter; + rady = radm * md.currentSettings().ellipseMinorAxis/md.currentSettings().diameter; double rado = center.m_radius; double cx = outside.m_center.x(); double cy = outside.m_center.y(); @@ -151,14 +151,14 @@ DFTArea::DFTArea(QWidget *mparent, IgramArea *ip, DFTTools * tools, vortexDebug grid->attach(test); QPolygonF points; mirrorDlg &md = *mirrorDlg::get_Instance(); - double roc = md.roc; - double diam = md.diameter; + double roc = md.currentSettings().roc; + double diam = md.currentSettings().diameter; double r3 = roc * roc * roc; double d4 = diam * diam * diam * diam; for (double i = 0; i < .03; i += .0001){ - double z1 = -i * 384. * r3 * md.lambda * 1.E-6/(d4); + double z1 = -i * 384. * r3 * md.currentSettings().lambda * 1.E-6/(d4); points << QPointF( -i, z1 ); @@ -251,20 +251,13 @@ cv::Mat DFTArea::grayComplexMatfromImage(QImage &img){ double centerY = igramArea->m_outside.m_center.y(); mirrorDlg &md = *mirrorDlg::get_Instance(); - double pixelsPermm =(igramArea->m_outside.m_radius/(md.diameter/2.)); - double reduction = md.aperatureReduction * pixelsPermm; - if (md.m_aperatureReductionEnabled == false) + double pixelsPermm =(igramArea->m_outside.m_radius/(md.currentSettings().diameter/2.)); + double reduction = md.currentSettings().apertureReduction * pixelsPermm; + if (md.currentSettings().apertureReductionEnabled == false) reduction = 0; double rad = igramArea->m_outside.m_radius - reduction; - - double rady = rad; - - if (md.isEllipse()){ - rady = rady * md.m_verticalAxis/ md.diameter; - } - double left = centerX - rad; double top = centerY - rad; std::vector bgr_planes; @@ -1032,8 +1025,8 @@ void DFTArea::makeSurface(){ mirrorDlg *md = mirrorDlg::get_Instance(); - if (md->fringeSpacing != 1.){ - result *= md->fringeSpacing; + if (md->currentSettings().fringeSpacing != 1.){ + result *= md->currentSettings().fringeSpacing; } if (md->isEllipse()) { diff --git a/foucaultview.cpp b/foucaultview.cpp index 88018422..e0596558 100644 --- a/foucaultview.cpp +++ b/foucaultview.cpp @@ -203,7 +203,7 @@ void foucaultView::drawGridOverlay(QImage &img) { int maxPixelRadius = w / 2; mirrorDlg *md = mirrorDlg::get_Instance(); - double mirrorRadiusMM = md->diameter / 2.0; + double mirrorRadiusMM = md->currentSettings().diameter / 2.0; // 3. Determine physics-to-pixel scale double stepSizeMM = 0; @@ -298,8 +298,8 @@ void foucaultView::setSurface(wavefront *wf){ double offset = set.value("foucault roc offset", 0.).toDouble(); m_wf = wf; mirrorDlg *md = mirrorDlg::get_Instance(); - double rad = md->diameter/2.; - double FL = md->roc/2.; + double rad = md->currentSettings().diameter/2.; + double FL = md->currentSettings().roc/2.; double mul = (ui->useMM->isChecked()) ? 1. : 1/25.4; m_sag = mul * (rad * rad) /( 4 * FL); m_sag = round(100 * m_sag)/100.; @@ -362,9 +362,9 @@ QImage foucaultView::generateOpticalTestImage(OpticalTestType type, wavefront* w double coc_offset_mm = s.rocOffset * unitMultiplyer; // Physics geometry - double r2 = (md->diameter / 2.0) * (md->diameter / 2.0); - double b = md->roc + coc_offset_mm; - double pv = (sqrt(r2 + (md->roc * md->roc)) - (sqrt(r2 + b * b) - coc_offset_mm)) / (md->lambda * 1.E-6); + double r2 = (md->currentSettings().diameter / 2.0) * (md->currentSettings().diameter / 2.0); + double b = md->currentSettings().roc + coc_offset_mm; + double pv = (sqrt(r2 + (md->currentSettings().roc * md->currentSettings().roc)) - (sqrt(r2 + b * b) - coc_offset_mm)) / (md->currentSettings().lambda * 1.E-6); double z3 = pv / moving_constant; double effectiveZ3 = (type == OpticalTestType::Ronchi) ? (s.ronchiX * z3) : z3; @@ -377,20 +377,17 @@ QImage foucaultView::generateOpticalTestImage(OpticalTestType type, wavefront* w SimulationsView *sv = SimulationsView::getInstance(0); sv->setSurface(wf); - bool oldDoNull = md->doNull; - if (bAutoCollimate == false) - md->doNull = false; // this is normal foucault/ronchi so we *don't* subtract the null (autcoCollimate ronchi or foucault mode will typically subtract the null) + // For normal Foucault/Ronchi mode (not autocollimation), disable null correction + // Autocollimation mode applies null if configured; normal mode does not + bool applyNull = bAutoCollimate && md->currentSettings().doNull; - cv::Mat surf_fft = sv->computeStarTest(s.heightMultiply * sv->nulledSurface(effectiveZ3), size, actualPad, true); - - wf->InputZerns = originalZerns; // Restore state immediately - md->doNull = oldDoNull; + cv::Mat surf_fft = sv->computeStarTest(s.heightMultiply * sv->nulledSurface(effectiveZ3, applyNull), size, actualPad, true); // 3. Mask Generation cv::Mat mask = cv::Mat::zeros(size, size, CV_64FC1); cv::Mat sourceSlit = cv::Mat::zeros(size, size, CV_64FC1); int hx = (size - 1) / 2 + s.lateralOffset; - double pixwidth = s.outputLambda * 1.E-6 * (0.5 * md->roc / md->diameter) * 2. / (25.4 * actualPad); + double pixwidth = s.outputLambda * 1.E-6 * (0.5 * md->currentSettings().roc / md->currentSettings().diameter) * 2. / (25.4 * actualPad); if (type == OpticalTestType::Ronchi) { double lpi_val = s.lpi * (s.useMM ? 25.4 : 1.0); @@ -954,8 +951,8 @@ void foucaultView::on_RonchiX_valueChanged(double arg1) void foucaultView::on_pushButton_clicked() { mirrorDlg *md = mirrorDlg::get_Instance(); - double rad = md->diameter/2.; - double FL = md->roc/2.; + double rad = md->currentSettings().diameter/2.; + double FL = md->currentSettings().roc/2.; double mul = (ui->useMM->isChecked()) ? 1. : 1/25.4; m_sag = mul * (rad * rad) /( 4 * FL); m_sag = round(100 * m_sag)/100.; diff --git a/igramarea.cpp b/igramarea.cpp index be3ef1ba..1257f200 100644 --- a/igramarea.cpp +++ b/igramarea.cpp @@ -22,6 +22,7 @@ #endif #include "IgramArea.h" +#include "settingsfacade.h" #include "Circleoutline.h" #include #include @@ -150,9 +151,9 @@ IgramArea::IgramArea(QWidget *parent, void *mw) void IgramArea::computeEdgeRadius(){ // compute mask inner edge in pixels mirrorDlg &md = *mirrorDlg::get_Instance(); - double pixelsPermm =(m_outside.m_radius/(md.diameter/2.)); - m_edgeMaskWidth = md.aperatureReduction * pixelsPermm; - if (md.m_aperatureReductionEnabled == false) + double pixelsPermm =(m_outside.m_radius/(md.currentSettings().diameter/2.)); + m_edgeMaskWidth = md.currentSettings().apertureReduction * pixelsPermm; + if (md.currentSettings().apertureReductionEnabled == false) m_edgeMaskWidth = 0; } @@ -882,7 +883,7 @@ void IgramArea::useAnnulusforCenterOutine(){ if (m_current_boundry == CenterOutline) { mirrorDlg *md = mirrorDlg::get_Instance(); - double rad = m_outside.m_radius * md->m_annularObsPercent; + double rad = m_outside.m_radius * md->currentSettings().annulusPercent; double cx = m_outside.m_center.x(); double cy = m_outside.m_center.y(); @@ -1544,7 +1545,7 @@ void IgramArea::mouseMoveEvent(QMouseEvent *event) int majorRad = fabs((m_OutterP2.x() - m_OutterP1.x()))/2.; double e = (double)minorRad/majorRad; mirrorDlg &md = *mirrorDlg::get_Instance(); - md.m_verticalAxis = md.diameter * e; + md.setMinorAxis(md.currentSettings().diameter * e); drawBoundary(); return; } @@ -1623,8 +1624,8 @@ void IgramArea::mouseReleaseEvent(QMouseEvent *event) setCursor(Qt::ArrowCursor); if (event->button() == Qt::LeftButton && verticalTracking) { mirrorDlg &md = *mirrorDlg::get_Instance(); - double e = md.m_verticalAxis/ md.diameter; - md.setMinorAxis( e * md.diameter); + double e = md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter; + md.setMinorAxis( e * md.currentSettings().diameter); } @@ -1704,7 +1705,7 @@ void IgramArea::drawBoundary() mirrorDlg &md = *mirrorDlg::get_Instance(); if ((md.isEllipse())){ - s2 = md.m_verticalAxis/ md.diameter; + s2 = md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter; } if (m_searching_outside){ QColor c(Qt::cyan); @@ -1718,7 +1719,7 @@ void IgramArea::drawBoundary() painter.setBrush(Qt::NoBrush); } outside.draw(painter,1.,s2); - if ( md.m_aperatureReductionEnabled && md.m_clearAperature != md.diameter){ + if ( md.currentSettings().apertureReductionEnabled && md.getClearAperture() != md.currentSettings().diameter){ painter.setPen(QPen(edgePenColor, edgePenWidth, Qt::DotLine)); computeEdgeRadius(); painter.drawEllipse(outside.m_center, @@ -1926,7 +1927,7 @@ void IgramArea::paintEvent(QPaintEvent *event) mirrorDlg &md = *mirrorDlg::get_Instance(); double e = 1.; if (md.isEllipse()){ - e = md.m_verticalAxis/md.diameter; + e = md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter; } @@ -2021,7 +2022,7 @@ void IgramArea::crop() { mirrorDlg &md = *mirrorDlg::get_Instance(); if (md.isEllipse()){ - double e = md.m_verticalAxis/md.diameter; + double e = md.currentSettings().ellipseMinorAxis/md.currentSettings().diameter; rady = radx * e; top = fmax(0,cy - rady); bottom = igramColor.height() - (rady + cy); @@ -2519,7 +2520,8 @@ void IgramArea::save(){ mimeTypeFilters.append(mimeTypeName); mimeTypeFilters.sort(); QSettings settings; - QString lastPath = settings.value("projectPath",".").toString(); + QString lastPath = SettingsFacade::instance().appStore().load().projectPath; + if (lastPath.isEmpty()) lastPath = "."; QString filters = QStringList(mimeTypeFilters.mid(1,6)).join(" "); diff --git a/igramintensity.cpp b/igramintensity.cpp index c074fc0b..055a1898 100644 --- a/igramintensity.cpp +++ b/igramintensity.cpp @@ -17,6 +17,7 @@ ****************************************************************************/ #include "igramintensity.h" #include "ui_igramintensity.h" +#include "settingsfacade.h" #include #include #include @@ -58,8 +59,7 @@ void igramIntensity::on_showGreen_clicked(bool checked) void igramIntensity::on_pushButton_clicked() { - QSettings set; - QString path = set.value("mirrorConfigFile").toString(); + QString path = SettingsFacade::instance().appStore().load().mirrorConfigFile; QFile fn(path); QFileInfo info(fn.fileName()); QString dd = info.dir().absolutePath(); diff --git a/mainwindow.cpp b/mainwindow.cpp index 86c48b67..f50a8562 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -18,6 +18,7 @@ #include "mainwindow.h" #include "ui_mainwindow.h" #include "spdlog/spdlog.h" +#include "settingsfacade.h" #include #include #include @@ -193,7 +194,6 @@ MainWindow::MainWindow(QWidget *parent) : m_ogl->m_surface, metrics); connect(m_contourView, &contourView::showAllContours, m_surfaceManager, &SurfaceManager::showAllContours); connect(m_dftArea, &DFTArea::newWavefront, m_surfaceManager, &SurfaceManager::createSurfaceFromPhaseMap); - connect(m_surfaceManager, &SurfaceManager::diameterChanged,this,&MainWindow::diameterChanged); connect(m_surfaceManager, &SurfaceManager::showTab, ui->tabWidget, &QTabWidget::setCurrentIndex); connect(m_surfTools, &surfaceAnalysisTools::updateSelected, m_surfaceManager, &SurfaceManager::backGroundUpdate); ui->tabWidget->addTab(review, "Results"); @@ -272,8 +272,6 @@ MainWindow::MainWindow(QWidget *parent) : zernEnables[i] = false; } - connect(m_surfaceManager, &SurfaceManager::rocChanged,this, &MainWindow::rocChanged); - connect(m_mirrorDlg, &mirrorDlg::newPath,this, &MainWindow::newMirrorDlgPath); progBar = new QProgressBar(this); status1 = new QLabel(); @@ -585,22 +583,22 @@ void MainWindow::updateMetrics(wavefront& wf){ double Strehl = pow(e, -st); metrics->mStrehl->setText(QString("%1").arg(Strehl, 6, 'f', 3)); QString ztitle("Zernike Values"); - if (m_mirrorDlg->m_useAnnular){ - ztitle = QString("Annular Zernike values %1% center hole").arg(100 * m_mirrorDlg->m_annularObsPercent, 6, 'f',1); + if (m_mirrorDlg->currentSettings().useAnnulus){ + ztitle = QString("Annular Zernike values %1% center hole").arg(100 * m_mirrorDlg->currentSettings().annulusPercent, 6, 'f',1); } metrics->setZernTitle(ztitle); double z8 = zernTablemodel->values[8]; double BestSC; - if (m_mirrorDlg->doNull && wf.useSANull){ - BestSC = z8/m_mirrorDlg->z8; + if (m_mirrorDlg->currentSettings().doNull && wf.useSANull){ + BestSC = z8/m_mirrorDlg->getZ8(); } else { - BestSC = m_mirrorDlg->cc +z8/m_mirrorDlg->z8; + BestSC = m_mirrorDlg->currentSettings().cc +z8/m_mirrorDlg->getZ8(); } metrics->setOutputLambda(outputLambda); - metrics->setWavePerFringe(m_mirrorDlg->fringeSpacing, m_mirrorDlg->lambda); - if (m_mirrorDlg->doNull) + metrics->setWavePerFringe(m_mirrorDlg->currentSettings().fringeSpacing, m_mirrorDlg->currentSettings().lambda); + if (m_mirrorDlg->currentSettings().doNull) metrics->mCC->setText(QString("%1").arg(BestSC, 6 ,'f', 3)); else { metrics->mCC->setText("NA"); @@ -778,15 +776,6 @@ void MainWindow::showMessage(const QString &msg, int id){ } -void MainWindow::diameterChanged(double v){ - m_mirrorDlg->on_diameter_Changed(v); -} -void MainWindow::rocChanged(double v){ - m_mirrorDlg->on_roc_Changed(v); -} - - - void MainWindow::on_SelectOutSideOutline_clicked(bool checked) { m_igramArea->SideOutLineActive( checked); @@ -844,11 +833,7 @@ void MainWindow::on_showIntensity_clicked(bool checked) else m_intensityPlot->close(); } -void MainWindow::newMirrorDlgPath(const QString &path){ - QFileInfo info(path); - QSettings settings; - settings.setValue("lastPath",info.path()); -} + //make a simulated wavefront based on zernike values #define TSIZE 200 void MainWindow::on_actionWavefront_triggered() @@ -1996,7 +1981,8 @@ void MainWindow::on_actionSave_curent_profile_triggered() if (m_profilePlot->m_wf == 0) return; QSettings settings; - QString lastPath = settings.value("projectPath",".").toString(); + QString lastPath = SettingsFacade::instance().appStore().load().projectPath; + if (lastPath.isEmpty()) lastPath = "."; QString fName = QFileDialog::getSaveFileName(0, tr("Save Profile"), lastPath + "//profile.txt"); if (fName.isEmpty()) diff --git a/mainwindow.h b/mainwindow.h index 1f03c955..80e95758 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -84,8 +84,6 @@ class MainWindow : public QMainWindow public slots: void enableShiftButtons(bool enable); void showMessage(const QString&, int id); - void diameterChanged(double); - void rocChanged(double); void batchProcess(QStringList fileList); void batchMakeSurfaceReady(); void batchConnections(bool flag); @@ -120,7 +118,6 @@ private slots: void on_shiftDown_clicked(); void on_shiftRight_clicked(); void selectDftTab(); - void newMirrorDlgPath(const QString &path); void on_actionRead_WaveFront_triggered(); void on_actionPreferences_triggered(); diff --git a/metricsdisplay.cpp b/metricsdisplay.cpp index 772b3fcf..0f70bd73 100644 --- a/metricsdisplay.cpp +++ b/metricsdisplay.cpp @@ -58,8 +58,8 @@ void metricsDisplay::setWavePerFringe(double val, double lambda){ ui->wavesPerFringe->setText(QString("Waves Per Fringe: %1").arg(val, 2, 'f', 1)); ui->lambda->setText(QString("Igram laser wavelength: %1 nm").arg(lambda, 6, 'f', 2)); mirrorDlg *md = mirrorDlg::get_Instance(); - QString donull = (md->doNull) ? (QString("SANull: %1").arg(md->z8 * md->cc, 6, 'f', 4)) : ""; - ui->desiredConicLb->setText(QString("Desired Conic: %1 ").arg( md->cc, 6, 'f', 2) + donull); + QString donull = (md->currentSettings().doNull) ? (QString("SANull: %1").arg(md->getZ8() * md->currentSettings().cc, 6, 'f', 4)) : ""; + ui->desiredConicLb->setText(QString("Desired Conic: %1 ").arg( md->currentSettings().cc, 6, 'f', 2) + donull); if (md->isEllipse()){ ui->desiredConicLb->setText(""); ui->zernTitle->setText("Zernike Values not computed for Flats"); diff --git a/mirrordlg.cpp b/mirrordlg.cpp index 95403981..ebb7598c 100644 --- a/mirrordlg.cpp +++ b/mirrordlg.cpp @@ -19,6 +19,7 @@ #include "ui_mirrordlg.h" #include "spdlog/spdlog.h" #include +#include #include #include #include @@ -40,93 +41,37 @@ mirrorDlg *mirrorDlg::get_Instance(){ mirrorDlg::mirrorDlg(QWidget *parent) : QDialog(parent), - mm(true),m_obsChanged(false),ui(new Ui::mirrorDlg) + ui(new Ui::mirrorDlg), + m_obsChanged(false), + mm(true) { - m_useAnnular = false; - m_connectAnnulusToObs = false; ui->setupUi(this); - QSettings settings; - m_name = settings.value("config mirror name", "default").toString(); - ui->name->setText(m_name); - doNull = settings.value("config doNull", true).toBool(); - m_useAnnular = settings.value("md use annulus", false).toBool(); - ui->useAnnulus->setChecked(m_useAnnular); - 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(); - m_aperatureReductionEnabled = settings.value("configAperatureReductionChecked",false).toBool(); - - roc = settings.value("config roc", 2000.).toDouble(); - FNumber = roc/(2. * diameter); + + // Initialize defaults only; loadDraftFromSettings() populates m_current and m_draft + FNumber = 0.0; ui->FNumber->blockSignals(true); ui->roc->blockSignals(true); ui->lambda->blockSignals(true); ui->cc->blockSignals(true); ui->unitsCB->blockSignals(true); ui->fringeSpacingEdit->blockSignals(true); - - if (!doNull){ - ui->roc->hide(); - ui->rocLab->hide(); - ui->FNumber->hide(); - ui->fnumberLab->hide(); - } - else - { ui->roc->show(); - ui->rocLab->show(); - ui->fnumberLab->show(); - ui->FNumber->show(); - ui->roc->setText(QString("%1").arg(roc, 6, 'f', 2)); - ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2)); - } - lambda = settings.value("config lambda", 640).toDouble(); - - ui->lambda->setText(QString("%1").arg(lambda, 6 ,'f' ,1)); - - obs = settings.value("config obstruction", 0.).toDouble(); - - cc = settings.value("config cc", -1.).toDouble(); - - ui->cc->setText(QString("%1").arg(cc, 6, 'f', 2)); - - ui->ReducApp->setChecked( m_aperatureReductionEnabled); - if ( m_aperatureReductionEnabled) - ui->reduceValue->setEnabled(true); - - ui->reduceValue->setValue(aperatureReduction); - - + ui->minorAxisEdit->blockSignals(true); + ui->unitsCB->setChecked(mm); - - ui->FNumber->blockSignals(false); - ui->flipH->setChecked((settings.value( "flipH", false).toBool())); - m_projectPath = settings.value("projectPath", "").toString(); - fringeSpacing = settings.value("config fringe spacing", 1.).toDouble(); - - ui->fringeSpacingEdit->setText(QString("%1").arg(fringeSpacing, 6, 'f', 3)); - ui->fringeSpacingEdit->blockSignals(false); - m_outlineShape = (outlineShape)settings.value("outlineShape", CIRCLE).toInt(); - ui->minorAxisEdit->setText(QString::number(settings.value("ellipseMinorAxis", 50.).toDouble())); connect(&spacingChangeTimer, &QTimer::timeout, this, &mirrorDlg::spacingChangeTimeout); - if (m_verticalAxis == 0) - m_verticalAxis = diameter; - ui->ellipseShape->setChecked(m_outlineShape == ELLIPSE); - ui->minorAxisEdit->setText(QString().number(m_verticalAxis)); - ui->diameter->setText(QString("%1").arg(diameter, 6, 'f', 2)); - ui->obs->setText(QString("%1").arg(obs, 6, 'f', 2)); + ui->FNumber->blockSignals(false); ui->roc->blockSignals(false); ui->lambda->blockSignals(false); ui->cc->blockSignals(false); ui->unitsCB->blockSignals(false); ui->fringeSpacingEdit->blockSignals(false); - ui->ClearAp->setVisible( m_aperatureReductionEnabled); - ui->clearApLabel->setVisible( m_aperatureReductionEnabled); + ui->minorAxisEdit->blockSignals(false); + m_aperatureReductionValueChanged = false; - setclearAp(); + + // Initialize settings from persistent storage (in case dialog used without showEvent) + loadDraftFromSettings(); } mirrorDlg::~mirrorDlg() @@ -134,6 +79,46 @@ mirrorDlg::~mirrorDlg() spdlog::get("logger")->trace("mirrorDlg::~mirrorDlg"); delete ui; } + +void mirrorDlg::loadDraftFromSettings() +{ + // Load mirror settings from persistent storage via facade into BOTH copies. + // m_current: persistent copy (source of truth for external code) + // m_draft: working copy for dialog edits (discarded on Cancel) + m_current = SettingsFacade::instance().mirrorStore().load(); + m_draft = m_current; + + // Load application-level settings separately (projectPath, mirrorConfigFile, lastPath) + ApplicationSettings appSettings = SettingsFacade::instance().appStore().load(); + m_projectPath = appSettings.projectPath; +} + +void mirrorDlg::showEvent(QShowEvent *event) +{ + // Reload draft from persistent settings before dialog becomes visible. + // This ensures Cancel always reverts to the last-saved state. + loadDraftFromSettings(); + + // Sync UI with reloaded draft (working copy) values + ui->name->setText(m_draft.mirrorName); + ui->diameter->setText(QString("%1").arg(m_draft.diameter, 6, 'f', 2)); + ui->roc->setText(QString("%1").arg(m_draft.roc, 6, 'f', 2)); + ui->obs->setText(QString("%1").arg(m_draft.obstruction, 6, 'f', 2)); + ui->lambda->setText(QString("%1").arg(m_draft.lambda, 6, 'f', 1)); + ui->cc->setText(QString("%1").arg(m_draft.cc, 6, 'f', 2)); + ui->flipH->setChecked(m_draft.flipH); + ui->nullCB->setChecked(m_draft.doNull); + ui->fringeSpacingEdit->setText(QString("%1").arg(m_draft.fringeSpacing, 6, 'f', 3)); + ui->ellipseShape->setChecked((outlineShape)m_draft.outlineShape == ELLIPSE); + ui->minorAxisEdit->setText(QString::number(m_draft.ellipseMinorAxis)); + ui->ReducApp->setChecked(m_draft.apertureReductionEnabled); + ui->reduceValue->setValue(m_draft.apertureReduction); + ui->useAnnulus->setChecked(m_draft.useAnnulus); + ui->annulusPercent->setValue(m_draft.annulusPercent * 100); + + QDialog::showEvent(event); +} + bool mirrorDlg::shouldFlipH(){ return ui->flipH->isChecked(); } @@ -142,30 +127,29 @@ double mirrorDlg::getMinorAxis(){ } bool mirrorDlg::isEllipse(){ - return m_outlineShape == ELLIPSE; + return (outlineShape)m_draft.outlineShape == ELLIPSE; } void mirrorDlg::saveJson(const QString &fileName){ QJsonObject jDoc, jMirror,jIgram, jEllipse, jAnnulus; - jDoc["name"] = m_name; + jDoc["name"] = m_draft.mirrorName; jDoc["show units in mm"] = mm; - jDoc["useNull"] = doNull; - jIgram["wavelength"] = lambda; - jIgram["fringe spacing"] = fringeSpacing; - jMirror["diameter"] = diameter; - jMirror["obs diameter"] = obs; - jMirror["roc"] = roc; - jMirror["desired conic"] = cc; - jMirror["edgeMaskon"] = m_aperatureReductionEnabled; - jMirror["edge mask value"] = aperatureReduction; - jIgram["wavelength"] = lambda; + jDoc["useNull"] = m_draft.doNull; + jIgram["wavelength"] = m_draft.lambda; + jIgram["fringe spacing"] = m_draft.fringeSpacing; + jMirror["diameter"] = m_draft.diameter; + jMirror["obs diameter"] = m_draft.obstruction; + jMirror["roc"] = m_draft.roc; + jMirror["desired conic"] = m_draft.cc; + jMirror["edgeMaskon"] = m_draft.apertureReductionEnabled; + jMirror["edge mask value"] = m_draft.apertureReduction; + jIgram["wavelength"] = m_draft.lambda; jIgram["null value"] = z8; - jIgram["flip horizontal"] = fliph; - jIgram["flip vert"] = flipv; - jIgram["fringe spacing"] = fringeSpacing; - jEllipse["is ellipse"] = m_outlineShape; - jEllipse["ellipse vert axis"] = m_verticalAxis; - jAnnulus["use annular Zernike values"] = m_useAnnular; - jAnnulus["obs percentage"] = m_annularObsPercent; + jIgram["flip horizontal"] = m_draft.flipH; + jIgram["fringe spacing"] = m_draft.fringeSpacing; + jEllipse["is ellipse"] = m_draft.outlineShape; + jEllipse["ellipse vert axis"] = m_draft.ellipseMinorAxis; + jAnnulus["use annular Zernike values"] = m_draft.useAnnulus; + jAnnulus["obs percentage"] = m_draft.annulusPercent; jDoc["mirror"] = jMirror; jDoc["igram"] = jIgram; jDoc["ellipse"] = jEllipse; @@ -184,8 +168,7 @@ void mirrorDlg::saveJson(const QString &fileName){ } void mirrorDlg:: on_saveBtn_clicked() { - QSettings settings; - QString path = settings.value("mirrorConfigFile").toString(); + QString path = m_projectPath; // Use current project path for file dialog default QString extensionTypes("config file (*.json)"); QString fileName = QFileDialog::getSaveFileName(this, tr("Save config file"), path, @@ -202,25 +185,33 @@ void mirrorDlg:: on_saveBtn_clicked() } saveJson(fileName); QFileInfo info(fileName); - settings.setValue("mirrorConfigFile", fileName); - settings.setValue("projectPath", info.absolutePath()); - m_projectPath = info.absolutePath(); + + // Update application settings with new file path + ApplicationSettings appSettings = SettingsFacade::instance().appStore().load(); + appSettings.mirrorConfigFile = fileName; + appSettings.projectPath = info.absolutePath(); + SettingsFacade::instance().appStore().save(appSettings); + m_projectPath = appSettings.projectPath; } void mirrorDlg::loadFile(QString & fileName){ // clear ellipse in case this is an old config that does not have it. ui->ellipseShape->setChecked(false); - m_outlineShape = CIRCLE; + m_draft.outlineShape = (int)CIRCLE; QFileInfo info(fileName); + + // Persist UI convenience path to QSettings QSettings settings; - - settings.setValue("lastPath", info.absolutePath()); - emit newPath(info.absolutePath()); - m_projectPath = info.absolutePath(); - settings.setValue("mirrorConfigFile",fileName); settings.setValue("lastPath", info.absolutePath()); + // Update application settings with new file path and mirror config file via facade + ApplicationSettings appSettings = SettingsFacade::instance().appStore().load(); + appSettings.projectPath = info.absolutePath(); + appSettings.mirrorConfigFile = fileName; + SettingsFacade::instance().appStore().save(appSettings); + m_projectPath = appSettings.projectPath; + if (fileName.endsWith(".json")){ @@ -240,56 +231,55 @@ void mirrorDlg::loadFile(QString & fileName){ // set diameter early - before setting roc and annulus percentage QJsonObject mirror = loadDoc["mirror"].toObject(); - diameter = QJsonValue(mirror["diameter"]).toDouble(); + m_draft.diameter = QJsonValue(mirror["diameter"]).toDouble(); ui->diameter->blockSignals(true); - ui->diameter->setText(QString("%1").arg(diameter, 6, 'f', 2)); + ui->diameter->setText(QString("%1").arg(m_draft.diameter, 6, 'f', 2)); ui->diameter->blockSignals(false); ui->nullCB->setChecked( QJsonValue(loadDoc["useNull"]).toBool()); - obs = QJsonValue(mirror["obs diameter"]).toDouble(); - roc = QJsonValue(mirror["roc"]).toDouble(); - cc = QJsonValue(mirror["desired conic"]).toDouble(); - m_aperatureReductionEnabled = QJsonValue(mirror["edgeMaskon"]).toBool(); - aperatureReduction=QJsonValue( mirror["edge mask value"]).toDouble(); + m_draft.obstruction = QJsonValue(mirror["obs diameter"]).toDouble(); + m_draft.roc = QJsonValue(mirror["roc"]).toDouble(); + m_draft.cc = QJsonValue(mirror["desired conic"]).toDouble(); + m_draft.apertureReductionEnabled = QJsonValue(mirror["edgeMaskon"]).toBool(); + m_draft.apertureReduction = QJsonValue( mirror["edge mask value"]).toDouble(); QJsonObject Igram = loadDoc["igram"].toObject(); - lambda = QJsonValue(Igram["wavelength"]).toDouble(); + m_draft.lambda = QJsonValue(Igram["wavelength"]).toDouble(); z8 = QJsonValue(Igram["null value"]).toDouble(); - fliph = QJsonValue(Igram["flip horizontal"]).toBool(); - flipv = QJsonValue(Igram["flip vert"]).toBool(); - fringeSpacing = QJsonValue(Igram["fringe spacing"]).toDouble(); + m_draft.flipH = QJsonValue(Igram["flip horizontal"]).toBool(); + m_draft.fringeSpacing = QJsonValue(Igram["fringe spacing"]).toDouble(); QJsonObject Ellipse = loadDoc["ellipse"].toObject(); - m_outlineShape = (outlineShape)QJsonValue(Ellipse["is ellipse"]).toInt(); - m_verticalAxis = QJsonValue(Ellipse["ellipse vert axis"]).toDouble(); + m_draft.outlineShape = QJsonValue(Ellipse["is ellipse"]).toInt(); + m_draft.ellipseMinorAxis = QJsonValue(Ellipse["ellipse vert axis"]).toDouble(); QJsonObject Annulus = loadDoc["Annulus"].toObject(); - m_useAnnular = QJsonValue(Annulus["use annular Zernike values"]).toBool(); - m_annularObsPercent = QJsonValue(Annulus["obs percentage"]).toDouble(); - ui->useAnnulus->setChecked(m_useAnnular); - ui->annulusPercent->setValue(m_annularObsPercent * 100); - on_annulusPercent_valueChanged(m_annularObsPercent * 100); - enableAnnular(m_useAnnular); + m_draft.useAnnulus = QJsonValue(Annulus["use annular Zernike values"]).toBool(); + m_draft.annulusPercent = QJsonValue(Annulus["obs percentage"]).toDouble(); + ui->useAnnulus->setChecked(m_draft.useAnnulus); + ui->annulusPercent->setValue(m_draft.annulusPercent * 100); + on_annulusPercent_valueChanged(m_draft.annulusPercent * 100); + enableAnnular(m_draft.useAnnulus); ui->fringeSpacingEdit->blockSignals(true); - ui->fringeSpacingEdit->setText(QString("%1").arg(fringeSpacing, 3, 'f', 1)); + ui->fringeSpacingEdit->setText(QString("%1").arg(m_draft.fringeSpacing, 3, 'f', 1)); ui->fringeSpacingEdit->blockSignals(false); - ui->obs->setText(QString().number(obs)); + ui->obs->setText(QString().number(m_draft.obstruction)); ui->roc->blockSignals(true); - ui->roc->setText(QString("%1").arg(roc, 6, 'f', 2)); + ui->roc->setText(QString("%1").arg(m_draft.roc, 6, 'f', 2)); ui->roc->blockSignals(false); - ui->cc->setText(QString().number(cc)); + ui->cc->setText(QString().number(m_draft.cc)); ui->z8->setText(QString().number(z8)); - ui->ellipseShape->setChecked(m_outlineShape == ELLIPSE); + ui->ellipseShape->setChecked((outlineShape)m_draft.outlineShape == ELLIPSE); - ui->minorAxisEdit->setText(QString::number(m_verticalAxis)); + ui->minorAxisEdit->setText(QString::number(m_draft.ellipseMinorAxis)); - FNumber = roc/(2. * diameter); + FNumber = m_draft.roc/(2. * m_draft.diameter); ui->FNumber->blockSignals(true); ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2)); ui->FNumber->blockSignals(false); @@ -337,29 +327,29 @@ void mirrorDlg::loadFile(QString & fileName){ } ui->name->setText(name); - m_name = name; + m_draft.mirrorName = name; // donull file.read(buf,4); bool *bp = (bool *)buf; ui->nullCB->setChecked(*bp); - doNull = *bp; + m_draft.doNull = *bp; //fringe Spacing file.read(buf,8); double *dp = (double*)buf; - fringeSpacing = *dp; + m_draft.fringeSpacing = *dp; ui->fringeSpacingEdit->blockSignals(true); ui->fringeSpacingEdit->setText(QString("%1").arg(*dp, 3, 'f', 1)); ui->fringeSpacingEdit->blockSignals(false); //read diameter file.read(buf,8); - diameter = *dp; + m_draft.diameter = *dp; //Lambda file.read(buf,8); - lambda = *dp; + m_draft.lambda = *dp; ui->lambda->setText(QString().number(*dp)); //Units mm @@ -369,11 +359,11 @@ void mirrorDlg::loadFile(QString & fileName){ //obsruction file.read(buf,4 * 9); - obs = *(dp++); - ui->obs->setText(QString().number(obs)); + m_draft.obstruction = *(dp++); + ui->obs->setText(QString().number(m_draft.obstruction)); //ROC - roc = *(dp++); + m_draft.roc = *(dp++); //Diameter if (!mm){ @@ -381,15 +371,15 @@ void mirrorDlg::loadFile(QString & fileName){ //roc *= 25.4; } ui->diameter->blockSignals(true); - ui->diameter->setText(QString("%1").arg(diameter, 6, 'f', 2)); + ui->diameter->setText(QString("%1").arg(m_draft.diameter, 6, 'f', 2)); ui->diameter->blockSignals(false); ui->roc->blockSignals(true); - ui->roc->setText(QString("%1").arg(roc, 6, 'f', 2)); + ui->roc->setText(QString("%1").arg(m_draft.roc, 6, 'f', 2)); ui->roc->blockSignals(false); //conic - cc = *(dp++); - ui->cc->setText(QString().number(cc)); + m_draft.cc = *(dp++); + ui->cc->setText(QString().number(m_draft.cc)); //z8 z8 = *(dp++); @@ -407,27 +397,27 @@ void mirrorDlg::loadFile(QString & fileName){ //flips if (!file.eof()){ file.read(buf,4); // 1234 read right here - fliph = *(bool*)buf; + m_draft.flipH = *(bool*)buf; file.read(buf,4); - flipv = *(bool*)buf; + // Skip vertical flip - not stored in MirrorSettings struct and not used } // ellipse if (file.tellg() > 0){ // read outlineShape file.read(buf,4); - m_outlineShape = *(outlineShape*)buf; - ui->ellipseShape->setChecked(m_outlineShape == ELLIPSE); + m_draft.outlineShape = (int)*(outlineShape*)buf; + ui->ellipseShape->setChecked((outlineShape)m_draft.outlineShape == ELLIPSE); } // vertical axis if (file.tellg() > 0){ file.read(buf,8); - m_verticalAxis = *(double*)buf; - ui->minorAxisEdit->setText(QString::number(m_verticalAxis)); + m_draft.ellipseMinorAxis = *(double*)buf; + ui->minorAxisEdit->setText(QString::number(m_draft.ellipseMinorAxis)); } - FNumber = roc/(2. * diameter); + FNumber = m_draft.roc/(2. * m_draft.diameter); ui->FNumber->blockSignals(true); ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2)); ui->FNumber->blockSignals(false); @@ -438,6 +428,41 @@ void mirrorDlg::loadFile(QString & fileName){ } } } + +void mirrorDlg::adoptWavefrontSettings(double diameter, double roc, double lambda) +{ + if ((outlineShape)m_draft.outlineShape == ELLIPSE && m_draft.diameter != 0.0) { + const double e = m_draft.ellipseMinorAxis / m_draft.diameter; + m_draft.ellipseMinorAxis = e * diameter; + } + + m_draft.diameter = diameter; + m_draft.roc = roc; + m_draft.lambda = lambda; + + FNumber = m_draft.roc / (2. * m_draft.diameter); + + { + const QSignalBlocker blockDiameter(ui->diameter); + const QSignalBlocker blockRoc(ui->roc); + const QSignalBlocker blockLambda(ui->lambda); + const QSignalBlocker blockMinor(ui->minorAxisEdit); + const QSignalBlocker blockFNumber(ui->FNumber); + + ui->diameter->setText(QString("%1").arg(m_draft.diameter * ((mm) ? 1. : 1./25.4), 6, 'f', 2)); + ui->roc->setText(QString("%1").arg(m_draft.roc * ((mm) ? 1. : 1./25.4), 6, 'f', 2)); + ui->lambda->setText(QString("%1").arg(m_draft.lambda, 6, 'f', 1)); + ui->minorAxisEdit->setText(QString::number(m_draft.ellipseMinorAxis)); + ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2)); + } + + setclearAp(); + updateZ8(); + + m_current = m_draft; + SettingsFacade::instance().saveMirrorSettings(m_current); +} + void mirrorDlg::on_ReadBtn_clicked() { QSettings settings; @@ -450,91 +475,55 @@ void mirrorDlg::on_ReadBtn_clicked() loadFile(fileName); } QString mirrorDlg::getProjectPath(){ - return m_projectPath; + return m_projectPath; // Already synced from application settings in loadDraftFromSettings() } void mirrorDlg::on_diameter_textChanged(const QString &arg1) { double diam = arg1.toDouble() * ((mm) ? 1.: 25.4); - if (m_outlineShape == ELLIPSE){ - double e = m_verticalAxis/diameter; - m_verticalAxis = e * diam; - ui->minorAxisEdit->setText(QString().number(m_verticalAxis)); + if ((outlineShape)m_draft.outlineShape == ELLIPSE){ + double e = m_draft.ellipseMinorAxis/m_draft.diameter; + m_draft.ellipseMinorAxis = e * diam; + ui->minorAxisEdit->setText(QString().number(m_draft.ellipseMinorAxis)); } - diameter = diam; - FNumber = roc/(2. * diameter); + m_draft.diameter = diam; + FNumber = m_draft.roc/(2. * m_draft.diameter); ui->FNumber->blockSignals(true); ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2)); ui->FNumber->blockSignals(false); updateZ8(); - if (m_useAnnular){ - on_annulusPercent_valueChanged(m_annularObsPercent * 100); - } - -} - -//Used when the just loading wavfront is different -void mirrorDlg::on_diameter_Changed(const double diam) -{ - if (m_outlineShape == ELLIPSE){ - double e = m_verticalAxis/diameter; - m_verticalAxis = e * diam; - ui->minorAxisEdit->setText(QString().number(m_verticalAxis)); + if (m_draft.useAnnulus){ + on_annulusPercent_valueChanged(m_draft.annulusPercent * 100); } - diameter = diam ; - FNumber = roc/(2. * diameter); - ui->FNumber->blockSignals(true); - const QSignalBlocker blocker(ui->diameter); - ui->FNumber->setText(QString("%1").arg(FNumber *( (mm) ? 1.: 25.4), 6, 'f', 2)); - ui->diameter->setText(QString("%1").arg(diameter * ((mm) ? 1.: 25.4), 6, 'f', 2)); - ui->FNumber->blockSignals(false); - ui->diameter->blockSignals(false); - - setclearAp(); - updateZ8(); } void mirrorDlg::on_roc_textChanged(const QString &arg1) { - roc = arg1.toDouble() * ((mm) ? 1: 25.4); - FNumber = roc /(2. * diameter); + m_draft.roc = arg1.toDouble() * ((mm) ? 1: 25.4); + FNumber = m_draft.roc /(2. * m_draft.diameter); ui->FNumber->blockSignals(true); ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2)); ui->FNumber->blockSignals(false); updateZ8(); } -/* used when the just loading wavefront is different */ -void mirrorDlg::on_roc_Changed(const double newVal) -{ - roc = newVal; - - FNumber = roc /(2. * diameter); - ui->FNumber->blockSignals(true); - ui->FNumber->setText(QString("%1").arg(FNumber * ((mm) ? 1.: 25.4), 6, 'f', 2)); - ui->FNumber->blockSignals(false); - ui->roc->blockSignals(true); - ui->roc->setText(QString("%1").arg(roc * ((mm) ? 1.: 25.4), 6, 'f', 2)); - ui->roc->blockSignals(false); - updateZ8(); -} void mirrorDlg::updateZ8(){ //Z = d^6 / (16 * R^5) - double aperature = (ui->ReducApp->isChecked()) ? diameter- aperatureReduction*2. : diameter; + double aperature = (ui->ReducApp->isChecked()) ? m_draft.diameter - m_draft.apertureReduction*2. : m_draft.diameter; z8 = (pow(aperature,4) * 1000000.) / - (384. * pow(roc, 3) * lambda); + (384. * pow(m_draft.roc, 3) * m_draft.lambda); - if (m_useAnnular){ - double f = (1 - (m_annularObsPercent * m_annularObsPercent)); + if (m_draft.useAnnulus){ + double f = (1 - (m_draft.annulusPercent * m_draft.annulusPercent)); f *= f; z8 *= f; } ui->z8->blockSignals(true); - ui->z8->setText(QString().number(z8 * cc)); + ui->z8->setText(QString().number(z8 * m_draft.cc)); ui->z8->blockSignals(false); } @@ -543,36 +532,33 @@ void mirrorDlg::on_FNumber_textChanged(const QString &arg1) { FNumber = arg1.toDouble(); - roc = FNumber *(2 * diameter); + m_draft.roc = FNumber *(2 * m_draft.diameter); ui->roc->blockSignals(true); - ui->roc->setText(QString().number(roc * ((mm) ? 1.: 1./25.4))); + ui->roc->setText(QString().number(m_draft.roc * ((mm) ? 1.: 1./25.4))); ui->roc->blockSignals(false); updateZ8(); } void mirrorDlg::on_obs_textChanged(const QString &arg1) { - if (arg1.toDouble() != obs) + if (arg1.toDouble() != m_draft.obstruction) m_obsChanged = true; - obs = ((mm) ? 1: 25.4) * arg1.toDouble(); + m_draft.obstruction = ((mm) ? 1: 25.4) * arg1.toDouble(); } -void mirrorDlg::newLambda(const QString &v){ - ui->lambda->setText(v); -} void mirrorDlg::on_lambda_textChanged(const QString &arg1) { - lambda = arg1.toDouble(); + m_draft.lambda = arg1.toDouble(); updateZ8(); } void mirrorDlg::on_nullCB_clicked(bool checked) { - doNull = checked; + m_draft.doNull = checked; ui->FNumber->blockSignals(true); ui->roc->blockSignals(true); - if (!doNull){ + if (!m_draft.doNull){ ui->FNumber->hide(); ui->fnumberLab->hide(); @@ -596,63 +582,47 @@ void mirrorDlg::on_unitsCB_clicked(bool checked) ui->roc->blockSignals(true); ui->diameter->blockSignals(true); - ui->diameter->setText(QString("%1").arg(diameter/div, 6, 'f', 2)); - ui->roc->setText(QString().number(roc/div)); - ui->obs->setText(QString().number(obs/div)); + ui->diameter->setText(QString("%1").arg(m_draft.diameter/div, 6, 'f', 2)); + ui->roc->setText(QString().number(m_draft.roc/div)); + ui->obs->setText(QString().number(m_draft.obstruction/div)); ui->diameter->blockSignals(false); ui->roc->blockSignals(false); ui->minorAxisEdit->blockSignals(true); - ui->minorAxisEdit->setText(QString("%1").arg(m_verticalAxis/div, 6, 'f', 2)); + ui->minorAxisEdit->setText(QString("%1").arg(m_draft.ellipseMinorAxis/div, 6, 'f', 2)); ui->reduceValue->blockSignals(true); ui->annularDiameter->blockSignals(true); - ui->annularDiameter->setValue(diameter * m_annularObsPercent * ((mm)? 1.: 1./25.4)); + ui->annularDiameter->setValue(m_draft.diameter * m_draft.annulusPercent * ((mm)? 1.: 1./25.4)); ui->annularDiameter->blockSignals(false); - QSettings set; - aperatureReduction = set.value("config aperatureReduction",0.).toDouble(); - - ui->reduceValue->setValue(aperatureReduction * ((mm) ? 1. : 1./25.4)); + + // Get apertureReduction from draft (already loaded from persistent storage) + ui->reduceValue->setValue(m_draft.apertureReduction * ((mm) ? 1. : 1./25.4)); ui->reduceValue->blockSignals(false); - ui->ClearAp->setText(QString("%1 ").arg(m_clearAperature * ((mm) ? 1: 1./25.4), 6, 'f', 2)); + setclearAp(); } void mirrorDlg::on_buttonBox_accepted() { - QSettings settings; setclearAp(); updateZ8(); SurfaceManager * sm = SurfaceManager::get_instance(); - if (sm->m_inverseMode == invCONIC && cc==0) { + if (sm->m_inverseMode == invCONIC && m_draft.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); - settings.setValue("config diameter",diameter); - settings.setValue("config obstruction", obs); - settings.setValue("config cc", cc); - settings.setValue("flipH", ui->flipH->isChecked()); - settings.setValue("md Annulus to obs", m_useAnnular); - - settings.setValue("outlineShape", m_outlineShape); - fringeSpacing = ui->fringeSpacingEdit->text().toDouble(); - settings.setValue("config fringe spacing", fringeSpacing); - //settings.setValue("config unitsMM", mm); - settings.setValue("config doNull",doNull); - settings.setValue("outlineShape",(int)m_outlineShape); - settings.setValue("ellipseMinorAxis",m_verticalAxis); - settings.setValue("configAperatureReductionChecked", m_aperatureReductionEnabled); - settings.setValue("config aperatureReduction", aperatureReduction); - settings.setValue("md annulus percent", m_annularObsPercent); - settings.setValue("md use annulus", m_useAnnular); - if (m_obsChanged) + // Commit draft edits to persistent copy + m_current = m_draft; + + // Persist persistent copy to QSettings via facade (single atomic save) + // Note: Only mirrordlg can call this (via friend declaration) - enforces single source of truth + SettingsFacade::instance().saveMirrorSettings(m_current); - emit obstructionChanged(); + if (m_obsChanged) + emit obstructionChanged(); emit recomputeZerns(); if (m_aperatureReductionValueChanged){ - + emit aperatureChanged(); QMessageBox::warning(0, tr("Aperature Reduction value was changed."), tr("Aperature Reduction was changed.\n" "The wave front will not be correct until it is recomputed from the interferogram.")); @@ -663,18 +633,18 @@ void mirrorDlg::on_buttonBox_accepted() void mirrorDlg::on_cc_textChanged(const QString &arg1) { - cc = arg1.toDouble(); + m_draft.cc = arg1.toDouble(); updateZ8(); } void mirrorDlg::spacingChangeTimeout(){ spacingChangeTimer.stop(); double v = ui->fringeSpacingEdit->text().toDouble(); - if ( v != fringeSpacing){ + if ( v != m_draft.fringeSpacing){ QMessageBox::information(0,"Fringe Spacing Changed", "This change will only be used when Interferograms are analyzed. " "It will not be applied to any existing wavefronts already loaded."); } - fringeSpacing = v; + m_draft.fringeSpacing = v; } @@ -685,7 +655,7 @@ void mirrorDlg::on_fringeSpacingEdit_textChanged(const QString & /*text*/) void mirrorDlg::on_name_editingFinished() { - m_name = ui->name->text(); + m_draft.mirrorName = ui->name->text(); } @@ -693,23 +663,28 @@ void mirrorDlg::on_name_editingFinished() void mirrorDlg::on_minorAxisEdit_textChanged(const QString &arg1) { - m_verticalAxis = arg1.toDouble(); + m_draft.ellipseMinorAxis = arg1.toDouble(); } void mirrorDlg::setMinorAxis(double val){ - m_verticalAxis = val; + m_draft.ellipseMinorAxis = val; ui->minorAxisEdit->setText(QString::number(val)); //on_minorAxisEdit_textChanged( QString::number(val)); } +void mirrorDlg::setOutlineShape(outlineShape shape){ + m_draft.outlineShape = (int)shape; + ui->ellipseShape->setChecked(shape == ELLIPSE); +} + void mirrorDlg::on_ellipseShape_clicked(bool checked) { - if (checked) m_outlineShape = ELLIPSE; - else m_outlineShape = CIRCLE; + if (checked) m_draft.outlineShape = (int)ELLIPSE; + else m_draft.outlineShape = (int)CIRCLE; - if (m_verticalAxis == 0){ - m_verticalAxis = diameter; - ui->minorAxisEdit->setText(QString().number(m_verticalAxis)); + if (m_draft.ellipseMinorAxis == 0){ + m_draft.ellipseMinorAxis = m_draft.diameter; + ui->minorAxisEdit->setText(QString().number(m_draft.ellipseMinorAxis)); } } @@ -722,46 +697,52 @@ void mirrorDlg::on_buttonBox_helpRequested() void mirrorDlg::setclearAp(){ - m_clearAperature = (diameter - aperatureReduction * 2) ; - if (m_aperatureReductionEnabled == false) - m_clearAperature = diameter; - ui->ClearAp->setText(QString("%1 ").arg(m_clearAperature * ((mm) ? 1: 1./25.4), 6, 'f', 2)); + double clearAperature = (m_draft.diameter - m_draft.apertureReduction * 2) ; + if (m_draft.apertureReductionEnabled == false) + clearAperature = m_draft.diameter; + ui->ClearAp->setText(QString("%1 ").arg(clearAperature * ((mm) ? 1: 1./25.4), 6, 'f', 2)); +} + +double mirrorDlg::getClearAperture() const { + double clearAperature = (m_current.diameter - m_current.apertureReduction * 2) ; + if (m_current.apertureReductionEnabled == false){ + clearAperature = m_current.diameter; + } + return clearAperature; } void mirrorDlg::on_ReducApp_clicked(bool checked) { - m_aperatureReductionEnabled = checked; + m_draft.apertureReductionEnabled = checked; ui->reduceValue->setEnabled(checked); ui->ClearAp->setVisible(checked); ui->clearApLabel->setVisible(checked); updateZ8(); - ui->reduceValue->setValue(aperatureReduction); + ui->reduceValue->setValue(m_draft.apertureReduction); m_aperatureReductionValueChanged = true; setclearAp(); - emit aperatureChanged(); } void mirrorDlg::on_reduceValue_valueChanged(double arg1) { - aperatureReduction = ((mm) ? 1: 25.4) * arg1; + m_draft.apertureReduction = ((mm) ? 1: 25.4) * arg1; updateZ8(); setclearAp(); m_aperatureReductionValueChanged = true; - emit aperatureChanged(); } void mirrorDlg::on_annulusPercent_valueChanged(double arg1) { ui->annularDiameter->blockSignals(true); - m_annularObsPercent = .01 * arg1; - ui->annularDiameter->setValue( m_annularObsPercent * diameter * ( (mm) ? 1.: 1./25.4)); + m_draft.annulusPercent = .01 * arg1; + ui->annularDiameter->setValue( m_draft.annulusPercent * m_draft.diameter * ( (mm) ? 1.: 1./25.4)); ui->annularDiameter->blockSignals(false); - if (m_connectAnnulusToObs){ - ui->obs->setText(QString::number(m_annularObsPercent * diameter * ((mm)? 1.: 1./25.4))); + if (m_draft.annulusToObstruction){ + ui->obs->setText(QString::number(m_draft.annulusPercent * m_draft.diameter * ((mm)? 1.: 1./25.4))); } updateZ8(); } @@ -787,7 +768,7 @@ void mirrorDlg::enableAnnular(bool enable){ void mirrorDlg::on_useAnnulus_clicked(bool checked) { - m_useAnnular = checked; + m_draft.useAnnulus = checked; enableAnnular(checked); updateZ8(); @@ -805,14 +786,11 @@ void mirrorDlg::on_annulusHelp_clicked() void mirrorDlg::on_annularDiameter_valueChanged(double arg1) { - m_annularObsPercent = arg1/diameter; - ui->annulusPercent->setValue(m_annularObsPercent * 100); + m_draft.annulusPercent = arg1/m_draft.diameter; + ui->annulusPercent->setValue(m_draft.annulusPercent * 100); updateZ8(); } -void mirrorDlg::setObsPercent(double obs){ - ui->annulusPercent->setValue(obs); -} void mirrorDlg::updateAutoInvertStatus() { @@ -841,7 +819,7 @@ void mirrorDlg::on_btnChangeAutoInvert_clicked() { autoInvertDlg dlg; dlg.setMainLabel("How should DFTFringe choose to auto invert?"); - dlg.enableConic(cc != 0); + dlg.enableConic(m_draft.cc != 0); dlg.exec(); updateAutoInvertStatus(); } diff --git a/mirrordlg.h b/mirrordlg.h index a810e1e8..9422360a 100644 --- a/mirrordlg.h +++ b/mirrordlg.h @@ -21,6 +21,7 @@ #include #include #include "autoinvertdlg.h" +#include "settingsfacade.h" namespace Ui { class mirrorDlg; @@ -31,48 +32,47 @@ class mirrorDlg : public QDialog Q_OBJECT public: + // TODO we could get rid of singleton if every file accessed settings though SettingsFacade instead of mirrorDlg::get_Instance()->currentSettings() static mirrorDlg *get_Instance(); ~mirrorDlg(); mirrorDlg(const mirrorDlg&) = delete; mirrorDlg& operator=(const mirrorDlg&) = delete; - void loadFile(QString & fileName); - void updateZ8(); - void updateAutoInvertStatus(); - - QString m_name; - bool mm; - double diameter; - double roc; - double FNumber; - double obs; // obstruction - double cc; - bool doNull; - double z8; - double lambda; - double fringeSpacing; - bool flipv; - bool fliph; - bool m_useAnnular; - bool m_connectAnnulusToObs; - double m_annularObsPercent; // a value from 0 to 1 (not 0 to 100) - double m_clearAperature; - double aperatureReduction; - static QString m_projectPath; - void on_roc_Changed(const double newVal); - void on_diameter_Changed(const double diam); - bool shouldFlipH(); + void updateAutoInvertStatus(); //This one makes sense. Not saved + + // ---- file loading ---- + //TODO This is still not 100% clean + // One call from loading file shoulb be integgrated to adoptWavefrontSettings + // other calls are outline helpers. Need to be clarified + void setMinorAxis(double val); + // TODO to be fixed with #358. + // saving shape shall be asked as it is for ROC, lambda and diameter and be saved using adoptWavefrontSettings + void setOutlineShape(outlineShape shape); + + + // Apply loaded wavefront settings to both runtime and persisted mirror settings. + // Intended for a single call after wavefront load mismatch decisions are finalized. + void adoptWavefrontSettings(double diameter, double roc, double lambda); + + + // Computed/derived value accessors (read-only) + double getFNumber() const { return FNumber; } + double getZ8() const { return z8; } static QString getProjectPath(); - bool m_obsChanged; - void newLambda(const QString &v); double getMinorAxis(); - bool m_majorHorizontal; - double m_verticalAxis; - outlineShape m_outlineShape; + double getClearAperture() const; bool isEllipse(); - void setMinorAxis(double val); - bool m_aperatureReductionEnabled; - void setObsPercent(double obs); + bool shouldFlipH(); + + + /** @brief Access current mirror settings. + * Returns the persistent copy - the last saved state. + * External code reads this as source of truth. */ + const MirrorSettings& currentSettings() const { return m_current; } + +private: + + private slots: void on_ReadBtn_clicked(); @@ -123,25 +123,49 @@ private slots: void on_btnChangeAutoInvert_clicked(); signals: - void diameterChanged(double); - void rocChanged(double); - void lambdaChanged(double); - void saNullChanged(double); - void CCChanged(double); + // Emitted only after OK/accept when committed settings are saved. void obstructionChanged(); - void newPath(QString); void recomputeZerns(); - void aperatureChanged(); + void aperatureChanged(); + +protected: + /** @brief Reload settings before dialog becomes visible. */ + void showEvent(QShowEvent *event) override; private: explicit mirrorDlg(QWidget *parent = 0); void setclearAp(); + + /** @brief Load draft from persistent settings before dialog is shown. + * Ensures Cancel always reverts to the last saved state. */ + void loadDraftFromSettings(); Ui::mirrorDlg *ui; + + // State flags bool m_aperatureReductionValueChanged; + bool m_obsChanged; + QTimer spacingChangeTimer; + + // Persistent mirror configuration copy (source of truth) + MirrorSettings m_current; + + // Working copy for dialog edits (discarded on Cancel, committed to m_current on OK) + MirrorSettings m_draft; + + // Computed/derived values (read-only, not from settings) + //TODO actually mm is not saved in settings. should probably be saved as it's a user preference + bool mm; // Unit display flag: true = mm, false = other units + double FNumber; // Computed f-number (focal length / diameter) + double z8; // Z8 Zernike coefficient or null reference value + static QString m_projectPath; // Current project directory path + void saveJson(const QString &fileName); void enableAnnular(bool enable); + void updateZ8(); + void loadFile(QString & fileName); + }; #endif // MIRRORDLG_H diff --git a/nullvariationdlg.cpp b/nullvariationdlg.cpp index a0612b0f..da231276 100644 --- a/nullvariationdlg.cpp +++ b/nullvariationdlg.cpp @@ -26,8 +26,8 @@ nullVariationDlg::nullVariationDlg(QWidget *parent) : ui->roc->blockSignals(true); ui->diameter->blockSignals(true); - ui->diameter->setText(QString::number(md->diameter)); - ui->roc->setText(QString::number(md->roc)); + ui->diameter->setText(QString::number(md->currentSettings().diameter)); + ui->roc->setText(QString::number(md->currentSettings().roc)); ui->roc->blockSignals(false); ui->diameter->blockSignals(false); @@ -151,7 +151,7 @@ void nullVariationDlg::calculate() double roc = ui->roc->text().toDouble() * mul; mirrorDlg *md = mirrorDlg::get_Instance(); - double lambda = md->lambda; + double lambda = md->currentSettings().lambda; double center = 1.5 * pow(diam,4) * 1000000. /(384. * lambda * pow(roc,3)); //qDebug() << center/1.5; @@ -190,7 +190,7 @@ void nullVariationDlg::on_ComputeSim_clicked() double roc = ui->roc->text().toDouble() * mul; mirrorDlg *md = mirrorDlg::get_Instance(); - double lambda = md->lambda; + double lambda = md->currentSettings().lambda; double center = 1.5 * pow(diam,4) * 1000000. /(384. * lambda * pow(roc,3)); std::default_random_engine generator(time(0)); std::default_random_engine g2(time(0) + 1000); diff --git a/percentcorrectiondlg.cpp b/percentcorrectiondlg.cpp index 20816d84..6d044c35 100644 --- a/percentcorrectiondlg.cpp +++ b/percentcorrectiondlg.cpp @@ -1,5 +1,6 @@ #include "percentcorrectiondlg.h" #include "ui_percentcorrectiondlg.h" +#include "settingsfacade.h" #include "qwt_plot_grid.h" #include "qwt_scale_div.h" #include "qwt_plot_barchart.h" @@ -30,7 +31,7 @@ percentCorrectionDlg::percentCorrectionDlg( QWidget *parent) : mirrorDlg &md = *mirrorDlg::get_Instance(); - m_radius = md.m_clearAperature/2.; + m_radius = md.getClearAperture()/2.; QSettings set; ui->minvalue->blockSignals(true); ui->maxvalue->blockSignals(true); @@ -97,6 +98,7 @@ void percentCorrectionDlg::saveSettings(){ * fixme figure that out. */ QList percentCorrectionDlg::generateZoneCenters(double radius, int number_of_zones, bool makeNew){ + QSettings set; QList zoneCenters; if (!makeNew) { // read last used zones @@ -353,7 +355,7 @@ QPolygonF percentCorrectionDlg::makePercentages(surfaceData *surf){ ActualZoneKnife << 0.0; mirrorDlg *md = mirrorDlg::get_Instance(); - double nullval = md->z8 * md->cc; // null value was computed at the igram wavevlength + double nullval = md->getZ8() * md->currentSettings().cc; // null value was computed at the igram wavevlength nullval *= m_lambda_nm/m_outputLambda; // only data from the profile needs the null but it's data is at the output wavelength; // process each zone center @@ -399,7 +401,7 @@ QPolygonF percentCorrectionDlg::makePercentages(surfaceData *surf){ void percentCorrectionDlg::plotProfile(){ mirrorDlg *md = mirrorDlg::get_Instance(); - double nullval = md->z8 * md->cc; + double nullval = md->getZ8() * md->currentSettings().cc; for (int i = 0; i < surfs.length(); ++ i) { QwtPlotCurve *Curve = new QwtPlotCurve(); @@ -637,12 +639,12 @@ void percentCorrectionDlg::setData( QVector< surfaceData *> data) { mirrorDlg &md = *mirrorDlg::get_Instance(); - m_roc = md.roc; - m_lambda_nm = md.lambda; + m_roc = md.currentSettings().roc; + m_lambda_nm = md.currentSettings().lambda; QSettings set; m_outputLambda = set.value("outputLambda").toDouble(); - m_radius = md.m_clearAperature/2.; + m_radius = md.getClearAperture()/2.; surfs = data; ui->percentTable->setRowCount(data.length()); @@ -715,9 +717,7 @@ void percentCorrectionDlg::on_help_clicked() void percentCorrectionDlg::on_loadZones_clicked() { - - QSettings set; - QString path = set.value("projectPath").toString(); + QString path = SettingsFacade::instance().appStore().load().projectPath; QString extensionTypes(tr( "zone file (*.zones)")); QString fileName = QFileDialog::getOpenFileName(0, tr("Read zone file"), path, @@ -755,7 +755,7 @@ void percentCorrectionDlg::on_loadZones_clicked() void percentCorrectionDlg::on_saveZones_clicked() { QSettings set; - QString path = set.value("projectPath").toString(); + QString path = SettingsFacade::instance().appStore().load().projectPath; QString extensionTypes(tr( "zone file (*.zones)")); QString fileName = QFileDialog::getSaveFileName(0, tr("Save zone file"), path, @@ -774,7 +774,11 @@ void percentCorrectionDlg::on_saveZones_clicked() out << jsonString; file.close(); - set.setValue("projectPath", QFileInfo(fileName).absolutePath()); + + // Update and persist application settings via facade + ApplicationSettings appSettings = SettingsFacade::instance().appStore().load(); + appSettings.projectPath = QFileInfo(fileName).absolutePath(); + SettingsFacade::instance().appStore().save(appSettings); } diff --git a/profileplot.cpp b/profileplot.cpp index 6b97bbd1..2d3c84ff 100644 --- a/profileplot.cpp +++ b/profileplot.cpp @@ -406,7 +406,7 @@ QPolygonF ProfilePlot::createAverageProfile(double /*umnits*/, wavefront * /*wf* // double rho = avg[i].x() / md.diameter/2.; // double rho2 = rho * rho; // double y = avg[i].y(); -// y += md.z8 * md.cc * (1. + rho2 * (-6 + 6. * rho2)); +// y += md.getZ8() * md.cc * (1. + rho2 * (-6 + 6. * rho2)); // avg2 << QPointF(avg[i].x(),y); // } // avg = avg2; @@ -427,8 +427,8 @@ QPolygonF ProfilePlot::createProfile(double units, const wavefront *wf, bool all // 1. Setup constants double steps = 1.0 / wf->m_outside.m_radius; double offset = allowOffset ? y_offset : 0.0; - double radius = md.m_clearAperature / 2.0; - double obs_radius = md.obs / 2.0; + double radius = md.getClearAperture() / 2.0; + double obs_radius = md.currentSettings().obstruction / 2.0; if (m_displayInches) { obs_radius /= 25.4; @@ -443,12 +443,12 @@ QPolygonF ProfilePlot::createProfile(double units, const wavefront *wf, bool all if (m_displayPercent) { radx = 100.0 * radx / radius; - obs_radius = 100.0 * (md.obs / 2.0) / radius; + obs_radius = 100.0 * (md.currentSettings().obstruction / 2.0) / radius; } double e = 1.0; if (md.isEllipse()) { - e = md.m_verticalAxis / md.diameter; + e = md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter; } // Round to the nearest pixel to avoid 1-pixel endpoint errors at cardinal angles. @@ -526,7 +526,7 @@ void ProfilePlot::make_correction_graph(){ QColor penColor = Settings2::m_profile->getColor(i); // give the plot routine new zernike values for each curve. mirrorDlg *md = mirrorDlg::get_Instance(); - surfs << new surfaceData( md->lambda, penColor, theZerns ,name); + surfs << new surfaceData( md->currentSettings().lambda, penColor, theZerns ,name); } QPolygonF avg = createAverageProfile(1., wfs->at(list[0]),true); @@ -1170,11 +1170,11 @@ void ProfilePlot::CreateWaveFrontFromAverage(){ //create a matrix from the avgRadius profile. mirrorDlg *md = mirrorDlg::get_Instance(); // first add the null back into it. - if (md->doNull){ + if (md->currentSettings().doNull){ for (unsigned int i = 0; i < avgRadius.size(); ++i) { double R2 = (double(i))/(avgRadius.size() -1); R2 *= R2; - avgRadius[i] += md->z8 * md->cc * (1. + R2 * (-6 + 6. * R2));; + avgRadius[i] += md->getZ8() * md->currentSettings().cc * (1. + R2 * (-6 + 6. * R2));; } } cv::Mat result = createInterpolatedCircularSurface(avgRadius); diff --git a/reportdlg.cpp b/reportdlg.cpp index ad5fda56..cd76deab 100644 --- a/reportdlg.cpp +++ b/reportdlg.cpp @@ -9,7 +9,7 @@ ReportDlg::ReportDlg(QPrinter *p, QWidget *parent) : ui(new Ui::ReportDlg) { ui->setupUi(this); - ui->title->setText( mirrorDlg::get_Instance()->m_name); + ui->title->setText(mirrorDlg::get_Instance()->currentSettings().mirrorName); QSettings set; contourWidth = set.value("ReprotContourWidth", 1.).toDouble(); ui->contourWidth->setValue(contourWidth); diff --git a/settingsfacade.cpp b/settingsfacade.cpp new file mode 100644 index 00000000..52617eb6 --- /dev/null +++ b/settingsfacade.cpp @@ -0,0 +1,53 @@ +#include "settingsfacade.h" + +SettingsFacade &SettingsFacade::instance() +{ + static SettingsFacade facade; + return facade; +} + +MirrorSettingsStore &SettingsFacade::mirrorStore() +{ + return m_mirrorStore; +} + +const MirrorSettingsStore &SettingsFacade::mirrorStore() const +{ + return m_mirrorStore; +} + +void SettingsFacade::saveMirrorSettings(const MirrorSettings &settings) +{ + m_mirrorStore.save(settings); +} + +ApplicationSettingsStore &SettingsFacade::appStore() +{ + return m_appStore; +} + +const ApplicationSettingsStore &SettingsFacade::appStore() const +{ + return m_appStore; +} + +// examples for future PRs +//GeneralProcessingSettingsStore &SettingsFacade::generalProcessingStore() +//{ +// return m_generalProcessingStore; +//} +// +//const GeneralProcessingSettingsStore &SettingsFacade::generalProcessingStore() const +//{ +// return m_generalProcessingStore; +//} +// +//ContourSettingsStore &SettingsFacade::contourStore() +//{ +// return m_contourStore; +//} +// +//const ContourSettingsStore &SettingsFacade::contourStore() const +//{ +// return m_contourStore; +//} diff --git a/settingsfacade.h b/settingsfacade.h new file mode 100644 index 00000000..83ecd7b1 --- /dev/null +++ b/settingsfacade.h @@ -0,0 +1,57 @@ +#ifndef SETTINGSFACADE_H +#define SETTINGSFACADE_H + +#include "settingsstores.h" + +// Forward declaration for friend access +class mirrorDlg; + +/** + * @brief Thin entry point that delegates to domain-specific settings stores. + * + * This class intentionally stays small; domain behavior belongs in internal + * stores such as MirrorSettingsStore or ContourSettingsStore. + * + * Access control: saveMirrorSettings() is restricted to mirrordlg (via friend) + * to ensure mirror configuration is saved only from the dialog's OK button. + */ +class SettingsFacade +{ + friend class mirrorDlg; // Only mirrordlg can call saveMirrorSettings() +public: + + static SettingsFacade &instance(); + + MirrorSettingsStore &mirrorStore(); + const MirrorSettingsStore &mirrorStore() const; + + ApplicationSettingsStore &appStore(); + const ApplicationSettingsStore &appStore() const; + + // examples for future PRs + //GeneralProcessingSettingsStore &generalProcessingStore(); + //const GeneralProcessingSettingsStore &generalProcessingStore() const; +// + //ContourSettingsStore &contourStore(); + //const ContourSettingsStore &contourStore() const; + + +private: + friend class mirrorDlg; // Allow mirrordlg to call restricted save + + /** @brief Restricted save for mirror settings (mirrordlg only via friend). + * Ensures single source of truth: only the mirror dialog's OK button can persist changes. + * Nobody will be able to save mirror settings directly elsewhere in the code. */ + void saveMirrorSettings(const MirrorSettings &settings); + + SettingsFacade() = default; // Enforce singleton + + // Only facade owns these + MirrorSettingsStore m_mirrorStore; + ApplicationSettingsStore m_appStore; + // examples for future PRs + //GeneralProcessingSettingsStore m_generalProcessingStore; + //ContourSettingsStore m_contourStore; +}; + +#endif // SETTINGSFACADE_H diff --git a/settingsstores.cpp b/settingsstores.cpp new file mode 100644 index 00000000..d2c2c6d5 --- /dev/null +++ b/settingsstores.cpp @@ -0,0 +1,77 @@ +#include "settingsstores.h" + +#include + +#define SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS(type, name, defaultValue, key, converter) \ + value.name = s.value(key, defaultValue).converter(); + +#define SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS(type, name, defaultValue, key, converter) \ + s.setValue(key, value.name); + +MirrorSettings MirrorSettingsStore::load() const +{ + QSettings s; + + MirrorSettings value{}; + SETTINGS_STORE_FOR_EACH_MIRROR_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS) + + return value; +} + +void MirrorSettingsStore::save(const MirrorSettings &value) const +{ + QSettings s; + SETTINGS_STORE_FOR_EACH_MIRROR_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS) +} + +ApplicationSettings ApplicationSettingsStore::load() const +{ + QSettings s; + + ApplicationSettings value{}; + SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS) + + return value; +} + +void ApplicationSettingsStore::save(const ApplicationSettings &value) const +{ + QSettings s; + SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS) +} + +// examples for future PRs +//GeneralProcessingSettings GeneralProcessingSettingsStore::load() const +//{ +// QSettings s; +// +// GeneralProcessingSettings value{}; +// SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS) +// +// return value; +//} +// +//void GeneralProcessingSettingsStore::save(const GeneralProcessingSettings &value) const +//{ +// QSettings s; +// SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS) +//} +// +//ContourSettings ContourSettingsStore::load() const +//{ +// QSettings s; +// +// ContourSettings value{}; +// SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS) +// +// return value; +//} +// +//void ContourSettingsStore::save(const ContourSettings &value) const +//{ +// QSettings s; +// SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS) +//} + +#undef SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS +#undef SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS diff --git a/settingsstores.h b/settingsstores.h new file mode 100644 index 00000000..ba1a54ea --- /dev/null +++ b/settingsstores.h @@ -0,0 +1,77 @@ +#ifndef SETTINGSSTORES_H +#define SETTINGSSTORES_H + +#include + +class QSettings; + +#include "settingsstores_fields.inc" + +#define SETTINGS_STORE_DECLARE_STRUCT_FIELD(type, name, defaultValue, key, converter) type name = defaultValue; + + +struct MirrorSettings { + SETTINGS_STORE_FOR_EACH_MIRROR_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD) +}; + +class MirrorSettingsStore { +private: + friend class SettingsFacade; // Only facade can construct and call save() + MirrorSettingsStore() = default; + + void save(const MirrorSettings &value) const; + +public: + MirrorSettings load() const; +}; + +struct ApplicationSettings { + SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD) +}; + +class ApplicationSettingsStore { +private: + friend class SettingsFacade; + ApplicationSettingsStore() = default; + +public: + ApplicationSettings load() const; + void save(const ApplicationSettings &value) const; +}; + +// examples for future PRs +//struct GeneralProcessingSettings { +// SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD) +//}; +// +//class GeneralProcessingSettingsStore { +//private: +// friend class SettingsFacade; +// GeneralProcessingSettingsStore() = default; +// +//public: +// GeneralProcessingSettings load() const; +// void save(const GeneralProcessingSettings &value) const; +//}; +// +// +// +//struct ContourSettings { +// SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD) +//}; +// +//class ContourSettingsStore { +//private: +// friend class SettingsFacade; +// ContourSettingsStore() = default; +// +//public: +// ContourSettings load() const; +// void save(const ContourSettings &value) const; +//}; + + + +#undef SETTINGS_STORE_DECLARE_STRUCT_FIELD + +#endif // SETTINGSSTORES_H diff --git a/settingsstores_fields.inc b/settingsstores_fields.inc new file mode 100644 index 00000000..19c86fe5 --- /dev/null +++ b/settingsstores_fields.inc @@ -0,0 +1,51 @@ +// Shared settings schema list. +// Entry format for callbacks: +// FIELD(type, memberName, defaultValue, key, converter) + +#define SETTINGS_STORE_FOR_EACH_MIRROR_FIELD(FIELD) \ + FIELD(QString, mirrorName, QStringLiteral("default"), "config mirror name", toString) \ + FIELD(bool, doNull, true, "config doNull", toBool) \ + FIELD(double, diameter, 200.0, "config diameter", toDouble) \ + FIELD(double, roc, 2000.0, "config roc", toDouble) \ + FIELD(double, obstruction, 0.0, "config obstruction", toDouble) \ + FIELD(double, cc, -1.0, "config cc", toDouble) \ + FIELD(double, lambda, 640.0, "config lambda", toDouble) \ + FIELD(double, fringeSpacing, 1.0, "config fringe spacing", toDouble) \ + FIELD(bool, flipH, false, "flipH", toBool) \ + FIELD(bool, useAnnulus, false, "md use annulus", toBool) \ + FIELD(double, annulusPercent, 0.0, "md annulus percent", toDouble) \ + FIELD(bool, annulusToObstruction, false, "md Annulus to obs", toBool) \ + FIELD(int, outlineShape, 0, "outlineShape", toInt) \ + FIELD(double, ellipseMinorAxis, 50.0, "ellipseMinorAxis", toDouble) \ + FIELD(bool, apertureReductionEnabled, false, "configAperatureReductionChecked", toBool) \ + FIELD(double, apertureReduction, 0.0, "config aperatureReduction", toDouble) + +#define SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(FIELD) \ + FIELD(QString, projectPath, QString(), "projectPath", toString) \ + FIELD(QString, mirrorConfigFile, QString(), "mirrorConfigFile", toString) \ + FIELD(QString, lastPath, QString(), "lastPath", toString) + +// examples for futur PRs +/*#define SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(FIELD) \ + FIELD(bool, useMakeStarTest, false, "useMakeStarTest", toBool) \ + FIELD(int, wavefrontDownSizeValue, 650, "wavefrontDownSizeValue", toInt) \ + FIELD(bool, wavefrontShouldDownsize, false, "wavefrontShouldDownsize", toBool) \ + FIELD(double, outputLambda, 550.0, "outputLambda", toDouble) \ + FIELD(bool, applyOffsets, false, "applyOffsets", toBool) \ + FIELD(int, astigDistGraphWidth, 0, "AstigDistGraphWidth", toInt) \ + FIELD(bool, gaussianBlurEnabled, true, "GBlur", toBool) \ + FIELD(int, gaussianBlurValue, 20, "GBValue", toInt) \ + FIELD(bool, gaussianRadiusConverted, false, "gaussianRadiusConverted", toBool) \ + FIELD(int, lowMemoryThreshold, 0, "lowMemoryThreshold", toInt) \ + FIELD(bool, deletePrevWave, false, "deletePrevWave", toBool) + +#define SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(FIELD) \ + FIELD(double, contourRange, 0.100, "contourRange", toDouble) \ + FIELD(bool, contourShowFill, true, "contourShowFill", toBool) \ + FIELD(bool, contourShowLines, true, "contourShowLines", toBool) \ + FIELD(bool, contourShowRuler, false, "contourShowRuler", toBool) \ + FIELD(int, colorMapType, 0, "colorMapType", toInt) \ + FIELD(int, colorMapIndex, 1, "colorMap ndx", toInt) \ + FIELD(QString, contourLineColor, QStringLiteral("grey"), "ContourLineColor", toString) \ + FIELD(QString, contourRulerColor, QStringLiteral("grey"), "ContourRulerColor", toString) \ + FIELD(double, contourRulerRadialDeg, 0.0, "contourRulerRadialDeg", toDouble)*/ diff --git a/simigramdlg.cpp b/simigramdlg.cpp index ac3567e2..d128754a 100644 --- a/simigramdlg.cpp +++ b/simigramdlg.cpp @@ -186,7 +186,7 @@ simIgramDlg::simIgramDlg(QWidget *parent) : zernikes[2] = ytilt; size = s.value("simSize", 601).toDouble(); ui->sizeSB->setValue(size); - if (mirrorDlg::get_Instance()->cc == 0.){ + if (mirrorDlg::get_Instance()->currentSettings().cc == 0.){ ui->correctionPb->setChecked(false); } @@ -325,8 +325,8 @@ void simIgramDlg::on_editArbitrary_clicked() { UserDrawnProfileDlg * dlg = UserDrawnProfileDlg::get_instance(); mirrorDlg* md = mirrorDlg::get_Instance(); - if (md->diameter>0) - dlg->setDiameter(md->diameter); + if (md->currentSettings().diameter>0) + dlg->setDiameter(md->currentSettings().diameter); dlg->setModal(true); dlg->exec(); if (dlg->bOkPressed == false) diff --git a/simulationsview.cpp b/simulationsview.cpp index 12fff464..71a4a36a 100644 --- a/simulationsview.cpp +++ b/simulationsview.cpp @@ -117,7 +117,7 @@ void SimulationsView::initMTFPlot(){ grid->enableXMin(true); grid->setPen( Qt::gray, 0.0, Qt::DotLine ); grid->attach( ui->MTF); - m_arcSecScaleDraw = new arcSecScaleDraw(mirrorDlg::get_Instance()->diameter); + m_arcSecScaleDraw = new arcSecScaleDraw(mirrorDlg::get_Instance()->currentSettings().diameter); ui->MTF->setAxisScaleDraw(ui->MTF->xBottom, m_arcSecScaleDraw); QwtPlotLegendItem *customLegend = new QwtPlotLegendItem(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) @@ -191,7 +191,7 @@ SimulationsView *SimulationsView::getInstance(QWidget *parent){ -cv::Mat SimulationsView::nulledSurface(double defocus){ +cv::Mat SimulationsView::nulledSurface(double defocus, bool applyNull){ cv::Mat out; mirrorDlg *md = mirrorDlg::get_Instance(); @@ -210,7 +210,9 @@ cv::Mat SimulationsView::nulledSurface(double defocus){ // save the user selected defocus enable to be restored after this. bool saved_defocus_enable = zernEnables[3]; zernEnables[3] = false; - cv::Mat nulled_surface = zp.null_unwrapped( *(m_Instance->m_wf), newZerns, zernEnables); + + // Pass the applyNull flag to control whether null correction is applied + cv::Mat nulled_surface = zp.null_unwrapped( *(m_Instance->m_wf), newZerns, zernEnables, 0, Z_TERMS, applyNull); zernEnables[3] = saved_defocus_enable; if (GB_enabled){ @@ -221,7 +223,7 @@ cv::Mat SimulationsView::nulledSurface(double defocus){ CropGaussianBlur(nulled_surface, nulled_surface, blurRad, m_wf->m_outside, m_wf->m_inside); } - nulled_surface *= M2PI * md->lambda/outputLambda; + nulled_surface *= M2PI * md->currentSettings().lambda/outputLambda; return nulled_surface; } @@ -663,7 +665,7 @@ void SimulationsView::on_MakePB_clicked() // remove obstructions cv::Mat noObstruction = savedMask.clone(); mirrorDlg *md = mirrorDlg::get_Instance(); - double r = md->obs * (2. * m_wf->m_outside.m_radius)/md->diameter; + double r = md->currentSettings().obstruction * (2. * m_wf->m_outside.m_radius)/md->currentSettings().diameter; if (r > 0){ circle(noObstruction,Point(noObstruction.cols/2,noObstruction.cols/2),r, Scalar(255),-1); diff --git a/simulationsview.h b/simulationsview.h index 59a68808..9c107a75 100644 --- a/simulationsview.h +++ b/simulationsview.h @@ -51,7 +51,7 @@ class SimulationsView : public QWidget void compute(); bool needs_drawing; bool needs_drawing_3D; - cv::Mat nulledSurface(double defocus); + cv::Mat nulledSurface(double defocus, bool applyNull = true); cv::Mat m_PSF; private: bool alias; diff --git a/standastigwizard.cpp b/standastigwizard.cpp index 4f7b9489..874ef690 100644 --- a/standastigwizard.cpp +++ b/standastigwizard.cpp @@ -17,6 +17,7 @@ ****************************************************************************/ #include "standastigwizard.h" #include "ui_standastigwizard.h" +#include "settingsfacade.h" #include "spdlog/spdlog.h" #include #include @@ -133,7 +134,8 @@ makeAverages::makeAverages(QWidget *parent) } void define_input::pdfNamesPressed(){ QSettings set; - QString standReportPath = set.value("stand report path", mirrorDlg::get_Instance()->getProjectPath()).toString(); + QString standReportPath = SettingsFacade::instance().appStore().load().projectPath; + if (standReportPath.isEmpty()) standReportPath = mirrorDlg::get_Instance()->getProjectPath(); QString fileName = QFileDialog::getSaveFileName((QWidget* )0, "Export PDF", standReportPath + "/stand.pdf" , "*.pdf"); if (fileName.isEmpty()) @@ -190,7 +192,7 @@ define_input::define_input(QWidget *parent) browsePb = new QPushButton("Add average Wavefront file to List"); QString pdfNameStr = set.value("stand pdf file", "stand.pdf").toString(); connect(browsePb, &QAbstractButton::pressed, this, &define_input::browse); - AstigReportTitle = mirrorDlg::get_Instance()->m_name; + AstigReportTitle = mirrorDlg::get_Instance()->currentSettings().mirrorName; AstigReportPdfName = mirrorDlg::get_Instance()->getProjectPath() + "/" + pdfNameStr; title = new QLineEdit(AstigReportTitle); pdfName = new QPushButton(AstigReportPdfName); @@ -227,7 +229,7 @@ define_input::define_input(QWidget *parent) connect(runpb, &QAbstractButton::pressed, this, &define_input::compute); QSettings settings; - QString lastPath = settings.value("projectPath","").toString(); + QString lastPath = SettingsFacade::instance().appStore().load().projectPath; basePath = new QLineEdit(settings.value("rotation base path",lastPath).toString()); basePath->setToolTip("Directory were rotation files are stored."); QPushButton *browsePath = new QPushButton("..."); diff --git a/statsview.cpp b/statsview.cpp index 26bbacb1..6e950d9d 100644 --- a/statsview.cpp +++ b/statsview.cpp @@ -1,5 +1,6 @@ #include "statsview.h" #include "ui_statsview.h" +#include "settingsfacade.h" #include #include "wftstats.h" #include "surfacemanager.h" @@ -173,8 +174,7 @@ void statsView::on_checkBox_2_toggled(bool checked) void statsView::on_saveImg_clicked() { - QSettings settings; - QString path = settings.value("projectPath").toString(); + QString path = SettingsFacade::instance().appStore().load().projectPath; QFile fn(path); QString csvName = path + "/stats.pdf"; QString name = QFileInfo(csvName).absoluteFilePath() + "/stats.png"; @@ -226,8 +226,7 @@ QString statsView::title(const QString &dir){ void statsView::on_SaveCSV_clicked() { - QSettings settings; - QString path = settings.value("projectPath").toString(); + QString path = SettingsFacade::instance().appStore().load().projectPath; QFile fn(path); QFileInfo info(fn.fileName()); QString csvName = path + "/stats.csv"; @@ -270,9 +269,9 @@ void statsView::on_SaveCSV_clicked() double v = wf->InputZerns[ndx]; // apply software Null if needed - if (ndx == 8 and md->doNull) - v -= md->z8 * md->cc; - double Sigma = computeRMS(ndx,v) * md->lambda/outputLambda; + if (ndx == 8 and md->currentSettings().doNull) + v -= md->getZ8() * md->currentSettings().cc; + double Sigma = computeRMS(ndx,v) * md->currentSettings().lambda/outputLambda; if (ndx == 8) { spherical << QPointF(row,Sigma); @@ -280,7 +279,7 @@ void statsView::on_SaveCSV_clicked() sphericaRunningAvg << QPointF(row,sperAvg/(i+1)); } - mZerns.at(row,ndx) = Sigma * md->lambda/outputLambda; + mZerns.at(row,ndx) = Sigma * md->currentSettings().lambda/outputLambda; } @@ -293,8 +292,7 @@ void statsView::on_SaveCSV_clicked() void statsView::on_savePdf_clicked() { - QSettings settings; - QString path = settings.value("projectPath").toString(); + QString path = SettingsFacade::instance().appStore().load().projectPath; QFile fn(path); QFileInfo info(fn.fileName()); QString csvName = path + "/stats.pdf"; diff --git a/surfacemanager.cpp b/surfacemanager.cpp index 06deb989..490463e7 100644 --- a/surfacemanager.cpp +++ b/surfacemanager.cpp @@ -17,6 +17,7 @@ ****************************************************************************/ #include "surfacemanager.h" #include "spdlog/spdlog.h" +#include "settingsfacade.h" #include #include #include @@ -397,7 +398,7 @@ void SurfaceManager::generateSurfacefromWavefront(wavefront * wf){ QGuiApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); 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.enableConic(md->currentSettings().cc != 0); dlg_ai.exec(); QGuiApplication::restoreOverrideCursor(); md->updateAutoInvertStatus(); @@ -405,7 +406,7 @@ void SurfaceManager::generateSurfacefromWavefront(wavefront * wf){ bool reverse = false; if (m_inverseMode == invCONIC) { - if (md->cc != 0.0 && md->cc * wf->InputZerns[8] < 0.) + if (md->currentSettings().cc != 0.0 && md->currentSettings().cc * wf->InputZerns[8] < 0.) reverse = true; } else if (m_inverseMode == invINSIDE) { @@ -501,8 +502,8 @@ cv::Mat SurfaceManager::computeWaveFrontFromZernikes(int wx, int wy, std::vector } else { if (en[z]){ - if (z == 8 && md->doNull) - S1 += md->z8 * zpolar.zernike(z); + if (z == 8 && md->currentSettings().doNull) + S1 += md->getZ8() * zpolar.zernike(z); S1 += zerns[z] * zpolar.zernike(z); } @@ -648,7 +649,7 @@ void SurfaceManager::makeMask(wavefront *wf, bool useInsideCircle){ mirrorDlg &md = *mirrorDlg::get_Instance(); double rx = radm; double rx2 = rx * rx; - double ry = rx * md.m_verticalAxis/md.diameter; + double ry = rx * md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter; double ry2 = ry * ry; if (!mirrorDlg::get_Instance()->isEllipse()){ uchar v = 0xff; @@ -719,7 +720,7 @@ void SurfaceManager::makeMask(wavefront *wf, bool useInsideCircle){ // add central obstruction (not to be confused with a hole in the mirror - this comes from mirror configuration) - double r = md.obs * (2. * radm)/md.diameter; + double r = md.currentSettings().obstruction * (2. * radm)/md.currentSettings().diameter; r/= 2.; if (r > 0){ @@ -801,7 +802,7 @@ void SurfaceManager::useDemoWaveFront(){ if (rho <= 1.) { - double S1 = md->z8 * -.9 * zpolar.zernike(8) + .02* zpolar.zernike(9); + double S1 = md->getZ8() * -.9 * zpolar.zernike(8) + .02* zpolar.zernike(9); result.at(j,i) = S1; } @@ -862,7 +863,7 @@ void SurfaceManager::surfaceSmoothGBValue(double value){ } mirrorDlg *md = mirrorDlg::get_Instance(); - m_surfaceTools->setBlurText(QString("%1 mm").arg( .01 * value * md->diameter, 6, 'f', 2)); + m_surfaceTools->setBlurText(QString("%1 mm").arg( .01 * value * md->currentSettings().diameter, 6, 'f', 2)); if (m_wavefronts.size() == 0) return; @@ -887,7 +888,7 @@ void SurfaceManager::surfaceSmoothGBEnabled(bool b){ rad = m_wavefronts[m_currentNdx]->m_outside.m_radius-1; mirrorDlg *md = ((MainWindow*)parent())->m_mirrorDlg; - double mmPerPixel = md->diameter/(2 * rad); + double mmPerPixel = md->currentSettings().diameter/(2 * rad); m_surfaceTools->setBlurText(QString("%1 mm").arg(m_gbValue* mmPerPixel, 6, 'f', 2)); if (m_wavefronts.size() == 0) return; @@ -905,23 +906,23 @@ void SurfaceManager::syncGaussianStateForWavefront(wavefront *wf){ m_surfaceTools->setGaussianControls(wf->gbEnabled, wf->gbValue); mirrorDlg *md = mirrorDlg::get_Instance(); - m_surfaceTools->setBlurText(QString("%1 mm").arg(.01 * wf->gbValue * md->diameter, 6, 'f', 2)); + m_surfaceTools->setBlurText(QString("%1 mm").arg(.01 * wf->gbValue * md->currentSettings().diameter, 6, 'f', 2)); } void SurfaceManager::computeMetrics(wavefront *wf){ mirrorDlg *md = mirrorDlg::get_Instance(); cv::Scalar mean,std; cv::meanStdDev(wf->workData,mean,std,wf->workMask); - wf->mean = mean.val[0] * md->lambda/outputLambda; - wf->std = std.val[0]* md->lambda/outputLambda; + wf->mean = mean.val[0] * md->currentSettings().lambda/outputLambda; + wf->std = std.val[0]* md->currentSettings().lambda/outputLambda; double mmin; double mmax; minMaxIdx(wf->workData, &mmin,&mmax); - wf->min = mmin * md->lambda/outputLambda; - wf->max = mmax * md->lambda/outputLambda; + wf->min = mmin * md->currentSettings().lambda/outputLambda; + wf->max = mmax * md->currentSettings().lambda/outputLambda; ((MainWindow*)(parent()))->zernTablemodel->setValues(wf->InputZerns, !wf->useSANull); @@ -963,9 +964,9 @@ void SurfaceManager::computeZerns() mirrorDlg &md = *mirrorDlg::get_Instance(); foreach(int ndx , doThese){ wavefront &wf = *m_wavefronts[ndx]; - wf.diameter = md.diameter; - wf.roc = md.roc; - wf.lambda = md.lambda; + wf.diameter = md.currentSettings().diameter; + wf.roc = md.currentSettings().roc; + wf.lambda = md.currentSettings().lambda; } m_waveFrontTimer->start(500); @@ -1019,7 +1020,7 @@ void SurfaceManager::writeWavefront(const QString &fname, wavefront *wf, bool sa } mirrorDlg &md = *mirrorDlg::get_Instance(); if (md.isEllipse()){ - file << "ellipse_vertical_axis " << md.m_verticalAxis; + file << "ellipse_vertical_axis " << md.currentSettings().ellipseMinorAxis; } } @@ -1140,9 +1141,9 @@ void SurfaceManager::createSurfaceFromPhaseMap(cv::Mat phase, CircleOutline outs wf->m_inside = center; wf->data = phase; mirrorDlg *md = mirrorDlg::get_Instance(); - wf->diameter = md->diameter; - wf->lambda = md->lambda; - wf->roc = md->roc; + wf->diameter = md->currentSettings().diameter; + wf->lambda = md->currentSettings().lambda; + wf->roc = md->currentSettings().roc; wf->gbEnabled = m_GB_enabled; wf->gbValue = m_gbValue; wf->dirtyZerns = true; @@ -1161,9 +1162,9 @@ void SurfaceManager::createSurfaceFromPhaseMap(cv::Mat phase, CircleOutline outs wavefront * SurfaceManager::readWaveFront(const QString &fileName){ mirrorDlg *md = mirrorDlg::get_Instance(); double xm,ym,radm; - double roc = md->roc, - lambda = md->lambda, - diam = md->diameter; + double roc = md->currentSettings().roc, + lambda = md->currentSettings().lambda, + diam = md->currentSettings().diameter; double xo, yo, rado; wavefront *wf = new wavefront(); @@ -1329,8 +1330,10 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){ continue; } if (l.startsWith("ellipse_vertical_axis")){ - md->m_outlineShape = ELLIPSE; - iss >> dummy >> md->m_verticalAxis; + md->setOutlineShape(ELLIPSE); + double vertAxis; + iss >> dummy >> vertAxis; + md->setMinorAxis(vertAxis); } if (l.startsWith("Do Not use null") || l.startsWith("nulled") ){ wf->useSANull = false; @@ -1349,12 +1352,14 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){ } wf->m_inside = CircleOutline(QPointF(xo,yo), rado); + bool shouldAdoptWavefrontSettings = false; - if (lambda != md->lambda){ + + if (lambda != md->currentSettings().lambda){ if (lambdResp == ASK){ QString message("The interferogram wavelength ("); message += QString("%1").arg( lambda, 6, 'f', 3) + - ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->lambda, 6, 'f', 3) + + ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->currentSettings().lambda, 6, 'f', 3) + "Do you want to make the config match?"; @@ -1372,15 +1377,15 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){ } if ( lambdResp == YES || messageResult == QMessageBox::Yes){ - md->newLambda(QString::number(lambda)); + shouldAdoptWavefrontSettings = true; } } - if (roundl(diam * 10) != roundl(md->diameter* 10)) + if (roundl(diam * 10) != roundl(md->currentSettings().diameter* 10)) { QString message("The mirror diameter ("); message += QString("%1").arg(diam, 6, 'f', 3) + - ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->diameter, 6, 'f', 3) + + ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->currentSettings().diameter, 6, 'f', 3) + "Do you want to make the config match?"; if (diamResp == ASK){ int resp = QMessageBox(QMessageBox::Information,"config", message,QMessageBox::Yes|QMessageBox::No | @@ -1396,19 +1401,19 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){ } } if (diamResp == YES || messageResult == QMessageBox::Yes){ - emit diameterChanged(diam); + shouldAdoptWavefrontSettings = true; } else { - diam = md->diameter; + diam = md->currentSettings().diameter; } } - if (roundl(roc * 10.) != roundl(md->roc * 10.)) + if (roundl(roc * 10.) != roundl(md->currentSettings().roc * 10.)) { QString message("The mirror roc ("); message += QString("%1").arg(roc, 6, 'f', 3) + - ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->roc, 6, 'f', 3) + + ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->currentSettings().roc, 6, 'f', 3) + "Do you want to make the config match?"; //qDebug() << message; if (rocResp == ASK){ @@ -1425,13 +1430,18 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){ } } if (rocResp == YES || messageResult == QMessageBox::Yes){ - emit rocChanged(roc); + shouldAdoptWavefrontSettings = true; } else { - roc = md->roc; + roc = md->currentSettings().roc; } } + + if (shouldAdoptWavefrontSettings) { + md->adoptWavefrontSettings(diam, roc, lambda); + } + wf->diameter = diam; wf->roc = roc; wf->lambda = lambda; @@ -3042,9 +3052,9 @@ void SurfaceManager::report(){ + QDate::currentDate().toString() + " " +QTime::currentTime().toString()+"
DFTFringe Version:"+APP_VERSION+""); - QString Diameter = (md->isEllipse()) ? " Horizontal Axis: " : " Diameter: " +QString().number(md->diameter,'f',1) ; - QString ROC = (md->isEllipse()) ? "Vertical Axis: " + QString().number(md->m_verticalAxis) : "ROC: " + QString().number(md->roc,'f',1); - QString FNumber = (md->isEllipse()) ? "" : "Fnumber: " + QString().number(md->FNumber,'f',1); + QString Diameter = (md->isEllipse()) ? " Horizontal Axis: " : " Diameter: " +QString().number(md->currentSettings().diameter,'f',1) ; + QString ROC = (md->isEllipse()) ? "Vertical Axis: " + QString().number(md->currentSettings().ellipseMinorAxis) : "ROC: " + QString().number(md->currentSettings().roc,'f',1); + QString FNumber = (md->isEllipse()) ? "" : "Fnumber: " + QString().number(md->currentSettings().roc/(2.0*md->currentSettings().diameter),'f',1); QString BFC = (md->isEllipse()) ? " Flat" : "Best Fit CC: " +metrics->mCC->text(); QString html = "

" "" @@ -3052,9 +3062,9 @@ void SurfaceManager::report(){ "" - "" - "" + "" + "" "
" + Diameter + " mm" + ROC + " mm
RMS: " + QString().number(wf->std,'f',3) + QString(" waves at %1 nmStrehl: ").arg(outputLambda, 6, 'f', 1) + metrics->mStrehl->text() + "" + BFC + "
" + ((md->isEllipse()) ? "":"Desired Conic: " + QString::number(md->cc)) + "" + - ((md->doNull) ? QString("SANull: %1").arg(md->z8 * md->cc, 6, 'f', 4) : "No software Null") + "Waves per fringe: " + QString::number(md->fringeSpacing) + "
Interferogram Wave length: "+ QString::number(md->lambda) + "nm
" + ((md->isEllipse()) ? "":"Desired Conic: " + QString::number(md->currentSettings().cc)) + "" + + ((md->currentSettings().doNull) ? QString("SANull: %1").arg(md->getZ8() * md->currentSettings().cc, 6, 'f', 4) : "No software Null") + "Waves per fringe: " + QString::number(md->currentSettings().fringeSpacing) + "
Interferogram Wave length: "+ QString::number(md->currentSettings().lambda) + "nm

"; // zerenike values @@ -3062,8 +3072,8 @@ void SurfaceManager::report(){ if (!md->isEllipse()){ zerns = "


" "" "

" + - ((!md->m_useAnnular) ? QString("Zernike Values at interferogram wavelength") : - QString("Annular Zernike Values %1\% center hole").arg(100 * md->m_annularObsPercent, 6,'f',2))+ + ((!md->currentSettings().useAnnulus) ? QString("Zernike Values at interferogram wavelength") : + QString("Annular Zernike Values %1\% center hole").arg(100 * md->currentSettings().annulusPercent, 6,'f',2))+ "

"; zerns.append(""); @@ -3075,8 +3085,8 @@ void SurfaceManager::report(){ val = m_surfaceTools->m_defocus; enabled = true; } - if ( i == 8 && md->doNull){ - val -= md->z8 * md->cc; + if ( i == 8 && md->currentSettings().doNull){ + val -= md->getZ8() * md->currentSettings().cc; } @@ -3438,7 +3448,7 @@ bool QPointFLessThan(QPointF p1, QPointF p2){ void SurfaceManager::tiltAnalysis(){ QSettings set; - QString path = set.value("mirrorConfigFile").toString(); + QString path = SettingsFacade::instance().appStore().load().mirrorConfigFile; QFile fn(path); QFileInfo info(fn.fileName()); QString dd = info.dir().absolutePath(); diff --git a/surfacemanager.h b/surfacemanager.h index 16ce5d87..19795c19 100644 --- a/surfacemanager.h +++ b/surfacemanager.h @@ -148,8 +148,6 @@ class SurfaceManager : public QObject void deleteWavefront(int); void rotateTheseSig(int, QList); void progress(int); - void diameterChanged(double); - void rocChanged(double); void nameChanged(const QString &, const QString &); void showTab(int); void enableControls(bool); diff --git a/unwraperrorsview.cpp b/unwraperrorsview.cpp index 2eea6f8b..908dd266 100644 --- a/unwraperrorsview.cpp +++ b/unwraperrorsview.cpp @@ -1,5 +1,6 @@ #include "unwraperrorsview.h" #include "ui_unwraperrorsview.h" +#include "settingsfacade.h" #include #include #include @@ -71,7 +72,7 @@ unwrapErrorsView::~unwrapErrorsView() void unwrapErrorsView::on_save_clicked() { QSettings set; - QString path = set.value("mirrorConfigFile").toString(); + QString path = SettingsFacade::instance().appStore().load().mirrorConfigFile; QFile fn(path); QFileInfo info(fn.fileName()); QString dd = info.dir().absolutePath(); diff --git a/usercolormapdlg.cpp b/usercolormapdlg.cpp index ed627550..3a2f8672 100644 --- a/usercolormapdlg.cpp +++ b/usercolormapdlg.cpp @@ -283,7 +283,7 @@ void userColorMapDlg::on_pb10_clicked() ui->pb10->setStyleSheet(s); ui->pb10->update(); QSettings set; - set.setValue("userColorStopColor09",c.name()); + set.setValue("userColorStopColor10",c.name()); setColorMap(); emit colorMapChanged(5); } diff --git a/wftstats.cpp b/wftstats.cpp index 3b4c876e..f1106625 100644 --- a/wftstats.cpp +++ b/wftstats.cpp @@ -139,10 +139,10 @@ void wftStats::computeZernStats( int ndx){ for (int i = 0; i < c.rows; ++i){ int row = (i + ndx) % c.rows; - double v = computeRMS(ndx,c.at(row)) * outputLambda/md->lambda; + double v = computeRMS(ndx,c.at(row)) * outputLambda/md->currentSettings().lambda; if (isPair){ cv::Mat c2 = m_Zerns.col(zern+1); - double v2 = computeRMS(ndx,c2.at(row)) * outputLambda/md->lambda; + double v2 = computeRMS(ndx,c2.at(row)) * outputLambda/md->currentSettings().lambda; double s = sqrt(v * v + v2 * v2); v = s; zname += " "; @@ -214,9 +214,9 @@ void wftStats::computeWftStats( QVector wavefronts, int ndx){ double v = wf->InputZerns[ndx]; // apply software Null if needed - if (ndx == 8 and md->doNull) - v -= md->z8 * md->cc; - double Sigma = computeRMS(ndx,v) * outputLambda/md->lambda; + if (ndx == 8 and md->currentSettings().doNull) + v -= md->getZ8() * md->currentSettings().cc; + double Sigma = computeRMS(ndx,v) * outputLambda/md->currentSettings().lambda; if (ndx == 8) { spherical << QPointF(row,Sigma); @@ -294,9 +294,9 @@ void wftStats::computeWftRunningAvg( QVector wavefronts, int ndx){ cv::Mat avg = sum/(j+1); cv::Scalar mean,std; cv::meanStdDev(resized,mean,std,mask); - double stdi = std.val[0]* md->lambda/outputLambda; + double stdi = std.val[0]* md->currentSettings().lambda/outputLambda; cv::meanStdDev(avg,mean,std,mask); - avgPoints << QPointF(j,std.val[0] * md->lambda/outputLambda); + avgPoints << QPointF(j,std.val[0] * md->currentSettings().lambda/outputLambda); wftPoints << QPointF(j,stdi); trueNdx << i; } diff --git a/zernikedlg.cpp b/zernikedlg.cpp index b95416b4..4533089d 100644 --- a/zernikedlg.cpp +++ b/zernikedlg.cpp @@ -119,8 +119,8 @@ QVariant ZernTableModel::data(const QModelIndex &index, int role) const } mirrorDlg &md = *mirrorDlg::get_Instance(); - if (index.row() == 8 && md.doNull && !m_nulled){ - double val = values[8] - md.z8 * md.cc; + if (index.row() == 8 && md.currentSettings().doNull && !m_nulled){ + double val = values[8] - md.getZ8() * md.currentSettings().cc; return QString("%1 %2").arg(val, 6, 'f', 3).arg( computeRMS(8, val), 6, 'f', 3); } diff --git a/zernikeprocess.cpp b/zernikeprocess.cpp index d6ea4a52..49a7535a 100644 --- a/zernikeprocess.cpp +++ b/zernikeprocess.cpp @@ -381,7 +381,7 @@ void zernikeProcess::unwrap_to_zernikes(wavefront &wf, int zterms){ // if annular zernikes needed then do this instead of all the other stuff below this. mirrorDlg *md = mirrorDlg::get_Instance(); - if (md->m_useAnnular) { + if (md->currentSettings().useAnnulus) { initGrid(wf, 12); ZernFitWavefront(wf); @@ -484,19 +484,19 @@ void zernikeProcess::unwrap_to_zernikes(wavefront &wf, int zterms){ } cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns, std::vector enables, - int start_term, int last_term) + int start_term, int last_term, bool applyNull) { int nx = wf.data.cols; cv::Mat unwrapped = wf.data.clone(); - double scz8 = md->z8 * md->cc; - mirrorDlg *md = mirrorDlg::get_Instance(); + + double scz8 = md->getZ8() * md->currentSettings().cc; - if (!md->doNull || !wf.useSANull){ + if (!applyNull || !md->currentSettings().doNull || !wf.useSANull){ scz8 = 0.; } double midx = wf.m_outside.m_center.rx(); @@ -524,7 +524,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns, // make a list of points on the surface containing their rho and theta values as well as their // row column indexes in the matix that contanis the wave front. // annular wave fronts already have this made elsewhere. - if (!md->m_useAnnular){ + if (!md->currentSettings().useAnnulus){ m_rhoTheta = rhotheta(nx ,wf.m_outside.m_radius, midx,midy, &wf); if (m_lastusedAnnulus) m_needsInit=true; @@ -541,7 +541,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns, rho = m_rhoTheta.row(0)(i); theta = m_rhoTheta.row(1)(i); - if (!md->m_useAnnular){ + if (!md->currentSettings().useAnnulus){ zpolar = new zernikePolar(rho,theta, Z_TERMS); } @@ -550,8 +550,8 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns, if (last_term > 7) { - if (md->doNull && enables[8]){ - if (!md->m_useAnnular) + if (md->currentSettings().doNull && enables[8]){ + if (!md->currentSettings().useAnnulus) nz -= scz8 * zpolar->zernike(8); else { nz -= scz8 * m_zerns(i, 8); @@ -562,7 +562,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns, for (int z = start_term; z < Z_TERMS; ++z) { if ((z == 3) && doDefocus){ - if (!md->m_useAnnular) { + if (!md->currentSettings().useAnnulus) { nz += defocus * zpolar->zernike(z); nz -= zerns[z] * zpolar->zernike(z); } @@ -572,7 +572,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns, } } else if (!enables[z]){ - if (!md->m_useAnnular) { + if (!md->currentSettings().useAnnulus) { nz -= zerns[z] * zpolar->zernike(z); } else { @@ -581,7 +581,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns, } } - if (!md->m_useAnnular){ + if (!md->currentSettings().useAnnulus){ delete zpolar; } @@ -597,7 +597,7 @@ void zernikeProcess::fillVoid(wavefront &wf){ double ux,uy; double rho,theta; mirrorDlg *md = mirrorDlg::get_Instance(); - bool useannular = md->m_useAnnular; + bool useannular = md->currentSettings().useAnnulus; if (wf.regions.size() > 0){ int x = wf.regions[0][0].x; @@ -667,7 +667,7 @@ void zernikeProcess::fillVoid(wavefront &wf){ arma::rowvec r(rhov),t(thetav); // now that we have the points in rho and theta get the zernike terms at each of those points - arma::mat zerns = zapm( r.as_col(), t.as_col(), md->m_annularObsPercent, 12); + arma::mat zerns = zapm( r.as_col(), t.as_col(), md->currentSettings().annulusPercent, 12); // compute the surface at each point by using the zernike poly at each point. for (arma::uword i = 0; i < r.size(); ++i){ double S1 = 0.0; @@ -748,7 +748,7 @@ void zernikeProcess::fillVoid(wavefront &wf){ arma::rowvec r(rhov),t(thetav); // now that we have the points in rho and theta get the zernike terms at each of those points - arma::mat zerns = zapm( r.as_col(), t.as_col(), md->m_annularObsPercent, 12); + arma::mat zerns = zapm( r.as_col(), t.as_col(), md->currentSettings().annulusPercent, 12); // compute the surface at each point by using the zernike poly at each point. for (arma::uword i = 0; i < r.size(); ++i){ double S1 = 0.0; @@ -875,7 +875,7 @@ cv::Mat zernikeProcess::makeSurfaceFromZerns(int border, bool doColor){ mirrorDlg *md = mirrorDlg::get_Instance(); double r,g,b; - spectral_color(r,g,b, md->lambda); + spectral_color(r,g,b, md->currentSettings().lambda); if (doColor) { result = cv::Vec4f(0.,125. * .5 * g, 125 * r, 125. * b); } @@ -914,9 +914,9 @@ cv::Mat zernikeProcess::makeSurfaceFromZerns(int border, bool doColor){ for (unsigned int z = 0; z < m_zerns.n_cols; ++z){ double val = dlg.zernikes[z]; if (z == 8){ - val = (dlg.doCorrection && md->doNull) ? md->cc * md->z8 * val * .01 : val; + val = (dlg.doCorrection && md->currentSettings().doNull) ? md->currentSettings().cc * md->getZ8() * val * .01 : val; } - S1 += val * m_zerns(i,z)/((doColor) ? md->fringeSpacing: 1.); + S1 += val * m_zerns(i,z)/((doColor) ? md->currentSettings().fringeSpacing: 1.); int x = m_col[i]; int y = m_row[i]; @@ -948,8 +948,8 @@ arma::mat zernikeProcess::rhotheta( int width, double radius, double cx, double bool useMask = false; double centerR = 0.0; mirrorDlg *md = mirrorDlg::get_Instance(); - if (md->m_useAnnular){ - centerR = md->m_annularObsPercent; + if (md->currentSettings().useAnnulus){ + centerR = md->currentSettings().annulusPercent; } if (wf != 0){ useMask = true; @@ -1079,8 +1079,8 @@ void zernikeProcess::initGrid(int width, double radius, double cx, double cy, in double obsPercent = 0.; bool shouldUseAnnulus = false; mirrorDlg *md = mirrorDlg::get_Instance(); - if (md->m_useAnnular){ - obsPercent = md->m_annularObsPercent; + if (md->currentSettings().useAnnulus){ + obsPercent = md->currentSettings().annulusPercent; shouldUseAnnulus = true; } diff --git a/zernikeprocess.h b/zernikeprocess.h index f01d570f..f7fd3183 100644 --- a/zernikeprocess.h +++ b/zernikeprocess.h @@ -55,7 +55,7 @@ class zernikeProcess : public QObject explicit zernikeProcess(QObject *parent = 0); static zernikeProcess *get_Instance(); void unwrap_to_zernikes(wavefront &wf, int zterms = Z_TERMS); - cv::Mat null_unwrapped(wavefront&wf, std::vector zerns, std::vector enables,int start_term =0, int last_term = Z_TERMS); + cv::Mat null_unwrapped(wavefront&wf, std::vector zerns, std::vector enables, int start_term = 0, int last_term = Z_TERMS, bool applyNull = true); std::vector ZernFitWavefront( wavefront &wf); void initGrid(wavefront &wf, int maxOrder); void initGrid(int width, double radius, double cx, double cy, int maxOrder, double inside = 0);
Term
WyantRMS