Python builder

The Python builder allows to build models that can be run with the PySD Model class.

The use of a one-to-one dictionary in translation means that the breadth of functionality is inherently limited. In the case where no direct Python equivalent is available, PySD provides a library of functions such as pulse, step, etc. that are specific to dynamic model behavior.

In addition to translating individual commands between Vensim/XMILE and Python, PySD reworks component identifiers to be Python-safe by replacing spaces with underscores. The translator allows source identifiers to make use of alphanumeric characters, spaces, or special characters. In order to make that possible a namespace is created, which links the original name of the variable with the Python-safe name. The namespace is also available in the PySD model class to allow users working with both original names and Python-safe names.

The resulting Python code from building the model is formatted with black library and it is written to the same folder where the original model is.

Main builders

The ModelBuilder class allows converting the AbstractModel into a PySD model writing the Python code in files that can be loaded later with PySD Model class. Each Abstract level has its own Builder. However, the user is only required to create a ModelBuilder object using the AbstractModel and call the build_model method.

class pysd.builders.python.python_model_builder.ModelBuilder(abstract_model: AbstractModel)[source]

ModelBuilder allows building a PySD Python model from the Abstract Model.

Parameters:

abstract_model (AbstractModel) – The abstract model to build.

build_model() Path[source]

Build the Python model in a file callled as the orginal model but with ‘.py’ suffix.

Returns:

path – The path to the new PySD model.

Return type:

pathlib.Path

class pysd.builders.python.python_model_builder.SectionBuilder(abstract_section: AbstractSection)[source]

SectionBuilder allows building a section of the PySD model. Each section will be a file unless the model has been set to be split in modules.

Parameters:

abstract_section (AbstractSection) – The abstract section to build.

build_section() None[source]

Build the Python section in a file callled as the orginal model if the section is main or in a file called as the macro name if the section is a macro.

class pysd.builders.python.python_model_builder.ElementBuilder(abstract_element: AbstractElement, section: SectionBuilder)[source]

ElementBuilder allows building an element of the PySD model.

Parameters:
  • abstract_element (AbstractElement) – The abstract element to build.

  • section (SectionBuilder) – The section where the element is defined. Necessary to give the acces to the subscripts and namespace.

build_element() None[source]

Build the element. Returns the string to include in the section which will be a decorated function definition and possible objects.

class pysd.builders.python.python_model_builder.ComponentBuilder(abstract_component: AbstractComponent, element: ElementBuilder, section: SectionBuilder)[source]

ComponentBuilder allows building a component of the PySD model.

Parameters:
  • abstract_component (AbstracComponent) – The abstract component to build.

  • element (ElementBuilder) – The element where the component is defined. Necessary to give the acces to the merging subscripts and other components.

  • section (SectionBuilder) – The section where the element is defined. Necessary to give the acces to the subscripts and namespace.

build_component() None[source]

Build model component parsing the Abstract Syntax Tree.

get() tuple[source]

Get build component to build the element.

Returns:

  • ast_build (BuildAST) – Parsed AbstractSyntaxTree.

  • subscript_dict (dict or list of dicts) – The subscripts of the component.

  • except_subscripts (list of dicts) – The subscripts to avoid.

Expression builders

The translation from Abstract Syntax Tree to Python happens in both ways. The outer expression is visited with its builder, which will split its arguments and visit them with their respective builders. Once the lowest level is reached, it will be translated into Python returning a BuildAST object, this object will include the python expression, its subscripts, its calls to other and its arithmetic order (see Build AST for more info). BuildAST will be returned for each visited argument from the lower lever to the top level, giving the final expression.

class pysd.builders.python.python_expressions_builder.BuildAST(expression: str, calls: dict, subscripts: dict, order: int)[source]

Python expression holder.

Parameters:
  • expression (str) – The Python expression.

  • calls (dict) – The calls to other variables for the dependencies dictionary.

  • subscripts (dict) – The subscripts dict of the expression.

  • order (int) – Arithmetic order of the expression. The arithmetic order depends on the last arithmetic operation. If the expression is a number, a call to a function, or is between parenthesis; its order will be 0. If the expression its an exponential of two terms its order will be 1. If the expression is a product or division its order will be 2. If the expression is a sum or substraction its order will be 3. If the expression is a logical comparison its order will be 4.

