Coverage for backend/ahuora-compounds/ahuora_compounds/packages/chemsep.py: 96%
90 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-03-26 20:57 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-03-26 20:57 +0000
1import xml.etree.ElementTree as ET
2from pydantic import BaseModel
3from typing import Dict
4from ahuora_compounds.PropertyPackage import PropertyPackage
5from ahuora_compounds.CompoundRegistry import CompoundRegistry
6import os
8ChemsepCompoundData: Dict[str, "ChemsepCompound"] = {}
11def register(registry: CompoundRegistry) -> None:
12 registry.register_package(PropertyPackage("peng-robinson"))
14 for file in os.listdir(os.path.dirname(__file__) + "/data/chemsep/"):
15 if file.endswith(".xml"): 15 ↛ 14line 15 didn't jump to line 14 because the condition on line 15 was always true
16 compound_name = file[:-4]
17 compound = load_compound(compound_name)
18 ChemsepCompoundData[compound_name] = compound
19 registry.bind(compound_name, "peng-robinson")
22def convert_string_to_float(string: str) -> float | str:
23 try:
24 return float(string)
25 except (AttributeError, ValueError):
26 # TODO: Why are we doing this again?
27 return string
30class UnitValuePair(BaseModel):
31 name: str | None
32 value: float | str | None
33 unit: str | None
36# Helper functions
37def parse_element(elem: ET.Element | None):
38 if elem is None:
39 return None
40 try:
41 return UnitValuePair(name=elem.get('name'), value=convert_string_to_float(elem.get('value')), unit=elem.get('units'))
42 except (AttributeError, ValueError):
43 #TODO: Why are we catching these errors here? This is not really good practice. Is there a good reason for it?
44 return None
47Coefficients = Dict[str, float | str]
50def parse_coeff(element: ET.Element | None) -> Coefficients:
51 if element is None:
52 return {}
53 self = {}
54 for child in element:
55 value = child.get('value')
56 if value is not None: 56 ↛ 54line 56 didn't jump to line 54 because the condition on line 56 was always true
57 self[child.tag] = convert_string_to_float(value)
58 return self
60class ChemsepCompound(BaseModel):
61 LibraryIndex: UnitValuePair | None = None
62 CompoundID: UnitValuePair | None = None
63 StructureFormula: UnitValuePair | None = None
64 Family: UnitValuePair | None = None
65 CriticalTemperature: UnitValuePair | None = None
66 CriticalPressure: UnitValuePair | None = None
67 CriticalVolume: UnitValuePair | None = None
68 CriticalCompressibility: UnitValuePair | None = None
69 NormalBoilingPointTemperature: UnitValuePair | None = None
70 NormalMeltingPointTemperature: UnitValuePair | None = None
71 TriplePointTemperature: UnitValuePair | None = None
72 TriplePointPressure: UnitValuePair | None = None
73 MolecularWeight: UnitValuePair | None = None
74 LiquidVolumeAtNormalBoilingPoint: UnitValuePair | None = None
75 AcentricityFactor: UnitValuePair | None = None
76 RadiusOfGyration: UnitValuePair | None = None
77 SolubilityParameter: UnitValuePair | None = None
78 DipoleMoment: UnitValuePair | None = None
79 VanDerWaalsVolume: UnitValuePair | None = None
80 VanDerWaalsArea: UnitValuePair | None = None
81 HeatOfFormation: UnitValuePair | None = None
82 GibbsEnergyOfFormation: UnitValuePair | None = None
83 AbsEntropy: UnitValuePair | None = None
84 HeatOfFusionAtMeltingPoint: UnitValuePair | None = None
85 MatthiasCopemanC1: UnitValuePair | None = None
86 HeatOfCombustion: UnitValuePair | None = None
87 SolidDensity: Coefficients | None = None
88 LiquidDensity: Coefficients | None = None
89 VaporPressure: Coefficients | None = None
90 HeatOfVaporization: Coefficients | None = None
91 SolidHeatCapacityCp: Coefficients | None = None
92 LiquidHeatCapacityCp: Coefficients | None = None
93 IdealGasHeatCapacityCp: Coefficients | None = None
94 SecondVirialCoefficient: Coefficients | None = None
95 LiquidViscosity: Coefficients | None = None
96 VaporViscosity: Coefficients | None = None
97 LiquidThermalConductivity: Coefficients | None = None
98 VaporThermalConductivity: Coefficients | None = None
99 SurfaceTension: Coefficients | None = None
100 RPPHeatCapacityCp: Coefficients | None = None
101 RelativeStaticPermittivity: Coefficients | None = None
102 AntoineVaporPressure: Coefficients | None = None
103 LiquidViscosityRPS: Coefficients | None = None
106def load_compound(name: str) -> ChemsepCompound:
107 """
108 Parses the XML string and populates the object's attributes.
110 Args:
111 name (str): The XML data as a string.
112 """
113 with open(os.path.dirname(__file__) + "/data/chemsep/" + name.lower() + ".xml", 'r') as file:
114 file = ''.join(file.readlines())
116 root = ET.fromstring(file)
118 return ChemsepCompound(
119 LibraryIndex=parse_element(root.find('LibraryIndex')),
120 CompoundID=parse_element(root.find('CompoundID')),
121 StructureFormula=parse_element(root.find('StructureFormula')),
122 Family=parse_element(root.find('Family')),
123 CriticalTemperature=parse_element(root.find('CriticalTemperature')),
124 CriticalPressure=parse_element(root.find('CriticalPressure')),
125 CriticalVolume=parse_element(root.find('CriticalVolume')),
126 CriticalCompressibility=parse_element(root.find('CriticalCompressibility')),
127 NormalBoilingPointTemperature=parse_element(root.find('NormalBoilingPointTemperature')),
128 NormalMeltingPointTemperature=parse_element(root.find('NormalMeltingPointTemperature')),
129 TriplePointTemperature=parse_element(root.find('TriplePointTemperature')),
130 TriplePointPressure=parse_element(root.find('TriplePointPressure')),
131 MolecularWeight=parse_element(root.find('MolecularWeight')),
132 LiquidVolumeAtNormalBoilingPoint=parse_element(root.find('LiquidVolumeAtNormalBoilingPoint')),
133 AcentricityFactor=parse_element(root.find('AcentricityFactor')),
134 RadiusOfGyration=parse_element(root.find('RadiusOfGyration')),
135 SolubilityParameter=parse_element(root.find('SolubilityParameter')),
136 DipoleMoment=parse_element(root.find('DipoleMoment')),
137 VanDerWaalsVolume=parse_element(root.find('VanDerWaalsVolume')),
138 VanDerWaalsArea=parse_element(root.find('VanDerWaalsArea')),
139 HeatOfFormation=parse_element(root.find('HeatOfFormation')),
140 GibbsEnergyOfFormation=parse_element(root.find('GibbsEnergyOfFormation')),
141 AbsEntropy=parse_element(root.find('AbsEntropy')),
142 HeatOfFusionAtMeltingPoint=parse_element(root.find('HeatOfFusionAtMeltingPoint')),
143 MatthiasCopemanC1=parse_element(root.find('MatthiasCopemanC1')),
144 HeatOfCombustion=parse_element(root.find('HeatOfCombustion')),
145 SolidDensity=parse_coeff(root.find('SolidDensity')),
146 LiquidDensity=parse_coeff(root.find('LiquidDensity')),
147 VaporPressure=parse_coeff(root.find('VaporPressure')),
148 HeatOfVaporization=parse_coeff(root.find('HeatOfVaporization')),
149 SolidHeatCapacityCp=parse_coeff(root.find('SolidHeatCapacityCp')),
150 LiquidHeatCapacityCp=parse_coeff(root.find('LiquidHeatCapacityCp')),
151 IdealGasHeatCapacityCp=parse_coeff(root.find('IdealGasHeatCapacityCp')),
152 SecondVirialCoefficient=parse_coeff(root.find('SecondVirialCoefficient')),
153 LiquidViscosity=parse_coeff(root.find('LiquidViscosity')),
154 VaporViscosity=parse_coeff(root.find('VaporViscosity')),
155 LiquidThermalConductivity=parse_coeff(root.find('LiquidThermalConductivity')),
156 VaporThermalConductivity=parse_coeff(root.find('VaporThermalConductivity')),
157 SurfaceTension=parse_coeff(root.find('SurfaceTension')),
158 RPPHeatCapacityCp=parse_coeff(root.find('RPPHeatCapacityCp')),
159 RelativeStaticPermittivity=parse_coeff(root.find('RelativeStaticPermittivity')),
160 AntoineVaporPressure=parse_coeff(root.find('AntoineVaporPressure')),
161 LiquidViscosityRPS=parse_coeff(root.find('LiquidViscosityRPS')),
162 )