Skip to content

Commit

Permalink
Fix exps.read_params to read Dymola experiment, method tuning, & outp…
Browse files Browse the repository at this point in the history
…ut parameters
  • Loading branch information
kdavies4 committed Dec 19, 2014
1 parent ca23ca7 commit d15acbf
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 70 deletions.
2 changes: 1 addition & 1 deletion UNRELEASED.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
2014-12-19 18:56:25Z
2014-12-19 18:59:10Z

Kevin Davies

Expand Down
61 changes: 34 additions & 27 deletions modelicares/exps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
import numpy as np

from six import string_types

from ..util import modelica_str


Expand All @@ -93,19 +92,20 @@ def read_params(names, fname='dsin.txt'):
**Example:**
>>> read_params(['Td', 'Ti'], 'examples/dsin.txt')
[0.1, 0.5]
>>> read_params(['Ti', 'Td'], 'examples/dsin.txt')
[0.5, 0.1]
"""
# Aliases for some regular subexpressions
# Some regular subexpressions
u = r'\d+' # Unsigned integer
i = '[+-]?' + u # Integer
f = i + r'(?:\.' + u + ')?(?:[Ee][+-]?' + u + ')?' # Floating point number
f = i + r'(?:\.' + u + ')?(?:[Ee][+-]?' + u + ')?' # Float

# Possible regular expressions for a parameter specification (with '%s' for
# the parameter name)
patterns = [ # Dymola 1- or 2-line parameter specification
(r'^\s*%s\s+(%s)\s+%s\s+%s\s+%s\s+%s\s*#\s*%s\s*$'
% (i, f, f, f, u, u, '%s')),
# the parameter name and parentheses around the value)
patterns = [
# For Dymola 1- or 2-line parameter specification:
r'^\s*{i}\s+({f})\s+{f}\s+{f}\s+{u}\s+{u}\s*#\s*%s\s*$'.format(i=i, f=f,
u=u),
# From Dymola:
# column 1: Type of initial value
# = -2: special case: for continuing simulation
Expand Down Expand Up @@ -135,17 +135,22 @@ def read_params(names, fname='dsin.txt'):
# = 0: real.
# = 1: boolean.
# = 2: integer.

# For Dymola experiment parameters, method tuning parameters, and output
# parameters:
r'^\s*({i})\s*#\s*%s\s'.format(i=i),
r'^\s*({f})\s*#\s*%s\s'.format(f=f),
]
# These are tried in order until there is a match. The group or pair of
# parentheses contains the parameter value.
# These are tried in order until there's a match.

# Read the file.
with open(fname, 'r') as src:
text = src.read()

# Read the parameters.
def _read_param(name):
"""Read a single parameter"""
"""Read a single parameter.
"""
namere = re.escape(name) # Escape the dots, square brackets, etc.
for pattern in patterns:
try:
Expand All @@ -162,7 +167,7 @@ def _read_param(name):
if isinstance(names, string_types):
return _read_param(names)
else:
return [_read_param(name) for name in names]
return map(_read_param, names)


def write_params(params, fname='dsin.txt'):
Expand Down Expand Up @@ -213,36 +218,38 @@ def write_params(params, fname='dsin.txt'):
"Strings cannot be used as values in the simulation initialization "
"file.")

# Aliases for some regular subexpressions
# Some regular subexpressions
u = r'\d+' # Unsigned integer
i = '[+-]?' + u # Integer
f = i + r'(?:\.' + u + ')?(?:[Ee][+-]' + u + ')?' # Floating point number
f = i + r'(?:\.' + u + ')?(?:[Ee][+-]' + u + ')?' # Float

# Possible regular expressions for a parameter specification (with '%s' for
# the parameter name)
patterns = [ # Dymola 1- or 2-line parameter specification
(r'(^\s*%s\s+)%s(\s+%s\s+%s\s+%s\s+%s\s*#\s*%s\s*$)'
% (i, f, f, f, u, u, '%s')),
r'(^\s*)' + i + r'(\s*#\s*%s)',
r'(^\s*)' + f + r'(\s*#\s*%s)',
# the parameter name and two pairs of parentheses: around everything before
# the value and around everything after the value)
patterns = [
# For Dymola 1- or 2-line parameter specification:
r'(^\s*{i}\s+)'.format(i=i) + f
+ r'(\s+{f}\s+{f}\s+{u}\s+{u}\s*#\s*%s\s*$)'.format(f=f, u=u),
# See read_params() for a description of the columns.

# For Dymola experiment parameters, method tuning parameters, and output
# parameters:
r'(^\s*)' + i + r'(\s*#\s*%s\s)',
r'(^\s*)' + f + r'(\s*#\s*%s\s)',
]
# These are tried in order until there is a match. The first group or pair
# of parentheses contains the text before the parameter value and the
# second contains the text after it (minus one space on both sides for
# clarity).
# These are tried in order until there's a match.

# Read the file.
with open(fname, 'r') as src:
text = src.read()

# Set the parameters.
for name, value in params.items():
namere = re.escape(name) # Escape the dots, square brackets, etc.
namere = re.escape(name) # Escape the dots, square brackets, etc.
for pattern in patterns:
text, num = re.subn(pattern % namere, r'\g<1>%s\2' % value, text, 1,
re.MULTILINE)
if num == 1:
if num: # Found a match
break
else:
raise AssertionError(
Expand Down
70 changes: 28 additions & 42 deletions modelicares/exps/doe.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,18 @@ def aslisted(*space):
**Example 1 (lists as positional arguments):**
.. code-block:: python
>>> from modelicares import doe
>>> for x in doe.aslisted([0, 1], [0, 1], [0, 1, 2]):
... print(x)
(0, 0, 0)
(1, 1, 1)
>>> for x in aslisted([0, 1], [0, 1], [0, 1, 2]):
... print(x)
(0, 0, 0)
(1, 1, 1)
**Example 2 (lists as keyword arguments):**
.. code-block:: python
>>> from modelicares import doe
>>> from modelicares.exps import ParamDict
>>> for x in doe.aslisted(a=[0, 1], b=[0, 1], c=[0, 1, 2]):
>>> for x in aslisted(a=[0, 1], b=[0, 1], c=[0, 1, 2]):
... print(ParamDict(x)) # ParamDict makes the output easier to read.
(a=0, b=0, c=0)
(a=1, b=1, c=1)
Expand All @@ -107,10 +102,9 @@ def aslisted(*space):
.. code-block:: python
>>> from modelicares import doe
>>> from modelicares.exps import ParamDict
>>> for x in doe.aslisted(dict(a=[0, 1], b=[0, 1], c=[0, 1, 2])):
>>> for x in aslisted(dict(a=[0, 1], b=[0, 1], c=[0, 1, 2])):
... print(ParamDict(x)) # ParamDict makes the output easier to read.
(a=0, b=0, c=0)
(a=1, b=1, c=1)
Expand All @@ -119,7 +113,7 @@ def aslisted(*space):
to represent a hierarchy using this approach in conjunction with
:class:`~modelicares.exps.ParamDict`:
>>> for x in doe.aslisted({'a': [0, 1], 'b.c': [0, 1], 'b.d': [0, 1, 2]}):
>>> for x in aslisted({'a': [0, 1], 'b.c': [0, 1], 'b.d': [0, 1, 2]}):
... print(ParamDict(x))
(a=0, b(c=0, d=0))
(a=1, b(c=1, d=1))
Expand All @@ -134,24 +128,20 @@ def fullfact(*space):
**Example:**
.. code-block:: python
>>> from modelicares import doe
>>> for x in doe.fullfact([0, 1], [0, 1], [0, 1, 2]):
... print(x)
(0, 0, 0)
(0, 0, 1)
(0, 0, 2)
(0, 1, 0)
(0, 1, 1)
(0, 1, 2)
(1, 0, 0)
(1, 0, 1)
(1, 0, 2)
(1, 1, 0)
(1, 1, 1)
(1, 1, 2)
>>> for x in fullfact([0, 1], [0, 1], [0, 1, 2]):
... print(x)
(0, 0, 0)
(0, 0, 1)
(0, 0, 2)
(0, 1, 0)
(0, 1, 1)
(0, 1, 2)
(1, 0, 0)
(1, 0, 1)
(1, 0, 2)
(1, 1, 0)
(1, 1, 1)
(1, 1, 2)
It is also possible to call this function with keyword arguments or with a
dictionary as a positional argument, like in examples 2 and 3 for
Expand All @@ -170,17 +160,13 @@ def ofat(*space):
**Example:**
.. code-block:: python
>>> from modelicares import doe
>>> for x in doe.ofat([0, 1], [0, 1], [0, 1, 2]):
... print(x)
(0, 0, 0)
(1, 0, 0)
(0, 1, 0)
(0, 0, 1)
(0, 0, 2)
>>> for x in ofat([0, 1], [0, 1], [0, 1, 2]):
... print(x)
(0, 0, 0)
(1, 0, 0)
(0, 1, 0)
(0, 0, 1)
(0, 0, 2)
It is also possible to call this function with keyword arguments or with a
dictionary as a positional argument, like in examples 2 and 3 for
Expand Down

0 comments on commit d15acbf

Please sign in to comment.