reshape(subscripts: SubscriptManager, final_subscripts: dict, final_element: bool = False) None[source]

Reshape the object to the desired subscripts. It will modify the expression and lower the order if it is not 0.

Parameters:
  • subscripts (SubscriptManager) – The subscripts of the section.

  • final_subscripts (dict) – The desired final subscripts.

  • final_element (bool (optional)) – If True the array will be reshaped with the final subscripts to have the shame shape. Otherwise, a length 1 dimension will be included in the position to allow arithmetic operations with other arrays. Default is False.

lower_order(new_order: int) None[source]

Lower the order to maintain the correct order in arithmetic operations. If the requested order is smaller than the current order parenthesis will be added to the expression to lower its order to 0.

Parameters:

new_order (int) – The required new order of the expression. If 0 it will be assumed that the expression will be passed as an argument of a function and therefore no operations will be done. If order 0 is required, a negative value can be used for new_order.

class pysd.builders.python.python_expressions_builder.StructureBuilder(value: object, component: object)[source]

Main builder for Abstract Syntax Tree structures. All the builders are children of this class, which allows them inheriting the methods.

static join_calls(arguments: dict) dict[source]

Merge the calls of the arguments.

Parameters:

arguments (dict) – The dictionary of arguments. The keys should br strings of ordered integer numbers starting from 0.

Returns:

calls – The merged dictionary of calls.

Return type:

dict

reorder(arguments: dict, force: bool = None) dict[source]

Reorder the subscripts of the arguments to make them match.

Parameters:
  • arguments (dict) – The dictionary of arguments. The keys should br strings of ordered integer numbers starting from 0.

  • force ('component', 'equal', or None (optional)) – If force is ‘component’ it will force the arguments to have the subscripts of the component definition. If force is ‘equal’ it will force all the arguments to have the same subscripts, includying the floats. If force is None, it will only modify the shape of the arrays adding length 1 dimensions to allow operation between different shape arrays. Default is None.

Returns:

final_subscripts – The final_subscripts after reordering all the elements.

Return type:

dict

get_final_subscripts(arguments: dict) dict[source]

Get the final subscripts of a combination of arguments.

Parameters:

arguments (dict) – The dictionary of arguments. The keys should br strings of ordered integer numbers starting from 0.

Returns:

final_subscripts – The final_subscripts of combining all the elements.

Return type:

dict

update_object_subscripts(name: str, component_final_subs: dict) None[source]

Update the object subscripts. Needed for those objects that use ‘add’ method to load several components at once and mixed definitions are used.

Parameters:
  • name (str) – The name of the object in the objects dictionary from the element.

  • component_final_subs (dict) – The subscripts of the component but with the element subscript ranges as keys. This can differ from the component subscripts when the component is defined with subranges of the final subscript ranges.

class pysd.builders.python.python_expressions_builder.OperationBuilder(operation: ArithmeticStructure | LogicStructure, component: object)[source]

Builder for arithmetic and logical operations.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.GameBuilder(game_str: GameStructure, component: object)[source]

Builder for GAME expressions.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.CallBuilder(call_str: CallStructure, component: object)[source]

Builder for calls to functions, macros and lookups.

build_not_implemented(arguments: dict) BuildAST[source]

Build method for not implemented function calls.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

build_incomplete_call(arguments: dict) BuildAST[source]

Build method for incomplete function calls.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

build_macro_call(arguments: dict) BuildAST[source]

Build method for macro calls.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

build_lookups_call(arguments: dict) BuildAST[source]

Build method for loookups calls.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

build_function_call(arguments: dict) BuildAST[source]

Build method for function calls.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.AllocateAvailableBuilder(allocate_str: AllocateAvailableStructure, component: object)[source]

Builder for allocate_available function.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.AllocateByPriorityBuilder(allocate_str: AllocateByPriorityStructure, component: object)[source]

