Skip to content

Commit

Permalink
Merge pull request #66 from rchristie/annotation
Browse files Browse the repository at this point in the history
Improve annotation groups
  • Loading branch information
hsorby authored Jan 20, 2020
2 parents 4df3b04 + 137144e commit 3f08256
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 112 deletions.
37 changes: 19 additions & 18 deletions src/scaffoldmaker/meshtypes/meshtype_3d_heart1.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import math
from opencmiss.utils.zinc.field import findOrCreateFieldCoordinates, findOrCreateFieldGroup, \
findOrCreateFieldNodeGroup, findOrCreateFieldStoredMeshLocation, findOrCreateFieldStoredString
from opencmiss.utils.zinc.finiteelement import getMaximumElementIdentifier
from opencmiss.utils.zinc.finiteelement import getMaximumElementIdentifier, getMaximumNodeIdentifier
from opencmiss.zinc.element import Element
from opencmiss.zinc.field import Field
from opencmiss.zinc.node import Node
Expand Down Expand Up @@ -135,23 +135,23 @@ def generateBaseMesh(cls, region, options):
annotationGroups += [ lFibrousRingGroup, rFibrousRingGroup ]

# annotation fiducial points
fiducialGroup = findOrCreateFieldGroup(fm, 'fiducial')
fiducialCoordinates = findOrCreateFieldCoordinates(fm, 'fiducial_coordinates')
fiducialLabel = findOrCreateFieldStoredString(fm, name='fiducial_label')
fiducialElementXi = findOrCreateFieldStoredMeshLocation(fm, mesh, name='fiducial_element_xi')

datapoints = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_DATAPOINTS)
fiducialPoints = findOrCreateFieldNodeGroup(fiducialGroup, datapoints).getNodesetGroup()
datapointTemplateInternal = datapoints.createNodetemplate()
datapointTemplateInternal.defineField(fiducialCoordinates)
datapointTemplateInternal.defineField(fiducialLabel)
datapointTemplateInternal.defineField(fiducialElementXi)
markerGroup = findOrCreateFieldGroup(fm, "marker")
markerCoordinates = findOrCreateFieldCoordinates(fm, "marker_coordinates")
markerName = findOrCreateFieldStoredString(fm, name="marker_name")
markerLocation = findOrCreateFieldStoredMeshLocation(fm, mesh, name="marker_location")

nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
markerPoints = findOrCreateFieldNodeGroup(markerGroup, nodes).getNodesetGroup()
markerTemplateInternal = nodes.createNodetemplate()
markerTemplateInternal.defineField(markerCoordinates)
markerTemplateInternal.defineField(markerName)
markerTemplateInternal.defineField(markerLocation)

##############
# Create nodes
##############

nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
nodeIdentifier = max(1, getMaximumNodeIdentifier(nodes) + 1)

# discover left and right fibrous ring nodes from ventricles and atria
# because nodes are iterated in identifier order, the lowest and first are on the lv outlet cfb, right and left on lower outer layers
Expand Down Expand Up @@ -404,11 +404,12 @@ def generateBaseMesh(cls, region, options):
cruxXi = [ 0.0, 0.5, 1.0 ]
cache.setMeshLocation(cruxElement, cruxXi)
result, cruxCoordinates = coordinates.evaluateReal(cache, 3)
datapoint = fiducialPoints.createNode(-1, datapointTemplateInternal)
cache.setNode(datapoint)
fiducialCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, cruxCoordinates)
fiducialLabel.assignString(cache, 'crux')
fiducialElementXi.assignMeshLocation(cache, cruxElement, cruxXi)
markerPoint = markerPoints.createNode(nodeIdentifier, markerTemplateInternal)
nodeIdentifier += 1
cache.setNode(markerPoint)
markerCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, cruxCoordinates)
markerName.assignString(cache, 'crux')
markerLocation.assignMeshLocation(cache, cruxElement, cruxXi)

