From 72d6409892d5b9df05f60351bb06072b7f9e1951 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Mon, 24 Apr 2023 12:40:59 +0200 Subject: Adding PupilFeatures file and PupilAnalysis folder. --- src/argaze.test/PupilAnalysis/WorkloadIndex.py | 46 +++++++ src/argaze.test/PupilAnalysis/__init__.py | 0 src/argaze.test/PupilFeatures.py | 160 +++++++++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 src/argaze.test/PupilAnalysis/WorkloadIndex.py create mode 100644 src/argaze.test/PupilAnalysis/__init__.py create mode 100644 src/argaze.test/PupilFeatures.py (limited to 'src/argaze.test') diff --git a/src/argaze.test/PupilAnalysis/WorkloadIndex.py b/src/argaze.test/PupilAnalysis/WorkloadIndex.py new file mode 100644 index 0000000..98a1e45 --- /dev/null +++ b/src/argaze.test/PupilAnalysis/WorkloadIndex.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +import unittest +import math + +from argaze import PupilFeatures +from argaze.PupilAnalysis import WorkloadIndex + +class TestWorkloadIndexClass(unittest.TestCase): + """Test WorkloadIndex class.""" + + def test_analysis(self): + """Test WorkloadIndex analysis.""" + + ts_pupil_diameters = { + 0: PupilFeatures.PupilDiameter(1.), + 1: PupilFeatures.PupilDiameter(1.1), + 2: PupilFeatures.PupilDiameter(1.2), + 3: PupilFeatures.PupilDiameter(1.3), + 4: PupilFeatures.PupilDiameter(1.2), + 5: PupilFeatures.PupilDiameter(1.1), + 6: PupilFeatures.PupilDiameter(1.), + 7: PupilFeatures.PupilDiameter(0.9), + 8: PupilFeatures.PupilDiameter(0.8), + 9: PupilFeatures.PupilDiameter(0.7) + } + + pupil_diameter_analyzer = WorkloadIndex.PupilDiameterAnalyzer(reference=PupilFeatures.PupilDiameter(1.), period=3) + ts_analysis = pupil_diameter_analyzer.browse(PupilFeatures.TimeStampedPupilDiameters(ts_pupil_diameters)) + + # Check result size + self.assertEqual(len(ts_analysis), 3) + + # Check each workload index + ts_1, analysis_1 = ts_analysis.pop_first() + self.assertTrue(math.isclose(analysis_1, 0.1, abs_tol=1e-2)) + + ts_2, analysis_2 = ts_analysis.pop_first() + self.assertTrue(math.isclose(analysis_2, 0.2, abs_tol=1e-2)) + + ts_3, analysis_3 = ts_analysis.pop_first() + self.assertTrue(math.isclose(analysis_3, 0.1, abs_tol=1e-2)) + +if __name__ == '__main__': + + unittest.main() \ No newline at end of file diff --git a/src/argaze.test/PupilAnalysis/__init__.py b/src/argaze.test/PupilAnalysis/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/argaze.test/PupilFeatures.py b/src/argaze.test/PupilFeatures.py new file mode 100644 index 0000000..6f3d03b --- /dev/null +++ b/src/argaze.test/PupilFeatures.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python + +import unittest + +from argaze import PupilFeatures + +import numpy + +def random_pupil_diameters(size): + """ Generate random TimeStampedPupilDiameters for testing purpose. + Timestamps are current time. + PupilDiameters are random values. + """ + + import random + import time + + ts_pupil_diameters = PupilFeatures.TimeStampedPupilDiameters() + + for i in range(0, size): + + # Edit pupil diameter + random_pupil_diameter = PupilFeatures.PupilDiameter(random.random()) + + # Store pupil diameter + ts_pupil_diameters[time.time()] = random_pupil_diameter + + return ts_pupil_diameters + +class TestPupilDiameterClass(unittest.TestCase): + """Test PupilDiameter class.""" + + def test_new(self): + """Test PupilDiameter creation.""" + + # Check empty PupilDiameter + empty_pupil_diameter = PupilFeatures.PupilDiameter() + + self.assertEqual(empty_pupil_diameter.value, 0.) + self.assertEqual(empty_pupil_diameter.valid, False) + + # Check float PupilDiameter + float_pupil_diameter = PupilFeatures.PupilDiameter(1.23) + + self.assertEqual(float_pupil_diameter.value, 1.23) + self.assertEqual(float_pupil_diameter.valid, True) + + def test_properties(self): + """Test PupilDiameter properties cannot be modified after creation.""" + + pupil_diameter = PupilFeatures.PupilDiameter() + + # Check that pupil diameter value setting fails + with self.assertRaises(AttributeError): + + pupil_diameter.value = 123 + + self.assertNotEqual(pupil_diameter.value, 123) + self.assertEqual(pupil_diameter.value, 0.) + + def test___repr__(self): + """Test PupilDiameter string representation.""" + + # Check empty PupilDiameter representation + self.assertEqual(repr(PupilFeatures.PupilDiameter()), "{\"value\": 0.0}") + +class TestUnvalidPupilDiameterClass(unittest.TestCase): + """Test UnvalidPupilDiameter class.""" + + def test_new(self): + """Test UnvalidPupilDiameter creation.""" + + unvalid_pupil_diameter = PupilFeatures.UnvalidPupilDiameter() + + self.assertEqual(unvalid_pupil_diameter.value, 0.) + self.assertEqual(unvalid_pupil_diameter.valid, False) + + def test___repr__(self): + """Test UnvalidPupilDiameter string representation.""" + + self.assertEqual(repr(PupilFeatures.UnvalidPupilDiameter()), "{\"message\": null, \"value\": 0.0}") + +class TestTimeStampedPupilDiametersClass(unittest.TestCase): + """Test TimeStampedPupilDiameters class.""" + + def test___setitem__(self): + """Test __setitem__ method.""" + + ts_pupil_diameters = PupilFeatures.TimeStampedPupilDiameters() + ts_pupil_diameters[0] = PupilFeatures.PupilDiameter() + ts_pupil_diameters[1] = PupilFeatures.UnvalidPupilDiameter() + ts_pupil_diameters[2] = {"value": 1.23} + + # Check PupilDiameter is correctly stored and accessible as a PupilDiameter + self.assertIsInstance(ts_pupil_diameters[0], PupilFeatures.PupilDiameter) + self.assertEqual(ts_pupil_diameters[0].valid, False) + + # Check UnvalidPupilDiameter is correctly stored and accessible as a UnvalidPupilDiameter + self.assertIsInstance(ts_pupil_diameters[1], PupilFeatures.UnvalidPupilDiameter) + self.assertEqual(ts_pupil_diameters[1].valid, False) + + # Check dict with "value" and "precision" keys is correctly stored and accessible as a PupilDiameter + self.assertIsInstance(ts_pupil_diameters[2], PupilFeatures.PupilDiameter) + self.assertEqual(ts_pupil_diameters[2].valid, True) + + # Check that bad data type insertion fails + with self.assertRaises(AssertionError): + + ts_pupil_diameters[3] = "This string is not a pupil diameter value." + + # Check that dict with bad keys insertion fails + with self.assertRaises(AssertionError): + + ts_pupil_diameters[4] = {"bad_key": 0.} + + def test___repr__(self): + """Test inherited string representation.""" + + ts_pupil_diameters = PupilFeatures.TimeStampedPupilDiameters() + + self.assertEqual(repr(PupilFeatures.TimeStampedPupilDiameters()), "{}") + + ts_pupil_diameters[0] = PupilFeatures.PupilDiameter() + + self.assertEqual(repr(ts_pupil_diameters), "{\"0\": {\"value\": 0.0}}") + + ts_pupil_diameters[0] = PupilFeatures.UnvalidPupilDiameter() + + self.assertEqual(repr(ts_pupil_diameters), "{\"0\": {\"message\": null, \"value\": 0.0}}") + + def test_as_dataframe(self): + """Test inherited as_dataframe method.""" + + ts_pupil_diameters_dataframe = random_pupil_diameters(10).as_dataframe() + + # Check dataframe conversion + self.assertEqual(ts_pupil_diameters_dataframe.index.name, "timestamp") + self.assertEqual(ts_pupil_diameters_dataframe.index.size, 10) + + self.assertEqual(ts_pupil_diameters_dataframe.columns.size, 1) + self.assertEqual(ts_pupil_diameters_dataframe.columns[0], "value") + + self.assertEqual(ts_pupil_diameters_dataframe["value"].dtype, 'float64') + + # Check unvalid diameter conversion + ts_pupil_diameters = PupilFeatures.TimeStampedPupilDiameters() + ts_pupil_diameters[0] = PupilFeatures.UnvalidPupilDiameter() + ts_pupil_diameters_dataframe = ts_pupil_diameters.as_dataframe() + + self.assertEqual(ts_pupil_diameters_dataframe.index.name, "timestamp") + self.assertEqual(ts_pupil_diameters_dataframe.index.size, 1) + + self.assertEqual(ts_pupil_diameters_dataframe.columns.size, 1) + self.assertEqual(ts_pupil_diameters_dataframe.columns[0], "value") + + self.assertEqual(ts_pupil_diameters_dataframe["value"].dtype, 'float64') + +if __name__ == '__main__': + + unittest.main() \ No newline at end of file -- cgit v1.1