diff --git a/biosim_extractor/helpers/metadata_utils.py b/biosim_extractor/helpers/metadata_utils.py index 140b971..c54a188 100644 --- a/biosim_extractor/helpers/metadata_utils.py +++ b/biosim_extractor/helpers/metadata_utils.py @@ -1,24 +1,33 @@ #!/usr/bin/env python3 -def round_floats(obj, decimals=3): +def round_floats(obj, decimals=3, preserve_below=1e-3): """ - Recursively round all floats in a nested structure (dict, list, tuple) to the given decimals. + Recursively round floats in nested dicts, lists, and tuples. + + Very small non-zero floats are rounded in scientific notation so they are + not rounded to zero. They remain numbers. Args: - obj: The object to process (dict, list, tuple, float, etc.). - decimals: Number of decimal places to round to. + obj: Object to process. + decimals: Decimal places to keep. + preserve_below: Lower absolute-value threshold for preserving floats. Returns: - The processed object with all floats rounded. + Object with floats rounded while preserving numeric types. """ if isinstance(obj, float): + if obj != 0 and abs(obj) < preserve_below: + return float(f"{obj:.{decimals}e}") return round(obj, decimals) + elif isinstance(obj, list): - return [round_floats(item, decimals) for item in obj] + return [round_floats(item, decimals, preserve_below) for item in obj] + elif isinstance(obj, tuple): - return tuple(round_floats(item, decimals) for item in obj) + return tuple(round_floats(item, decimals, preserve_below) for item in obj) + elif isinstance(obj, dict): - return {k: round_floats(v, decimals) for k, v in obj.items()} - else: - return obj + return {k: round_floats(v, decimals, preserve_below) for k, v in obj.items()} + + return obj diff --git a/biosim_extractor/units/unitconversion.py b/biosim_extractor/units/unitconversion.py index 4022e23..7e9dd51 100644 --- a/biosim_extractor/units/unitconversion.py +++ b/biosim_extractor/units/unitconversion.py @@ -25,7 +25,7 @@ def __init__(self, standard_units: Optional[Dict[str, str]] = None) -> None: self.standards: Dict[str, str] = standard_units or { "length": "nm", # nanometers "volume": "nm³", # nanometers cubed - "time": "ps", # picoseconds + "time": "s", # seconds "energy": "kJ/mol", # kilojoules per mole "temperature": "K", # Kelvin "pressure": "bar", # bar @@ -37,6 +37,7 @@ def __init__(self, standard_units: Optional[Dict[str, str]] = None) -> None: "angle": "degree", # degree "charge": "e", # atomic charge units "molecular_weight": "g/mol", # grams per mol + "information_storage": "GB", # gigabytes } # Conversion factors to standard units @@ -59,10 +60,12 @@ def __init__(self, standard_units: Optional[Dict[str, str]] = None) -> None: "ų": 1000, }, "time": { - "fs": 0.001, - "ps": 1.0, - "ns": 1000.0, - "s": 1e12, + "fs": 1e-15, + "ps": 1e-12, + "ns": 1e-9, + "μs": 1e-6, + "ms": 0.001, + "s": 1.0, }, "energy": { "kcal/mol": 4.184, @@ -120,6 +123,10 @@ def __init__(self, standard_units: Optional[Dict[str, str]] = None) -> None: "amu": 1.0, "Da": 1.0, }, + "information_storage": { + "GB": 1.0, + "MB": 0.001, + }, } # Create reverse lookup: unit -> unit_type