Skip to content

Commit

Permalink
Merge pull request #226 from rchristie/groups
Browse files Browse the repository at this point in the history
Apply zinc group changes
  • Loading branch information
rchristie authored Jun 22, 2023
2 parents b3e94d2 + 880939a commit 8ae8756
Show file tree
Hide file tree
Showing 33 changed files with 350 additions and 638 deletions.
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ def readfile(filename, split=False):
# into the 'requirements.txt' file.
requires = [
# minimal requirements listing
"cmlibs.maths",
"cmlibs.utils",
"cmlibs.zinc",
"cmlibs.maths >= 0.3",
"cmlibs.utils >= 0.6",
"cmlibs.zinc >= 4.0",
"scipy",
"numpy",
]
source_license = readfile("LICENSE")

setup(
name="scaffoldmaker",
version="0.9.0",
version="0.10.0",
description="Python client for generating anatomical scaffolds using Zinc",
long_description="\n".join(readme) + source_license,
long_description_content_type="text/x-rst",
Expand Down
69 changes: 20 additions & 49 deletions src/scaffoldmaker/annotation/annotationgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
from cmlibs.utils.zinc.general import ChangeManager
from cmlibs.utils.zinc.field import find_or_create_field_coordinates, find_or_create_field_group, \
find_or_create_field_stored_mesh_location, find_or_create_field_stored_string
from cmlibs.utils.zinc.finiteelement import get_highest_dimension_mesh, get_next_unused_node_identifier
from cmlibs.utils.zinc.group import group_get_highest_dimension, \
identifier_ranges_from_string, identifier_ranges_to_string, \
mesh_group_add_identifier_ranges, mesh_group_to_identifier_ranges, \
nodeset_group_add_identifier_ranges, nodeset_group_to_identifier_ranges
from cmlibs.zinc.element import Element, Mesh
from cmlibs.zinc.field import Field, FieldFiniteElement, FieldGroup, FieldStoredMeshLocation, FieldStoredString, \
FieldFindMeshLocation
from cmlibs.zinc.fieldcache import Fieldcache
from cmlibs.zinc.fieldmodule import Fieldmodule
from cmlibs.zinc.node import Node
from cmlibs.zinc.result import RESULT_OK
from scaffoldmaker.utils.zinc_utils import get_highest_dimension_mesh, get_next_unused_node_identifier, \
group_get_highest_dimension, identifier_ranges_from_string, identifier_ranges_to_string, \
mesh_group_add_identifier_ranges, mesh_group_to_identifier_ranges, \
nodeset_group_add_identifier_ranges, nodeset_group_to_identifier_ranges


class AnnotationGroup(object):
Expand Down Expand Up @@ -75,7 +75,7 @@ def toDict(self):
identifierRanges = []
if dimension > 0:
mesh = fieldmodule.findMeshByDimension(dimension)
meshGroup = self._group.getFieldElementGroup(mesh).getMeshGroup()
meshGroup = self._group.getMeshGroup(mesh)
if meshGroup.isValid():
identifierRanges = mesh_group_to_identifier_ranges(meshGroup)
else:
Expand All @@ -84,7 +84,7 @@ def toDict(self):
identifierRanges = [[self._markerIdentifier, self._markerIdentifier]]
else:
nodes = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
nodesetGroup = self._group.getFieldNodeGroup(nodes).getNodesetGroup()
nodesetGroup = self._group.getNodesetGroup(nodes)
if nodesetGroup.isValid():
identifierRanges = nodeset_group_to_identifier_ranges(nodesetGroup)
dct = {
Expand Down Expand Up @@ -438,18 +438,8 @@ def setName(self, name):
fieldcache.setNode(markerNode)
markerName.assignString(fieldcache, name)
else:
with ChangeManager(fieldmodule):
if RESULT_OK != self._group.setName(name):
return False
# workaround for zinc issue: must rename subelement groups
for dimension in range(3, 0, -1):
mesh = fieldmodule.findMeshByDimension(dimension)
elementGroup = self._group.getFieldElementGroup(mesh)
if elementGroup.isValid():
elementGroup.setName(name + '.' + mesh.getName())
nodeGroup = self._group.getFieldNodeGroup(nodes)
if nodeGroup.isValid():
nodeGroup.setName(name + '.' + nodes.getName())
if RESULT_OK != self._group.setName(name):
return False
self._name = name
return True

Expand Down Expand Up @@ -488,55 +478,37 @@ def getDimension(self):
"""
return group_get_highest_dimension(self._group)

def getFieldElementGroup(self, mesh):
"""
:param mesh: The Zinc mesh to manage a sub group of.
:return: The Zinc element group field for mesh in this AnnotationGroup.
"""
elementGroup = self._group.getFieldElementGroup(mesh)
if not elementGroup.isValid():
elementGroup = self._group.createFieldElementGroup(mesh)
return elementGroup

def getFieldNodeGroup(self, nodeset):
"""
:param nodeset: The Zinc nodeset to manage a sub group of.
:return: The Zinc node group field for nodeset in this AnnotationGroup.
"""
nodeGroup = self._group.getFieldNodeGroup(nodeset)
if not nodeGroup.isValid():
nodeGroup = self._group.createFieldNodeGroup(nodeset)
return nodeGroup

def getMeshGroup(self, mesh):
"""
Get or create mesh group.
:param mesh: The Zinc mesh to manage a sub group of.
:return: The Zinc meshGroup for adding elements of mesh in this AnnotationGroup.
"""
return self.getFieldElementGroup(mesh).getMeshGroup()
return self._group.getOrCreateMeshGroup(mesh)

def hasMeshGroup(self, mesh):
"""
:param mesh: The Zinc mesh to query a sub group of.
:return: True if MeshGroup for mesh exists and is not empty, otherwise False.
"""
elementGroup = self._group.getFieldElementGroup(mesh)
return elementGroup.isValid() and (elementGroup.getMeshGroup().getSize() > 0)
meshGroup = self._group.getMeshGroup(mesh)
return meshGroup.isValid() and (meshGroup.getSize() > 0)

def getNodesetGroup(self, nodeset):
"""
Get or create nodeset group.
:param nodeset: The Zinc nodeset to manage a sub group of.
:return: The Zinc nodesetGroup for adding nodes from nodeset in this AnnotationGroup.
"""
return self.getFieldNodeGroup(nodeset).getNodesetGroup()
return self._group.getOrCreateNodesetGroup(nodeset)

def hasNodesetGroup(self, nodeset):
"""
:param nodeset: The Zinc nodeset to query a sub group of.
:return: True if NodesetGroup for nodeset exists and is not empty, otherwise False.
"""
nodeGroup = self._group.getFieldNodeGroup(nodeset)
return nodeGroup.isValid() and (nodeGroup.getNodesetGroup().getSize() > 0)
nodesetGroup = self._group.getNodesetGroup(nodeset)
return nodesetGroup.isValid() and (nodesetGroup.getSize() > 0)

def addSubelements(self):
"""
Expand All @@ -546,11 +518,10 @@ def addSubelements(self):
fm = self._group.getFieldmodule()
for dimension in range(1, 4):
mesh = fm.findMeshByDimension(dimension)
elementGroup = self._group.getFieldElementGroup(mesh)
if elementGroup.isValid():
meshGroup = elementGroup.getMeshGroup()
meshGroup = self._group.getMeshGroup(mesh)
if meshGroup.isValid():
#print('Mesh group:', self._name, ', size', meshGroup.getSize())
meshGroup.addElementsConditional(elementGroup) # use FieldElementGroup as conditional field
meshGroup.addElementsConditional(self._group) # use whole group as conditional field


def findAnnotationGroupByName(annotationGroups: list, name: str):
Expand Down
4 changes: 2 additions & 2 deletions src/scaffoldmaker/meshtypes/meshtype_3d_bladder1.py
Original file line number Diff line number Diff line change
Expand Up @@ -872,11 +872,11 @@ def defineFaceAnnotations(cls, region, options, annotationGroups):
is_exterior_face_xi3_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_1))
is_exterior_face_xi3_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_0))

