Coverage for physioblocks / simulation / saved_quantities.py: 82%

33 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-09 16:40 +0100

1# SPDX-FileCopyrightText: Copyright INRIA 

2# 

3# SPDX-License-Identifier: LGPL-3.0-only 

4# 

5# Copyright INRIA 

6# 

7# This file is part of PhysioBlocks, a library mostly developed by the 

8# [Ananke project-team](https://team.inria.fr/ananke) at INRIA. 

9# 

10# Authors: 

11# - Colin Drieu 

12# - Dominique Chapelle 

13# - François Kimmig 

14# - Philippe Moireau 

15# 

16# PhysioBlocks is free software: you can redistribute it and/or modify it under the 

17# terms of the GNU Lesser General Public License as published by the Free Software 

18# Foundation, version 3 of the License. 

19# 

20# PhysioBlocks is distributed in the hope that it will be useful, but WITHOUT ANY 

21# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 

22# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 

23# 

24# You should have received a copy of the GNU Lesser General Public License along with 

25# PhysioBlocks. If not, see <https://www.gnu.org/licenses/>. 

26 

27""" 

28Define a register to hold **SavedQuantities** during the simulation. 

29""" 

30 

31from __future__ import annotations 

32 

33from collections.abc import Generator 

34from typing import Any 

35 

36from physioblocks.computing.models import Expression, ModelComponent 

37from physioblocks.computing.quantities import Quantity 

38 

39 

40class SavedQuantities: 

41 """ 

42 Register holding saved quantities. 

43 """ 

44 

45 _saved_quantities: dict[str, Quantity[Any]] 

46 _quantities_expressions: dict[str, tuple[Expression, ModelComponent, int, int]] 

47 

48 def __init__(self) -> None: 

49 self._saved_quantities = {} 

50 self._quantities_expressions = {} 

51 

52 def __contains__(self, quantity_id: str) -> bool: 

53 return quantity_id in self._saved_quantities 

54 

55 def __getitem__(self, quantity_id: str) -> Quantity[Any]: 

56 """ 

57 Get the saved quantity 

58 

59 :param quantity_id: the quantity global name. 

60 :type quantity_id: str 

61 

62 :return: the saved quantity 

63 :rtype: Quantity 

64 """ 

65 return self._saved_quantities[quantity_id] 

66 

67 def items(self) -> Generator[tuple[str, Quantity[Any]], None, None]: 

68 yield from self._saved_quantities.items() 

69 

70 def values(self) -> Generator[Quantity[Any], None, None]: 

71 yield from self._saved_quantities.values() 

72 

73 def __iter__(self) -> Generator[str, None, None]: 

74 yield from self._saved_quantities 

75 

76 def update(self) -> None: 

77 """ 

78 Update all saved quantities using their 

79 :class:`~physioblocks.computing.models.Expression` object. 

80 """ 

81 for quantity_id, ( 

82 expression, 

83 model, 

84 size, 

85 index, 

86 ) in self._quantities_expressions.items(): 

87 if size == 1: 

88 self._saved_quantities[quantity_id].initialize( 

89 expression.expr_func(model) 

90 ) 

91 else: 

92 self._saved_quantities[quantity_id].initialize( 

93 expression.expr_func(model)[index : index + size] # type: ignore 

94 ) 

95 

96 def register( 

97 self, 

98 quantity_id: str, 

99 expression: Expression, 

100 model: ModelComponent, 

101 size: int, 

102 index: int, 

103 ) -> None: 

104 """ 

105 Register a **Saved Quantity** with its expression and model. 

106 

107 :param quantity_id: the global saved quantity name 

108 :type quantity_id: str 

109 

110 :param expression: the expression to use for the quantity 

111 :type expression: Expression 

112 

113 :param model: the model declaring the expression 

114 :type model: ModelComponent 

115 """ 

116 self._quantities_expressions[quantity_id] = (expression, model, size, index) 

117 # initialise quantity to 0 

118 init_value = [0.0] * size if size > 1 else 0.0 

119 self._saved_quantities[quantity_id] = Quantity(init_value) 

120 

121 def unregister(self, quantity_id: str) -> None: 

122 """ 

123 Unregister a saved quantity 

124 

125 :param quantity_id: the quantity global name to unregister 

126 :type quantity_id: str 

127 """ 

128 self._saved_quantities.pop(quantity_id) 

129 self._quantities_expressions.pop(quantity_id)