test_evaluation.py 11.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 22 13:58:25 2020

@author: luna
"""

import unittest
import random
import sys
sys.path.append("C://Users//xbrjos//Desktop//Python")
import gepard
from gepard.analysis.particleAndMeasurement import Particle, Measurement

Josef Brandt's avatar
Josef Brandt committed
16 17 18
from evaluation import TotalResults, SampleResult, SubsamplingResult
import methods as meth
import geometricMethods as gmeth
19

Josef Brandt's avatar
Josef Brandt committed
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

class TestTotalResults(unittest.TestCase):
    def setUp(self) -> None:
        self.totalResults = TotalResults()

    def test_add_sample(self):
        self.totalResults.add_sample('fakePath/fakeFolder/fakeFile.pkl')
        self.assertEqual(len(self.totalResults.sampleResults), 1)

        self.totalResults.add_sample('fakePath/fakeFolder/fakeFile.pkl')  # the same file should not be added again
        self.assertEqual(len(self.totalResults.sampleResults), 1)

        self.totalResults.add_sample('fakePath/fakeFolder/fakeFile2.pkl')  # another should be added, though
        self.assertEqual(len(self.totalResults.sampleResults), 2)

        self.totalResults.add_sample('fakePath/fakeFolder/fakeFile2.txt')  # invalid extention, not added...
        self.assertEqual(len(self.totalResults.sampleResults), 2)

    def test_get_methods_for_fraction(self):
        def containsMethod(listOfMethods: list, template: meth.SubsamplingMethod) -> bool:
            contains: bool = False
            for method in listOfMethods:
                if type(method) == type(template) and method.fraction == template.fraction:
                    contains = True
                    break
            return contains

        dset: gepard.dataset.DataSet = gepard.dataset.DataSet('fakepath')

        imgdim = 10
        dset.imagescanMode = 'df'
        dset.imagedim_df = [imgdim, imgdim]
        dset.pixelscale_df = 1.0
        minX, maxX, minY, maxY = 0, 1000, 0, 1000
        dset.maxdim = minX + imgdim / 2, maxY - imgdim / 2, maxX - imgdim / 2, minY + imgdim / 2

        desiredFraction = 0.1
        methods = self.totalResults._get_methods_for_fraction(dset, desiredFraction)
        possibleRandomMethods = 2
        possibleCrossBoxMethods = 2
        possibleSpiralBoxMethods = 3
        totalPossible = possibleCrossBoxMethods + possibleRandomMethods + possibleSpiralBoxMethods
        self.assertEqual(len(methods), totalPossible)
        self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
        self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction)))
        self.assertTrue(containsMethod(methods, gmeth.CrossBoxSubSampling(dset, desiredFraction)))
        self.assertTrue(containsMethod(methods, gmeth.SpiralBoxSubsampling(dset, desiredFraction)))

        desiredFraction = 0.5
        methods = self.totalResults._get_methods_for_fraction(dset, desiredFraction)
        possibleRandomMethods = 2
        possibleCrossBoxMethods = 1
        possibleSpiralBoxMethods = 0
        totalPossible = possibleCrossBoxMethods + possibleRandomMethods + possibleSpiralBoxMethods
        self.assertEqual(len(methods), totalPossible)
        self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
        self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction)))
        self.assertTrue(containsMethod(methods, gmeth.CrossBoxSubSampling(dset, desiredFraction)))
        self.assertFalse(containsMethod(methods, gmeth.SpiralBoxSubsampling(dset, desiredFraction)))

        desiredFraction = 0.9
        methods = self.totalResults._get_methods_for_fraction(dset, desiredFraction)
        possibleRandomMethods = 2
        possibleCrossBoxMethods = 0
        possibleSpiralBoxMethods = 0
        totalPossible = possibleCrossBoxMethods + possibleRandomMethods + possibleSpiralBoxMethods
        self.assertEqual(len(methods), totalPossible)
        self.assertTrue(containsMethod(methods, meth.RandomSampling(dset, desiredFraction)))
        self.assertTrue(containsMethod(methods, meth.SizeBinFractioning(dset, desiredFraction)))
        self.assertFalse(containsMethod(methods, gmeth.CrossBoxSubSampling(dset, desiredFraction)))
        self.assertFalse(containsMethod(methods, gmeth.SpiralBoxSubsampling(dset, desiredFraction)))


class TestSampleResult(unittest.TestCase):
    def setUp(self) -> None:
        self.sampleResult: SampleResult = SampleResult('fakePath/fakeFile.pkl')
        self.sampleResult.dataset = gepard.dataset.DataSet('fakePath/fakeFile.pkl')
        self.sampleResult.results.append(SubsamplingResult(meth.RandomSampling(None, 0.1)))
        self.sampleResult.results.append(SubsamplingResult(gmeth.SpiralBoxSubsampling(None, 0.1)))
        self.sampleResult.results.append(SubsamplingResult(gmeth.SpiralBoxSubsampling(None, 0.3)))

    def test_sampleResults_added_correctly(self):
        method: meth.SubsamplingMethod = self.sampleResult.results[0].method
        self.assertTrue(type(method), meth.RandomSampling)
        self.assertTrue(method.fraction, 0.1)

        method: meth.SubsamplingMethod = self.sampleResult.results[1].method
        self.assertTrue(type(method), gmeth.SpiralBoxSubsampling)
        self.assertTrue(method.fraction, 0.1)

        method: meth.SubsamplingMethod = self.sampleResult.results[2].method
        self.assertTrue(type(method), gmeth.SpiralBoxSubsampling)
        self.assertTrue(method.fraction, 0.3)

    def test_result_is_already_present(self):
        newMethod: meth.SubsamplingMethod = meth.RandomSampling(None, 0.1)
        self.assertTrue(self.sampleResult._result_is_already_present(newMethod))
        newMethod: meth.SubsamplingMethod = meth.RandomSampling(None, 0.2)
        self.assertFalse(self.sampleResult._result_is_already_present(newMethod))

        newMethod: meth.SubsamplingMethod = gmeth.SpiralBoxSubsampling(None, 0.1)
        self.assertTrue(self.sampleResult._result_is_already_present(newMethod))
        newMethod: meth.SubsamplingMethod = gmeth.SpiralBoxSubsampling(None, 0.2)
        self.assertFalse(self.sampleResult._result_is_already_present(newMethod))

        newMethod: meth.SubsamplingMethod = gmeth.CrossBoxSubSampling(None, 0.3)
        self.assertFalse(self.sampleResult._result_is_already_present(newMethod))

    def test_remove_result_of_method(self):
        self.sampleResult._remove_result_of_method(meth.RandomSampling(None, 0.1))
        self.assertEqual(len(self.sampleResult.results), 2)

        self.sampleResult._remove_result_of_method(gmeth.SpiralBoxSubsampling(None, 0.1))
        self.assertEqual(len(self.sampleResult.results), 1)

        self.sampleResult._remove_result_of_method(gmeth.SpiralBoxSubsampling(None, 0.2))  # this is one is not present...
        self.assertEqual(len(self.sampleResult.results), 1)


class TestSubsamplingResult(unittest.TestCase):
140
    def setUp(self):
Josef Brandt's avatar
Josef Brandt committed
141 142
        self.subsamplingResult: SubsamplingResult = SubsamplingResult(meth.RandomSampling(None, 0.1))

143
    def test_get_error_per_bin(self):
Josef Brandt's avatar
Josef Brandt committed
144 145
        def get_full_and_sub_particles():
            allParticles = []
146 147 148 149 150
            subParticles = []
            for particleSize in particleSizes:
                for _ in range(numParticlesPerSizeFull):
                    mpParticle = self._get_MP_particle()
                    mpParticle.longSize = mpParticle.shortSize = particleSize
Josef Brandt's avatar
Josef Brandt committed
151
                    allParticles.append(mpParticle)
152 153 154 155 156 157
                
                for _ in range(numParticlesPerSizeSub):
                    mpParticle = self._get_MP_particle()
                    mpParticle.longSize = mpParticle.shortSize = particleSize
                    subParticles.append(mpParticle)
            
Josef Brandt's avatar
Josef Brandt committed
158
            return allParticles, subParticles
159 160 161 162 163 164
                    
        binSizes = [5, 10, 20, 50, 100, 200, 500]
        particleSizes = [upperLimit - 1 for upperLimit in binSizes]
        
        numParticlesPerSizeFull = 20
        numParticlesPerSizeSub = 10
Josef Brandt's avatar
Josef Brandt committed
165
        fullParticles, subParticles = get_full_and_sub_particles()
166
        
Josef Brandt's avatar
Josef Brandt committed
167 168
        # assume everything was measured
        bins, mpCountErrorsPerBin = self.subsamplingResult._get_mp_count_error_per_bin(fullParticles, subParticles, 1.)
169 170 171 172

        for binIndex, binError in enumerate(mpCountErrorsPerBin):
            if binIndex <= 6:
                self.assertEqual(binError, 0.5)
Josef Brandt's avatar
Josef Brandt committed
173
            else:   # it's the last and largest bin, no particles where added there
174 175
                self.assertEqual(binError, 0)
        
Josef Brandt's avatar
Josef Brandt committed
176 177
        # assume only 50 % was measured
        bins, mpCountErrorsPerBin = self.subsamplingResult._get_mp_count_error_per_bin(fullParticles, subParticles, 0.5)
178 179 180 181 182 183 184 185 186 187 188 189

        for binIndex, binError in enumerate(mpCountErrorsPerBin):
            self.assertEqual(binError, 0)

    def test_get_number_of_MP_particles(self):
        mpParticles = self._get_MP_particles(5)
        numMPParticles = len(mpParticles)
        
        nonMPparticles = self._get_non_MP_particles(50)
        
        allParticles = mpParticles + nonMPparticles
        
Josef Brandt's avatar
Josef Brandt committed
190
        calculatedNumMPParticles = self.subsamplingResult._get_number_of_MP_particles(allParticles)
191 192 193 194 195 196 197 198 199
        self.assertEqual(numMPParticles, calculatedNumMPParticles)

    def test_get_mp_count_error(self):
        mpParticles1 = self._get_MP_particles(20)
        nonMPparticles1 = self._get_non_MP_particles(20)
        origParticles = mpParticles1 + nonMPparticles1
        
        mpParticles2 = self._get_MP_particles(30)
        estimateParticles = mpParticles2 + nonMPparticles1
Josef Brandt's avatar
Josef Brandt committed
200
        mpCountError = self.subsamplingResult._get_mp_count_error(origParticles, estimateParticles, 1.0)
201 202 203 204
        self.assertEqual(mpCountError, 0.5)
        
        mpParticles2 = self._get_MP_particles(20)
        estimateParticles = mpParticles2 + nonMPparticles1
Josef Brandt's avatar
Josef Brandt committed
205
        mpCountError = self.subsamplingResult._get_mp_count_error(origParticles, estimateParticles, 1.0)
206 207
        self.assertEqual(mpCountError, 0)
        
Josef Brandt's avatar
Josef Brandt committed
208
        mpCountError = self.subsamplingResult._get_mp_count_error(origParticles, estimateParticles, 0.5)
209 210 211 212
        self.assertEqual(mpCountError, 1.0)
    
    def test_get_error_from_values(self):
        exact, estimate = 100, 90
Josef Brandt's avatar
Josef Brandt committed
213
        error = self.subsamplingResult._get_error_from_values(exact, estimate)
214 215 216
        self.assertEqual(error, 0.1)
       
        exact, estimate = 100, 110
Josef Brandt's avatar
Josef Brandt committed
217
        error = self.subsamplingResult._get_error_from_values(exact, estimate)
218 219 220
        self.assertEqual(error, 0.1)
        
        exact, estimate = 100, 50
Josef Brandt's avatar
Josef Brandt committed
221
        error = self.subsamplingResult._get_error_from_values(exact, estimate)
222 223 224
        self.assertEqual(error, 0.5)
        
        exact, estimate = 100, 150
Josef Brandt's avatar
Josef Brandt committed
225
        error = self.subsamplingResult._get_error_from_values(exact, estimate)
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
        self.assertEqual(error, 0.5)        
        
    def _get_MP_particles(self, numParticles):
        mpParticles = []
        for _ in range(numParticles):
            mpParticles.append(self._get_MP_particle())
        return mpParticles
    
    def _get_non_MP_particles(self, numParticles):
        nonMPParticles = []
        for _ in range(numParticles):
            nonMPParticles.append(self._get_non_MP_particle())
        return nonMPParticles
    
    def _get_MP_particle(self):
        polymerNames = ['Poly (methyl methacrylate',
                        'Polyethylene',
                        'Silicone rubber',
                        'PB15',
                        'PY13',
                        'PR20']
        polymName = random.sample(polymerNames, 1)[0]
        newParticle = Particle()
        newMeas = Measurement()
        newMeas.setAssignment(polymName)
        newParticle.addMeasurement(newMeas)
        return newParticle

    def _get_non_MP_particle(self):
        newParticle = Particle()
        newParticle.addMeasurement(Measurement())        
        return newParticle