Source code for FileTools

"""The WaveBlocks Project

This file contains various functions for finding and retrieving
the files that contain parameter settings and simulation results.
Note: The terms 'path' and 'ID' are used as synonyms here. Each simulation
ID is just the basename of the path or the configuration file.

@author: R. Bourquin
@copyright: Copyright (C) 2010, 2011 R. Bourquin
@license: Modified BSD License
"""

import os

import GlobalDefaults as GD


[docs]def get_result_dirs(path): r""" Lists all simulations (IDs) that can be found under the given path. :param path: The filesystem path under which we search for simulations. :return: A list of simulation IDs. """ dirs = [ os.path.join(path, dir) for dir in os.listdir(path) ] return dirs
[docs]def get_parameters_file(path): r""" Search for a configuration file containing the simulation parameters under a given path. :param path: The path under which we search for a configuration file. :return: The path (filename) of the configuration file. .. note:: In case there are more than one .py file under the given path we just return the first one found! """ parameters_file = None for file in os.listdir(path): if file[-3:] == ".py": parameters_file = file break if parameters_file is None: raise IOError("No configuration .py file found!") parameters_file = os.path.join(path, parameters_file) return parameters_file
[docs]def get_results_file(path): r""" Search for a file containing the simulation results under a given path. :param path: The path under which we search for a output file. :return: The path (filename) of the output file. .. note:: In case there are more than one .hdf5 file under the given path we just return the first one found! """ results_file = None for file in os.listdir(path): # Should we allow extensions .hdf and .h5 too? if file[-5:] == ".hdf5": results_file = file break if results_file is None: raise IOError("No results .hdf5 file found!") results_file = os.path.join(path, results_file) return results_file
[docs]def get_number_simulations(path): r""" Get the number of simulations at hand below the given path. :param path: The path under which we search for a output file. :return: The number of simulations result directories. """ ids = get_result_dirs(path) return len(ids)
[docs]def name_contains(name, pattern): r""" Checks if a simulation ID contains a given pattern. :param name: The full simulation ID. :param pattern: The pattern in question. :return: A boolean answer. """ return pattern in name
[docs]def gather_all(stringlist, pattern): r""" Collects all simulation IDs which contain a specific pattern from a given list. :param stringlist: A list with the simulation IDs :param pattern: The pattern :return: A list of simulation IDs that contain the given pattern. """ gathered = [ s for s in stringlist if name_contains(s, pattern) ] return gathered
[docs]def compare_by(namea, nameb, pattern, ldel=GD.kvp_ldel, mdel=GD.kvp_mdel, rdel=GD.kvp_rdel, as_string=True): r""" Compare two simulation IDs with respect to a (numerical) value in the ID. :param namea: The first name in the comparison :param nameb: The second name in the comparison :param pattern: The pattern whose (numerical) value is used for sorting :param ldel: Left delimiter of the pattern :param mdel: Middle delimiter of the pattern :param rdel: Right delimiter of the pattern :param as_string: Determines if the values for ``pattern`` get converted to floats :return: A boolean answer if the IDs are the same w.r.t the pattern. """ part1 = namea.partition(ldel + pattern + mdel) part2 = nameb.partition(ldel + pattern + mdel) part1 = part1[0:2] + part1[2].partition(rdel) part2 = part2[0:2] + part2[2].partition(rdel) # Convert values to float for comparisons if not as_string: part1 = part1[0:2] + (float(part1[2]),) + part1[3:] part2 = part2[0:2] + (float(part2[2]),) + part2[3:] return part1[2] == part2[2]
[docs]def group_by(stringlist, pattern, ldel=GD.kvp_ldel, mdel=GD.kvp_mdel, rdel=GD.kvp_rdel, as_string=True): r""" Groups simulation IDs with respect to a pattern. :param stringlist: A list with the simulation IDs :param pattern: The pattern used for grouping :param ldel: Left delimiter of the pattern :param mdel: Middle delimiter of the pattern :param rdel: Right delimiter of the pattern :param as_string: Determines if the values for ``pattern`` get converted to floats. Not used here. :return: A list of groups of simulation IDs. """ tmp = [ s.partition(ldel + pattern + mdel) for s in stringlist ] tmp = [ s[0:2] + s[2].partition(rdel) for s in tmp ] distinct_vals = set([ s[2] for s in tmp ]) groups = [ [] for i in xrange(len(distinct_vals)) ] for item in tmp: for index, val in enumerate(distinct_vals): # Yes, we compare the strings here and not the floats # to avoid representation errors when converting to floats. if item[2] == val: # Concatenate the fragments again groups[index].append( reduce(lambda x,y: x+y, item) ) break return groups
[docs]def intersect_by(lista, listb, pattern, ldel=GD.kvp_ldel, mdel=GD.kvp_mdel, rdel=GD.kvp_rdel, as_string=True): r""" Find the intersection of two lists containing simulation IDs. :param lista: A first list with the simulation IDs :param listb: A second list with the simulation IDs :param pattern: The pattern whose numerical value is used for sorting :param ldel: Left delimiter of the pattern :param mdel: Middle delimiter of the pattern :param rdel: Right delimiter of the pattern :param as_string: Determines if the values for ``pattern`` get converted to floats :return: A sorted list of simulation IDs. """ result = [] for namea in lista: for nameb in listb: if compare_by(namea, nameb, pattern, ldel=ldel, mdel=mdel, rdel=rdel, as_string=as_string): result.append(namea) result.append(nameb) # Remove possible duplicates result = list(set(result)) return result
[docs]def sort_by(stringlist, pattern, ldel=GD.kvp_ldel, mdel=GD.kvp_mdel, rdel=GD.kvp_rdel, as_string=False): r""" Sorts simulation IDs with respect to a (numerical) value in the ID. :param stringlist: A list with the simulation IDs :param pattern: The pattern whose (numerical) value is used for sorting :param ldel: Left delimiter of the pattern :param mdel: Middle delimiter of the pattern :param rdel: Right delimiter of the pattern :param as_string: Determines if the values for ``pattern`` get converted to floats :return: A sorted list of simulation IDs. """ tmp = [ s.partition(ldel + pattern + mdel) for s in stringlist ] tmp = [ s[0:2] + s[2].partition(rdel) for s in tmp ] if not as_string: # Convert to float and append numeric values to the splitted IDs tmp = [ s + (float(s[2]),) for s in tmp ] else: # Use string in comparison, allows sorting tmp = [ s + (s[2],) for s in tmp ] # Define a costum order relation def compare(x,y): if x[-1] > y[-1]: return 1 elif y[-1] > x[-1]: return -1 else: return 0 # Sort w.r.t. the numerical value tmp.sort(cmp=compare) # Remove numeric value and concatenate the fragments again f = lambda x,y: x+y sorted_list = [ reduce(f, s[:-1]) for s in tmp ] return sorted_list
[docs]def get_max_by(stringlist, pattern, ldel=GD.kvp_ldel, mdel=GD.kvp_mdel, rdel=GD.kvp_rdel, as_string=False): r""" Get the maximum of a list with simulation IDs with respect to a (numerical) value in the ID. :param stringlist: A list with the simulation IDs :param pattern: The pattern whose (numerical) value is used for sorting :param ldel: Left delimiter of the pattern :param mdel: Middle delimiter of the pattern :param rdel: Right delimiter of the pattern :param as_string: Determines if the values for ``pattern`` get converted to floats :return: A sorted list of simulation IDs. .. note:: This is just a simple convenience function so that the user needs not to remember if the sort order is ascending or descending which plays no role for iteration. """ sortedlist = sort_by(stringlist, pattern, ldel=ldel, mdel=mdel, rdel=rdel, as_string=as_string) return sortedlist[-1]
[docs]def get_min_by(stringlist, pattern, ldel=GD.kvp_ldel, mdel=GD.kvp_mdel, rdel=GD.kvp_rdel, as_string=False): r""" Get the minimum of a list with simulation IDs with respect to a (numerical) value in the ID. :param stringlist: A list with the simulation IDs :param pattern: The pattern whose (numerical) value is used for sorting :param ldel: Left delimiter of the pattern :param mdel: Middle delimiter of the pattern :param rdel: Right delimiter of the pattern :param as_string: Determines if the values for ``pattern`` get converted to floats :return: A sorted list of simulation IDs. .. note:: This is just a simple convenience function so that the user needs not to remember if the sort order is ascending or descending which plays no role for iteration. """ sortedlist = sort_by(stringlist, pattern, ldel=ldel, mdel=mdel, rdel=rdel, as_string=as_string) return sortedlist[0]