methods.py 4.23 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 26 17:42:33 2019

@author: brandt
"""
import random
import numpy as np
from helpers import ParticleBinSorter

Josef Brandt's avatar
Josef Brandt committed
12

13 14 15 16 17 18
class SubsamplingMethod(object):
    def __init__(self, particleConatainer, desiredFraction: float = 0.2):
        super(SubsamplingMethod, self).__init__()
        self.particleContainer = particleConatainer
        self.fraction = desiredFraction

Josef Brandt's avatar
Josef Brandt committed
19 20 21 22 23 24 25 26
    @property
    def label(self) -> str:
        """
        A specific label that can be used for plots, for instance.
        :return:
        """
        raise NotImplementedError

27
    def apply_subsampling_method(self) -> list:
Josef Brandt's avatar
Josef Brandt committed
28 29 30 31
        """
        Takes all particles from the supplied particle conatiner and returns a new list of particles that
        were measured by applying that subsampling procedure. Also, the actualy measured fraction is returned.
        (The desired fraction may not always be achievable)
32
        :returns listOfActuallyMeasuredParticles:
Josef Brandt's avatar
Josef Brandt committed
33
        """
34 35
        raise NotImplementedError

36 37 38 39 40 41 42 43
    def equals(self, otherMethod) -> bool:
        """
        Checks if another provided method has the same configuration as the used instance.
        :param otherMethod:
        :return isEqual:
        """
        raise NotImplementedError

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
    def matches_any_pattern(self, patternList: list) -> bool:
        """
        Tests. wether one of the given patterns is matching.
        :param patternList:
        :return:
        """
        matches: bool = False
        for pattern in patternList:
            if self.matches_pattern(pattern):
                matches = True
                break
        return matches

    def matches_pattern(self, pattern: str) -> bool:
        """
        Tests, wether the method matches a given pattern. Strings of at least 4 characters are required!
        :param pattern: The string to test against
        :return matchesThePattern:
        """
        matches: bool = False
        if len(pattern) > 3 and not pattern == 'layout':
            matches = (self.label.lower().find(pattern.lower()) != -1)
        return matches

68

Josef Brandt's avatar
Josef Brandt committed
69
class RandomSampling(SubsamplingMethod):
Josef Brandt's avatar
Josef Brandt committed
70 71 72 73
    @property
    def label(self) -> str:
        return 'Random Subsampling'

74
    def apply_subsampling_method(self) -> list:
75 76 77
        numOrigParticles = len(self.particleContainer.particles)
        numParticles = self._get_number_of_random_particles(numOrigParticles)
        subParticles = random.sample(self.particleContainer.particles, numParticles)
78
        return subParticles
79 80 81
    
    def _get_number_of_random_particles(self, numTotalParticles):
        return np.int(np.ceil(numTotalParticles * self.fraction))
82 83 84

    def equals(self, otherMethod) -> bool:
        return type(otherMethod) == type(self) and otherMethod.fraction == self.fraction
85 86 87 88 89 90
    

class SizeBinFractioning(SubsamplingMethod):
    def __init__(self, particleConatiner, desiredfraction: float = 0.2):
        super(SizeBinFractioning, self).__init__(particleConatiner, desiredfraction)
        self.sorter: ParticleBinSorter = ParticleBinSorter()
Josef Brandt's avatar
Josef Brandt committed
91 92 93

    @property
    def label(self) -> str:
94
        return 'SizeBin Subsampling'
Josef Brandt's avatar
Josef Brandt committed
95

96
    def apply_subsampling_method(self) -> list:
97 98 99 100 101
        subParticlesPerBin: list = self._get_subParticles_per_bin(self.particleContainer.particles)
        subParticles: list = []
        for subParticleList in subParticlesPerBin:
            for particle in subParticleList:
                subParticles.append(particle)
102
        return subParticles
103 104 105 106 107 108
    
    def _get_subParticles_per_bin(self, particleList: list):
        particlesInBins: list = self.sorter.sort_particles_into_bins(particleList)
        subParticlesPerBin: list = []
        for particles in particlesInBins:
            numParticlesInBin: int = len(particles)
Josef Brandt's avatar
Josef Brandt committed
109
            numSubParticlesPerBin: int = np.int(np.round(numParticlesInBin * self.fraction))
110 111 112 113 114 115 116
            if numSubParticlesPerBin == 0 and numParticlesInBin > 0:
                numSubParticlesPerBin = 1

            subParticlesInBin: list = random.sample(particles, numSubParticlesPerBin)
            subParticlesPerBin.append(subParticlesInBin)
            
        return subParticlesPerBin
117 118 119

    def equals(self, otherMethod) -> bool:
        return type(otherMethod) == type(self) and otherMethod.fraction == self.fraction