Skip to content

Commit

Permalink
Creating Dimension class that is required for multi-dim Measurements (g…
Browse files Browse the repository at this point in the history
…oogle#710)

* Creating Dimension class that is required for multi-dim Measurements

* removing stray line

* minor formatting/comment changes suggested during review
  • Loading branch information
kdsudac authored and grybmadsci committed Jan 26, 2018
1 parent 35142b8 commit fb2694c
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 6 deletions.
7 changes: 4 additions & 3 deletions examples/all_the_things.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ def set_measurements(test):
htf.Measurement('unset_dims').with_dimensions(units.HERTZ),
htf.Measurement('dimensions').with_dimensions(units.HERTZ),
htf.Measurement('lots_of_dims').with_dimensions(
units.HERTZ, units.SECOND, units.RADIAN))
units.HERTZ, units.SECOND,
htf.Dimension(description='my_angle', unit=units.RADIAN)))
def dimensions(test):
for dim in range(5):
test.measurements.dimensions[dim] = 1 << dim
Expand All @@ -112,7 +113,7 @@ def attachments(test):
os.path.join(os.path.dirname(__file__), 'example_attachment.txt'))

test_attachment = test.get_attachment('test_attachment')
assert test_attachment == 'This is test attachment data.'
assert test_attachment.data == 'This is test attachment data.'


@htf.TestPhase(run_if=lambda: False)
Expand All @@ -124,7 +125,7 @@ def analysis(test):
level_all = test.get_measurement('level_all')
assert level_all.value == 9
test_attachment = test.get_attachment('test_attachment')
assert test_attachment == 'This is test attachment data.'
assert test_attachment.data == 'This is test attachment data.'
lots_of_dims = test.get_measurement('lots_of_dims')
assert lots_of_dims.value == [
(1, 21, 101, 123),
Expand Down
2 changes: 1 addition & 1 deletion openhtf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from openhtf import core
from openhtf import plugs
from openhtf import util
from openhtf.core.measurements import Measurement, measures
from openhtf.core.measurements import Dimension, Measurement, measures
from openhtf.core.monitors import monitors
from openhtf.core import phase_executor
from openhtf.core import station_api
Expand Down
64 changes: 63 additions & 1 deletion openhtf/core/measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,19 @@ def _maybe_make_unit_desc(self, unit_desc):
unit_desc))
return unit_desc

def _maybe_make_dimension(self, dimension):
"""Return a `measurements.Dimension` instance."""
# For backwards compatibility the argument can be either a Dimension, a
# string or a `units.UnitDescriptor`.
if isinstance(dimension, Dimension):
return dimension
if isinstance(dimension, units.UnitDescriptor):
return Dimension.from_unit_descriptor(dimension)
if isinstance(dimension, str):
return Dimension.from_string(string)

raise TypeError('Cannot convert %s to a dimension', dimension)

def with_units(self, unit_desc):
"""Declare the units for this Measurement, returns self for chaining."""
self.units = self._maybe_make_unit_desc(unit_desc)
Expand All @@ -193,7 +206,7 @@ def with_units(self, unit_desc):
def with_dimensions(self, *dimensions):
"""Declare dimensions for this Measurement, returns self for chaining."""
self.dimensions = tuple(
self._maybe_make_unit_desc(dim) for dim in dimensions)
self._maybe_make_dimension(dim) for dim in dimensions)
return self

def with_validator(self, validator):
Expand Down Expand Up @@ -304,6 +317,55 @@ def set(self, value):
self.is_value_set = True


class Dimension(object):
"""Dimension for multi-dim Measurements.
Dimensions optionally include a unit and a description. This is intended
as a drop-in replacement for UnitDescriptor for backwards compatibility.
"""

def __init__(self, description='', unit=units.NO_DIMENSION):
self.description = description
self.unit = unit

@classmethod
def from_unit_descriptor(cls, unit_desc):
return cls(unit=unit_desc)

@classmethod
def from_string(cls, string):
"""Convert a string into a Dimension"""
# Note: There is some ambiguity as to whether the string passed is intended
# to become a unit looked up by name or suffix, or a Dimension descriptor.
if string in units.UNITS_BY_ALL:
return cls(description=string, unit=units.Unit(string))
else:
return cls(description=string)

@property
def code(self):
"""Provides backwards compatibility to `units.UnitDescriptor` api."""
return self.unit.code

@property
def suffix(self):
"""Provides backwards compatibility to `units.UnitDescriptor` api."""
return self.unit.suffix

@property
def name(self):
"""Provides backwards compatibility to `units.UnitDescriptor` api."""
return self.description or self.unit.name

def _asdict(self):
return {
'code': self.code,
'description': self.description,
'name': self.name,
'suffix': self.suffix,
}


class DimensionedMeasuredValue(mutablerecords.Record(
'DimensionedMeasuredValue', ['name', 'num_dimensions'],
{'notify_value_set': None, 'value_dict': collections.OrderedDict})):
Expand Down
2 changes: 1 addition & 1 deletion test/core/measurements_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def test_chaining_in_measurement_declarations(self, user_mock):
self.assertMeasurementPass(record, 'specified_as_args')

@htf_test.yields_phases
def test_measurements_with_dimenstions(self):
def test_measurements_with_dimensions(self):
record = yield all_the_things.dimensions
self.assertNotMeasured(record, 'unset_dims')
self.assertMeasured(record, 'dimensions',
Expand Down

0 comments on commit fb2694c

Please sign in to comment.