is_body = bodyGroup.getFieldElementGroup(mesh2d)
is_body = bodyGroup.getGroup()
is_body_serosa = fm.createFieldAnd(is_body, is_exterior_face_xi3_1)
is_body_lumen = fm.createFieldAnd(is_body, is_exterior_face_xi3_0)

is_neck = neckGroup.getFieldElementGroup(mesh2d)
is_neck = neckGroup.getGroup()
is_neck_serosa = fm.createFieldAnd(is_neck, is_exterior_face_xi3_1)
is_neck_lumen = fm.createFieldAnd(is_neck, is_exterior_face_xi3_0)

Expand Down
24 changes: 12 additions & 12 deletions src/scaffoldmaker/meshtypes/meshtype_3d_bladderurethra1.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import copy
import math

from cmlibs.utils.zinc.field import findOrCreateFieldGroup, findOrCreateFieldNodeGroup, \
from cmlibs.utils.zinc.field import findOrCreateFieldGroup, \
findOrCreateFieldStoredMeshLocation, findOrCreateFieldStoredString
from cmlibs.zinc.element import Element
from cmlibs.zinc.field import Field
Expand Down Expand Up @@ -632,7 +632,7 @@ def generateBaseMesh(cls, region, options):
markerLocation = findOrCreateFieldStoredMeshLocation(fm, mesh, name="marker_location")

nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
markerPoints = findOrCreateFieldNodeGroup(markerGroup, nodes).getNodesetGroup()
markerPoints = markerGroup.getOrCreateNodesetGroup(nodes)
markerTemplateInternal = nodes.createNodetemplate()
markerTemplateInternal.defineField(markerName)
markerTemplateInternal.defineField(markerLocation)
Expand All @@ -649,12 +649,12 @@ def generateBaseMesh(cls, region, options):

tmpGroup = tmpFieldmodule.findFieldByName("urinary bladder").castGroup()
cx_bladder, cd1_bladder, cd2_bladder, cd12_bladder = get_nodeset_path_field_parameters(
tmpGroup.getFieldNodeGroup(tmpNodes).getNodesetGroup(), tmpCoordinates,
tmpGroup.getNodesetGroup(tmpNodes), tmpCoordinates,
[Node.VALUE_LABEL_VALUE, Node.VALUE_LABEL_D_DS1, Node.VALUE_LABEL_D_DS2, Node.VALUE_LABEL_D2_DS1DS2])

tmpGroup = tmpFieldmodule.findFieldByName("urethra").castGroup()
cx_urethra, cd1_urethra, cd2_urethra, cd12_urethra = get_nodeset_path_field_parameters(
tmpGroup.getFieldNodeGroup(tmpNodes).getNodesetGroup(), tmpCoordinates,
tmpGroup.getNodesetGroup(tmpNodes), tmpCoordinates,
[Node.VALUE_LABEL_VALUE, Node.VALUE_LABEL_D_DS1, Node.VALUE_LABEL_D_DS2, Node.VALUE_LABEL_D2_DS1DS2])

del tmpGroup
Expand Down Expand Up @@ -1208,20 +1208,20 @@ def defineFaceAnnotations(cls, region, options, annotationGroups):
is_exterior_face_xi3_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_1))
is_exterior_face_xi3_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_0))

is_body = bodyGroup.getFieldElementGroup(mesh2d)
is_body = bodyGroup.getGroup()
is_body_serosa = fm.createFieldAnd(is_body, is_exterior_face_xi3_1)
is_body_lumen = fm.createFieldAnd(is_body, is_exterior_face_xi3_0)

is_neck = neckGroup.getFieldElementGroup(mesh2d)
is_neck = neckGroup.getGroup()
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 = urinaryBladderGroup.getGroup()
is_urinaryBladder_serosa = fm.createFieldAnd(is_urinaryBladder, is_exterior_face_xi3_1)
is_urinaryBladder_lumen = fm.createFieldAnd(is_urinaryBladder, is_exterior_face_xi3_0)

