Skip to content

Commit

Permalink
Merge pull request #11 from nanthony21/dev
Browse files Browse the repository at this point in the history
Allow OPD filtering in GUI
  • Loading branch information
nanthony21 authored Dec 17, 2021
2 parents 095a4cd + 78731b6 commit 4ce7fc3
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 21 deletions.
4 changes: 2 additions & 2 deletions conda.recipe/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ build:

requirements:
build:
- python >=3.7
- python >=3.7,<3.10 # In python 3.10 a change occurred so that PyQt no longer implicitly converts float to int. causees crashes.
- setuptools
- setuptools_scm

Expand All @@ -32,7 +32,7 @@ requirements:
- google-auth-httplib2
- google-auth-oauthlib
- pyqt =5
- pwspy >=0.2.12 # Core pws package, available on backmanlab anaconda cloud account.
- pwspy >=0.2.13 # Core pws package, available on backmanlab anaconda cloud account.
- mpl_qt_viz >1.0.9 # Plotting package available on PyPi and the backmanlab anaconda cloud account and conda-forge. Written for this project by Nick Anthony
- descartes
- cachetools >=4
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
author='Nick Anthony',
author_email='[email protected]',
url='https://github.com/nanthony21/pwspy_gui',
python_requires='>=3.7',
python_requires='>=3.7,<3.10', # In python 3.10 a chnage occured which means that PyQt no longer implicitly converts float to int. Causes crashes.
install_requires=['numpy',
'matplotlib',
'psutil',
Expand All @@ -46,7 +46,7 @@
'google-auth-httplib2',
'google-auth-oauthlib',
'PyQt5',
'pwspy>=0.2.12', # Core pws package, available on backmanlab anaconda cloud account.
'pwspy>=0.2.13', # Core pws package, available on backmanlab anaconda cloud account.
'mpl_qt_viz>1.0.9', # Plotting package available on PyPi and the backmanlab anaconda cloud account. Written for this project by Nick Anthony
'descartes',
'cachetools>=4'],
Expand Down
2 changes: 2 additions & 0 deletions src/pwspy_gui/ExtraReflectanceCreator/ERWorkFlow.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ def save(self, includeSettings: t_.List[str], binning: int, parallelProcessing:
title=str(matCombo)
)
logger = logging.getLogger(__name__)
erCube.data[np.isnan(erCube.data)] = 0 # Somehow a nan can still get through. This will mess everything up.
erCube.data[erCube.data < 0] = 0
logger.info(f"Final data max is {erCube.data.max()}")
logger.info(f"Final data min is {erCube.data.min()}")
self.figs.append(dock) # keep track of opened figures.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ def cropStateChanged(state: bool):
self.polySub = QGroupBox("Polynomial Subtraction")
self.polySub.setFixedSize(150, 50)
self.polySub.setToolTip("A polynomial is fit to each spectrum and then it is subtracted from the spectrum."
"This is so that we remove effects of absorbtion and our final signal is only due to interference")
"This is so that we remove effects of absorbtion and our final signal is only due to interference"
"For liquid covered samples this is always set to 0. For samples in air a 2nd order polynomial is used.")
layout = QGridLayout()
layout.setContentsMargins(5, 1, 5, 5)
_ = layout.addWidget
Expand All @@ -179,8 +180,30 @@ def cropStateChanged(state: bool):
_(self.polynomialOrder, 0, 1, 1, 1)
self.polySub.setLayout(layout)
self._layout.addWidget(self.polySub, row, 0, 1, 2)

# WaveNumber Filtering
self.waveNumberCutoff = QHDoubleSpinBox()
self.waveNumberCutoff.setValue(4.3) # OPD = estimated depth * 2(roundtrip) * 1.37 (RI of cell). DOF=1.1um -> OPD = 2.95. To achieve 5% attenuation at 2.95um a 3dB cutoff of 4.3 is selected (4th-order butterworth)
self.cutoffWaveNumber = QCheckBox("Perform Filtering")
self.cutoffWaveNumber.stateChanged.connect(lambda state: self.waveNumberCutoff.setEnabled(state != QtCore.Qt.Unchecked))
self.cutoffWaveNumber.setCheckState(QtCore.Qt.Checked)
self.cutoffWaveNumber.setCheckState(QtCore.Qt.Unchecked) # Default to off

