-
Notifications
You must be signed in to change notification settings - Fork 10
Units in LabRAD
LabRAD servers work independently from one another and be able to communicate with each other through the LabRAD protocol. This protocol allows servers to specify the physical units they are expecting for each of their settings. Communications with these settings will require inputs of the specified units.
The specification of units accomplishes multiple goals. First, it provides a sanity check: if a server expects a value in seconds, it will reject anyone trying to send it kilograms as such a message would point to an obvious error. Secondly, this allows for better interoperability: if a server A expects a value in seconds, and server B sends out values in milliseconds, the communication will be deemed valid and the value will be automatically converted appropriately. Lastly, units may be valuable for calculations within a server or a client as pylabrad allows for easy unit conversion and defines many fundamental constants.
Units in pylabrad can be accessed in labrad.untis. WithUnit allows to attach units to floating point and complex numbers.
>>>from labrad.units import WithUnit
>>>import labrad.units as U
Let's create our first value of 2 seconds.
>>> val = WithUnit(2, 's')
>>> val
Value(2.0, 's')
Equivalently, one can create this value by multiplying the factor 2 directly the unit
>>> val = 2*U.s
Value(2.0, 's')
The Value class contains both the numerical value and the units. These can be accessed in the following way:
>>> val.value
2.0
>>> val.units
's'
Lets now convert value to a different unit:
>>> new_val = val.inUnitsOf('ms')
>>> new_val
Value(2000.0, 'ms')
>>> new_val.value
2000.0
>>> new_val.units
'ms'
A quicker way to get the value after conversion is
>>> val['s']
2.0
>>> val['ms']
2000.0
Lets use this to calculate the number of seconds in one year: the converted units do not have to be SI, they just need to be compatible.
>>> WithUnit(1, 'y')['s']
31557600.0
What if we try to convert seconds to kilograms?
>>> WithUnit(1, 's')['kg']
TypeError: Incompatible units: 's', 'kg'
We are able to compare values with units. For instance:
>>> WithUnit(1,'s') == WithUnit(1, 'ms')
False
>>> WithUnit(1,'s') == WithUnit(1000, 'ms')
True
>>> WithUnit(1,'s') < WithUnit(2, 'ms')
False
Previously we accessed the unit second as U.s. To get a list of all available units run
>>> U.description()
The list of all predefined fundamental constants can be seen in /labrad/units.py
- The current implementation does not reduce the value to dimensionless units. One can use inUnitsOf or inBaseUnits methods to access the dimensionless value.
>>> val = WithUnit(1,'s') / WithUnit(1, 'ms')
>>> val
Value(1.0, 's/ms')
>>> val.inBaseUnits()
Value(1000.0, '')
>>> val.inUnitsOf('')
Value(1000.0, '')
-
A known bug where comparing a value with units with a floating number such as
WithUnit(1,'ms') < 2.0
results in RuntimeError, Maximum Recursion Exceeded. -
- This happens because in
labrad.units
: the linereturn cmp(self, other)
of__lt__(self, other)
calls__lt__(self, other)
again. Likelycmp
calls__gt__
of afloat
which then calls__lt__
once again. In python 3cmp
and__cmp___
were removed because of such issues. These issues can be solved by having something similar to__eq__
whereFalse
is returned if two objects are not of the same type.
- This happens because in
- value
- units
- inUnitsOf(unit)
- inBaseUnits()
- isCompatible(unit)
- isDimensionless()
- sqrt()
- name
- isCompatible(unit)
- conversionFactorTo(unit)
- conversionTupleTo(unit)
- isDimensionless()
- isAngle()
- units (such as m, s, kg...)
- fundamental constants (hbar, Hartree, eps0 ...)
- description()
- convert()