fm.endChange()
return annotationGroups
Expand Down
29 changes: 14 additions & 15 deletions src/scaffoldmaker/meshtypes/meshtype_3d_heartarterialroot1.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,23 +137,21 @@ def generateBaseMesh(cls, region, options, baseCentre=[ 0.0, 0.0, 0.0 ], axisSid
annotationGroups = allGroups + cuspGroups

# annotation fiducial points
fiducialGroup = findOrCreateFieldGroup(fm, 'fiducial')
fiducialCoordinates = findOrCreateFieldCoordinates(fm, 'fiducial_coordinates')
fiducialLabel = findOrCreateFieldStoredString(fm, name='fiducial_label')
#fiducialElementXi = findOrCreateFieldStoredMeshLocation(fm, mesh, name='fiducial_element_xi')
markerGroup = findOrCreateFieldGroup(fm, "marker")
markerCoordinates = findOrCreateFieldCoordinates(fm, "marker_coordinates")
markerName = findOrCreateFieldStoredString(fm, name="marker_name")
#markerLocation = findOrCreateFieldStoredMeshLocation(fm, mesh, name="marker_location")

datapoints = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_DATAPOINTS)
fiducialPoints = findOrCreateFieldNodeGroup(fiducialGroup, datapoints).getNodesetGroup()
datapointTemplateExternal = datapoints.createNodetemplate()
datapointTemplateExternal.defineField(fiducialCoordinates)
datapointTemplateExternal.defineField(fiducialLabel)
nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
markerPoints = findOrCreateFieldNodeGroup(markerGroup, nodes).getNodesetGroup()
markerTemplateExternal = nodes.createNodetemplate()
markerTemplateExternal.defineField(markerCoordinates)
markerTemplateExternal.defineField(markerName)

#################
# Create nodes
#################

nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)

nodetemplate = nodes.createNodetemplate()
nodetemplate.defineField(coordinates)
nodetemplate.setValueNumberOfVersions(coordinates, -1, Node.VALUE_LABEL_VALUE, 1)
Expand Down Expand Up @@ -509,10 +507,11 @@ def generateBaseMesh(cls, region, options, baseCentre=[ 0.0, 0.0, 0.0 ], axisSid

# create annotation points

datapoint = fiducialPoints.createNode(-1, datapointTemplateExternal)
cache.setNode(datapoint)
fiducialCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, noduleCentre)
fiducialLabel.assignString(cache, 'aortic valve ctr' if aorticNotPulmonary else 'pulmonary valve ctr')
markerPoint = markerPoints.createNode(nodeIdentifier, markerTemplateExternal)
nodeIdentifier += 1
cache.setNode(markerPoint)
markerCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, noduleCentre)
markerName.assignString(cache, 'aortic valve ctr' if aorticNotPulmonary else 'pulmonary valve ctr')

fm.endChange()
return annotationGroups
Expand Down
43 changes: 39 additions & 4 deletions src/scaffoldmaker/meshtypes/meshtype_3d_heartatria1.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,10 +736,10 @@ def generateBaseMesh(cls, region, options):
coordinates = findOrCreateFieldCoordinates(fm)
cache = fm.createFieldcache()

laGroup = AnnotationGroup(region, 'left atrium', FMANumber = 7097, lyphID = 'Lyph ID unknown')
raGroup = AnnotationGroup(region, 'right atrium', FMANumber = 7096, lyphID = 'Lyph ID unknown')
aSeptumGroup = AnnotationGroup(region, 'interatrial septum', FMANumber = 7108, lyphID = 'Lyph ID unknown')
fossaGroup = AnnotationGroup(region, 'fossa ovalis', FMANumber = 9246, lyphID = 'Lyph ID unknown')
laGroup = AnnotationGroup(region, "left atrium myocardium", FMANumber = 7285, lyphID = "Lyph ID unknown")
raGroup = AnnotationGroup(region, "right atrium myocardium", FMANumber = 7282, lyphID = "Lyph ID unknown")
aSeptumGroup = AnnotationGroup(region, "interatrial septum", FMANumber = 7108, lyphID = "Lyph ID unknown")
fossaGroup = AnnotationGroup(region, "fossa ovalis", FMANumber = 9246, lyphID = "Lyph ID unknown")
laaGroup = AnnotationGroup(region, 'left atrial appendage', FMANumber = 7219, lyphID = 'Lyph ID unknown')
raaGroup = AnnotationGroup(region, 'right atrial appendage', FMANumber = 7218, lyphID = 'Lyph ID unknown')
annotationGroups = [ laGroup, raGroup, aSeptumGroup, fossaGroup, laaGroup, raaGroup ]
Expand Down Expand Up @@ -3164,6 +3164,41 @@ def generateBaseMesh(cls, region, options):
nid1 = raTrackSurfaceFirstNodeIdentifier + e2*nodesCount1 + e1
element.setNodesByIdentifier(eft2d, [ nid1, nid1 + 1, nid1 + nodesCount1, nid1 + nodesCount1 + 1 ])

