methods.py 2.93 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 36
        raise NotImplementedError


Josef Brandt's avatar
Josef Brandt committed
37
class RandomSampling(SubsamplingMethod):
Josef Brandt's avatar
Josef Brandt committed
38 39 40 41
    @property
    def label(self) -> str:
        return 'Random Subsampling'

42
    def apply_subsampling_method(self) -> list:
43 44 45
        numOrigParticles = len(self.particleContainer.particles)
        numParticles = self._get_number_of_random_particles(numOrigParticles)
        subParticles = random.sample(self.particleContainer.particles, numParticles)
46
        return subParticles
47 48 49 50 51 52 53 54 55
    
    def _get_number_of_random_particles(self, numTotalParticles):
        return np.int(np.ceil(numTotalParticles * self.fraction))
    

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
56 57 58 59 60

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

61
    def apply_subsampling_method(self) -> list:
62 63 64 65 66
        subParticlesPerBin: list = self._get_subParticles_per_bin(self.particleContainer.particles)
        subParticles: list = []
        for subParticleList in subParticlesPerBin:
            for particle in subParticleList:
                subParticles.append(particle)
67
        return subParticles
68 69 70 71 72 73
    
    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
74
            numSubParticlesPerBin: int = np.int(np.round(numParticlesInBin * self.fraction))
75 76 77 78 79 80 81
            if numSubParticlesPerBin == 0 and numParticlesInBin > 0:
                numSubParticlesPerBin = 1

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