11import numpy
22
3- from ConfigParser import ConfigParser
3+ try :
4+ from ConfigParser import ConfigParser
5+ except :
6+ from configparser import ConfigParser
7+ from collections import defaultdict
48
59try :
610 import f90nml
711 HAS_F90NML = True
812except :
913 HAS_F90NML = False
10- from collections import defaultdict
11- from amuse .units .quantities import new_quantity , to_quantity , is_quantity
1214
15+ from amuse .units .quantities import new_quantity , to_quantity , is_quantity
1316
1417# CodeWithNamelistParameters
1518#
1619# namelist_parameters=(
1720# dict(name="name", group_name="name", short="codename", dtype="int32", default=64, description="description", ptype="nml" [, set_name="name"]), ...
1821# )
1922
20- class CodeWithNamelistParameters (object ):
21- def __init__ (self , namelist_parameters ):
22- self ._namelist_parameters = dict ([((x ["short" ].lower (),x ["group_name" ]),x ) for x in namelist_parameters ])
23-
24- def define_parameters (self ,handler ):
25- for p in self ._namelist_parameters .values ():
26- if p ["ptype" ] in ["nml" , "nml+normal" ]:
27- parameter_set_name = p .get ("set_name" , "parameters_" + p ["group_name" ])
28- handler .add_interface_parameter ( p ["name" ], p ["description" ], p ["default" ], "before_set_interface_parameter" , parameter_set = parameter_set_name )
23+ class _CodeWithFileParameters (object ):
24+ _ptypes = None
25+ def write_file (self , inputfile , ** kwargs ):
26+ raise Exception ("not implemented" )
27+ def read_file (self , inputfile , rawvals , ** kwargs ):
28+ raise Exception ("not implemented" )
2929
30- def read_namelist_parameters (self , inputfile ):
30+ def define_parameters (self , handler ):
31+ _tmp = dict ()
32+ for p in self ._parameters .values ():
33+ if p ["ptype" ] not in self ._ptypes :
34+ continue
35+ parameter_set_name = p .get ("set_name" , self ._prefix + p ["group_name" ] )
36+ if parameter_set_name not in _tmp :
37+ _tmp [parameter_set_name ]= [ x .name for x in handler .definitions [parameter_set_name ] ]
38+ if not p ["name" ] in _tmp [parameter_set_name ]:
39+ handler .add_interface_parameter ( p ["name" ], p ["description" ], p ["default" ],
40+ "before_set_interface_parameter" , parameter_set = parameter_set_name )
3141
32- self ._nml_file = inputfile
33- self ._nml_params = f90nml .read (inputfile )
42+ self .set_parameters ()
3443
35- for group , d in self ._nml_params .iteritems ():
36- for short , val in d .iteritems ():
37- key = (short .lower (),group .upper ())
38- if key in self ._namelist_parameters :
39- group_name = self ._namelist_parameters [key ]["group_name" ]
40- name = self ._namelist_parameters [key ]["name" ]
41- parameter_set_name = self ._namelist_parameters [key ].get ("set_name" , "parameters_" + group_name )
42- parameter_set = getattr (self , parameter_set_name )
43- if is_quantity (self ._namelist_parameters [key ]["default" ]):
44- setattr (parameter_set , name , new_quantity (val , to_quantity (self ._namelist_parameters [key ]["default" ]).unit ) )
44+ def set_parameters (self ):
45+ for p in self ._parameters .values ():
46+ if p ["ptype" ] not in self ._ptypes :
47+ continue
48+ parameter_set_name = p .get ("set_name" , None ) or self ._prefix + p ["group_name" ]
49+ parameter_set = getattr (self , parameter_set_name )
50+ name = p ["name" ]
51+ value = p .get ("value" , p ["default" ])
52+ setattr (parameter_set , name , value )
53+
54+ def interpret_value (self ,value , dtype = None ):
55+ raise Exception ("not implemented" )
56+
57+ def read_parameters (self , inputfile , add_missing_parameters = False ):
58+ self ._file = inputfile
59+
60+ _nml_params = f90nml .read (inputfile )
61+
62+ rawvals , comments = self ._read_file (inputfile )
63+
64+ for key , rawval in rawvals .items ():
65+ if key in self ._parameters :
66+ group_name = self ._parameters [key ]["group_name" ]
67+ name = self ._parameters [key ]["name" ]
68+ val = self .interpret_value ( rawval , dtype = dtype )
69+ if is_quantity (self ._parameters [key ]["default" ]):
70+ self ._parameters [key ]["value" ]= new_quantity (val , to_quantity (self ._namelist_parameters [key ]["default" ]).unit )
4571 else :
46- setattr ( parameter_set , name , val )
72+ self . _parameters [ key ][ "value" ] = val
4773 else :
48- print "'%s' of group '%s' not in the namelist_parameters" % (short , group )
49-
50- def write_namelist_parameters (self , outputfile , do_patch = False , nml_file = None ):
51- patch = defaultdict ( dict )
52- for p in self ._namelist_parameters .values ():
74+ if not add_missing_parameters :
75+ print ("'{0}' of group '{1}' not in the namelist_parameters" .format (* key ))
76+ else :
77+ value = rawval
78+ description = comments .get (key , "unknown parameter read from {0}" .format (inputfile ))
79+ self ._parameters [key ]= dict (
80+ group_name = key [1 ],
81+ name = key [0 ],
82+ short_name = key [0 ],
83+ default = value ,
84+ value = value ,
85+ short = key [0 ],
86+ ptype = self ._ptypes [0 ],
87+ dtype = str (type (value )),
88+ description = description
89+ )
90+
91+ def write_parameters (self , outputfile , ** options ):
92+
93+ rawvals = dict ()
94+
95+ for key , p in self ._parameters .items ():
5396 name = p ["name" ]
5497 group_name = p ["group_name" ]
55- group = patch [group_name ]
5698 short = p ["short" ]
57- parameter_set_name = p .get ("set_name" , "parameters_" + group_name )
58- parameter_set = getattr (self , parameter_set_name )
59- if getattr (parameter_set , name ) is None : # omit if value is None
60- continue
99+ parameter_set_name = p .get ("set_name" , group_name )
100+ parameter_set = getattr (self , self ._prefix + parameter_set_name )
61101 if is_quantity (p ["default" ]):
62102 value = to_quantity (getattr (parameter_set , name )).value_in (p ["default" ].unit )
63103 else :
64- value = getattr (parameter_set , name )
65- if isinstance (value ,numpy .ndarray ):
66- value = list (value ) # necessary until f90nml supports numpy arrays
67- group [short ]= value
104+ value = getattr (parameter_set , name )
105+
106+ rawvals [key ]= self .output_format_value (value )
107+
108+ self .write_file (outputfile , rawvals , ** options )
109+
110+ class CodeWithNamelistParameters (_CodeWithFileParameters ):
111+ """
112+ Mix-in class to 1) namelist file support to code interfaces and 2) automatically generate
113+ parameter sets from descriptions or namelist files.
114+
115+ This class takes a list of parameter descriptions (optional) and has functions to
116+ read and write namelist files. Every namelist section corresponds to a different
117+ parameter set.
118+ """
119+ _ptypes = ["nml" , "nml+normal" ]
120+
121+ def __init__ (self , _parameters , prefix = "parameters_" ):
122+ if not HAS_F90NML :
123+ raise Exception ("f90nml package not available" )
124+ self ._parameters = dict ([((x ["short" ].lower (),x ["group_name" ]),x ) for x in _parameters ])
125+ self ._prefix = prefix
126+ self ._file = None
127+
128+ def _read_file (self , inputfile ):
129+ _nml_params = f90nml .read (inputfile )
130+ rawvals = dict ()
131+
132+ for group , d in _nml_params .items ():
133+ for short , val in d .items ():
134+ key = (short .lower (),group .upper ())
135+ rawvals [key ]= val
136+
137+ return rawvals , dict ()
138+
139+ def write_file (self , outputfile , rawvals , do_patch = False , nml_file = None ):
140+ patch = defaultdict ( dict )
141+
142+ for key ,rawval in rawvals .items ():
143+ if rawval is None : # omit if value is None
144+ continue
145+ if isinstance (rawval ,numpy .ndarray ):
146+ rawval = list (rawval ) # necessary until f90nml supports numpy arrays
147+ patch [key [1 ]][key [0 ]]= rawval
68148
69149 if do_patch :
70150 f90nml .patch (nml_file or self ._nml_file ,patch ,outputfile )
71151 else :
72152 f90nml .write (patch , outputfile , force = True )
73153
74- class CodeWithIniFileParameters (object ):
75- def __init__ (self , inifile_parameters = dict ()):
76- self ._inifile_parameters = dict ([((x ["name" ],x ["group_name" ]),x ) for x in inifile_parameters ])
77- self ._optionxform = str
78-
79- def define_parameters (self , handler ):
80- _tmp = dict ()
81- for p in self ._inifile_parameters .values ():
82- if p ["ptype" ] in ["ini" , "ini+normal" ]:
83- parameter_set_name = p .get ("set_name" , p ["group_name" ])
84- if parameter_set_name not in _tmp :
85- _tmp [parameter_set_name ]= [ x .name for x in handler .definitions [parameter_set_name ] ]
86- if not p ["name" ] in _tmp [parameter_set_name ]:
87- handler .add_interface_parameter ( p ["name" ], p ["description" ], p ["default" ],
88- "before_set_interface_parameter" , parameter_set = parameter_set_name )
89-
90- self .set_parameters ()
154+ def write_namelist_parameters (self , outputfile , do_patch = False , nml_file = None ):
155+ return self .write_parameters (outputfile , do_patch = do_patch , nml_file = nml_file )
91156
92- def set_parameters (self ):
93- for p in self ._inifile_parameters .values ():
94- parameter_set_name = p .get ("set_name" , None ) or p ["group_name" ]
95- parameter_set = getattr (self , parameter_set_name )
96- name = p ["name" ]
97- value = p .get ("value" , None ) or p ["default" ]
98- setattr (parameter_set , name , value )
99-
100- def read_inifile_parameters (self , configfile ):
101- self ._configfile = configfile
157+ def read_namelist_parameters (self , inputfile , add_missing_parameters = False ):
158+ return self .read_parameters (inputfile ,add_missing_parameters )
159+
160+ def output_format_value (self ,value ):
161+ return value
162+
163+
164+ class CodeWithIniFileParameters (_CodeWithFileParameters ):
165+ """
166+ Mix-in class to 1) INI-like file support to code interfaces and 2) automatically generate
167+ parameter sets from descriptions or Ini files.
168+
169+ This class takes a list of parameter descriptions (optional) and has functions to
170+ read and write INI files. Every section corresponds to a different parameter set.
171+ """
172+ _ptypes = ["ini" , "ini+normal" ]
173+ def __init__ (self , _parameters = dict (), prefix = "ini_" ):
174+ self ._parameters = dict ([((x ["name" ],x ["group_name" ]),x ) for x in _parameters ])
175+ self ._optionxform = str
176+ self ._prefix = prefix
177+ self ._file = None
178+
179+ def read_file (self , inputfile ):
102180 parser = ConfigParser ()
103181 parser .optionxform = self ._optionxform
104- parser .read (configfile )
182+ parser .read (inputfile )
105183 for section in parser .sections ():
106184 group = section
107185 for option in parser .options (section ):
108186 key = (option ,group )
109- if key in self ._inifile_parameters :
110- ptype = self ._inifile_parameters [key ]["ptype" ]
111- dtype = self ._inifile_parameters [key ]["dtype" ]
112- value = self .interpret_value (parser .get (group , option ), dtype = dtype )
113- if is_quantity (self ._inifile_parameters [key ]["default" ]):
114- value = new_quantity (val , to_quantity (self ._inifile_parameters [key ]["default" ]).unit )
115- self ._inifile_parameters [key ]["value" ]= value
116- else :
117- value = self .interpret_value (parser .get (group , option ))
118- self ._inifile_parameters [key ]= dict (
119- group_name = group ,
120- name = option ,
121- set_name = group ,
122- default = value ,
123- value = value ,
124- short = option ,
125- ptype = "ini" ,
126- dtype = "unknown" ,
127- description = "unknown parameter read from %s" % configfile
128- )
187+
188+ rawvals [key ]= parser .get (group , option )
189+
190+ return rawvals , dict ()
129191
130192 def _convert (self , value , dtype ):
131193 if dtype is "bool" :
@@ -142,32 +204,29 @@ def interpret_value(self,value, dtype=None):
142204 return [self ._convert (x , dtype ) for x in value .split ("," )]
143205 return self ._convert (value , dtype )
144206
145- def output_format_value (self ,value ):
146- if isinstance (value , list ):
147- return ',' .join (value )
148- else :
149- return value
150-
151-
152- def write_inifile_parameters (self , outputfile ):
207+ def write_file (self , outputfile , rawvals ):
153208 parser = ConfigParser ()
154209 parser .optionxform = self ._optionxform
155210
156- for p in self ._inifile_parameters .values ():
157- name = p ["name" ]
158- group_name = p ["group_name" ]
159- short = p ["short" ]
160- parameter_set_name = p .get ("set_name" , group_name )
161- parameter_set = getattr (self , parameter_set_name )
162- if is_quantity (p ["default" ]):
163- value = to_quantity (getattr (parameter_set , name )).value_in (p ["default" ].unit )
164- else :
165- value = self .output_format_value (getattr (parameter_set , name ))
166- if not parser .has_section (group_name ):
167- parser .add_section (group_name )
168- parser .set (group_name ,short ,value )
169-
211+ for key , rawval in rawvals .items ():
212+ section = key [1 ]
213+
214+ if not parser .has_section (section ):
215+ parser .add_section (section )
216+
217+ if isinstance (rawval , list ):
218+ rawval = ',' .join (rawval )
219+
220+ parser .set (section ,short ,self .output_format_value (rawval ))
221+
170222 f = open (outputfile , "w" )
171223 parser .write (f )
172224 f .close ()
173225
226+ def output_format_value (self ,value ):
227+ if isinstance (value , list ):
228+ return ',' .join (value )
229+ else :
230+ return value
231+
232+
0 commit comments