is_dorsal_bladder = bladderDorsalGroup.getFieldElementGroup(mesh2d)
is_ventral_bladder = bladderVentralGroup.getFieldElementGroup(mesh2d)
is_dorsal_bladder = bladderDorsalGroup.getGroup()
is_ventral_bladder = bladderVentralGroup.getGroup()

serosaOfUrinaryBladder = \
findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_bladder_term("serosa of urinary bladder"))
Expand Down Expand Up @@ -1324,12 +1324,12 @@ def defineFaceAnnotations(cls, region, options, annotationGroups):
get_bladder_term("ventral part of urethra"))
urethraDorsalGroup = getAnnotationGroupForTerm(annotationGroups, get_bladder_term("dorsal part of urethra"))

is_urethra = urethraGroup.getFieldElementGroup(mesh2d)
is_urethra = urethraGroup.getGroup()
is_urethra_serosa = fm.createFieldAnd(is_urethra, is_exterior_face_xi3_1)
is_urethra_lumen = fm.createFieldAnd(is_urethra, is_exterior_face_xi3_0)

is_dorsal_urethra = urethraDorsalGroup.getFieldElementGroup(mesh2d)
is_ventral_urethra = urethraVentralGroup.getFieldElementGroup(mesh2d)
is_dorsal_urethra = urethraDorsalGroup.getGroup()
is_ventral_urethra = urethraVentralGroup.getGroup()

serosaOfUrethra = findOrCreateAnnotationGroupForTerm(annotationGroups, region,
get_bladder_term("serosa of urethra"))
Expand Down
8 changes: 3 additions & 5 deletions src/scaffoldmaker/meshtypes/meshtype_3d_brainstem.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

from cmlibs.zinc.element import Element
from cmlibs.zinc.node import Node
from cmlibs.zinc.field import FieldFindMeshLocation
from cmlibs.utils.zinc.field import Field, findOrCreateFieldCoordinates, findOrCreateFieldGroup, findOrCreateFieldNodeGroup, findOrCreateFieldStoredMeshLocation, \
findOrCreateFieldStoredString
from cmlibs.utils.zinc.field import Field, findOrCreateFieldCoordinates, findOrCreateFieldStoredString
from cmlibs.utils.zinc.general import ChangeManager
from cmlibs.utils.zinc.finiteelement import getMaximumNodeIdentifier
from scaffoldmaker.annotation.annotationgroup import AnnotationGroup, findOrCreateAnnotationGroupForTerm
Expand Down Expand Up @@ -626,7 +624,7 @@ def defineFaceAnnotations(cls, region, options, annotationGroups):
groupNames = ['brainstem', 'midbrain', 'medulla oblongata', 'pons']
for groupName in groupNames:
subGroup = AnnotationGroup(region, get_brainstem_term(groupName))
issub = subGroup.getFieldElementGroup(mesh2d)
issub = subGroup.getGroup()
is_subface_ext = fm.createFieldOr(fm.createFieldAnd(issub, is_exterior_face_xi1), fm.createFieldAnd(issub, is_exterior_face_xi3))
subFaceGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_brainstem_term(groupName + ' exterior'))
subFaceGroup.getMeshGroup(mesh2d).addElementsConditional(is_subface_ext)
Expand All @@ -636,7 +634,7 @@ def defineFaceAnnotations(cls, region, options, annotationGroups):
for groupName in groupNames:
subGroupName = 'midbrain' if groupName == 'thalamus-brainstem interface' else 'medulla oblongata'
subGroup = AnnotationGroup(region, get_brainstem_term(subGroupName))
issub = subGroup.getFieldElementGroup(mesh2d)
issub = subGroup.getGroup()
is_subface_ext = fm.createFieldAnd(issub, is_exterior_face_xi2)
subFaceGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region,
get_brainstem_term(groupName))
Expand Down
4 changes: 2 additions & 2 deletions src/scaffoldmaker/meshtypes/meshtype_3d_colon1.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ def generateBaseMesh(cls, region, options):

for termName in colonTermsAlong:
tmpGroup = tmpFieldmodule.findFieldByName(termName).castGroup() if termName else None
tmpNodeset = tmpGroup.getFieldNodeGroup(tmpNodes).getNodesetGroup() if tmpGroup else tmpNodes
tmpNodeset = tmpGroup.getNodesetGroup(tmpNodes) if tmpGroup else tmpNodes