# create endocardium and epicardium groups
fm.defineAllFaces()
laGroup.addSubelements()
raGroup.addSubelements()
aSeptumGroup.addSubelements()
mesh2d = fm.findMeshByDimension(2)
is_exterior = fm.createFieldIsExterior()
is_exterior_face_xi3_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_0))
is_exterior_face_xi3_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_1))
is_la = laGroup.getFieldElementGroup(mesh2d)
is_ra = raGroup.getFieldElementGroup(mesh2d)
is_la_endo = fm.createFieldAnd(is_la, is_exterior_face_xi3_0)
is_ra_endo = fm.createFieldOr(fm.createFieldAnd(fm.createFieldAnd(is_ra, is_exterior_face_xi3_0),
fm.createFieldNot(is_la_endo)),
fm.createFieldAnd(aSeptumGroup.getFieldElementGroup(mesh2d), is_exterior_face_xi3_1))
is_a_epi = fm.createFieldAnd(fm.createFieldOr(is_la, is_ra),
fm.createFieldAnd(is_exterior_face_xi3_1,
fm.createFieldNot(aSeptumGroup.getFieldElementGroup(mesh2d))))
laEndoGroup = AnnotationGroup(region, "Endocardium of left atrium", FMANumber = 7286, lyphID = 'Lyph ID unknown')
laEndoGroup.getMeshGroup(mesh2d).addElementsConditional(is_la_endo)
raEndoGroup = AnnotationGroup(region, "Endocardium of right atrium", FMANumber = 7281, lyphID = 'Lyph ID unknown')
raEndoGroup.getMeshGroup(mesh2d).addElementsConditional(is_ra_endo)
# Note I could not find any epicardium of atria
aEpiGroup = AnnotationGroup(region, "Epicardium of atrium", FMANumber = 0, lyphID = 'Lyph ID unknown')
aEpiGroup.getMeshGroup(mesh2d).addElementsConditional(is_a_epi)
del is_exterior
del is_exterior_face_xi3_0
del is_exterior_face_xi3_1
del is_la
del is_ra
del is_la_endo
del is_ra_endo
del is_a_epi
annotationGroups += [ laEndoGroup, raEndoGroup, aEpiGroup ]

fm.endChange()
return annotationGroups

Expand Down
8 changes: 4 additions & 4 deletions src/scaffoldmaker/meshtypes/meshtype_3d_heartatria2.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@ def generateBaseMesh(cls, region, options):
coordinates = findOrCreateFieldCoordinates(fm)
cache = fm.createFieldcache()

laGroup = AnnotationGroup(region, 'left atrium', FMANumber = 7097, lyphID = 'Lyph ID unknown')
raGroup = AnnotationGroup(region, 'right atrium', FMANumber = 7096, lyphID = 'Lyph ID unknown')
aSeptumGroup = AnnotationGroup(region, 'interatrial septum', FMANumber = 7108, lyphID = 'Lyph ID unknown')
fossaGroup = AnnotationGroup(region, 'fossa ovalis', FMANumber = 9246, lyphID = 'Lyph ID unknown')
laGroup = AnnotationGroup(region, "left atrium myocardium", FMANumber = 7285, lyphID = "Lyph ID unknown")
raGroup = AnnotationGroup(region, "right atrium myocardium", FMANumber = 7282, lyphID = "Lyph ID unknown")
aSeptumGroup = AnnotationGroup(region, "interatrial septum", FMANumber = 7108, lyphID = "Lyph ID unknown")
fossaGroup = AnnotationGroup(region, "fossa ovalis", FMANumber = 9246, lyphID = "Lyph ID unknown")
lipvGroup = AnnotationGroup(region, 'left inferior pulmonary vein', FMANumber = 49913, lyphID = 'Lyph ID unknown')
lspvGroup = AnnotationGroup(region, 'left superior pulmonary vein', FMANumber = 49916, lyphID = 'Lyph ID unknown')
ripvGroup = AnnotationGroup(region, 'right inferior pulmonary vein', FMANumber = 49911, lyphID = 'Lyph ID unknown')
Expand Down
85 changes: 59 additions & 26 deletions src/scaffoldmaker/meshtypes/meshtype_3d_heartventricles1.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,29 +249,27 @@ def generateBaseMesh(cls, region, options):

