Commit 3ea53e47 authored by Josef Brandt's avatar Josef Brandt

RandomBoxSampling

Also Quarter RandomBoxSampling
parent c070f4ab
......@@ -43,6 +43,7 @@ def get_methods_to_test(dataset: dataset.DataSet, fractions: list = []) -> list:
boxCreator: gmeth.BoxSelectionCreator = gmeth.BoxSelectionCreator(dataset)
methods += boxCreator.get_crossBoxSubsamplers_for_fraction(fraction)
methods += boxCreator.get_spiralBoxSubsamplers_for_fraction(fraction)
methods += boxCreator.get_randomBoxSubsamplers_for_fraction(fraction)
# methods.append(cmeth.ChemometricSubsampling(particleContainer, fraction))
return methods
......
This diff is collapsed.
......@@ -4,7 +4,7 @@ sys.path.append("C://Users//xbrjos//Desktop//Python")
import gepard
from gepard import dataset
from gui.filterView import FilterView
from gui.measureModes import MeasureMode, CrossBoxMode, CrossBoxesControls, SpiralBoxMode
from gui.measureModes import *
import helpers
from evaluation import SubsamplingResult
......@@ -55,10 +55,17 @@ class MainView(QtWidgets.QWidget):
self._switch_to_default_mode()
def _add_measure_modes(self) -> None:
self.measureModes['spiralSelection'] = SpiralBoxMode(self.filterView)
self.measureModes['crossSelection'] = CrossBoxMode(self.filterView)
self.modeSelector.addItem('spiralSelection')
self.modeSelector.addItem('crossSelection')
self.measureModes['Random Particle Selection'] = RandomMeasureMode(self.filterView)
self.measureModes['Spiral Box Selection'] = SpiralBoxMode(self.filterView)
self.measureModes['Cross Box Selection'] = CrossBoxMode(self.filterView)
self.measureModes['Random Box Selection'] = RandomBoxMode(self.filterView)
self.measureModes['Quarter Random Box Selection'] = QuarterRandomBoxMode(self.filterView)
self.modeSelector.addItem('Random Particle Selection')
self.modeSelector.addItem('Spiral Box Selection')
self.modeSelector.addItem('Cross Box Selection')
self.modeSelector.addItem('Random Box Selection')
self.modeSelector.addItem('Quarter Random Box Selection')
for mode in self.measureModes.values():
mode.updatedResult.connect(self.infoWidget.update_results)
......@@ -101,8 +108,8 @@ class MainView(QtWidgets.QWidget):
self.filterView.filter.update_filterSize(width, height, diameter, (offsetx, offsety))
for mode in self.measureModes.values():
mode.boxSelectionMethod.particleContainer = dset.particleContainer
mode.boxSelectionMethod.offset = (offsetx, offsety)
mode.method.particleContainer = dset.particleContainer
mode.method.offset = (offsetx, offsety)
self.filterView.update_from_dataset(dset)
self.activeMode.update_measure_viewItems()
......
from PyQt5 import QtCore, QtWidgets
from gui.filterView import FilterView, MeasureBoxGraphItem
from geometricMethods import BoxSelectionSubsamplingMethod, CrossBoxSubSampling, SpiralBoxSubsampling
from methods import *
from geometricMethods import *
from evaluation import SubsamplingResult
class MeasureMode(QtCore.QObject):
updatedResult: QtCore.pyqtSignal = QtCore.pyqtSignal(SubsamplingResult)
def __init__(self, relatedFilterView: FilterView):
def __init__(self, relatedFilterView: FilterView) -> None:
super(MeasureMode, self).__init__()
self.filterView: FilterView = relatedFilterView
self.uiControls: QtWidgets.QGroupBox = QtWidgets.QGroupBox()
self.boxSelectionMethod: BoxSelectionSubsamplingMethod = None
self.subsamplingResult: SubsamplingResult = SubsamplingResult(self.boxSelectionMethod)
self.method: SubsamplingMethod = None
self.subsamplingResult: SubsamplingResult = SubsamplingResult(self.method)
self.subParticles: list = []
def get_control_groupBox(self) -> QtWidgets.QGroupBox:
return self.uiControls
def update_measure_viewItems(self) -> None:
raise NotImplementedError
self.method.filterDiameter = self.filterView.filter.diameter
self.method.numBoxes = self.uiControls.numBoxesSpinbox.value()
self.method.fraction = self.uiControls.coverageSpinbox.value() / 100
topLefts: list = self.method.get_topLeft_of_boxes()
boxSize = self.method.boxSize
self.filterView.update_measure_boxes(topLefts, boxSize)
self.send_measuredParticles_to_filterview()
def send_measuredParticles_to_filterview(self) -> None:
if self.boxSelectionMethod.particleContainer is not None:
subParticles = self.boxSelectionMethod.apply_subsampling_method()
self.subsamplingResult.method = self.boxSelectionMethod
if self.method.particleContainer is not None:
subParticles = self.method.apply_subsampling_method()
self.subsamplingResult.method = self.method
self.subsamplingResult.reset_results()
self.subsamplingResult.add_result(self.boxSelectionMethod.particleContainer.particles, subParticles)
self.subsamplingResult.add_result(self.method.particleContainer.particles, subParticles)
self.updatedResult.emit(self.subsamplingResult)
self.filterView.update_measured_particles(subParticles)
class RandomMeasureMode(MeasureMode):
updatedResult: QtCore.pyqtSignal = QtCore.pyqtSignal(SubsamplingResult)
def __init__(self, filterView: FilterView):
super(RandomMeasureMode, self).__init__(filterView)
self.method: RandomSampling = RandomSampling(None)
self.uiControls = ParticleModeControlGroup(self, 'Random Particle Measurement')
def update_measure_viewItems(self) -> None:
self.method.fraction = self.uiControls.coverageSpinbox.value() / 100
self.filterView.update_measure_boxes([], 0.0)
self.send_measuredParticles_to_filterview()
class ParticleModeControlGroup(QtWidgets.QGroupBox):
def __init__(self, measureModeParent: MeasureMode, title: str) -> None:
super(ParticleModeControlGroup, self).__init__()
self.measureModeParent = measureModeParent
self.setTitle(title)
layout = QtWidgets.QHBoxLayout()
self.setLayout(layout)
layout.addWidget(QtWidgets.QLabel('Desired Coverage (%)'))
self.coverageSpinbox = QtWidgets.QSpinBox()
self.coverageSpinbox.setFixedWidth(50)
self.coverageSpinbox.setMinimum(0)
self.coverageSpinbox.setMaximum(100)
self.coverageSpinbox.setValue(10)
self.coverageSpinbox.valueChanged.connect(self._config_changed)
layout.addWidget(self.coverageSpinbox)
def _config_changed(self) -> None:
self.measureModeParent.update_measure_viewItems()
class CrossBoxMode(MeasureMode):
def __init__(self, *args):
super(CrossBoxMode, self).__init__(*args)
self.uiControls = CrossBoxesControls(self)
self.boxSelectionMethod: CrossBoxSubSampling = CrossBoxSubSampling(None)
self.method: CrossBoxSubSampling = CrossBoxSubSampling(None)
self.update_measure_viewItems()
def update_measure_viewItems(self) -> None:
self.boxSelectionMethod.filterDiameter = self.filterView.filter.diameter
self.boxSelectionMethod.numBoxesAcross = int(self.uiControls.numBoxesSelector.currentText())
self.method.filterDiameter = self.filterView.filter.diameter
self.method.numBoxesAcross = int(self.uiControls.numBoxesSelector.currentText())
desiredCoverage: int = self.uiControls.coverageSpinbox.value()
maxCoverage: int = int(self.boxSelectionMethod.get_maximum_achievable_fraction() * 100)
maxCoverage: int = int(self.method.get_maximum_achievable_fraction() * 100)
self.uiControls.set_to_max_possible_coverage(maxCoverage)
if desiredCoverage > maxCoverage:
desiredCoverage = maxCoverage
self.boxSelectionMethod.fraction = desiredCoverage / 100
self.method.fraction = desiredCoverage / 100
topLefts: list = self.boxSelectionMethod.get_topLeft_of_boxes()
boxSize = self.boxSelectionMethod.boxSize
topLefts: list = self.method.get_topLeft_of_boxes()
boxSize = self.method.boxSize
self.filterView.update_measure_boxes(topLefts, boxSize)
self.send_measuredParticles_to_filterview()
......@@ -96,33 +141,14 @@ class CrossBoxesControls(QtWidgets.QGroupBox):
self.coverageSpinbox.valueChanged.connect(self._config_changed)
class SpiralBoxMode(MeasureMode):
def __init__(self, *args):
super(SpiralBoxMode, self).__init__(*args)
self.uiControls: SpiralBoxControls = SpiralBoxControls(self)
self.boxSelectionMethod: SpiralBoxSubsampling = SpiralBoxSubsampling(None)
self.update_measure_viewItems()
def update_measure_viewItems(self) -> None:
self.boxSelectionMethod.filterDiameter = self.filterView.filter.diameter
self.boxSelectionMethod.numBoxes = self.uiControls.numBoxesSpinbox.value()
self.boxSelectionMethod.fraction = self.uiControls.coverageSpinbox.value() / 100
topLefts: list = self.boxSelectionMethod.get_topLeft_of_boxes()
boxSize = self.boxSelectionMethod.boxSize
self.filterView.update_measure_boxes(topLefts, boxSize)
self.send_measuredParticles_to_filterview()
class SpiralBoxControls(QtWidgets.QGroupBox):
class BoxControlGroup(QtWidgets.QGroupBox):
"""
Gives a groupbox with the controls for setting up the cross boxes.
"""
def __init__(self, measureModeParent: MeasureMode):
super(SpiralBoxControls, self).__init__()
self.setTitle('Spiral Box Controls')
def __init__(self, measureModeParent: MeasureMode, title: str) -> None:
super(BoxControlGroup, self).__init__()
self.setTitle(title)
self.measureModeParent = measureModeParent
layout = QtWidgets.QHBoxLayout()
self.setLayout(layout)
......@@ -144,6 +170,46 @@ class SpiralBoxControls(QtWidgets.QGroupBox):
self.coverageSpinbox.valueChanged.connect(self._config_changed)
layout.addWidget(self.coverageSpinbox)
def _config_changed(self):
def _config_changed(self) -> None:
if self.numBoxesSpinbox.value() > 0:
numBoxes: int = self.numBoxesSpinbox.value()
self.measureModeParent.method.numBoxes = numBoxes
maxCoverage: float = self.measureModeParent.method.get_maximum_achievable_fraction()
self.set_to_max_possible_coverage(round(maxCoverage * 100))
self.measureModeParent.update_measure_viewItems()
def set_to_max_possible_coverage(self, maxCoverage: int) -> None:
"""
Adjusts maximum of coverage spinbox and, if necessary, caps the current value.
:param maxCoverage: the maximum pssible converage IN PERCENT!!
:return:
"""
self.coverageSpinbox.setMaximum(maxCoverage)
if maxCoverage < self.coverageSpinbox.value():
self.coverageSpinbox.valueChanged.disconnect()
self.coverageSpinbox.setValue(maxCoverage)
self.coverageSpinbox.valueChanged.connect(self._config_changed)
class SpiralBoxMode(MeasureMode):
def __init__(self, *args):
super(SpiralBoxMode, self).__init__(*args)
self.uiControls: BoxControlGroup = BoxControlGroup(self, 'Spiral Box Controls')
self.method: SpiralBoxSubsampling = SpiralBoxSubsampling(None)
self.update_measure_viewItems()
class RandomBoxMode(MeasureMode):
def __init__(self, *args):
super(RandomBoxMode, self).__init__(*args)
self.uiControls: BoxControlGroup = BoxControlGroup(self, 'Random Box Controls')
self.method: RandomBoxSampling = RandomBoxSampling(None)
self.update_measure_viewItems()
class QuarterRandomBoxMode(MeasureMode):
def __init__(self, *args):
super(QuarterRandomBoxMode, self).__init__(*args)
self.uiControls: BoxControlGroup = BoxControlGroup(self, 'Quarter Random Box Controls')
self.method: RandomQuarterBoxes = RandomQuarterBoxes(None)
self.update_measure_viewItems()
......@@ -11,6 +11,8 @@ from helpers import ParticleBinSorter
class SubsamplingMethod(object):
randomSeed = 15203018
def __init__(self, particleConatainer, desiredFraction: float = 0.2):
super(SubsamplingMethod, self).__init__()
self.particleContainer = particleConatainer
......@@ -65,6 +67,14 @@ class SubsamplingMethod(object):
matches = (self.label.lower().find(pattern.lower()) != -1)
return matches
def config_is_valid(self) -> bool:
isValid: bool = False
if self.fraction <= self.get_maximum_achievable_fraction():
isValid = True
return isValid
def get_maximum_achievable_fraction(self) -> float:
raise NotImplementedError
class RandomSampling(SubsamplingMethod):
@property
......@@ -82,6 +92,9 @@ class RandomSampling(SubsamplingMethod):
def equals(self, otherMethod) -> bool:
return type(otherMethod) == type(self) and otherMethod.fraction == self.fraction
def get_maximum_achievable_fraction(self) -> float:
return 1.0
class SizeBinFractioning(SubsamplingMethod):
......@@ -117,3 +130,6 @@ class SizeBinFractioning(SubsamplingMethod):
def equals(self, otherMethod) -> bool:
return type(otherMethod) == type(self) and otherMethod.fraction == self.fraction
def get_maximum_achievable_fraction(self) -> float:
return 1.0
\ No newline at end of file
......@@ -28,3 +28,4 @@ def get_default_ParticleContainer() -> ParticleContainer:
contours.append(np.array([[[x, 0]], [[x+10, 0]], [[x+10, 10]], [[x, 10]]], dtype=np.int32))
particleContainer.setParticleContours(contours)
return particleContainer
......@@ -258,14 +258,18 @@ class TestSampleResult(unittest.TestCase):
possibleRandomMethods = 2
possibleCrossBoxMethods = 2
possibleSpiralBoxMethods = 3
possibleRandomBoxMethods = 3
possibleChemometricMethods = 0
totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \
possibleSpiralBoxMethods + possibleChemometricMethods
possibleSpiralBoxMethods + possibleChemometricMethods + \
possibleRandomBoxMethods
self.assertEqual(len(methods), totalPossible)
self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction)))
self.assertTrue(containsMethod(methods, gmeth.CrossBoxSubSampling(dset, desiredFraction)))
self.assertTrue(containsMethod(methods, gmeth.SpiralBoxSubsampling(dset, desiredFraction)))
self.assertTrue(containsMethod(methods, gmeth.RandomBoxSampling(dset, desiredFraction)))
desiredFraction = 0.5
methods = get_methods_to_test(dset, [desiredFraction])
......@@ -273,8 +277,10 @@ class TestSampleResult(unittest.TestCase):
possibleCrossBoxMethods = 1
possibleSpiralBoxMethods = 0
possibleChemometricMethods = 0
possibleRandomBoxMethods = 0
totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \
possibleSpiralBoxMethods + possibleChemometricMethods
possibleSpiralBoxMethods + possibleChemometricMethods + \
possibleRandomBoxMethods
self.assertEqual(len(methods), totalPossible)
self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction)))
......@@ -286,9 +292,11 @@ class TestSampleResult(unittest.TestCase):
possibleRandomMethods = 2
possibleCrossBoxMethods = 0
possibleSpiralBoxMethods = 0
possibleRandomBoxMethods = 0
possibleChemometricMethods = 0
totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \
possibleSpiralBoxMethods + possibleChemometricMethods
possibleSpiralBoxMethods + possibleChemometricMethods + \
possibleRandomBoxMethods
self.assertEqual(len(methods), totalPossible)
self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction)))
......@@ -301,8 +309,10 @@ class TestSampleResult(unittest.TestCase):
possibleCrossBoxMethods = 3
possibleSpiralBoxMethods = 3
possibleChemometricMethods = 0
possibleRandomBoxMethods = 3
totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \
possibleSpiralBoxMethods + possibleChemometricMethods
possibleSpiralBoxMethods + possibleChemometricMethods + \
possibleRandomBoxMethods
self.assertEqual(len(methods), totalPossible)
for desiredFraction in desiredFractions:
self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
......@@ -492,6 +502,7 @@ class TestSubsamplingResult(unittest.TestCase):
return nonMPParticles
def _get_MP_particle(self) -> Particle:
random.seed(15203018)
polymerNames = ['Poly (methyl methacrylate',
'Polyethylene',
'Silicone rubber',
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment