ThermoML Data Sets¶
ThermoMLDataSet object offers an API for extracting physical properties from the NIST ThermoML Archive, both directly from the archive itself or from files stored in the IUPAC-
standard ThermoML format.
The API only supports extracting those properties which have been registered with the frameworks plug-in system, and does not currently load the full set of metadata available in the archive files.
If the metadata you require is not currently exposed, please open an issue on the GitHub issue tracker to request it.
Currently the framework has built-in support for extracting:
Mass density, kg/m3 (
Excess molar volume, m3/mol (
Relative permittivity at zero frequency (
Excess molar enthalpy (molar enthalpy of mixing), kJ/mol (
Molar enthalpy of vaporization or sublimation, kJ/mol (
where here both the ThermoML property name (as defined by the IUPAC XML schema) and the built-in framework class are listed.
Properties to be extracted from ThermoML archives must have a corresponding class representation to be loading into. This class representation must both:
inherit from the frameworks
As an example, a class representation of the ThermoML ‘Mass density, kg/m3’ property could be defined and registered with the plug-in system using:
@thermoml_property("Mass density, kg/m3", supported_phases=PropertyPhase.Liquid) class Density(PhysicalProperty): """A class representation of a mass density property"""
Multiple ThermoML properties can be mapped onto a single class using the flexible
function. For example, the ‘Specific volume, m3/kg’ property (which is simply the reciprocal of mass density) may
be mapped onto the
Density object by providing a
def specific_volume_to_mass_density(specific_volume): """Converts a specific volume measurement into a mass density. Parameters ---------- specific_volume: ThermoMLProperty The specific volume measurement to convert. """ mass_density = Density() mass_density.value = 1.0 / specific_volume.value if mass_density.uncertainty is not None: mass_density.uncertainty = 1.0 / mass_density.uncertainty mass_density.phase = specific_volume.phase mass_density.thermodynamic_state = specific_volume.thermodynamic_state mass_density.substance = specific_volume.substance return mass_density # Register the ThermoML property using the conversion function. register_thermoml_property( thermoml_string="Specific volume, m3/kg", supported_phases=PropertyPhase.Liquid, property_class=Density, conversion_function=specific_volume_to_mass_density )
Converting the different density derivatives into a single density class removes the need to produce many very similar class representations of density measurements, and allows a single calculation schema to be defined for all variants.
Loading Data Sets¶
Data sets are most easily loaded using their digital object identifiers (DOI). For example, to retrieve the ThermoML
data set that accompanies this paper, we can simply use the DOI
data_set = ThermoMLDataset.from_doi('10.1016/j.jct.2005.03.012')
Data can be pulled from multiple sources at once by specifying multiple identifiers:
identifiers = ['10.1021/acs.jced.5b00365', '10.1021/acs.jced.5b00474'] dataset = ThermoMLDataset.from_doi(*identifiers)
Entire archives of properties can be downloaded directly from the ThermoML website and parsed by the framework. For example, to create a data set object containing all of the measurements recorded from the International Journal of Thermophysics:
# Download the archive of all properties from the IJT journal. import requests request = requests.get("https://trc.nist.gov/ThermoML/IJT.tgz", stream=True) # Make sure the request went ok. assert request # Unzip the files into a new 'ijt_files' directory. import io, tarfile tar_file = tarfile.open(fileobj=io.BytesIO(request.content)) tar_file.extractall("ijt_files") # Get the names of the extracted files import glob file_names = glob.glob("ijt_files/*.xml") # Create the data set object from propertyestimator.datasets.thermoml import ThermoMLDataSet data_set = ThermoMLDataSet.from_file(*file_names) # Save the data set to a JSON object data_set.json(file_path="ijt.json", format=True)