from __future__ import unicode_literals
import os
import copy
try:
import subprocess32 as subprocess
except ImportError:
import subprocess
from os.path import join as opj
from .basejob import SingleJob
from .results import Results
from .settings import Settings
from .utils import PT
from .kftools import KFFile
from .common import string
__all__ = ['DiracJob', 'DiracResults']
[docs]class DiracResults(Results):
"""A class for result of computation done with DIRAC."""
_rename_map = {'DFCOEF':'$JN.dfcoef', 'GRIDOUT':'$JN.grid', 'dirac.xml':'$JN.xml',}
[docs] def collect(self):
"""After collecting the files produced by job execution with parent method :meth:`Results.collect<scm.plams.results.Results.collect>` append the ``pam`` output to the regular output file.
"""
Results.collect(self)
pamfile = self.job._filename('out')
s = subprocess.check_output(['grep', 'output file', pamfile], cwd=self.job.path)
s = string(s)
diracfile = s.split(':')[-1].strip()
if diracfile in self.files:
pampath = opj(self.job.path, pamfile)
diracpath = opj(self.job.path, diracfile)
with open(pampath, 'rU') as f:
pamoutput = f.readlines()
with open(diracpath, 'rU') as f:
diracoutput = f.readlines()
with open(pampath, 'w') as f:
f.writelines(diracoutput)
f.write('\n\n '+'*'*74+'\n')
f.write(' '+'*'*30+' pam output '+'*'*30+'\n')
f.write(' '+'*'*74+'\n\n')
f.writelines(pamoutput)
os.remove(diracpath)
self.refresh()
[docs]class DiracJob(SingleJob):
"""A class representing a single computational job with DIRAC."""
_result_type = DiracResults
_top = ['dirac']
_filenames = {'inp':'$JN.inp', 'run':'$JN.run', 'out':'$JN.out', 'err': '$JN.err'}
def __init__(self, **kwargs):
SingleJob.__init__(self, **kwargs)
self.settings.runscript.pam.noarch = True
self.settings.runscript.pam.get = ['DFCOEF', 'GRIDOUT', 'dirac.xml']
[docs] def _get_ready(self):
"""Before generating runscript and input with parent method :meth:`SingleJob._get_ready<scm.plams.basejob.SingleJob._get_ready>` add proper ``mol`` and ``inp`` entries to ``self.settings.runscript.pam``. If already present there, ``mol`` will not be added.
"""
s = self.settings.runscript.pam
if 'mol' not in s:
s.mol = self.name+'.xyz'
with open(opj(self.path, self.name+'.xyz'), 'w') as f:
f.write(str(len(self.molecule)) + '\n\n')
for atom in self.molecule:
suffix = 'b={block}' if hasattr(atom,'block') else ''
f.write(atom.str(suffix=suffix)+'\n')
s.inp = self._filename('inp')
SingleJob._get_ready(self)
[docs] def get_runscript(self):
"""Generate a runscript. Returned string is a ``pam`` call followed by option flags generated based on ``self.settings.runscript.pam`` contents. See :ref:`dirac-runscript` for details."""
r = self.settings.runscript.pam
ret = 'pam'
for k,v in r.items():
ret += ' --%s'%k
if v is not True:
if isinstance(v, list):
ret += '="%s"' % ' '.join(v)
else:
ret += '='+str(v)
if self.settings.runscript.stdout_redirect:
ret += ' >'+self._filename('out')
ret += '\n\n'
return ret
[docs] def check(self):
"""Check if the calculation was successful by examining the last line of ``pam`` output."""
s = self.results.grep_output('exit :')[0]
status = s.split(':')[-1].strip()
return status == 'normal'