Source code for crtomo.cfg

"""Representations of CRMod and CRTomo configurations.

Examples
--------

    >>> import crtomo.cfg as CRcfg
        crmod_cfg = CRcfg.crmod_config()
        print(crmod_cfg)
    ***FILES***       !  mswitch
    ../grid/elem.dat       !  elem
    ../grid/elec.dat       !  elec
    ../rho/rho.dat       !  rho
    ../config/config.dat       !  config
    F       !  write_pot
    ../mod/pot/pot.dat       !  pot_file
    T       !  write_volts
    ../mod/volt.dat       !  volt_file
    F       !  write_sens
    ../mod/sens/sens.dat       !  sens_file
    F       !  another_dataset
    1       !  2D
    F       !  fictitious_sink
    1660       !  sink_node
    F       !  boundary_values
    boundary.dat       !  boundary_file

TODO
----

* we could also add help texts here for each parameter

"""
import io


[docs] class crmod_config(dict): """ Write CRMod configuration files (crmod.cfg). This class is essentially a dict of CRMod configurations with a few extra functions that know how to write a proper crmod.cfg file. Examples -------- >>> import crtomo.cfg as cCFG crmod_cfg = cCfg.crmod_config() crmod_cfg.write_to_file('crmod.cfg') """ def __init__(self, *arg, **kw): super(crmod_config, self).__init__(*arg, **kw) self.set_defaults() self.key_order = ( 'mswitch', 'elem', 'elec', 'rho', 'config', 'write_pots', 'pot_file', 'write_volts', 'volt_file', 'write_sens', 'sens_file', 'another_dataset', '2D', 'fictitious_sink', 'sink_node', 'boundary_values', 'boundary_file' ) # boolean options self.bools = ( 'write_pots', 'write_volts', 'write_sens', )
[docs] def _check_and_convert_bools(self): """Replace boolean variables by the characters 'F'/'T' """ replacements = { True: 'T', False: 'F', } for key in self.bools: if isinstance(self[key], bool): self[key] = replacements[self[key]]
[docs] def copy(self): return self.__copy__()
def __copy__(self): new_copy = crmod_config() # translate the keys for key in self.keys(): new_copy[key] = self[key] return new_copy def __deepcopy__(self, memo): print('deepcopy') raise Exception('not implemented')
[docs] def set_defaults(self): """ Fill the dictionary with all defaults """ self['mswitch'] = '***FILES***' self['elem'] = '../grid/elem.dat' self['elec'] = '../grid/elec.dat' self['rho'] = '../rho/rho.dat' self['config'] = '../config/config.dat' self['write_pots'] = 'F' # ! potentials ? self['pot_file'] = '../mod/pot/pot.dat' self['write_volts'] = 'T' # ! measurements ? self['volt_file'] = '../mod/volt.dat' self['write_sens'] = 'F' # ! sensitivities ? self['sens_file'] = '../mod/sens/sens.dat' self['another_dataset'] = 'F' # ! another dataset ? self['2D'] = '1' # ! 2D (=0) or 2.5D (=1) self['fictitious_sink'] = 'F' # ! fictitious sink ? self['sink_node'] = '1660' # ! fictitious sink node number self['boundary_values'] = 'F' # ! boundary values ? self['boundary_file'] = 'boundary.dat'
[docs] def write_to_file(self, filename): """ Write the configuration to a file. Use the correct order of values. """ self._check_and_convert_bools() if isinstance(filename, io.BytesIO): fid = filename else: fid = open(filename, 'wb') for key in self.key_order: if (key == -1): fid.write(bytes('\n', 'utf-8')) else: fid.write( bytes( '{0}\n'.format(self[key]), 'utf-8', ) ) # do not close BytesIO stream if not isinstance(filename, io.BytesIO): fid.close()
def __repr__(self): self._check_and_convert_bools() representation = '' for key in self.key_order: if key == -1: representation += '\n' else: representation += '{0} ! {1}\n'.format(self[key], key) return representation def __str__(self): return self.__repr__()
[docs] class crtomo_config(dict): """ Write CRTomo configuration files (crtomo.cfg). This class is essentially a dict of CRTomo configurations with a few extra functions that know how to write a proper crtomo.cfg file. """ def __init__(self, *arg, **kw): super(crtomo_config, self).__init__(*arg, **kw) self.set_defaults() # -1 indicates an empty line self.key_order = ( 'mswitch', 'elem', 'elec', 'volt', 'inv_dir', 'diff_inv', -1, 'prior_model', -1, 'iseed_var', 'cells_x', 'cells_z', 'ani_x', 'ani_z', 'max_it', 'dc_inv', 'robust_inv', 'fpi_inv', 'mag_rel', 'mag_abs', 'pha_a1', 'pha_b', 'pha_rel', 'pha_abs', 'hom_bg', 'hom_mag', 'hom_pha', 'another_ds', 'd2_5', 'fic_sink', 'fic_sink_node', 'boundaries', 'boundaries_file', 'mswitch2', 'lambda', ) self.mswitch_values = { 'l1_cov_dw': 1, 'lcov1': 2, 'res_m': 4, 'lcov2': 8, 'ols_gauss': 16, 'err_ellipse': 32, 'force_neg_phase': 128, 'lsytop': 256, 'lvario': 512, 'verbose': 1024, 'verbose_dat': 2048, }
[docs] def set_defaults(self): """Fill the dictionary with all defaults """ self['mswitch'] = 1 self['elem'] = '../grid/elem.dat' self['elec'] = '../grid/elec.dat' self['volt'] = '../mod/volt.dat' self['inv_dir'] = '../inv' self['prior_model'] = '' self['diff_inv'] = 'F ! difference inversion?' self['iseed_var'] = 'iseed variance' self['cells_x'] = '0 ! # cells in x-direction' self['cells_z'] = '0 ! # cells in z-direction' self['ani_x'] = '1.000 ! smoothing parameter in x-direction' self['ani_z'] = '1.000 ! smoothing parameter in z-direction' self['max_it'] = '20 ! max. nr of iterations' self['dc_inv'] = 'F ! DC inversion?' self['robust_inv'] = 'T ! robust inversion?' self['fpi_inv'] = 'F ! final phase improvement?' self['mag_rel'] = '5' self['mag_abs'] = '1e-3' self['pha_a1'] = 0 self['pha_b'] = 0 self['pha_rel'] = 0 self['pha_abs'] = 0 self['hom_bg'] = 'F' self['hom_mag'] = '10.00' self['hom_pha'] = '0.00' self['another_ds'] = 'F' self['d2_5'] = '1' self['fic_sink'] = 'F' self['fic_sink_node'] = '10000' self['boundaries'] = 'F' self['boundaries_file'] = 'boundary.dat' self['mswitch2'] = '1' self['lambda'] = 'lambda'
[docs] def set_mswitch(self, key, active): """The mswitch can enable/disable various functions of CRTomo, mainly concerned with the computation of various resolution parameters. The switch itself is implemented as a binary switch, meaning that each function can be enabled/disabled by setting its corresponding bit. This function simplifies control of these functions by providing a simple boolean interface for these options. Possible keys: {} Parameters ---------- key : str Function to control active : bool Activate (True) or deactivate (False) the feature """.format( ['{}'.format(x) for x in self.mswitch_values.keys()] ) assert key in self.mswitch_values if active: self['mswitch'] = ( self['mswitch'] % self.mswitch_values[key] ) + self.mswitch_values[key] else: self['mswitch'] = (self['mswitch'] % self.mswitch_values[key])
[docs] def write_to_file(self, filename): """ Write the configuration to a file. Use the correct order of values. """ if isinstance(filename, io.BytesIO): fid = filename else: fid = open(filename, 'wb') for key in self.key_order: if (key == -1): fid.write(bytes('\n', 'utf-8')) else: fid.write( bytes( '{0}\n'.format(self[key]), 'utf-8', ) ) if not isinstance(filename, io.BytesIO): fid.close()
[docs] def copy(self): return self.__copy__()
def __copy__(self): new_copy = crtomo_config() # translate the keys for key in self.keys(): new_copy[key] = self[key] return new_copy def __deepcopy__(self, memo): print('deepcopy') raise Exception('not implemented') def __repr__(self): representation = '' for key in self.key_order: if key == -1: representation += '\n' else: representation += '{0} ! {1}\n'.format(self[key], key) return representation def __str__(self): return self.__repr__()
[docs] def help(key): """Return the help text specific to a certain key """ help_dict = { } return_text = help_dict.get(key, 'no help available') return return_text
[docs] def import_from_file(self, filename): """Import a CRTomo configuration from an existing crtomo.cfg file Parameters ---------- filename : str Path to crtomo.cfg file """ if isinstance(filename, io.BytesIO): line_data = filename.readlines() else: with open(filename, 'r') as fid: line_data = fid.readlines() lines_raw = [x.strip() for x in line_data] key_index = 0 for line in lines_raw: # ignore comments if line.startswith('#'): continue else: # check if we have inline comments index_inline_comment = line.find('!') if index_inline_comment != -1: line = line[0:index_inline_comment].strip() key = self.key_order[key_index] if key == -1: pass else: self[key] = line # increment the key_index key_index += 1