cxGroup, cd1Group, cd2Group, cd3Group, cd12Group, cd13Group = get_nodeset_path_field_parameters(
tmpNodeset, tmpCoordinates,
Expand Down Expand Up @@ -959,7 +959,7 @@ def defineFaceAnnotations(cls, region, options, annotationGroups):
is_exterior = fm.createFieldIsExterior()
is_exterior_face_xi3_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_1))
is_exterior_face_xi3_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_0))
is_colon = colonGroup.getFieldElementGroup(mesh2d)
is_colon = colonGroup.getGroup()
is_serosa = fm.createFieldAnd(is_colon, is_exterior_face_xi3_1)
serosa = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_colon_term("serosa of colon"))
serosa.getMeshGroup(mesh2d).addElementsConditional(is_serosa)
Expand Down
2 changes: 1 addition & 1 deletion src/scaffoldmaker/meshtypes/meshtype_3d_colonsegment1.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ def defineFaceAnnotations(cls, region, options, annotationGroups):
is_exterior = fm.createFieldIsExterior()
is_exterior_face_xi3_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_1))
is_exterior_face_xi3_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_0))
is_colon = colonGroup.getFieldElementGroup(mesh2d)
is_colon = colonGroup.getGroup()
is_serosa = fm.createFieldAnd(is_colon, is_exterior_face_xi3_1)
serosa = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_colon_term("serosa of colon"))
serosa.getMeshGroup(mesh2d).addElementsConditional(is_serosa)
Expand Down
8 changes: 4 additions & 4 deletions src/scaffoldmaker/meshtypes/meshtype_3d_esophagus1.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import copy
import math
from cmlibs.utils.zinc.field import findOrCreateFieldGroup, findOrCreateFieldStoredString, \
findOrCreateFieldStoredMeshLocation, findOrCreateFieldNodeGroup
findOrCreateFieldStoredMeshLocation
from cmlibs.zinc.element import Element
from cmlibs.zinc.field import Field
from cmlibs.zinc.node import Node
Expand Down Expand Up @@ -214,7 +214,7 @@ def generateBaseMesh(cls, region, options):

for termName in esophagusTermsAlong:
tmpGroup = tmpFieldmodule.findFieldByName(termName).castGroup() if termName else None
tmpNodeset = tmpGroup.getFieldNodeGroup(tmpNodes).getNodesetGroup() if tmpGroup else tmpNodes
tmpNodeset = tmpGroup.getNodesetGroup(tmpNodes) if tmpGroup else tmpNodes

cxGroup, cd1Group, cd2Group, cd3Group, cd12Group, cd13Group = get_nodeset_path_field_parameters(
tmpNodeset, tmpCoordinates,
Expand Down Expand Up @@ -457,7 +457,7 @@ def generateBaseMesh(cls, region, options):
markerLocation = findOrCreateFieldStoredMeshLocation(fm, mesh, name="marker_location")

nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
markerPoints = findOrCreateFieldNodeGroup(markerGroup, nodes).getNodesetGroup()
markerPoints = markerGroup.getOrCreateNodesetGroup(nodes)
markerTemplateInternal = nodes.createNodetemplate()
markerTemplateInternal.defineField(markerName)
markerTemplateInternal.defineField(markerLocation)
Expand Down Expand Up @@ -535,7 +535,7 @@ def defineFaceAnnotations(cls, region, options, annotationGroups):
is_exterior = fm.createFieldIsExterior()
is_exterior_face_xi3_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_1))
is_exterior_face_xi3_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI3_0))
is_esophagus = esophagusGroup.getFieldElementGroup(mesh2d)
is_esophagus = esophagusGroup.getGroup()
is_serosa = fm.createFieldAnd(is_esophagus, is_exterior_face_xi3_1)
serosa = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_esophagus_term("serosa of esophagus"))
serosa.getMeshGroup(mesh2d).addElementsConditional(is_serosa)
Expand Down
Loading

0 comments on commit 8ae8756

Please sign in to comment.