Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colon coordinates #157

Merged
merged 21 commits into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f777139
Remove texture coordinates
mlin865 Oct 11, 2021
0001701
Remove texture coordinates in bladder, small intestine and cecum
mlin865 Oct 11, 2021
6aa7469
Add colon coordinates
mlin865 Oct 12, 2021
83258f3
Update tenia coli width for mouse colon
mlin865 Oct 12, 2021
0d97f4b
Allow varying thickness through wall elements
mlin865 Oct 12, 2021
e235d77
Restrict number of elements through wall to 4 in colon
mlin865 Oct 12, 2021
a1923f9
Annotate colon wall layers
mlin865 Oct 12, 2021
a5bb3ce
Update unit tests
mlin865 Oct 13, 2021
15731d7
Match tenai coli thickness to 0.25 of wall thickness
mlin865 Oct 17, 2021
5569558
Use 0.25 as thickness ratio for all layers for colon coordinates
mlin865 Oct 17, 2021
873a18d
Increase mesenteric zone width in cattle colon
mlin865 Oct 18, 2021
a2e5d91
Allow 1 to 4 elements through wall
mlin865 Oct 18, 2021
71351f3
Annotate serosa using 2D outside surface of colon
mlin865 Oct 18, 2021
6146e3a
Remove annotation group for myenteric nerve plexus
mlin865 Oct 18, 2021
a99581c
Make tenia coli thickness 0.25 of wall thickness in colon coordinates
mlin865 Oct 18, 2021
27a77fc
Recalculate thickness proportions for less than 4 elements through wall
mlin865 Oct 18, 2021
8ffbd3c
Add annotation for inner surface of colonic mucosa
mlin865 Oct 18, 2021
b050540
Remove longitudinal muscle annotation for tenia coli for 1 element th…
mlin865 Oct 18, 2021
b2cc273
Remove upper case
mlin865 Oct 18, 2021
f5eec0a
Update unit tests
mlin865 Oct 18, 2021
c20a504
Limit number of elements through wall to 1 and 4
mlin865 Oct 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/scaffoldmaker/annotation/colon_terms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
( "ascending colon", "UBERON:0001156", "FMA:14545", "ILX:0734393"),
( "descending colon", "UBERON:0001158", "FMA:14547", "ILX:0724444"),
( "caecum", "UBERON:0001153", "FMA:14541", "ILX:0732270"),
( "Circular muscle layer of colon", "ILX:0772428"),
( "colon", "UBERON:0001155", "FMA:14543", "ILX:0736005"),
( "colonic mucosa", "UBERON:0000317", "FMA:14984", "ILX:0731046"),
( "distal colon", "UBERON:0008971", "ILX:0727523"),
( "Longitudinal muscle layer of colon", "ILX:0775554"),
( "mesenteric zone", "None"),
( "myenteric nerve plexus", "UBERON:0002439", "FMA:63252", "ILX:0725342"),
( "non-mesenteric zone", "None"),
( "proximal colon", "UBERON:0008972", "ILX:0733240"),
( "serosa of colon", "UBERON:0003335", "FMA:14990", "ILX:0736932"),
Expand Down
8 changes: 5 additions & 3 deletions src/scaffoldmaker/meshtypes/meshtype_3d_bladderurethra1.py
Original file line number Diff line number Diff line change
Expand Up @@ -860,9 +860,11 @@ def generateBaseMesh(cls, region, options):
wallThicknessList = [bladderWallThickness] * (elementsCountAlong + 1)
transitElementList = [0] * elementsCountAround

