Skip to content

Commit

Permalink
add utility module for unit conversions
Browse files Browse the repository at this point in the history
Adds mxcubecore.utils.units module, so there is a common place
for unit converson utility functions.

Adds some initial function to convert between time, energy, length
and current units.
  • Loading branch information
elmjag authored and marcus-oscarsson committed Jun 20, 2024
1 parent cf4c1d2 commit 39eeddd
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ code base
* Pixels are to be used for beam location (center)
* Datetime YYYY-MM-DD HH:MM:SS(.ff) ,possibly with hundreds of seconds (ff), and with 24 hour clock.

When writing code that converts between different units,
it is recommended to use utility functions from {py:mod}`mxcubecore.utils.units` module.
This will to aid in the readability of the code.

#### Value update signals/callbacks
The "valueChanged" and "stateChanged" signals should be used when a HardwareObjects value or state
has been changed. Defined in for instance the base class [HardwareObject](https://github.com/mxcube/HardwareRepository/blob/ea8369ab2c08dbe539fd92ffee18fd21bb3a81b8/BaseHardwareObjects.py#L666), [AbstractMotor](https://github.com/mxcube/HardwareRepository/blob/master/HardwareObjects/abstract/AbstractMotor.py) and
Expand Down
71 changes: 71 additions & 0 deletions mxcubecore/utils/units.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""
Utility functions for converting between different units.
"""

#
# time units
#


def us_to_sec(us: float) -> float:
"""
convert microseconds (μs) to seconds
"""
return us / 1_000_000.0


def sec_to_us(sec: float) -> float:
"""
convert seconds to microseconds (μs)
"""
return sec * 1_000_000.0


def sec_to_hour(sec: float) -> float:
"""
convert seconds to hours
"""
return sec / (60 * 60)


#
# energy units
#


def ev_to_kev(ev: float) -> float:
"""
convert eV value to KeV value
"""
return ev / 1000.0


#
# length units
#


def meter_to_mm(meters: float) -> float:
"""
convert meters to millimeters (mm)
"""
return meters * 1000.0


def mm_to_meter(millimeters: float) -> float:
"""
convert millimeters (mm) to meters
"""
return millimeters / 1000.0


#
# current units
#


def A_to_mA(amp: float) -> float:
"""
convert Ampere (A) to milli Ampere (mA)
"""
return amp * 1000
45 changes: 45 additions & 0 deletions test/pytest/test_utils_units.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from math import isclose
from mxcubecore.utils.units import (
us_to_sec,
sec_to_us,
sec_to_hour,
ev_to_kev,
meter_to_mm,
mm_to_meter,
A_to_mA,
)


def test_us_to_sec():
assert isclose(us_to_sec(500_000), 0.5)
assert isclose(us_to_sec(123.4), 0.0001234)


def test_sec_to_us():
assert isclose(sec_to_us(2), 2_000_000.0)
assert isclose(sec_to_us(0.42), 420_000.0)


def test_sec_to_hour():
assert isclose(sec_to_hour(3800), 1.056, abs_tol=0.001)
assert isclose(sec_to_hour(1800.0), 0.5)


def test_ev_to_kev():
assert isclose(ev_to_kev(12000), 12.0)
assert isclose(ev_to_kev(10.5), 0.0105)


def test_meter_to_mm():
assert isclose(meter_to_mm(10), 10_000.0)
assert isclose(meter_to_mm(0.5214), 521.4)


def test_mm_to_meter():
assert isclose(mm_to_meter(1200), 1.2)
assert isclose(mm_to_meter(10.5), 0.0105)


def test_A_to_mA():
assert isclose(A_to_mA(2), 2000.0)
assert isclose(A_to_mA(0.3921), 392.1)

0 comments on commit 39eeddd

Please sign in to comment.