methods.py 3.43 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

Josef Brandt's avatar
Josef Brandt committed
45
class RandomSampling(SubsamplingMethod):
Josef Brandt's avatar
Josef Brandt committed
46 47 48 49
    @property
    def label(self) -> str:
        return 'Random Subsampling'

50
    def apply_subsampling_method(self) -> list:
51 52 53
        numOrigParticles = len(self.particleContainer.particles)
        numParticles = self._get_number_of_random_particles(numOrigParticles)
        subParticles = random.sample(self.particleContainer.particles, numParticles)
54
        return subParticles
55 56 57
    
    def _get_number_of_random_particles(self, numTotalParticles):
        return np.int(np.ceil(numTotalParticles * self.fraction))
58 59 60

    def equals(self, otherMethod) -> bool:
        return type(otherMethod) == type(self) and otherMethod.fraction == self.fraction
61 62 63 64 65 66
    

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
67 68 69 70 71

    @property
    def label(self) -> str:
        return 'SizeBin Random Subsampling'

72
    def apply_subsampling_method(self) -> list:
73 74 75 76 77
        subParticlesPerBin: list = self._get_subParticles_per_bin(self.particleContainer.particles)
        subParticles: list = []
        for subParticleList in subParticlesPerBin:
            for particle in subParticleList:
                subParticles.append(particle)
78
        return subParticles
79 80 81 82 83 84
    
    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
85
            numSubParticlesPerBin: int = np.int(np.round(numParticlesInBin * self.fraction))
86 87 88 89 90 91 92
            if numSubParticlesPerBin == 0 and numParticlesInBin > 0:
                numSubParticlesPerBin = 1

            subParticlesInBin: list = random.sample(particles, numSubParticlesPerBin)
            subParticlesPerBin.append(subParticlesInBin)
            
        return subParticlesPerBin
93 94 95

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