Ts Lib Units #
Version #
v0.3.16
Table of Contents #
Summary#
This library stores the TetraScience standard unit strings, so they can easily be imported and used in Task Scripts
Unit Usage#
The Unit enum is used to store the TetraScience standard unit strings.
It can be used in Task Scripts instead of manually typing out the unit strings:
from ts_lib_units import Unit
from ts_ids_core.schema import ValueUnit
temperature = ValueUnit(value=20, unit=Unit.DEGREE_CELSIUS)
print(temperature.dict())
# Output:
# {'value': 20, 'unit': 'DegreeCelsius'}
UnitParser Usage#
The UnitParser class is used to parse raw unit strings to the TetraScience standard unit strings in task scripts.
The class should be initialized with a mapping (or a list of mappings) of raw unit strings to the TetraScience standard unit strings.
The UnitParser.parse method can then be used to parse a raw unit string to the TetraScience standard unit string:
from ts_lib_units import Unit, UnitParser
MY_MAPPING = {
"°C": Unit.DEGREE_CELSIUS,
"ng/ml": Unit.NANOGRAM_PER_MILLILITER,
}
unit_parser = UnitParser(MY_MAPPING)
parsed_unit = unit_parser.parse("°C")
print("Parsed unit: ", parsed_unit)
# Output:
# Parsed unit: DegreeCelsius
If the raw unit string is not in the mapping, the raw unit string will be returned, and stored within the UnitParser.unmapped_units set.
This can then be used to log a warning for all units that could not be parsed:
import logging
from ts_lib_units import Unit, UnitParser
MY_MAPPING = {
"°C": Unit.DEGREE_CELSIUS,
"ng/ml": Unit.NANOGRAM_PER_MILLILITER,
}
unit_parser = UnitParser(MY_MAPPING)
parsed_unit = unit_parser.parse("m")
print("Parsed unit: ", parsed_unit)
if unit_parser.unmapped_units:
logging.warning(
"The following units could not be parsed to the TetraScience standard unit "
f"strings: \n {sorted(list(unit_parser.unmapped_units))}"
)
# Output:
# Parsed unit: m
# WARNING:root:The following units could not be parsed to the TetraScience standard unit strings:
# ['m']
To avoid adding many similar warnings to the workflow logs, it is recommended to only log the unmapped units once per workflow run, for the entire set of unmapped units.
Standard Mappings#
A number of standard mappings are available in this library:
Mapping |
Description |
|---|---|
|
Maps concentration units, like |
|
Maps mole units, like |
|
Maps molar mass units, like |
|
Maps temperature units, like |
|
Maps length units, like |
|
Maps mass units, like |
|
Maps time units, like |
|
Maps volume units, like |
These can be imported in Task Scripts and used with any custom mappings to create a UnitParser instance:
from ts_lib_units import UnitParser, TEMPERATURE_MAPPING
custom_mappings = {
"mg/ml": Unit.MILLIGRAM_PER_MILLILITER,
}
unit_parser = UnitParser([TEMPERATURE_MAPPING, custom_mappings])
Unit Library#
All units are singular rather than plural, e.g. Meter as in 1 Meter rather than Meters as in 2 Meters.
If the unit cannot be found in this library, request for it to be added.
New units will be added following this approach:
If the unit is in QUDT, or Allotrope QUDT-extended, the name in the URI will be used.
See the
allotrope-qudt-merged.txtfile for reference.
Otherwise:
Use Pascal case.
Use
Perfor units divided by another unit.Simply concatenate units when it is one unit multiplied by another unit, e.g.
VoltMeter.Do not capitalize after prefixes such as
MilliorMicro.
Finding a QUDT URI for a New Unit#
When adding a new unit, use the semantic search tool to find the correct QUDT URI.
Step 1: Set up the vector database (first time only)
# Install search dependencies (optional group, not installed by default)
poetry install --with search
# Index the QUDT units (creates .qudt_vectordb/ directory)
poetry run index-qudt
To remove the search dependencies afterwards, recreate the venv without the group:
poetry env remove --all
poetry install
Step 2: Search for your unit
# Search by name, symbol, or description
poetry run search-qudt "milligrams per liter"
poetry run search-qudt "RLU"
poetry run search-qudt "concentration unit" --top 10
Example output:
1. URI: http://purl.allotrope.org/ontology/qudt-ext/unit#MilligramPerLiter
Labels: Milligram per Liter
Symbols: mg/L
Similarity: 0.878
2. URI: http://qudt.org/vocab/unit/MilliGM-PER-L
Labels: Milligram per Litre
Symbols: mg/L
Similarity: 0.827
Step 3: Choose the correct URI
Prefer Allotrope URIs (
http://purl.allotrope.org/...) when availableUse QUDT URIs (
http://qudt.org/...) if no Allotrope equivalent existsIf no match is found, the unit may not exist in QUDT - use
qudt_uri=None
Step 4: Validate after adding
After adding a new unit, run the validation script:
poetry run validate-qudt-uris
Unit Conversion#
The convert_unit function can be used to convert a RawValueUnit or ValueUnit instance from one unit to another:
from ts_lib_units import convert_unit, Unit
previous = RawValueUnit(
raw_value = "20 g/L",
value = 20,
unit = "GramPerLiter"
)
converted = convert_unit(previous, Unit.MILLIGRAM_PER_LITER)
print(converted)
# Output:
# ValueUnit(value=20000, unit='MilligramPerLiter')
Changelog#
v0.3.16 #
Add
NanoliterAdd
MeterPerSecond
v0.3.15 #
Add
EndotoxinUnit
v0.3.14 #
Add
EndotoxinUnitPerMicroliterAdd
EndotoxinUnitPerLiterAdd
EndotoxinUnitPerNanogramAdd
EndotoxinUnitPerMicrogramAdd
EndotoxinUnitPerGramAdd
ENDOTOXIN_MAPPING
v0.3.13 #
Add
EndotoxinUnitPerMilliliter
v0.3.12 #
Add LICENSE
v0.3.11 #
Add
SquareMicrometer
v0.3.10 #
Add
ImportErrorwith helpful message tosearch_qudt.pyandindex_qudt_units.pywhensearchdependencies are not installed
v0.3.9 #
Move
chromadb,sentence-transformers, andrdflibinto an optionalsearchdependency groupRun
poetry install --with searchto install these dependencies when using the QUDT search/index tools
v0.3.8 #
Add QUDT vector database search tooling for finding unit URIs via semantic similarity
Expose CLI commands via
poetry run:search-qudt,index-qudt,download-qudt,validate-qudt-uris
v0.3.7 #
Add
InternationalUnitPerLiterfor enzyme activity
v0.3.6 #
Add
mmol/Lmapping toMillimolePerLiterinCONCENTRATION_MAPPING
v0.3.5 #
Add
Femtoliter,CountPerLiter,CountPerMicroliter,CountPerMilliliter,CountPerNanoliter
v0.3.4 #
Add
KilocaloriePerMole,MoleFraction
v0.3.3 #
Add
CubicCentimeterPerMole,GramPerLiterSolvent,GramPerLiterSolution,JoulePerMole,KiloJoulePerMole,SquareRootMegaPascal
v0.3.2 #
Add
PerSecond,PascalSecond,MillipascalSecondDeprecate
Permittivitywhich is a quantity rather than a unitFix QUDT URIs for
GramPerMilliliter,LiterPerMinute,Microvolt
v0.3.1 #
Fix
MilliAbsorbanceUnit,MilliAbsorbanceUnitTimesMinuteandMilliAbsorbanceUnitTimesMilliliterunit definitions
v0.3.0 #
Modify
UnitParser.parsemethod:Allow to map to
NonetypeMap empty string, “”, to
Noneas a rule
Add units
AbsorbanceUnit,MilliAbsorbanceUnit,MilliAbsorbanceUnitTimesMinute,MilliAbsorbanceUnitTimesMilliliter,CentimeterPerHour,CycleNumber, andLiterPerHour
v0.2.1 #
Add units
MillivoltPerPHandMilliVolt
v0.2.0 #
Update the unit library to also store the following for each unit:
The QUDT / Allotrope QUDT Extended URI.
The representation of the unit according to the
pintlibrary, which is used for unit conversion.
Update the following unit strings to improve consistency between unit strings compared to the Allotrope / QUDT standards:
CentiPoisetoCentipoiseFemtoGramtoFemtogramMilliSiementoMillisiemensMilliSiemensPerCentimetertoMillisiemensPerCentimeterOsmolePerLitertoOsmolesPerLiter
Add the unit
PerMinuteAdd
convert_unitfunction to convert aRawValueUnitorValueUnitinstance from one unit to another, using thepintlibrary.
v0.1.5 #
Add unit
MilliSiemen,LiterPerSquareMeter,MilliSiemensPerCentimeter,LiterPerSquareMeterPerMinute,LiterPerSquareMeterPerHour,LiterPerSquareMeterPerHourPerPoundPerSquareInch
v0.1.4 #
Add unit
MillimolePerLiter
v0.1.3 #
Add units
MilliDegreeAngle,NanometerPerMinuteAdd mapping for
"NANOMETERS" -> "Nanometer","msec" -> "MilliSecond","ul" -> "Microliter"
v0.1.2 #
Add
PERCENT_MAPPING
v0.1.1 #
Fix bug where
Unit.NANOGRAM_PER_LITERmapped to “NanogramPerMilliliter”
v0.1.0 #
Initial version