Units in LabRAD - syue99/Lab_control GitHub Wiki
Introduction
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.
How To Use
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'
Comparing Units
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
List of available units
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
Caveats
- 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.0results 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. Likelycmpcalls__gt__of afloatwhich then calls__lt__once again. In python 3cmpand__cmp___were removed because of such issues. These issues can be solved by having something similar to__eq__whereFalseis returned if two objects are not of the same type.
- This happens because in
All methods
labrad.units.WithUnit
- value
- units
- inUnitsOf(unit)
- inBaseUnits()
- isCompatible(unit)
- isDimensionless()
- sqrt()
labrad.units.Unit
- name
- isCompatible(unit)
- conversionFactorTo(unit)
- conversionTupleTo(unit)
- isDimensionless()
- isAngle()
labrad.units
- units (such as m, s, kg...)
- fundamental constants (hbar, Hartree, eps0 ...)
- description()
- convert()