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

Apply zinc group changes #226

Merged
merged 9 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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