Skip to content

Commit

Permalink
Merge pull request #3 from well-id/devel
Browse files Browse the repository at this point in the history
Instantiating EFLRObjects directly
  • Loading branch information
the-mysh authored Dec 7, 2023
2 parents 50ae906 + 13b7b87 commit a057836
Show file tree
Hide file tree
Showing 23 changed files with 153 additions and 89 deletions.
5 changes: 3 additions & 2 deletions examples/create_synth_dlis.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging

from dlis_writer.writer.file import DLISFile
from dlis_writer.logical_record.eflr_types import Origin
from dlis_writer.logical_record.eflr_types.origin import OriginObject
from dlis_writer.utils.logging import install_logger
from dlis_writer.utils.enums import RepresentationCode

Expand All @@ -14,7 +14,8 @@


# set up origin & file header with custom parameters - by creating an instance or dict of kwargs
origin = Origin.make_object("DEFAULT ORIGIN", file_set_number=1, company="XXX")
origin = OriginObject("DEFAULT ORIGIN", file_set_number=1, company="XXX")
origin.creation_time.value = datetime(year=2023, month=12, day=6, hour=12, minute=30, second=5)
file_header = {'sequence_number': 2}


Expand Down
23 changes: 16 additions & 7 deletions src/dlis_writer/logical_record/core/eflr/eflr.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,20 @@ def _make_body_bytes(self) -> bytes:

return bts

def register_child(self, child: EFLRObject):
"""Register a child EFLRObject with this EFLR."""

if not isinstance(child, self.object_type):
raise TypeError(f"Expected an instance of {self.object_type}; got {type(child)}: {child}")

self._object_dict[child.name] = child

if len(self._object_dict) == 1:
for attr_name, attr in child.attributes.items():
self._attributes[attr_name] = attr.copy()

child.origin_reference = self.origin_reference

