M-layer-concept Python code

The Python code has two main roles:

  1. to refer to the M-layer registry (the JSON files), and

  2. to support client-side code that will uses the M-layer representation.

(There are also some Python modules that can assist when extending the M-layer JSON entries.)

M-layer-register API

The first role is handled by the Context class, which provides access to conversion and casting tables in the registry. Client-side software does not see the context.

A default context is created when the Python package is imported. This object reads and internally organises all the JSON data.

Support for scale transformation

As part of the initialisation process, mathematical transformation functions are instantiated from string descriptors for the functions and parameters stored in the registry.

The built-in Python function eval() is used to convert parameter strings and functions into Python objects. During evaluation, some numerical constants defined in the SI and mathematical constants are available. There is also a small number of scale transformation functions.

Defined SI constants

The following definitions of numeric values are available in the namespace si during evaluation.

"""
Numerical values for some of the physical constants given 
explicit exact values in the 9th edition of the SI Brochure. 
"""
e = 1.602176634E-19     # coulomb
c = 2.99792458E8        # meter per second
h = 6.62607015E-34      # joule second
k = 1.380649E-23        # joule per kelvin

atto    =   1E-18
femto   =   1E-15
pico    =   1E-12
nano    =   1E-9
micro   =   1E-6
milli   =   1E-3
centi   =   1E-2
deci    =   1E-1
deca    =   1E1
hecto   =   1E2  
kilo    =   1E3 
mega    =   1E6 
giga    =   1E9
tera    =   1E12
peta    =   1E15



Mathematical constants

The following definitions provide numeric constants in the namespace number during evaluation.

"""
Values for some mathematical constants. 
"""
e = 2.718281828459045   # Euler's number
pi = 3.141592653589793  # PI
tau = 6.283185307179586 # 2 PI

Defined transformations

The following conversion functions for scales are defined in the ml_math namespace during evaluation.

The functions exported from this module are used during parsing of JSON strings that define mathematical transformations.

bounded_convert(x, a, y_lb, y_ub)

Convert x to a bounded interval scale

Parameters:
  • x – the value to be converted

  • a – the scaling factor for divisions

  • y_lb – the lower limit of the destination scale

  • y_ub – the upper limit of the destination scale

Returns:

A value corresponding to x on the destination scale

interval_convert(x, a, b)

Convert x to an interval scale

Parameters:
  • x – the value to be converted

  • a – the scaling factor for divisions

  • b – the scale offset

Returns:

A value corresponding to x on the destination scale

ratio_convert(x, a)

Convert x to an ratio scale

Parameters:
  • x – the value to be converted

  • a – the scaling factor for divisions

Returns:

A value corresponding to x on the destination scale

The Context

The Context methods used to access registry entries are shown here.

class Context(locale='default', scale_reg=None, reference_reg=None, aspect_reg=None, conversion_reg=None, casting_reg=None, scales_for_aspect_reg=None, system_reg=None)

A Context provide a Python interface to M-layer registry records.

cast_from_scale_aspect(src_scale_uid, src_aspect_uid, dst_scale_uid, dst_aspect_uid)

Return a function to transform data on an initial scale-aspect to a different scale and aspect.

Parameters:
  • src_scale_uid – initial scale

  • src_aspect_uid – initial aspect

  • dst_scale_uid – final scale

  • dst_aspect_uid – final aspect

Returns:

A Python function or None

When the initial and final aspect is the same and no cast has been defined, a matching conversion will be used.

When the initial aspect is unspecified, an aspect-specific conversion can be used.

conversion_from_scale_aspect(src_scale_uid, src_aspect_uid, dst_scale_uid)

Return a function to convert data expressed in the src scale and aspect to the dst scale.

The aspect does not change.

Parameters:
  • src_scale_uid – initial scale

  • src_aspect_uid – initial aspect

  • dst_scale_uid – final scale

Returns:

A Python function or None

Modules that support the context

A number of other modules support Context

class Register(context)
get(uid, default=None)
set(entry)

Conversion changes the scale of an expression but leaves the type of scale and aspect unchanged.

Legitimate conversions are recorded in a ConversionRegister

class ConversionRegister(context)

A ConversionRegister maps scale pairs to a function that will convert tokens between scales.

get(uid_pair, default=None)

