Skip to content

Commit

Permalink
Merge pull request #51 from ErlendHaa/metadata-objects
Browse files Browse the repository at this point in the history
Add Tool, Parameter and Calibration objects to Python interface
  • Loading branch information
ErlendHaa authored Feb 27, 2019
2 parents 86d6735 + 3ddd813 commit 529568a
Show file tree
Hide file tree
Showing 3 changed files with 345 additions and 26 deletions.
30 changes: 30 additions & 0 deletions python/dlisio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,36 @@ def frames(self):
"""
return self._objects.frames

@property
def tools(self):
""" Read all Tool metadata objects
Returns
-------
tools: generator of Tool objects
"""
return self._objects.tools

@property
def parameters(self):
""" Read all Parameter metadata objects
Returns
-------
parameters: generator of Parameter objects
"""
return self._objects.parameters

@property
def calibrations(self):
""" Read all Calibration objects
Returns
-------
calibrations: generator of Calibration objects
"""
return self._objects.calibrations

@property
def unknowns(self):
return self._objects.unknowns
Expand Down
267 changes: 243 additions & 24 deletions python/dlisio/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ def __init__(self, objects):

for os in objects:
for obj in os.objects:
if os.type == "FRAME" : obj = Frame(obj)
elif os.type == "CHANNEL" : obj = Channel(obj)
if os.type == "FRAME" : obj = Frame(obj)
elif os.type == "CHANNEL" : obj = Channel(obj)
elif os.type == "TOOL" : obj = Tool(obj)
elif os.type == "PARAMETER" : obj = Parameter(obj)
elif os.type == "CALIBRATION" : obj = Calibration(obj)
else: obj = Unknown(obj)
self.objects.append(obj)

Expand All @@ -47,14 +50,23 @@ def link(self, obj):
if o.name == obj.source.name: obj.source = o

if obj.type == "frame":
obj.channels = [r for r in self.channels if r.name in obj.channels]
obj.channels = [o for o in self.channels if obj.haschannel(o.name)]

if obj.type == "tool":
obj.channels = [o for o in self.channels if obj.haschannel(o.name)]
obj.parameters = [o for o in self.parameters if obj.hasparameter(o.name)]

if obj.type == "calibration":
obj.uncal_ch = [o for o in self.channels if obj.hasuncalibrated_channel(o.name)]
obj.cal_ch = [o for o in self.channels if obj.hascalibrated_channel(o.name)]
obj.parameters = [o for o in self.parameters if obj.hasparameter(o.name)]

def getobject(self, name, type):
""" return object corresponding to the unique identifier given by name + type
Parameters
----------
name : tuple or dlisio.core.obname
name : tuple(str, int, int) or dlisio.core.obname
type : str
Returns
Expand Down Expand Up @@ -99,6 +111,21 @@ def frames(self):
"""Frame objects"""
return (o for o in self.objects if o.type == "frame")

@property
def tools(self):
"""Tool objects"""
return (o for o in self.objects if o.type == "tool")

@property
def parameters(self):
"""Parameter objects"""
return (o for o in self.objects if o.type == "parameter")

@property
def calibrations(self):
"""Calibration objects"""
return (o for o in self.objects if o.type == "calibration")

@property
def unknowns(self):
"""Frame objects"""
Expand Down Expand Up @@ -136,6 +163,53 @@ def __str__(self):
s += "\t{}: {}\n".format(key, value)
return s

@staticmethod
def contains(base, name):
""" Check if base cotains obj
Parameters:
----------
base : list of dlis.core.obname or list of any object derived from
basic_object, e.g. Channel, Frame
obj : dlis.core.obname, tuple (str, int, int)
Returns
-------
isin : bool
True if obj or (name, type) is in base, else False
Examples
--------
Check if "frame" contain channel:
>>> ans = contains(frame.channels, obj=channel.name)
Check if "frame" contains a channel with name:
>>> name = ("TDEP", 2, 0)
>>> ans = contains(frame.channels, name)
find all frames that have "channel":
>>> fr = [o for o in frames if contains(o.channels, obj=channel.name)]
"""
child = None
parents = None

if isinstance(name, core.obname):
child = (name.id, name.origin, name.copynumber)
else:
child = name
try:
parents = [(o.id, o.origin, o.copynumber) for o in base]
except AttributeError:
parents = [(o.name.id, o.name.origin, o.name.copynumber) for o in base]

if any(child == p for p in parents): return True

return False

class Channel(basic_object):
"""
The Channel object reflects the logical record type CHANNEL (listed in
Expand Down Expand Up @@ -170,23 +244,15 @@ def hassource(self, obj):
Parameters
----------
obj : dlis.core.obname or any object class derived from basic_object
obj : dlis.core.obname or tuple(str, int, int)
Returns
-------
issource : bool
True if obj is the source of channel, else False
"""
if self.source is None: return False

if isinstance(obj, core.obname): child = obj
else : child = obj.name

if isinstance(self.source, core.obname): parent = self.source
else : parent = self.source.name

