def read_forces(self, task): """ Function that parses walks a given directory and parses the respective output files. Arguments --------- ''task'' string Task that should be analyzed. Will be filtered via `_normalize_task()`. By specifying the `task` the routine knows, where the respective calculations are stored (hard coded in the parent class!). Returns ------- ''data'' list List of tuples (var, forces, exists, finished, converged) of type (str, np.array, bool, bool, bool). Each calculation corresponds to a tuple. """ data = [] result_dir = 'results' task = self._normalize_task(task) calc_dir = os.path.join(self.base_dir, task) for path, dirs, files in os.walk(calc_dir): if result_dir in dirs: var = os.path.basename(path).split('-')[0] forces = np.ones(( 1, 1, )) * np.nan existing = False finished = False converged = False for f in os.listdir(os.path.join(path, result_dir)): if f.endswith('.castep'): existing = True _, finished, converged = read_energy(os.path.join( path, result_dir, f), get_status=True) if finished: atoms = read_castep( os.path.join(path, result_dir, f)) forces = atoms.calc.get_forces() #print(E, E_corr) else: forces = np.ones_like(atoms.positions) * np.nan data.append((var, forces, existing, finished, converged)) return data
def read_fcc_lattice_constant(self, task): """ Function that parses walks a given directory and parses the respective output files. Arguments --------- ''task'' string Task that should be analyzed. Will be filtered via `_normalize_task()`. By specifying the `task` the routine knows, where the respective calculations are stored (hard coded in the parent class!). Returns ------- ''data'' list List of tuples (var, d, exists, finished, converged) of type (str, float, bool, bool, bool). Each calculation corresponds to a tuple. """ data = [] result_dir = 'results' variable = self._normalize_task(task) calc_dir = os.path.join(self.base_dir, variable) for path, dirs, files in os.walk(calc_dir): if result_dir in dirs: var = os.path.basename(path).split('-')[0] d = np.nan existing = False finished = False converged = False for f in os.listdir(os.path.join(path, result_dir)): if f.endswith('.castep'): existing = True _, finished, converged = read_energy(os.path.join( path, result_dir, f), get_status=True) atoms = read_castep(os.path.join(path, result_dir, f))[0] d = sum(atoms.cell[0]) data.append((var, d, existing, finished, converged)) return data
def _read_data(self, base_dir=None, process_resultfolder=None): """ Function that walks a given directory and parses the respective output files. Parameters ---------- ''base_dir'' string Path to the base directory. Defaults to the <self.base_dir> if None is given. ''process_resultfolder'' Function, optional (default = None) Function to be called with the path to a result directory in case you want some more customized interpretation of your results. This function has to necessarily return: * point_dict : A dictionary containg any information (besides the energy which is parsed anyway outside of this routine) that may be deduced from any file in the result folder. Note that you have to explicitely include the point informationon, this is no longer done automatically. One possible application would either be that you need the float values of the points more accurately than they are represented on the string level, or that you also want to extract information from files other than the *.castep file. Returns ------- Dictionary holding all information on the data. It is organized as follows: for every point: <point_str> : dictionary Dictionary containg the information for the individual points. In this particular case it will be ''*{point_names}'' : The respective point coordinates coordinates. as floats ''energy' : Float, energy for this particular configuration. ''existing'' : Boolean, flag indicating whether the job has been submitted (if a *.castep file exists in the results directory). ''finished'' : Boolean, flag indicating whether a calculation is finished properly (has a regular end) ''converged'' : Boolean, flag indicating whether the calculation is converged with respect to both, SCF and geometry relaxation (if existing). PLUS any additional elements from 'add_dict' if you use 'process_resultfolder()' """ if base_dir is None: base_dir = self.base_dir data = [] # it is ensured that no user settings can change that! result_dir = 'results' for path, dirs, files in os.walk(base_dir): if result_dir in dirs: if process_resultfolder is None: # assume the prefix in get_idir --> hard coded in parent # only split at the first occurence, rest is done with # "_string_to_point()" point_str = os.path.basename(path).split('__', 1)[-1] # convert to array of floats point = self._string_to_point(point_str) # get the point dictionary point_dict = self._point_to_dict(point) else: result_path = os.path.abspath( os.path.join(path, result_dir)) point_dict = process_resultfolder(result_path) E = np.nan existing = False finished = False converged = False result_path = os.path.join(path, result_dir) for f in os.listdir(result_path): f = os.path.join(result_path, f) if f.endswith('.castep'): existing = True E, finished, converged = read_energy(f, get_status=True) # the info dict for the calculation. Make sure that types are # properly assigned calc_infos = { 'energy': float(E), 'existing': bool(existing), 'finished': bool(finished), 'converged': bool(converged) } calc_infos.update(point_dict) data.append(calc_infos) return data