def test_from_str_int(): pairs = [('0', 0), ('1', 1), ('2', 2), ('-1', -1), ('-2', -2)] for int_str, int_exp in pairs: int_act = _misc.from_str(int_str) a_str = 'Expected ' + str(int_exp) + ' and got ' + str(int_act) assert int_exp == int_act, a_str
def test_from_str_float(): pairs = [('1.234', 1.234), ('0.214', 0.214), ('-0.4', -0.4), ('1.2e5', 1.2e5)] for flt_str, flt_exp in pairs: flt_act = _misc.from_str(flt_str) a_str = 'Expected ' + str(flt_exp) + ' and got ' + str(flt_act) assert flt_exp == flt_act, a_str
def test_from_str_list(): pairs = [('[0]', [0]), ('[1, 0, a]', [1, 0, 'a']), ('-2.3, true', [-2.3, True])] for list_str, list_exp in pairs: list_act = _misc.from_str(list_str) assert len(list_exp) == len(list_act) for act_val, exp_val in zip(list_act, list_exp): assert act_val == exp_val
def test_from_str_bool(): pairs = [('True', True), ('False', False), ('true', True), ('false', False)] for bool_str, bool_exp in pairs: bool_act = _misc.from_str(bool_str) a_str = 'Expected ' + str(bool_exp) + ' and got ' + str(bool_act) a_str += ' for string ' + repr(bool_str) assert bool_exp == bool_act, a_str
def test_from_str_list_of_lists(): lol_str = '[[1, 0, 0, True, False], [2, 4, a, -2.3]]' lol_exp = [[1, 0, 0, True, False], [2, 4, 'a', -2.3]] lol_act = _misc.from_str(lol_str) assert len(lol_exp) == len(lol_act) for list_exp, list_act in zip(lol_exp, lol_act): assert len(list_exp) == len(list_act) for val_exp, val_act in zip(list_exp, list_act): assert val_exp == val_act
def from_str(cls, seed_str): """Create seed from a string. This method creates a seed particle from a string representation. This is used when reading in seeds from a file. Args: seed_str (str): String representation of the seed. Returns: Seed: An instance of a Seed derived class. """ # Convert to dictionary str_dict = {} for line in seed_str.strip().split('\n'): try: k_str, v_str = line.split(':') except ValueError: continue else: k = k_str.strip().lower().replace(' ', '_') v = _misc.from_str(v_str) str_dict[k] = v # Extract seed type, phase, and breakdown seed_type = str_dict['geometry'] del str_dict['geometry'] if 'phase' in str_dict: phase = str_dict['phase'] del str_dict['phase'] else: phase = 0 if 'breakdown' in str_dict: breakdown = str_dict['breakdown'] if not isinstance(breakdown[0], tuple): breakdown = (breakdown, ) del str_dict['breakdown'] else: breakdown = None if 'position' in str_dict: position = str_dict['position'] del str_dict['position'] else: position = None return cls.factory(seed_type, phase, breakdown, position, **str_dict)
def _dist_convert(dist_dict): """Convert distribution dictionary to distribution""" dist_type = dist_dict['dist_type'].strip().lower() params = {k: _misc.from_str(v) for k, v in dist_dict.items()} del params['dist_type'] if dist_type == 'cdf': cdf_filename = params['filename'] with open(cdf_filename, 'r') as file: cdf = [[float(s) for s in line.split(',')] for line in file] bin_bnds = [x for x, _ in cdf] bin_cnts = [cdf[i + 1][1] - cdf[i][1] for i in range(len(cdf) - 1)] return scipy.stats.rv_histogram(tuple([bin_cnts, bin_bnds])) elif dist_type == 'histogram': hist_filename = params['filename'] with open(hist_filename, 'r') as file: hist = [[float(s) for s in line.split(',')] for line in file] return scipy.stats.rv_histogram(tuple(hist)) else: return scipy.stats.__dict__[dist_type](**params)
def dict_convert(dictionary, filepath='.'): """Convert dictionary from xmltodict_ The xmltodict_ ``parse`` method creates dictionaries with values that are all strings, rather than strings, floats, ints, etc. This function recursively searches the dictionary for string values and attempts to convert the dictionary values. If a dictionary contains the key ``dist_type``, it is assumed that the corresponding name is a :mod:`scipy.stats` statistical distribution and the remaining keys are inputs for that distribution, with two exceptions. First, if the value of ``dist_type`` is ``cdf``, then the remaining key should be ``filename`` and its value should be the path to a CSV file, where each row contains the (x, CDF) points along the CDF curve. Second, if the value of ``dist_type`` is ``histogram``, then the remaining key should also be ``filename`` and its value should be the path to a CSV file. For the histogram, the first row of this CDF should be the *n* bin heights and the second row should be the *n+1* bin locations. Additionally, if a key in the dictionary contains ``filename`` or ``directory`` and the value associated with that key is a relative path, then the filepath is converted from a relative to an absolute path using the ``filepath`` input as the reference point. This behavior can be switched off by setting ``filepath=False``. Args: dictionary (list, dict, or collections.OrderedDict): Dictionary or dictionaries to be converted. filepath (str): *(optional)* Reference path to resolve relative paths. Returns: list or collections.OrderedDict: A copy of the input where the string values have been converted. If only one dict is passed into the function, then an instance of :class:`collections.OrderedDict` is returned. .. _xmltodict: https://github.com/martinblech/xmltodict """ # Convert lists if isinstance(dictionary, list): return [dict_convert(d) for d in dictionary] # Convert strings if isinstance(dictionary, str): return _misc.from_str(dictionary) # Convert Nones if dictionary is None: return {} # Convert filepaths for key in dictionary: val = dictionary[key] if any([s in key.lower() for s in ('filename', 'directory')]): val = os.path.expanduser(val) if not os.path.isabs(val) and filepath: new_val = os.path.abspath(os.path.join(filepath, val)) else: new_val = val dictionary[key] = new_val # Convert SciPy.stats distributions if 'dist_type' in dictionary: return _dist_convert(dictionary) # Convert Dictionaries new_dict = collections.OrderedDict() for key in dictionary: val = dictionary[key] new_val = dict_convert(val, filepath) new_dict[key] = new_val return new_dict
def from_file(cls, filename): """Read TriMesh from file. This function reads in a triangular mesh from a file and creates an instance from that file. Currently the only supported file type is the output from :meth:`.write` with the ``format='str'`` option. Args: filename (str): Name of file to read from. Returns: TriMesh: An instance of the class. """ with open(filename, 'r') as file: stage = 0 pts = [] elems = [] elem_atts = [] facets = [] facet_atts = [] n_eas = 0 n_facets = 0 n_fas = 0 for line in file.readlines(): if 'Mesh Points'.lower() in line.lower(): n_pts = int(line.split(':')[1]) stage = 'points' elif 'Mesh Elements'.lower() in line.lower(): n_elems = int(line.split(':')[1]) stage = 'elements' elif 'Element Attributes'.lower() in line.lower(): n_eas = int(line.split(':')[1]) stage = 'element attributes' elif 'Facets'.lower() in line.lower(): n_facets = int(line.split(':')[1]) stage = 'facets' elif 'Facet Attributes'.lower() in line.lower(): n_fas = int(line.split(':')[1]) stage = 'facet attributes' else: if stage == 'points': pts.append([float(x) for x in line.split(',')]) elif stage == 'elements': elems.append([int(kp) for kp in line.split(',')]) elif stage == 'element attributes': elem_atts.append(_misc.from_str(line)) elif stage == 'facets': facets.append([int(kp) for kp in line.split(',')]) elif stage == 'facet attributes': facet_atts.append(_misc.from_str(line)) else: pass # check the inputs assert len(pts) == n_pts assert len(elems) == n_elems assert len(elem_atts) == n_eas assert len(facets) == n_facets assert len(facet_atts) == n_fas return cls(pts, elems, elem_atts, facets, facet_atts)
def from_file(cls, filename): """Read PolyMesh from file. This function reads in a polygon mesh from a file and creates an instance from that file. Currently the only supported file type is the output from :meth:`.write` with the ``format='txt'`` option. Args: filename (str): Name of file to read from. Returns: PolyMesh: The instance of the class written to the file. """ with open(filename, 'r') as file: stage = 0 pts = [] facets = [] f_neighbors = [] regions = [] seed_numbers = [] phase_numbers = [] volumes = [] for line in file.readlines(): if 'Mesh Points'.lower() in line.lower(): n_pts = int(line.split(':')[1]) stage = 'points' elif 'Mesh Facets'.lower() in line.lower(): n_fts = int(line.split(':')[1]) stage = 'facets' elif 'Facet Neighbors'.lower() in line.lower(): n_nns = int(line.split(':')[1]) stage = 'facet neighbors' elif 'Mesh Regions'.lower() in line.lower(): n_rns = int(line.split(':')[1]) stage = 'regions' elif 'Seed Numbers'.lower() in line.lower(): n_sns = int(line.split(':')[1]) stage = 'seed numbers' elif 'Phase Numbers'.lower() in line.lower(): n_pns = int(line.split(':')[1]) stage = 'phase numbers' elif 'Volumes'.lower() in line.lower(): n_vols = int(line.split(':')[1]) stage = 'volumes' else: if stage == 'points': pts.append([float(x) for x in line.split(',')]) elif stage == 'facets': facets.append([int(kp) for kp in line.split(',')]) elif stage == 'facet neighbors': f_neighbors.append([int(n) for n in line.split(',')]) elif stage == 'regions': regions.append([int(f) for f in line.split(',')]) elif stage == 'seed numbers': seed_numbers.append(_misc.from_str(line)) elif stage == 'phase numbers': phase_numbers.append(_misc.from_str(line)) elif stage == 'volumes': volumes.append(_misc.from_str(line)) else: pass # check the inputs assert len(pts) == n_pts assert len(facets) == n_fts assert len(regions) == n_rns assert len(seed_numbers) == n_sns assert len(phase_numbers) == n_pns assert len(volumes) == n_vols if len(f_neighbors) == 0: f_neighbors = None else: assert len(f_neighbors) == n_nns return cls(pts, facets, regions, seed_numbers, phase_numbers, volumes=volumes, facet_neighbors=f_neighbors)