fosanalysis
A framework to evaluate distributed fiber optic sensor data
Loading...
Searching...
No Matches
cracks.py
Go to the documentation of this file.
2r"""
3Contains class definitions for Crack and CrackList.
4\author Bertram Richter
5\date 2022
6"""
7
8import warnings
9
10import numpy as np
11import copy
12
13
14class Crack():
15 r"""
16 A Crack object presents a crack in concrete with its properties.
17 The attributes of a Crack object are additionally exposed in a
18 special `dict`-like interface
19 The `dict`-like interface should be preferred over calling the
20 attributes directly.
21 Querying an unset (or nonexistant) attribute using the `dict`-like
22 interface returns `None` without raising an error.
23 Hence, attributes explicitely set to `None` or nonexitant report the same.
24 In this context, `None` means "N/A, no answer or not available".
25 """
26 def __init__(self,
27 location: float = None,
28 index: int = None,
29 x_l: float = None,
30 x_r: float = None,
31 max_strain: float = None,
32 width: float = None,
33 **kwargs):
34 r"""
35 Constructs a Crack object.
36 \param location \copybrief location For more, see \ref location.
37 \param index \copybrief index For more, see \ref index.
38 \param x_l \copybrief x_l For more, see \ref x_l.
39 \param x_r \copybrief x_r For more, see \ref x_r.
40 \param max_strain \copybrief max_strain For more, see \ref max_strain.
41 \param width \copybrief width For more, see \ref width.
42 \param **kwargs Additional keyword arguments, stored as attributes ().
43 """
44
45 self.index = index
46
47 self.location = location
48
49 self.x_l = x_l
50
51 self.x_r = x_r
52
54 self.width = width
55
56 self.max_strain = max_strain
57 for key, value in kwargs.items():
58 self[key] = value
59 def __getitem__(self, key):
60 return getattr(self, key, None)
61 def __setitem__(self, key, value):
62 return setattr(self, key, value)
63 def __delitem__(self, key):
64 try:
65 delattr(self, key)
66 except:
67 pass
68 @property
69 def lt(self):
70 r"""
71 Returns the length of the transfer length.
72 """
73 try:
74 return self["x_r"] - self["x_l"]
75 except:
76 return None
77 @property
78 def lt_l(self):
79 r""" Distance from the crack position to the left-hand side end of its transfer length. """
80 try:
81 return self["location"] - self["x_l"]
82 except:
83 return None
84 @property
85 def lt_r(self):
86 r""" Distance from the crack position to the right-hand side end of its transfer length. """
87 try:
88 return self["x_r"] - self["location"]
89 except:
90 return None
91 @property
92 def segment(self):
93 r"""
94 Returns the absolute influence segment of the crack.
95 """
96 try:
97 return self["x_l"], self["x_r"]
98 except:
99 None
100
101class CrackList(list):
102 r"""
103 List of crack objects.
104 """
105 def __init__(self, *crack_list):
106 r"""
107 Constructs a CrackList.
108 \param crack_list Data, from which the CrackList is constructed.
109 Possible arguments :
110 - any number of \ref Crack objects,
111 - \ref Crack objects wrapped in a `list`, `tuple` or `set`,
112 - \ref CrackList object (same as above)
113 """
114 if len(crack_list) == 1 and hasattr(crack_list[0], "__iter__"):
115 crack_list = crack_list[0]
116 assert all([isinstance(entry, Crack) for entry in crack_list]) \
117 or len(crack_list) == 0, "At least one entry is not a Crack!"
118 super().__init__(crack_list)
119 @property
120 def x_l(self) -> list:
121 r""" Returns a list with the left-hand side border of transfer length of all cracks. """
122 return self.get_attribute_list("x_l")
123 @property
124 def x_r(self) -> list:
125 r""" Returns a list with the right-hand side border of transfer length of all cracks. """
126 return self.get_attribute_list("x_r")
127 @property
128 def locations(self) -> list:
129 r""" Returns a list with the locations of all cracks. """
130 return self.get_attribute_list("location")
131 @property
132 def max_strains(self) -> list:
133 r""" Returns a list with the peak strains of all cracks. """
134 return self.get_attribute_list("max_strain")
135 @property
136 def widths(self) -> list:
137 r""" Returns a list with the widths of all cracks. """
138 return self.get_attribute_list("width")
139 def get_attribute_list(self, attribute: str) -> list:
140 r"""
141 Extract a list of values from the given attribute of all cracks.
142 \param attribute Name of the attribute to extract.
143 If the attribute of the crack object is not set, `None` is reported instead.
144 """
145 return [crack[attribute] for crack in self]
147 *locations: tuple,
148 tol: float = None,
149 method: str = "nearest",
150 make_copy: bool = True,
151 placeholder: bool = False,
152 ):
153 r"""
154 Get a list of \ref Crack according to the given list of positions `locations` and the `method`.
155 \param locations Locations along the sensor to get cracks at.
156 \param tol Tolerance in location difference, to take a Crack into account.
157 Only used with `method = "nearest"`.
158 Defaults to `None`, which is turned off.
159 \param method Method how the cracks are selected.
160 Available methods:
161 - `"nearest"` (default): adds the crack to the CrackList,
162 for which the distance between the location of the crack
163 and the entry in `locations` is the smallest among all cracks.
164 - `"lt"`: returns the first crack, for which holds:
165 \f$x_{\mathrm{t,l}} < x \leq x_{\mathrm{t,r}}\f$.
166 \param make_copy If set to `True`, independent copies are returned.
167 Defaults to `False`.
168 \param placeholder Switch to report `None`, when no suitable Crack is found.
169 Defaults to `False`, which is no replacement.
170 \return Returns a \ref CrackList.
171 """
172 selected_crack_list = CrackList()
173 if method == "nearest":
174 crack_locations = self.get_attribute_list("location")
175 crack_locations = np.array([entry if entry is not None else float("nan") for entry in crack_locations])
176 if not np.any(np.isfinite(crack_locations)):
177 return selected_crack_list
178 for loc in locations:
179 dist = np.array(np.abs(loc - crack_locations))
180 min_index = np.nanargmin(dist)
181 if tol is None or dist[min_index] <= tol:
182 selected_crack_list.append(self[min_index])
183 elif placeholder:
184 selected_crack_list.append(None)
185 elif method == "lt":
186 for loc in locations:
187 found_crack = None
188 for crack in self:
189 try:
190 if crack["x_l"] < loc <= crack["x_r"]:
191 found_crack = crack
192 break
193 except:
194 pass
195 if found_crack is not None or placeholder:
196 selected_crack_list.append(found_crack)
197 else:
198 raise ValueError("`method` '{}' unknown for getting a crack from CrackList.".format(method))
199 if make_copy:
200 return copy.deepcopy(selected_crack_list)
201 else:
202 return selected_crack_list
204 attribute: str = "location",
205 minimum: float = -np.inf,
206 maximum: float = np.inf,
207 make_copy: bool = True,
208 ):
209 r"""
210 Get a list of \ref Crack objects according to the given attribute.
211 \param attribute Name of the relevant attribute.
212 \param minimum Threshold for the minimum accepted value of the attribute.
213 \param maximum Threshold for the maximum accepted value of the attribute.
214 \param make_copy if true, a deepcopy of the CrackList is returned.
215 \return Returns a \ref CrackList.
216 If no crack satisfies the condition, an empty CrackList is returned.
217 """
218 selected_crack_list = CrackList()
219 for crack in self:
220 try:
221 if minimum <= crack[attribute] <= maximum:
222 selected_crack_list.append(crack)
223 except:
224 pass
225 if make_copy:
226 return copy.deepcopy(selected_crack_list)
227 else:
228 return selected_crack_list
230 attribute: str,
231 make_copy: bool = True,
232 ):
233 r"""
234 Get a list of \ref Crack whose `attribute` is None.
235 \param attribute Name of the relevant attribute.
236 \param make_copy If true, a deepcopy of the CrackList is returned.
237 \return Returns a \ref CrackList.
238 If no crack satisfies the condition, an empty CrackList is returned.
239 """
240 selected_crack_list = CrackList()
241 crack_attribute = self.get_attribute_list(attribute)
242 for i, attr in enumerate(crack_attribute):
243 if attr is None:
244 selected_crack_list.append(self[i])
245 if make_copy:
246 return copy.deepcopy(selected_crack_list)
247 else:
248 return selected_crack_list
250 attribute: str,
251 make_copy: bool = True,
252 ):
253 r"""
254 Sets the attribute to `None` for each \ref Crack object contained.
255 """
256 if make_copy:
257 new_cracklist = copy.deepcopy(self)
258 for crack_object in new_cracklist:
259 del crack_object[attribute]
260 return new_cracklist
261 else:
262 for crack_object in self:
263 del crack_object[attribute]
264 return self
265 def sort(self, attribute: str = "location"):
266 r"""
267 Sort the list of \ref Crack according to the given attribute.
268 \param attribute Name of the relevant attribute.
269 """
270 orig_order = self.get_attribute_list(attribute)
271 index_list = np.argsort(orig_order)
272 self.__init__(*(self[i] for i in index_list))
A Crack object presents a crack in concrete with its properties.
Definition cracks.py:14
__init__(self, float location=None, int index=None, float x_l=None, float x_r=None, float max_strain=None, float width=None, **kwargs)
Constructs a Crack object.
Definition cracks.py:33
lt_r(self)
Distance from the crack position to the right-hand side end of its transfer length.
Definition cracks.py:85
index
Position index in the sanitized measurement data of strainprofile.StrainProfile (e....
Definition cracks.py:45
segment(self)
Returns the absolute influence segment of the crack.
Definition cracks.py:92
lt(self)
Returns the length of the transfer length.
Definition cracks.py:69
x_r
Absolute location right-hand side end of its transfer length.
Definition cracks.py:51
lt_l(self)
Distance from the crack position to the left-hand side end of its transfer length.
Definition cracks.py:78
x_l
Absolute location left-hand side end of its transfer length.
Definition cracks.py:49
max_strain
The strain in the fibre-optical sensor at the location.
Definition cracks.py:56
location
Absolute location (e.g.,\ in meters) along the fibre optical sensor.
Definition cracks.py:47
width
The opening width of the crack.
Definition cracks.py:54
list get_attribute_list(self, str attribute)
Extract a list of values from the given attribute of all cracks.
Definition cracks.py:139
sort(self, str attribute="location")
Sort the list of Crack according to the given attribute.
Definition cracks.py:265
list widths(self)
Returns a list with the widths of all cracks.
Definition cracks.py:136
list max_strains(self)
Returns a list with the peak strains of all cracks.
Definition cracks.py:132
list locations(self)
Returns a list with the locations of all cracks.
Definition cracks.py:128
get_cracks_attribute_by_range(self, str attribute="location", float minimum=-np.inf, float maximum=np.inf, bool make_copy=True)
Get a list of Crack objects according to the given attribute.
Definition cracks.py:208
list x_r(self)
Returns a list with the right-hand side border of transfer length of all cracks.
Definition cracks.py:124
list x_l(self)
Returns a list with the left-hand side border of transfer length of all cracks.
Definition cracks.py:120
get_cracks_attribute_is_none(self, str attribute, bool make_copy=True)
Get a list of Crack whose attribute is None.
Definition cracks.py:232
get_cracks_by_location(self, *tuple locations, float tol=None, str method="nearest", bool make_copy=True, bool placeholder=False)
Definition cracks.py:152
__init__(self, *crack_list)
Constructs a CrackList.
Definition cracks.py:105
clear_attribute(self, str attribute, bool make_copy=True)
Sets the attribute to None for each Crack object contained.
Definition cracks.py:252