...
 
Commits (5)
import numpy as np
cimport numpy as np
cimport numpy.random
cimport cython
DTYPE = np.float
ctypedef np.int32_t INT32_t
cdef get_random_topleft(double maxDist, double maxAngle, double radius, double boxSize):
cdef double angle, dist, x, y
cdef np.ndarray[INT32_t, ndim=1] newTopLeft
dist = np.random.rand() * maxDist
angle = np.random.rand() * maxAngle
newTopLeft = np.empty(2, dtype=np.int32)
x = dist*np.cos(angle) + radius - boxSize/2
y = dist*np.sin(angle) + radius - boxSize/2
newTopLeft[0] = np.int32(np.round(x))
newTopLeft[1] = np.int32(np.round(y))
return newTopLeft
def get_random_topLefts(int numBoxes, double boxSize, double radius, double maxAngle, int seed=1337, int maxTries=50):
cdef np.ndarray[INT32_t, ndim=2] topLefts
cdef np.ndarray[INT32_t, ndim=1] newTopLeft
cdef double maxDist
cdef int outerCounter, counter, x, y, i, j, diffX, diffY, successfullyAdded
cdef bint validSolutionFound, boxOverlaps
np.random.seed(seed)
maxDist = radius - np.sqrt((boxSize/2)**2 + (boxSize/2)**2)
outerCounter = 0
validSolutionFound = False
while not validSolutionFound and outerCounter < maxTries:
successfullyAdded = 0
topLefts = np.empty((numBoxes, 2), dtype=np.int32)
for i in range(numBoxes):
if i == 0:
topLefts[0, :] = get_random_topleft(maxDist, maxAngle, radius, boxSize)
successfullyAdded += 1
else:
counter = 0
while counter < 50:
newTopLeft = get_random_topleft(maxDist, maxAngle, radius, boxSize)
boxOverlaps = False
for j in range(i):
diffX = abs(np.float(newTopLeft[0] - np.float(topLefts[j, 0])))
diffY = abs(np.float(newTopLeft[1] - np.float(topLefts[j, 1])))
if diffX < boxSize and diffY < boxSize:
boxOverlaps = True
break
if boxOverlaps:
counter += 1
else:
topLefts[i, :] = newTopLeft
successfullyAdded += 1
break
if successfullyAdded == numBoxes:
validSolutionFound = True
else:
outerCounter += 1
return validSolutionFound, topLefts
\ No newline at end of file
...@@ -9,10 +9,18 @@ if len(sys.argv) == 1: ...@@ -9,10 +9,18 @@ if len(sys.argv) == 1:
sys.argv.append("build_ext") sys.argv.append("build_ext")
sys.argv.append("--inplace") sys.argv.append("--inplace")
ext = Extension("rotateContour", ["rotateContour.pyx"], extra_compile_args=['-O3'],) # ext = Extension("rotateContour", ["rotateContour.pyx"], extra_compile_args=['-O3'],)
# setup(
# name="rotate contour around reference point",
# ext_modules=cythonize([ext], annotate=True), # accepts a glob pattern
# include_dirs=[np.get_include()]
# )
# ext = Extension("getRandomTopLefts", ["getRandomTopLefts.pyx"], extra_compile_args=['-O3'],)
setup( setup(
name="rotate contour around reference point", name="get a given number of random topLefts",
ext_modules=cythonize([ext], annotate=True), # accepts a glob pattern ext_modules=cythonize("randoms.pyx", annotate=True), # accepts a glob pattern
include_dirs=[np.get_include()] include_dirs=[np.get_include()]
) )
\ No newline at end of file
...@@ -5,7 +5,7 @@ sys.path.append("C://Users//xbrjos//Desktop//Python") ...@@ -5,7 +5,7 @@ sys.path.append("C://Users//xbrjos//Desktop//Python")
from gepard import dataset from gepard import dataset
from gepard.analysis.particleContainer import ParticleContainer from gepard.analysis.particleContainer import ParticleContainer
from cythonModules import rotateContour from cythonModules import rotateContour
from helpers import get_filterDimensions_from_dataset, get_center_from_filter_dimensions from helpers import get_filterDimensions_from_dataset, get_center_from_filter_dimensions, convert_length_to_pixels
class ParticleVariations(object): class ParticleVariations(object):
...@@ -18,9 +18,12 @@ class ParticleVariations(object): ...@@ -18,9 +18,12 @@ class ParticleVariations(object):
def get_particleContainer_variations(self) -> ParticleContainer: def get_particleContainer_variations(self) -> ParticleContainer:
if self.numVariations > 0: if self.numVariations > 0:
offset, diameter, [width, height] = get_filterDimensions_from_dataset(self.dataset) offset, diameter, [width, height] = get_filterDimensions_from_dataset(self.dataset)
diameter: float = convert_length_to_pixels(self.dataset, diameter)
offset: tuple = convert_length_to_pixels(self.dataset, offset[0]), \
convert_length_to_pixels(self.dataset, offset[1])
center: np.ndarray = get_center_from_filter_dimensions(offset, diameter) center: np.ndarray = get_center_from_filter_dimensions(offset, diameter)
partContainer: ParticleContainer = self.origParticleContainer partContainer: ParticleContainer = self.origParticleContainer
# contours: list = partContainer.getParticleContours()
angles = self._get_angles() angles = self._get_angles()
for i in range(self.numVariations): for i in range(self.numVariations):
if i > 0: if i > 0:
......
...@@ -32,7 +32,8 @@ def get_methods_to_test(dataset: dataset.DataSet, fractions: list = []) -> list: ...@@ -32,7 +32,8 @@ def get_methods_to_test(dataset: dataset.DataSet, fractions: list = []) -> list:
:return: list of measurement Objects that are applicable :return: list of measurement Objects that are applicable
""" """
if len(fractions) == 0: if len(fractions) == 0:
fractions: list = [0.02, 0.05, 0.1, 0.2, 0.3, 0.5, 0.7, 0.9] fractions: list = [0.02, 0.05, 0.1, 0.25, 0.5, 0.7, 0.9]
# fractions: list = [0.02, 0.1, 0.5, 0.9]
methods: list = [] methods: list = []
particleContainer = dataset.particleContainer particleContainer = dataset.particleContainer
...@@ -44,6 +45,7 @@ def get_methods_to_test(dataset: dataset.DataSet, fractions: list = []) -> list: ...@@ -44,6 +45,7 @@ def get_methods_to_test(dataset: dataset.DataSet, fractions: list = []) -> list:
methods += boxCreator.get_crossBoxSubsamplers_for_fraction(fraction) methods += boxCreator.get_crossBoxSubsamplers_for_fraction(fraction)
methods += boxCreator.get_spiralBoxSubsamplers_for_fraction(fraction) methods += boxCreator.get_spiralBoxSubsamplers_for_fraction(fraction)
methods += boxCreator.get_randomBoxSubsamplers_for_fraction(fraction) methods += boxCreator.get_randomBoxSubsamplers_for_fraction(fraction)
methods += boxCreator.get_randomQuarterBoxSubsamplers_for_fraction(fraction)
# methods.append(cmeth.ChemometricSubsampling(particleContainer, fraction)) # methods.append(cmeth.ChemometricSubsampling(particleContainer, fraction))
return methods return methods
...@@ -55,6 +57,7 @@ def update_sample(sample, force: bool, index: int): ...@@ -55,6 +57,7 @@ def update_sample(sample, force: bool, index: int):
sample.update_result_with_methods(methods, force) sample.update_result_with_methods(methods, force)
return sample, index return sample, index
def is_MP_particle(particle: Particle) -> bool: def is_MP_particle(particle: Particle) -> bool:
# TODO: UPDATE PATTERNS -> ARE THESE REASONABLE??? # TODO: UPDATE PATTERNS -> ARE THESE REASONABLE???
isMP: bool = False isMP: bool = False
...@@ -197,10 +200,6 @@ class SubsamplingResult(object): ...@@ -197,10 +200,6 @@ class SubsamplingResult(object):
:param subParticles: :param subParticles:
:return: :return:
""" """
# if type(self.method) == cmeth.ChemometricSubsampling:
# print('chemometric subsamling found')
# error: float = self._get_mp_count_error(origParticles, subParticles, 1.0)
# else:
error: float = self._get_mp_count_error(origParticles, subParticles, self.method.fraction) error: float = self._get_mp_count_error(origParticles, subParticles, self.method.fraction)
self.origParticleCount = len(origParticles) self.origParticleCount = len(origParticles)
self.mpCountErrors.append(error) self.mpCountErrors.append(error)
...@@ -243,9 +242,9 @@ class SubsamplingResult(object): ...@@ -243,9 +242,9 @@ class SubsamplingResult(object):
class SampleResult(object): class SampleResult(object):
""" """
An object the actually stores all generated results per sample and can update and report on them. An object the stores all generated results per sample and can update and report on them.
""" """
def __init__(self, filepath: str, numVariations: int = 10): def __init__(self, filepath: str, numVariations: int = 5):
super(SampleResult, self).__init__() super(SampleResult, self).__init__()
self.filepath: str = filepath self.filepath: str = filepath
self.dataset: dataset.DataSet = None self.dataset: dataset.DataSet = None
...@@ -345,6 +344,3 @@ class SampleResult(object): ...@@ -345,6 +344,3 @@ class SampleResult(object):
requestedResult = result requestedResult = result
break break
return requestedResult return requestedResult
# def _get_result_of_method(self, method: meth.SubsamplingMethod) -> SubsamplingResult:
# return None
\ No newline at end of file
...@@ -6,6 +6,7 @@ import sys ...@@ -6,6 +6,7 @@ import sys
sys.path.append("C://Users//xbrjos//Desktop//Python") sys.path.append("C://Users//xbrjos//Desktop//Python")
from gepard import dataset from gepard import dataset
import helpers import helpers
from cythonModules import randoms
def box_overlaps_other_box(topLeft1: list, topLeft2: list, boxSize: float) -> bool: def box_overlaps_other_box(topLeft1: list, topLeft2: list, boxSize: float) -> bool:
...@@ -62,7 +63,6 @@ class BoxSelectionSubsamplingMethod(SubsamplingMethod): ...@@ -62,7 +63,6 @@ class BoxSelectionSubsamplingMethod(SubsamplingMethod):
for topLeftXY in sortedTopLefts: for topLeftXY in sortedTopLefts:
if helpers.box_overlaps_contour(topLeftXY, boxWidthHeight, particle.contour): if helpers.box_overlaps_contour(topLeftXY, boxWidthHeight, particle.contour):
subParticles.append(particle) subParticles.append(particle)
break
return subParticles return subParticles
...@@ -136,10 +136,7 @@ class BoxSelectionCreator(object): ...@@ -136,10 +136,7 @@ class BoxSelectionCreator(object):
:return list of CrossBoxSubsamplers: :return list of CrossBoxSubsamplers:
""" """
crossBoxSubsamplers = [] crossBoxSubsamplers = []
offset, diameter, widthHeight = helpers.get_filterDimensions_from_dataset(self.dataset) diameter, offset = self._get_diameter_and_offset()
diameter = helpers.convert_length_to_pixels(self.dataset, diameter)
offset = helpers.convert_length_to_pixels(self.dataset, offset[0]), \
helpers.convert_length_to_pixels(self.dataset, offset[1])
for numBoxesAcross in [3, 5]: for numBoxesAcross in [3, 5]:
newBoxSelector: CrossBoxSubSampling = CrossBoxSubSampling(self.dataset.particleContainer, desiredFraction) newBoxSelector: CrossBoxSubSampling = CrossBoxSubSampling(self.dataset.particleContainer, desiredFraction)
...@@ -159,10 +156,7 @@ class BoxSelectionCreator(object): ...@@ -159,10 +156,7 @@ class BoxSelectionCreator(object):
:return list of SpiralBoxSelectors: :return list of SpiralBoxSelectors:
""" """
spiralBoxSubsamplers = [] spiralBoxSubsamplers = []
offset, diameter, widthHeight = helpers.get_filterDimensions_from_dataset(self.dataset) diameter, offset = self._get_diameter_and_offset()
diameter = helpers.convert_length_to_pixels(self.dataset, diameter)
offset = helpers.convert_length_to_pixels(self.dataset, offset[0]), \
helpers.convert_length_to_pixels(self.dataset, offset[1])
for numBoxes in SpiralBoxSubsampling.possibleBoxNumbers: for numBoxes in SpiralBoxSubsampling.possibleBoxNumbers:
newBoxSelector: SpiralBoxSubsampling = SpiralBoxSubsampling(self.dataset.particleContainer, desiredFraction) newBoxSelector: SpiralBoxSubsampling = SpiralBoxSubsampling(self.dataset.particleContainer, desiredFraction)
...@@ -177,6 +171,8 @@ class BoxSelectionCreator(object): ...@@ -177,6 +171,8 @@ class BoxSelectionCreator(object):
def get_randomBoxSubsamplers_for_fraction(self, desiredFraction: float) -> list: def get_randomBoxSubsamplers_for_fraction(self, desiredFraction: float) -> list:
randomBoxSamplers: list = [] randomBoxSamplers: list = []
diameter, offset = self._get_diameter_and_offset()
randomBoxSampler: RandomBoxSampling = RandomBoxSampling(None, desiredFraction) randomBoxSampler: RandomBoxSampling = RandomBoxSampling(None, desiredFraction)
randomBoxSampler.update_max_fractions() randomBoxSampler.update_max_fractions()
for numBoxes in randomBoxSampler.possibleBoxNumbers: for numBoxes in randomBoxSampler.possibleBoxNumbers:
...@@ -184,10 +180,36 @@ class BoxSelectionCreator(object): ...@@ -184,10 +180,36 @@ class BoxSelectionCreator(object):
if randomBoxSampler.config_is_valid(): if randomBoxSampler.config_is_valid():
newSampler: RandomBoxSampling = deepcopy(randomBoxSampler) newSampler: RandomBoxSampling = deepcopy(randomBoxSampler)
newSampler.particleContainer = self.dataset.particleContainer newSampler.particleContainer = self.dataset.particleContainer
newSampler.filterDiameter = diameter
newSampler.offset = offset
randomBoxSamplers.append(newSampler)
return randomBoxSamplers
def get_randomQuarterBoxSubsamplers_for_fraction(self, desiredFraction: float) -> list:
randomBoxSamplers: list = []
diameter, offset = self._get_diameter_and_offset()
randomBoxSampler: RandomQuarterBoxes = RandomQuarterBoxes(None, desiredFraction)
randomBoxSampler.update_max_fractions()
for numBoxes in randomBoxSampler.possibleBoxNumbers:
randomBoxSampler.numBoxes = numBoxes
if randomBoxSampler.config_is_valid():
newSampler: RandomBoxSampling = deepcopy(randomBoxSampler)
newSampler.particleContainer = self.dataset.particleContainer
newSampler.filterDiameter = diameter
newSampler.offset = offset
randomBoxSamplers.append(newSampler) randomBoxSamplers.append(newSampler)
return randomBoxSamplers return randomBoxSamplers
def _get_diameter_and_offset(self) -> tuple:
offset, diameter, widthHeight = helpers.get_filterDimensions_from_dataset(self.dataset)
diameter: float = helpers.convert_length_to_pixels(self.dataset, diameter)
offset: tuple = helpers.convert_length_to_pixels(self.dataset, offset[0]), \
helpers.convert_length_to_pixels(self.dataset, offset[1])
return diameter, offset
class CrossBoxSubSampling(BoxSelectionSubsamplingMethod): class CrossBoxSubSampling(BoxSelectionSubsamplingMethod):
def __init__(self, particleContainer, desiredFraction: float = 0.1) -> None: def __init__(self, particleContainer, desiredFraction: float = 0.1) -> None:
...@@ -354,28 +376,47 @@ class SpiralBoxSubsampling(BoxSelectionSubsamplingMethod): ...@@ -354,28 +376,47 @@ class SpiralBoxSubsampling(BoxSelectionSubsamplingMethod):
class RandomBoxSampling(BoxSelectionSubsamplingMethod): class RandomBoxSampling(BoxSelectionSubsamplingMethod):
def __init__(self, particleContainer, desiredFraction=0.1): def __init__(self, particleContainer, desiredFraction=0.1, maxAngle=2*np.pi):
super(RandomBoxSampling, self).__init__(particleContainer, desiredFraction) super(RandomBoxSampling, self).__init__(particleContainer, desiredFraction)
self.numBoxes: int = 10 self.numBoxes: int = 10
self.maxTries: int = 50 self.maxTries: int = 50
self.__maxAngle: float = maxAngle
@property @property
def label(self) -> str: def label(self) -> str:
return f'Boxes random layout ({self.numBoxes} boxes)' return f'Boxes random layout ({self.numBoxes} boxes)'
def equals(self, otherMethod) -> bool:
equals: bool = False
if type(otherMethod) == type(self) and otherMethod.fraction == self.fraction:
if otherMethod.numBoxes == self.numBoxes and otherMethod.__maxAngle == self.__maxAngle:
equals = True
return equals
def get_topLeft_of_boxes(self) -> list: def get_topLeft_of_boxes(self) -> list:
#
# valid, topLefts = randoms.get_random_topLefts(self.numBoxes, self.boxSize,
# self.filterDiameter/2, self.__maxAngle,
# seed=self.randomSeed, maxTries=self.maxTries)
#
# if not valid:
# raise AttributeError
#
# topLefts: list = [[topLefts[i, 0], topLefts[i, 1]] for i in range(topLefts.shape[0])]
#
def get_random_topleft() -> list: def get_random_topleft() -> list:
angle = np.random.rand() * 2 * np.pi angle = np.random.rand() * self.__maxAngle
dist = np.random.rand() * maxDist dist = np.random.rand() * maxDist
x: float = dist * np.cos(angle) + radius - boxSize/2 x: float = dist * np.cos(angle) + radius - boxSize / 2
y: float = dist * np.sin(angle) + radius - boxSize/2 y: float = dist * np.sin(angle) + radius - boxSize / 2
return [x, y] return [x, y]
np.random.seed(self.randomSeed) np.random.seed(self.randomSeed)
topLefts: list = [] topLefts: list = []
boxSize: float = self.boxSize boxSize: float = self.boxSize
radius: float = self.filterDiameter/2 radius: float = self.filterDiameter / 2
maxDist: float = radius - np.sqrt((boxSize/2)**2 + (boxSize/2)**2) maxDist: float = radius - np.sqrt((boxSize / 2) ** 2 + (boxSize / 2) ** 2)
outerCounter: int = 0 outerCounter: int = 0
validSolutionFound: bool = False validSolutionFound: bool = False
...@@ -388,8 +429,10 @@ class RandomBoxSampling(BoxSelectionSubsamplingMethod): ...@@ -388,8 +429,10 @@ class RandomBoxSampling(BoxSelectionSubsamplingMethod):
counter: int = 0 counter: int = 0
while counter < 50: while counter < 50:
newTopLeft: list = get_random_topleft() newTopLeft: list = get_random_topleft()
overlaps: list = [box_overlaps_other_box(newTopLeft, topLeft2, boxSize) for topLeft2 in topLefts] for topLeft2 in topLefts:
if not True in overlaps: if box_overlaps_other_box(newTopLeft, topLeft2, boxSize):
break
else: # i.e., if no break occurred
topLefts.append(newTopLeft) topLefts.append(newTopLeft)
break break
counter += 1 counter += 1
...@@ -405,6 +448,15 @@ class RandomBoxSampling(BoxSelectionSubsamplingMethod): ...@@ -405,6 +448,15 @@ class RandomBoxSampling(BoxSelectionSubsamplingMethod):
return topLefts return topLefts
class RandomQuarterBoxes(RandomBoxSampling):
def __init__(self, particleContainer, desiredFraction=0.1, maxAngle=0.5*np.pi):
super(RandomQuarterBoxes, self).__init__(particleContainer, desiredFraction, maxAngle)
@property
def label(self) -> str:
return f'Boxes random layout (quarter) ({self.numBoxes} boxes)'
def determine_max_achievable_frac(method: BoxSelectionSubsamplingMethod, numBoxes: int) -> float: def determine_max_achievable_frac(method: BoxSelectionSubsamplingMethod, numBoxes: int) -> float:
""" """
Takes a boxsampling method and iteratively increases the covered fraction for the given number of boxes. Takes a boxsampling method and iteratively increases the covered fraction for the given number of boxes.
...@@ -420,7 +472,7 @@ def determine_max_achievable_frac(method: BoxSelectionSubsamplingMethod, numBoxe ...@@ -420,7 +472,7 @@ def determine_max_achievable_frac(method: BoxSelectionSubsamplingMethod, numBoxe
method.numBoxes = numBoxes method.numBoxes = numBoxes
frac: float = 0.0 frac: float = 0.0
lastvalidFrac: float = 0.0 lastvalidFrac: float = 0.0
for frac in np.linspace(0.05, 0.6, 50): for frac in np.linspace(0.01, 0.6, 50):
method.fraction = frac method.fraction = frac
valid: bool = False valid: bool = False
...@@ -436,4 +488,5 @@ def determine_max_achievable_frac(method: BoxSelectionSubsamplingMethod, numBoxe ...@@ -436,4 +488,5 @@ def determine_max_achievable_frac(method: BoxSelectionSubsamplingMethod, numBoxe
method.fraction = origFrac method.fraction = origFrac
method.numBoxes = origBoxNum method.numBoxes = origBoxNum
# print(method.label, numBoxes, lastvalidFrac)
return lastvalidFrac return lastvalidFrac
...@@ -4,9 +4,15 @@ import numpy as np ...@@ -4,9 +4,15 @@ import numpy as np
from evaluation import TotalResults from evaluation import TotalResults
def get_error_vs_frac_plot(totalResults: TotalResults, attributes: list = [], methods: list = []) -> Figure: def get_error_vs_frac_plot(totalResults: TotalResults, attributes: list = [], methods: list = [],
standarddevs=True, fill=True) -> Figure:
if len(attributes) == 0 and len(methods) != 0:
attributes = [[]]*len(methods)
elif len(methods) == 0 and len(attributes) != 0:
methods = [[]]*len(attributes)
assert len(attributes) == len(methods) assert len(attributes) == len(methods)
fig: Figure = plt.figure() fig: Figure = plt.figure(figsize=(10, 5))
numRows: int = 1 numRows: int = 1
numCols: int = 1 numCols: int = 1
if len(attributes) == 0: if len(attributes) == 0:
...@@ -26,9 +32,15 @@ def get_error_vs_frac_plot(totalResults: TotalResults, attributes: list = [], me ...@@ -26,9 +32,15 @@ def get_error_vs_frac_plot(totalResults: TotalResults, attributes: list = [], me
for methodLabel in errorPerFraction.keys(): for methodLabel in errorPerFraction.keys():
errorDict: dict = errorPerFraction[methodLabel] errorDict: dict = errorPerFraction[methodLabel]
fractions: list = list(errorDict.keys()) fractions: list = list(errorDict.keys())
errors: list = [errorDict[fraction][0] for fraction in fractions] errors: np.ndarray = np.array([errorDict[fraction][0] for fraction in fractions])
stdevs: list = [errorDict[fraction][1] for fraction in fractions] stdevs: np.ndarray = np.array([errorDict[fraction][1] for fraction in fractions])
ax.errorbar(fractions, errors, stdevs, label=methodLabel, marker='s', capsize=5) if not standarddevs:
ax.plot(fractions, errors, label=methodLabel, marker='s')
else:
line = ax.errorbar(fractions, errors, stdevs, label=methodLabel, marker='s', capsize=5)
if fill:
color = line[0].get_color()
ax.fill_between(fractions, errors-stdevs, errors+stdevs, alpha=0.2, facecolor=color)
title: str = '' title: str = ''
if len(attrs) > 0: if len(attrs) > 0:
...@@ -43,6 +55,8 @@ def get_error_vs_frac_plot(totalResults: TotalResults, attributes: list = [], me ...@@ -43,6 +55,8 @@ def get_error_vs_frac_plot(totalResults: TotalResults, attributes: list = [], me
ax.legend() ax.legend()
index += 1 index += 1
fig.tight_layout()
return fig return fig
......
...@@ -55,14 +55,16 @@ class MainView(QtWidgets.QWidget): ...@@ -55,14 +55,16 @@ class MainView(QtWidgets.QWidget):
self._switch_to_default_mode() self._switch_to_default_mode()
def _add_measure_modes(self) -> None: def _add_measure_modes(self) -> None:
self.measureModes['Random Particle Selection'] = RandomMeasureMode(self.filterView)
self.measureModes['Spiral Box Selection'] = SpiralBoxMode(self.filterView) self.measureModes['Spiral Box Selection'] = SpiralBoxMode(self.filterView)
self.measureModes['Cross Box Selection'] = CrossBoxMode(self.filterView) self.measureModes['Cross Box Selection'] = CrossBoxMode(self.filterView)
self.measureModes['Random Box Selection'] = RandomBoxMode(self.filterView) self.measureModes['Random Box Selection'] = RandomBoxMode(self.filterView)
self.measureModes['Random Particle Selection'] = RandomMeasureMode(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('Spiral Box Selection')
self.modeSelector.addItem('Cross Box Selection') self.modeSelector.addItem('Cross Box Selection')
self.modeSelector.addItem('Random Box Selection') self.modeSelector.addItem('Random Box Selection')
self.modeSelector.addItem('Random Particle Selection') self.modeSelector.addItem('Quarter Random Box Selection')
for mode in self.measureModes.values(): for mode in self.measureModes.values():
mode.updatedResult.connect(self.infoWidget.update_results) mode.updatedResult.connect(self.infoWidget.update_results)
......
...@@ -205,3 +205,11 @@ class RandomBoxMode(MeasureMode): ...@@ -205,3 +205,11 @@ class RandomBoxMode(MeasureMode):
self.uiControls: BoxControlGroup = BoxControlGroup(self, 'Random Box Controls') self.uiControls: BoxControlGroup = BoxControlGroup(self, 'Random Box Controls')
self.method: RandomBoxSampling = RandomBoxSampling(None) self.method: RandomBoxSampling = RandomBoxSampling(None)
self.update_measure_viewItems() 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()
...@@ -12,23 +12,27 @@ SET GEPARD TO EVALUATION BRANCH (WITHOUT THE TILING STUFF), OTHERWISE SOME OF TH ...@@ -12,23 +12,27 @@ SET GEPARD TO EVALUATION BRANCH (WITHOUT THE TILING STUFF), OTHERWISE SOME OF TH
""" """
if __name__ == '__main__': if __name__ == '__main__':
# results: TotalResults = TotalResults() results: TotalResults = TotalResults()
# pklsInFolders = get_pkls_from_directory(r'C:\Users\xbrjos\Desktop\temp MP\NewDatasets') pklsInFolders = get_pkls_from_directory(r'C:\Users\xbrjos\Desktop\temp MP\NewDatasets')
#
# for folder in pklsInFolders.keys(): for folder in pklsInFolders.keys():
# for samplePath in pklsInFolders[folder]: for samplePath in pklsInFolders[folder]:
# newSampleResult: SampleResult = results.add_sample(samplePath) newSampleResult: SampleResult = results.add_sample(samplePath)
# for attr in get_attributes_from_foldername(folder): for attr in get_attributes_from_foldername(folder):
# newSampleResult.set_attribute(attr) newSampleResult.set_attribute(attr)
#
# t0 = time.time() t0 = time.time()
# results.update_all() results.update_all()
# print('updating all took', time.time()-t0, 'seconds') print('updating all took', time.time()-t0, 'seconds')
#
# save_results('results1.res', results) save_results('results2.res', results)
results: TotalResults = load_results('results1.res') # results: TotalResults = load_results('results1.res')
# save_results('results1.res', results)
# plot: Figure = get_error_vs_frac_plot(results, attributes=[['air', 'water'], ['sediment', 'soil', 'beach', 'slush']],
plot: Figure = get_error_vs_frac_plot(results, attributes=[['air', 'water'], ['sediment', 'soil', 'beach', 'slush']], # methods=[['Boxes random']]*2)
methods=[['random', 'size']]*2) # methods=[['Random Subsampling', 'Sizebin']] * 2)
plot.show()
\ No newline at end of file plot: Figure = get_error_vs_frac_plot(results,
attributes=[['air', 'water'], ['sediment', 'soil', 'beach', 'slush']],
methods=[['layout (7', 'layout (10', 'layout (15', 'cross', 'random subsampling', 'sizebin']] * 2)
plot.show()
...@@ -259,10 +259,11 @@ class TestSampleResult(unittest.TestCase): ...@@ -259,10 +259,11 @@ class TestSampleResult(unittest.TestCase):
possibleCrossBoxMethods = 2 possibleCrossBoxMethods = 2
possibleSpiralBoxMethods = 3 possibleSpiralBoxMethods = 3
possibleRandomBoxMethods = 3 possibleRandomBoxMethods = 3
possibleQuarterRandomBoxMethods = 3
possibleChemometricMethods = 0 possibleChemometricMethods = 0
totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \ totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \
possibleSpiralBoxMethods + possibleChemometricMethods + \ possibleSpiralBoxMethods + possibleChemometricMethods + \
possibleRandomBoxMethods possibleRandomBoxMethods + possibleQuarterRandomBoxMethods
self.assertEqual(len(methods), totalPossible) self.assertEqual(len(methods), totalPossible)
self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction))) self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
...@@ -276,11 +277,12 @@ class TestSampleResult(unittest.TestCase): ...@@ -276,11 +277,12 @@ class TestSampleResult(unittest.TestCase):
possibleRandomMethods = 2 possibleRandomMethods = 2
possibleCrossBoxMethods = 1 possibleCrossBoxMethods = 1
possibleSpiralBoxMethods = 0 possibleSpiralBoxMethods = 0
possibleChemometricMethods = 0
possibleRandomBoxMethods = 0 possibleRandomBoxMethods = 0
possibleQuarterRandomBoxMethods = 0
possibleChemometricMethods = 0
totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \ totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \
possibleSpiralBoxMethods + possibleChemometricMethods + \ possibleSpiralBoxMethods + possibleChemometricMethods + \
possibleRandomBoxMethods possibleRandomBoxMethods + possibleQuarterRandomBoxMethods
self.assertEqual(len(methods), totalPossible) self.assertEqual(len(methods), totalPossible)
self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction))) self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction))) self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction)))
...@@ -293,10 +295,11 @@ class TestSampleResult(unittest.TestCase): ...@@ -293,10 +295,11 @@ class TestSampleResult(unittest.TestCase):
possibleCrossBoxMethods = 0 possibleCrossBoxMethods = 0
possibleSpiralBoxMethods = 0 possibleSpiralBoxMethods = 0
possibleRandomBoxMethods = 0 possibleRandomBoxMethods = 0
possibleQuarterRandomBoxMethods = 0
possibleChemometricMethods = 0 possibleChemometricMethods = 0
totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \ totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \
possibleSpiralBoxMethods + possibleChemometricMethods + \ possibleSpiralBoxMethods + possibleChemometricMethods + \
possibleRandomBoxMethods possibleRandomBoxMethods + possibleQuarterRandomBoxMethods
self.assertEqual(len(methods), totalPossible) self.assertEqual(len(methods), totalPossible)
self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction))) self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction))) self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction)))
...@@ -310,9 +313,10 @@ class TestSampleResult(unittest.TestCase): ...@@ -310,9 +313,10 @@ class TestSampleResult(unittest.TestCase):
possibleSpiralBoxMethods = 3 possibleSpiralBoxMethods = 3
possibleChemometricMethods = 0 possibleChemometricMethods = 0
possibleRandomBoxMethods = 3 possibleRandomBoxMethods = 3
possibleQuarterRandomBoxMethods = 3
totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \ totalPossible = possibleCrossBoxMethods + possibleRandomMethods + \
possibleSpiralBoxMethods + possibleChemometricMethods + \ possibleSpiralBoxMethods + possibleChemometricMethods + \
possibleRandomBoxMethods possibleRandomBoxMethods + possibleQuarterRandomBoxMethods
self.assertEqual(len(methods), totalPossible) self.assertEqual(len(methods), totalPossible)
for desiredFraction in desiredFractions: for desiredFraction in desiredFractions:
self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction))) self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
......
...@@ -225,6 +225,47 @@ class TestRandomBoxes(unittest.TestCase): ...@@ -225,6 +225,47 @@ class TestRandomBoxes(unittest.TestCase):
self.assertEqual(self.randBoxes.get_maximum_achievable_fraction(), maxFrac) self.assertEqual(self.randBoxes.get_maximum_achievable_fraction(), maxFrac)
class TestRandomQuarterBoxes(unittest.TestCase):
def setUp(self) -> None:
self.randBoxes: RandomQuarterBoxes = RandomQuarterBoxes(None, 0.1)
self.randBoxes.maxTries = 10
def test_get_top_lefts(self):
self.randBoxes.update_max_fractions()
radius: float = self.randBoxes.filterDiameter/2
center: tuple = radius, radius
for frac in [0.1, 0.3, 0.5]:
self.randBoxes.fraction = frac
for numBoxes in self.randBoxes.possibleBoxNumbers:
self.randBoxes.numBoxes = numBoxes
if self.randBoxes.config_is_valid():
topLefts: list = self.randBoxes.get_topLeft_of_boxes()
self.assertEqual(len(topLefts), numBoxes)
boxSize: float = self.randBoxes.boxSize
for topLeft in topLefts:
points: list = [[topLeft[0], topLeft[1]], [topLeft[0], topLeft[1]+boxSize],
[topLeft[0]+boxSize, topLeft[1]], [topLeft[0]+boxSize, topLeft[1]+boxSize]]
for point in points:
dist = np.linalg.norm([point[0]-center[0], point[1]-center[1]])
self.assertTrue(point[0] >= 0 and point[1] >= 0)
self.assertTrue(dist <= radius)
boxCenter: tuple = topLeft[0] + boxSize/2, topLeft[1] + boxSize/2
self.assertTrue(boxCenter[0] >= radius - boxSize/2)
self.assertTrue(boxCenter[1] >= radius - boxSize/2)
def test_label(self):
self.assertTrue(type(self.randBoxes.label), str)
def test_get_max_fraction(self):
for numBoxes in self.randBoxes.possibleBoxNumbers:
self.randBoxes.numBoxes = numBoxes
maxFrac: float = determine_max_achievable_frac(self.randBoxes, numBoxes)
self.assertEqual(self.randBoxes.get_maximum_achievable_fraction(), maxFrac)
class TestBoxCreator(unittest.TestCase): class TestBoxCreator(unittest.TestCase):
def setUp(self) -> None: def setUp(self) -> None:
self.dataset: dataset.DataSet = dataset.DataSet('test') self.dataset: dataset.DataSet = dataset.DataSet('test')
......
File added