layout = QGridLayout()
layout.setContentsMargins(5, 1, 5, 5)

layout.addWidget(self.cutoffWaveNumber, 0, 0, 1, 2)
layout.addWidget(QLabel("OPD Cutoff (um)"), 1, 0, 1, 1)
layout.addWidget(self.waveNumberCutoff, 1, 1, 1, 1)
wnFilter = QGroupBox("OPD Filtering")
wnFilter.setLayout(layout)
wnFilter.setToolTip("A 4th order buttersworth filter will be applied to the spectra (x axis: wavenumber) at the specified cutoff frequency."
"The cutoff is the frequency at which the attenuation will be -3dB. After the cutoff the attenuation slope will be 80dB per decade.")
self._layout.addWidget(wnFilter, row, 2, 1, 2)

row += 1


'''Advanced Calculations'''
self.advanced = CollapsibleSection('Skip Advanced Analysis', 200, self)
self.advanced.stateChanged.connect(self._updateSize)
Expand Down Expand Up @@ -235,6 +258,11 @@ def loadFromSettings(self, settings: PWSAnalysisSettings):
self.minSubCheckBox.setCheckState(2 if settings.autoCorrMinSub else 0)
self.relativeUnits.setCheckState(2 if settings.relativeUnits else 0)
self.hardwareCorrections.loadCameraCorrection(settings.cameraCorrection)
if settings.waveNumberCutoff is None:
self.cutoffWaveNumber.setCheckState(QtCore.Qt.Unchecked)
else:
self.cutoffWaveNumber.setCheckState(QtCore.Qt.Checked)
self.waveNumberCutoff.setValue(settings.waveNumberCutoff)

def getSettings(self) -> PWSRuntimeAnalysisSettings:
erMetadata, refMaterial, numericalAperture = self.extraReflection.getSettings()
Expand Down Expand Up @@ -268,7 +296,8 @@ def getSettings(self) -> PWSRuntimeAnalysisSettings:
numericalAperture=numericalAperture,
relativeUnits=self.relativeUnits.checkState() != 0,
cameraCorrection=self.hardwareCorrections.getCameraCorrection(),
extraReflectanceId=erMetadata.idTag if erMetadata is not None else None),
extraReflectanceId=erMetadata.idTag if erMetadata is not None else None,
waveNumberCutoff=self.waveNumberCutoff.value() if self.cutoffWaveNumber.checkState != QtCore.Qt.Unchecked else None),
extraReflectanceMetadata=erMetadata,
referenceMetadata=refMeta,
cellMetadata=cellMeta,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@

from __future__ import annotations
import os
from typing import Optional, Tuple

import typing as t_
from PyQt5 import QtGui, QtCore
from PyQt5.QtGui import QPalette, QValidator, QDoubleValidator
from PyQt5.QtWidgets import QGroupBox, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QHBoxLayout, QMessageBox, QGridLayout, QSpinBox, QDoubleSpinBox, \
Expand All @@ -28,8 +27,7 @@
from pwspy_gui.PWSAnalysisApp.sharedWidgets import CollapsibleSection
from pwspy.dataTypes import CameraCorrection, ERMetaData
from pwspy.utility.reflection import reflectanceHelper, Material
import typing
if typing.TYPE_CHECKING:
if t_.TYPE_CHECKING:
from pwspy_gui.sharedWidgets.extraReflectionManager import ERManager


Expand Down Expand Up @@ -83,7 +81,7 @@ def __init__(self, parent: QWidget, erManager: ERManager):
layout.addLayout(rLayout)
self.setLayout(layout)

def getSettings(self) -> Tuple[ERMetaData, Material, float]:
def getSettings(self) -> t_.Tuple[ERMetaData, Material, float]:
self._initializeERSelector()
if self.ERExplorer.getSelectedMetadata() is None:
ans = QMessageBox.question(self, "Uh", "An extra reflectance cube has not been selected. Do you want to ignore this important correction?")
Expand All @@ -98,7 +96,7 @@ def getSettings(self) -> Tuple[ERMetaData, Material, float]:
refMaterial = Material[self.refMaterialCombo.currentText()]
return erMd, refMaterial, numericalAperture

def getSelectedERMetadata(self) -> Optional[ERMetaData]:
def getSelectedERMetadata(self) -> t_.Optional[ERMetaData]:
return self.ERExplorer.getSelectedMetadata()

def loadFromSettings(self, numericalAperture: float, referenceMaterial: Material, extraReflectanceId: str):
Expand All @@ -123,7 +121,7 @@ def _initializeERSelector(self):
if self.ERExplorer is None: # Don't initialize the ERSelector window until we actually need it. It can be slow to initiate
self.ERExplorer = self._erManager.createSelectorWindow(self)

def extraReflectionChanged(md: Optional[ERMetaData]):
def extraReflectionChanged(md: t_.Optional[ERMetaData]):
if md is None:
self.RSubtractionNameLabel.setText('None')
else:
Expand Down Expand Up @@ -177,7 +175,7 @@ def getCameraCorrection(self) -> CameraCorrection:
cameraCorrection = None
return cameraCorrection

def loadCameraCorrection(self, camCorr: Optional[CameraCorrection] = None):
def loadCameraCorrection(self, camCorr: t_.Optional[CameraCorrection] = None):
if camCorr is None: #Automatic camera corrections
self.setCheckState(2)
else:
Expand Down Expand Up @@ -234,9 +232,9 @@ def wheelEvent(self, event):
return HumbleDoubleSpinBox


QHSpinBox = humble(QSpinBox)
QHDoubleSpinBox = humble(QDoubleSpinBox)
QHComboBox = humble(QComboBox)
QHSpinBox: t_.Type[QSpinBox] = humble(QSpinBox)
QHDoubleSpinBox: t_.Type[QDoubleSpinBox] = humble(QDoubleSpinBox)
QHComboBox: t_.Type[QComboBox] = humble(QComboBox)


class VerticallyCompressedWidget(QWidget):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ def isChecked(self) -> bool:
class ERSelectorWindow(QDialog):
selectionChanged = QtCore.pyqtSignal(object) #Usually an ERMetaData object, sometimes None

# noinspection PyUnresolvedReferences
def __init__(self, manager: ERManager, parent: Optional[QWidget] = None):
self._manager = manager
self._plots = [] # Use this to maintain references to plots
self._selectedMetadata: Optional[pwsdt.ERMetaData] = None
super().__init__(parent)
self.setModal(False)
Expand Down Expand Up @@ -154,7 +154,7 @@ def displayInfo(self, item: ERTreeWidgetItem):

def _plot3dData(self, widgetItem):
er = pwsdt.ExtraReflectanceCube.fromHdfFile(self._manager._directory, widgetItem.name)
PlotNd(er.data, indices=[range(er.data.shape[0]), range(er.data.shape[1]), er.wavelengths])
self._plots.append(PlotNd(er.data, indices=[range(er.data.shape[0]), range(er.data.shape[1]), er.wavelengths]))

def _downloadCheckedItems(self):
try :
Expand Down
4 changes: 2 additions & 2 deletions src/pwspy_gui/sharedWidgets/utilityWidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ def _resize(self, width, height):
newWidth = height * self._aspect #the ideal width based on the new commanded height
#Now determine which of the new dimensions to use.
if width > newWidth:
self.setMaximumWidth(newWidth)
self.setMaximumWidth(int(newWidth))
self.setMaximumHeight(QWIDGETSIZE_MAX)
else:
self.setMaximumHeight(newHeight)
self.setMaximumHeight(int(newHeight))
self.setMaximumWidth(QWIDGETSIZE_MAX)

def setAspect(self, aspect: float):
Expand Down

0 comments on commit 4ce7fc3

Please sign in to comment.