FAQ | This is a LIVE service | Changelog

Skip to content
Snippets Groups Projects
Commit 58e64933 authored by Mark Driver's avatar Mark Driver
Browse files

add phases class.

parent 82dc7590
No related branches found
No related tags found
No related merge requests found
# -*- coding: utf-8 -*-
# phasecalculator calculates FGIPs, solvent similarity and VLE with SSIMPLE.
# Copyright (C) 2019 Mark D. Driver
#
# phasecalculator is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
Script for Phases class.
@author: Mark
"""
import logging
from lxml import etree
from phasecalculator.classes.phase import Phase
from phasecalculator.classes.xmlnamespacing import PHASE_CALCULATOR, PHASE_CALC_NAMESPACE_DICT
logging.basicConfig()
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.WARN)
class Phases(object):
"""Phases class."""
def __init__(self, phase_list):
self.phase_list = phase_list
def __eq__(self, other):
"""Overload equality comparison operator.
Parameters
----------
other : object
object to compare.
Returns
-------
boolean
is equal.
"""
if other is None:
return False
if isinstance(other, type(self)):
if len(self.phase_list) != len(other.phase_list):
return False
phase_comps = all([self.phase_list[i] == other.phase_list[i] for i in range(len(self.phase_list))])
return phase_comps
else:
return False
@classmethod
def parse_xml(cls, phases_xml):
"""Parse XML representation to new instance.
Parameters
----------
phases_xml : lxml.etree.ElementTree
Element tree representation of phases XML.
Returns
-------
Phases
New instance.
"""
phase_xpath = "phasecalc:Phase"
phase_xml_list = phases_xml.xpath(phase_xpath, namespaces=PHASE_CALC_NAMESPACE_DICT)
phase_list = [Phase.parse_xml(phase_xml) for phase_xml in phase_xml_list]
return Phases(phase_list)
def write_to_xml(self):
"""Write phases to XML.
Returns
-------
phases_element : lxml.etree.Element
XML representation of Phases.
"""
phases_element = etree.Element(PHASE_CALCULATOR + "Phases", nsmap=PHASE_CALC_NAMESPACE_DICT)
for phase in self.phase_list:
phases_element.append(phase.write_to_xml())
return phases_element
def get_phase_compositions_by_temperature(self):
"""Get phases split up by temperature. This is for solvent XML generation.
Returns
-------
phase_dict : dict
Temperature: list of Phase objects pairs.
"""
phase_dict = {}
for phase in self.phase_list:
if phase.temperature in phase_dict.keys():
phase_dict[phase.temperature].append(phase)
else:
phase_dict[phase.temperature] = [phase]
return phase_dict
def get_ssip_file_locations(self):
"""Gets the SSIP file locations for all molecules in a contained phase.
Returns
-------
set of str
Set of unique SSIP file locations.
"""
ssip_file_locations = []
for phase in self.phase_list:
ssip_file_locations.extend(phase.get_ssip_file_locations())
return set(ssip_file_locations)
\ No newline at end of file
# -*- coding: utf-8 -*-
# phasecalculator calculates FGIPs, solvent similarity and VLE with SSIMPLE.
# Copyright (C) 2019 Mark D. Driver
#
# phasecalculator is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
Script for phases class tests.
@author: Mark
"""
import logging
from lxml import etree
import unittest
from phasecalculator.classes.temperature import Temperature
from phasecalculator.classes.molecule import Molecule
from phasecalculator.classes.phase import Phase
from phasecalculator.classes.phases import Phases
logging.basicConfig()
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.WARN)
class PhasesTestCase(unittest.TestCase):
"""Test case for Phases class."""
def setUp(self):
"""Set up before tests.
Returns
-------
None.
"""
self.temperature = Temperature(298.0, "KELVIN")
self.molecule = Molecule("water", "XLYOFNOQVPJJNP-UHFFFAOYSA-N", "XLYOFNOQVPJJNP-UHFFFAOYSA-N_ssip.xml", 1.0)
self.phase = Phase([self.molecule], self.temperature)
self.phases = Phases([self.phase])
def tearDown(self):
"""Clean up after tests.
Returns
-------
None.
"""
del self.phase
del self.molecule
del self.temperature
del self.phases
def test_parse_xml(self):
"""Test expected phases object is created.
Returns
-------
None.
"""
actual_phases = Phases.parse_xml(self.phases.write_to_xml())
self.assertEqual(self.phases, actual_phases)
def test_write_to_xml(self):
"""Test expected XML is produced.
Returns
-------
None.
"""
expected_xml = """<phasecalc:Phases xmlns:phasecalc="http://www-hunter.ch.cam.ac.uk/schema/PhaseCalculatorSchema.xsd">
<phasecalc:Phase>
<phasecalc:Molecule phasecalc:name="water" phasecalc:inChIKey="XLYOFNOQVPJJNP-UHFFFAOYSA-N" phasecalc:ssipFileLocation="XLYOFNOQVPJJNP-UHFFFAOYSA-N_ssip.xml" phasecalc:molefraction="1.0000"/>
<phasecalc:Temperature phasecalc:value="298.0" phasecalc:unit="KELVIN"/>
</phasecalc:Phase>
</phasecalc:Phases>
"""
actual_xml = self.phases.write_to_xml()
self.assertMultiLineEqual(expected_xml, etree.tounicode(actual_xml, pretty_print=True))
def test_get_phase_compositions_by_temperature(self):
"""Test expected dictionary produced.
Returns
-------
None.
"""
expected_dict = {self.temperature: [self.phase]}
actual_dict = self.phases.get_phase_compositions_by_temperature()
self.assertDictEqual(expected_dict, actual_dict)
def test_get_ssip_file_locations(self):
"""Test expected set of file locations is returned.
Returns
-------
None.
"""
expected_set = {self.molecule.ssip_file_loc}
actual_set = self.phases.get_ssip_file_locations()
self.assertSetEqual(expected_set, actual_set)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment