root/src/parameters.py @ 67:66f547a1e169

Revision 67:66f547a1e169, 3.4 KB (checked in by andrew@…, 3 years ago)

Wrote unit tests for parameters module

Line 
1"""
2The parameters module handles different parameter file formats, taking care of
3converting them to/from Sumatra's internal parameter format, which is the
4NeuroTools ParameterSet class.
5
6Classes
7-------
8
9NTParameterSet           - handles parameter files in the NeuroTools parameter
10                           set format, based on nested dictionaries
11SimpleParameterSet       - handles parameter files in a simple "name = value"
12                           format, with no nesting or grouping.
13ConfigParserParameterSet - handles parameter files in traditional config file
14                           format, as parsed by the standard Python ConfigParser
15                           module.
16"""
17
18from __future__ import with_statement
19import os.path
20import shutil
21import NeuroTools.parameters
22
23class NTParameterSet(NeuroTools.parameters.ParameterSet):
24    # just a re-name, to clarify things
25    pass
26
27class 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
92def 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
Note: See TracBrowser for help on using the browser.