Source code for dfttopif

import os
import uuid
import tarfile
import shutil
from dfttopif.parsers import VaspParser
from dfttopif.parsers import PwscfParser
from pypif.obj import *


[docs]def tarfile_to_pif(filename, temp_root_dir='', verbose=0): """ Process a tar file that contains DFT data. Input: filename - String, Path to the file to process. temp_root_dir - String, Directory in which to save temporary files. Defaults to working directory. verbose - int, How much status messages to print Output: pif - ChemicalSystem, Results and settings of the DFT calculation in pif format """ temp_dir = temp_root_dir + str(uuid.uuid4()) os.makedirs(temp_dir) try: tar = tarfile.open(filename, 'r') tar.extractall(path=temp_dir) tar.close() for i in os.listdir(temp_dir): cur_dir = temp_dir + '/' + i if os.path.isdir(cur_dir): return directory_to_pif(cur_dir, verbose) return directory_to_pif(temp_dir, verbose) finally: shutil.rmtree(temp_dir)
[docs]def archive_to_pif(filename, verbose=0): """ Given a archive file that contains output from a DFT calculation, parse the data and return a PIF object. Input: filename - String, Path to the file to process. verbose - int, How much status messages to print Output: pif - ChemicalSystem, Results and settings of the DFT calculation in pif format """ if tarfile.is_tarfile(filename): return tarfile_to_pif(filename, verbose) raise Exception('Cannot process file type')
[docs]def directory_to_pif(directory, verbose=0, quality_report=False): '''Given a directory that contains output from a DFT calculation, parse the data and return a pif object Input: directory - String, path to directory containing DFT results verbose - int, How much status messages to print Output: pif - ChemicalSystem, Results and settings of the DFT calculation in pif format ''' # Look for the first parser compatible with the directory foundParser = False for possible_parser in [VaspParser, PwscfParser]: try: parser = possible_parser(directory) if parser.test_if_from(directory): foundParser = True break except: pass if not foundParser: raise Exception('Directory is not in correct format for an existing parser') if verbose > 0: print("Found a %s directory", parser.get_name()) # Get information about the chemical system chem = ChemicalSystem() chem.chemical_formula = parser.get_composition() # Get software information, to list as method software = Software(name=parser.get_name(), version=parser.get_version_number()) # Define the DFT method object method = Method(name='Density Functional Theory', software=software) # Get the settings (aka. "conditions") of the DFT calculations conditions = [] for name, func in parser.get_setting_functions().items(): # Get the condition cond = getattr(parser, func)() # If the condition is None or False, skip it if cond is None: continue # Set the name cond.name = name # Set the types conditions.append(cond) # Get the properties of the system chem.properties = [] for name, func in parser.get_result_functions().items(): # Get the property prop = getattr(parser, func)() # If the property is None, skip it if prop is None: continue # Add name and other data prop.name = name prop.method = method prop.data_type='COMPUTATIONAL' if verbose > 0 and isinstance(prop, Value): print(name) if prop.conditions is None: prop.conditions = conditions else: if not isinstance(prop.conditions, list): prop.conditions = [prop.conditions] prop.conditions.extend(conditions) # Add it to the output chem.properties.append(prop) if quality_report: import tarfile tar = tarfile.open("tmp.tar", "w") tar.add(os.path.join(directory, "OUTCAR")) tar.add(os.path.join(directory, "INCAR")) tar.close() import requests import json r = requests.post('https://calval.citrination.com/validate/tarfile', data=open('tmp.tar', 'rb').read()) if r.status_code == requests.codes.ok: report = r.json()[0] report_file = os.path.join(directory, "report.txt") with open(report_file, "w") as f: f.write(report) if report_file[0:2] == "./": report_file = report_file[2:] chem.properties.append( Property( name="quality_report", files=[FileReference(relative_path=report_file)] ) ) else: print("Something failed: {}".format(r.status_code)) print(r.status_code) return chem