diff --git a/.bumpversion.cfg b/.bumpversion.cfg index eeb7a32..577b356 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.6.13 +current_version = 0.6.14 commit = True tag = False diff --git a/CITATION.cff b/CITATION.cff index d0555ac..7d089c5 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -20,4 +20,4 @@ url: 'https://atomrdf.pyscal.org' license: "MIT" repository-code: https://github.com/pyscal/atomRDF type: software -version: 0.6.13 +version: 0.6.14 diff --git a/atomrdf/graph.py b/atomrdf/graph.py index d579c24..66b9b2f 100644 --- a/atomrdf/graph.py +++ b/atomrdf/graph.py @@ -34,6 +34,7 @@ import logging import warnings import re +import pickle # from pyscal3.core import System from pyscal3.atoms import Atoms @@ -803,6 +804,21 @@ def write(self, filename, format="json-ld"): with open(filename, "w") as fout: fout.write(self.graph.serialize(format=format)) + def close(self, filename, format="json-ld"): + """ + Close the graph and write to a file + + Parameters + ---------- + filename: string + name of output file + + Returns + ------- + None + """ + self.write(filename, format=format) + def archive(self, package_name, format="turtle", compress=True, add_simulations=False): """ Publish a dataset from graph including per atom quantities. @@ -1215,7 +1231,11 @@ def get_system_from_sample(self, sample): sys.graph = self return sys - def to_file(self, sample, filename=None, format="poscar", add_sample_id=True): + def to_file(self, sample, filename=None, format="poscar", add_sample_id=True, + input_data=None, pseudopotentials=None, + kspacing=None, kpts=None, + koffset=(0, 0, 0), + crystal_coordinates=False): """ Save a given sample to a file @@ -1227,9 +1247,28 @@ def to_file(self, sample, filename=None, format="poscar", add_sample_id=True): filename: string name of output file - format: string, {"lammps-dump","lammps-data", "poscar"} + format: string, {"lammps-dump","lammps-data", "poscar", 'cif', 'quantum-espresso'} or any format supported by ase + input_data : str, optional + Additional input data to include in the output file. Defaults to None. + Only valid for quantum-espresso format. See ASE write docs for more information. + pseudopotentials : str, optional + The path to the pseudopotentials file. Defaults to None. + Only valid for quantum-espresso format. See ASE write docs for more information. + kspacing : float, optional + The k-spacing value to include in the output file. Defaults to None. + Only valid for quantum-espresso format. See ASE write docs for more information. + kpts : list, optional + A list of k-points to include in the output file. Defaults to None. + Only valid for quantum-espresso format. See ASE write docs for more information. + koffset : tuple, optional + The k-offset values to include in the output file. Defaults to (0, 0, 0). + Only valid for quantum-espresso format. See ASE write docs for more information. + crystal_coordinates : bool, optional + Whether to include crystal coordinates in the output file. Defaults to False. + Only valid for quantum-espresso format. See ASE write docs for more information. + Returns ------- None @@ -1239,24 +1278,9 @@ def to_file(self, sample, filename=None, format="poscar", add_sample_id=True): filename = os.path.join(os.getcwd(), "out") sys = self.get_system_from_sample(sample) - - if format == "ase": - return sys.write.ase() - elif format == "poscar": - asesys = sys.write.ase() - write(filename, asesys, format="vasp") - if add_sample_id: - lines = [] - with open(filename, "r") as fin: - for line in fin: - lines.append(line) - lines[0] = sample.toPython() + "\n" - with open(filename, "w") as fout: - for line in lines: - fout.write(line) - else: - asesys = sys.write.ase() - write(filename, asesys, format=format) + sys.to_file(filename, format=format, add_sample_id=add_sample_id, input_data=input_data, + pseudopotentials=pseudopotentials, kspacing=kspacing, + kpts=kpts, koffset=koffset, crystal_coordinates=crystal_coordinates) def enable_workflow(self, workflow_object, workflow_environment=None, workflow_module=None): self.workflow.inform_graph(workflow_object, @@ -1264,7 +1288,7 @@ def enable_workflow(self, workflow_object, workflow_environment=None, workflow_m workflow_module=workflow_module) def add_workflow(self, job, workflow_environment=None, workflow_module=None, job_dicts=None, - add_intermediate_jobs=False): + add_intermediate_jobs=False): self.workflow.to_graph(job, workflow_environment=workflow_environment, workflow_module=workflow_module, job_dicts=job_dicts, diff --git a/atomrdf/structure.py b/atomrdf/structure.py index 4a76c18..14acf08 100644 --- a/atomrdf/structure.py +++ b/atomrdf/structure.py @@ -16,7 +16,7 @@ import shutil import tarfile import warnings - +from ase.io import write import pyscal3.structure_creator as pcs from pyscal3.grain_boundary import GrainBoundary @@ -1083,22 +1083,104 @@ def __delitem__(self, val): # now the graph has to be updated accordingly self.delete(indices=list(val)) + def write_poscar_id(self, outfile): + lines = [] + with open(outfile, "r") as fin: + for line in fin: + lines.append(line) + lines[0] = self.sample.toPython() + "\n" + with open(outfile, "w") as fout: + for line in lines: + fout.write(line) + + def write_quatum_espresso_id(self, outfile): + lines = [] + lines.append(f"! {self.sample.toPython()}\n") + with open(outfile, "r") as fin: + for line in fin: + lines.append(line) + with open(outfile, "w") as fout: + for line in lines: + fout.write(line) + def to_file(self, outfile, format='lammps-dump', customkeys=None, customvals=None, - compressed=False, timestep=0, species=None, add_sample_id=True): + compressed=False, timestep=0, species=None, add_sample_id=True, + input_data=None, pseudopotentials=None, + kspacing=None, kpts=None, + koffset=(0, 0, 0), + crystal_coordinates=False): + """ + Write the structure to a file in the specified format. - inputmethods.to_file(self, outfile, format=format, customkeys=customkeys, customvals=customvals, - compressed=compressed, timestep=timestep, species=species) - if format == 'poscar': - if add_sample_id and (self.sample is not None): - lines = [] - with open(outfile, "r") as fin: - for line in fin: - lines.append(line) - lines[0] = self.sample.toPython() + "\n" - with open(outfile, "w") as fout: - for line in lines: - fout.write(line) + Parameters + ---------- + outfile : str + The path to the output file. + format : str, optional + The format of the output file. Defaults to 'lammps-dump'. + customkeys : list, optional + A list of custom keys to include in the output file. Defaults to None. + Only valid if format is 'lammps-dump'. + customvals : list, optional + A list of custom values corresponding to the custom keys. Defaults to None. + Only valid if format is 'lammps-dump'. + compressed : bool, optional + Whether to compress the output file. Defaults to False. + timestep : int, optional + The timestep value to include in the output file. Defaults to 0. + Only valid if format is 'lammps-dump'. + species : list, optional + A list of species to include in the output file. Defaults to None. + Only valid for ASE, if species is not specified. + add_sample_id : bool, optional + Whether to add a sample ID to the output file. Defaults to True. + Only valid for poscar and quantum-espresso formats. + input_data : str, optional + Additional input data to include in the output file. Defaults to None. + Only valid for quantum-espresso format. See ASE write docs for more information. + pseudopotentials : str, optional + The path to the pseudopotentials file. Defaults to None. + Only valid for quantum-espresso format. See ASE write docs for more information. + kspacing : float, optional + The k-spacing value to include in the output file. Defaults to None. + Only valid for quantum-espresso format. See ASE write docs for more information. + kpts : list, optional + A list of k-points to include in the output file. Defaults to None. + Only valid for quantum-espresso format. See ASE write docs for more information. + koffset : tuple, optional + The k-offset values to include in the output file. Defaults to (0, 0, 0). + Only valid for quantum-espresso format. See ASE write docs for more information. + crystal_coordinates : bool, optional + Whether to include crystal coordinates in the output file. Defaults to False. + Only valid for quantum-espresso format. See ASE write docs for more information. + Returns + ------- + None + """ + if format == "ase": + return self.write.ase() + elif format == "poscar": + asesys = self.write.ase() + write(outfile, asesys, format="vasp") + if add_sample_id and (self.sample is not None): + self.write_poscar_id(outfile) + elif format == "lammps-dump": + inputmethods.to_file(self, outfile, format='lammps-dump', customkeys=customkeys, customvals=customvals, + compressed=compressed, timestep=timestep, species=species) + elif format == "lammps-data": + asesys = self.write.ase() + write(outfile, asesys, format='lammps-data', atom_style='atomic') + elif format == "quantum-espresso": + asesys = self.write.ase() + write(outfile, asesys, format='espresso-in', input_data=input_data, + pseudopotentials=pseudopotentials, kspacing=kspacing, + kpts=kpts, koffset=koffset, crystal_coordinates=crystal_coordinates) + if add_sample_id and (self.sample is not None): + self.write_quatum_espresso_id(outfile) + else: + asesys = self.write.ase() + write(outfile, asesys, format=format) def to_graph(self): """ diff --git a/examples/08_write_qe.ipynb b/examples/08_write_qe.ipynb new file mode 100644 index 0000000..e8c2dc4 --- /dev/null +++ b/examples/08_write_qe.ipynb @@ -0,0 +1,108 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from atomrdf import KnowledgeGraph, System" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "kg = KnowledgeGraph()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "s = System.create.element.Fe(graph = kg)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "s.write.file('qe_input', format='quantum-espresso')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "! sample:f2b5122e-7458-40e2-a197-4275dde7ed77\n", + "&CONTROL\n", + "/\n", + "&SYSTEM\n", + " ntyp = 1\n", + " nat = 2\n", + " ibrav = 0\n", + "/\n", + "&ELECTRONS\n", + "/\n", + "&IONS\n", + "/\n", + "&CELL\n", + "/\n", + "\n", + "ATOMIC_SPECIES\n", + "Fe 55.845 None\n", + "\n", + "K_POINTS gamma\n", + "\n", + "CELL_PARAMETERS angstrom\n", + "2.87000000000000 0.00000000000000 0.00000000000000\n", + "0.00000000000000 2.87000000000000 0.00000000000000\n", + "\u001b[Km--More--(67%)\u001b[m" + ] + } + ], + "source": [ + "! more qe_input" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "workflow-rdf", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/setup.py b/setup.py index 306e7da..a8c3428 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name='atomrdf', - version='0.6.13', + version='0.6.14', author='Abril Azocar Guzman, Sarath Menon', author_email='sarath.menon@pyscal.org', description='Ontology based structural manipulation and quering',