ReFRACtor
param.py
Go to the documentation of this file.
1 import re
2 
3 import numpy as np
4 
5 from refractor import framework as rf
6 
7 class ParamError(BaseException):
8  pass
9 
10 class ConfigParam(object):
11  "Base class for configuration parameters"
12 
13  def __init__(self, required=True, default=None):
14  self.accessor_func = None
15  self.default = default
16 
17  if default is not None:
18  self.required = False
19  else:
20  self.required = required
21 
22  def evaluate(self, in_value, **kwargs):
23 
24  # If value to be evaluated is callable, call and pass
25  # along the creator requesting the parameter
26  if callable(in_value):
27  out_value = in_value(**kwargs)
28  else:
29  out_value = in_value
30 
31  self.check_type(out_value)
32 
33  return out_value
34 
35  def check_type(self, value):
36  raise NotImplementedError("check_type must be implemented in inheriting class")
37 
39  "Bypasses type checking for the parameter"
40 
41  def check_type(self, value):
42  pass
43 
44 class Choice(ConfigParam):
45  "Allows the choice of multiple parameter types"
46 
47  def __init__(self, *vargs, **kwargs):
48  super().__init__(**kwargs)
49 
50  self.choices = []
51  for choice in vargs:
52  if isinstance(choice, ConfigParam):
53  self.choices.append(choice)
54  else:
55  raise ParamError("Arguments to Choice must be instance of ConfigParam types.")
56 
57  def check_type(self, value):
58 
59  valid = False
60  for choice in self.choices:
61  try:
62  choice.check_type(value)
63  except ParamError:
64  pass
65  else:
66  valid = True
67  break
68 
69  if not valid:
70  raise ParamError("Parameter value does not match any of the parameter choices")
71 
73  "Configuration parameter that resolves to a single scalar value"
74 
75  def __init__(self, dtype=None, **kwargs):
76  super().__init__(**kwargs)
77 
78  self.dtype = dtype
79 
80  def check_type(self, value):
81  if not np.isscalar(value):
82  raise ParamError("Value is not a scalar: %s" % value)
83 
84  if self.dtype is not None and not isinstance(value, self.dtype):
85  raise ParamError("Type of parameter %s does not match expected %s for value: %s" % (type(value), self.dtype, value))
86 
88  "Configuration parameter that resolves to a numpy array with optional checking on dimensionality and units"
89 
90  def __init__(self, dims=None, dtype=None, **kwargs):
91  super().__init__(**kwargs)
92 
93  self.dims = dims
94  self.dtype = dtype
95 
96  def check_type(self, value):
97 
98  if not isinstance(value, np.ndarray):
99  raise ParamError("Value is not a numpy array: %s" % value)
100 
101  if self.dims is not None and len(value.shape) != self.dims:
102  raise ParamError("Number of dimensions %d do not match the expected number %s for value: %s" % (len(value.shape), self.dims, value))
103 
104  if self.dtype is not None and not isinstance(value.dtype, self.dtype):
105  raise ParamError("Type of parameter %s does not match expected %s for value: %s" % (value.dtype, self.dtype, value))
106 
108  "Configuration parameter that resolve to an iterable object like a tuple or list, but that is not required to be an array"
109 
110  def __init__(self, val_type=None, **kwargs):
111  super().__init__(**kwargs)
112  self.val_type = val_type
113 
114  def check_type(self, value):
115 
116  if not hasattr(value, "__iter__"):
117  raise ParamError("Expected an iterable for value: %s" % value)
118 
119  if self.val_type is not None:
120  for idx, iter_val in enumerate(value):
121  if not isinstance(iter_val, self.val_type):
122  raise ParamError("Expected an instance of %s for value %s at index %d of iterable" % (self.val_type, iter_val, idx))
123 
125  "Configuration parameter that must be an instance of a specific type of class"
126 
127  def __init__(self, val_type, **kwargs):
128  super().__init__(**kwargs)
129  self.val_type = val_type
130 
131  def check_type(self, value):
132 
133  if not isinstance(value, self.val_type):
134  raise ParamError("Expected an instance of %s for value: %s" % (self.val_type, value))
135 
137  "Configuration parameter that resolves to a dict"
138 
139  def __init__(self, **kwargs):
140  super().__init__(dict, **kwargs)
141 
143 
144  awu_type_pattern = r"ArrayWithUnit_\w+_\d+"
145 
146  def __init__(self, dims=None, dtype=None, **kwargs):
147  super().__init__(**kwargs)
148 
149  self.dims = dims
150  self.dtype = dtype
151 
152  def check_type(self, value):
153 
154  # Check that type string matches the pattern, can't just use ininstance
155  # on the SWIG type
156  type_str = str(type(value))
157 
158  if not re.search(self.awu_type_pattern, type_str):
159  raise ParamError("Value is not an ArrayWithUnit type: %s" % type(value))
160 
161  # Check dims and dtype against the value within the awu
162  if self.dims is not None and len(value.value.shape) != self.dims:
163  raise ParamError("Number of dimensions %d do not match the expected number %s for ArrayWithUnit value: %s" % (len(value.value.shape), self.dims, value))
164 
165  if self.dtype is not None and not isinstance(value.value.dtype, self.dtype):
166  raise ParamError("Type of parameter %s does not match expected %s for ArrayWithUnit value: %s" % (value.value.dtype, self.dtype, value))
167 
169  "Short cut for the DoubleWithUnit type to parallel the ArrayWithUnit type parameter"
170 
171  def __init__(self, **kwargs):
172  super().__init__(rf.DoubleWithUnit, **kwargs)
173 
175  "Checks that value is a C++ vector of a certain type"
176 
177  def __init__(self, vec_type=None, **kwargs):
178  super().__init__(**kwargs)
179 
180  self.vec_type = vec_type
181 
182  def check_type(self, value):
183 
184  # Check that the type string has vector_ in it and vec_type if that is supplied
185  if self.vec_type is not None:
186  check_str = "\.vector_%s" % self.vec_type
187  else:
188  check_str = "\.vector_.*"
189 
190  type_str = str(type(value))
191 
192  if not re.search(check_str, type_str):
193  raise ParamError("Value with type string %s is not a C++ vector with type vector_%s" % (type_str, self.vec_type and self.vec_type or ""))
def check_type(self, value)
Definition: param.py:131
def __init__(self, val_type, kwargs)
Definition: param.py:127
def __init__(self, dims=None, dtype=None, kwargs)
Definition: param.py:146
def check_type(self, value)
Definition: param.py:35
def __init__(self, dims=None, dtype=None, kwargs)
Definition: param.py:90
def check_type(self, value)
Definition: param.py:57
def __init__(self, kwargs)
Definition: param.py:139
def check_type(self, value)
Definition: param.py:152
def __init__(self, dtype=None, kwargs)
Definition: param.py:75
def check_type(self, value)
Definition: param.py:182
def __init__(self, kwargs)
Definition: param.py:171
def check_type(self, value)
Definition: param.py:41
def check_type(self, value)
Definition: param.py:96
def __init__(self, required=True, default=None)
Definition: param.py:13
def evaluate(self, in_value, kwargs)
Definition: param.py:22
def check_type(self, value)
Definition: param.py:80
def __init__(self, vargs, kwargs)
Definition: param.py:47
def __init__(self, val_type=None, kwargs)
Definition: param.py:110
def check_type(self, value)
Definition: param.py:114
def __init__(self, vec_type=None, kwargs)
Definition: param.py:177

Copyright © 2017, California Institute of Technology.
ALL RIGHTS RESERVED.
U.S. Government Sponsorship acknowledged.
Generated Fri Aug 24 2018 15:44:10