def make_object_in_this_set(self, name: str, get_if_exists: bool = False, **kwargs) -> EFLRObject:
"""Make an EFLRObject according the specifications and register it with this EFLR instance.
Expand All @@ -126,14 +140,9 @@ def make_object_in_this_set(self, name: str, get_if_exists: bool = False, **kwar
if get_if_exists and name in self._object_dict:
return self._object_dict[name]

obj = self.object_type(name, self, **kwargs)
self._object_dict[name] = obj

if len(self._object_dict) == 1:
for attr_name, attr in obj.attributes.items():
self._attributes[attr_name] = attr.copy()
obj = self.object_type(name, parent=self, **kwargs)

obj.origin_reference = self.origin_reference
self.register_child(obj)

return obj

Expand Down
1 change: 0 additions & 1 deletion src/dlis_writer/logical_record/core/eflr/eflr_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from typing_extensions import Self

from dlis_writer.logical_record.core.logical_record import LRMeta
from dlis_writer.logical_record.core.eflr.eflr_object import EFLRObject

if TYPE_CHECKING:
from dlis_writer.logical_record.core.eflr.eflr import EFLR
Expand Down
39 changes: 34 additions & 5 deletions src/dlis_writer/logical_record/core/eflr/eflr_object.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
from functools import cached_property
from typing import TYPE_CHECKING, Any, Union
from typing import TYPE_CHECKING, Any, Union, Optional

from dlis_writer.utils.struct_writer import write_struct_obname
from dlis_writer.logical_record.core.attribute.attribute import Attribute
Expand All @@ -15,12 +15,15 @@
class EFLRObject:
"""Model an object belonging to an Explicitly Formatted Logical Record - e.g. a particular channel."""

def __init__(self, name: str, parent: "EFLR", **kwargs):
parent_eflr_class: type["EFLR"] = NotImplemented

def __init__(self, name: str, parent: Optional["EFLR"] = None, set_name: Optional[str] = None, **kwargs):
"""Initialise an EFLRObject.
Args:
name : Name of the object. This will be the name it is stored with in the created DLIS file.
parent : EFLR instance this object belongs to.
parent : EFLR instance this object belongs to. If not provided, retrieved/made based on set_name.
set_name : Set name of the parent EFLR instance.
**kwargs : Values to be set in attributes of this object.
Note:
Expand All @@ -30,14 +33,40 @@ def __init__(self, name: str, parent: "EFLR", **kwargs):
"""

self.name = name #: name of the object
self.parent = parent #: EFLR instance this object belongs to
self.name = name #: name of the object
self.parent = self._get_parent(parent=parent, set_name=set_name) #: EFLR instance this object belongs to
self.parent.register_child(self)

self.origin_reference: Union[int, None] = None #: origin reference value, common for records sharing origin
self.copy_number = 0 #: copy number of the object

self.set_attributes(**{k: v for k, v in kwargs.items() if v is not None})

@classmethod
def _get_parent(cls, parent: Optional["EFLR"] = None, set_name: Optional[str] = None) -> "EFLR":
"""Validate, retrieve, or create a parent EFLR instance.
Args:
parent : Parent EFLR instance. If not provided, set_name will be used to retrieve/make one.
set_name : Set name of the parent EFLR instance. If parent is provided, it is checked against its
set_name.
Returns:
The parent EFLR instance.
"""

if parent is not None:
if not isinstance(parent, cls.parent_eflr_class):
raise TypeError(f"Expected an instance of {cls.parent_eflr_class.__name__}; "
f"got a {type(parent)}: {parent}")
if parent.set_name != set_name and set_name is not None:
raise ValueError(f"The provided set name: {set_name} does not match the set name of the "
f"provided parent EFLR: {parent.set_name}")

return parent

return cls.parent_eflr_class.get_or_make_eflr(set_name=set_name)

@property
def attributes(self) -> dict[str, Attribute]:
"""Attributes defined for this EFLRObject (sub)class with its values for the current instance."""
Expand Down
7 changes: 4 additions & 3 deletions src/dlis_writer/logical_record/eflr_types/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ class AxisObject(EFLRObject):

parent: "Axis"

def __init__(self, name: str, parent: "Axis", **kwargs):
def __init__(self, name: str, **kwargs):
"""Initialise AxisObject.
Args:
name : Name of the AxisObject.
parent : Axis EFLR instance this AxisObject belongs to.
**kwargs : Values of to be set as characteristics of the AxisObject Attributes.
"""

Expand All @@ -22,7 +21,7 @@ def __init__(self, name: str, parent: "Axis", **kwargs):
converter=self.convert_maybe_numeric)
self.spacing = NumericAttribute('spacing', parent_eflr=self)

super().__init__(name, parent, **kwargs)
super().__init__(name, **kwargs)


class Axis(EFLR):
Expand All @@ -32,3 +31,5 @@ class Axis(EFLR):
logical_record_type = EFLRType.AXIS
object_type = AxisObject


AxisObject.parent_eflr_class = Axis
20 changes: 11 additions & 9 deletions src/dlis_writer/logical_record/eflr_types/calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ class CalibrationMeasurementObject(EFLRObject):

parent: "CalibrationMeasurement"

def __init__(self, name: str, parent: "CalibrationMeasurement", **kwargs):
def __init__(self, name: str, **kwargs):
"""Initialise CalibrationMeasurementObject.
Args:
name : Name of the CalibrationMeasurementObject.
parent : CalibrationMeasurement EFLR instance this CalibrationMeasurementObject belongs to.
**kwargs : Values of to be set as characteristics of the CalibrationMeasurementObject Attributes.
"""

Expand All @@ -42,7 +41,7 @@ def __init__(self, name: str, parent: "CalibrationMeasurement", **kwargs):
self.plus_tolerance = NumericAttribute('plus_tolerance', multivalued=True, parent_eflr=self)
self.minus_tolerance = NumericAttribute('minus_tolerance', multivalued=True, parent_eflr=self)

super().__init__(name, parent, **kwargs)
super().__init__(name, **kwargs)


class CalibrationMeasurement(EFLR):
Expand All @@ -58,12 +57,11 @@ class CalibrationCoefficientObject(EFLRObject):

parent: "CalibrationCoefficient"

def __init__(self, name: str, parent: "CalibrationCoefficient", **kwargs):
def __init__(self, name: str, **kwargs):
"""Initialise CalibrationCoefficientObject.
Args:
name : Name of the CalibrationCoefficientObject.
parent : CalibrationCoefficient EFLR instance this CalibrationCoefficientObject belongs to.
**kwargs : Values of to be set as characteristics of the CalibrationCoefficientObject Attributes.
"""

Expand All @@ -73,7 +71,7 @@ def __init__(self, name: str, parent: "CalibrationCoefficient", **kwargs):
self.plus_tolerances = NumericAttribute('plus_tolerances', multivalued=True, parent_eflr=self)
self.minus_tolerances = NumericAttribute('minus_tolerances', multivalued=True, parent_eflr=self)

super().__init__(name, parent, **kwargs)
super().__init__(name, **kwargs)


class CalibrationCoefficient(EFLR):
Expand All @@ -89,12 +87,11 @@ class CalibrationObject(EFLRObject):

parent: "Calibration"

def __init__(self, name: str, parent: "Calibration", **kwargs):
def __init__(self, name: str, **kwargs):
"""Initialise CalibrationObject.
Args:
name : Name of the CalibrationObject.
parent : Calibration EFLR instance this CalibrationObject belongs to.
**kwargs : Values of to be set as characteristics of the CalibrationObject Attributes.
"""

Expand All @@ -109,7 +106,7 @@ def __init__(self, name: str, parent: "Calibration", **kwargs):
self.parameters = EFLRAttribute('parameters', object_class=Parameter, multivalued=True, parent_eflr=self)
self.method = Attribute('method', representation_code=RepC.IDENT, parent_eflr=self)

super().__init__(name, parent, **kwargs)
super().__init__(name, **kwargs)


class Calibration(EFLR):
Expand All @@ -118,3 +115,8 @@ class Calibration(EFLR):
set_type = 'CALIBRATION'
logical_record_type = EFLRType.STATIC
object_type = CalibrationObject


CalibrationMeasurementObject.parent_eflr_class = CalibrationMeasurement
CalibrationCoefficientObject.parent_eflr_class = CalibrationCoefficient
CalibrationObject.parent_eflr_class = Calibration
8 changes: 5 additions & 3 deletions src/dlis_writer/logical_record/eflr_types/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ class ChannelObject(EFLRObject):

parent: "Channel"

def __init__(self, name, parent: "Channel", dataset_name: Optional[str] = None, **kwargs):
def __init__(self, name, dataset_name: Optional[str] = None, **kwargs):
"""Initialise ChannelObject.
Args:
name : Name of the ChannelObject.
parent : Channel EFLR instance this ChannelObject belongs to.
dataset_name : Name of the data corresponding to this channel in the SourceDataObject.
**kwargs : Values of to be set as characteristics of the ChannelObject Attributes.
"""
Expand All @@ -47,7 +46,7 @@ def __init__(self, name, parent: "Channel", dataset_name: Optional[str] = None,

self._dataset_name: Union[str, None] = dataset_name

super().__init__(name, parent, **kwargs)
super().__init__(name, **kwargs)

self.set_defaults()

Expand Down Expand Up @@ -157,3 +156,6 @@ class Channel(EFLR):
set_type = 'CHANNEL'
logical_record_type = EFLRType.CHANNL
object_type = ChannelObject


ChannelObject.parent_eflr_class = Channel
8 changes: 5 additions & 3 deletions src/dlis_writer/logical_record/eflr_types/computation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ class ComputationObject(EFLRObject):

parent: "Computation"

def __init__(self, name: str, parent: "Computation", **kwargs):
def __init__(self, name: str, **kwargs):
"""Initialise ComputationObject.
Args:
name : Name of the ComputationObject.
parent : Computation EFLR instance this ComputationObject belongs to.
**kwargs : Values of to be set as characteristics of the ComputationObject Attributes.
"""

Expand All @@ -32,7 +31,7 @@ def __init__(self, name: str, parent: "Computation", **kwargs):
self.values = NumericAttribute('values', multivalued=True, parent_eflr=self)
self.source = EFLRAttribute('source', parent_eflr=self)

super().__init__(name, parent, **kwargs)
super().__init__(name, **kwargs)

self._set_defaults()
self.check_values_and_zones()
Expand All @@ -58,3 +57,6 @@ class Computation(EFLR):
set_type = 'COMPUTATION'
logical_record_type = EFLRType.STATIC
object_type = ComputationObject


ComputationObject.parent_eflr_class = Computation
7 changes: 4 additions & 3 deletions src/dlis_writer/logical_record/eflr_types/equipment.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ class EquipmentObject(EFLRObject):

parent: "Equipment"

def __init__(self, name: str, parent: "Equipment", **kwargs):
def __init__(self, name: str, **kwargs):
"""Initialise EquipmentObject.
Args:
name : Name of the EquipmentObject.
parent : Equipment EFLR instance this EquipmentObject belongs to.
**kwargs : Values of to be set as characteristics of the EquipmentObject Attributes.
"""

Expand All @@ -35,7 +34,7 @@ def __init__(self, name: str, parent: "Equipment", **kwargs):
self.radial_drift = NumericAttribute('radial_drift', parent_eflr=self)
self.angular_drift = NumericAttribute('angular_drift', parent_eflr=self)

super().__init__(name, parent, **kwargs)
super().__init__(name, **kwargs)


class Equipment(EFLR):
Expand All @@ -45,3 +44,5 @@ class Equipment(EFLR):
logical_record_type = EFLRType.STATIC
object_type = EquipmentObject


EquipmentObject.parent_eflr_class = Equipment
7 changes: 4 additions & 3 deletions src/dlis_writer/logical_record/eflr_types/file_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ class FileHeaderObject(EFLRObject):

identifier_length_limit = 65 #: max length of the file header name

def __init__(self, identifier: str, parent: "FileHeader", sequence_number: int = 1, **kwargs):
def __init__(self, identifier: str, sequence_number: int = 1, **kwargs):
"""Initialise FileHeaderObject.
Args:
identifier : Name of the FileHeaderObject.
parent : FileHeader EFLR instance this FileHeaderObject belongs to.
sequence_number : Sequence number of the file.
**kwargs : Values of to be set as characteristics of the FileHeaderObject Attributes.
"""
Expand All @@ -34,7 +33,7 @@ def __init__(self, identifier: str, parent: "FileHeader", sequence_number: int =
if len(identifier) > self.identifier_length_limit:
raise ValueError(f"'identifier' length should not exceed {self.identifier_length_limit} characters")

super().__init__(name='0', parent=parent, **kwargs)
super().__init__(name='0', **kwargs)

def _make_attrs_bytes(self) -> bytes:
"""Create bytes describing the values of attributes of FIleHeaderObject."""
Expand Down Expand Up @@ -73,3 +72,5 @@ def _make_template_bytes(self) -> bytes:

return bts


FileHeaderObject.parent_eflr_class = FileHeader
8 changes: 5 additions & 3 deletions src/dlis_writer/logical_record/eflr_types/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ class FrameObject(EFLRObject):
'VERTICAL-DEPTH'
)

def __init__(self, name: str, parent: "Frame", **kwargs):
def __init__(self, name: str, **kwargs):
"""Initialise FrameObject.
Args:
name : Name of the FrameObject.
parent : Frame EFLR instance this FrameObject belongs to.
**kwargs : Values of to be set as characteristics of the FrameObject Attributes.
"""

Expand All @@ -46,7 +45,7 @@ def __init__(self, name: str, parent: "Frame", **kwargs):
self.index_min = NumericAttribute('index_min', parent_eflr=self)
self.index_max = NumericAttribute('index_max', parent_eflr=self)

super().__init__(name, parent, **kwargs)
super().__init__(name, **kwargs)

@classmethod
def parse_index_type(cls, value: str) -> str:
Expand Down Expand Up @@ -136,3 +135,6 @@ class Frame(EFLR):
set_type = 'FRAME'
logical_record_type = EFLRType.FRAME
object_type = FrameObject


FrameObject.parent_eflr_class = Frame
Loading

0 comments on commit a057836

Please sign in to comment.