1
2
3
4 """Module holding all types of model parameters."""
5 import copy
6 import logging
7
10
12 """Model parameter - keeps track of arguments to a model.
13
14 This object has a dual purpose, first to declare the parameters
15 that are actually needed by a module and secondly to keep track
16 of the values of that parameter. To switch between the two, a
17 call to "withValue" creates a copy of the parameter, this time
18 with a given value.
19
20 Note: this is a lot less screwy than it sounds.
21 """
24
26 """Instantiates a copy of the model parameter with a given value.
27
28 The setValue method will return a ValidationError if validation fails, so
29 this method implicitly performs parameter verification.
30 """
31
32 ret = copy.copy(self)
33 ret.setValue(value)
34 return ret
35
37 return {
38 "name" : self.name,
39 "value": self.value
40 }
41
43 if d["name"] != self.name:
44 raise ValidationError("Trying to instantiate the wrong parameter (called '%s' for '%s')",\
45 self.name, d["name"])
46
47 return self.withValue(d["value"])
48
50 """Converts an instance of this parameter (with value) into matlab code.
51
52 This is used to inject copies of the parameters __directly__ into the Matlab
53 namespace.
54 """
55
56 logging.warning("Unable to convert parameter '%s' to matlab code", self.name)
57 return "%s='UNABLE TO CONVERT TO MATLAB';" % self.value
58
60 """Returns this parameter as HTML."""
61
62 return "No HTML for this parameter type"
63
65 """Returns this parameter as hidden HTML."""
66
67 return "No hidden HTML for this parameter type"
68
70 """Returns HTML helptext for this parameter (directly for inclusion)"""
71
72 if self.helpText:
73 img = "<img src='/static/images/question_mark_icon.gif' />"
74 return "<a href='#' class='modelParameterHelp' data-helpText='%s'>%s</a>" \
75 % (htmlAttributeEscape(self.helpText), img)
76 else:
77 return ""
78
80 """Gives a value of this parameter does not exist (i.e. in a post request).
81
82 This is mostly useful for the screwy way browsers handle "checkbox" parameters,
83 by simply not sending the key when the checkbox is unchecked.
84 """
85
86 raise MissingError("Missing value")
87
88
90 """Parameter type for selecting from a fixed set of string options (like a combo box)."""
91
92 - def __init__(self, name, options=[], description="", default=None, hidden=False, helpText=""):
93 self.name = name
94
95 if len(options) == 0:
96 raise ValidationError("Select parameter '%s' specified with no options" % name)
97
98 self.options = options
99 self.description = description
100 self.units = ""
101
102 if default == None:
103 default = self.options[0]
104
105 self.default = default
106 self.hidden = hidden
107 self.helpText = helpText
108
109 self.setValue(self.default)
110
112 checkVal = str(value)
113 if checkVal not in self.options:
114 raise ValidationError("Attempted to set ComboParameter with invalid value '%s'" % value)
115
116 self.value = value
117
119 if self.value:
120 return "%s='%s'" % (self.name, self.value)
121 else:
122 return "%s='%s'" % (self.name, self.value)
123
124 - def asTextRow(self):
125 return "%s: %s %s" % (self.description, self.value, self.units)
126
129
131 return str(self.value)
132
134 return "<tr><td></td><td><input type='hidden' name='%s' value='%s' /></td></tr>" % (self.name, self.valueString())
135
137 if self.hidden:
138 return self.hiddenHTML()
139
140 optionSelections = []
141 for option in self.options:
142 if option == self.default:
143 optionSelections.append("<option value='%s' selected='selected'>%s</option>" % (option, option))
144 else:
145 optionSelections.append("<option value='%s'>%s</option>" % (option, option))
146
147 return "<tr><td><label for='%s'>%s</label></td><td><select name='%s'/>%s</select> %s</td></tr>" %\
148 (self.name, self.description, self.name, "".join(optionSelections), self.helpHTML())
149
151 """Parameter type for selecting true/false values."""
152
153 - def __init__(self, name, description="", default=False, hidden=False, helpText=""):
154 self.name = name
155 self.description = description
156 self.units = ""
157 self.default = default
158 self.hidden = hidden
159 self.helpText = helpText
160
161 self.setValue(self.default)
162
164 self.value = bool(value)
165
167 if self.value:
168 return "%s=1" % (self.name)
169 else:
170 return "%s=0" % (self.name)
171
172 - def asTextRow(self):
173 return "%s: %s %s" % (self.description, self.value, self.units)
174
177
179 return str(self.value)
180
182 return "<tr><td></td><td><input type='hidden' name='%s' value='%s' /></td></tr>" % (self.name, self.valueString())
183
185 if self.hidden:
186 return self.hiddenHTML()
187
188 if self.value:
189 checkedString = "checked='checked'"
190 else:
191 checkedString = ""
192
193 return "<tr><td><label for='%s'>%s</label></td><td><input type='checkbox' name='%s' value='%s' %s/> %s</td></tr>" %\
194 (self.name, self.description, self.name, self.valueString(), checkedString, self.helpHTML())
195
198
200 """Parameter type for selecting string values."""
201
202 - def __init__(self, name, description="", units="", default=None, hidden=False, helpText=""):
203 self.name = name
204 self.description = description
205 self.units = units
206 self.default = default
207 self.value = None
208 self.hidden = hidden
209 self.helpText = helpText
210 if default != None:
211 self.setValue(self.default)
212
214 self.value = str(value)
215
217 return "%s='%s';" % (self.name, matlabEscape(self.value))
218
219 - def asTextRow(self):
220 return "%s: %s %s" % (self.description, self.value, self.units)
221
224
232
234 return "<tr><td></td><td><input type='hidden' name='%s' value='%s' /></td></tr>" % (self.name, self.valueString())
235
237 if self.hidden:
238 return self.hiddenHTML()
239
240 return "<tr><td><label for='%s'>%s</label></td><td><input type='text' name='%s' value='%s'/> %s</td></tr>" %\
241 (self.name, self.description, self.name, self.valueString(), self.helpHTML())
242
243
245 """Parameter type for selecting a range of floats (e.g. 420.4nm-500nm) at a fixed step."""
246
247 - def __init__(self, name, description="", rangeStart=1.0, rangeEnd=10.0, \
248 step=1.0, units="", default=None, hidden=False, helpText=""):
249 self.name = name
250 self.description = description
251 self.rangeStart = rangeStart
252 self.rangeEnd = rangeEnd
253 self.step = step
254 self.default = None
255 self.units = units
256 self.hidden = hidden
257 self.helpText = helpText
258 self.value = None
259
260 if default != None:
261 self.setValue(self.default)
262
264 if isinstance(value, basestring):
265 start, end = [float(e.strip()) for e in value.split("-")]
266 else:
267 start, end = map(float, value)
268
269 if start > end:
270 raise ValidationError("%s starts after it ends (%s-%s)" %
271 (self.name, start, end))
272
273 if start < self.rangeStart:
274 raise ValidationError("%s start value of '%s' less than minimum '%s'" %
275 (self.name, start, self.rangeStart))
276
277 if end > self.rangeEnd:
278 raise ValidationError("%s end value of '%s' greater than maximum '%s'" %
279 (self.name, end, self.rangeEnd))
280
281
282 self.value = (start, end)
283
285 start, end = self.value
286 return "%sStart=%s;\n%sEnd=%s;\n%s=%s:%s:%s;" % (self.name, start, self.name, end, self.name, start, self.step, end)
287
288 - def asTextRow(self):
289 return "%s: %s-%s %s" % (self.description, self.value[0], self.value[1], self.units)
290
292 return "%s & %s-%s %s" % (latexEscape(self.description), self.value[0], self.value[1], latexEscape(self.units))
293
301
302
304 return """
305 <tr>
306 <td></td>
307 <td>
308 <input type='hidden' name='%s' value='%s' /> %s
309 </td>
310 </tr>
311 """ % (self.name, self.valueString())
312
313
315 if self.hidden:
316 return self.hiddenHTML()
317
318 return """
319 <tr class="rangeParameter">
320 <td>
321 <label for='%s'>%s</label>
322 </td>
323 <td>
324 <input type='text' class="npsgdRange" name='%s' value='%s' data-rangeStart='%s' data-rangeEnd='%s' data-step='%s' /> %s %s
325 <div class="slider"></div>
326 </td>
327 </tr>
328 """ % (self.name, self.description, self.name, self.valueString(), self.rangeStart, self.rangeEnd, self.step, self.units, self.helpHTML())
329
331 """Parameter type for selecting a single float value."""
332
333 - def __init__(self, name, description="", rangeStart=None, rangeEnd=None, \
334 step=None, units="", default=None, hidden=False, helpText=""):
335 self.name = name
336 self.description = description
337 self.rangeStart = rangeStart
338 self.rangeEnd = rangeEnd
339 self.step = step
340 self.default = default
341 self.units = units
342 self.value = None
343 self.hidden = hidden
344 self.helpText = helpText
345 self.htmlClassBase = "npsgdFloat"
346 if default != None:
347 self.setValue(self.default)
348
350 value = float(inVal)
351
352 if self.rangeStart != None and value < self.rangeStart:
353 raise ValidationError("%s value (%s) out of range" %
354 (self.name, value))
355
356 if self.rangeEnd != None and value > self.rangeEnd:
357 raise ValidationError("%s value (%s) out of range" %
358 (self.name, value))
359
360 self.value = value
361
363 return "%s=%s;" % (self.name, self.value)
364
365 - def asTextRow(self):
366 return "%s: %s %s" % (self.description, self.value, self.units)
367
370
378
380 return "<tr><td></td><td><input type='hidden' name='%s' value='%s'/></td></tr>" \
381 % (self.name, self.valueString())
382
384 if self.hidden:
385 return self.hiddenHTML()
386
387 if self.rangeStart != None and self.rangeEnd != None and self.step != None:
388 return """
389 <tr class="floatSliderParameter">
390 <td>
391 <label for='%s'>%s</label>
392 </td>
393 <td>
394 <input type='text' class='%sRange' name='%s' value='%s'
395 data-rangeStart='%s' data-rangeEnd='%s' data-step='%s' /> %s %s
396 <div class="slider"></div>
397 </td>
398 </tr>
399 """ % (self.name, self.description, self.htmlClassBase, self.name, self.valueString(), self.rangeStart, self.rangeEnd, self.step, self.units, self.helpHTML())
400 else:
401 return "<tr><td><label for='%s'>%s</label></td><td><input type='text' class='%s' name='%s' value='%s' data-rangeStart='%s' data-rangeEnd='%s' data-step='%s'/> %s %s</td></tr>" \
402 % (self.name, self.description, self.htmlClassBase, self.name, self.valueString(), self.rangeStart, self.rangeEnd, self.step, self.units, self.helpHTML())
403
405 """Parameter type for selecting a single integer value."""
406
410
412 self.value = int(value)
413
414
416 for find, replace in replaceList:
417 replacee = replacee.replace(find, replace)
418
419 return replacee
420
422 """Escapes parameter values (strings usually) for inclusion in a Matlab script."""
423 return string.replace("'", "\\'")\
424 .replace("%", "%%")\
425 .replace("\\", "\\\\")
426
428 return string.replace("'", "\\'")
429
431 """Escapes parameter values for inclusion in LaTeX."""
432
433 return replaceAll(string,
434 [("\\",r"\textbackslash "),
435 ("<", r"\textless "),
436 (">", r"\textgreater "),
437 ("~", r"\texasciitilde "),
438 ("^", r"\textasciicircum "),
439 ("|", r"\docbooktolatexpipe "),
440 ("&", r"\&"),
441 ("#", r"\#"),
442 ("_", r"\_"),
443 ("$", r"\$"),
444 ("%", r"\%"),
445 ("{", r"\{"),
446 ("}", r"\}")])
447