FAQ | This is a LIVE service | Changelog

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

update to add phasecalculator runner- top level runner of system.

parent 7c86d7ff
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 running phase calculator calculations.
@author: Mark
"""
import logging
import pathlib
import phasecalculator.runners.phasexmlcreatorrunner as phasexmlrun
import phasecalculator.runners.fgipanalysisrunner as fgiprun
import phasecalculator.runners.similarityanalysisrunner as simrun
import phasecalculator.runners.vleanalysisrunner as vlerun
logging.basicConfig()
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.WARN)
def run_all_analysis(system_info, **kwargs):
# TODO Logging output of analysis
phase_filename, solvent_list = create_phase_and_solvent_xml_files(system_info, **kwargs)
if system_info.calc_vle():
run_vle_analysis(system_info, phase_filename, **kwargs)
if system_info.calc_fgip():
run_fgip_analysis(system_info, solvent_list, **kwargs)
if system_info.calc_similarity():
run_similarity_analysis(system_info, solvent_list, **kwargs)
def run_fgip_analysis(system_info, solvent_filename_dict_list, **kwargs):
"""
Parameters
----------
system_info : TYPE
DESCRIPTION.
solvent_filename_dict_list : TYPE
DESCRIPTION.
**kwargs : TYPE
DESCRIPTION.
Returns
-------
None.
"""
# TODO: for each solvent file/temp combo in dict
jar_path = system_info.runtime_information.phasetransfer_jar
combined_results = []
combined_latex_blocks = ""
for solvent_filename_dict in solvent_filename_dict_list:
solvent_filename = solvent_filename_dict["solvent_filename"]
energy_xml_filename = create_binding_energy_output_filename(solvent_filename)
directory_base = system_info.runtime_information.output_dir
temperature = solvent_filename_dict["temperature_value"]
temperature_unit = solvent_filename_dict["temperature_units"]
results, latex_blocks = fgiprun.calc_energies_and_fgips(jar_path, energy_xml_filename,
solvent_filename, directory_base,
temperature=temperature,
temperature_unit=temperature_unit,
**kwargs)
combined_results.extend(results)
combined_latex_blocks += latex_blocks
return combined_results, combined_latex_blocks
def run_similarity_analysis(system_info, solvent_filename_dict, **kwargs):
"""
Parameters
----------
system_info : TYPE
DESCRIPTION.
solvent_filename_dict : TYPE
DESCRIPTION.
**kwargs : TYPE
DESCRIPTION.
Returns
-------
None.
"""
solvent_filename_dict_list = []
jar_path = system_info.runtime_information.phasetransfer_jar
for solv_dict in solvent_filename_dict:
solvent_filename = solv_dict["solvent_filename"]
energy_filename = create_free_energy_output_filename(solvent_filename)
temperature = solv_dict["temperature_value"]
temperature_unit = solv_dict["temperature_units"]
solv_dict["energy_filename"] = energy_filename
solvent_filename_dict_list.append(solv_dict)
simrun.run_free_energy_calculation(jar_path, energy_filename,
solvent_filename,
temperature=temperature,
temperature_unit=temperature_unit,
**kwargs)
output_dir = system_info.runtime_information.output_dir
output_type = system_info.output_information.similarity_output_type
out_res, poly_filename_list = simrun.extract_all_solvents_and_generate_polynomials(solvent_filename_dict_list,
output_dir)
simrun.run_similarity_analysis(poly_filename_list, output_type, output_dir)
#
def run_vle_analysis(system_info, phase_filename, **kwargs):
"""
Parameters
----------
system_info : TYPE
DESCRIPTION.
phase_filename : TYPE
DESCRIPTION.
**kwargs : TYPE
DESCRIPTION.
Returns
-------
TYPE
DESCRIPTION.
"""
jar_path = system_info.runtime_information.phasetransfer_jar
output_filename = create_phase_output_filename(phase_filename)
return vlerun.run_vle_calculation(jar_path, phase_filename, output_filename, **kwargs)
def create_output_dir(system_info):
"""Makes output directory for system calculation.
Parameters
----------
system_info : System
Calculation System object.
Returns
-------
None.
"""
output_path = pathlib.Path(system_info.runtime_information.output_dir)
output_path.mkdir(parents=True,exist_ok=True)
return output_path.as_posix()
def create_free_energy_output_filename(solvent_filename):
"""
Parameters
----------
solvent_filename : TYPE
DESCRIPTION.
Returns
-------
TYPE
DESCRIPTION.
"""
return solvent_filename.replace(".xml","free.xml")
def create_binding_energy_output_filename(solvent_filename):
"""
Parameters
----------
solvent_filename : TYPE
DESCRIPTION.
Returns
-------
TYPE
DESCRIPTION.
"""
return solvent_filename.replace(".xml", "binding.xml")
def create_phase_output_filename(phase_filename):
"""
Parameters
----------
phase_filename : TYPE
DESCRIPTION.
Returns
-------
TYPE
DESCRIPTION.
"""
return phase_filename.replace(".xml", "calculated.xml")
def create_phase_and_solvent_xml_files(system_info, **kwargs):
"""
Parameters
----------
system_info : TYPE
DESCRIPTION.
filestem : TYPE, optional
DESCRIPTION. The default is "system".
**kwargs : TYPE
DESCRIPTION.
Returns
-------
phase_file : TYPE
DESCRIPTION.
solvent_list : TYPE
DESCRIPTION.
"""
return phasexmlrun.create_phase_and_solvent_files(system_info, **kwargs)
\ 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 phase calculator runner tests.
@author: Mark
"""
import logging
import unittest
import pandas
import pathlib
import os
import shutil
import numpy as np
from testfixtures import Replacer
from testfixtures.popen import MockPopen
from lxml import etree
import puresolventinformation.information as pureinf
from phasecalculator.classes.temperature import Temperature
from phasecalculator.classes.molecule import Molecule
from phasecalculator.classes.phase import Phase
from phasecalculator.classes.phases import Phases
from phasecalculator.classes.runtimeinformation import RuntimeInformation
from phasecalculator.classes.outputinformation import OutputInformation
from phasecalculator.classes.system import System
import phasecalculator.runners.phasecalculatorrunner as pcalcrun
class PhaseCalculatorRunnerTestCase(unittest.TestCase):
"""Test case for phase calculator runner methods."""
def setUp(self):
"""Set up before tests.
Returns
-------
None.
"""
ssip_filenames = pureinf.get_ssip_file_dict()
self.water_ssip = ssip_filenames["XLYOFNOQVPJJNP-UHFFFAOYSA-N"]
self.butanol_ssip = ssip_filenames["LRHPLDYGYMQRHN-UHFFFAOYSA-N"]
self.temperature = Temperature(298.0, "KELVIN")
self.water_molecule = Molecule("water", "XLYOFNOQVPJJNP-UHFFFAOYSA-N", self.water_ssip, 0.8354716981132075)
self.butanol_molecule = Molecule("1-butanol", "LRHPLDYGYMQRHN-UHFFFAOYSA-N", self.butanol_ssip, 0.16452830188679246)
self.phase = Phase([self.water_molecule, self.butanol_molecule], self.temperature)
self.phases = Phases([self.phase])
parent_directory = pathlib.Path(__file__).parents[1]
self.example_jar = (parent_directory / "resources/example.jar").absolute().as_posix()
self.runtime_inf = RuntimeInformation(self.example_jar, "scratch", "fgip")
self.out_inf = OutputInformation(True, True, "all", True)
self.system = System(self.phases, self.runtime_inf, self.out_inf)
pcalcrun.phasexmlrun.create_scratch_dir(self.system)
self.directory_base = pcalcrun.create_output_dir(self.system)
self.expected_phase_file = (parent_directory /"resources" / "expected_phase.xml").absolute().as_posix()
self.expected_solvent_file = (parent_directory /"resources" / "expected_solvent.xml").absolute().as_posix()
self.expected_binding_file = (parent_directory /"resources" / "expected_solventbinding.xml").absolute().as_posix()
self.expected_free_file = (parent_directory /"resources" / "expected_solventfree.xml").absolute().as_posix()
self.phase_filename = "scratch/systemphase.xml"
self.solv_energy_dict = {"solvent_filename":self.expected_solvent_file,
"temperature_value":298.0,
"temperature_units":"KELVIN"}
self.energy_xmlfile = "fgip/298_0K/1-butanol0.165water0.835binding.xml"
self.poly_file = "fgip/298_0K/1-butanol0.165water0.835binding_poly_fit_split.csv"
self.matrix_file = "fgip/298_0K/1-butanol0.165water0.835_solv_map.csv"
self.solvent_map = "fgip/298_0K/1-butanol0.165water0.835_solv_map.svg"
self.fgip_file = "fgip/298_0K/1-butanol0_165water0_835_FGIP.svg"
self.similarity_file = "fgip/similaritymatrix.csv"
self.expected_latex = r"""
\begin{figure}[H]
\centering
\includegraphics[width=0.5\textwidth]{fgip/298_0K/1-butanol0_165water0_835_FGIP.eps}
\caption[1-butanol0.165water0.835 FGIP]{FGIP for 1-butanol0.165water0.835 at 298K.}
\label{fig:1-butanol0_165water0_835solvationmap}
\end{figure}
"""
def tearDown(self):
"""Clean up after tests.
Returns
-------
None.
"""
for filename in os.listdir(self.directory_base):
file_path = os.path.join(self.directory_base, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
LOGGER.error('Failed to delete %s. Reason: %s', file_path, e)
if pathlib.Path(self.directory_base).is_dir():
os.rmdir(self.directory_base)
def copy_intermediate_files(self):
"""Test fixture required for run all analysis test as intermediate
energy files are not produced during test as an SSIP jar is not present.
Returns
-------
None.
"""
shutil.copyfile(self.expected_binding_file, "scratch/systemsolvent_298.0Kbinding.xml")
shutil.copyfile(self.expected_free_file, "scratch/systemsolvent_298.0Kfree.xml")
def test_run_all_analysis(self):
"""Test
Returns
-------
None.
"""
self.copy_intermediate_files()
pcalcrun.run_all_analysis(self.system)
self.assertTrue(pathlib.Path(self.matrix_file).is_file())
self.assertTrue(pathlib.Path(self.solvent_map).is_file())
self.assertTrue(pathlib.Path(self.fgip_file).is_file())
self.assertTrue(pathlib.Path(self.similarity_file).is_file())
def test_run_fgip_analysis(self):
"""Test
Returns
-------
None.
"""
results, latex_blocks = pcalcrun.run_fgip_analysis(self.system, [self.solv_energy_dict])
self.assertListEqual([(0,0)], results)
self.assertMultiLineEqual(self.expected_latex, latex_blocks)
self.assertTrue(pathlib.Path(self.matrix_file).is_file())
self.assertTrue(pathlib.Path(self.solvent_map).is_file())
self.assertTrue(pathlib.Path(self.fgip_file).is_file())
def test_run_similarity_analysis(self):
"""Test
Returns
-------
None.
"""
pcalcrun.run_similarity_analysis(self.system, [self.solv_energy_dict])
self.assertTrue(pathlib.Path(self.similarity_file).is_file())
def test_run_vle_analysis(self):
"""Test
Returns
-------
None.
"""
expected_args = ["java", "-jar", self.example_jar,"--phaseOut",
"--phaseCollectionList", "--conccalc",
"--gascalc", "--calc", "--phaseFile", self.phase_filename,
"-o", self.phase_filename.replace(".xml","calculated.xml")]
process = pcalcrun.run_vle_analysis(self.system, self.phase_filename)
self.assertListEqual(expected_args, process.args)
def test_create_output_dir(self):
"""Test
Returns
-------
None.
"""
self.assertTrue(pathlib.Path(self.system.runtime_information.output_dir).is_dir())
def test_create_free_energy_output_filename(self):
"""Test
Returns
-------
None.
"""
expected_filename = "solvent_filenamefree.xml"
actual_filename = pcalcrun.create_free_energy_output_filename("solvent_filename.xml")
self.assertEqual(expected_filename, actual_filename)
def test_create_binding_energy_output_filename(self):
"""Test
Returns
-------
None.
"""
expected_filename = "solvent_filenamebinding.xml"
actual_filename = pcalcrun.create_binding_energy_output_filename("solvent_filename.xml")
self.assertEqual(expected_filename, actual_filename)
def test_create_phase_output_filename(self):
"""Test
Returns
-------
None.
"""
expected_filename = "phase_filenamecalculated.xml"
actual_filename = pcalcrun.create_phase_output_filename("phase_filename.xml")
self.assertEqual(expected_filename, actual_filename)
def test_create_phase_and_solvent_xml_files(self):
"""Test
Returns
-------
None.
"""
phase_filename, solvent_filename_list = pcalcrun.create_phase_and_solvent_xml_files(self.system)
self.assertEqual("scratch/systemphase.xml", phase_filename)
with open(phase_filename, "r") as act_file:
actual_contents = act_file.read()
with open(self.expected_phase_file, "r") as exp_file:
expected_contents = exp_file.read()
self.assertMultiLineEqual(expected_contents, actual_contents)
expected_list = [{"solvent_filename":"scratch/systemsolvent_298.0K.xml",
'temperature_units': 'KELVIN',
'temperature_value': 298.0}]
self.assertListEqual(expected_list, solvent_filename_list)
solvent_filename = solvent_filename_list[0]["solvent_filename"]
with open(solvent_filename, "r") as act_file:
actual_contents = act_file.read()
with open(self.expected_solvent_file, "r") as exp_file:
expected_contents = exp_file.read()
self.assertMultiLineEqual(expected_contents, actual_contents)
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