Source code for anypytools.macroutils

# -*- coding: utf-8 -*-
# pylint: disable: line-too-long
"""
Created on Mon Mar 23 21:14:59 2015.

@author: Morten
"""
import types
import logging
from pprint import pprint, pformat  # noqa
from copy import deepcopy
from collections.abc import MutableSequence

import numpy as np

from anypytools.tools import define2str, path2str, array2anyscript

logger = logging.getLogger("abt.anypytools")


__all__ = [
    "MacroCommand",
    "Load",
    "SetValue",
    "SetValue_random",
    "Dump",
    "SaveDesign",
    "LoadDesign",
    "SaveValues",
    "LoadValues",
    "UpdateValues",
    "OperationRun",
    "SaveData",
]


def _isgenerator(x):
    return isinstance(x, types.GeneratorType)


def _batch(iterable, n=1):
    length = len(iterable)
    for ndx in range(0, length, n):
        yield iterable[ndx : min(ndx + n, length)]


[docs]class MacroCommand(object): """Class for custom macro commands. This class also serves as base class for other macro commands. Examples -------- >>> mc = MacroCommand('operation "Main.MyStudy.InverseDynamics"') ) >>> print(mc) operation "Main.MyStudy.InverseDynamics" """ def __init__(self, command): if not isinstance(command, list): self.cmd = [command] else: self.cmd = command def __repr__(self): return self.get_macro(0)
[docs] def get_macro(self, index, **kwarg): """Create a string representation of the macro. Parameters ---------- index : int The index for the macro beeing generated. Some child classes use the index to generate different macros depending on the index. Returns ------- string A string with the AnyScript macro """ return "\n".join(self.cmd)
[docs]class Load(MacroCommand): """Create a load macro command. Parameters ---------- filename : str Path of the file to load defs : dict Dictionary of defines statements to set during load paths : dict Dictionary of path staements to set during load Examples -------- >>> Load('model.main.any') load "model.main.any" >>> paths = {'DATA':'c:/MyModel/Data'} >>> defines = {'EXCLUDE_ARMS':None, 'N_STEP':20} >>> Load('c:/MyModel/model.main.any', defines, paths) load "c:/MyModel/model.main.any" -def EXCLUDE_ARMS="" -def N_STEP="20" -p DATA=---"c:/MyModel/Data" >>> mcr = AnyMacro( Load('model_{id}.main.any'), counter_token = '{id}') >>> mcr.create_macros(3) [[u'load "model_0.main.any"'], [u'load "model_1.main.any"'], [u'load "model_2.main.any"']] """ def __init__(self, filename, defs={}, paths={}): self.filename = filename self.defs = defs.copy() self.paths = paths.copy()
[docs] def get_macro(self, index, **kwarg): cmd = [f'load "{self.filename}"'] for key in sorted(self.defs): value = self.defs[key] cmd.append(define2str(key, value)) for key in sorted(self.paths): value = self.paths[key] cmd.append(path2str(key, value)) return " ".join(cmd)
[docs]class SetValue(MacroCommand): """Create 'Set Value' classoperation macro command. Parameters ---------- var : string An AnyScript variable. value : number or list of number A value or list of values to assign to the AnyScript variable. Examples --------- Set a single values: >>> SetValue('Main.Study.myvar1', 23.1) classoperation Main.Study.myvar1 "Set Value" --value="23.1" >>> SetValue('Main.Study.myvar2', np.array([2,3,4])) classoperation Main.Study.myvar2 "Set Value" --value="{2,3,4}" Set variable across different macros >>> SetValue('Main.Study.myvar1',[1,2,3]) classoperation Main.Study.myvar1 "Set Value" --value="1" classoperation Main.Study.myvar1 "Set Value" --value="2" classoperation Main.Study.myvar1 "Set Value" --value="3" Here is a elaborate example: >>> mg = AnyMacro( Load('MyModel.main.any'), SetValue('Main.Study.myvar1',[1,2]), OperationRun('Main.Study.InverseDynamics') ) >>> mg.number_of_macros = 2 [['load "MyModel.main.any"', 'classoperation Main.Study.myvar1 "Set Value" --value="1"', 'operation Main.Study.InverseDynamics', 'run'], ['load "MyModel.main.any"', 'classoperation Main.Study.myvar1 "Set Value" --value="2"', 'operation Main.Study.InverseDynamics', 'run']] If we generate more macros that there are values then the values are just repeated >>> mg.number_of_macros = 4 >>> mg [['load "MyModel.main.any"', 'classoperation Main.Study.myvar1 "Set Value" --value="1"', 'operation Main.Study.InverseDynamics', 'run'], ['load "MyModel.main.any"', 'classoperation Main.Study.myvar1 "Set Value" --value="2"', 'operation Main.Study.InverseDynamics', 'run'], ['load "MyModel.main.any"', 'classoperation Main.Study.myvar1 "Set Value" --value="1"', 'operation Main.Study.InverseDynamics', 'run'], ['load "MyModel.main.any"', 'classoperation Main.Study.myvar1 "Set Value" --value="2"', 'operation Main.Study.InverseDynamics', 'run']] """ def __init__(self, var, value): self.var = var self.value = value def __repr__(self): if isinstance(self.value, list): n_elem = len(self.value) else: n_elem = 1 return "\n".join([self.get_macro(i) for i in range(n_elem)])
[docs] def get_macro(self, index, **kwarg): if isinstance(self.value, list): val = self.value[index % len(self.value)] else: val = self.value return self._format_macro(val)
def _format_macro(self, val): if isinstance(val, np.ndarray): val = array2anyscript(val) elif isinstance(val, float): val = f"{val:.12g}" elif isinstance(val, int): val = f"{val:d}" return f'classoperation {self.var} "Set Value" --value="{val}"'
[docs]class SetValue_random(SetValue): """Create a 'Set Value' macro command from a distribution. The value is connected to a distibution in scipy.stats.distributions. Parameters ---------- var : str An AnyScript variable. frozen_distribution : <scipy.stats.distributions.rv_frozen> A frozen distribution from scipy.stats.distributions default_lower_tail_probability : float The lower tail probability of the default value. Defaults to 0.5 which is the mean value. Examples -------- Creating normal macros will use the default values. Usually the 50 percentile (mean values). >>> np.random.seed(1) >>> from scipy.stats.distributions import logistic, norm >>> log_dist = logistic( loc= [1,3,4],scale = [0.1,0.5,1] ) >>> norm_dist = norm( loc= [0,0,0],scale = [0.1,0.5,1] ) >>> cmd = [SetValue_random('Main.MyVar1', log_dist), SetValue_random('Main.MyVar2', norm_dist) ] >>> mg = AnyMacro(cmd, number_of_macros = 3) >>> mg [['classoperation Main.MyVar1 "Set Value" --value="{0,0,0}"', 'classoperation Main.MyVar2 "Set Value" --value="{1,3,4}"'], ['classoperation Main.MyVar1 "Set Value" --value="{0,0,0}"', 'classoperation Main.MyVar2 "Set Value" --value="{1,3,4}"'], ['classoperation Main.MyVar1 "Set Value" --value="{0,0,0}"', 'classoperation Main.MyVar2 "Set Value" --value="{1,3,4}"']] Values can be sampled randomly in a 'Monte Carlo' fashion. Note that the first value is still the defaut mean values >>> mg.create_macros_MonteCarlo() [['classoperation Main.MyVar1 "Set Value" --value="{0,0,0}"', 'classoperation Main.MyVar2 "Set Value" --value="{1,3,4}"'], ['classoperation Main.MyVar1 "Set Value" --value="{-0.0209517840916,0.291902872134,-3.68494766954}"', 'classoperation Main.MyVar2 "Set Value" --value="{0.916378512121,2.11986245798,1.71459079162}"'], ['classoperation Main.MyVar1 "Set Value" --value="{-0.0891762169545,-0.198666812922,-0.261723075945}"', 'classoperation Main.MyVar2 "Set Value" --value="{1.01555799978,2.83695956934,4.7778636562}"']] Values can also be sampled with a Latin Hyper Cube sampler. >>> mg.create_macros_LHS() [['classoperation Main.MyVar1 "Set Value" --value="{0.0928967116493,-0.591418725401,-0.484696993931}"', 'classoperation Main.MyVar2 "Set Value" --value="{1.01049414425,2.46211329129,5.73806916203}"'], ['classoperation Main.MyVar1 "Set Value" --value="{-0.0166741228961,0.707722119582,-0.294180629253}"', 'classoperation Main.MyVar2 "Set Value" --value="{1.11326829265,2.66016732923,4.28054911097}"'], ['classoperation Main.MyVar1 "Set Value" --value="{-0.20265197275,0.114947152258,0.924796936287}"', 'classoperation Main.MyVar2 "Set Value" --value="{0.806864877696,4.4114188826,2.93941843565}"']] """ def __init__(self, var, frozen_distribution, default_lower_tail_probability=0.5): from scipy.stats.distributions import rv_frozen self.var = var if not isinstance(frozen_distribution, rv_frozen): raise TypeError( "frozen_distribution must be frozen distribtuion from \ scipy.stats.distributions" ) self.rv = frozen_distribution self.meanvalue = frozen_distribution.mean() if isinstance(self.meanvalue, np.ndarray): self.shape = self.meanvalue.shape self.n_factors = np.prod(self.shape) self.default_lower_tail_probability = ( default_lower_tail_probability * np.ones(self.shape) ) else: self.shape = None self.n_factors = 1 self.default_lower_tail_probability = default_lower_tail_probability def __repr__(self): return self.get_macro(0)
[docs] def get_macro(self, index, lower_tail_probability=None, **kwarg): if lower_tail_probability is None: lower_tail_probability = self.default_lower_tail_probability if self.shape is None and isinstance(lower_tail_probability, np.ndarray): lower_tail_probability = lower_tail_probability[0] val = self.rv.ppf(lower_tail_probability).reshape(self.shape) # Replace any nan from ppf function with actual sampled values. if np.any(np.isnan(val)): val[np.isnan(val)] = self.rv.rvs()[np.isnan(val)] return self._format_macro(val)
[docs]class Dump(MacroCommand): """Create a Dump classoperation macro command. Parameters ---------- var : str or list of str The anyscript values to create a 'Dump' macro command for include_in_macro: int or list of int Specifices in which macros [0,1,2....NumberOfMacros] to include the dump command. If None, the command is included in all macros. Examples --------- >>> Dump('Main.Study.myvar1') classoperation Main.Study.myvar1 "Dump" Only include the dump command in the two first macro >>> mg = AnyMacro(number_of_macros = 5) >>> mg.append(Load('mymodel.main.any')) >>> mg.append(Dump('Main.Study.myvar1', include_in_macro = [0,1])) >>> mg [['load "mymodel.main.any"', 'classoperation Main.Study.myvar1 "Dump"'], ['load "mymodel.main.any"', 'classoperation Main.Study.myvar1 "Dump"'], ['load "mymodel.main.any"'], ['load "mymodel.main.any"'], ['load "mymodel.main.any"']] """ def __init__(self, var, include_in_macro=None): if not isinstance(var, list): self.var_list = [var] else: self.var_list = var self._include_in_macro = include_in_macro
[docs] def get_macro(self, index, **kwarg): cmd = [] if self._include_in_macro is None or index in self._include_in_macro: for var in self.var_list: cmd.append(f'classoperation {var} "Dump"') return "\n".join(cmd)
[docs]class SaveDesign(MacroCommand): """Create a Save Design classoperation macro command. Parameters ---------- operation : str The AnyScript operation filename : str The filename in which to save the design Examples -------- >>> SaveDesign('Main.MyStudy.Kinematics', 'c:/design.txt') classoperation Main.MyStudy.Kinematics "Save design" --file="c:/design.txt" """ def __init__(self, operation, filename): self.filename = filename self.operation = operation
[docs] def get_macro(self, index, **kwarg): return f'classoperation {self.operation} "Save design" --file="{self.filename}"'
[docs]class LoadDesign(MacroCommand): """Create a Load Design classoperation macro command. Parameters ---------- operation : str The AnyScript operation filename : str The file in which to load the design from Examples -------- >>> LoadDesign('Main.MyStudy.Kinematics', 'c:/design.txt') classoperation Main.MyStudy.Kinematics "Load design" --file="c:/design.txt" """ def __init__(self, operation, filename): self.filename = filename self.operation = operation
[docs] def get_macro(self, index, **kwarg): return f'classoperation {self.operation} "Load design" --file="{self.filename}"'
[docs]class SaveValues(MacroCommand): """Create a Save Values classoperation macro command. Parameters ---------- filename : str The anyset file to save the values to Examples -------- >>> SaveValues('c:/values.anyset') classoperation Main "Save Values" --file="c:/values.anyset" """ def __init__(self, filename): self.filename = filename
[docs] def get_macro(self, index, **kwarg): return f'classoperation Main "Save Values" --file="{self.filename}"'
[docs]class SaveData(MacroCommand): """Create a Save Data classoperation macro command. This macro operation will save all data from a study to a HDF5 file. Parameters ---------- operation : str Operation to save the h5 from filename : str The anyset file to save the values to Examples -------- >>> SaveData('Main.Study', 'output.anydata.h5') classoperation Main.Study.Output "Save data" --type="Deep" --file="output.anydata.h5" """ def __init__(self, operation, filename): self.filename = filename self.opeation = operation
[docs] def get_macro(self, index, **kwarg): macro_str = 'classoperation {}.Output "Save data" --type="Deep" --file="{}"' return macro_str.format(self.opeation, self.filename)
[docs]class LoadValues(MacroCommand): """Create a Load Values classoperation macro command. Parameters ---------- filename : str The anyset file to load the values from. Examples -------- >>> LoadValues('c:/values.anyset') classoperation Main "Load Values" --file="c:/values.anyset" """ def __init__(self, filename): self.filename = filename
[docs] def get_macro(self, index, **kwarg): return f'classoperation Main "Load Values" --file="{self.filename}"'
[docs]class UpdateValues(MacroCommand): """Create an 'Update Values' classoperation macro command. Examples -------- >>> UpdateValues() classoperation Main "Update Values" """ def __init__(self): pass
[docs] def get_macro(self, index, **kwarg): return 'classoperation Main "Update Values"'
[docs]class OperationRun(MacroCommand): """Create a macro command to select and run an operation. Examples -------- >>> OperationRun('Main.MyStudy.Kinematics') >>> pprint( mg.generate_macros()) operation Main.MyStudy.Kinematics run >>> mg = AnyMacro(Load('my_model.main.any'), OperationRun('Main.MyStudy.Kinematics')) >>> mg.create_macros() [[u'load "my_model.main.any"', u'operation Main.MyStudy.Kinematics', u'run']] """ def __init__(self, operation): self.operation = operation
[docs] def get_macro(self, index, **kwarg): return f"operation {self.operation}" + "\n" + "run"
[docs]class AnyMacro(MutableSequence): """ Class to generate multiple macros. Use the class to contruct multiple anyscript macros from a single macro. E.g. for parameter studies, Monte Carlo, Latin Hyper Cube studies. Parameters ---------- maco_commands : list or positional arguments A list of macro command classes. These may also be given a arbitrary number of positional arguments. counter_token : str A string in the macro commands which will be replace with a counter for every macro generated number_of_macros : int The default number of macros which are created. This can be overruled when calling the AnyMacro.create_macros() function. Defults to 1. seed : int or array_like A constant seed value used which will be used every time macros are created. Must be convertable to 32 bit unsigned integers. Returns ------- An AnyMacro instance A Macro object for constructing the macro. Examples -------- >>> mg = AnyMacro(number_of_macros = 22) >>> mg.append( Load('c:/MyModel/model.main.any', defs = {}, paths = {} ) ) >>> mg.append( SetValue('Main.myvar', 12.3) ) >>> mg.extend( [RunOperation('Main.Study.Kinematics'), Dump('Main.Study.Output.MyVar') ] ) >>> mg [['load "c:/MyModel/model.main.any"', 'classoperation Main.myvar "Set Value" --value="12.3"', 'operation Main.Study.Kinematics', 'run', 'classoperation Main.Study.Output.MyVar "Dump"'], ['load "c:/MyModel/model.main.any"', 'classoperation Main.myvar "Set Value" --value="12.3"', 'operation Main.Study.Kinematics', 'run', 'classoperation Main.Study.Output.MyVar "Dump"']] >>> mg = AnyMacro( number_of_macros = 3, counter_token='{COUNTER}' ) >>> mg.append(Load('c:/MyModel/model_{COUNTER}_.main.any') ) >>> pprint(mg.create_macros()) [['load "c:/MyModel/model_0_.main.any"'], ['load "c:/MyModel/model_1_.main.any"'], ['load "c:/MyModel/model_2_.main.any"']] """ def __init__(self, *args, **kwargs): # number_of_macros=1, counter_token = None ): super(AnyMacro, self).__init__() if len(args) == 0: self._list = list() else: if len(args) == 1 and isinstance(args[0], list): args = args[0] for arg in args: if not isinstance(arg, MacroCommand): raise ValueError("Argument must be valid macro command classes") self._list = list(args) self.seed = kwargs.pop("seed", None) self.number_of_macros = kwargs.pop("number_of_macros", 1) self.counter_token = kwargs.pop("counter_token", None) def __mul__(self, other): if not isinstance(other, (int, float)): raise NotImplementedError("operator must be integer") mg = deepcopy(self) mg.number_of_macros = mg.number_of_macros * round(other) return mg __rmul__ = __mul__ def __len__(self): return len(self._list) def __getitem__(self, ii): return self._list[ii] def __delitem__(self, ii): del self._list[ii] def __setitem__(self, ii, val): self._list[ii] = val return self._list[ii] def __str__(self): return self.__repr__() def __repr__(self): return pformat(self.create_macros())
[docs] def insert(self, ii, val): self._list.insert(ii, val)
[docs] def append(self, val): list_idx = len(self._list) self.insert(list_idx, val)
[docs] def create_macros(self, number_of_macros=None, batch_size=None): """Generate a given number of macros. The function return its output either as list (batch_size = None) or in batches as generator object (memory efficient when generating many macros) Parameters ---------- number_of_macros : int (Optional) The number of macro to create. batch_size : int (Optional) If specified the function will return a generator which creates macros in batches. Returns ------- list or generator A list macros or a generator which creates macros in batches Examples -------- >>> from anypytools import AnyMacro >>> from anypytools.macro_commands import * >>> macro = [ ... Load('c:/Model.main.any'), ... OperationRun('Main.study.Kinematics'), ... ] >>> mg = AnyMacro(macro, number_of_macros=4) >>> macrolist = mg.create_macros() >>> pprint(macrolist) [['load "c:/Model.main.any"', 'operation Main.study.Kinematics', 'run'], ['load "c:/Model.main.any"', 'operation Main.study.Kinematics', 'run'], ['load "c:/Model.main.any"', 'operation Main.study.Kinematics', 'run'], ['load "c:/Model.main.any"', 'operation Main.study.Kinematics', 'run']] Generate macros in batches >>> mg = AnyMacro([Load('c:/Model.main.any')], number_of_macros = 6) >>> macro_gen = mg.create_macros(batch_size=2) >>> for i, macros in enumerate( macro_gen ): ... print('Batch ', i) ... pprint(macros) Batch 0 [['load "c:/Model.main.any"'], ['load "c:/Model.main.any"']] Batch 1 [['load "c:/Model.main.any"'], ['load "c:/Model.main.any"']] Batch 2 [['load "c:/Model.main.any"'], ['load "c:/Model.main.any"']] """ if batch_size is not None: return _batch(self.create_macros(number_of_macros), n=batch_size) if number_of_macros is None: number_of_macros = self.number_of_macros if self.seed is not None: np.random.seed(self.seed) macro_list = [] for macro_idx in range(number_of_macros): macro = [] for elem in self: mcr = elem.get_macro(macro_idx) if self.counter_token: mcr = mcr.replace(self.counter_token, str(macro_idx)) if mcr != "": macro.extend(mcr.split("\n")) macro_list.append(macro) return macro_list
[docs] def create_macros_MonteCarlo(self, number_of_macros=None, batch_size=None): # noqa """Generate AnyScript macros for monte carlos studies. The function returns macros for Monte Carlo parameter studies. This methods extends the `create_macros` methods with functionality to randomly vary parameters across macros. Values added with `SetValue_random` class are sampled randomly in a 'Monte Carlo' fashion. Note that the values of the first macro is the defaut mean value. Parameters ---------- number_of_macros : int (Optional) The number of macro to create. batch_size : int (Optional) If specified the function will return a generator which creates macros in batches. Returns ------- list or generator A list macros or a generator which creates macros in batches Examples -------- >>> np.random.seed(1) >>> from scipy.stats.distributions import logistic, norm >>> log_dist = logistic( loc= [1,3,4],scale = [0.1,0.5,1] ) >>> norm_dist = norm( loc= [0,0,0],scale = [0.1,0.5,1] ) >>> cmd = [SetValue_random('Main.MyVar1', log_dist), SetValue_random('Main.MyVar2', norm_dist) ] >>> mg = AnyMacro(cmd, number_of_macros = 3) >>> mg.create_macros_MonteCarlo() [['classoperation Main.MyVar1 "Set Value" --value="{0,0,0}"', 'classoperation Main.MyVar2 "Set Value" --value="{1,3,4}"'], ['classoperation Main.MyVar1 "Set Value" --value="{-0.0209517840916,0.291902872134,-3.68494766954}"', 'classoperation Main.MyVar2 "Set Value" --value="{0.916378512121,2.11986245798,1.71459079162}"'], ['classoperation Main.MyVar1 "Set Value" --value="{-0.0891762169545,-0.198666812922,-0.261723075945}"', 'classoperation Main.MyVar2 "Set Value" --value="{1.01555799978,2.83695956934,4.7778636562}"']] """ if batch_size is not None: return _batch(self.create_macros_MonteCarlo(number_of_macros), batch_size) if number_of_macros is None: number_of_macros = self.number_of_macros if self.seed is not None: np.random.seed(self.seed) macro_list = [] for macro_idx in range(number_of_macros): macro = [] lhs_idx = 0 for elem in self: if isinstance(elem, SetValue_random): if macro_idx == 0: lower_tail_probability = ( None # First macro get the default values ) else: lower_tail_probability = np.random.random(elem.n_factors) mcr = elem.get_macro(macro_idx, lower_tail_probability) lhs_idx += elem.n_factors else: mcr = elem.get_macro(macro_idx) if self.counter_token: mcr = mcr.replace(self.counter_token, str(macro_idx)) if mcr != "": macro.extend(mcr.split("\n")) macro_list.append(macro) return macro_list
[docs] def create_macros_LHS( self, number_of_macros=None, criterion=None, # noqa iterations=None, batch_size=None, append_default=False, ): """Generate AnyScript macros for Latin Hyper Cube Studies studies. Generates AnyScript macros for parameter studies using Latin hyper cube sampling. The macros added with the `SetValue_random` are created with with Latin Hypercube Sampling (LHS) of the parameter space. The number of generated macros determines the number of LHS samples. The method uses the pyDOE package to generate the LHS data. Parameters ---------- number_of_macros : int (Optional) The number of macro to create. batch_size : int (Optional) If specified the function will return a generator which creates macros in batches. criterion : {None, 'c', 'm', 'cm', 'corr'} A a string that specifies how points are sampled (see: http://pythonhosted.org/pyDOE/randomized.html) `None` (Default) points are randomizes within the intervals. "center" or "c" center the points within the sampling intervals "maximin" or "m": maximize the minimum distance between points, but place the point in a randomized location within its interval "centermaximin" or "cm": same as “maximin”, but centered within the intervals "corr" minimize the maximum correlation coefficient iterations : int Specifies how many iterations are used to accomplished the selected criterion append_default : bool If True a macro with default (mean) values is appended to the returned list of returned macros Returns ------- list or generator A list macros or a generator which creates macros in batches Examples -------- >>> np.random.seed(1) >>> from scipy.stats.distributions import logistic, norm >>> log_dist = logistic( loc= [1,3,4],scale = [0.1,0.5,1] ) >>> norm_dist = norm( loc= [0,0,0],scale = [0.1,0.5,1] ) >>> cmd = [SetValue_random('Main.MyVar1', log_dist), SetValue_random('Main.MyVar2', norm_dist) ] >>> mg = AnyMacro(cmd, number_of_macros = 3) >>> mg.create_macros_LHS() [['classoperation Main.MyVar1 "Set Value" --value="{0.0928967116493,-0.591418725401,-0.484696993931}"', 'classoperation Main.MyVar2 "Set Value" --value="{1.01049414425,2.46211329129,5.73806916203}"'], ['classoperation Main.MyVar1 "Set Value" --value="{-0.0166741228961,0.707722119582,-0.294180629253}"', 'classoperation Main.MyVar2 "Set Value" --value="{1.11326829265,2.66016732923,4.28054911097}"'], ['classoperation Main.MyVar1 "Set Value" --value="{-0.20265197275,0.114947152258,0.924796936287}"', 'classoperation Main.MyVar2 "Set Value" --value="{0.806864877696,4.4114188826,2.93941843565}"']] """ # noqa try: import pyDOE except ImportError: raise ImportError("The pyDOE package must be install to use this class") if batch_size is not None: return _batch( self.create_macros_LHS(number_of_macros, criterion, iterations), n=batch_size, ) if number_of_macros is None: number_of_macros = self.number_of_macros if self.seed is not None: np.random.seed(self.seed) factors = sum([e.n_factors for e in self if isinstance(e, SetValue_random)]) lhs_matrix = pyDOE.lhs( factors, number_of_macros, criterion=criterion, iterations=iterations ) macro_list = [] for macro_idx in range(number_of_macros): macro = [] lhs_idx = 0 for elem in self: if isinstance(elem, SetValue_random): lhs_val = lhs_matrix[macro_idx, lhs_idx : lhs_idx + elem.n_factors] mcr = elem.get_macro(macro_idx, lower_tail_probability=lhs_val) lhs_idx += elem.n_factors else: mcr = elem.get_macro(macro_idx) if self.counter_token: mcr = mcr.replace(self.counter_token, str(macro_idx)) if len(mcr) > 0: macro.extend(mcr.split("\n")) macro_list.append(macro) if append_default: macro = [] for elem in self: mcr = elem.get_macro(number_of_macros) if self.counter_token: mcr = mcr.replace(self.counter_token, str(number_of_macros)) if len(mcr) > 0: macro.extend(mcr.split("\n")) macro_list.append(macro) return macro_list
if __name__ == "__main__": # mg = PertubationMacroGenerator() # mg.add_set_value_designvar('test',1) # mg.add_set_value_designvar('test',2) # # pprint(mg.generate_macros()) # import pytest pytest.main(str("generate_macros.py --doctest-modules"))