Skip to content

Commit

Permalink
Added drusen saving in data_path/.eyepy folder. Added function to rec…
Browse files Browse the repository at this point in the history
…ompute drusen if needed with a custom drusenfinder
  • Loading branch information
Oli4 committed Sep 22, 2020
1 parent 2ee6f41 commit 40ed65d
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 13 deletions.
39 changes: 36 additions & 3 deletions eyepy/core/octbase.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import hashlib
import warnings
from abc import ABC, abstractmethod
from pathlib import Path

import numpy as np
from matplotlib import cm, colors, patches
Expand All @@ -15,14 +17,14 @@

class Oct(ABC):

def __new__(cls, bscans, slo, meta, *args, **kwargs):
def __new__(cls, bscans, slo, meta, data_path, *args, **kwargs):
# Set all the meta fields as attributes
for meta_attr in meta._meta_fields:
setattr(cls, meta_attr, _get_meta_attr(meta_attr))
return object.__new__(cls, *args, **kwargs)

@abstractmethod
def __init__(self, bscans, enfacereader, meta,
def __init__(self, bscans, enfacereader, meta, data_path,
drusenfinder=DefaultDrusenFinder(),
eyequantifier=DefaultEyeQuantifier()):
"""
Expand All @@ -41,6 +43,10 @@ def __init__(self, bscans, enfacereader, meta,
self._drusenfinder = drusenfinder
self._eyequantifier = eyequantifier

# Create a visit_id for saving visit related files
self._eyepy_id = None
self.data_path = Path(data_path)
self.drusen_path = self.data_path / ".eyepy" / f"{self.eyepy_id}_drusen_map.npy"
self._drusen = None
self._drusen_raw = None
self._segmentation_raw = None
Expand All @@ -66,6 +72,15 @@ def __len__(self):
""" The number of B-Scans """
return len(self._bscans)

@property
def eyepy_id(self):
if self._eyepy_id is None:
# Compute a hash of the first B-Scan as ID
sha1 = hashlib.sha1()
sha1.update(self[0].scan.tobytes())
self._eyepy_id = sha1.hexdigest()
return self._eyepy_id

@property
@abstractmethod
def shape(self):
Expand Down Expand Up @@ -148,7 +163,25 @@ def drusen(self):
Here the `filter` function of the DrusenFinder has been applied
"""
if self._drusen is None:
self._drusen = self._drusenfinder.filter(self.drusen_raw)
# Try to load the drusen from the default location
try:
self._drusen = np.load(self.drusen_path)
except FileNotFoundError:
self._drusen = self._drusenfinder.filter(self.drusen_raw)
self.drusen_path.parent.mkdir(parents=True, exist_ok=True)
np.save(self.drusen_path, self._drusen)
return self._drusen

def drusen_recompute(self, drusenfinder=None):
""" Recompute Drusen optionally with a custom DrusenFinder
Use this if you do not like the computed / loaded drusen
"""
if drusenfinder is not None:
self._drusenfinder = drusenfinder

self._drusen_raw = self._drusenfinder.find(self)
self._drusen = self._drusenfinder.filter(self.drusen_raw)
return self._drusen

@property
Expand Down
28 changes: 18 additions & 10 deletions eyepy/io/heyex/heyex.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class HeyexOct(Oct):
"""

def __init__(self, bscans, slo, meta):
def __init__(self, bscans, slo, meta, data_path):
"""
Parameters
Expand All @@ -53,7 +53,7 @@ def __init__(self, bscans, slo, meta):
slo :
meta :
"""
super().__init__(bscans, slo, meta)
super().__init__(bscans, slo, meta, data_path)

@property
def shape(self):
Expand All @@ -64,18 +64,26 @@ def fovea_pos(self):
return self.SizeXSlo / 2, self.SizeYSlo / 2

@classmethod
def read_vol(cls, file_obj):
def read_vol(cls, file_obj, data_path):
meta = he_vol.get_octmeta(file_obj)
bscans = he_vol.get_bscans(file_obj, meta)
slo = he_vol.get_slo(file_obj, meta)
return cls(bscans, slo, meta)
return cls(bscans, slo, meta, data_path=data_path)

@classmethod
def read_xml(cls, filepath):
meta = he_xml.get_octmeta(filepath)
bscans = he_xml.get_bscans(filepath)
slo = he_xml.get_slo(filepath)
return cls(bscans, slo, meta)
path = Path(filepath)
if not path.suffix == ".xml":
xmls = list(path.glob("*.xml"))
if len(xmls) == 0:
raise FileNotFoundError("There is no .xml file under the given filepath")
elif len(xmls) > 1:
raise ValueError("There is more than one .xml file under the given filepath.")
path = xmls[0]
meta = he_xml.get_octmeta(path)
bscans = he_xml.get_bscans(path)
slo = he_xml.get_slo(path)
return cls(bscans, slo, meta, data_path=path.parent)

@classmethod
def from_images(cls, images):
Expand All @@ -97,10 +105,10 @@ def read_vol(file_obj: Union[str, Path, IO]):
if type(file_obj) is str or type(file_obj) is PosixPath:
with open(file_obj, "rb") as myfile:
mm = mmap.mmap(myfile.fileno(), 0, access=mmap.ACCESS_READ)
return HeyexOct.read_vol(mm)
return HeyexOct.read_vol(mm, data_path=Path(file_obj).parent)
else:
mm = mmap.mmap(file_obj.fileno(), 0, access=mmap.ACCESS_READ)
return HeyexOct.read_vol(mm)
return HeyexOct.read_vol(mm, data_path=Path(file_obj.name).parent)


def read_xml(filepath: Union[str, Path]):
Expand Down

0 comments on commit 40ed65d

Please sign in to comment.