diff --git a/src/scaffoldmaker/annotation/bladder_terms.py b/src/scaffoldmaker/annotation/bladder_terms.py index 943a95a1..29e90616 100644 --- a/src/scaffoldmaker/annotation/bladder_terms.py +++ b/src/scaffoldmaker/annotation/bladder_terms.py @@ -4,16 +4,19 @@ # convention: preferred name, preferred id, followed by any other ids and alternative names bladder_terms = [ - ("urinary bladder", "FMA:15900", "UBERON:0001255"), - ("neck of urinary bladder", "FMA:15912", "UBERON:0001258"), + ("urinary bladder", "UBERON:0001255", "FMA:15900"), + ("neck of urinary bladder", "UBERON:0001258", "FMA:15912"), ("Dome of the Bladder", "ILX:0738433"), + ("serosa of urinary bladder", "UBERON:0001260"), + ("bladder lumen", "UBERON:0009958"), ("serosa of body of urinary bladder", "ILX:0739276"), ("lumen of body of urinary bladder", "ILX:0739252"), ("serosa of neck of urinary bladder", "ILX:0739277"), ("lumen of neck of urinary bladder", "ILX:0739256"), - ("urethra", "ILX:0733022"), + ("urethra", "UBERON:0000057", "ILX:0733022"), ("lumen of urethra", "ILX:0736762"), - ("serosa of urethra", "ILX:0739282") + ("serosa of urethra", "ILX:0739282"), + ("ureter", "UBERON:0000056", "ILX:0728080") ] def get_bladder_term(name : str): diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_bladderurethra1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_bladderurethra1.py index e2610285..12a0a5bc 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_bladderurethra1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_bladderurethra1.py @@ -107,13 +107,14 @@ class MeshType_3d_bladderurethra1(Scaffold_base): 'scaffoldSettings': { 'Number of vessels': 1, 'Number of elements around ostium': 8, # implemented for 8 - 'Number of elements along': 2, + 'Number of elements along': 1, 'Unit scale': 1.0, 'Outlet': False, - 'Ostium diameter': 2.0, - 'Ostium length': 1.0, + 'Ostium diameter': 2.2, + 'Ostium length': 0.5, 'Ostium wall thickness': 0.5, 'Use linear through ostium wall': True, + 'Vessel end length factor': 2.0, 'Vessel inner diameter': 0.8, 'Vessel wall thickness': 0.25, 'Vessel angle 1 degrees': 0.0, @@ -136,10 +137,11 @@ class MeshType_3d_bladderurethra1(Scaffold_base): 'Unit scale': 1.0, 'Outlet': False, 'Ostium diameter': 1.0, - 'Ostium length': 0.5, + 'Ostium length': 0.25, 'Ostium wall thickness': 0.02, 'Use linear through ostium wall': True, - 'Vessel inner diameter': 0.4, + 'Vessel end length factor': 2.0, + 'Vessel inner diameter': 0.3, 'Vessel wall thickness': 0.1, 'Vessel angle 1 degrees': 0.0, 'Vessel angle 1 spread degrees': 0.0, @@ -654,6 +656,7 @@ def generateBaseMesh(cls, region, options): neckGroup = AnnotationGroup(region, get_bladder_term("neck of urinary bladder")) bladderGroup = AnnotationGroup(region, get_bladder_term("urinary bladder")) urethraGroup = AnnotationGroup(region, get_bladder_term("urethra")) + ureterGroup = AnnotationGroup(region, get_bladder_term("ureter")) if includeUrethra: elementsCountAlongGroups = [elementsCountAlongBody, elementsCountAlongNeck, elementsCountAlongUrethra] annotationGroupAlong = [[bladderGroup, bodyGroup], [bladderGroup, neckGroup], [urethraGroup]] @@ -679,6 +682,7 @@ def generateBaseMesh(cls, region, options): bodyMeshGroup = bodyGroup.getMeshGroup(mesh) urinaryBladderMeshGroup = bladderGroup.getMeshGroup(mesh) urethraMeshGroup = urethraGroup. getMeshGroup(mesh) + ureterMeshGroup = ureterGroup. getMeshGroup(mesh) # Create nodes and elements nextNodeIdentifier, nextElementIdentifier, annotationGroups = tubemesh.createNodesAndElements( @@ -688,6 +692,8 @@ def generateBaseMesh(cls, region, options): firstNodeIdentifier, firstElementIdentifier, useCubicHermiteThroughWall, useCrossDerivatives, closedProximalEnd=True) + annotationGroups.append(ureterGroup) + # Define outer layer of the bladder to create the trackSurface on it outerNodes_x = [] outerNodes_d1 = [] @@ -736,12 +742,12 @@ def generateBaseMesh(cls, region, options): ureterElementPositionDown, (1 - ureter1Position.xi1) if ureter1Position.xi1 > 0 else ureter1Position.xi1, ureter1Position.xi2) - annulusMeshGroups = [neckMeshGroup, urinaryBladderMeshGroup] - generateUreters(region, nodes, mesh, ureterDefaultOptions, elementsCountAround, elementsCountThroughWall, + bladderMeshGroup = [neckMeshGroup, urinaryBladderMeshGroup] + generateUreterInlets(region, nodes, mesh, ureterDefaultOptions, elementsCountAround, elementsCountThroughWall, elementsCountAroundUreter, trackSurfaceUreter1, ureter1Position, trackSurfaceUreter2, ureter2Position, ureterElementPositionDown, ureterElementPositionAround, xFinal, d1Final, d2Final, nextNodeIdentifier, nextElementIdentifier, elementsCountUreterRadial, - annulusMeshGroups) + ureterMeshGroup, bladderMeshGroup) fm.endChange() return annotationGroups @@ -791,6 +797,10 @@ def defineFaceAnnotations(cls, region, options, annotationGroups): is_neck_serosa = fm.createFieldAnd(is_neck, is_exterior_face_xi3_1) is_neck_lumen = fm.createFieldAnd(is_neck, is_exterior_face_xi3_0) + is_urinaryBladder = urinaryBladderGroup.getFieldElementGroup(mesh2d) + is_urinaryBladder_serosa = fm.createFieldAnd(is_urinaryBladder, is_exterior_face_xi3_1) + is_urinaryBladder_lumen = fm.createFieldAnd(is_urinaryBladder, is_exterior_face_xi3_0) + serosaOfBody = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_bladder_term("serosa of body of urinary bladder")) serosaOfBody.getMeshGroup(mesh2d).addElementsConditional(is_body_serosa) lumenOfBody = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_bladder_term("lumen of body of urinary bladder")) @@ -801,6 +811,11 @@ def defineFaceAnnotations(cls, region, options, annotationGroups): lumenOfNeck = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_bladder_term("lumen of neck of urinary bladder")) lumenOfNeck.getMeshGroup(mesh2d).addElementsConditional(is_neck_lumen) + serosaOfUrinaryBladder = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_bladder_term("serosa of urinary bladder")) + serosaOfUrinaryBladder.getMeshGroup(mesh2d).addElementsConditional(is_urinaryBladder_serosa) + lumenOfUrinaryBladder = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_bladder_term("bladder lumen")) + lumenOfUrinaryBladder.getMeshGroup(mesh2d).addElementsConditional(is_urinaryBladder_lumen) + if options['Include urethra'] == True: urethraGroup = getAnnotationGroupForTerm(annotationGroups, get_bladder_term("urethra")) @@ -813,11 +828,11 @@ def defineFaceAnnotations(cls, region, options, annotationGroups): lumenOfUrethra = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_bladder_term("lumen of urethra")) lumenOfUrethra.getMeshGroup(mesh2d).addElementsConditional(is_urethra_lumen) -def generateUreters(region, nodes, mesh, ureterDefaultOptions,elementsCountAround, elementsCountThroughWall, +def generateUreterInlets(region, nodes, mesh, ureterDefaultOptions,elementsCountAround, elementsCountThroughWall, elementsCountAroundUreter, trackSurfaceUreter1, ureter1Position, trackSurfaceUreter2, ureter2Position, ureterElementPositionDown, ureterElementPositionAround, xBladder, d1Bladder, d2Bladder, nextNodeIdentifier, nextElementIdentifier, - elementsCountUreterRadial, annulusMeshGroups = []): + elementsCountUreterRadial, ureterMeshGroup, bladderMeshGroup): # Create ureters on the surface # Ureter 1 @@ -833,7 +848,7 @@ def generateUreters(region, nodes, mesh, ureterDefaultOptions,elementsCountAroun nodeIdentifier, elementIdentifier, (o1_x, o1_d1, o1_d2, _, o1_NodeId, o1_Positions) = \ generateOstiumMesh(region, ureterDefaultOptions, trackSurfaceUreter1, ureter1Position, ureter1Direction, startNodeIdentifier=nextNodeIdentifier, startElementIdentifier=nextElementIdentifier, - ostiumMeshGroups=None) + vesselMeshGroups=[[ureterMeshGroup]], ostiumMeshGroups=bladderMeshGroup) # Ureter 2 centerUreter2_x, centerUreter2_d1, centerUreter2_d2 = trackSurfaceUreter2.evaluateCoordinates(ureter2Position, @@ -848,7 +863,8 @@ def generateUreters(region, nodes, mesh, ureterDefaultOptions,elementsCountAroun ureter2Direction = vector.crossproduct3(ad3, v2) nodeIdentifier, elementIdentifier, (o2_x, o2_d1, o2_d2, _, o2_NodeId, o2_Positions) = \ generateOstiumMesh(region, ureterDefaultOptions, trackSurfaceUreter2, ureter2Position, ureter2Direction, - startNodeIdentifier=nodeIdentifier, startElementIdentifier=elementIdentifier) + startNodeIdentifier=nodeIdentifier, startElementIdentifier=elementIdentifier, + vesselMeshGroups=[[ureterMeshGroup]], ostiumMeshGroups=bladderMeshGroup) # Create annulus mesh around ureters endPoints1_x = [[None] * elementsCountAroundUreter, [None] * elementsCountAroundUreter] @@ -965,7 +981,7 @@ def generateUreters(region, nodes, mesh, ureterDefaultOptions,elementsCountAroun nodes, mesh, nodeIdentifier, elementIdentifier, o1_x, o1_d1, o1_d2, None, o1_NodeId, None, endPoints1_x, endPoints1_d1, endPoints1_d2, None, endNode1_Id, endDerivativesMap, - elementsCountRadial=elementsCountUreterRadial, meshGroups=annulusMeshGroups, + elementsCountRadial=elementsCountUreterRadial, meshGroups=bladderMeshGroup, tracksurface=trackSurfaceUreter1, startProportions=startProportions1, endProportions=endProportions1, rescaleEndDerivatives=True) @@ -973,7 +989,7 @@ def generateUreters(region, nodes, mesh, ureterDefaultOptions,elementsCountAroun nodes, mesh, nodeIdentifier, elementIdentifier, o2_x, o2_d1, o2_d2, None, o2_NodeId, None, endPoints2_x, endPoints2_d1, endPoints2_d2, None, endNode2_Id, endDerivativesMap, - elementsCountRadial=elementsCountUreterRadial, meshGroups=annulusMeshGroups, + elementsCountRadial=elementsCountUreterRadial, meshGroups=bladderMeshGroup, tracksurface=trackSurfaceUreter2, startProportions=startProportions2, endProportions=endProportions2, rescaleEndDerivatives=True)