mesh = fm.findMeshByDimension(3)

lvGroup = AnnotationGroup(region, 'left ventricle', FMANumber = 7101, lyphID = 'Lyph ID unknown')
rvGroup = AnnotationGroup(region, 'right ventricle', FMANumber = 7098, lyphID = 'Lyph ID unknown')
vSeptumGroup = AnnotationGroup(region, 'interventricular septum', FMANumber = 7133, lyphID = 'Lyph ID unknown')
lvGroup = AnnotationGroup(region, "left ventricle myocardium", FMANumber = 9558, lyphID = 'Lyph ID unknown')
rvGroup = AnnotationGroup(region, "right ventricle myocardium", FMANumber = 9535, lyphID = 'Lyph ID unknown')
vSeptumGroup = AnnotationGroup(region, "interventricular septum", FMANumber = 7133, lyphID = 'Lyph ID unknown')
annotationGroups = [ lvGroup, rvGroup, vSeptumGroup ]

# annotation fiducial points
fiducialGroup = findOrCreateFieldGroup(fm, 'fiducial')
fiducialCoordinates = findOrCreateFieldCoordinates(fm, 'fiducial_coordinates')
fiducialLabel = findOrCreateFieldStoredString(fm, name='fiducial_label')
fiducialElementXi = findOrCreateFieldStoredMeshLocation(fm, mesh, name='fiducial_element_xi')

datapoints = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_DATAPOINTS)
fiducialPoints = findOrCreateFieldNodeGroup(fiducialGroup, datapoints).getNodesetGroup()
datapointTemplateInternal = datapoints.createNodetemplate()
datapointTemplateInternal.defineField(fiducialCoordinates)
datapointTemplateInternal.defineField(fiducialLabel)
datapointTemplateInternal.defineField(fiducialElementXi)
markerGroup = findOrCreateFieldGroup(fm, "marker")
markerCoordinates = findOrCreateFieldCoordinates(fm, "marker_coordinates")
markerName = findOrCreateFieldStoredString(fm, name="marker_name")
markerLocation = findOrCreateFieldStoredMeshLocation(fm, mesh, name="marker_location")

nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
markerPoints = findOrCreateFieldNodeGroup(markerGroup, nodes).getNodesetGroup()
markerTemplateInternal = nodes.createNodetemplate()
markerTemplateInternal.defineField(markerCoordinates)
markerTemplateInternal.defineField(markerName)
markerTemplateInternal.defineField(markerLocation)

#################
# Create nodes
#################

nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
nodetemplate = nodes.createNodetemplate()
nodetemplate.defineField(coordinates)
nodetemplate.setValueNumberOfVersions(coordinates, -1, Node.VALUE_LABEL_VALUE, 1)
Expand Down Expand Up @@ -1037,18 +1035,53 @@ def generateBaseMesh(cls, region, options):
for meshGroup in meshGroups:
meshGroup.addElement(element)

