sensotwin.defect_placement.configuration
1from collections import defaultdict, Counter 2from .. import read_vtt, write_vtt 3from ..store_connection import LocalStoreConnection, FusekiConnection, StoreConnection 4from pyiron_base import HasHDF 5import numpy as np 6import pandas as pd 7from abc import ABC, abstractmethod 8 9class InputDefect(ABC): 10 """Base class for all defect types, only used to search for available defect types via __subclasses__. 11 12 Attributes: 13 type_id: every subclass must have unique integer id, creating an uninterruped serial starting from 1 to total number of subclasses 14 """ 15 type_id = 0 16 _id = None 17 @abstractmethod 18 def __init__(self): 19 pass 20 21 @abstractmethod 22 def generate_display_label(self): 23 pass 24 25 @abstractmethod 26 def generate_ontology_label(self, set_id, iter_id): 27 pass 28 29 @abstractmethod 30 def generate_store_insert_stub(self): 31 pass 32 33 @staticmethod 34 @abstractmethod 35 def get_all_entries_from_store(conn): 36 pass 37 38 def get_cell_id(self) -> int: 39 """Return cell position of defect.""" 40 return self._cell_id 41 42 def get_layer_id(self) -> int: 43 """Return layer position of defect.""" 44 return self._layer_id 45 46 @staticmethod 47 def get_id_from_ontology_iri(label) -> int: 48 """Extract defect id from full ontology instance iri.""" 49 return int(label.split("_")[-1]) 50 51 @staticmethod 52 def get_set_id_from_ontology_iri(label) -> int: 53 """Extract input set id from full ontology instance iri.""" 54 return int(label.split("_")[-2]) 55 56 57class PlyWavinessDefect(InputDefect): 58 """Ply waviness defect. 59 60 Attributes: 61 type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set 62 display_name: Human readable name of defect type for legends 63 display_color: tuple of RGB color values scaled from 0 to 1 64 """ 65 data = None 66 type_id = 1 67 display_name = "Ply Waviness" 68 display_color = (200 / 256, 200 / 256, 0 / 256) 69 70 def __init__(self, cell_id: int=None, layer_id: int=None, orientation: float=None, length: float=None, amplitude: float=None): 71 """Initialize object. 72 73 Args: 74 cell_id: integer cell id from 3D mesh of wind turbine 75 layer_id: integer layer id from 3D mesh of wind turbine 76 orientation: orientation of waviness in ° 77 length: length of waviness in m 78 amplitude: amplitude of waviness in m 79 """ 80 self._cell_id = cell_id 81 self._layer_id = layer_id 82 self._orientation = orientation 83 self._length = length 84 self._amplitude = amplitude 85 86 def generate_display_label(self): 87 """Return string display for object in list displays.""" 88 return "{}, O: {}°, L: {}m, A: {}m".format(self.display_name, self._orientation, self._length, self._amplitude) 89 90 def generate_ontology_label(self, set_id: int, iter_id: int) -> str: 91 """Generate ontology instance iri from object. 92 93 Args: 94 set_id: id of input set this defect belongs to 95 iter_id: unique id of defect within this specific input set 96 97 Returns: 98 relative iri of ontology instance 99 """ 100 return "__PlyWavinessDefect_{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id) 101 102 def generate_store_insert_stub(self, uniq_id: str) -> str: 103 """Generate SPARQL stub for inserting this object in a multi INSERT query. 104 105 Args: 106 uniq_id: unique string identifier with a combination of input set and defect ids 107 108 Returns: 109 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 110 """ 111 return """ 112 senso:__PlyWavinessDefect_{uniq_id} a senso:PlyWavinessDefect ; 113 senso:defectOrientation {orientation} ; 114 senso:defectLength {length} ; 115 senso:defectAmplitude {amplitude} ; 116 senso:hasCellNumber {cell_id} ; 117 senso:hasLayerNumber {layer_id} . 118 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id, orientation=self._orientation, length=self._length, amplitude=self._amplitude) 119 120 @staticmethod 121 def get_all_entries_from_store(conn: StoreConnection) -> dict: 122 """Get all instances of PlyWavinessDefect from store connection passed during initialization. 123 124 Args: 125 conn: Any subclass instance of StoreConnection 126 Returns: 127 dict of int -> PlyWavinessDefect 128 """ 129 query = """ 130 SELECT ?x ?cell_number ?layer_number ?orientation ?length ?amplitude 131 WHERE { 132 ?x a senso:PlyWavinessDefect . 133 ?x senso:defectOrientation ?orientation . 134 ?x senso:defectLength ?length . 135 ?x senso:defectAmplitude ?amplitude . 136 ?x senso:hasCellNumber ?cell_number . 137 ?x senso:hasLayerNumber ?layer_number . 138 } 139 """ 140 result = {} 141 for x in conn.get_data(query): 142 result[x[0]] = PlyWavinessDefect(cell_id=int(x[1]), layer_id=int(x[2]), orientation=float(x[3]), length=float(x[4]), amplitude=float(x[5])) 143 return result 144 145 def to_simulation_input_dict(self) -> dict: 146 """Return dict representation of object intended for input into process simulation.""" 147 return { 148 "type": self.display_name, 149 "cell_id": self._cell_id, 150 "layer_id": self._layer_id, 151 "absolute_local_ply_orientation": self._orientation, 152 "amplitude": self._amplitude, 153 "length": self._length 154 } 155 156 def __str__(self): 157 return "{} (Type ID {}) in cell {}, layer {}, data TBA".format(self.display_name, self.type_id, self._cell_id, self._layer_id) 158 159 def __repr__(self): 160 return "PlyWavinessDefect(cell_id={cell_id}, layer_id={layer_id}, orientation={orientation}, length={length}, amplitude={amplitude})".format( 161 cell_id = self._cell_id, 162 layer_id = self._layer_id, 163 orientation = self._orientation, 164 length = self._length, 165 amplitude = self._amplitude) 166 167 168class PlyMisorientationDefect(InputDefect): 169 """Defect for different fibre angle in layer than intended. 170 171 Attributes: 172 type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set 173 display_name: Human readable name of defect type for legends 174 display_color: tuple of RGB color values scaled from 0 to 1 175 """ 176 data = None 177 type_id = 2 178 display_name = "Ply Misorientation" 179 display_color = (12 / 256, 238 / 256, 246 / 256) 180 181 def __init__(self, cell_id: int=None, layer_id: int=None, angle: float=None): 182 """Initialize object. 183 184 Args: 185 cell_id: integer cell id from 3D mesh of wind turbine 186 layer_id: integer layer id from 3D mesh of wind turbine 187 angle: relative deviation from intended angle in ° 188 """ 189 self._cell_id = cell_id 190 self._layer_id = layer_id 191 self._angle = angle 192 193 def generate_display_label(self) -> str: 194 """Return string display for object in list displays.""" 195 return "{}, Offset: {}°".format(self.display_name, self._angle) 196 197 def generate_ontology_label(self, set_id: int, iter_id: int) -> str: 198 """Generate ontology instance iri from object. 199 200 Args: 201 set_id: id of input set this defect belongs to 202 iter_id: unique id of defect within this specific input set 203 204 Returns: 205 relative iri of ontology instance 206 """ 207 return "__PlyMisorientationDefect_{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id) 208 209 def generate_store_insert_stub(self, uniq_id: str) -> str: 210 """Generate SPARQL stub for inserting this object in a multi INSERT query. 211 212 Args: 213 uniq_id: unique string identifier with a combination of input set and defect ids 214 215 Returns: 216 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 217 """ 218 return """ 219 senso:__PlyMisorientationDefect_{uniq_id} a senso:PlyMisorientationDefect ; 220 co:value {angle} ; 221 senso:hasCellNumber {cell_id} ; 222 senso:hasLayerNumber {layer_id} . 223 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id, angle=self._angle) 224 225 @staticmethod 226 def get_all_entries_from_store(conn: StoreConnection) -> dict: 227 """Get all instances of PlyMisorientationDefect from store connection passed during initialization. 228 229 Args: 230 conn: Any subclass instance of StoreConnection 231 Returns: 232 dict of int -> PlyMisorientationDefect 233 """ 234 query = """ 235 SELECT ?x ?angle ?cell_number ?layer_number 236 WHERE { 237 ?x a senso:PlyMisorientationDefect . 238 ?x co:value ?angle . 239 ?x senso:hasCellNumber ?cell_number . 240 ?x senso:hasLayerNumber ?layer_number . 241 } 242 """ 243 result = {} 244 for x in conn.get_data(query): 245 result[x[0]] = PlyMisorientationDefect(cell_id=int(x[2]), layer_id=int(x[3]), angle=float(x[1])) 246 return result 247 248 def to_simulation_input_dict(self) -> dict: 249 """Return dict representation of object intended for input into process simulation.""" 250 return { 251 "type": self.display_name, 252 "cell_id": self._cell_id, 253 "layer_id": self._layer_id, 254 "local_angular_deviation": self._angle 255 } 256 257 def __str__(self): 258 return "{} (Type ID {}) in cell {}, layer {}, data TBA".format(self.display_name, self.type_id, self._cell_id, self._layer_id) 259 260 def __repr__(self): 261 return "PlyMisorientationDefect(cell_id={cell_id}, layer_id={layer_id}, angle={angle})".format(cell_id = self._cell_id, layer_id = self._layer_id, angle = self._angle) 262 263 264class MissingPlyDefect(InputDefect): 265 """Defect for an entire layer missing. 266 267 Attributes: 268 type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set 269 display_name: Human readable name of defect type for legends 270 display_color: tuple of RGB color values scaled from 0 to 1 271 """ 272 data = None 273 type_id = 3 274 display_name = "Missing Ply" 275 display_color = (25 / 256, 248 / 256, 5 / 256) 276 277 def __init__(self, cell_id: int=None, layer_id: int=None): 278 """Initialize object. 279 280 Args: 281 cell_id: integer cell id from 3D mesh of wind turbine 282 layer_id: integer layer id from 3D mesh of wind turbine 283 """ 284 self._cell_id = cell_id 285 self._layer_id = layer_id 286 287 def generate_display_label(self) -> str: 288 """Return string display for object in list displays.""" 289 return "{}, Ply missing".format(self.display_name) 290 291 def generate_ontology_label(self, set_id, iter_id): 292 """Generate ontology instance iri from object. 293 294 Args: 295 set_id: id of input set this defect belongs to 296 iter_id: unique id of defect within this specific input set 297 298 Returns: 299 relative iri of ontology instance 300 """ 301 return "__MissingPlyDefect_{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id) 302 303 def generate_store_insert_stub(self, uniq_id: str) -> str: 304 """Generate SPARQL stub for inserting this object in a multi INSERT query. 305 306 Args: 307 uniq_id: unique string identifier with a combination of input set and defect ids 308 309 Returns: 310 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 311 """ 312 return """ 313 senso:__MissingPlyDefect_{uniq_id} a senso:MissingPlyDefect ; 314 senso:hasCellNumber {cell_id} ; 315 senso:hasLayerNumber {layer_id} . 316 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id) 317 318 @staticmethod 319 def get_all_entries_from_store(conn: StoreConnection) -> dict: 320 """Get all instances of MissingPlyDefect from store connection passed during initialization. 321 322 Args: 323 conn: Any subclass instance of StoreConnection 324 Returns: 325 dict of int -> MissingPlyDefect 326 """ 327 query = """ 328 SELECT ?x ?cell_number ?layer_number 329 WHERE { 330 ?x a senso:MissingPlyDefect . 331 ?x senso:hasCellNumber ?cell_number . 332 ?x senso:hasLayerNumber ?layer_number . 333 } 334 """ 335 result = {} 336 for x in conn.get_data(query): 337 result[x[0]] = MissingPlyDefect(cell_id=int(x[1]), layer_id=int(x[2])) 338 return result 339 340 def to_simulation_input_dict(self) -> dict: 341 """Return dict representation of object intended for input into process simulation.""" 342 return { 343 "type": self.display_name, 344 "cell_id": self._cell_id, 345 "layer_id": self._layer_id, 346 } 347 348 def __str__(self): 349 return "{} (Type ID {}) in cell {}, layer {}, data TBA".format(self.display_name, self.type_id, self._cell_id, self._layer_id) 350 351 def __repr__(self): 352 return "MissingPlyDefect(cell_id={cell_id}, layer_id={layer_id})".format(cell_id = self._cell_id, layer_id = self._layer_id) 353 354 355class VaryingThicknessDefect(InputDefect): 356 """Defect for a different layer thickness than intended. 357 358 Attributes: 359 type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set 360 display_name: Human readable name of defect type for legends 361 display_color: tuple of RGB color values scaled from 0 to 1 362 """ 363 data = None 364 type_id = 4 365 display_name = "Varying Thickness" 366 display_color = (255 / 256, 130 / 256, 3 / 256) 367 368 def __init__(self, cell_id: int=None, layer_id: int=None, fvc: float=None): 369 self._cell_id = cell_id 370 self._layer_id = layer_id 371 self._fvc = fvc 372 373 def generate_display_label(self) -> str: 374 """Return string display for object in list displays.""" 375 return "{}, {}% FVC".format(self.display_name, self._fvc) 376 377 def generate_ontology_label(self, set_id: int, iter_id: int) -> str: 378 """Generate ontology instance iri from object. 379 380 Args: 381 set_id: id of input set this defect belongs to 382 iter_id: unique id of defect within this specific input set 383 384 Returns: 385 relative iri of ontology instance 386 """ 387 return "__VaryingThicknessDefect__{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id) 388 389 def generate_store_insert_stub(self, uniq_id: str) -> str: 390 """Generate SPARQL stub for inserting this object in a multi INSERT query. 391 392 Args: 393 uniq_id: unique string identifier with a combination of input set and defect ids 394 395 Returns: 396 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 397 """ 398 return """ 399 senso:__VaryingThicknessDefect_{uniq_id} a senso:VaryingThicknessDefect ; 400 co:value {fvc} ; 401 senso:hasCellNumber {cell_id} ; 402 senso:hasLayerNumber {layer_id} . 403 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id, fvc=self._fvc) 404 405 @staticmethod 406 def get_all_entries_from_store(conn: StoreConnection) -> dict: 407 """Get all instances of VaryingThicknessDefect from store connection passed during initialization. 408 409 Args: 410 conn: Any subclass instance of StoreConnection 411 Returns: 412 dict of int -> VaryingThicknessDefect 413 """ 414 query = """ 415 SELECT ?x ?fvc ?cell_number ?layer_number 416 WHERE { 417 ?x a senso:VaryingThicknessDefect . 418 ?x co:value ?fvc . 419 ?x senso:hasCellNumber ?cell_number . 420 ?x senso:hasLayerNumber ?layer_number . 421 } 422 """ 423 result = {} 424 for x in conn.get_data(query): 425 result[x[0]] = VaryingThicknessDefect(cell_id=int(x[2]), layer_id=int(x[3]), fvc=float(x[1])) 426 return result 427 428 def to_simulation_input_dict(self) -> dict: 429 """Return dict representation of object intended for input into process simulation.""" 430 return { 431 "type": self.display_name, 432 "cell_id": self._cell_id, 433 "layer_id": self._layer_id, 434 "fvc": self._fvc 435 } 436 437 def __str__(self): 438 return "{} (Type ID {}) in cell {}, layer {}, data TBA".format(self.display_name, self.type_id, self._cell_id, self._layer_id) 439 440 def __repr__(self): 441 return "VaryingThicknessDefect(cell_id={cell_id}, layer_id={layer_id}, fvc={fvc})".format(cell_id = self._cell_id, layer_id = self._layer_id, fvc = self._fvc) 442 443 444class DefectInputDataSet(HasHDF): 445 """Input data set for future simulation containing placed defects. 446 447 Contains all info for a single simulation concerning deviations from the standard 3D model 448 Information is sorted according to cell id of the 3D model first and then layer information of 449 composite material markup second, individual defects are instances of an InputDefect subclass; 450 implements pyiron HasHDF interface for automatic HDF5 serialization during job execution for storage 451 """ 452 def __init__(self, uniq_id: int=None, defects: list=None, conn: StoreConnection=None): 453 """Initialize empty internal data storage object""" 454 self._defect_data = {} 455 self._id = uniq_id 456 self._store_connection = conn 457 if defects: 458 for defect in defects: 459 self.add_defect_to_cell(defect.get_cell_id(), defect.get_layer_id(), defect) 460 461 def get_id(self): 462 """Return id of input data set, can be None if object not saved to data storage yet""" 463 return self._id 464 465 def get_defects_of_cell(self, cell_id: int) -> dict: 466 """Return all defects for specified cell 467 468 Args: 469 cell_id: unique cell id of associated 3D model 470 471 Returns: 472 dict of layer id to defect dicts (defect id => defect object) 473 """ 474 if cell_id not in self._defect_data: 475 return {} 476 else: 477 return self._defect_data[cell_id] 478 479 def add_defect_to_cell(self, cell_id: int, layer_id: int, defect: InputDefect): 480 """Add 1 defect,overwriting any existing defect of this specific InputDefect subclass. 481 482 Args: 483 cell_id: unique cell id of associated 3D model 484 layer_id: id of layer in material of defect 485 defect: child class of InputDefect containing defect data 486 """ 487 if cell_id not in self._defect_data: 488 self._defect_data[cell_id] = {} 489 if layer_id not in self._defect_data[cell_id]: 490 self._defect_data[cell_id][layer_id] = {} 491 self._defect_data[cell_id][layer_id][defect.type_id] = defect 492 493 def clear_defects_of_cell(self, cell_id: int): 494 """Remove all defects of specific cell""" 495 if cell_id in self._defect_data: 496 self._defect_data.pop(cell_id) 497 498 def generate_input_file(self): 499 print("generate the calculix input file i guess") 500 501 def generate_defect_display_summary(self) -> dict: 502 """Generate summary containing ids of all cells with defects and list of contained defect types, disregarding layer information. 503 504 Returns: 505 dictionary containing list of cells of with defects and list of defect types per cell 506 """ 507 summary = { 508 "defect_cells": list(self._defect_data.keys()), 509 "cell_defect_types": {} 510 } 511 for vtk_id, layers in self._defect_data.items(): 512 summary["cell_defect_types"][vtk_id] = [] 513 for layer_id, layer_data in layers.items(): 514 summary["cell_defect_types"][vtk_id].extend(layer_data.keys()) 515 summary["cell_defect_types"][vtk_id] = list(set(summary["cell_defect_types"][vtk_id])) 516 return summary 517 518 def generate_input_set_display_label(self) -> str: 519 """Return string display for object in list displays.""" 520 summ = self.get_defects() 521 c = Counter([x.type_id for x in summ]) 522 occurence_string = ", ".join(["{}: {}".format(value, count) for value, count in c.most_common()]) 523 return "Total: {} | {}".format(c.total(), occurence_string) 524 525 def get_defects(self) -> list: 526 """Get all defect objects of input set 527 528 Returns: 529 list of InputDefect objects 530 """ 531 defects = [] 532 for _, cell_data in self._defect_data.items(): 533 for _, layer_data in cell_data.items(): 534 for defect_id, defect in layer_data.items(): 535 defects.append(defect) 536 return defects 537 538 @staticmethod 539 def get_available_defect_types() -> list: 540 """Return all subclasses of the class InputDefect""" 541 return InputDefect.__subclasses__() 542 543 def generate_ontology_label(self) -> str: 544 """Generate ontology instance iri from object.""" 545 return "__DefectPlacementInputSet_{}".format(self._id) 546 547 @staticmethod 548 def get_id_from_ontology_iri(label: str) -> int: 549 """Extract id from full ontology instance iri.""" 550 return int(label.split("_")[-1]) 551 552 def generate_store_insert_stub(self, uniq_id): 553 return """ 554 senso:__DefectPlacementInputSet_{uniq_id} a senso:DefectPlacementInputSet . 555 """.format(uniq_id=uniq_id) 556 557 def save_entry_to_store(self, set_id: int): 558 """Save object to store connection passed during initialization.""" 559 self._id = set_id 560 label = self.generate_ontology_label() 561 insert_stubs = [self.generate_store_insert_stub(self._id)] 562 for i, defect in enumerate(self.get_defects()): 563 new_id = "{}_{}".format(self._id, i) 564 insert_stubs.append(defect.generate_store_insert_stub(new_id)) 565 query = """ 566 INSERT {{ 567 {stubs} 568 }} WHERE {{ }} 569 """.format(stubs="\n".join(insert_stubs)) 570 self._store_connection.update_data(query) 571 572 @staticmethod 573 def get_all_entries_from_store(conn: StoreConnection) -> dict: 574 """Get all instances of DefectInputDataSet from store connection passed during initialization. 575 576 Args: 577 conn: Any subclass instance of StoreConnection 578 Returns: 579 dict of int -> DefectInputDataSet 580 """ 581 defects = {} 582 for defect_type in DefectInputDataSet.get_available_defect_types(): 583 defects[defect_type.__name__] = defect_type.get_all_entries_from_store(conn) 584 query = """ 585 SELECT DISTINCT ?x 586 WHERE { 587 ?x a senso:DefectPlacementInputSet . 588 } 589 """ 590 result = {} 591 for x in conn.get_data(query): 592 uniq_id = DefectInputDataSet.get_id_from_ontology_iri(x[0]) 593 result[uniq_id] = DefectInputDataSet(uniq_id=uniq_id, conn=conn) 594 for defect_type, defect_dict in defects.items(): 595 for iri, defect in defect_dict.items(): 596 set_id = defect.get_set_id_from_ontology_iri(iri) 597 result[set_id].add_defect_to_cell(defect.get_cell_id(), defect.get_layer_id(), defect) 598 return result 599 600 def __str__(self): 601 summ = self.get_defects() 602 c = Counter([x.display_name for x in summ]) 603 occurence_string = ", ".join(["{}: {}".format(value, count) for value, count in c.most_common()]) 604 return "DefectInputDataSet ID {} with {} defects: {}".format(self._id, c.total(), occurence_string) 605 606 def __repr__(self): 607 return "DefectInputDataSet(uniq_id={uniq_id}, defects={defects}, conn={conn})".format(uniq_id=self._id,defects=repr(self.get_defects()),conn=repr(self._store_connection)) 608 609 def _to_hdf(self, hdf=None, group_name=None): 610 with hdf.open("defect_placement_input_data") as hdf_store: 611 hdf_store["_id"] = self._id 612 hdf_store["_defects"] = repr(self.get_defects()) 613 hdf_store["_store_connection"] = repr(self._store_connection) 614 615 def _from_hdf(self, hdf=None, version=None): 616 pass 617 618 def from_hdf_args(hdf): 619 with hdf.open("defect_placement_input_data") as hdf_store: 620 arg_dict = { 621 "uniq_id": hdf_store["_id"], 622 "defects": eval(hdf_store["_defects"]), 623 "conn": eval(hdf_store["_store_connection"]) 624 } 625 return arg_dict 626 627 628class CellLayersDataSet: 629 """Data set containing information about layer structure of all cells. 630 631 reads data from .vtt file containing information about the different layers for each cell of the 3D model 632 expects vtk table structure according to following definition: 633 634 "element_label": int (id of associated cell), starting at 1 635 "layer_id": int (id of layer, unique per cell) 636 "layer_material": str (layer material name) 637 "layer_thickness_mm": float (thickness of layer in mm) 638 "layer_angle_deg": int (angle of fiber alignment in °, [-90 to 90]) 639 640 """ 641 NECESSARY_KEYS = ["element_label", "layer_id", "layer_material", "layer_thickness_mm", "layer_angle_deg"] 642 def __init__(self, vtt_path: str): 643 """Initialise data set from file and check if necessary columns are present. 644 645 Args: 646 vtt_path: full or relative path of .vtt file containing cell information table 647 """ 648 self._file_path = vtt_path 649 self._dataframe = read_vtt.get_dataframe(self._file_path) 650 self.check_data_source() 651 self._dataframe.layer_material.replace(to_replace={"SAERTEX-U-E-SKIN": "GLASS-U-E-SKIN","SAERTEX-U-E-WEB": "GLASS-U-E-WEB", "E-LT-5500(UD)": "GLASS-UD"}, inplace=True) 652 653 def get_available_layers_for_cell(self, cell_id: int) -> pd.DataFrame: 654 """Return dataframe containing the data subset of the passed cell_id """ 655 return self._dataframe.loc[self._dataframe.element_label == cell_id] 656 657 def get_layer_of_cell(self, cell_id: int, layer_id: int) -> pd.DataFrame: 658 """Return one specific entry to dataset with the correct combination of cell id and layer id""" 659 return self._dataframe.loc[(self._dataframe.element_label == cell_id) & (self._dataframe.layer_id == layer_id)].iloc[0] 660 661 def check_data_source(self): 662 """Check if data source contains all necessary keys. 663 664 Raises: 665 KeyError: If any key as defined in NECESSARY_KEYS is not found 666 ValueError: If serial ids in element_label do not start with 1 667 """ 668 for key in self.NECESSARY_KEYS: 669 if key not in self._dataframe: 670 raise KeyError("'{}' not found in input data '{}'".format(key, self._file_path)) 671 if self._dataframe["element_label"].min() != 1: 672 raise ValueError("Serial IDs in 'element_label' need to start at 1, minimum value found: {}".format(self._dataframe["element_label"].min())) 673 674 def __str__(self): 675 return "CellLayersDataSet with {} cells with up to {} layers per cell".format(len(self._dataframe["element_label"].unique()), len(self._dataframe["layer_id"].unique())) 676 677 def __repr__(self): 678 return self.__str__() 679 680 681def get_material_color(name: str) -> str: 682 """Get color for specific layer in matplotlib material layup display.""" 683 color_dict = defaultdict(lambda: 'white') 684 color_dict['gelcoat'] = 'red' 685 color_dict['GELCOAT'] = 'red' 686 color_dict['SNL(Triax)'] = 'green' 687 color_dict['saertex(DB)'] = 'blue' 688 color_dict['foam'] = 'yellow' 689 color_dict['FOAM'] = 'yellow' 690 color_dict['Carbon(UD)'] = 'cyan' 691 color_dict['CARBON(UD)'] = 'cyan' 692 color_dict['E-LT-5500(UD)'] = 'salmon' 693 color_dict["GLASS-UD"] = 'salmon' 694 color_dict['E-LT-5500(UD)-SKIN'] = 'orange' 695 color_dict['GLASS-TRIAX'] = 'orange' 696 color_dict['E-LT-5500(UD)-WEB'] = 'peachpuff' 697 color_dict['SAERTEX-U-E-SKIN'] = 'orange' 698 color_dict['SAERTEX-U-E-WEB'] = 'peachpuff' 699 color_dict['GLASS-U-E-SKIN'] = 'orange' 700 color_dict['GLASS-U-E-WEB'] = 'peachpuff' 701 return color_dict[name]
10class InputDefect(ABC): 11 """Base class for all defect types, only used to search for available defect types via __subclasses__. 12 13 Attributes: 14 type_id: every subclass must have unique integer id, creating an uninterruped serial starting from 1 to total number of subclasses 15 """ 16 type_id = 0 17 _id = None 18 @abstractmethod 19 def __init__(self): 20 pass 21 22 @abstractmethod 23 def generate_display_label(self): 24 pass 25 26 @abstractmethod 27 def generate_ontology_label(self, set_id, iter_id): 28 pass 29 30 @abstractmethod 31 def generate_store_insert_stub(self): 32 pass 33 34 @staticmethod 35 @abstractmethod 36 def get_all_entries_from_store(conn): 37 pass 38 39 def get_cell_id(self) -> int: 40 """Return cell position of defect.""" 41 return self._cell_id 42 43 def get_layer_id(self) -> int: 44 """Return layer position of defect.""" 45 return self._layer_id 46 47 @staticmethod 48 def get_id_from_ontology_iri(label) -> int: 49 """Extract defect id from full ontology instance iri.""" 50 return int(label.split("_")[-1]) 51 52 @staticmethod 53 def get_set_id_from_ontology_iri(label) -> int: 54 """Extract input set id from full ontology instance iri.""" 55 return int(label.split("_")[-2])
Base class for all defect types, only used to search for available defect types via __subclasses__.
Attributes: type_id: every subclass must have unique integer id, creating an uninterruped serial starting from 1 to total number of subclasses
43 def get_layer_id(self) -> int: 44 """Return layer position of defect.""" 45 return self._layer_id
Return layer position of defect.
58class PlyWavinessDefect(InputDefect): 59 """Ply waviness defect. 60 61 Attributes: 62 type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set 63 display_name: Human readable name of defect type for legends 64 display_color: tuple of RGB color values scaled from 0 to 1 65 """ 66 data = None 67 type_id = 1 68 display_name = "Ply Waviness" 69 display_color = (200 / 256, 200 / 256, 0 / 256) 70 71 def __init__(self, cell_id: int=None, layer_id: int=None, orientation: float=None, length: float=None, amplitude: float=None): 72 """Initialize object. 73 74 Args: 75 cell_id: integer cell id from 3D mesh of wind turbine 76 layer_id: integer layer id from 3D mesh of wind turbine 77 orientation: orientation of waviness in ° 78 length: length of waviness in m 79 amplitude: amplitude of waviness in m 80 """ 81 self._cell_id = cell_id 82 self._layer_id = layer_id 83 self._orientation = orientation 84 self._length = length 85 self._amplitude = amplitude 86 87 def generate_display_label(self): 88 """Return string display for object in list displays.""" 89 return "{}, O: {}°, L: {}m, A: {}m".format(self.display_name, self._orientation, self._length, self._amplitude) 90 91 def generate_ontology_label(self, set_id: int, iter_id: int) -> str: 92 """Generate ontology instance iri from object. 93 94 Args: 95 set_id: id of input set this defect belongs to 96 iter_id: unique id of defect within this specific input set 97 98 Returns: 99 relative iri of ontology instance 100 """ 101 return "__PlyWavinessDefect_{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id) 102 103 def generate_store_insert_stub(self, uniq_id: str) -> str: 104 """Generate SPARQL stub for inserting this object in a multi INSERT query. 105 106 Args: 107 uniq_id: unique string identifier with a combination of input set and defect ids 108 109 Returns: 110 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 111 """ 112 return """ 113 senso:__PlyWavinessDefect_{uniq_id} a senso:PlyWavinessDefect ; 114 senso:defectOrientation {orientation} ; 115 senso:defectLength {length} ; 116 senso:defectAmplitude {amplitude} ; 117 senso:hasCellNumber {cell_id} ; 118 senso:hasLayerNumber {layer_id} . 119 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id, orientation=self._orientation, length=self._length, amplitude=self._amplitude) 120 121 @staticmethod 122 def get_all_entries_from_store(conn: StoreConnection) -> dict: 123 """Get all instances of PlyWavinessDefect from store connection passed during initialization. 124 125 Args: 126 conn: Any subclass instance of StoreConnection 127 Returns: 128 dict of int -> PlyWavinessDefect 129 """ 130 query = """ 131 SELECT ?x ?cell_number ?layer_number ?orientation ?length ?amplitude 132 WHERE { 133 ?x a senso:PlyWavinessDefect . 134 ?x senso:defectOrientation ?orientation . 135 ?x senso:defectLength ?length . 136 ?x senso:defectAmplitude ?amplitude . 137 ?x senso:hasCellNumber ?cell_number . 138 ?x senso:hasLayerNumber ?layer_number . 139 } 140 """ 141 result = {} 142 for x in conn.get_data(query): 143 result[x[0]] = PlyWavinessDefect(cell_id=int(x[1]), layer_id=int(x[2]), orientation=float(x[3]), length=float(x[4]), amplitude=float(x[5])) 144 return result 145 146 def to_simulation_input_dict(self) -> dict: 147 """Return dict representation of object intended for input into process simulation.""" 148 return { 149 "type": self.display_name, 150 "cell_id": self._cell_id, 151 "layer_id": self._layer_id, 152 "absolute_local_ply_orientation": self._orientation, 153 "amplitude": self._amplitude, 154 "length": self._length 155 } 156 157 def __str__(self): 158 return "{} (Type ID {}) in cell {}, layer {}, data TBA".format(self.display_name, self.type_id, self._cell_id, self._layer_id) 159 160 def __repr__(self): 161 return "PlyWavinessDefect(cell_id={cell_id}, layer_id={layer_id}, orientation={orientation}, length={length}, amplitude={amplitude})".format( 162 cell_id = self._cell_id, 163 layer_id = self._layer_id, 164 orientation = self._orientation, 165 length = self._length, 166 amplitude = self._amplitude)
Ply waviness defect.
Attributes: type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set display_name: Human readable name of defect type for legends display_color: tuple of RGB color values scaled from 0 to 1
71 def __init__(self, cell_id: int=None, layer_id: int=None, orientation: float=None, length: float=None, amplitude: float=None): 72 """Initialize object. 73 74 Args: 75 cell_id: integer cell id from 3D mesh of wind turbine 76 layer_id: integer layer id from 3D mesh of wind turbine 77 orientation: orientation of waviness in ° 78 length: length of waviness in m 79 amplitude: amplitude of waviness in m 80 """ 81 self._cell_id = cell_id 82 self._layer_id = layer_id 83 self._orientation = orientation 84 self._length = length 85 self._amplitude = amplitude
Initialize object.
Args: cell_id: integer cell id from 3D mesh of wind turbine layer_id: integer layer id from 3D mesh of wind turbine orientation: orientation of waviness in ° length: length of waviness in m amplitude: amplitude of waviness in m
87 def generate_display_label(self): 88 """Return string display for object in list displays.""" 89 return "{}, O: {}°, L: {}m, A: {}m".format(self.display_name, self._orientation, self._length, self._amplitude)
Return string display for object in list displays.
91 def generate_ontology_label(self, set_id: int, iter_id: int) -> str: 92 """Generate ontology instance iri from object. 93 94 Args: 95 set_id: id of input set this defect belongs to 96 iter_id: unique id of defect within this specific input set 97 98 Returns: 99 relative iri of ontology instance 100 """ 101 return "__PlyWavinessDefect_{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id)
Generate ontology instance iri from object.
Args: set_id: id of input set this defect belongs to iter_id: unique id of defect within this specific input set
Returns: relative iri of ontology instance
103 def generate_store_insert_stub(self, uniq_id: str) -> str: 104 """Generate SPARQL stub for inserting this object in a multi INSERT query. 105 106 Args: 107 uniq_id: unique string identifier with a combination of input set and defect ids 108 109 Returns: 110 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 111 """ 112 return """ 113 senso:__PlyWavinessDefect_{uniq_id} a senso:PlyWavinessDefect ; 114 senso:defectOrientation {orientation} ; 115 senso:defectLength {length} ; 116 senso:defectAmplitude {amplitude} ; 117 senso:hasCellNumber {cell_id} ; 118 senso:hasLayerNumber {layer_id} . 119 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id, orientation=self._orientation, length=self._length, amplitude=self._amplitude)
Generate SPARQL stub for inserting this object in a multi INSERT query.
Args: uniq_id: unique string identifier with a combination of input set and defect ids
Returns: SPARQL insert statement without INSERT, PREFIXES or WHERE clause
121 @staticmethod 122 def get_all_entries_from_store(conn: StoreConnection) -> dict: 123 """Get all instances of PlyWavinessDefect from store connection passed during initialization. 124 125 Args: 126 conn: Any subclass instance of StoreConnection 127 Returns: 128 dict of int -> PlyWavinessDefect 129 """ 130 query = """ 131 SELECT ?x ?cell_number ?layer_number ?orientation ?length ?amplitude 132 WHERE { 133 ?x a senso:PlyWavinessDefect . 134 ?x senso:defectOrientation ?orientation . 135 ?x senso:defectLength ?length . 136 ?x senso:defectAmplitude ?amplitude . 137 ?x senso:hasCellNumber ?cell_number . 138 ?x senso:hasLayerNumber ?layer_number . 139 } 140 """ 141 result = {} 142 for x in conn.get_data(query): 143 result[x[0]] = PlyWavinessDefect(cell_id=int(x[1]), layer_id=int(x[2]), orientation=float(x[3]), length=float(x[4]), amplitude=float(x[5])) 144 return result
Get all instances of PlyWavinessDefect from store connection passed during initialization.
Args: conn: Any subclass instance of StoreConnection Returns: dict of int -> PlyWavinessDefect
146 def to_simulation_input_dict(self) -> dict: 147 """Return dict representation of object intended for input into process simulation.""" 148 return { 149 "type": self.display_name, 150 "cell_id": self._cell_id, 151 "layer_id": self._layer_id, 152 "absolute_local_ply_orientation": self._orientation, 153 "amplitude": self._amplitude, 154 "length": self._length 155 }
Return dict representation of object intended for input into process simulation.
Inherited Members
169class PlyMisorientationDefect(InputDefect): 170 """Defect for different fibre angle in layer than intended. 171 172 Attributes: 173 type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set 174 display_name: Human readable name of defect type for legends 175 display_color: tuple of RGB color values scaled from 0 to 1 176 """ 177 data = None 178 type_id = 2 179 display_name = "Ply Misorientation" 180 display_color = (12 / 256, 238 / 256, 246 / 256) 181 182 def __init__(self, cell_id: int=None, layer_id: int=None, angle: float=None): 183 """Initialize object. 184 185 Args: 186 cell_id: integer cell id from 3D mesh of wind turbine 187 layer_id: integer layer id from 3D mesh of wind turbine 188 angle: relative deviation from intended angle in ° 189 """ 190 self._cell_id = cell_id 191 self._layer_id = layer_id 192 self._angle = angle 193 194 def generate_display_label(self) -> str: 195 """Return string display for object in list displays.""" 196 return "{}, Offset: {}°".format(self.display_name, self._angle) 197 198 def generate_ontology_label(self, set_id: int, iter_id: int) -> str: 199 """Generate ontology instance iri from object. 200 201 Args: 202 set_id: id of input set this defect belongs to 203 iter_id: unique id of defect within this specific input set 204 205 Returns: 206 relative iri of ontology instance 207 """ 208 return "__PlyMisorientationDefect_{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id) 209 210 def generate_store_insert_stub(self, uniq_id: str) -> str: 211 """Generate SPARQL stub for inserting this object in a multi INSERT query. 212 213 Args: 214 uniq_id: unique string identifier with a combination of input set and defect ids 215 216 Returns: 217 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 218 """ 219 return """ 220 senso:__PlyMisorientationDefect_{uniq_id} a senso:PlyMisorientationDefect ; 221 co:value {angle} ; 222 senso:hasCellNumber {cell_id} ; 223 senso:hasLayerNumber {layer_id} . 224 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id, angle=self._angle) 225 226 @staticmethod 227 def get_all_entries_from_store(conn: StoreConnection) -> dict: 228 """Get all instances of PlyMisorientationDefect from store connection passed during initialization. 229 230 Args: 231 conn: Any subclass instance of StoreConnection 232 Returns: 233 dict of int -> PlyMisorientationDefect 234 """ 235 query = """ 236 SELECT ?x ?angle ?cell_number ?layer_number 237 WHERE { 238 ?x a senso:PlyMisorientationDefect . 239 ?x co:value ?angle . 240 ?x senso:hasCellNumber ?cell_number . 241 ?x senso:hasLayerNumber ?layer_number . 242 } 243 """ 244 result = {} 245 for x in conn.get_data(query): 246 result[x[0]] = PlyMisorientationDefect(cell_id=int(x[2]), layer_id=int(x[3]), angle=float(x[1])) 247 return result 248 249 def to_simulation_input_dict(self) -> dict: 250 """Return dict representation of object intended for input into process simulation.""" 251 return { 252 "type": self.display_name, 253 "cell_id": self._cell_id, 254 "layer_id": self._layer_id, 255 "local_angular_deviation": self._angle 256 } 257 258 def __str__(self): 259 return "{} (Type ID {}) in cell {}, layer {}, data TBA".format(self.display_name, self.type_id, self._cell_id, self._layer_id) 260 261 def __repr__(self): 262 return "PlyMisorientationDefect(cell_id={cell_id}, layer_id={layer_id}, angle={angle})".format(cell_id = self._cell_id, layer_id = self._layer_id, angle = self._angle)
Defect for different fibre angle in layer than intended.
Attributes: type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set display_name: Human readable name of defect type for legends display_color: tuple of RGB color values scaled from 0 to 1
182 def __init__(self, cell_id: int=None, layer_id: int=None, angle: float=None): 183 """Initialize object. 184 185 Args: 186 cell_id: integer cell id from 3D mesh of wind turbine 187 layer_id: integer layer id from 3D mesh of wind turbine 188 angle: relative deviation from intended angle in ° 189 """ 190 self._cell_id = cell_id 191 self._layer_id = layer_id 192 self._angle = angle
Initialize object.
Args: cell_id: integer cell id from 3D mesh of wind turbine layer_id: integer layer id from 3D mesh of wind turbine angle: relative deviation from intended angle in °
194 def generate_display_label(self) -> str: 195 """Return string display for object in list displays.""" 196 return "{}, Offset: {}°".format(self.display_name, self._angle)
Return string display for object in list displays.
198 def generate_ontology_label(self, set_id: int, iter_id: int) -> str: 199 """Generate ontology instance iri from object. 200 201 Args: 202 set_id: id of input set this defect belongs to 203 iter_id: unique id of defect within this specific input set 204 205 Returns: 206 relative iri of ontology instance 207 """ 208 return "__PlyMisorientationDefect_{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id)
Generate ontology instance iri from object.
Args: set_id: id of input set this defect belongs to iter_id: unique id of defect within this specific input set
Returns: relative iri of ontology instance
210 def generate_store_insert_stub(self, uniq_id: str) -> str: 211 """Generate SPARQL stub for inserting this object in a multi INSERT query. 212 213 Args: 214 uniq_id: unique string identifier with a combination of input set and defect ids 215 216 Returns: 217 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 218 """ 219 return """ 220 senso:__PlyMisorientationDefect_{uniq_id} a senso:PlyMisorientationDefect ; 221 co:value {angle} ; 222 senso:hasCellNumber {cell_id} ; 223 senso:hasLayerNumber {layer_id} . 224 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id, angle=self._angle)
Generate SPARQL stub for inserting this object in a multi INSERT query.
Args: uniq_id: unique string identifier with a combination of input set and defect ids
Returns: SPARQL insert statement without INSERT, PREFIXES or WHERE clause
226 @staticmethod 227 def get_all_entries_from_store(conn: StoreConnection) -> dict: 228 """Get all instances of PlyMisorientationDefect from store connection passed during initialization. 229 230 Args: 231 conn: Any subclass instance of StoreConnection 232 Returns: 233 dict of int -> PlyMisorientationDefect 234 """ 235 query = """ 236 SELECT ?x ?angle ?cell_number ?layer_number 237 WHERE { 238 ?x a senso:PlyMisorientationDefect . 239 ?x co:value ?angle . 240 ?x senso:hasCellNumber ?cell_number . 241 ?x senso:hasLayerNumber ?layer_number . 242 } 243 """ 244 result = {} 245 for x in conn.get_data(query): 246 result[x[0]] = PlyMisorientationDefect(cell_id=int(x[2]), layer_id=int(x[3]), angle=float(x[1])) 247 return result
Get all instances of PlyMisorientationDefect from store connection passed during initialization.
Args: conn: Any subclass instance of StoreConnection Returns: dict of int -> PlyMisorientationDefect
249 def to_simulation_input_dict(self) -> dict: 250 """Return dict representation of object intended for input into process simulation.""" 251 return { 252 "type": self.display_name, 253 "cell_id": self._cell_id, 254 "layer_id": self._layer_id, 255 "local_angular_deviation": self._angle 256 }
Return dict representation of object intended for input into process simulation.
Inherited Members
265class MissingPlyDefect(InputDefect): 266 """Defect for an entire layer missing. 267 268 Attributes: 269 type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set 270 display_name: Human readable name of defect type for legends 271 display_color: tuple of RGB color values scaled from 0 to 1 272 """ 273 data = None 274 type_id = 3 275 display_name = "Missing Ply" 276 display_color = (25 / 256, 248 / 256, 5 / 256) 277 278 def __init__(self, cell_id: int=None, layer_id: int=None): 279 """Initialize object. 280 281 Args: 282 cell_id: integer cell id from 3D mesh of wind turbine 283 layer_id: integer layer id from 3D mesh of wind turbine 284 """ 285 self._cell_id = cell_id 286 self._layer_id = layer_id 287 288 def generate_display_label(self) -> str: 289 """Return string display for object in list displays.""" 290 return "{}, Ply missing".format(self.display_name) 291 292 def generate_ontology_label(self, set_id, iter_id): 293 """Generate ontology instance iri from object. 294 295 Args: 296 set_id: id of input set this defect belongs to 297 iter_id: unique id of defect within this specific input set 298 299 Returns: 300 relative iri of ontology instance 301 """ 302 return "__MissingPlyDefect_{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id) 303 304 def generate_store_insert_stub(self, uniq_id: str) -> str: 305 """Generate SPARQL stub for inserting this object in a multi INSERT query. 306 307 Args: 308 uniq_id: unique string identifier with a combination of input set and defect ids 309 310 Returns: 311 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 312 """ 313 return """ 314 senso:__MissingPlyDefect_{uniq_id} a senso:MissingPlyDefect ; 315 senso:hasCellNumber {cell_id} ; 316 senso:hasLayerNumber {layer_id} . 317 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id) 318 319 @staticmethod 320 def get_all_entries_from_store(conn: StoreConnection) -> dict: 321 """Get all instances of MissingPlyDefect from store connection passed during initialization. 322 323 Args: 324 conn: Any subclass instance of StoreConnection 325 Returns: 326 dict of int -> MissingPlyDefect 327 """ 328 query = """ 329 SELECT ?x ?cell_number ?layer_number 330 WHERE { 331 ?x a senso:MissingPlyDefect . 332 ?x senso:hasCellNumber ?cell_number . 333 ?x senso:hasLayerNumber ?layer_number . 334 } 335 """ 336 result = {} 337 for x in conn.get_data(query): 338 result[x[0]] = MissingPlyDefect(cell_id=int(x[1]), layer_id=int(x[2])) 339 return result 340 341 def to_simulation_input_dict(self) -> dict: 342 """Return dict representation of object intended for input into process simulation.""" 343 return { 344 "type": self.display_name, 345 "cell_id": self._cell_id, 346 "layer_id": self._layer_id, 347 } 348 349 def __str__(self): 350 return "{} (Type ID {}) in cell {}, layer {}, data TBA".format(self.display_name, self.type_id, self._cell_id, self._layer_id) 351 352 def __repr__(self): 353 return "MissingPlyDefect(cell_id={cell_id}, layer_id={layer_id})".format(cell_id = self._cell_id, layer_id = self._layer_id)
Defect for an entire layer missing.
Attributes: type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set display_name: Human readable name of defect type for legends display_color: tuple of RGB color values scaled from 0 to 1
278 def __init__(self, cell_id: int=None, layer_id: int=None): 279 """Initialize object. 280 281 Args: 282 cell_id: integer cell id from 3D mesh of wind turbine 283 layer_id: integer layer id from 3D mesh of wind turbine 284 """ 285 self._cell_id = cell_id 286 self._layer_id = layer_id
Initialize object.
Args: cell_id: integer cell id from 3D mesh of wind turbine layer_id: integer layer id from 3D mesh of wind turbine
288 def generate_display_label(self) -> str: 289 """Return string display for object in list displays.""" 290 return "{}, Ply missing".format(self.display_name)
Return string display for object in list displays.
292 def generate_ontology_label(self, set_id, iter_id): 293 """Generate ontology instance iri from object. 294 295 Args: 296 set_id: id of input set this defect belongs to 297 iter_id: unique id of defect within this specific input set 298 299 Returns: 300 relative iri of ontology instance 301 """ 302 return "__MissingPlyDefect_{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id)
Generate ontology instance iri from object.
Args: set_id: id of input set this defect belongs to iter_id: unique id of defect within this specific input set
Returns: relative iri of ontology instance
304 def generate_store_insert_stub(self, uniq_id: str) -> str: 305 """Generate SPARQL stub for inserting this object in a multi INSERT query. 306 307 Args: 308 uniq_id: unique string identifier with a combination of input set and defect ids 309 310 Returns: 311 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 312 """ 313 return """ 314 senso:__MissingPlyDefect_{uniq_id} a senso:MissingPlyDefect ; 315 senso:hasCellNumber {cell_id} ; 316 senso:hasLayerNumber {layer_id} . 317 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id)
Generate SPARQL stub for inserting this object in a multi INSERT query.
Args: uniq_id: unique string identifier with a combination of input set and defect ids
Returns: SPARQL insert statement without INSERT, PREFIXES or WHERE clause
319 @staticmethod 320 def get_all_entries_from_store(conn: StoreConnection) -> dict: 321 """Get all instances of MissingPlyDefect from store connection passed during initialization. 322 323 Args: 324 conn: Any subclass instance of StoreConnection 325 Returns: 326 dict of int -> MissingPlyDefect 327 """ 328 query = """ 329 SELECT ?x ?cell_number ?layer_number 330 WHERE { 331 ?x a senso:MissingPlyDefect . 332 ?x senso:hasCellNumber ?cell_number . 333 ?x senso:hasLayerNumber ?layer_number . 334 } 335 """ 336 result = {} 337 for x in conn.get_data(query): 338 result[x[0]] = MissingPlyDefect(cell_id=int(x[1]), layer_id=int(x[2])) 339 return result
Get all instances of MissingPlyDefect from store connection passed during initialization.
Args: conn: Any subclass instance of StoreConnection Returns: dict of int -> MissingPlyDefect
341 def to_simulation_input_dict(self) -> dict: 342 """Return dict representation of object intended for input into process simulation.""" 343 return { 344 "type": self.display_name, 345 "cell_id": self._cell_id, 346 "layer_id": self._layer_id, 347 }
Return dict representation of object intended for input into process simulation.
Inherited Members
356class VaryingThicknessDefect(InputDefect): 357 """Defect for a different layer thickness than intended. 358 359 Attributes: 360 type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set 361 display_name: Human readable name of defect type for legends 362 display_color: tuple of RGB color values scaled from 0 to 1 363 """ 364 data = None 365 type_id = 4 366 display_name = "Varying Thickness" 367 display_color = (255 / 256, 130 / 256, 3 / 256) 368 369 def __init__(self, cell_id: int=None, layer_id: int=None, fvc: float=None): 370 self._cell_id = cell_id 371 self._layer_id = layer_id 372 self._fvc = fvc 373 374 def generate_display_label(self) -> str: 375 """Return string display for object in list displays.""" 376 return "{}, {}% FVC".format(self.display_name, self._fvc) 377 378 def generate_ontology_label(self, set_id: int, iter_id: int) -> str: 379 """Generate ontology instance iri from object. 380 381 Args: 382 set_id: id of input set this defect belongs to 383 iter_id: unique id of defect within this specific input set 384 385 Returns: 386 relative iri of ontology instance 387 """ 388 return "__VaryingThicknessDefect__{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id) 389 390 def generate_store_insert_stub(self, uniq_id: str) -> str: 391 """Generate SPARQL stub for inserting this object in a multi INSERT query. 392 393 Args: 394 uniq_id: unique string identifier with a combination of input set and defect ids 395 396 Returns: 397 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 398 """ 399 return """ 400 senso:__VaryingThicknessDefect_{uniq_id} a senso:VaryingThicknessDefect ; 401 co:value {fvc} ; 402 senso:hasCellNumber {cell_id} ; 403 senso:hasLayerNumber {layer_id} . 404 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id, fvc=self._fvc) 405 406 @staticmethod 407 def get_all_entries_from_store(conn: StoreConnection) -> dict: 408 """Get all instances of VaryingThicknessDefect from store connection passed during initialization. 409 410 Args: 411 conn: Any subclass instance of StoreConnection 412 Returns: 413 dict of int -> VaryingThicknessDefect 414 """ 415 query = """ 416 SELECT ?x ?fvc ?cell_number ?layer_number 417 WHERE { 418 ?x a senso:VaryingThicknessDefect . 419 ?x co:value ?fvc . 420 ?x senso:hasCellNumber ?cell_number . 421 ?x senso:hasLayerNumber ?layer_number . 422 } 423 """ 424 result = {} 425 for x in conn.get_data(query): 426 result[x[0]] = VaryingThicknessDefect(cell_id=int(x[2]), layer_id=int(x[3]), fvc=float(x[1])) 427 return result 428 429 def to_simulation_input_dict(self) -> dict: 430 """Return dict representation of object intended for input into process simulation.""" 431 return { 432 "type": self.display_name, 433 "cell_id": self._cell_id, 434 "layer_id": self._layer_id, 435 "fvc": self._fvc 436 } 437 438 def __str__(self): 439 return "{} (Type ID {}) in cell {}, layer {}, data TBA".format(self.display_name, self.type_id, self._cell_id, self._layer_id) 440 441 def __repr__(self): 442 return "VaryingThicknessDefect(cell_id={cell_id}, layer_id={layer_id}, fvc={fvc})".format(cell_id = self._cell_id, layer_id = self._layer_id, fvc = self._fvc)
Defect for a different layer thickness than intended.
Attributes: type_id: Integer unique among all subclasses of InputDefect belonging to one specific defect input set display_name: Human readable name of defect type for legends display_color: tuple of RGB color values scaled from 0 to 1
374 def generate_display_label(self) -> str: 375 """Return string display for object in list displays.""" 376 return "{}, {}% FVC".format(self.display_name, self._fvc)
Return string display for object in list displays.
378 def generate_ontology_label(self, set_id: int, iter_id: int) -> str: 379 """Generate ontology instance iri from object. 380 381 Args: 382 set_id: id of input set this defect belongs to 383 iter_id: unique id of defect within this specific input set 384 385 Returns: 386 relative iri of ontology instance 387 """ 388 return "__VaryingThicknessDefect__{set_id}_{iter_id}".format(set_id=set_id, iter_id=iter_id)
Generate ontology instance iri from object.
Args: set_id: id of input set this defect belongs to iter_id: unique id of defect within this specific input set
Returns: relative iri of ontology instance
390 def generate_store_insert_stub(self, uniq_id: str) -> str: 391 """Generate SPARQL stub for inserting this object in a multi INSERT query. 392 393 Args: 394 uniq_id: unique string identifier with a combination of input set and defect ids 395 396 Returns: 397 SPARQL insert statement without INSERT, PREFIXES or WHERE clause 398 """ 399 return """ 400 senso:__VaryingThicknessDefect_{uniq_id} a senso:VaryingThicknessDefect ; 401 co:value {fvc} ; 402 senso:hasCellNumber {cell_id} ; 403 senso:hasLayerNumber {layer_id} . 404 """.format(uniq_id=uniq_id, cell_id=self._cell_id, layer_id=self._layer_id, fvc=self._fvc)
Generate SPARQL stub for inserting this object in a multi INSERT query.
Args: uniq_id: unique string identifier with a combination of input set and defect ids
Returns: SPARQL insert statement without INSERT, PREFIXES or WHERE clause
406 @staticmethod 407 def get_all_entries_from_store(conn: StoreConnection) -> dict: 408 """Get all instances of VaryingThicknessDefect from store connection passed during initialization. 409 410 Args: 411 conn: Any subclass instance of StoreConnection 412 Returns: 413 dict of int -> VaryingThicknessDefect 414 """ 415 query = """ 416 SELECT ?x ?fvc ?cell_number ?layer_number 417 WHERE { 418 ?x a senso:VaryingThicknessDefect . 419 ?x co:value ?fvc . 420 ?x senso:hasCellNumber ?cell_number . 421 ?x senso:hasLayerNumber ?layer_number . 422 } 423 """ 424 result = {} 425 for x in conn.get_data(query): 426 result[x[0]] = VaryingThicknessDefect(cell_id=int(x[2]), layer_id=int(x[3]), fvc=float(x[1])) 427 return result
Get all instances of VaryingThicknessDefect from store connection passed during initialization.
Args: conn: Any subclass instance of StoreConnection Returns: dict of int -> VaryingThicknessDefect
429 def to_simulation_input_dict(self) -> dict: 430 """Return dict representation of object intended for input into process simulation.""" 431 return { 432 "type": self.display_name, 433 "cell_id": self._cell_id, 434 "layer_id": self._layer_id, 435 "fvc": self._fvc 436 }
Return dict representation of object intended for input into process simulation.
Inherited Members
445class DefectInputDataSet(HasHDF): 446 """Input data set for future simulation containing placed defects. 447 448 Contains all info for a single simulation concerning deviations from the standard 3D model 449 Information is sorted according to cell id of the 3D model first and then layer information of 450 composite material markup second, individual defects are instances of an InputDefect subclass; 451 implements pyiron HasHDF interface for automatic HDF5 serialization during job execution for storage 452 """ 453 def __init__(self, uniq_id: int=None, defects: list=None, conn: StoreConnection=None): 454 """Initialize empty internal data storage object""" 455 self._defect_data = {} 456 self._id = uniq_id 457 self._store_connection = conn 458 if defects: 459 for defect in defects: 460 self.add_defect_to_cell(defect.get_cell_id(), defect.get_layer_id(), defect) 461 462 def get_id(self): 463 """Return id of input data set, can be None if object not saved to data storage yet""" 464 return self._id 465 466 def get_defects_of_cell(self, cell_id: int) -> dict: 467 """Return all defects for specified cell 468 469 Args: 470 cell_id: unique cell id of associated 3D model 471 472 Returns: 473 dict of layer id to defect dicts (defect id => defect object) 474 """ 475 if cell_id not in self._defect_data: 476 return {} 477 else: 478 return self._defect_data[cell_id] 479 480 def add_defect_to_cell(self, cell_id: int, layer_id: int, defect: InputDefect): 481 """Add 1 defect,overwriting any existing defect of this specific InputDefect subclass. 482 483 Args: 484 cell_id: unique cell id of associated 3D model 485 layer_id: id of layer in material of defect 486 defect: child class of InputDefect containing defect data 487 """ 488 if cell_id not in self._defect_data: 489 self._defect_data[cell_id] = {} 490 if layer_id not in self._defect_data[cell_id]: 491 self._defect_data[cell_id][layer_id] = {} 492 self._defect_data[cell_id][layer_id][defect.type_id] = defect 493 494 def clear_defects_of_cell(self, cell_id: int): 495 """Remove all defects of specific cell""" 496 if cell_id in self._defect_data: 497 self._defect_data.pop(cell_id) 498 499 def generate_input_file(self): 500 print("generate the calculix input file i guess") 501 502 def generate_defect_display_summary(self) -> dict: 503 """Generate summary containing ids of all cells with defects and list of contained defect types, disregarding layer information. 504 505 Returns: 506 dictionary containing list of cells of with defects and list of defect types per cell 507 """ 508 summary = { 509 "defect_cells": list(self._defect_data.keys()), 510 "cell_defect_types": {} 511 } 512 for vtk_id, layers in self._defect_data.items(): 513 summary["cell_defect_types"][vtk_id] = [] 514 for layer_id, layer_data in layers.items(): 515 summary["cell_defect_types"][vtk_id].extend(layer_data.keys()) 516 summary["cell_defect_types"][vtk_id] = list(set(summary["cell_defect_types"][vtk_id])) 517 return summary 518 519 def generate_input_set_display_label(self) -> str: 520 """Return string display for object in list displays.""" 521 summ = self.get_defects() 522 c = Counter([x.type_id for x in summ]) 523 occurence_string = ", ".join(["{}: {}".format(value, count) for value, count in c.most_common()]) 524 return "Total: {} | {}".format(c.total(), occurence_string) 525 526 def get_defects(self) -> list: 527 """Get all defect objects of input set 528 529 Returns: 530 list of InputDefect objects 531 """ 532 defects = [] 533 for _, cell_data in self._defect_data.items(): 534 for _, layer_data in cell_data.items(): 535 for defect_id, defect in layer_data.items(): 536 defects.append(defect) 537 return defects 538 539 @staticmethod 540 def get_available_defect_types() -> list: 541 """Return all subclasses of the class InputDefect""" 542 return InputDefect.__subclasses__() 543 544 def generate_ontology_label(self) -> str: 545 """Generate ontology instance iri from object.""" 546 return "__DefectPlacementInputSet_{}".format(self._id) 547 548 @staticmethod 549 def get_id_from_ontology_iri(label: str) -> int: 550 """Extract id from full ontology instance iri.""" 551 return int(label.split("_")[-1]) 552 553 def generate_store_insert_stub(self, uniq_id): 554 return """ 555 senso:__DefectPlacementInputSet_{uniq_id} a senso:DefectPlacementInputSet . 556 """.format(uniq_id=uniq_id) 557 558 def save_entry_to_store(self, set_id: int): 559 """Save object to store connection passed during initialization.""" 560 self._id = set_id 561 label = self.generate_ontology_label() 562 insert_stubs = [self.generate_store_insert_stub(self._id)] 563 for i, defect in enumerate(self.get_defects()): 564 new_id = "{}_{}".format(self._id, i) 565 insert_stubs.append(defect.generate_store_insert_stub(new_id)) 566 query = """ 567 INSERT {{ 568 {stubs} 569 }} WHERE {{ }} 570 """.format(stubs="\n".join(insert_stubs)) 571 self._store_connection.update_data(query) 572 573 @staticmethod 574 def get_all_entries_from_store(conn: StoreConnection) -> dict: 575 """Get all instances of DefectInputDataSet from store connection passed during initialization. 576 577 Args: 578 conn: Any subclass instance of StoreConnection 579 Returns: 580 dict of int -> DefectInputDataSet 581 """ 582 defects = {} 583 for defect_type in DefectInputDataSet.get_available_defect_types(): 584 defects[defect_type.__name__] = defect_type.get_all_entries_from_store(conn) 585 query = """ 586 SELECT DISTINCT ?x 587 WHERE { 588 ?x a senso:DefectPlacementInputSet . 589 } 590 """ 591 result = {} 592 for x in conn.get_data(query): 593 uniq_id = DefectInputDataSet.get_id_from_ontology_iri(x[0]) 594 result[uniq_id] = DefectInputDataSet(uniq_id=uniq_id, conn=conn) 595 for defect_type, defect_dict in defects.items(): 596 for iri, defect in defect_dict.items(): 597 set_id = defect.get_set_id_from_ontology_iri(iri) 598 result[set_id].add_defect_to_cell(defect.get_cell_id(), defect.get_layer_id(), defect) 599 return result 600 601 def __str__(self): 602 summ = self.get_defects() 603 c = Counter([x.display_name for x in summ]) 604 occurence_string = ", ".join(["{}: {}".format(value, count) for value, count in c.most_common()]) 605 return "DefectInputDataSet ID {} with {} defects: {}".format(self._id, c.total(), occurence_string) 606 607 def __repr__(self): 608 return "DefectInputDataSet(uniq_id={uniq_id}, defects={defects}, conn={conn})".format(uniq_id=self._id,defects=repr(self.get_defects()),conn=repr(self._store_connection)) 609 610 def _to_hdf(self, hdf=None, group_name=None): 611 with hdf.open("defect_placement_input_data") as hdf_store: 612 hdf_store["_id"] = self._id 613 hdf_store["_defects"] = repr(self.get_defects()) 614 hdf_store["_store_connection"] = repr(self._store_connection) 615 616 def _from_hdf(self, hdf=None, version=None): 617 pass 618 619 def from_hdf_args(hdf): 620 with hdf.open("defect_placement_input_data") as hdf_store: 621 arg_dict = { 622 "uniq_id": hdf_store["_id"], 623 "defects": eval(hdf_store["_defects"]), 624 "conn": eval(hdf_store["_store_connection"]) 625 } 626 return arg_dict
Input data set for future simulation containing placed defects.
Contains all info for a single simulation concerning deviations from the standard 3D model Information is sorted according to cell id of the 3D model first and then layer information of composite material markup second, individual defects are instances of an InputDefect subclass; implements pyiron HasHDF interface for automatic HDF5 serialization during job execution for storage
453 def __init__(self, uniq_id: int=None, defects: list=None, conn: StoreConnection=None): 454 """Initialize empty internal data storage object""" 455 self._defect_data = {} 456 self._id = uniq_id 457 self._store_connection = conn 458 if defects: 459 for defect in defects: 460 self.add_defect_to_cell(defect.get_cell_id(), defect.get_layer_id(), defect)
Initialize empty internal data storage object
462 def get_id(self): 463 """Return id of input data set, can be None if object not saved to data storage yet""" 464 return self._id
Return id of input data set, can be None if object not saved to data storage yet
466 def get_defects_of_cell(self, cell_id: int) -> dict: 467 """Return all defects for specified cell 468 469 Args: 470 cell_id: unique cell id of associated 3D model 471 472 Returns: 473 dict of layer id to defect dicts (defect id => defect object) 474 """ 475 if cell_id not in self._defect_data: 476 return {} 477 else: 478 return self._defect_data[cell_id]
Return all defects for specified cell
Args: cell_id: unique cell id of associated 3D model
Returns: dict of layer id to defect dicts (defect id => defect object)
480 def add_defect_to_cell(self, cell_id: int, layer_id: int, defect: InputDefect): 481 """Add 1 defect,overwriting any existing defect of this specific InputDefect subclass. 482 483 Args: 484 cell_id: unique cell id of associated 3D model 485 layer_id: id of layer in material of defect 486 defect: child class of InputDefect containing defect data 487 """ 488 if cell_id not in self._defect_data: 489 self._defect_data[cell_id] = {} 490 if layer_id not in self._defect_data[cell_id]: 491 self._defect_data[cell_id][layer_id] = {} 492 self._defect_data[cell_id][layer_id][defect.type_id] = defect
Add 1 defect,overwriting any existing defect of this specific InputDefect subclass.
Args: cell_id: unique cell id of associated 3D model layer_id: id of layer in material of defect defect: child class of InputDefect containing defect data
494 def clear_defects_of_cell(self, cell_id: int): 495 """Remove all defects of specific cell""" 496 if cell_id in self._defect_data: 497 self._defect_data.pop(cell_id)
Remove all defects of specific cell
502 def generate_defect_display_summary(self) -> dict: 503 """Generate summary containing ids of all cells with defects and list of contained defect types, disregarding layer information. 504 505 Returns: 506 dictionary containing list of cells of with defects and list of defect types per cell 507 """ 508 summary = { 509 "defect_cells": list(self._defect_data.keys()), 510 "cell_defect_types": {} 511 } 512 for vtk_id, layers in self._defect_data.items(): 513 summary["cell_defect_types"][vtk_id] = [] 514 for layer_id, layer_data in layers.items(): 515 summary["cell_defect_types"][vtk_id].extend(layer_data.keys()) 516 summary["cell_defect_types"][vtk_id] = list(set(summary["cell_defect_types"][vtk_id])) 517 return summary
Generate summary containing ids of all cells with defects and list of contained defect types, disregarding layer information.
Returns: dictionary containing list of cells of with defects and list of defect types per cell
519 def generate_input_set_display_label(self) -> str: 520 """Return string display for object in list displays.""" 521 summ = self.get_defects() 522 c = Counter([x.type_id for x in summ]) 523 occurence_string = ", ".join(["{}: {}".format(value, count) for value, count in c.most_common()]) 524 return "Total: {} | {}".format(c.total(), occurence_string)
Return string display for object in list displays.
526 def get_defects(self) -> list: 527 """Get all defect objects of input set 528 529 Returns: 530 list of InputDefect objects 531 """ 532 defects = [] 533 for _, cell_data in self._defect_data.items(): 534 for _, layer_data in cell_data.items(): 535 for defect_id, defect in layer_data.items(): 536 defects.append(defect) 537 return defects
Get all defect objects of input set
Returns: list of InputDefect objects
539 @staticmethod 540 def get_available_defect_types() -> list: 541 """Return all subclasses of the class InputDefect""" 542 return InputDefect.__subclasses__()
Return all subclasses of the class InputDefect
544 def generate_ontology_label(self) -> str: 545 """Generate ontology instance iri from object.""" 546 return "__DefectPlacementInputSet_{}".format(self._id)
Generate ontology instance iri from object.
548 @staticmethod 549 def get_id_from_ontology_iri(label: str) -> int: 550 """Extract id from full ontology instance iri.""" 551 return int(label.split("_")[-1])
Extract id from full ontology instance iri.
558 def save_entry_to_store(self, set_id: int): 559 """Save object to store connection passed during initialization.""" 560 self._id = set_id 561 label = self.generate_ontology_label() 562 insert_stubs = [self.generate_store_insert_stub(self._id)] 563 for i, defect in enumerate(self.get_defects()): 564 new_id = "{}_{}".format(self._id, i) 565 insert_stubs.append(defect.generate_store_insert_stub(new_id)) 566 query = """ 567 INSERT {{ 568 {stubs} 569 }} WHERE {{ }} 570 """.format(stubs="\n".join(insert_stubs)) 571 self._store_connection.update_data(query)
Save object to store connection passed during initialization.
573 @staticmethod 574 def get_all_entries_from_store(conn: StoreConnection) -> dict: 575 """Get all instances of DefectInputDataSet from store connection passed during initialization. 576 577 Args: 578 conn: Any subclass instance of StoreConnection 579 Returns: 580 dict of int -> DefectInputDataSet 581 """ 582 defects = {} 583 for defect_type in DefectInputDataSet.get_available_defect_types(): 584 defects[defect_type.__name__] = defect_type.get_all_entries_from_store(conn) 585 query = """ 586 SELECT DISTINCT ?x 587 WHERE { 588 ?x a senso:DefectPlacementInputSet . 589 } 590 """ 591 result = {} 592 for x in conn.get_data(query): 593 uniq_id = DefectInputDataSet.get_id_from_ontology_iri(x[0]) 594 result[uniq_id] = DefectInputDataSet(uniq_id=uniq_id, conn=conn) 595 for defect_type, defect_dict in defects.items(): 596 for iri, defect in defect_dict.items(): 597 set_id = defect.get_set_id_from_ontology_iri(iri) 598 result[set_id].add_defect_to_cell(defect.get_cell_id(), defect.get_layer_id(), defect) 599 return result
Get all instances of DefectInputDataSet from store connection passed during initialization.
Args: conn: Any subclass instance of StoreConnection Returns: dict of int -> DefectInputDataSet
619 def from_hdf_args(hdf): 620 with hdf.open("defect_placement_input_data") as hdf_store: 621 arg_dict = { 622 "uniq_id": hdf_store["_id"], 623 "defects": eval(hdf_store["_defects"]), 624 "conn": eval(hdf_store["_store_connection"]) 625 } 626 return arg_dict
Read arguments for instance creation from HDF5 file.
Args: hdf (ProjectHDFio): HDF5 group object
Returns: dict: arguments that can be **kwarg-passed to cls().
Inherited Members
- pyiron_base.interfaces.has_hdf.HasHDF
- from_hdf
- to_hdf
- rewrite_hdf
629class CellLayersDataSet: 630 """Data set containing information about layer structure of all cells. 631 632 reads data from .vtt file containing information about the different layers for each cell of the 3D model 633 expects vtk table structure according to following definition: 634 635 "element_label": int (id of associated cell), starting at 1 636 "layer_id": int (id of layer, unique per cell) 637 "layer_material": str (layer material name) 638 "layer_thickness_mm": float (thickness of layer in mm) 639 "layer_angle_deg": int (angle of fiber alignment in °, [-90 to 90]) 640 641 """ 642 NECESSARY_KEYS = ["element_label", "layer_id", "layer_material", "layer_thickness_mm", "layer_angle_deg"] 643 def __init__(self, vtt_path: str): 644 """Initialise data set from file and check if necessary columns are present. 645 646 Args: 647 vtt_path: full or relative path of .vtt file containing cell information table 648 """ 649 self._file_path = vtt_path 650 self._dataframe = read_vtt.get_dataframe(self._file_path) 651 self.check_data_source() 652 self._dataframe.layer_material.replace(to_replace={"SAERTEX-U-E-SKIN": "GLASS-U-E-SKIN","SAERTEX-U-E-WEB": "GLASS-U-E-WEB", "E-LT-5500(UD)": "GLASS-UD"}, inplace=True) 653 654 def get_available_layers_for_cell(self, cell_id: int) -> pd.DataFrame: 655 """Return dataframe containing the data subset of the passed cell_id """ 656 return self._dataframe.loc[self._dataframe.element_label == cell_id] 657 658 def get_layer_of_cell(self, cell_id: int, layer_id: int) -> pd.DataFrame: 659 """Return one specific entry to dataset with the correct combination of cell id and layer id""" 660 return self._dataframe.loc[(self._dataframe.element_label == cell_id) & (self._dataframe.layer_id == layer_id)].iloc[0] 661 662 def check_data_source(self): 663 """Check if data source contains all necessary keys. 664 665 Raises: 666 KeyError: If any key as defined in NECESSARY_KEYS is not found 667 ValueError: If serial ids in element_label do not start with 1 668 """ 669 for key in self.NECESSARY_KEYS: 670 if key not in self._dataframe: 671 raise KeyError("'{}' not found in input data '{}'".format(key, self._file_path)) 672 if self._dataframe["element_label"].min() != 1: 673 raise ValueError("Serial IDs in 'element_label' need to start at 1, minimum value found: {}".format(self._dataframe["element_label"].min())) 674 675 def __str__(self): 676 return "CellLayersDataSet with {} cells with up to {} layers per cell".format(len(self._dataframe["element_label"].unique()), len(self._dataframe["layer_id"].unique())) 677 678 def __repr__(self): 679 return self.__str__()
Data set containing information about layer structure of all cells.
reads data from .vtt file containing information about the different layers for each cell of the 3D model expects vtk table structure according to following definition:
"element_label": int (id of associated cell), starting at 1 "layer_id": int (id of layer, unique per cell) "layer_material": str (layer material name) "layer_thickness_mm": float (thickness of layer in mm) "layer_angle_deg": int (angle of fiber alignment in °, [-90 to 90])
643 def __init__(self, vtt_path: str): 644 """Initialise data set from file and check if necessary columns are present. 645 646 Args: 647 vtt_path: full or relative path of .vtt file containing cell information table 648 """ 649 self._file_path = vtt_path 650 self._dataframe = read_vtt.get_dataframe(self._file_path) 651 self.check_data_source() 652 self._dataframe.layer_material.replace(to_replace={"SAERTEX-U-E-SKIN": "GLASS-U-E-SKIN","SAERTEX-U-E-WEB": "GLASS-U-E-WEB", "E-LT-5500(UD)": "GLASS-UD"}, inplace=True)
Initialise data set from file and check if necessary columns are present.
Args: vtt_path: full or relative path of .vtt file containing cell information table
654 def get_available_layers_for_cell(self, cell_id: int) -> pd.DataFrame: 655 """Return dataframe containing the data subset of the passed cell_id """ 656 return self._dataframe.loc[self._dataframe.element_label == cell_id]
Return dataframe containing the data subset of the passed cell_id
658 def get_layer_of_cell(self, cell_id: int, layer_id: int) -> pd.DataFrame: 659 """Return one specific entry to dataset with the correct combination of cell id and layer id""" 660 return self._dataframe.loc[(self._dataframe.element_label == cell_id) & (self._dataframe.layer_id == layer_id)].iloc[0]
Return one specific entry to dataset with the correct combination of cell id and layer id
662 def check_data_source(self): 663 """Check if data source contains all necessary keys. 664 665 Raises: 666 KeyError: If any key as defined in NECESSARY_KEYS is not found 667 ValueError: If serial ids in element_label do not start with 1 668 """ 669 for key in self.NECESSARY_KEYS: 670 if key not in self._dataframe: 671 raise KeyError("'{}' not found in input data '{}'".format(key, self._file_path)) 672 if self._dataframe["element_label"].min() != 1: 673 raise ValueError("Serial IDs in 'element_label' need to start at 1, minimum value found: {}".format(self._dataframe["element_label"].min()))
Check if data source contains all necessary keys.
Raises: KeyError: If any key as defined in NECESSARY_KEYS is not found ValueError: If serial ids in element_label do not start with 1
682def get_material_color(name: str) -> str: 683 """Get color for specific layer in matplotlib material layup display.""" 684 color_dict = defaultdict(lambda: 'white') 685 color_dict['gelcoat'] = 'red' 686 color_dict['GELCOAT'] = 'red' 687 color_dict['SNL(Triax)'] = 'green' 688 color_dict['saertex(DB)'] = 'blue' 689 color_dict['foam'] = 'yellow' 690 color_dict['FOAM'] = 'yellow' 691 color_dict['Carbon(UD)'] = 'cyan' 692 color_dict['CARBON(UD)'] = 'cyan' 693 color_dict['E-LT-5500(UD)'] = 'salmon' 694 color_dict["GLASS-UD"] = 'salmon' 695 color_dict['E-LT-5500(UD)-SKIN'] = 'orange' 696 color_dict['GLASS-TRIAX'] = 'orange' 697 color_dict['E-LT-5500(UD)-WEB'] = 'peachpuff' 698 color_dict['SAERTEX-U-E-SKIN'] = 'orange' 699 color_dict['SAERTEX-U-E-WEB'] = 'peachpuff' 700 color_dict['GLASS-U-E-SKIN'] = 'orange' 701 color_dict['GLASS-U-E-WEB'] = 'peachpuff' 702 return color_dict[name]
Get color for specific layer in matplotlib material layup display.