|
1 | 1 | import io |
| 2 | +import json |
2 | 3 | import os |
3 | 4 | import tempfile |
4 | 5 | import unittest |
5 | 6 | from unittest.mock import MagicMock, patch |
6 | 7 |
|
7 | 8 | import numpy as np |
8 | 9 |
|
| 10 | +from pytissueoptics import Sphere |
9 | 11 | from pytissueoptics.rayscattering.display.utils import Direction |
10 | 12 | from pytissueoptics.rayscattering.display.views import ( |
11 | 13 | View2DProjection, |
|
16 | 18 | ) |
17 | 19 | from pytissueoptics.rayscattering.energyLogging import EnergyLogger |
18 | 20 | from pytissueoptics.rayscattering.materials import ScatteringMaterial |
| 21 | +from pytissueoptics.rayscattering.opencl.CLScene import NO_SOLID_LABEL |
| 22 | +from pytissueoptics.rayscattering.samples import PhantomTissue |
19 | 23 | from pytissueoptics.rayscattering.scatteringScene import ScatteringScene |
20 | 24 | from pytissueoptics.scene.geometry import Vector |
21 | 25 | from pytissueoptics.scene.logger import InteractionKey |
@@ -284,3 +288,64 @@ def testWhenLogSegmentArray_shouldRaiseError(self): |
284 | 288 | def testWhenLogSegment_shouldRaiseError(self): |
285 | 289 | with self.assertRaises(NotImplementedError): |
286 | 290 | self.logger.logSegment(Vector(0, 0, 0), Vector(0, 0, 0), self.INTERACTION_KEY) |
| 291 | + |
| 292 | + def testWhenExport_shouldExport3DDataPointsToFile(self): |
| 293 | + # Use a scene that contains a stack, a sphere and a world material. |
| 294 | + scene = PhantomTissue(worldMaterial=ScatteringMaterial(0.1, 0.1, 0.99)) |
| 295 | + scene.add(Sphere(position=Vector(0, 5, 0), material=ScatteringMaterial(0.4, 0.2, 0.9))) |
| 296 | + self.logger = EnergyLogger(scene) |
| 297 | + |
| 298 | + # Log entering surface event, world scattering event and scattering event in both solids. |
| 299 | + self.logger.logDataPoint(0.1, Vector(0.7, 0.8, 0.8), InteractionKey("middleLayer")) |
| 300 | + self.logger.logDataPoint(-0.9, Vector(0.5, 1.0, 0.75), InteractionKey("frontLayer", "interface1")) |
| 301 | + self.logger.logDataPoint(0.4, Vector(0, 5, 0), InteractionKey("sphere")) |
| 302 | + self.logger.logDataPoint(0.2, Vector(0, 0, 0), InteractionKey(NO_SOLID_LABEL)) |
| 303 | + |
| 304 | + with tempfile.TemporaryDirectory() as tempDir: |
| 305 | + filePath = os.path.join(tempDir, "test_sim") |
| 306 | + self.logger.export(filePath) |
| 307 | + self.assertTrue(os.path.exists(filePath + ".csv")) |
| 308 | + |
| 309 | + with open(filePath + ".csv", "r") as f: |
| 310 | + lines = f.readlines() |
| 311 | + |
| 312 | + self.assertEqual(5, len(lines)) |
| 313 | + self.assertEqual("energy,x,y,z,solid_index,surface_index\n", lines[0]) |
| 314 | + self.assertEqual("0.2,0.0,0.0,0.0,-1,-1\n", lines[1]) |
| 315 | + self.assertEqual("0.1,0.7,0.8,0.8,1,-1\n", lines[2]) |
| 316 | + self.assertEqual("-0.9,0.5,1.0,0.75,2,5\n", lines[3]) |
| 317 | + self.assertEqual("0.4,0.0,5.0,0.0,3,-1\n", lines[4]) |
| 318 | + |
| 319 | + def testWhenExport_shouldExportMetadataToFile(self): |
| 320 | + scene = PhantomTissue(worldMaterial=ScatteringMaterial(0.1, 0.1, 0.99)) |
| 321 | + scene.add(Sphere(position=Vector(0, 5, 0), material=ScatteringMaterial(0.4, 0.2, 0.9))) |
| 322 | + self.logger = EnergyLogger(scene) |
| 323 | + |
| 324 | + with tempfile.TemporaryDirectory() as tempDir: |
| 325 | + filePath = os.path.join(tempDir, "test_sim") |
| 326 | + self.logger.export(filePath) |
| 327 | + self.assertTrue(os.path.exists(filePath + ".json")) |
| 328 | + sceneInfo = json.loads(open(filePath + ".json", "r").read()) |
| 329 | + |
| 330 | + self.assertEqual(["-1", "0", "1", "2", "3"], list(sceneInfo.keys())) |
| 331 | + |
| 332 | + expectedWorldInfo = { |
| 333 | + "label": "world", |
| 334 | + "material": { |
| 335 | + "mu_s": 0.1, |
| 336 | + "mu_a": 0.1, |
| 337 | + "mu_t": 0.2, |
| 338 | + "_albedo": 0.5, |
| 339 | + "g": 0.99, |
| 340 | + "n": 1.0, |
| 341 | + }, |
| 342 | + } |
| 343 | + self.assertEqual(expectedWorldInfo, sceneInfo["-1"]) |
| 344 | + |
| 345 | + self.assertEqual(["label", "type", "material", "geometry", "surfaces"], list(sceneInfo["0"].keys())) |
| 346 | + self.assertEqual("backLayer", sceneInfo["0"]["label"]) |
| 347 | + self.assertEqual("Cuboid", sceneInfo["0"]["type"]) |
| 348 | + expectedLayerGeometry = {"shape": [3, 3, 2], "position": [0, 0, 1], "bbox": [[-1.5, 1.5], [-1.5, 1.5], [0, 2]]} |
| 349 | + self.assertEqual(expectedLayerGeometry, sceneInfo["0"]["geometry"]) |
| 350 | + self.assertEqual(16, len(sceneInfo["0"]["surfaces"])) |
| 351 | + self.assertEqual({"label": "interface0", "normal": [0.0, 0.0, -1.0]}, sceneInfo["0"]["surfaces"]["14"]) |
0 commit comments