relativeThicknessList = []
xList, d1List, d2List, d3List, curvatureList = tubemesh.getCoordinatesFromInner(xWarpedList, d1WarpedList,
d2WarpedList, d3WarpedUnitList,
wallThicknessList,
relativeThicknessList,
elementsCountAround,
elementsCountAlong,
elementsCountThroughWall,
Expand Down Expand Up @@ -902,8 +904,8 @@ def generateBaseMesh(cls, region, options):
d2Final += d2List[(elementsCountThroughWall + 1) * elementsCountAround:]
d3Final += d3List[(elementsCountThroughWall + 1) * elementsCountAround:]

xFlat = d1Flat = d2Flat = d3Flat = []
xTexture = d1Texture = d2Texture = d3Texture = []
xFlat = d1Flat = d2Flat = []
xOrgan = d1Organ = d2Organ = []

# Obtain elements count along body and neck of the bladder for defining annotation groups
elementsCountAlongBody = round(ureterPositionDown * elementsCountAlongBladder - 1)
Expand Down Expand Up @@ -1004,7 +1006,7 @@ def generateBaseMesh(cls, region, options):

# Create nodes and elements
nextNodeIdentifier, nextElementIdentifier, annotationGroups = tubemesh.createNodesAndElements(
region, xFinal, d1Final, d2Final, d3Final, xFlat, d1Flat, d2Flat, xTexture, d1Texture, d2Texture,
region, xFinal, d1Final, d2Final, d3Final, xFlat, d1Flat, d2Flat, xOrgan, d1Organ, d2Organ, None,
elementsCountAround, elementsCountAlong, elementsCountThroughWall,
annotationGroupsAround, annotationGroupsAlong, annotationGroupsThroughWall,
firstNodeIdentifier, firstElementIdentifier,
Expand Down
11 changes: 6 additions & 5 deletions src/scaffoldmaker/meshtypes/meshtype_3d_cecum1.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,9 @@ def generateBaseMesh(cls, region, options):
# Create coordinates and derivatives
wallThicknessList = [wallThickness] * (elementsCountAlong + 1)

relativeThicknessList = []
xList, d1List, d2List, d3List, curvatureList = tubemesh.getCoordinatesFromInner(xWarpedList, d1WarpedList,
d2WarpedList, d3WarpedUnitList, wallThicknessList,
d2WarpedList, d3WarpedUnitList, wallThicknessList, relativeThicknessList,
elementsCountAround, elementsCountAlong, elementsCountThroughWall, transitElementList)

# Deal with multiple nodes at end point for closed proximal end
Expand Down Expand Up @@ -463,8 +464,8 @@ def generateBaseMesh(cls, region, options):
d2Cecum += d2List[(elementsCountThroughWall + 1) * elementsCountAround:]
d3Cecum += d3List[(elementsCountThroughWall + 1) * elementsCountAround:]

xFlat = d1Flat = d2Flat = d3Flat = []
xTexture = d1Texture = d2Texture = d3Texture = []
xFlat = d1Flat = d2Flat = []
xOrgan = d1Organ = d2Organ = []

# Create nodes and elements
if tcThickness > 0:
Expand All @@ -475,15 +476,15 @@ def generateBaseMesh(cls, region, options):
tubeTCWidthList, tcThickness, sxRefList, annotationGroupsAround, closedProximalEnd)

nextNodeIdentifier, nextElementIdentifier, annotationGroups = createNodesAndElementsTeniaColi(
region, xCecum, d1Cecum, d2Cecum, d3Cecum, xFlat, d1Flat, d2Flat, xTexture, d1Texture, d2Texture,
region, xCecum, d1Cecum, d2Cecum, d3Cecum, xFlat, d1Flat, d2Flat, xOrgan, d1Organ, d2Organ, None,
elementsCountAroundTC, elementsCountAroundHaustrum, elementsCountAlong, elementsCountThroughWall,
tcCount, annotationGroupsAround, annotationGroupsAlong, annotationGroupsThroughWall,
firstNodeIdentifier, firstElementIdentifier, useCubicHermiteThroughWall, useCrossDerivatives,
closedProximalEnd)

else:
nextNodeIdentifier, nextElementIdentifier, annotationGroups = tubemesh.createNodesAndElements(
region, xCecum, d1Cecum, d2Cecum, d3Cecum, xFlat, d1Flat, d2Flat, xTexture, d1Texture, d2Texture,
region, xCecum, d1Cecum, d2Cecum, d3Cecum, xFlat, d1Flat, d2Flat, xOrgan, d1Organ, d2Organ, None,
elementsCountAround, elementsCountAlong, elementsCountThroughWall,
annotationGroupsAround, annotationGroupsAlong, annotationGroupsThroughWall,
firstNodeIdentifier, firstElementIdentifier, useCubicHermiteThroughWall, useCrossDerivatives,
Expand Down
109 changes: 87 additions & 22 deletions src/scaffoldmaker/meshtypes/meshtype_3d_colon1.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
"""

import copy
from scaffoldmaker.annotation.annotationgroup import AnnotationGroup
from opencmiss.zinc.element import Element
from scaffoldmaker.annotation.annotationgroup import AnnotationGroup, findOrCreateAnnotationGroupForTerm, getAnnotationGroupForTerm
from scaffoldmaker.annotation.colon_terms import get_colon_term
from scaffoldmaker.meshtypes.meshtype_1d_path1 import MeshType_1d_path1, extractPathParametersFromRegion
from scaffoldmaker.meshtypes.meshtype_3d_colonsegment1 import MeshType_3d_colonsegment1, ColonSegmentTubeMeshInnerPoints,\
getTeniaColi, createFlatAndTextureCoordinatesTeniaColi, createNodesAndElementsTeniaColi
getTeniaColi, createFlatCoordinatesTeniaColi, createColonCoordinatesTeniaColi, createNodesAndElementsTeniaColi
from scaffoldmaker.meshtypes.scaffold_base import Scaffold_base
from scaffoldmaker.scaffoldpackage import ScaffoldPackage
from scaffoldmaker.utils import interpolation as interp
Expand Down Expand Up @@ -313,11 +314,11 @@ def getDefaultOptions(cls, parameterSetName='Default'):
options['Proximal inner radius'] = 1.0
options['Proximal tenia coli width'] = 0.5
options['Proximal-transverse inner radius'] = 0.9
options['Proximal-transverse tenia coli width'] = 0.7
options['Proximal-transverse tenia coli width'] = 0.5
options['Transverse-distal inner radius'] = 0.7
options['Transverse-distal tenia coli width'] = 1.0
options['Transverse-distal tenia coli width'] = 0.5
options['Distal inner radius'] = 0.7
options['Distal tenia coli width'] = 1.0
options['Distal tenia coli width'] = 0.5
elif 'Pig 1' in parameterSetName:
options['Number of segments'] = 120
options['Proximal length'] = 3000.0
Expand Down Expand Up @@ -471,10 +472,19 @@ def generateBaseMesh(cls, region, options):
elementsCountAlongSegment = segmentSettings['Number of elements along segment']
elementsCountThroughWall = segmentSettings['Number of elements through wall']
wallThickness = segmentSettings['Wall thickness']
mucosaRelThickness = segmentSettings['Mucosa relative thickness']
submucosaRelThickness = segmentSettings['Submucosa relative thickness']
circularRelThickness = segmentSettings['Circular muscle layer relative thickness']
longitudinalRelThickness = segmentSettings['Longitudinal muscle layer relative thickness']
useCrossDerivatives = segmentSettings['Use cross derivatives']
useCubicHermiteThroughWall = not(segmentSettings['Use linear through wall'])
elementsCountAlong = int(elementsCountAlongSegment*segmentCount)

# Colon coordinates
lengthToDiameterRatio = 24
wallThicknessToDiameterRatio = 0.1
teniaColiThicknessToDiameterRatio = 0.005

firstNodeIdentifier = 1
firstElementIdentifier = 1

Expand Down Expand Up @@ -565,16 +575,21 @@ def generateBaseMesh(cls, region, options):
for n in range(elementsCount):
annotationGroupsAlong.append(annotationGroupAlong[i])

annotationGroupsThroughWall = []
for i in range(elementsCountThroughWall):
annotationGroupsThroughWall.append([ ])
mucosaGroup = AnnotationGroup(region, get_colon_term("colonic mucosa"))
submucosaGroup = AnnotationGroup(region, get_colon_term("submucosa of colon"))
circularMuscleGroup = AnnotationGroup(region, get_colon_term("Circular muscle layer of colon"))
longitudinalMuscleGroup = AnnotationGroup(region, get_colon_term("Longitudinal muscle layer of colon"))
annotationGroupsThroughWall = [[mucosaGroup], [submucosaGroup], [circularMuscleGroup], [longitudinalMuscleGroup]]

xExtrude = []
d1Extrude = []
d2Extrude = []
d3UnitExtrude = []
sxRefExtrudeList = []

relativeThicknessList = [mucosaRelThickness, submucosaRelThickness, circularRelThickness,
longitudinalRelThickness]

# Create object
colonSegmentTubeMeshInnerPoints = ColonSegmentTubeMeshInnerPoints(
region, elementsCountAroundTC, elementsCountAroundHaustrum, elementsCountAlongSegment,
Expand Down Expand Up @@ -613,7 +628,7 @@ def generateBaseMesh(cls, region, options):

# Create coordinates and derivatives
xList, d1List, d2List, d3List, curvatureList = tubemesh.getCoordinatesFromInner(xExtrude, d1Extrude,
d2Extrude, d3UnitExtrude, contractedWallThicknessList,
d2Extrude, d3UnitExtrude, contractedWallThicknessList, relativeThicknessList,
elementsCountAround, elementsCountAlong, elementsCountThroughWall, transitElementList)

relaxedLengthList, xiList = colonSegmentTubeMeshInnerPoints.getRelaxedLengthAndXiList()
Expand All @@ -628,30 +643,48 @@ def generateBaseMesh(cls, region, options):
tubeTCWidthList, tcThickness, sxRefExtrudeList, annotationGroupsAround,
closedProximalEnd)

# Create flat and texture coordinates
xFlat, d1Flat, d2Flat, xTexture, d1Texture, d2Texture = createFlatAndTextureCoordinatesTeniaColi(
xiList, relaxedLengthList, length, wallThickness, tcCount, tcThickness,
# Create flat coordinates
xFlat, d1Flat, d2Flat = createFlatCoordinatesTeniaColi(
xiList, relaxedLengthList, length, wallThickness, relativeThicknessList, tcCount, tcThickness,
elementsCountAroundTC, elementsCountAroundHaustrum, elementsCountAlong,
elementsCountThroughWall, transitElementList, closedProximalEnd)

# Create colon coordinates
xColon, d1Colon, d2Colon = createColonCoordinatesTeniaColi(xiList, relativeThicknessList,
lengthToDiameterRatio,
wallThicknessToDiameterRatio,
teniaColiThicknessToDiameterRatio, tcCount,
elementsCountAroundTC,
elementsCountAroundHaustrum,
elementsCountAlong, elementsCountThroughWall,
transitElementList, closedProximalEnd)

# Create nodes and elements
nextNodeIdentifier, nextElementIdentifier, annotationGroups = createNodesAndElementsTeniaColi(
region, xList, d1List, d2List, d3List, xFlat, d1Flat, d2Flat, xTexture, d1Texture, d2Texture,
elementsCountAroundTC, elementsCountAroundHaustrum, elementsCountAlong, elementsCountThroughWall,
tcCount, annotationGroupsAround, annotationGroupsAlong, annotationGroupsThroughWall,
firstNodeIdentifier, firstElementIdentifier, useCubicHermiteThroughWall, useCrossDerivatives,
closedProximalEnd)
region, xList, d1List, d2List, d3List, xFlat, d1Flat, d2Flat, xColon, d1Colon, d2Colon,
"colon coordinates", elementsCountAroundTC, elementsCountAroundHaustrum, elementsCountAlong,
elementsCountThroughWall, tcCount, annotationGroupsAround, annotationGroupsAlong,
annotationGroupsThroughWall, firstNodeIdentifier, firstElementIdentifier, useCubicHermiteThroughWall,
useCrossDerivatives, closedProximalEnd)

else:
# Create flat and texture coordinates
xFlat, d1Flat, d2Flat, xTexture, d1Texture, d2Texture = tubemesh.createFlatAndTextureCoordinates(
xiList, relaxedLengthList, length, wallThickness, elementsCountAround,
# Create flat coordinates
xFlat, d1Flat, d2Flat = tubemesh.createFlatCoordinates(
xiList, relaxedLengthList, length, wallThickness, relativeThicknessList, elementsCountAround,
elementsCountAlong, elementsCountThroughWall, transitElementList)

# Create colon coordinates
xColon, d1Colon, d2Colon = tubemesh.createOrganCoordinates(xiList, relativeThicknessList,
lengthToDiameterRatio,
wallThicknessToDiameterRatio,
elementsCountAround,
elementsCountAlong, elementsCountThroughWall,
transitElementList)

# Create nodes and elements
nextNodeIdentifier, nextElementIdentifier, annotationGroups = tubemesh.createNodesAndElements(
region, xList, d1List, d2List, d3List, xFlat, d1Flat, d2Flat, xTexture, d1Texture, d2Texture,
elementsCountAround, elementsCountAlong, elementsCountThroughWall,
region, xList, d1List, d2List, d3List, xFlat, d1Flat, d2Flat, xColon, d1Colon, d2Colon,
"colon coordinates", elementsCountAround, elementsCountAlong, elementsCountThroughWall,
annotationGroupsAround, annotationGroupsAlong, annotationGroupsThroughWall,
firstNodeIdentifier, firstElementIdentifier, useCubicHermiteThroughWall, useCrossDerivatives,
closedProximalEnd)
Expand All @@ -672,3 +705,35 @@ def refineMesh(cls, meshrefinement, options):
meshrefinement.refineAllElementsCubeStandard3d(refineElementsCountAround, refineElementsCountAlong,
refineElementsCountThroughWall)
return

@classmethod
def defineFaceAnnotations(cls, region, options, annotationGroups):
'''
Add face annotation groups from the highest dimension mesh.
Must have defined faces and added subelements for highest dimension groups.
:param region: Zinc region containing model.
:param options: Dict containing options. See getDefaultOptions().
:param annotationGroups: List of annotation groups for top-level elements.
New face annotation groups are appended to this list.
'''
# Create 2d surface mesh groups
fm = region.getFieldmodule()
longitudinalMuscleGroup = getAnnotationGroupForTerm(annotationGroups,
get_colon_term("Longitudinal muscle layer of colon"))
circularMuscleGroup = getAnnotationGroupForTerm(annotationGroups,
get_colon_term("Circular muscle layer of colon"))
mesh2d = fm.findMeshByDimension(2)
is_exterior = fm.createFieldIsExterior()
is_exterior_face_xi3_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_1))

is_longitudinalMuscle = longitudinalMuscleGroup.getFieldElementGroup(mesh2d)
is_serosa = fm.createFieldAnd(is_longitudinalMuscle, is_exterior_face_xi3_1)
is_circularMuscle = circularMuscleGroup.getFieldElementGroup(mesh2d)
is_myentericPlexus = fm.createFieldAnd(is_longitudinalMuscle, is_circularMuscle)

serosa = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_colon_term("serosa of colon"))
serosa.getMeshGroup(mesh2d).addElementsConditional(is_serosa)

myentericPlexus = findOrCreateAnnotationGroupForTerm(annotationGroups, region,
get_colon_term("myenteric nerve plexus"))
myentericPlexus.getMeshGroup(mesh2d).addElementsConditional(is_myentericPlexus)
Loading