return parent == child
return self.contains(self.source, obj)

class Frame(basic_object):
"""
Expand Down Expand Up @@ -223,25 +289,178 @@ def haschannel(self, channel):
Parameters
----------
channel : dlis.core.obname or Channel object
channel : dlis.core.obname or tuple(str, int, int)
Returns
-------
haschannel : bool
True if Frame has the channel obj, else False
"""
if len(self.channels) == 0: return False
return self.contains(self.channels, channel)

class Tool(basic_object):
"""
The tool object reflects the logical record type TOOL (listed in Appendix
A.2 - Logical Record Types, described in Chapter 5.8.4 - Static and Frame
Data, TOOL objects)
"""
def __init__(self, obj):
super().__init__(obj, "tool")
self.description = None
self.trademark_name = None
self.generic_name = None
self.status = None
self.parts = []
self.channels = []
self.parameters = []

if isinstance(channel, core.obname): child = channel
else : child = channel.name
for attr in obj.values():
if attr.value is None: continue
if attr.label == "DESCRIPTION" : self.description = attr.value[0]
if attr.label == "TRADEMARK-NAME" : self.trademark_name = attr.value[0]
if attr.label == "GENERIC-NAME" : self.generic_name = attr.value[0]
if attr.label == "STATUS" : self.status = attr.value[0]
if attr.label == "PARTS" : self.parts = attr.value
if attr.label == "CHANNELS" : self.channels = attr.value
if attr.label == "PARAMETERS" : self.parameters = attr.value

for ch in self.channels:
if isinstance(ch, core.obname):
if ch == child: return True
if isinstance(ch, Channel):
if ch.name == child: return True
return False
def haschannel(self, channel):
"""
Return True if channels is in tool.channels,
else return False
Parameters
----------
channel : dlis.core.obname or tuple(str, int, int)
Returns
-------
haschannel : bool
True if Tool has the channel obj, else False
"""
return self.contains(self.channels, channel)

def hasparameter(self, param):
"""
Return True if param is in tool.parameters,
else return False
Parameters
----------
param : dlis.core.obname or tuple(str, int, int)
Returns
-------
hasparam : bool
True if Tool has the parameter obj, else False
"""
return self.contains(self.parameters, param)


class Parameter(basic_object):
"""
The Parameter object reflects the logical record type PARAMETER (listed in
Appendix A.2 - Logical Record Types, described in Chapter 5.8.2 - Static
and Frame Data, PARAMETER objects)
"""
def __init__(self, obj):
super().__init__(obj, "parameter")
self.long_name = None
self.dimension = None
self.axis = None
self.zones = None
self.values = None

for attr in obj.values():
if attr.value is None: continue
if attr.label == "LONG-NAME" : self.long_name = attr.value[0]
if attr.label == "DIMENSION" : self.dimension = attr.value
if attr.label == "AXIS" : self.axis = attr.value
if attr.label == "ZONES" : self.zones = attr.value

class Calibration(basic_object):
"""
The Calibration reflects the logical record type CALIBRATION (listed in
Appendix A.2 - Logical Record Types, described in Chapter 5.8.7.3 - Static and
Frame Data, CALIBRATION objects)
The calibrated_channels and uncalibrated_channels attributes are lists of
refrences to Channel objects.
"""
def __init__(self, obj):
super().__init__(obj, "calibration")
self.method = None
self.calibrated_channel = []
self.uncalibrated_channel = []
self.coefficients = []
self.parameters = []

for attr in obj.values():
if attr.value is None: continue
if attr.label == "METHOD":
self.method = attr.value[0]
if attr.label == "CALIBRATED-CHANNELS":
self.calibrated_channel = attr.value
if attr.label == "UNCALIBRATED-CHANNELS":
self.uncalibrated_channel = attr.value
if attr.label == "COEFFICIENTS":
self.coefficients = attr.value
if attr.label == "PARAMETERS":
self.parameters = attr.value

def hasuncalibrated_channel(self, channel):
"""
Return True if channels is in Calibration.uncal_ch,
else return False
Parameters
----------
channel : dlis.core.obname or tuple(str, int, int)
Returns
-------
hasuncalchannel : bool
True if Calibration has the channel obj in uncal_ch, else False
"""
return self.contains(self.uncalibrated_channel, channel)

def hascalibrated_channel(self, channel):
"""
Return True if channels is in Calibration.cal_ch,
else return False
Parameters
----------
channel : dlis.core.obname or tuple(str, int, int)
Returns
-------
hasuncalchannel : bool
True if Calibration has the channel obj in self.cal_ch, else False
"""
return self.contains(self.calibrated_channel, channel)

def hasparameter(self, param):
"""
Return True if parameter is in calibration.parameter,
else return False
Parameters
----------
param : dlis.core.obname, tuple(str, int, int)
Returns
-------
hasparameter : bool
True if Calibration has the param obj, else False
"""
return self.contains(self.parameters, param)

class Unknown(basic_object):
"""
Expand Down
Loading

0 comments on commit 529568a

Please sign in to comment.