Builder for allocate_by_priority function.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.ExtLookupBuilder(getlookup_str: GetLookupsStructure, component: object)[source]

Builder for External Lookups.

build(arguments: dict) BuildAST | None[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object, unless the component has been added to an existing object using the ‘add’ method.

Return type:

BuildAST or None

class pysd.builders.python.python_expressions_builder.ExtDataBuilder(getdata_str: GetDataStructure, component: object)[source]

Builder for External Data.

build(arguments: dict) BuildAST | None[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object, unless the component has been added to an existing object using the ‘add’ method.

Return type:

BuildAST or None

class pysd.builders.python.python_expressions_builder.ExtConstantBuilder(getconstant_str: GetConstantsStructure, component: object)[source]

Builder for External Constants.

build(arguments: dict) BuildAST | None[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object, unless the component has been added to an existing object using the ‘add’ method.

Return type:

BuildAST or None

class pysd.builders.python.python_expressions_builder.TabDataBuilder(data_str: DataStructure, component: object)[source]

Builder for empty DATA expressions.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.InitialBuilder(initial_str: InitialStructure, component: object)[source]

Builder for Initials.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.IntegBuilder(integ_str: IntegStructure, component: object)[source]

Builder for Integs/Stocks.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.DelayBuilder(dtype: str, delay_str: DelayStructure | DelayNStructure, component: object)[source]

Builder for regular Delays.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.DelayFixedBuilder(delay_str: DelayFixedStructure, component: object)[source]

Builder for Delay Fixed.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.SmoothBuilder(smooth_str: SmoothStructure | SmoothNStructure, component: object)[source]

Builder for Smooths.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.TrendBuilder(trend_str: TrendStructure, component: object)[source]

Builder for Trends.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.ForecastBuilder(forecast_str: ForecastStructure, component: object)[source]

Builder for Forecasts.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.SampleIfTrueBuilder(sampleiftrue_str: SampleIfTrueStructure, component: object)[source]

Builder for Sample If True.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.LookupsBuilder(lookups_str: LookupsStructure, component: object)[source]

Builder for regular Lookups.

build(arguments: dict) BuildAST | None[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object, unless the component has been added to an existing object using the ‘add’ method.

Return type:

BuildAST or None

class pysd.builders.python.python_expressions_builder.InlineLookupsBuilder(inlinelookups_str: InlineLookupsStructure, component: object)[source]

Builder for inline Lookups.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.ReferenceBuilder(reference_str: ReferenceStructure, component: object)[source]

Builder for references to other variables.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.NumericBuilder(value: object, component: object)[source]

Builder for numeric and nan values.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

class pysd.builders.python.python_expressions_builder.ArrayBuilder(value: object, component: object)[source]

Builder for arrays.

build(arguments: dict) BuildAST[source]

Build method.

Parameters:

arguments (dict) – The dictionary of builded arguments.

Returns:

built_ast – The built object.

Return type:

BuildAST

pysd.builders.python.python_expressions_builder.merge_dependencies(*dependencies: dict, inplace: bool = False) dict[source]

Merge two dependencies dicts of an element.

Parameters:
  • dependencies (dict) – The dictionaries of dependencies to merge.

  • inplace (bool (optional)) – If True the final dependencies dict will be updated in the first dependencies argument, mutating it. Default is False.

Returns:

current – The final dependencies dict.

Return type:

dict

pysd.builders.python.python_expressions_builder.visit_loc(current_subs: dict, original_subs: dict, keep_shape: bool = False) tuple[source]

Compares the original subscripts and the current subscripts and returns subindexing information if needed.

Parameters:
  • current_subs (dict) – The dictionary of the subscripts that are used in the variable.

  • original_subs (dict) – The dictionary of the original subscripts of the variable.

  • keep_shape (bool (optional)) – If True will keep the number of dimensions of the original element and return only loc. Default is False.

Returns:

  • loc (list of str or None) – List of the subscripting in each dimensions. If all are full (“:”), None is rerned wich means that array indexing is not needed.

  • rename (dict) – Dictionary of the dimensions to rename.

  • final_subs (dict) – Dictionary of the final subscripts of the variable.

  • reset_coords (bool) – Boolean indicating if the coords need to be reseted.

  • to_float (bool) – Boolean indicating if the variable should be converted to a float.

class pysd.builders.python.python_expressions_builder.ASTVisitor(component: object)[source]

ASTVisitor allows visiting the Abstract Synatx Tree of a component returning the Python object and generating the neccessary objects.

Parameters:

component (ComponentBuilder) – The component builder to build.

visit() None | BuildAST[source]

Visit the Abstract Syntax Tree of the component.

Returns:

visit_out – The BuildAST object resulting from visiting the AST. If the component content has been added to an existing object using the ‘add’ method it will return None.

Return type:

BuildAST or None

Supported expressions examples

Operators

Supported unary operators

Abstract Syntax

Python Translation

LogicStructure([‘negative’], (A,))

-A

A

A

LogicStructure([‘:NOT:’], (A,))

numpy.not(A)

Supported binary operators

Abstract Syntax

Python Translation

ArithmeticStructure([‘^’], (A, B))

A**B

ArithmeticStructure([‘*’], (A, B))

A*B

ArithmeticStructure([‘/’], (A, B))

A/B

CallStructure(‘modulo’, (A, B))

pysd.functions.modulo(A, B)

ArithmeticStructure([‘+’], (A, B))

A+B

ArithmeticStructure([‘-‘], (A, B))

A-B

LogicStructure([‘=’], (A, B))

A == B

LogicStructure([‘<>’], (A, B))

A != B

LogicStructure([‘<’], (A, B))

A < B

LogicStructure([‘>’], (A, B))

A > B

LogicStructure([‘>=’], (A, B))

A >= B

LogicStructure([‘<=’], (A, B))

A <= B

LogicStructure([‘:AND:’], (A, B))

numpy.and(A, B)

LogicStructure([‘:OR:’], (A, B))

numpy.or(A, B)

Functions

Supported basic functions

Abstract Syntax

Python Translation

Python comments

CallStructure(‘abs’, (A,))

numpy.abs(A)

CallStructure(‘min’, (A, B))

numpy.minimum(A, B)

CallStructure(‘max’, (A, B))

numpy.maximum(A, B)

CallStructure(‘vmin_xmile’, (A,))

pysd.functions.vmin(A)

CallStructure(‘vmax_xmile’, (A,))

pysd.functions.vmax(A)

CallStructure(‘sqrt’, (A,))

numpy.sqrt

CallStructure(‘exp’, (A,))

numpy.exp(A)

CallStructure(‘ln’, (A,))

numpy.log(A)

CallStructure(‘pi’, (,))

numpy.py

CallStructure(‘sin’, (A,))

numpy.sin(A)

CallStructure(‘cos’, (A,))

numpy.cos(A)

CallStructure(‘tan’, (A,))

numpy.tan(A)

CallStructure(‘arcsin’, (A,))

numpy.arcsin(A)

CallStructure(‘arccos’, (A,))

numpy.arccos(A)

CallStructure(‘arctan’, (A,))

numpy.arctan(A)

CallStructure(‘invert_matrix’, (A,))

pysd.functions.invert_matrix(A)

CallStructure(‘elmcount’, (A,))

len(A)

CallStructure(‘int’, (A,))

pysd.functions.integer(A)

CallStructure(‘quantum’, (A, B))

pysd.functions.quantum(A, B)

CallStructure(‘modulo’, (A, B))

pysd.functions.modulo(A, B)

CallStructure(‘if_then_else’, (A, B))

pysd.functions.if_then_else(A, lambda: B, lambda: C)

CallStructure(‘if_then_else’, (A, B))

pysd.functions.if_then_else(A, lambda: B, lambda: C)

CallStructure(‘xidz’, (A, B, X))

pysd.functions.xidz(A, B, X)

CallStructure(‘zidz’, (A, B))

pysd.functions.zidz(A, B)

CallStructure(‘vmin’, (A,))

pysd.functions.vmin(A, [‘dim!’])

CallStructure(‘vmax’, (A,))

pysd.functions.vmax(A, [‘dim!’])

CallStructure(‘sum’, (A,))

pysd.functions.sum(A, [‘dim!’])

CallStructure(‘prod’, (A,))

pysd.functions.prod(A, [‘dim!’])

CallStructure(‘pulse’, (start, width))

pysd.functions.pulse(start, width=width)

CallStructure(‘Xpulse’, (start, magnitude))

pysd.functions.pulse(start, magnitude=magnitude)

CallStructure(‘Xpulse_train’, (start, interval, magnitude))

pysd.functions.pulse(start, repeat_time=interval, magnitude=magnitude)

CallStructure(‘pulse_train’, (start, tbetween, width, end))

pysd.functions.pulse(start, repeat_time=tbetween, width=width, end=end)

CallStructure(‘ramp’, (slope, start_time, end_time))

pysd.functions.ramp(time, slope, start_time, end_time)

CallStructure(‘ramp’, (slope, start_time))

pysd.functions.ramp(time, slope, start_time)

CallStructure(‘step’, (height, step_time))

pysd.functions.step(time, height, step_time)

CallStructure(‘get_time_value’, (relativeto, offset, measure))

pysd.functions.get_time_value(time, relativeto, offset, measure)

CallStructure(‘vector_select’, (sel_array, exp_array, miss_val, n_action, e_action))

pysd.functions.vector_select(sel_array, exp_array, [‘dim!’], miss_val, n_action, e_action)

CallStructure(‘vector_rank’, (vec, direction))

vector_rank(vec, direction)

CallStructure(‘vector_reorder’, (vec, svec))

vector_reorder(vec, svec)

CallStructure(‘vector_sort_order’, (vec, direction))

vector_sort_order(vec, direction)

GameStructure(A)

A

AllocateAvailableStructure(request, pp, avail)

allocate_available(request, pp, avail)

Not all the priority profiles are included.

AllocateByPriorityStructure(request, priority, size, width, supply)

allocate_by_priority(request, priority, width, supply)

InitialStructure(value)

pysd.statefuls.Initial

SampleIfTrueStructure(condition, input, initial_value)

pysd.statefuls.SampleIfTrue(…)

CallStructure(‘random_0_1’, ())

np.random.uniform(0, 1, size=final_shape)

CallStructure(‘random_uniform’, (m, x, s))

np.random.uniform(m, x, size=final_shape)

CallStructure(‘random_normal’, (m, x, h, r, s))

stats.truncnorm.rvs((m-h)/r, (x-h)/r, loc=h, scale=r, size=final_shape)

CallStructure(‘random_exponential’, (m, x, h, r, s))

stats.truncexpon.rvs((x-np.maximum(m, h))/r, loc=np.maximum(m, h), scale=r, size=final_shape)

Supported delay functions

Abstract Syntax

Python Translation

DelayStructure(input, delay_time, initial_value, 1)

pysd.statefuls.Delay(…)

DelayStructure(input, delay_time, input, 1)

pysd.statefuls.Delay(…)

DelayStructure(input, delay_time, initial_value, 3)

pysd.statefuls.Delay(…)

DelayStructure(input, delay_time, input, 3)

pysd.statefuls.Delay(…)

DelayNStructure(input, delay_time, initial_value, n)

pysd.statefuls.DelayN(…)

DelayNStructure(input, delay_time, input, n)

pysd.statefuls.DelayN(…)

DelayFixed(input, delay_time, initial_value)

pysd.statefuls.DelayFixed(…)

DelayFixed(input, delay_time, input)

pysd.statefuls.DelayFixed(…)

SmoothStructure(input, smth_time, initial_value, 1)

pysd.statefuls.Smooth(…)

SmoothStructure(input, smth_time, input, 1)

pysd.statefuls.Smooth(…)

SmoothStructure(input, smth_time, initial_value, 3)

pysd.statefuls.Smooth(…)

SmoothStructure(input, smth_time, input, 3)

pysd.statefuls.Smooth(…)

SmoothNStructure(input, smth_time, initial_value, n)

pysd.statefuls.SmoothN(…)

SmoothNStructure(input, smth_time, input, n)

pysd.statefuls.SmoothN(…)

ForecastStructure(input, average_time, horizon, initial_trend)

pysd.statefuls.Forecast(…)

ForecastStructure(input, average_time, horizon, 0)

pysd.statefuls.Forecast(…)

TrendStructure(input, average_time, initial_trend)

pysd.statefuls.Trend(…)

TrendStructure(input, average_time, 0)

pysd.statefuls.Trend(…)

Supported get functions

Abstract Syntax

Python Translation

GetDataStructure(‘file’, ‘tab’, ‘time_row_or_col’, ‘cell’)

pysd.external.ExtData(…)

GetDataStructure(‘file’, ‘tab’, ‘time_row_or_col’, ‘cell’)

pysd.external.ExtData(…)

GetLookupsStructure(‘file’, ‘tab’, ‘x_row_or_col’, ‘cell’)

pysd.external.ExtLookup(…)

GetLookupsStructure(‘file’, ‘tab’, ‘x_row_or_col’, ‘cell’)

pysd.external.ExtLookup(…)

GetConstantsStructure(‘file’, ‘tab’, ‘cell’)

pysd.external.ExtConstant(…)

GetConstantsStructure(‘file’, ‘tab’, ‘cell’)

pysd.external.ExtConstant(…)

Namespace manager

class pysd.builders.python.namespace.NamespaceManager(parameters: List[str] = [])[source]

NamespaceManager object allows includying new elements to the namespace and searching for elements in the namespace. When includying new elements a Python safe name is used to be able to write the equations.

Parameters:

parameters (list (optional)) – List of the parameters that are used as argument in the Macro. By defaukt it is an empty list.

add_to_namespace(string: str) None[source]

Add a new string to the namespace.

Parameters:

string (str) – String to add to the namespace.

Return type:

None

make_python_identifier(string: str, prefix: str = None, add_to_namespace: bool = False) str[source]

Takes an arbitrary string and creates a valid Python identifier.

If the Python identifier created is already in the namespace, but the input string is not (ie, two similar strings resolve to the same Python identifier) or if the identifier is a reserved word in the reserved_words list, or is a Python default reserved word, adds _1, or if _1 is in the namespace, _2, etc.

Parameters:
  • string (str) – The text to be converted into a valid Python identifier.

  • prefix (str or None (optional)) – If given it will be used as a prefix for the output string. Default is None.

  • add_to_namespace (bool (optional)) – If True it will add the passed string to the namespace and to the cleanspace. Default is False.

Returns:

identifier – A vaild Python identifier based on the input string.

Return type:

str

Examples

>>> make_python_identifier('Capital')
'capital'
>>> make_python_identifier('multiple words')
'multiple_words'
>>> make_python_identifier('multiple     spaces')
'multiple_spaces'

When the name is a Python keyword, add ‘_1’ to differentiate it >>> make_python_identifier(‘for’) ‘for_1’

Remove leading and trailing whitespace >>> make_python_identifier(’ whitespace ‘) ‘whitespace’

Remove most special characters outright: >>> make_python_identifier(‘H@t tr!ck’) ‘ht_trck’

add valid string to leading digits >>> make_python_identifier(‘123abc’) ‘nvs_123abc’

already in namespace >>> make_python_identifier(‘Var$’) # namespace={‘Var$’: ‘var’} ‘var’

namespace conflicts >>> make_python_identifier(‘Var@’) # namespace={‘Var$’: ‘var’} ‘var_1’

>>> make_python_identifier('Var$')  # namespace={'Var@': 'var',
...                                              'Var%':'var_1'}
'var_2'

References

Identifiers must follow the convention outlined here:

https://docs.python.org/2/reference/lexical_analysis.html#identifiers

get_original_name(identifier)[source]

Search for the original name of a variable’s Python identifier.

Parameters:
  • identifier (str) – It should be a value in the namespace.

  • Rerturns

  • --------

  • original_name (str) – The original name of the variable.

Subscript manager

class pysd.builders.python.subscripts.SubscriptManager(abstract_subscripts: List[AbstractSubscriptRange], _root: Path)[source]

SubscriptManager object allows saving the subscripts included in the Section, searching for elements or keys and simplifying them.

Parameters:
  • abstrac_subscripts (list) – List of the AbstractSubscriptRanges comming from the AbstractModel.

  • _root (pathlib.Path) – Path to the model file. Needed to read subscript ranges from Excel files.

make_coord_dict(subs: List[str]) dict[source]

This is for assisting with the lookup of a particular element.

Parameters:

subs (list of strings) – Coordinates, either as names of dimensions, or positions within a dimension.

Returns:

coordinates – Coordinates needed to access the xarray quantities we are interested in.

Return type:

dict

Examples

>>> sm = SubscriptManager([], Path(''))
>>> sm._subscripts = {
...     'Dim1': ['A', 'B', 'C'],
...     'Dim2': ['A', 'B', 'C', 'D']}
>>> sm.make_coord_dict(['Dim1', 'D'])
{'Dim1': ['A', 'B', 'C'], 'Dim2': ['D']}
>>> sm.make_coord_dict(['A'])
{'Dim1': ['A']}
>>> sm.make_coord_dict(['A', 'B'])
{'Dim1': ['A'], 'Dim2': ['B']}
>>> sm.make_coord_dict(['A', 'Dim1'])
{'Dim2': ['A'], 'Dim1': ['A', 'B', 'C']}
make_merge_list(subs_list: List[List[str]], element: str = '') List[str][source]

This is for assisting when building xrmerge. From a list of subscript lists returns the final subscript list after merging. Necessary when merging variables with subscripts comming from different definitions.

Parameters:
  • subs_list (list of lists of strings) – Coordinates, either as names of dimensions, or positions within a dimension.

  • element (str (optional)) – Element name, if given it will be printed with any error or warning message. Default is “”.

Returns:

dims – Final subscripts after merging.

Return type:

list

Examples

>>> sm = SubscriptManager([], Path(''))
>>> sm._subscripts = {"upper": ["A", "B"], "all": ["A", "B", "C"]}
>>> sm.make_merge_list([['A'], ['B']])
['upper']
>>> sm.make_merge_list([['A'], ['B'], ['C']])
['all']
>>> sm.make_merge_list([['upper'], ['C']])
['all']
>>> sm.make_merge_list([['A'], ['C']])
['all']
simplify_subscript_input(coords: dict, merge_subs: List[str] = None) tuple[source]

Simplifies the subscripts input to avoid printing the coordinates list when the _subscript_dict can be used. Makes model code more simple.

Parameters:
  • coords (dict) – Coordinates to write in the model file.

  • merge_subs (list of strings or None (optional)) – List of the final subscript range of the Python array after merging with other objects. If None the merge_subs will be taken from coords. Default is None.

Returns:

final_subs, coords – Final subscripts and the equations to generate the coord dicttionary in the model file.

Return type:

dict, str

Examples

>>> sm = SubscriptManager([], Path(''))
>>> sm._subscripts = {
...     "dim": ["A", "B", "C"],
...     "dim2": ["A", "B", "C", "D"]}
>>> sm.simplify_subscript_input({"dim": ["A", "B", "C"]})
({"dim": ["A", "B", "C"]}, "{'dim': _subscript_dict['dim']}"
>>> sm.simplify_subscript_input({"dim": ["A", "B", "C"]}, ["dim2"])
({"dim2": ["A", "B", "C"]}, "{'dim2': _subscript_dict['dim']}"
>>> sm.simplify_subscript_input({"dim": ["A", "B"]})
({"dim": ["A", "B"]}, "{'dim': ['A', 'B']}"

Imports manager

class pysd.builders.python.imports.ImportsManager[source]

Class to save the imported modules information for intelligent import

add(module: str, function: str | None = None) None[source]

Add a function from module.

Parameters:
  • module (str) – module name.

  • function (str or None) – function name. If None module will be set to true.

get_header(outfile: str) str[source]

Returns the importing information to print in the model file

Parameters:

outfile (str) – Name of the outfile to print in the header.

Returns:

text – Header of the translated model file.

Return type:

str