Return a conversion function

Parameters:

uid_pair – a pair of M-layer scale uids

set(entry)

Create an entry for a conversion function The type of the source and destination scales determines the form of the conversion function and the function parameters are elements in entry.

Parameters:

entry – the M-layer record for a conversion

Casting can change the type of scale and aspect of an expression.

Legitimate castings are recorded in a CastingRegister.

class CastingRegister(context)

A CastingRegister maps scale-aspect pairs to a function that will convert tokens.

get(uid_pair, default=None)

Return a conversion function

Parameters:

uid_pair – a pair of M-layer scale-aspect uids

set(entry)

Create an entry for a casting function

Parameters:

entry – the M-layer record for a casting

Conversions can be declared for specific aspects. The ScalesForAspectRegister is used to hold these records.

class ScalesForAspectRegister(context)

A ScalesForAspectRegister maps an aspect to a mapping of scale pairs, which, in turn, index conversion functions.

get(aspect, default)

Return a mapping of scale-pairs to conversion functions (same format as conversion_register entries)

Parameters:

aspect (Aspect) –

get_fn(aspect, scale_uid_pair, default=None)

Return a conversion function

Parameters:
  • aspect (Aspect) –

  • scale_uid_pair – a pair of M-layer scale uids

Client-side API

The Aspect and Scale classes encapsulate unique identifiers.

class Aspect(aspect_uid=cxt.no_aspect_uid)

Aspect objects provide a lightweight wrapper around the unique identifier for an M-layer aspect.

__eq__(other)

True when both objects have the same uid

property uid

The M-layer identifier for this aspect

class Scale(scale_uid)

A Scale encapsulates a unique identifier for an M-layer scale.

__eq__(other)

True when both objects have the same uids

property systematic

Return a Systematic when a ratio scale is associated with a reference in a coherent system of units, like the SI. Otherwise return None.

There is also ScaleAspect, in which a scale-aspect pair are encapsulated.

class ScaleAspect(scale, aspect=no_aspect)

A wrapper around a scale and aspect pair.

__eq__(other)

True when the M-layer identifiers of both objects match

property uid

A pair of M-layer identifiers for scale and aspect

Supporting classes for compound expressions

Aspects, Scales or ScaleAspects can be multiplied, divided and exponentiated, which will generate corresponding compound objects.

class CompoundAspect(aspect_stack)

A CompoundAspect holds an Aspect expression

property no_aspect

True if no_aspect is anywhere in the expression.

property uid
class CompoundScale(scale_stack)

A CompoundScale holds a Scale expression

property is_systematic

A CompoundScale is systematic when all scales are systematic

property systematic

The dimensions of the component scales

property uid

The UIDs of the component scales

class CompoundScaleAspect(scale_aspect_stack)

A CompoundScaleAspect holds a ScaleAspect expression

property is_systematic

A CompoundScaleAspect is systematic when all scales are systematic

to_compound_scales_and_aspects()

Return a CompoundScale-CompoundAspect pair

Parameters:

compound_scale_aspect (CompoundScaleAspect) –

property uid

A product of powers for Scale-Aspect uid pairs.

Systematic and CompoundSystematic

When the expression encapsulated in a CompoundScale or CompoundScaleAspect consists of scales associated with a unit system, a systematic.Systematic can express the dimensional exponents in that system’s dimensions.

class Systematic(system, dim, prefix=1)
__eq__(other)

Return self==value.

commensurate(other)

True when this object and other belong to the same system and have the same dimensional exponents.

property dimensions

The tuple of dimensions

property prefix

The numerical unit prefix

property system

The unit system

Dimensions can be multiplied, divided and exponentiated, which generates a corresponding compound class.

class CompoundSystematic(stack)

A CompoundSystematic holds an expression of Systematic objects

__eq__(other)

Return self==value.

property simplify

Return the combination of the exponentiated factors

UID and CompoundUID

The UID class encapsulates M-layer unique identifiers

class UID(uid)
__eq__(other)

Return self==value.

A CompoundUID encapsulates the individual uids of the scales, or scale-aspects, in a compound unit expression.

class CompoundUID(stack)
__eq__(other)

Return self==value.

json(**kwargs)

Return a JSON record for the CompoundUID

Parameters:

kwargs – will be passed directly to json.dumps