# create endocardium and epicardium groups
fm.defineAllFaces()
lvGroup.addSubelements()
rvGroup.addSubelements()
vSeptumGroup.addSubelements()
mesh2d = fm.findMeshByDimension(2)
is_exterior = fm.createFieldIsExterior()
is_exterior_face_xi3_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_0))
is_exterior_face_xi3_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_1))
is_lv = lvGroup.getFieldElementGroup(mesh2d)
is_rv = rvGroup.getFieldElementGroup(mesh2d)
is_lv_endo = fm.createFieldAnd(is_lv, is_exterior_face_xi3_0)
is_rv_endo = fm.createFieldOr(fm.createFieldAnd(fm.createFieldAnd(is_rv, is_exterior_face_xi3_0),
fm.createFieldNot(is_lv_endo)),
fm.createFieldAnd(vSeptumGroup.getFieldElementGroup(mesh2d), is_exterior_face_xi3_1))
is_epi = fm.createFieldAnd(is_exterior_face_xi3_1,
fm.createFieldNot(vSeptumGroup.getFieldElementGroup(mesh2d)))
lvEndoGroup = AnnotationGroup(region, "Endocardium of left ventricle", FMANumber = 9559, lyphID = 'Lyph ID unknown')
lvEndoGroup.getMeshGroup(mesh2d).addElementsConditional(is_lv_endo)
rvEndoGroup = AnnotationGroup(region, "Endocardium of right ventricle", FMANumber = 9536, lyphID = 'Lyph ID unknown')
rvEndoGroup.getMeshGroup(mesh2d).addElementsConditional(is_rv_endo)
vEpiGroup = AnnotationGroup(region, "Epicardium of ventricle", FMANumber = 12150, lyphID = 'Lyph ID unknown')
vEpiGroup.getMeshGroup(mesh2d).addElementsConditional(is_epi)
del is_exterior
del is_exterior_face_xi3_0
del is_exterior_face_xi3_1
del is_lv
del is_rv
del is_lv_endo
del is_rv_endo
del is_epi
annotationGroups += [ lvEndoGroup, rvEndoGroup, vEpiGroup ]

# apex annotation points
element1 = mesh.findElementByIdentifier(1)
datapoint = fiducialPoints.createNode(-1, datapointTemplateInternal)
cache.setNode(datapoint)
fiducialCoordinates.assignReal(cache, lvApexInnerx)
fiducialLabel.assignString(cache, 'apex endo')
fiducialElementXi.assignMeshLocation(cache, element1, [ 0.0, 0.0, 0.0 ])
datapoint = fiducialPoints.createNode(-1, datapointTemplateInternal)
cache.setNode(datapoint)
fiducialCoordinates.assignReal(cache, lvApexOuterx)
fiducialLabel.assignString(cache, 'apex epi')
fiducialElementXi.assignMeshLocation(cache, element1, [ 0.0, 0.0, 1.0 ])
markerPoint = markerPoints.createNode(nodeIdentifier, markerTemplateInternal)
nodeIdentifier += 1
cache.setNode(markerPoint)
markerCoordinates.assignReal(cache, lvApexInnerx)
markerName.assignString(cache, 'apex endo')
markerLocation.assignMeshLocation(cache, element1, [ 0.0, 0.0, 0.0 ])
markerPoint = markerPoints.createNode(nodeIdentifier, markerTemplateInternal)
nodeIdentifier += 1
cache.setNode(markerPoint)
markerCoordinates.assignReal(cache, lvApexOuterx)
markerName.assignString(cache, 'apex epi')
markerLocation.assignMeshLocation(cache, element1, [ 0.0, 0.0, 1.0 ])

fm.endChange()
return annotationGroups
Expand Down
6 changes: 3 additions & 3 deletions src/scaffoldmaker/meshtypes/meshtype_3d_heartventricles2.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ def generateBaseMesh(cls, region, options):
coordinates = findOrCreateFieldCoordinates(fm)
cache = fm.createFieldcache()

lvGroup = AnnotationGroup(region, 'left ventricle', FMANumber = 7101, lyphID = 'Lyph ID unknown')
rvGroup = AnnotationGroup(region, 'right ventricle', FMANumber = 7098, lyphID = 'Lyph ID unknown')
vSeptumGroup = AnnotationGroup(region, 'interventricular septum', FMANumber = 7133, lyphID = 'Lyph ID unknown')
lvGroup = AnnotationGroup(region, "left ventricle myocardium", FMANumber = 9558, lyphID = 'Lyph ID unknown')
rvGroup = AnnotationGroup(region, "right ventricle myocardium", FMANumber = 9535, lyphID = 'Lyph ID unknown')
vSeptumGroup = AnnotationGroup(region, "interventricular septum", FMANumber = 7133, lyphID = 'Lyph ID unknown')
annotationGroups = [ lvGroup, rvGroup, vSeptumGroup ]

#################
Expand Down
Loading

0 comments on commit 3f08256

Please sign in to comment.