|
9 | 9 | import numpy as np |
10 | 10 | from numpy._typing import NDArray |
11 | 11 |
|
| 12 | +from pyvcell._internal.simdata.python_infix import get_numexpr_expression |
12 | 13 | from pyvcell.sim_results.var_types import NDArray1D |
13 | 14 |
|
14 | 15 | PYTHON_ENDIANNESS: Literal["little", "big"] = "big" |
@@ -350,23 +351,23 @@ def get_data(self, variable: VariableInfo | str, time: float) -> NDArray1D: |
350 | 351 | class NamedFunction: |
351 | 352 | name: str |
352 | 353 | vcell_expression: str |
353 | | - python_expression: str |
| 354 | + num_expr_expression: str |
354 | 355 | variables: list[str] |
355 | 356 | variable_type: VariableType |
356 | 357 |
|
357 | 358 | def __init__(self, name: str, vcell_expression: str, variable_type: VariableType) -> None: |
358 | 359 | self.name = name |
359 | 360 | self.vcell_expression = vcell_expression |
360 | | - self.python_expression = vcell_expression.replace("^", "**").lstrip(" ").rstrip(" ") |
| 361 | + self.num_expr_expression = get_numexpr_expression(self.vcell_expression) |
361 | 362 | self.variable_type = variable_type |
362 | 363 |
|
363 | 364 | # Parse the python expression into an AST and extract all Name nodes (which represent variables) |
364 | | - tree = ast.parse(self.python_expression) |
| 365 | + tree = ast.parse(self.num_expr_expression) |
365 | 366 | self.variables = [node.id for node in ast.walk(tree) if isinstance(node, ast.Name)] |
366 | 367 |
|
367 | 368 | def evaluate(self, variable_bindings: dict[str, NDArray[np.float64]]) -> NDArray[np.float64]: |
368 | 369 | ne.set_num_threads(1) |
369 | | - expression = self.python_expression |
| 370 | + expression = self.num_expr_expression |
370 | 371 | result = ne.evaluate(expression, local_dict=variable_bindings) |
371 | 372 | if not isinstance(result, np.ndarray): |
372 | 373 | raise TypeError(f"Expression {expression} did not evaluate to a numpy array") |
|
0 commit comments