| 1 | """ |
|---|
| 2 | The parameters module handles different parameter file formats, taking care of |
|---|
| 3 | converting them to/from Sumatra's internal parameter format, which is the |
|---|
| 4 | NeuroTools ParameterSet class. |
|---|
| 5 | |
|---|
| 6 | Classes |
|---|
| 7 | ------- |
|---|
| 8 | |
|---|
| 9 | NTParameterSet - handles parameter files in the NeuroTools parameter |
|---|
| 10 | set format, based on nested dictionaries |
|---|
| 11 | SimpleParameterSet - handles parameter files in a simple "name = value" |
|---|
| 12 | format, with no nesting or grouping. |
|---|
| 13 | ConfigParserParameterSet - handles parameter files in traditional config file |
|---|
| 14 | format, as parsed by the standard Python ConfigParser |
|---|
| 15 | module. |
|---|
| 16 | """ |
|---|
| 17 | |
|---|
| 18 | from __future__ import with_statement |
|---|
| 19 | import os.path |
|---|
| 20 | import shutil |
|---|
| 21 | import NeuroTools.parameters |
|---|
| 22 | |
|---|
| 23 | class NTParameterSet(NeuroTools.parameters.ParameterSet): |
|---|
| 24 | # just a re-name, to clarify things |
|---|
| 25 | pass |
|---|
| 26 | |
|---|
| 27 | class SimpleParameterSet(object): |
|---|
| 28 | |
|---|
| 29 | def __init__(self, initialiser): |
|---|
| 30 | self.values = {} |
|---|
| 31 | self.types = {} |
|---|
| 32 | self.comments = {} |
|---|
| 33 | if os.path.exists(initialiser): |
|---|
| 34 | with open(initialiser) as f: |
|---|
| 35 | content = f.readlines() |
|---|
| 36 | else: |
|---|
| 37 | content = initialiser.split("\n") |
|---|
| 38 | for line in content: |
|---|
| 39 | if "=" in line: |
|---|
| 40 | name, value = line.split("=")[:2] |
|---|
| 41 | name = name.strip() |
|---|
| 42 | if "#" in value: |
|---|
| 43 | value, comment = value.split("#")[:2] |
|---|
| 44 | self.comments[name] = comment |
|---|
| 45 | self.values[name] = eval(value) |
|---|
| 46 | self.types[name] = type(self.values[name]) |
|---|
| 47 | |
|---|
| 48 | def __str__(self): |
|---|
| 49 | return self.pretty() |
|---|
| 50 | |
|---|
| 51 | def __getitem__(self, name): |
|---|
| 52 | return self.values[name] |
|---|
| 53 | |
|---|
| 54 | def pretty(self, expand_urls=False): |
|---|
| 55 | output = [] |
|---|
| 56 | for name, value in self.values.items(): |
|---|
| 57 | type = self.types[name] |
|---|
| 58 | if issubclass(type, basestring): |
|---|
| 59 | output.append('%s = "%s"' % (name, value)) |
|---|
| 60 | else: |
|---|
| 61 | output.append('%s = %s' % (name, value)) |
|---|
| 62 | if name in self.comments: |
|---|
| 63 | output[-1] += ' #%s' % self.comments[name] |
|---|
| 64 | return "\n".join(output) |
|---|
| 65 | |
|---|
| 66 | def as_dict(self): |
|---|
| 67 | return self.values.copy() |
|---|
| 68 | |
|---|
| 69 | def save(self, filename): |
|---|
| 70 | if os.path.exists(filename): |
|---|
| 71 | shutil.copy(filename, filename + ".orig") |
|---|
| 72 | with open(filename, 'w') as f: |
|---|
| 73 | f.write(self.pretty()) |
|---|
| 74 | |
|---|
| 75 | def update(self, E, **F): |
|---|
| 76 | def _update(name, value): |
|---|
| 77 | if not isinstance(value, (int, float, basestring)): |
|---|
| 78 | raise TypeError("value must be a numeric value or a string") |
|---|
| 79 | self.values[name] = value |
|---|
| 80 | self.types[name] = type(value) |
|---|
| 81 | if hasattr(E, "items"): |
|---|
| 82 | for name,value in E.items(): |
|---|
| 83 | _update(name, value) |
|---|
| 84 | else: |
|---|
| 85 | for name, value in E: |
|---|
| 86 | _update(name, value) |
|---|
| 87 | for name,value in F.items(): |
|---|
| 88 | _update(name, value) |
|---|
| 89 | |
|---|
| 90 | |
|---|
| 91 | |
|---|
| 92 | def build_parameters(filename, cmdline_parameters=[]): |
|---|
| 93 | try: |
|---|
| 94 | parameters = NTParameterSet(filename) |
|---|
| 95 | except SyntaxError: |
|---|
| 96 | parameters = SimpleParameterSet(filename) |
|---|
| 97 | for p in cmdline_parameters: |
|---|
| 98 | name, value = p.split("=") |
|---|
| 99 | for cast in int, float: |
|---|
| 100 | try: |
|---|
| 101 | value = cast(value) |
|---|
| 102 | break |
|---|
| 103 | except ValueError: |
|---|
| 104 | pass |
|---|
| 105 | parameters.update({name: value}) |
|---|
| 106 | return parameters |
|---|