Coverage for bim2sim/elements/mapping/condition.py: 57%
87 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-12 13:34 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-12 13:34 +0000
1"""Module for validating an element by a condition"""
2import logging
4from bim2sim.elements.mapping.units import ureg
7class Condition:
8 """Class for validating an element by a condition"""
10 _logger = None
12 def __init__(self, name, critical_for_creation=True):
13 self.name = name
14 self.critical_for_creation = critical_for_creation
16 @property
17 def logger(self):
18 """logger instance"""
19 if not Condition._logger:
20 Condition._logger = logging.getLogger(__name__)
21 return Condition._logger
23 def check(self, element, value):
24 pass
27class RangeCondition(Condition):
28 """"Validate through a simple ValueRange
30 Args:
31 key: attribute of the element to validate
32 value_min: minimum allowed value
33 value_max: maximum allowed value
34 incl_edges: if True, the value_min and value_max are valid as well
35 critical_for_creation: if True, the element will not be created if the validation fails
36 Return:
37 True if valid, False if not valid
38 """
40 def __init__(self, key: str, value_min, value_max, incl_edges: bool = False,
41 critical_for_creation: bool = True):
42 super().__init__(key, critical_for_creation)
43 self.key = key
44 self.valueMin = value_min
45 self.valueMax = value_max
46 self.incl_edges = incl_edges
47 self.critical_for_creation = critical_for_creation
49 def check(self, element, value):
50 if value is None:
51 return False
52 if not isinstance(value, (list, set)):
53 value = [value]
54 check_list = []
55 for v in value:
56 if self.incl_edges:
57 check_list.append(False if not v or v <= self.valueMin
58 or v >= self.valueMax else True)
59 else:
60 check_list.append(False if not v or v < self.valueMin
61 or v > self.valueMax else True)
62 return all(check_list)
65class ListCondition(Condition):
66 """Validate if a list has elements, or a specific number of elements
68 Args:
69 key: attribute of the element to validate
70 values: list of allowed values
71 critical_for_creation: if True, the element will not be created if the
72 validation fails
73 Return:
74 True if valid, False if not valid
75 """
77 def __init__(self, key: str, list_length: int = None,
78 critical_for_creation: bool = True):
79 super().__init__(key, critical_for_creation)
80 self.key = key
81 self.listLength = list_length
82 self.critical_for_creation = critical_for_creation
84 def check(self, element, value):
85 if type(value) is not list:
86 return False
87 if self.listLength is None:
88 return True if len(value) > 0 else False
89 else:
90 return True if len(value) == self.listLength else False
93class ThicknessCondition(Condition):
94 def __init__(self, key: str,
95 threshold: ureg.Quantity = 0,
96 critical_for_creation: bool = True):
97 super().__init__(key, critical_for_creation)
98 self.key = key
99 self.threshold = threshold
100 self.critical_for_creation = critical_for_creation
102 def check(self, element, value):
103 if value is None:
104 return False
105 value_from_layers = sum(layer.thickness for layer in element.layers)
106 if not value_from_layers:
107 return False
108 if not self.threshold:
109 return True if value == value_from_layers else False
110 discrepancy = abs(value - value_from_layers) / value
111 return True if discrepancy <= self.threshold else False
114class UValueCondition(Condition):
115 def __init__(self, key: str,
116 threshold: ureg.Quantity = 0,
117 critical_for_creation: bool = True):
118 super().__init__(key, critical_for_creation)
119 self.key = key
120 self.threshold = threshold
121 self.critical_for_creation = critical_for_creation
123 def check(self, element, value):
124 if value is None:
125 return False
126 value_from_layers = self.get_u_value_from_layers(element.layerset)
127 if not value_from_layers:
128 return False
129 if not self.threshold:
130 return True if value == value_from_layers else False
131 discrepancy = abs(value - value_from_layers) / value
132 return True if discrepancy <= self.threshold else False
134 @staticmethod
135 def get_u_value_from_layers(layer_set):
136 layers_r = 0
137 for layer in layer_set.layers:
138 if layer.thickness:
139 if layer.material.thermal_conduc and \
140 layer.material.thermal_conduc > 0:
141 layers_r += layer.thickness / layer.material.thermal_conduc
143 if layers_r > 0:
144 return 1 / layers_r
145 return None