Source code for geouned.GEOUNED.utils.data_classes

import typing
from numbers import Real


[docs] class Options: """A class for containing conversion options Args: forceCylinder (bool, optional): Use cylinder (instead of cones) as ancillary surface where unclosed torus surfaces are involved in the solid definition. Defaults to False. newSplitPlane (bool, optional): New method to consider plane as cutting surface during the decomposition process. Former method split first planes perpendicular to X,Y,Z axis and then the other planes involved in the solid definition. New method group all parallel planes independently whether their normal are along X,Y,Z axes, and start the decomposition process cutting first with the group having the highest number of parallel planes. Defaults to True. delLastNumber (bool, optional): Deleting the last word in the comment if it is a number. Defaults to False. enlargeBox (Real, optional): Enlarge box boundary when evaluating the constraint table during the simplification of the void cell definition. (unit is millimeter). Defaults to 2. nPlaneReverse (int, optional): Threshold value to determine whether cut with parallel planes should be carried out first. Defaults to 0. splitTolerance (Real, optional): Fuzzy tolerance value used in the FreeCAD function “BOPTools.SplitAPI.slice”. This function is used during the solid decomposition process. Defaults to 0. scaleUp (bool, optional): Scale up Fuzzy tolerance once get below 1e-12. Defaults to True. quadricPY (bool, optional): In openMC python script format, the cones or cylinders no aligned with the X,Y, or Z axis can be defined using the openmc.Cone or open.Cylinder methods but can also be defined with their quadric parameter. If “quadricPY” is 11 True then all cones and cylinders will be defined in the openMC python script format under their quadric form. Defaults to False. Facets (bool, optional): use alternative conversion module when geometry is defined by cells compound by only triangular plane faces. Defaults to False. prnt3PPlane (bool, optional): print 3 point plane definition in output as 3 points coordinates. Defaults to False. forceNoOverlap (bool, optional): force no overlaping cell definition. Adjacent cell definition are rested from current cell definition. Defaults to False. """ def __init__( self, forceCylinder: bool = False, newSplitPlane: bool = True, delLastNumber: bool = False, enlargeBox: Real = 2.0, nPlaneReverse: int = 0, splitTolerance: Real = 0.0, scaleUp: bool = True, quadricPY: bool = False, Facets: bool = False, prnt3PPlane: bool = False, forceNoOverlap: bool = False, ): self.forceCylinder = forceCylinder self.newSplitPlane = newSplitPlane self.delLastNumber = delLastNumber self.enlargeBox = enlargeBox self.nPlaneReverse = nPlaneReverse self.splitTolerance = splitTolerance self.scaleUp = scaleUp self.quadricPY = quadricPY self.Facets = Facets self.prnt3PPlane = prnt3PPlane self.forceNoOverlap = forceNoOverlap @property def forceCylinder(self): return self._forceCylinder @forceCylinder.setter def forceCylinder(self, value: bool): if not isinstance(value, bool): raise TypeError(f"geouned.Options.forceCylinder should be a bool, not a {type(value)}") self._forceCylinder = value @property def newSplitPlane(self): return self._newSplitPlane @newSplitPlane.setter def newSplitPlane(self, value: bool): if not isinstance(value, bool): raise TypeError(f"geouned.Options.newSplitPlane should be a bool, not a {type(value)}") self._newSplitPlane = value @property def delLastNumber(self): return self._delLastNumber @delLastNumber.setter def delLastNumber(self, value: bool): if not isinstance(value, bool): raise TypeError(f"geouned.Options.delLastNumber should be a bool, not a {type(value)}") self._delLastNumber = value @property def enlargeBox(self): return self._enlargeBox @enlargeBox.setter def enlargeBox(self, value: Real): if not isinstance(value, Real): raise TypeError(f"geouned.Options.enlargeBox should be a Real, not a {type(value)}") if value < 0: raise ValueError(f"geouned.Options.enlargeBox should be above 0, not {value}") self._enlargeBox = value @property def nPlaneReverse(self): return self._nPlaneReverse @nPlaneReverse.setter def nPlaneReverse(self, value: int): if not isinstance(value, int): raise TypeError(f"geouned.Options.nPlaneReverse should be a int, not a {type(value)}") self._nPlaneReverse = value @property def splitTolerance(self): return self._splitTolerance @splitTolerance.setter def splitTolerance(self, value: Real): if not isinstance(value, Real): raise TypeError(f"geouned.Options.splitTolerance should be a Real, not a {type(value)}") if value < 0: raise ValueError(f"geouned.Options.splitTolerance should be above 0, not {value}") self._splitTolerance = value @property def scaleUp(self): return self._scaleUp @scaleUp.setter def scaleUp(self, value: bool): if not isinstance(value, bool): raise TypeError(f"geouned.Options.scaleUp should be a bool, not a {type(value)}") self._scaleUp = value @property def quadricPY(self): return self._quadricPY @quadricPY.setter def quadricPY(self, value: bool): if not isinstance(value, bool): raise TypeError(f"geouned.Options.quadricPY should be a bool, not a {type(value)}") self._quadricPY = value @property def Facets(self): return self._Facets @Facets.setter def Facets(self, value: bool): if not isinstance(value, bool): raise TypeError(f"geouned.Options.Facets should be a bool, not a {type(value)}") self._Facets = value @property def prnt3PPlane(self): return self._prnt3PPlane @prnt3PPlane.setter def prnt3PPlane(self, value: bool): if not isinstance(value, bool): raise TypeError(f"geouned.Options.prnt3PPlane should be a bool, not a {type(value)}") self._prnt3PPlane = value @property def forceNoOverlap(self): return self._forceNoOverlap @forceNoOverlap.setter def forceNoOverlap(self, value: bool): if not isinstance(value, bool): raise TypeError(f"geouned.Options.forceNoOverlap should be a bool, not a {type(value)}") self._forceNoOverlap = value
[docs] class Tolerances: """A class for containing tolerances values Args: relativeTol (bool, optional): _description_. Defaults to False. relativePrecision (float, optional): relative precision. Defaults to 1.0e-6. value (float, optional): Tolerance in single value comparison. Defaults to 1.0e-6. distance (float, optional): General Distance Tolerance. Defaults to 1.0e-4. angle (float, optional): General Angle Tolerance. Defaults to 1.0e-4. pln_distance (float, optional): distance between planes equal planes if distance between parallel planes < 1e-4 cm. Defaults to 1.0e-4. pln_angle (float, optional): angle between axis. 1e-4 : planes separate each other 0.1mm each 1m. Defaults to 1.0e-4. cyl_distance (float, optional): distance between radius/center. Defaults to 1.0e-4. cyl_angle (float, optional): angle between axis. Defaults to 1.0e-4. sph_distance (float, optional): distance between radius/center. Defaults to 1.0e-4. kne_distance (float, optional): distance between apex. Defaults to 1.0e-4. kne_angle (float, optional): angle between semiangles/axis. Defaults to 1.0e-4. tor_distance (float, optional): distance between Major/Minor radii/center. Defaults to 1.0e-4. tor_angle (float, optional): angle between axis. Defaults to 1.0e-4. min_area (float, optional): minimum face area to consider in cell definition. Defaults to 1.0e-2. """ def __init__( self, relativeTol: bool = False, relativePrecision: float = 1.0e-6, value: float = 1.0e-6, distance: float = 1.0e-4, angle: float = 1.0e-4, pln_distance: float = 1.0e-4, pln_angle: float = 1.0e-4, cyl_distance: float = 1.0e-4, cyl_angle: float = 1.0e-4, sph_distance: float = 1.0e-4, kne_distance: float = 1.0e-4, kne_angle: float = 1.0e-4, tor_distance: float = 1.0e-4, tor_angle: float = 1.0e-4, min_area: float = 1.0e-2, ): self.relativeTol = relativeTol self.relativePrecision = relativePrecision self.value = value self.distance = distance self.angle = angle self.pln_distance = pln_distance self.pln_angle = pln_angle self.cyl_distance = cyl_distance self.cyl_angle = cyl_angle self.sph_distance = sph_distance self.kne_distance = kne_distance self.kne_angle = kne_angle self.tor_distance = tor_distance self.tor_angle = tor_angle self.min_area = min_area @property def relativeTol(self): return self._relativeTol @relativeTol.setter def relativeTol(self, value: bool): if not isinstance(value, bool): raise TypeError(f"geouned.Tolerances.relativeTol should be a bool, not a {type(value)}") self._relativeTol = value @property def relativePrecision(self): return self._relativePrecision @relativePrecision.setter def relativePrecision(self, value: float): if not isinstance(value, float): raise TypeError(f"geouned.Tolerances.relativePrecision should be a float, not a {type(value)}") self._relativePrecision = value @property def value(self): return self._value @value.setter def value(self, value: float): if not isinstance(value, float): raise TypeError(f"geouned.Tolerances.value should be a float, not a {type(value)}") self._value = value @property def distance(self): return self._distance @distance.setter def distance(self, distance: float): if not isinstance(distance, float): raise TypeError(f"geouned.Tolerances.distance should be a float, not a {type(distance)}") self._distance = distance @property def angle(self): return self._angle @angle.setter def angle(self, angle: float): if not isinstance(angle, float): raise TypeError(f"geouned.Tolerances.angle should be a float, not a {type(angle)}") self._angle = angle @property def pln_distance(self): return self._pln_distance @pln_distance.setter def pln_distance(self, pln_distance: float): if not isinstance(pln_distance, float): raise TypeError(f"geouned.Tolerances.pln_distance should be a float, not a {type(pln_distance)}") self._pln_distance = pln_distance @property def cyl_distance(self): return self._cyl_distance @cyl_distance.setter def cyl_distance(self, cyl_distance: float): if not isinstance(cyl_distance, float): raise TypeError(f"geouned.Tolerances.cyl_distance should be a float, not a {type(cyl_distance)}") self._cyl_distance = cyl_distance @property def cyl_angle(self): return self._cyl_angle @cyl_angle.setter def cyl_angle(self, cyl_angle: float): if not isinstance(cyl_angle, float): raise TypeError(f"geouned.Tolerances.cyl_angle should be a float, not a {type(cyl_angle)}") self._cyl_angle = cyl_angle @property def sph_distance(self): return self._sph_distance @sph_distance.setter def sph_distance(self, sph_distance: float): if not isinstance(sph_distance, float): raise TypeError(f"geouned.Tolerances.sph_distance should be a float, not a {type(sph_distance)}") self._sph_distance = sph_distance @property def pln_angle(self): return self._pln_angle @pln_angle.setter def pln_angle(self, pln_angle: float): if not isinstance(pln_angle, float): raise TypeError(f"geouned.Tolerances.pln_angle should be a float, not a {type(pln_angle)}") self._pln_angle = pln_angle @property def kne_distance(self): return self._kne_distance @kne_distance.setter def kne_distance(self, kne_distance: float): if not isinstance(kne_distance, float): raise TypeError(f"geouned.Tolerances.kne_distance should be a float, not a {type(kne_distance)}") self._kne_distance = kne_distance @property def kne_angle(self): return self._kne_angle @kne_angle.setter def kne_angle(self, kne_angle: float): if not isinstance(kne_angle, float): raise TypeError(f"geouned.Tolerances.kne_angle should be a float, not a {type(kne_angle)}") self._kne_angle = kne_angle @property def tor_distance(self): return self._tor_distance @tor_distance.setter def tor_distance(self, tor_distance: float): if not isinstance(tor_distance, float): raise TypeError(f"geouned.Tolerances.tor_distance should be a float, not a {type(tor_distance)}") self._tor_distance = tor_distance @property def tor_angle(self): return self._tor_angle @tor_angle.setter def tor_angle(self, tor_angle: float): if not isinstance(tor_angle, float): raise TypeError(f"geouned.Tolerances.tor_angle should be a float, not a {type(tor_angle)}") self._tor_angle = tor_angle @property def min_area(self): return self._min_area @min_area.setter def min_area(self, min_area: float): if not isinstance(min_area, float): raise TypeError(f"geouned.Tolerances.min_area should be a float, not a {type(min_area)}") self._min_area = min_area
[docs] class NumericFormat: """Numerical format options for each of the surface types. Args: P_abc (str, optional): Plane general a,b,c params. Defaults to "14.7e". P_d (str, optional): Plane general d params. Defaults to "14.7e". P_xyz (str, optional): PX/PY/PZ params. Defaults to "14.7e". S_r (str, optional): SO/SX/SY/SZ/S radius. Defaults to "14.7e". S_xyz (str, optional): SO/SX/SY/SZ/S center. Defaults to "14.7e". C_r (str, optional): Cylinder radius. Defaults to "12f". C_xyz (str, optional): Cylinder center. Defaults to "12f". K_xyz (str, optional): Cone apex. Defaults to "13.6e". K_tan2 (str, optional): Cone tan^2 value. Defaults to "12f". T_r (str, optional): Torus radii. Defaults to "14.7e". T_xyz (str, optional): Torus center. Defaults to "14.7e". GQ_1to6 (str, optional): GQ 1 to 6 coefficients (order 2 x2,y2,z2,xy,...). Defaults to "18.15f". GQ_7to9 (str, optional): GQ 7 to 9 coefficients (order 1 x,y,z). Defaults to "18.15f". GQ_10 (str, optional): GQ 10 coefficient. Defaults to "18.15f". """ def __init__( self, P_abc: str = "14.7e", P_d: str = "14.7e", P_xyz: str = "14.7e", S_r: str = "14.7e", S_xyz: str = "14.7e", C_r: str = "12f", C_xyz: str = "12f", K_xyz: str = "13.6e", K_tan2: str = "12f", T_r: str = "14.7e", T_xyz: str = "14.7e", GQ_1to6: str = "18.15f", GQ_7to9: str = "18.15f", GQ_10: str = "18.15f", ): self.P_abc = P_abc self.P_d = P_d self.P_xyz = P_xyz self.S_r = S_r self.S_xyz = S_xyz self.C_r = C_r self.C_xyz = C_xyz self.K_xyz = K_xyz self.K_tan2 = K_tan2 self.T_r = T_r self.T_xyz = T_xyz self.GQ_1to6 = GQ_1to6 self.GQ_7to9 = GQ_7to9 self.GQ_10 = GQ_10 @property def P_abc(self): return self._P_abc @P_abc.setter def P_abc(self, P_abc: str): if not isinstance(P_abc, str): raise TypeError(f"geouned.Tolerances.P_abc should be a str, not a {type(P_abc)}") self._P_abc = P_abc @property def P_d(self): return self._P_d @P_d.setter def P_d(self, P_d: str): if not isinstance(P_d, str): raise TypeError(f"geouned.Tolerances.P_d should be a str, not a {type(P_d)}") self._P_d = P_d @property def P_xyz(self): return self._P_xyz @P_xyz.setter def P_xyz(self, P_xyz: str): if not isinstance(P_xyz, str): raise TypeError(f"geouned.Tolerances.P_xyz should be a str, not a {type(P_xyz)}") self._P_xyz = P_xyz @property def S_r(self): return self._S_r @S_r.setter def S_r(self, S_r: str): if not isinstance(S_r, str): raise TypeError(f"geouned.Tolerances.S_r should be a str, not a {type(S_r)}") self._S_r = S_r @property def S_xyz(self): return self._S_xyz @S_xyz.setter def S_xyz(self, S_xyz: str): if not isinstance(S_xyz, str): raise TypeError(f"geouned.Tolerances.S_xyz should be a str, not a {type(S_xyz)}") self._S_xyz = S_xyz @property def C_r(self): return self._C_r @C_r.setter def C_r(self, C_r: str): if not isinstance(C_r, str): raise TypeError(f"geouned.Tolerances.C_r should be a str, not a {type(C_r)}") self._C_r = C_r @property def C_xyz(self): return self._C_xyz @C_xyz.setter def C_xyz(self, C_xyz: str): if not isinstance(C_xyz, str): raise TypeError(f"geouned.Tolerances.C_xyz should be a str, not a {type(C_xyz)}") self._C_xyz = C_xyz @property def K_xyz(self): return self._K_xyz @K_xyz.setter def K_xyz(self, K_xyz: str): if not isinstance(K_xyz, str): raise TypeError(f"geouned.Tolerances.K_xyz should be a str, not a {type(K_xyz)}") self._K_xyz = K_xyz @property def K_tan2(self): return self._K_tan2 @K_tan2.setter def K_tan2(self, K_tan2: str): if not isinstance(K_tan2, str): raise TypeError(f"geouned.Tolerances.K_tan2 should be a str, not a {type(K_tan2)}") self._K_tan2 = K_tan2 @property def T_r(self): return self._T_r @T_r.setter def T_r(self, T_r: str): if not isinstance(T_r, str): raise TypeError(f"geouned.Tolerances.T_r should be a str, not a {type(T_r)}") self._T_r = T_r @property def T_xyz(self): return self._T_xyz @T_xyz.setter def T_xyz(self, T_xyz: str): if not isinstance(T_xyz, str): raise TypeError(f"geouned.Tolerances.T_xyz should be a str, not a {type(T_xyz)}") self._T_xyz = T_xyz @property def GQ_1to6(self): return self._GQ_1to6 @GQ_1to6.setter def GQ_1to6(self, GQ_1to6: str): if not isinstance(GQ_1to6, str): raise TypeError(f"geouned.Tolerances.GQ_1to6 should be a str, not a {type(GQ_1to6)}") self._GQ_1to6 = GQ_1to6 @property def GQ_7to9(self): return self._GQ_7to9 @GQ_7to9.setter def GQ_7to9(self, GQ_7to9: str): if not isinstance(GQ_7to9, str): raise TypeError(f"geouned.Tolerances.GQ_7to9 should be a str, not a {type(GQ_7to9)}") self._GQ_7to9 = GQ_7to9 @property def GQ_10(self): return self._GQ_10 @GQ_10.setter def GQ_10(self, GQ_10: str): if not isinstance(GQ_10, str): raise TypeError(f"geouned.Tolerances.GQ_10 should be a str, not a {type(GQ_10)}") self._GQ_10 = GQ_10
[docs] class Settings: """Settings for changing the way the CAD to CSG conversion is done Args: matFile (str, optional): _description_. Defaults to "". voidGen (bool, optional): Generate voids of the geometry. Defaults to True. debug (bool, optional): Write step files of original and decomposed solids, for each solid in the STEP file. Defaults to False. compSolids (bool, optional): Join subsolids of STEP file as a single compound solid. Step files generated with SpaceClaim have not exactly the same level of solids as FreeCAD. It may a happened that solids defined has separated solids are read by FreeCAD as a single compound solid (and will produce only one MCNP cell). In this case compSolids should be set to False. Defaults to False. simplify (str, optional): Simplify the cell definition considering relative surfaces position and using Boolean logics. Available options are: "no" no optimization, "void" only void cells are simplified. Algorithm is faster but the simplification is not optimal. "voidfull" : only void cells are simplified with the most optimal algorithm. The time of the conversion can be multiplied by 5 or more. "full" : all the cells (solids and voids) are simplified. Defaults to "No". exportSolids (str, optional): Export CAD solid after reading. The execution is stopped after export, the translation is not carried out. Defaults to "". minVoidSize (float, optional): Minimum size of the edges of the void cell. Units are in mm. Defaults to 200.0. maxSurf (int, optional): #TODO maxBracket (int, optional): Maximum number of brackets (solid complementary) allowed in void cell definition. Defaults to 30. voidMat (list, optional): Assign a material defined by the user instead of void for cells without material definition and the cells generated in the automatic void generation. The format is a 3 valued tuple (mat_label, mat_density, mat_description). Example (100,1e-3,'Air assigned to Void'). Defaults to []. voidExclude (list, optional): #TODO see issue 87. Defaults to []. startCell (int, optional): Starting cell numbering label. Defaults to 1. startSurf (int, optional): Starting surface numbering label. Defaults to 1. sort_enclosure (bool, optional): If enclosures are defined in the CAD models, the voids cells of the enclosure will be located in the output file in the same location where the enclosure solid is located in the CAD solid tree.. Defaults to False. """ def __init__( self, matFile: str = "", voidGen: bool = True, debug: bool = False, compSolids: bool = False, simplify: str = "no", exportSolids: typing.Optional[str] = None, minVoidSize: float = 200.0, # units mm maxSurf: int = 50, maxBracket: int = 30, voidMat: list = [], voidExclude: list = [], startCell: int = 1, startSurf: int = 1, sort_enclosure: bool = False, ): self.matFile = matFile self.voidGen = voidGen self.debug = debug self.compSolids = compSolids self.simplify = simplify self.exportSolids = exportSolids self.minVoidSize = minVoidSize self.maxSurf = maxSurf self.maxBracket = maxBracket self.voidMat = voidMat self.voidExclude = voidExclude self.startCell = startCell self.startSurf = startSurf self.sort_enclosure = sort_enclosure @property def matFile(self): return self._matFile @matFile.setter def matFile(self, matFile: str): if not isinstance(matFile, str): raise TypeError(f"geouned.Settings.matFile should be a str, not a {type(matFile)}") self._matFile = matFile @property def voidGen(self): return self._voidGen @voidGen.setter def voidGen(self, voidGen: bool): if not isinstance(voidGen, bool): raise TypeError(f"geouned.Settings.voidGen should be a bool, not a {type(voidGen)}") self._voidGen = voidGen @property def debug(self): return self._debug @debug.setter def debug(self, debug: bool): if not isinstance(debug, bool): raise TypeError(f"geouned.Settings.debug should be a bool, not a {type(debug)}") self._debug = debug @property def compSolids(self): return self._compSolids @compSolids.setter def compSolids(self, compSolids: bool): if not isinstance(compSolids, bool): raise TypeError(f"geouned.Settings.compSolids should be a bool, not a {type(compSolids)}") self._compSolids = compSolids @property def simplify(self): return self._simplify @simplify.setter def simplify(self, simplify: str): if not isinstance(simplify, str): raise TypeError(f"geouned.Settings.simplify should be a str, not a {type(simplify)}") self._simplify = simplify @property def exportSolids(self): return self._exportSolids @exportSolids.setter def exportSolids(self, exportSolids: str): if exportSolids == None: pass elif not isinstance(exportSolids, str): raise TypeError(f"geouned.Settings.exportSolids should be a str, not a {type(exportSolids)}") self._exportSolids = exportSolids @property def minVoidSize(self): return self._minVoidSize @minVoidSize.setter def minVoidSize(self, minVoidSize: float): if not isinstance(minVoidSize, float): raise TypeError(f"geouned.Settings.minVoidSize should be a float, not a {type(minVoidSize)}") self._minVoidSize = minVoidSize @property def maxSurf(self): return self._maxSurf @maxSurf.setter def maxSurf(self, maxSurf: int): if not isinstance(maxSurf, int): raise TypeError(f"geouned.Settings.maxSurf should be a int, not a {type(maxSurf)}") self._maxSurf = maxSurf @property def maxBracket(self): return self._maxBracket @maxBracket.setter def maxBracket(self, maxBracket: int): if not isinstance(maxBracket, int): raise TypeError(f"geouned.Settings.maxBracket should be a int, not a {type(maxBracket)}") self._maxBracket = maxBracket @property def voidMat(self): return self._voidMat @voidMat.setter def voidMat(self, voidMat: list): if not isinstance(voidMat, list): raise TypeError(f"geouned.Settings.voidMat should be a list, not a {type(voidMat)}") if len(voidMat) == 3: entry0, entry1, entry2 = voidMat if not isinstance(entry0, int): raise TypeError(f"first entry of geouned.Settings.voidMat should be an int, not a {type(entry0)}") if not isinstance(entry1, int): if not isinstance(entry1, float): raise TypeError(f"second entry of geouned.Settings.voidMat should be an int or float, not a {type(entry1)}") if not isinstance(entry2, str): raise TypeError(f"third entry of geouned.Settings.voidMat should be a str, not a {type(entry2)}") elif len(voidMat) > 0: raise TypeError(f"geouned.Settings.voidMat should be a list with 3 elements or void list") self._voidMat = voidMat @property def voidExclude(self): return self._voidExclude @voidExclude.setter def voidExclude(self, voidExclude: list): if not isinstance(voidExclude, list): raise TypeError(f"geouned.Settings.voidExclude should be a list, not a {type(voidExclude)}") for entry in voidExclude: if not isinstance(entry, int): raise TypeError(f"geouned.Settings.voidExclude should be a list of ints, not a {type(entry)}") self._voidExclude = voidExclude @property def startCell(self): return self._startCell @startCell.setter def startCell(self, startCell: int): if not isinstance(startCell, int): raise TypeError(f"geouned.Settings.startCell should be a int, not a {type(startCell)}") self._startCell = startCell @property def startSurf(self): return self._startSurf @startSurf.setter def startSurf(self, startSurf: int): if not isinstance(startSurf, int): raise TypeError(f"geouned.Settings.startSurf should be a int, not a {type(startSurf)}") self._startSurf = startSurf @property def sort_enclosure(self): return self._sort_enclosure @sort_enclosure.setter def sort_enclosure(self, sort_enclosure: bool): if not isinstance(sort_enclosure, bool): raise TypeError(f"geouned.Settings.sort_enclosure should be a bool, not a {type(sort_enclosure)}") self._sort_enclosure = sort_enclosure