Coverage for bim2sim/elements/mapping/condition.py: 57%
87 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 17:09 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 17:09 +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
36 validation fails
37 Return:
38 True if valid, False if not valid
39 """
41 def __init__(self, key: str, value_min, value_max, incl_edges: bool = False,
42 critical_for_creation: bool = True):
43 super().__init__(key, critical_for_creation)
44 self.key = key
45 self.valueMin = value_min
46 self.valueMax = value_max
47 self.incl_edges = incl_edges
48 self.critical_for_creation = critical_for_creation
50 def check(self, element, value):
51 if value is None:
52 return False
53 if not isinstance(value, (list, set)):
54 value = [value]
55 check_list = []
56 for v in value:
57 if self.incl_edges:
58 check_list.append(False if not v or v <= self.valueMin
59 or v >= self.valueMax else True)
60 else:
61 check_list.append(False if not v or v < self.valueMin
62 or v > self.valueMax else True)
63 return all(check_list)
66class ListCondition(Condition):
67 """Validate if a list has elements, or a specific number of elements
69 Args:
70 key: attribute of the element to validate
71 values: list of allowed values
72 critical_for_creation: if True, the element will not be created if the
73 validation fails
74 Return:
75 True if valid, False if not valid
76 """
78 def __init__(self, key: str, list_length: int = None,
79 critical_for_creation: bool = True):
80 super().__init__(key, critical_for_creation)
81 self.key = key
82 self.listLength = list_length
83 self.critical_for_creation = critical_for_creation
85 def check(self, element, value):
86 if type(value) is not list:
87 return False
88 if self.listLength is None:
89 return True if len(value) > 0 else False
90 else:
91 return True if len(value) == self.listLength else False
94class ThicknessCondition(Condition):
95 def __init__(self, key: str,
96 threshold: ureg.Quantity = 0,
97 critical_for_creation: bool = True):
98 super().__init__(key, critical_for_creation)
99 self.key = key
100 self.threshold = threshold
101 self.critical_for_creation = critical_for_creation
103 def check(self, element, value):
104 if value is None:
105 return False
106 value_from_layers = sum(layer.thickness for layer in element.layers)
107 if not value_from_layers:
108 return False
109 if not self.threshold:
110 return True if value == value_from_layers else False
111 discrepancy = abs(value - value_from_layers) / value
112 return True if discrepancy <= self.threshold else False
115class UValueCondition(Condition):
116 def __init__(self, key: str,
117 threshold: ureg.Quantity = 0,
118 critical_for_creation: bool = True):
119 super().__init__(key, critical_for_creation)
120 self.key = key
121 self.threshold = threshold
122 self.critical_for_creation = critical_for_creation
124 def check(self, element, value):
125 if value is None:
126 return False
127 value_from_layers = self.get_u_value_from_layers(element.layerset)
128 if not value_from_layers:
129 return False
130 if not self.threshold:
131 return True if value == value_from_layers else False
132 discrepancy = abs(value - value_from_layers) / value
133 return True if discrepancy <= self.threshold else False
135 @staticmethod
136 def get_u_value_from_layers(layer_set):
137 layers_r = 0
138 for layer in layer_set.layers:
139 if layer.thickness:
140 if layer.material.thermal_conduc and \
141 layer.material.thermal_conduc > 0:
142 layers_r += layer.thickness / layer.material.thermal_conduc
144 if layers_r > 0:
145 return 1 / layers_r
146 return None