"""
Routines for conversion of physical units.
"""
import numpy as np
from . import string as string_utils
import re
[docs]
def split_units(value):
"""
Split string value with a dimension.
Return tuple ``(val, unit)``, where ``val`` is the float part of the value, and ``unit`` is the string representing units.
"""
m=re.match(r"([+-.\d]+)\s*([a-zA-Z]*)$",value)
if not m:
raise ValueError("can't parse value {}".format(value))
return float(m[1]),m[2]
[docs]
def convert_length_units(value, value_unit="m", result_unit="m", case_sensitive=True):
"""
Convert `value` from `value_unit` to `result_unit`.
The possible length units are ``'m'``, ``'mm'``, ``'um'``, ``'nm'``, ``'pm'``, ``'fm'``.
If ``case_sensitive==True``, matching units is case sensitive.
"""
if string_utils.string_equal(value_unit,"m",case_sensitive=case_sensitive):
value_m=value
elif string_utils.string_equal(value_unit,"mm",case_sensitive=case_sensitive):
value_m=value*1E-3
elif string_utils.string_equal(value_unit,"um",case_sensitive=case_sensitive):
value_m=value*1E-6
elif string_utils.string_equal(value_unit,"nm",case_sensitive=case_sensitive):
value_m=value*1E-9
elif string_utils.string_equal(value_unit,"pm",case_sensitive=case_sensitive):
value_m=value*1E-12
elif string_utils.string_equal(value_unit,"fm",case_sensitive=case_sensitive):
value_m=value*1E-15
else:
raise ValueError("unrecognized length unit: {0}".format(value_unit))
if string_utils.string_equal(result_unit,"m",case_sensitive=case_sensitive):
return value_m
elif string_utils.string_equal(result_unit,"mm",case_sensitive=case_sensitive):
return value_m*1E3
elif string_utils.string_equal(result_unit,"um",case_sensitive=case_sensitive):
return value_m*1E6
elif string_utils.string_equal(result_unit,"nm",case_sensitive=case_sensitive):
return value_m*1E9
elif string_utils.string_equal(result_unit,"pm",case_sensitive=case_sensitive):
return value_m*1E12
elif string_utils.string_equal(result_unit,"fm",case_sensitive=case_sensitive):
return value_m*1E15
else:
raise ValueError("unrecognized length unit: {0}".format(result_unit))
[docs]
def convert_time_units(value, value_unit="s", result_unit="s", case_sensitive=True):
"""
Convert `value` from `value_unit` to `result_unit`.
The possible time units are ``'s'``, ``'ms'``, ``'us'``, ``'ns'``, ``'ps'``, ``'fs'``, ``'as'``.
If ``case_sensitive==True``, matching units is case sensitive.
"""
if string_utils.string_equal(value_unit,"s",case_sensitive=case_sensitive):
value_s=value
elif string_utils.string_equal(value_unit,"ms",case_sensitive=case_sensitive):
value_s=value*1E-3
elif string_utils.string_equal(value_unit,"us",case_sensitive=case_sensitive):
value_s=value*1E-6
elif string_utils.string_equal(value_unit,"ns",case_sensitive=case_sensitive):
value_s=value*1E-9
elif string_utils.string_equal(value_unit,"ps",case_sensitive=case_sensitive):
value_s=value*1E-12
elif string_utils.string_equal(value_unit,"fs",case_sensitive=case_sensitive):
value_s=value*1E-15
elif string_utils.string_equal(value_unit,"as",case_sensitive=case_sensitive):
value_s=value*1E-18
else:
raise ValueError("unrecognized length unit: {0}".format(value_unit))
if string_utils.string_equal(result_unit,"s",case_sensitive=case_sensitive):
return value_s
elif string_utils.string_equal(result_unit,"ms",case_sensitive=case_sensitive):
return value_s*1E3
elif string_utils.string_equal(result_unit,"us",case_sensitive=case_sensitive):
return value_s*1E6
elif string_utils.string_equal(result_unit,"ns",case_sensitive=case_sensitive):
return value_s*1E9
elif string_utils.string_equal(result_unit,"ps",case_sensitive=case_sensitive):
return value_s*1E12
elif string_utils.string_equal(result_unit,"fs",case_sensitive=case_sensitive):
return value_s*1E15
elif string_utils.string_equal(result_unit,"as",case_sensitive=case_sensitive):
return value_s*1E18
else:
raise ValueError("unrecognized length unit: {0}".format(result_unit))
[docs]
def convert_frequency_units(value, value_unit="Hz", result_unit="Hz", case_sensitive=True):
"""
Convert `value` from `value_unit` to `result_unit`.
The possible frequency units are ``'Hz'``, ``'kHz'``, ``'MHz'``, ``'GHz'``.
If ``case_sensitive==True``, matching units is case sensitive.
"""
if string_utils.string_equal(value_unit,"Hz",case_sensitive=case_sensitive):
value_Hz=value
elif string_utils.string_equal(value_unit,"kHz",case_sensitive=case_sensitive):
value_Hz=value*1E3
elif string_utils.string_equal(value_unit,"MHz",case_sensitive=case_sensitive):
value_Hz=value*1E6
elif string_utils.string_equal(value_unit,"GHz",case_sensitive=case_sensitive):
value_Hz=value*1E9
else:
raise ValueError("unrecognized frequency unit: {0}".format(value_unit))
if string_utils.string_equal(result_unit,"Hz",case_sensitive=case_sensitive):
return value_Hz
elif string_utils.string_equal(result_unit,"kHz",case_sensitive=case_sensitive):
return value_Hz/1E3
elif string_utils.string_equal(result_unit,"MHz",case_sensitive=case_sensitive):
return value_Hz/1E6
elif string_utils.string_equal(result_unit,"GHz",case_sensitive=case_sensitive):
return value_Hz/1E9
else:
raise ValueError("unrecognized frequency unit: {0}".format(result_unit))
[docs]
def convert_power_units(value, value_unit="dBm", result_unit="dBm", case_sensitive=True, impedance=50.):
"""
Convert `value` from `value_unit` to `result_unit`.
For conversion between voltage and power, assume RMS voltage and the given `impedance`.
The possible power units are ``'dBm'``, ``'dBmV'``, ``'dBuV'``, ``'W'``, ``'mW'``, ``'uW'``, ``'nW'``, ``'mV'``, ``'nV'``.
If ``case_sensitive==True``, matching units is case sensitive.
"""
# dBmV=20*log10(V/1mV), 220mV<->1mW => 20*log10(220)dBmV=47dBmV<->0dBm
s=1.
W2V_dB=np.log10(impedance)*10.
if string_utils.string_equal(value_unit,"dBm",case_sensitive=case_sensitive):
value_dBm=value
elif string_utils.string_equal(value_unit,"dBmV",case_sensitive=case_sensitive):
value_dBm=value-30.-W2V_dB
elif string_utils.string_equal(value_unit,"dBuV",case_sensitive=case_sensitive):
value_dBm=value-90.-W2V_dB
else:
s=np.sign(value)
value=abs(value)
if string_utils.string_equal(value_unit,"W",case_sensitive=case_sensitive):
value_dBm=10.*np.log10(value)+30.
elif string_utils.string_equal(value_unit,"mW",case_sensitive=case_sensitive):
value_dBm=10.*np.log10(value)
elif string_utils.string_equal(value_unit,"uW",case_sensitive=case_sensitive):
value_dBm=10.*np.log10(value)-30.
elif string_utils.string_equal(value_unit,"nW",case_sensitive=case_sensitive):
value_dBm=10.*np.log10(value)-60.
elif string_utils.string_equal(value_unit,"mV",case_sensitive=case_sensitive):
value_dBm=20.*np.log10(value)-30.-W2V_dB
elif string_utils.string_equal(value_unit,"uV",case_sensitive=case_sensitive):
value_dBm=20.*np.log10(value)-90.-W2V_dB
else:
raise ValueError("unrecognized power unit: {0}".format(value_unit))
if string_utils.string_equal(result_unit,"dBm",case_sensitive=case_sensitive):
return value_dBm if s>0 else np.nan
elif string_utils.string_equal(result_unit,"dBmV",case_sensitive=case_sensitive):
return value_dBm+30.+W2V_dB if s>0 else np.nan
elif string_utils.string_equal(result_unit,"dBuV",case_sensitive=case_sensitive):
return value_dBm+90.+W2V_dB if s>0 else np.nan
elif string_utils.string_equal(result_unit,"W",case_sensitive=case_sensitive):
return 10.**((value_dBm-30.)/10.)*s
elif string_utils.string_equal(result_unit,"mW",case_sensitive=case_sensitive):
return 10.**(value_dBm/10.)*s
elif string_utils.string_equal(result_unit,"uW",case_sensitive=case_sensitive):
return 10.**((value_dBm+30.)/10.)*s
elif string_utils.string_equal(result_unit,"nW",case_sensitive=case_sensitive):
return 10.**((value_dBm+60.)/10.)*s
elif string_utils.string_equal(result_unit,"mV",case_sensitive=case_sensitive):
return 10.**((value_dBm+30.+W2V_dB)/20.) if s>0 else np.nan
elif string_utils.string_equal(result_unit,"uV",case_sensitive=case_sensitive):
return 10.**((value_dBm+90.+W2V_dB)/20.) if s>0 else np.nan
else:
raise ValueError("unrecognized power unit: {0}".format(result_unit))