import sys from .common import * from . import structs from . import lib from .i3object import I3Object class OptionError(ValueError): pass class Options(I3Object): def __init__(self, filename=None, **options): self._struct = lib.i3_options_default() if filename: self.read(filename) # important to set model_name first as some # of the others depend on it if 'model_name' in options: self['model_name'] = options['model_name'] for (param, value) in options.items(): self[param] = value super(Options, self).__init__() def items(self): for name,ptype in self._fields_: yield (name, getattr(self,name)) def __setitem__(self, key, value): try_model=True status = ct.c_int() found = self._handle_name_value(str(key), str(value), try_model, ct.byref(status)) if status: raise ValueError("Parameter %s can not have value %s"% (key, value)) if not found: raise ValueError("No im3shape option called %s" % key) def __getitem__(self, key): try: return getattr(self._struct[0], key) except AttributeError: new_key = self._struct[0].model_name+"_"+key try: return getattr(self._struct[0], new_key) except AttributeError: raise AttributeError("No parameter value called %s (or %s)"%(key,new_key)) def __setattr__(self, name, value): # The only thing we might want to set on an if name == "_struct": return super(Options,self).__setattr__(name, value) self[name]=value def __del__(self): try: lib.i3_options_destroy(self._struct) except: pass def _create_reduced_option_list(self): reduced_options = [] for key, ptype in self._struct[0]._fields_: value = getattr(self, key) default_value = getattr(default_options,key) if isinstance(value, ct.Array): value = value[:] default_value = default_value[:] if value != default_value: line = '%s = %s' % (key, str(value)) reduced_options.append(line) return '\n'.join(reduced_options) _handle_name_value = lib.i3_options_handle_name_value_body _printf = lib.i3_options_printf save = lib.i3_options_save read = lib.i3_options_read def write(self, f=None, reduced=False): if reduced: if f is None or f is sys.stdout: print self._create_reduced_option_list() elif isinstance(f, basestring): outfile = open(f, 'w') self.save(self._create_reduced_option_list()) else: raise ValueError("Can only write to file named by string (or None for stdout)") else: if f is None or f is sys.stdout: self._printf() elif isinstance(f, basestring): outfile = open(f, 'w') self.save(outfile) else: raise ValueError("Can only write to file named by string (or None for stdout)") def validate(self): """ Do some basic options checks """ if not getattr(structs, self.model_name+"_parameter_set", None): raise OptionError("Unknown model name. Support for the model chosen in options '%s' was not compiled."%self.model_name) class ImmutableOptions(Options): """ This class of options you cannot change just exists so that no one messes with the default options""" def __setitem__(self, key, value): raise RuntimeError("Cannot modify default options (or other immutable options)") default_options = ImmutableOptions()