Commit deabc28f authored by Josef Brandt's avatar Josef Brandt

Several updates..

parent 5a4bf706
......@@ -223,7 +223,7 @@ def get_curvature_ft(contour: np.ndarray, angularSegment: float = 20, numHarmoni
tan_before: float = 0
if x - x_before != 0:
tan_before = np.rad2deg(np.arctan((y-y_before) / (x-x_before)))
tanr_before = np.rad2deg(np.arctan((y-y_before) / (x-x_before)))
tan_after: float = 0
if x_after - x != 0:
......@@ -273,9 +273,11 @@ class TrainedSubsampling(SubsamplingMethod):
@property
def label(self) -> str:
label: str = 'Trained Random Sampling'
label: str = 'Dummy Trained Random Sampling'
if self.fakeClassifier:
label += f' faked to score {self.fakeScore}'
label += f' (score {self.fakeScore})'
else:
label += f' (score {self.score})'
return label
def _predict_MP_Indices(self) -> None:
......@@ -293,127 +295,39 @@ class TrainedSubsampling(SubsamplingMethod):
self.score = self.fakeScore
particles: list = self.particleContainer.particles
predictions: np.ndarray = np.zeros(len(particles))
falsePositives, falseNegatives = 0, 0
numMP = 0
for index, particle in enumerate(particles):
if is_MP_particle(particle):
numMP += 1
if random() <= self.fakeScore:
predictions[index] = 1
else:
falseNegatives += 1
else:
if random() > self.fakeScore:
predictions[index] = 1
falsePositives += 1
mpIndices = list(np.where(predictions == 1)[0])
nonMPIndices = list(np.where(predictions == 0)[0])
numNonMPIndices = len(nonMPIndices)
fracNonMPToTake: float = float(np.clip(-1 + 1/0.075 * self.fraction, 0.0, 1.0))
fracNonMPToTake: float = float(np.clip(-0.5 + 1/0.1 * self.fraction, 0.0, 1.0))
numNonMPToTake: int = int(round(fracNonMPToTake * numNonMPIndices))
# numNonMPToTake = int(round(self.fraction**0.8 * numNonMPIndices))
# numNonMPToTake = int(round(self.fraction * numNonMPIndices))
self.predictedMPIndices = mpIndices + sample(nonMPIndices, numNonMPToTake)
def get_maximum_achievable_fraction(self) -> float:
numParticles: int = len(self.particleContainer.particles)
numMPPredicted: int = len(self.predictedMPIndices)
if numParticles > 0:
maxFrac: float = numMPPredicted / numParticles
else:
maxFrac: float = 0.0
maxFrac: float = 0.10
return maxFrac
def apply_subsampling_method(self) -> list:
# if not self.fakeClassifier:
# self._load_classifier()
# fullimgpath: str = r'C:\Users\xbrjos\Desktop\temp MP\Fullimages'
# dsetname: str = self.particleContainer.datasetParent.name
# imgPath: str = os.path.join(fullimgpath, dsetname + '.tif')
# fullimg = cv2imread_fix(imgPath)
#
# features: np.ndarray = get_particle_featurematrix(self.particleContainer, fullimg)
# predictions: np.ndarray = self.clf.predict(features)
# else:
# from evaluation import is_MP_particle
# self.score = self.fakeScore
# particles: list = self.particleContainer.particles
# predictions: np.ndarray = np.zeros(len(particles))
# falsePositives, falseNegatives = 0, 0
# numMP = 0
# for index, particle in enumerate(particles):
# if is_MP_particle(particle):
# numMP += 1
# if random() <= self.fakeScore:
# predictions[index] = 1
# else:
# falseNegatives += 1
# # assert predictions[index] == 1
# else:
# if random() > self.fakeScore:
# predictions[index] = 1
# falsePositives += 1
# # assert predictions[index] == 0
# particles = self.particleContainer.particles
# predictedMPIndices = list(np.where(predictions == 1)[0])
# numPredictedMP = len(self.predictedMPIndices)
# numParticlesToMeasure = round(len(particles) * self.fraction)
# origMPFrac = round(numMP/len(particles)*100, 1)
# origNumMP = numMP
# print(f'numTotal: , {len(particles)}, numPredictedMP: {numPredictedMP}, '
# f'numMeasured: {numParticlesToMeasure}')
# print(f'falsePos: {falsePositives}, falseNeg: {falseNegatives}')
# print('measuredFrac is', self.fraction)
# print(f'orig MP Fraction {origMPFrac}, numMPParticles: {numMP}')
numParticlesToSelect = round(len(self.particleContainer.particles) * self.fraction)
if numParticlesToSelect > len(self.predictedMPIndices):
print(numParticlesToSelect, len(self.predictedMPIndices))
numParticlesToSelect = len(self.predictedMPIndices)
# assert numParticlesToSelect <= len(self.predictedMPIndices)
# enhancedParticles = []
# for particle in self.particleContainer.particles:
# if particle.index in self.predictedMPIndices:
# enhancedParticles.append(particle)
indicesToSelect = sample(self.predictedMPIndices, numParticlesToSelect)
# print(f'having to measure according to fraction: {numParticlesToMeasure}, actually measured: {len(indicesToSelect)}')
# indicesToSelect: set = self._get_measure_indices(list(predictions))
selectedParticles: list = []
for particle in self.particleContainer.particles:
if particle.index in indicesToSelect:
selectedParticles.append(particle)
for index in indicesToSelect:
selectedParticles.append(self.particleContainer.getParticleOfIndex(index))
# fac = measuredMPFrac / self.fraction
# if fac > 0:
# self.fractionForExtrapolation = fac
# else:
# self.fractionForExtrapolation = self.fraction
# numEstimMP = numMP / self.fractionForExtrapolation
numOrigParticles = len(self.particleContainer.particles)
numEnhancedParticles = len(self.predictedMPIndices)
self.fractionForExtrapolation = self.fraction * (numOrigParticles/numEnhancedParticles)
# print(f'fraction: {self.fraction}, measured mpfrac: {measuredMPFrac}')
# print(self.fraction, self.score, measuredMPFrac)
# fac: float = 0.5 * np.log10(self.fraction) + self.score*1.2 # empirical
# estimOrigMPFraction = measuredMPFrac / fac
# print(self.fraction, origMPFrac, round(estimOrigMPFraction*100, 1))
# estimOrigMPFraction = measuredMPFrac / self.score
# estimNumMPParticles = estimOrigMPFraction * len(particles)
# print(f'orig MP {origNumMP}, estimated MP {round(estimNumMPParticles)}')
# if estimNumMPParticles > 0:
# self.fractionForExtrapolation = numMP/estimNumMPParticles
# else:
# self.fractionForExtrapolation = self.fraction
# self.fractionForExtrapolation = self.fraction / self.score
# print('measured MP frac is', round(measuredMPFrac*100, 1))
# print('estimMPFraction', round(estimOrigMPFration*100, 1))
# print('frac for extrap', self.fractionForExtrapolation)
return selectedParticles
def _load_classifier(self) -> None:
......
......@@ -9,8 +9,11 @@ from scipy import spatial
import os
import matplotlib.pyplot as plt
from helpers import get_filterDimensions_from_dataset, get_center_from_filter_dimensions, convert_length_to_pixels
# from evaluation import is_MP_particle
import evaluation
def get_particle_heterogeneity(dataset: DataSet, numCells: int = 50) -> float:
def get_particle_patchiness(dataset: DataSet, numCells: int = 50, onlyMP=False) -> float:
offset, diameter, [width, height] = get_filterDimensions_from_dataset(dataset)
center: np.ndarray = get_center_from_filter_dimensions(offset, diameter)
width: float = convert_length_to_pixels(dataset, width)
......@@ -24,12 +27,15 @@ def get_particle_heterogeneity(dataset: DataSet, numCells: int = 50) -> float:
numRows: int = int(np.ceil(height / pixelsPerTile)) + 1
numCols: int = int(np.ceil(width / pixelsPerTile)) + 1
partCount: int = 0
densityImage: np.ndarray = np.zeros((numRows, numCols))
for particle in dataset.particleContainer.particles:
particleCenter: tuple = np.mean(particle.contour[:, 0, 0]), np.mean(particle.contour[:, 0, 1])
row: int = int(round(particleCenter[1] / pixelsPerTile))
col: int = int(round(particleCenter[0] / pixelsPerTile))
densityImage[row, col] += 1
if (onlyMP and evaluation.is_MP_particle(particle)) or not onlyMP:
particleCenter: tuple = np.mean(particle.contour[:, 0, 0]), np.mean(particle.contour[:, 0, 1])
row: int = int(round(particleCenter[1] / pixelsPerTile))
col: int = int(round(particleCenter[0] / pixelsPerTile))
densityImage[row, col] += 1
partCount += 1
mask: np.ndarray = np.zeros_like(densityImage)
cv2.circle(mask, (centerY, centerX), radius, 1, -1)
......@@ -41,7 +47,9 @@ def get_particle_heterogeneity(dataset: DataSet, numCells: int = 50) -> float:
ratio: float = round(std/mean, 2)
# plt.imshow(densityImage)
# plt.title(f'sample: {dataset.name},\nmean: {mean}, std: {std}, ratio = {ratio}')
# plt.title(f'MP particle count: {partCount},\ndensity mean: {mean}, density std: {std},\npatchiness = {ratio}')
# plt.axis('off')
# plt.tight_layout()
# plt.show()
# print(f'sample: {dataset.name}, mean: {mean}, std: {std}, ratio = {ratio}')
return ratio
......@@ -51,37 +59,23 @@ if __name__ == '__main__':
# imgpath: str = r'C:\Users\xbrjos\Desktop\temp MP\Fullimages'
# imgname: str = '181120_MCI_2_ds1+2_all_ kleiner500_10_1.tif'
# imgname: str = '190619_5_PTPH_sld_190321_ds1_50_1_neu.tif'
#
#191213_P190814_TPHZ_ds1_50_1
# img: np.ndarray = cv2imread_fix(os.path.join(imgpath, imgname))
# gray: np.ndarray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# _, binimg = cv2.threshold(gray, 20, 1, cv2.THRESH_BINARY_INV)
# distmap: np.ndarray = cv2.distanceTransform(binimg, cv2.DIST_L1, 3)
# plt.imshow(distmap, cmap='gray')
paths: list = [r'C:\Users\xbrjos\Desktop\temp MP\NewDatasets\water\181120_MCI_2_ds1+2_all_ kleiner500_10_1.pkl',
r'C:\Users\xbrjos\Desktop\temp MP\NewDatasets\wastewater, slush\190619_5_PTPH_sld_190321_ds1_50_1_neu.pkl']
paths.append(r'C:\Users\xbrjos\Desktop\temp MP\NewDatasets\water\190306_MCII_1_2_50.pkl')
paths.append(r'C:\Users\xbrjos\Desktop\temp MP\NewDatasets\water\190222_MCII_1_1_50_1.pkl')
r'C:\Users\xbrjos\Desktop\temp MP\NewDatasets\wastewater, water\191213_P190814_TPHZ_ds1_50_1.pkl',
r'C:\Users\xbrjos\Desktop\temp MP\NewDatasets\Air\191119_RW6_Solling_50_2_neu.pkl']
distances: list = []
allParticles = []
for path in paths:
dset = loadData(path)
get_particle_heterogeneity(dset)
# particleContainer: ParticleContainer = dset.particleContainer
# particleCenters: list = []
# for particle in particleContainer.particles:
# particleCenters.append([np.mean(particle.contour[:, 0, 0]), np.mean(particle.contour[:, 0, 1])])
#
# closest_particle_distances: np.ndarray = np.zeros(len(particleCenters))
# particleCenters: np.ndarray = np.array(particleCenters)
# print('particle centers done')
get_particle_patchiness(dset, 50, onlyMP=True)
for particle in dset.particleContainer.particles:
if evaluation.is_MP_particle(particle):
allParticles.append(particle.getParticleAssignment())
# distMat: np.ndarray = spatial.distance_matrix(particleCenters, particleCenters)
# print('distmat computed')
# for i in range(distMat.shape[0]):
# if i == 0:
# closest_particle_distances[i] = np.min(distMat[i, 1:])
# elif i == distMat.shape[0]-1:
# closest_particle_distances[i] = np.min(distMat[i, :-1])
# else:
# closest_particle_distances[i] = np.min([np.min(distMat[i, :i]), np.min(distMat[i, i+1:])])
# distances.append(closest_particle_distances)
# plt.boxplot(distances)
print(set(allParticles))
\ No newline at end of file
import numpy as np
cimport numpy as np
cimport cython
from cython cimport boundscheck, wraparound
@boundscheck(False)
@wraparound(False)
cdef bint box_overlaps_contour(unsigned int[:] boxTopLeftXY, unsigned int boxSize, unsigned int[:, :, :] contourData):
cdef bint isOverlapping = False
cdef unsigned int xmin, xmax, width, boxXmin, boxXmax, ymin, ymax, height, boxYmin, boxYmax
xmin = np.min(contourData[:, 0, 1])
xmax = np.max(contourData[:, 0, 1])
width = xmax - xmin
boxXmin = boxTopLeftXY[0]
boxXmax = boxTopLeftXY[0] + boxSize
if xmin > (boxXmin-width/2):
if xmax < (boxXmax+width/2):
ymin = np.min(contourData[:, 0, 1])
ymax = np.max(contourData[:, 0, 1])
height = ymax - ymin
boxYmin = boxTopLeftXY[1]
boxYmax = boxTopLeftXY[1] + boxSize
if ymin > (boxYmin-height/2):
if ymax < (boxYmax+width/2):
isOverlapping = True
return isOverlapping
@boundscheck(False)
@wraparound(False)
def def_get_indices_of_overlapping_particles(contours not None, unsigned int[:, :] topLefts, unsigned int boxSize):
cdef Py_ssize_t i, j
cdef unsigned int counter, numParticles, numTopLefts
numParticles = len(contours)
numTopLefts = topLefts.shape[0]
cdef unsigned int[:] overlappingIndices = np.zeros(numParticles, dtype=np.uint32)
cdef unsigned int[:, :, :] currentContour
counter = 0
for i in range(numParticles):
currentContour = contours[i]
for j in range(numTopLefts):
if box_overlaps_contour(topLefts[j, :], boxSize, currentContour):
overlappingIndices[counter] = i
counter += 1
break
return overlappingIndices[:counter]
......@@ -19,8 +19,14 @@ if len(sys.argv) == 1:
# ext = Extension("getRandomTopLefts", ["getRandomTopLefts.pyx"], extra_compile_args=['-O3'],)
# setup(
# name="get a given number of random topLefts",
# ext_modules=cythonize("randoms.pyx", annotate=True), # accepts a glob pattern
# include_dirs=[np.get_include()]
# )
setup(
name="get a given number of random topLefts",
ext_modules=cythonize("randoms.pyx", annotate=True), # accepts a glob pattern
name="checks which particle contours overlap the boxes",
ext_modules=cythonize("particleBoxOverlap.pyx", annotate=True), # accepts a glob pattern
include_dirs=[np.get_include()]
)
)
\ No newline at end of file
......@@ -5,7 +5,7 @@ sys.path.append("C://Users//xbrjos//Desktop//Python")
from gepard import dataset
from gepard.analysis.particleContainer import ParticleContainer
from cythonModules import rotateContour
from helpers import get_filterDimensions_from_dataset, get_center_from_filter_dimensions, convert_length_to_pixels, timingDecorator
from helpers import get_filterDimensions_from_dataset, get_center_from_filter_dimensions, convert_length_to_pixels
class ParticleVariations(object):
......@@ -15,7 +15,6 @@ class ParticleVariations(object):
self.origParticleContainer: ParticleContainer = self.dataset.particleContainer
self.numVariations = numVariations
@timingDecorator
def get_particleContainer_variations(self) -> ParticleContainer:
if self.numVariations > 0:
offset, diameter, [width, height] = get_filterDimensions_from_dataset(self.dataset)
......
......@@ -21,6 +21,7 @@ from helpers import ParticleBinSorter
import methods as meth
import geometricMethods as gmeth
from chemometrics import chemometricMethods as cmeth
from chemometrics.imageOperations import get_particle_patchiness
from datasetOperations import ParticleVariations
......@@ -34,27 +35,25 @@ def get_methods_to_test(dataset: dataset.DataSet, fractions: list = [], maxTries
:return: list of measurement Objects that are applicable
"""
if len(fractions) == 0:
# fractions: list = [0.02, 0.04, 0.06, 0.1, 0.2, 0.4, 0.5, 0.7, 0.9]
fractions: list = [0.02, 0.03, 0.05, 0.1, 0.25, 0.5, 0.7, 0.9]
# fractions: list = [0.02, 0.06, 0.15, 0.2, 0.5]
fractions: list = [0.01, 0.1, 0.5, 0.9]
# fractions: list = [0.01, 0.1, 0.5, 0.9]
methods: list = []
particleContainer = dataset.particleContainer
for fraction in fractions:
# methods.append(meth.RandomSampling(particleContainer, fraction))
# methods.append(meth.SizeBinFractioning(particleContainer, fraction))
# 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, maxTries=maxTries)
# methods += boxCreator.get_randomQuarterBoxSubsamplers_for_fraction(fraction, maxTries=maxTries)
methods.append(meth.RandomSampling(particleContainer, fraction))
methods.append(meth.SizeBinFractioning(particleContainer, fraction))
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, maxTries=maxTries)
methods += boxCreator.get_randomQuarterBoxSubsamplers_for_fraction(fraction, maxTries=maxTries)
for fakeScore in [0.6, 0.7, 0.8]:
trainedSampling = cmeth.TrainedSubsampling(particleContainer, fraction, fakeScore=fakeScore)
if trainedSampling.config_is_valid():
methods.append(trainedSampling)
else:
print('rejecting trained sample with fraction', fraction)
return methods
......@@ -139,10 +138,12 @@ class TotalResults(object):
self.sampleResults[index] = updatedResult
print(f'done updating {updatedResult.dataset.name} at index {index}')
def get_error_vs_fraction_data(self, attributes: list = [], methods: list = []) -> tuple:
def get_error_vs_fraction_data(self, attributes: list = [], methods: list = [], partCount: tuple = (0, np.inf)) -> tuple:
"""
:param attributes: A list of attributes that should be used for filtering the samples. Only samples with an
attribute from within that list are considered.
:param methods: A list of methods to extract
:param patchiness: Tuple, first val: min patchiness, second val, max patchiness
:return: Dict: Key: Method Label,
Value: {Dict: Key:Measured Fraction, Value: Tuple (averaged MPCountError, StDev MPCountError) over all samples}
"""
......@@ -152,28 +153,38 @@ class TotalResults(object):
for sample in self.sampleResults:
sample: SampleResult = sample
if attributes == [] or sample.has_any_attribute(attributes):
numSamples += 1
if sample.dataset is None:
sample.load_dataset()
for particle in sample.dataset.particleContainer.particles:
allParticles.append(particle)
for res in sample.results:
res: SubsamplingResult = res
method: meth.SubsamplingMethod = res.method
if methods == [] or method.matches_any_pattern(methods):
label: str = method.label
frac: float = method.fraction
error: float = res.mpCountError
stdev: float = res.mpCountErrorStDev
if label not in result.keys():
result[label] = {frac: [(error, stdev)]}
elif frac not in result[label].keys():
result[label][frac] = [(error, stdev)]
else:
result[label][frac].append((error, stdev))
if partCount[0] == 0 and partCount[1] == np.inf:
samplePartCount: int = 1
# samplePatchiness: float = 1.0 # doesn't matter in this case
else:
if sample.dataset is None:
sample.load_dataset()
samplePartCount: int = len(sample.dataset.particleContainer.particles)
# samplePatchiness: float = sample.get_patchiness()
# print(sample.sampleName, samplePatchiness)
if partCount[0] <= samplePartCount < partCount[1]:
numSamples += 1
if sample.dataset is None:
sample.load_dataset()
for particle in sample.dataset.particleContainer.particles:
allParticles.append(particle)
for res in sample.results:
res: SubsamplingResult = res
method: meth.SubsamplingMethod = res.method
if methods == [] or method.matches_any_pattern(methods):
label: str = method.label
frac: float = method.fraction
error: float = res.mpCountError
stdev: float = res.mpCountErrorStDev
if label not in result.keys():
result[label] = {frac: [(error, stdev)]}
elif frac not in result[label].keys():
result[label][frac] = [(error, stdev)]
else:
result[label][frac].append((error, stdev))
numMPParticles: float = get_number_of_MP_particles(allParticles)
stats: dict = {'numSamples': numSamples,
......@@ -282,13 +293,14 @@ class SampleResult(object):
"""
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 = 20):
super(SampleResult, self).__init__()
self.filepath: str = filepath
self.dataset: dataset.DataSet = None
self.results: list = []
self.attributes: list = []
self.numVariations: int = numVariations # how often the sample is altered for each method
self.patchiness: float = -1
@property
def sampleName(self) -> str:
......@@ -298,6 +310,13 @@ class SampleResult(object):
self.dataset = dataset.loadData(self.filepath)
assert self.dataset is not None
def get_patchiness(self) -> float:
if not hasattr(self, "patchiness") or self.patchiness == -1:
if self.dataset is None:
self.load_dataset()
self.patchiness = get_particle_patchiness(self.dataset)
return self.patchiness
def update_result_with_methods(self, methods: list, force: bool = False) -> list:
"""
Updates result with the given method (contains desiredFraction already)
......@@ -330,13 +349,12 @@ class SampleResult(object):
needsToBeUpdated[method] = True
if needsToBeUpdated[method]:
t0 = time.time()
subParticles = method.apply_subsampling_method()
result.add_result(method.particleContainer.particles, subParticles)
updatedMethods.append(method)
print(f'updated {self.sampleName} with {method.label} at fraction {method.fraction}, '
f'iteration {index+1}, took {round(time.time()-t0, 2)}, seconds')
# print(f'updated {self.sampleName} with {method.label} at fraction {method.fraction}, '
# f'iteration {index+1}, took {round(time.time()-t0, 2)}, seconds')
print(f'finished updating sample {self.sampleName}, it took {round(time.time()-t0, 2)} seconds')
return updatedMethods
def set_attribute(self, newAttribute: str) -> None:
......
import time
import numpy as np
from itertools import combinations
from methods import SubsamplingMethod
......@@ -6,7 +7,7 @@ import sys
sys.path.append("C://Users//xbrjos//Desktop//Python")
from gepard import dataset
import helpers
from cythonModules import randoms
from cythonModules import randoms, particleBoxOverlap
def box_overlaps_other_box(topLeft1: list, topLeft2: list, boxSize: float) -> bool:
......@@ -53,16 +54,27 @@ class BoxSelectionSubsamplingMethod(SubsamplingMethod):
return abs(topleft[0] - cntStart[0]) + abs(topleft[1] - cntStart[1])
subParticles: list = []
topLefts: list = self.get_topLeft_of_boxes()
boxWidthHeight: tuple = (self.boxSize, self.boxSize)
topLefts: np.ndarray = np.array(self.get_topLeft_of_boxes())
cython: bool = False
if cython:
topLefts = np.round(topLefts).astype(np.uint32)
# contours: np.ndarray = np.array(self.particleContainer.getParticleContours())
contours = [cnt.astype(np.uint32) for cnt in self.particleContainer.getParticleContours()]
boxSize: np.uint32 = np.uint32(round(self.boxSize))
indices = particleBoxOverlap.def_get_indices_of_overlapping_particles(contours, topLefts, boxSize)
for index in indices:
subParticles.append(self.particleContainer.getParticleOfIndex(index))
for particle in self.particleContainer.particles:
cntStart: tuple = (particle.contour[0, 0, 0], particle.contour[0, 0, 1])
sortedTopLefts = sorted(topLefts, key=distanceToCnt)
else:
boxWidthHeight: tuple = (self.boxSize, self.boxSize)
for particle in self.particleContainer.particles:
cntStart: tuple = (particle.contour[0, 0, 0], particle.contour[0, 0, 1])
sortedTopLefts = sorted(topLefts, key=distanceToCnt)
for topLeftXY in sortedTopLefts:
if helpers.box_overlaps_contour(topLeftXY, boxWidthHeight, particle.contour):
subParticles.append(particle)
for topLeftXY in sortedTopLefts:
if helpers.box_overlaps_contour(topLeftXY, boxWidthHeight, particle.contour):
subParticles.append(particle)
break
return subParticles
......@@ -387,7 +399,7 @@ class RandomBoxSampling(BoxSelectionSubsamplingMethod):
@property
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
......@@ -413,7 +425,7 @@ class RandomQuarterBoxes(RandomBoxSampling):
@property
def label(self) -> str:
return f'Boxes random layout (quarter) ({self.numBoxes} boxes)'
return f'Boxes Random layout (quarter) ({self.numBoxes} boxes)'
def determine_max_achievable_frac(method: BoxSelectionSubsamplingMethod, numBoxes: int) -> float:
......
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter, FixedLocator
from scipy import optimize
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from evaluation import TotalResults, get_number_of_MP_particles
from chemometrics.imageOperations import get_particle_heterogeneity
from evaluation import TotalResults, get_number_of_MP_particles, is_MP_particle
from chemometrics.imageOperations import get_particle_patchiness
from helpers import get_filterDimensions_from_dataset, get_center_from_filter_dimensions, convert_length_to_pixels
def get_error_vs_frac_plot(totalResults: TotalResults, attributes: list = [], methods: list = [],
standarddevs=True, fill=True) -> Figure:
def get_error_vs_frac_plot(totalResults: TotalResults, attributes: list = [], methods: list = [], partCounts: list = [],
standarddevs=True, fill=True, poissonRef=True) -> Figure:
if len(attributes) == 0 and len(methods) != 0:
attributes = [[]]*len(methods)
elif len(methods) == 0 and len(attributes) != 0:
methods = [[]]*len(attributes)
if len(partCounts) == 0:
patchiness = [[]]*len(attributes)
assert len(attributes) == len(methods)
fig: Figure = plt.figure(figsize=(14, 7))
numRows: int = 1
numCols: int = 1
if len(attributes) == 0: