From cddf37be38eb76350221afa87c4b38bc96c0fc3b Mon Sep 17 00:00:00 2001 From: Sarath Date: Fri, 13 Sep 2024 11:25:25 +0200 Subject: [PATCH 1/4] fix free energy --- examples/example_12/analysis.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/example_12/analysis.ipynb b/examples/example_12/analysis.ipynb index 7edf9d7..60eed9d 100644 --- a/examples/example_12/analysis.ipynb +++ b/examples/example_12/analysis.ipynb @@ -89,7 +89,7 @@ "The first step is to calculate the entropy from free energy using the following equation, \n", "\n", "$$\n", - "-S = \\bigg ( \\frac{dF}{dT} \\bigg )_p\n", + "-S = \\bigg ( \\frac{dG}{dT} \\bigg )_p\n", "$$\n", "\n", "Then differentiating once more provides the specific heat, \n", @@ -255,7 +255,7 @@ "kernelspec": { "display_name": "calphy", "language": "python", - "name": "calphy" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -267,7 +267,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.5" + "version": "3.12.5" } }, "nbformat": 4, From 1ac19b471507948a63351802391a4c7ecad2bd5b Mon Sep 17 00:00:00 2001 From: Sarath Menon Date: Fri, 13 Sep 2024 12:32:34 +0200 Subject: [PATCH 2/4] add methods to parse results --- calphy/input.py | 12 ---- calphy/postprocessing.py | 115 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 calphy/postprocessing.py diff --git a/calphy/input.py b/calphy/input.py index 3add0b0..2d0f6ba 100644 --- a/calphy/input.py +++ b/calphy/input.py @@ -42,18 +42,6 @@ __version__ = "1.3.10" -def read_report(folder): - """ - Read the finished calculation report - """ - repfile = os.path.join(folder, "report.yaml") - if not os.path.exists(repfile): - raise FileNotFoundError(f"file {repfile} not found") - - with open(repfile, 'r') as fin: - data = yaml.safe_load(fin) - return data - def _check_equal(val): if not (val[0]==val[1]==val[2]): return False diff --git a/calphy/postprocessing.py b/calphy/postprocessing.py new file mode 100644 index 0000000..29e24a3 --- /dev/null +++ b/calphy/postprocessing.py @@ -0,0 +1,115 @@ +import os +import numpy as np +import pandas as pd + +def read_report(folder): + """ + Read the finished calculation report + + Parameters + ---------- + folder: string + folder from which calculation is to be read + + Returns + ------- + data: dict + dictionary with results + + """ + repfile = os.path.join(folder, "report.yaml") + if not os.path.exists(repfile): + raise FileNotFoundError(f"file {repfile} not found") + + with open(repfile, 'r') as fin: + data = yaml.safe_load(fin) + return data + +def gather_results(mainfolder): + """ + Gather results from all subfolders in a given folder into a Pandas DataFrame + + Parameters + ---------- + mainfolder: string + folder where calculations are stored + + Returns + ------- + df: pandas DataFrame + DataFrame with results + """ + datadict = {} + datadict['mode'] = [] + datadict['status'] = [] + datadict['temperature'] = [] + datadict['pressure'] = [] + datadict['free_energy'] = [] + datadict['reference_phase'] = [] + datadict['error_code'] = [] + + folders = next(os.walk(mainfolder))[1] + for folder in folders: + #adjust for pyiron folder, see + if folder.split('_')[-1] == 'hdf5': + #this could be a pyiron calc + withouthdf = folder.split('_hdf5')[0] + folder = f'{folder}/{withouthdf}' + + inpfile = os.path.join(mainfolder, folder, 'input_file.yaml') + #print(inpfile) + if not os.path.exists(inpfile): + continue; + + #ok, valid calculation, try to parse input file to get info + with open(inpfile, 'r') as fin: + inp = yaml.safe_load(fin) + #grab the first calculation + inp = inp['calculations'][0] + #mode + mode = inp['mode'] + datadict['mode'].append(mode) + datadict['temperature'].append(inp['temperature']) + datadict['pressure'].append(inp['pressure']) + datadict['reference_phase'].append(inp['reference_phase']) + + #check output file + outfile = os.path.join(mainfolder, folder, 'report.yaml') + datadict['error_code'].append(None) + + #print(inpfile) + if not os.path.exists(outfile): + datadict['status'].append('False') + datadict['free_energy'].append(np.NaN) + #check if error file is found + errfile = os.path.join(os.getcwd(), mainfolder, folder+'.sub.err') + if os.path.exists(errfile): + with open(errfile, 'r') as fin: + for line in fin: + if 'calphy.errors' in line: + break + try: + error_code = line.split(':')[0].split('.')[-1] + datadict['error_code'][-1] = error_code + except: + pass + continue; + + if mode in ['fe', 'alchemy', 'composition_scaling']: + datadict['status'].append('True') + + #ok, valid calculation, try to parse input file to get info + with open(outfile, 'r') as fin: + out = yaml.safe_load(fin) + + datadict['free_energy'].append(out['results']['free_energy']) + + #parse extra info + if mode in ['ts', 'tscale']: + datafile = os.path.join(os.getcwd(), folder, 'temperature_sweep.dat') + t, f = np.unpack(datafile, unpack=True, usecols=(0,1)) + datadict['temperature'][-1] = t + datadict['free_energy'][-1] = f + + df = pd.DataFrame(data=datadict) + return df \ No newline at end of file From dda6b2732237882e3ea8ea2a620183731b578b73 Mon Sep 17 00:00:00 2001 From: Sarath Menon Date: Fri, 13 Sep 2024 12:38:11 +0200 Subject: [PATCH 3/4] add pandas as dependency --- environment-nolammps.yml | 1 + environment.yml | 1 + setup.py | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/environment-nolammps.yml b/environment-nolammps.yml index cc6d8a4..280f290 100644 --- a/environment-nolammps.yml +++ b/environment-nolammps.yml @@ -17,3 +17,4 @@ dependencies: - uncertainties - pydantic >=2.3.0 - pyscal3 + - pandas diff --git a/environment.yml b/environment.yml index 3e164e3..c2ceed7 100644 --- a/environment.yml +++ b/environment.yml @@ -16,3 +16,4 @@ dependencies: - uncertainties - pydantic >=2.3.0 - pyscal3 + - pandas diff --git a/setup.py b/setup.py index 25c8b93..2dde7dc 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ description="free energy calculation for python", install_requires=['matplotlib', 'pytest', 'pyyaml', 'mendeleev', - 'tqdm', 'scipy', 'pydantic', 'pyscal3'], + 'tqdm', 'scipy', 'pydantic', 'pyscal3', 'pandas'], license="GNU General Public License v3", long_description=readme, long_description_content_type='text/markdown', From 46b56049d4f0ac8c955046e0d68d01d0622159f1 Mon Sep 17 00:00:00 2001 From: Sarath Menon Date: Fri, 13 Sep 2024 12:41:23 +0200 Subject: [PATCH 4/4] make pandas optional --- calphy/postprocessing.py | 6 +++++- environment-nolammps.yml | 1 - environment.yml | 1 - setup.py | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/calphy/postprocessing.py b/calphy/postprocessing.py index 29e24a3..5781839 100644 --- a/calphy/postprocessing.py +++ b/calphy/postprocessing.py @@ -1,6 +1,5 @@ import os import numpy as np -import pandas as pd def read_report(folder): """ @@ -39,6 +38,11 @@ def gather_results(mainfolder): df: pandas DataFrame DataFrame with results """ + try: + import pandas as pd + except ImportError: + raise ImportError('Please install pandas to use this function') + datadict = {} datadict['mode'] = [] datadict['status'] = [] diff --git a/environment-nolammps.yml b/environment-nolammps.yml index 280f290..cc6d8a4 100644 --- a/environment-nolammps.yml +++ b/environment-nolammps.yml @@ -17,4 +17,3 @@ dependencies: - uncertainties - pydantic >=2.3.0 - pyscal3 - - pandas diff --git a/environment.yml b/environment.yml index c2ceed7..3e164e3 100644 --- a/environment.yml +++ b/environment.yml @@ -16,4 +16,3 @@ dependencies: - uncertainties - pydantic >=2.3.0 - pyscal3 - - pandas diff --git a/setup.py b/setup.py index 2dde7dc..25c8b93 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ description="free energy calculation for python", install_requires=['matplotlib', 'pytest', 'pyyaml', 'mendeleev', - 'tqdm', 'scipy', 'pydantic', 'pyscal3', 'pandas'], + 'tqdm', 'scipy', 'pydantic', 'pyscal3'], license="GNU General Public License v3", long_description=readme, long_description_content_type='text/markdown',