From fede36b557699db3ac05c97c2fa5b1aae5bb3b2e Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Thu, 10 Sep 2020 15:28:57 +1200 Subject: [PATCH 01/11] Adding markers and parameter set for species-specific datasets (mouse) --- .../meshtypes/meshtype_3d_stellate1.py | 168 +++++++++++++++--- 1 file changed, 148 insertions(+), 20 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index 3de66275..e0327065 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -1,13 +1,16 @@ """ Generates a 3-D planar stellate mesh with cross arms radiating from a central node, and variable numbers of elements along each arm. +Ability to change between generic mesh or species-specific set, which involves changing parameter set. """ from __future__ import division import math -from opencmiss.utils.zinc.field import findOrCreateFieldCoordinates +from opencmiss.utils.zinc.field import findOrCreateFieldCoordinates, findOrCreateFieldGroup, findOrCreateFieldNodeGroup, findOrCreateFieldStoredMeshLocation, findOrCreateFieldStoredString from opencmiss.zinc.element import Element from opencmiss.zinc.field import Field from opencmiss.zinc.node import Node +from scaffoldmaker.annotation.stellate_terms import get_stellate_term +from scaffoldmaker.annotation.annotationgroup import AnnotationGroup, findOrCreateAnnotationGroupForTerm, getAnnotationGroupForTerm from scaffoldmaker.meshtypes.scaffold_base import Scaffold_base from scaffoldmaker.utils.eftfactory_bicubichermitelinear import eftfactory_bicubichermitelinear from scaffoldmaker.utils.meshrefinement import MeshRefinement @@ -25,20 +28,38 @@ def getName(): return '3D Stellate 1' @staticmethod - def getDefaultOptions(parameterSetName='Default'): - return { - 'Numbers of elements along arms' : [4,2,2], - 'Element length along arm' : 1.0, - 'Element width across arm' : 0.5, - 'Element thickness' : 0.5, - 'Refine' : False, - 'Refine number of elements along arm' : 1, - 'Refine number of elements across arm' : 1, - 'Refine number of elements through thickness' : 1 - } + def getParameterSetNames(): + return [ + 'Default', + 'Mouse 1', + 'Mouse Mean 1'] + + @classmethod + def getDefaultOptions(cls, parameterSetName='Default'): + # isMouse = 'Mouse' in parameterSetName #options['Base parameter set'] + options = {} + options['Base parameter set'] = parameterSetName + + isMouse = 'Mouse' in parameterSetName + + if isMouse: + options['Numbers of elements along arms'] = [4,2,2] + else: + options['Numbers of elements along arms'] = [4,3,3] + options['Element length along arm'] = 1.0 + options['Element width across arm'] = 0.5 + options['Element thickness'] = 0.5 + options['Refine'] = False + options['Refine number of elements along arm'] = 1 + options['Refine number of elements across arm'] = 1 + options['Refine number of elements through thickness'] = 1 + # cls.updateSubScaffoldOptions(options) + return options + @staticmethod def getOrderedOptionNames(): + return [ 'Numbers of elements along arms', 'Element length along arm', @@ -48,10 +69,11 @@ def getOrderedOptionNames(): 'Refine number of elements along arm', 'Refine number of elements across arm', 'Refine number of elements through thickness' + ] - @staticmethod - def checkOptions(options): + @classmethod + def checkOptions(cls, options): for key in [ 'Refine number of elements along arm', 'Refine number of elements across arm', @@ -77,6 +99,8 @@ def checkOptions(options): if numberOfElements < 2: options[armCountsKey][i] = 2 + # cls.updateSubScaffoldOptions(options) + @classmethod def generateBaseMesh(cls, region, options): """ @@ -85,6 +109,9 @@ def generateBaseMesh(cls, region, options): :param options: Dict containing options. See getDefaultOptions(). :return: None """ + + isMouse = 'Mouse' in options['Base parameter set'] + armCount = 3 elementLengths = [options['Element length along arm'], options['Element width across arm'], @@ -95,9 +122,9 @@ def generateBaseMesh(cls, region, options): useCrossDerivatives = False fm = region.getFieldmodule() + nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES) coordinates = findOrCreateFieldCoordinates(fm) - nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES) nodetemplate = nodes.createNodetemplate() nodetemplate.defineField(coordinates) nodetemplate.setValueNumberOfVersions(coordinates, -1, Node.VALUE_LABEL_VALUE, 1) @@ -108,11 +135,31 @@ def generateBaseMesh(cls, region, options): mesh = fm.findMeshByDimension(3) cache = fm.createFieldcache() + markerGroup = findOrCreateFieldGroup(fm, "marker") + markerName = findOrCreateFieldStoredString(fm, name="marker_name") + markerLocation = findOrCreateFieldStoredMeshLocation(fm, mesh, name="marker_location") + + markerPoints = findOrCreateFieldNodeGroup(markerGroup, nodes).getNodesetGroup() + markerTemplateInternal = nodes.createNodetemplate() + markerTemplateInternal.defineField(markerName) + markerTemplateInternal.defineField(markerLocation) + + # addMarker = {"name": "stellate-test", "xi": [0.0, 1.0, 0.0]} + # markers with element number and xi position + allMarkers = { "Inferior cardiac nerve" : {"elementID": 10, "xi": [0.50, 0.0, 0.5]}, + "Ventral ansa subclavia" : {"elementID": 12, "xi": [0.50, 1.0, 0.5]}, + "Dorsal ansa subclavia" : {"elementID": 14, "xi": [0.50, 0.0, 0.5]}, + "C8 segment of cervical spinal cord" : {"elementID": 16, "xi": [0.50, 1.0, 0.5]}, + "first thoracic spinal cord segment" : {"elementID": 1, "xi": [1.0, 0.0, 0.5]}, + "second thoracic spinal cord segment" : {"elementID": 2, "xi": [1.0, 0.0, 0.5]}, + "third thoracic spinal cord segment" : {"elementID": 3, "xi": [1.0, 0.0, 0.5]}, + "thoracic sympathetic trunk" : {"elementID": 4, "xi": [1.0, 1.0, 0.5]} + } + # Create nodes numNodesPerArm = [0] halfArmArcAngleRadians = math.pi / armCount dipMultiplier = 1 #elementLengths[1] * 1.2 * 1.5 - nodeIdentifier = 1 minArmAngle = 2 * math.pi / armCount xx = [] @@ -129,6 +176,7 @@ def generateBaseMesh(cls, region, options): coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, x[ix]) coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, ds1[ix]) coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, ds2[ix]) + nodeIdentifier += 1 x_in_nodes.append(x[ix]) numNodesPerArm.append(len(x)) @@ -136,6 +184,7 @@ def generateBaseMesh(cls, region, options): xds1.append(ds1) xds2.append(ds2) + # Create elements bicubichermitelinear = eftfactory_bicubichermitelinear(mesh, useCrossDerivatives) eft = bicubichermitelinear.createEftNoCrossDerivatives() #createEftBasic() @@ -367,7 +416,25 @@ def generateBaseMesh(cls, region, options): element = mesh.createElement(elementIdentifier, elementtemplate1) result = element.setNodesByIdentifier(eft1, nodeIdentifiers) result3 = element.setScaleFactors(eft1, scalefactors) if scalefactors else None + + ############################ + # annotation fiducial points + ############################ + if isMouse: + for key in allMarkers: + if elementIdentifier == allMarkers[key]["elementID"]: + elementID = allMarkers[key]["elementID"] + xi = allMarkers[key]["xi"] + addMarker = {"name": key, "xi": allMarkers[key]["xi"]} + + markerPoint = markerPoints.createNode(nodeIdentifier, markerTemplateInternal) + nodeIdentifier += 1 + cache.setNode(markerPoint) + markerName.assignString(cache, addMarker["name"]) + markerLocation.assignMeshLocation(cache, element, addMarker["xi"]) + elementIdentifier += 1 + return [] @classmethod @@ -384,6 +451,58 @@ def refineMesh(cls, meshrefinement, options): meshrefinement.refineAllElementsCubeStandard3d(refineElementsCount1, refineElementsCount2, refineElementsCount3) + # @classmethod + # def defineFaceAnnotations(cls, region, options, annotationGroups): + # """ + # Add point annotation groups from the 1D mesh. + # :param region: Zinc region containing model. + # :param options: Dict containing options. See getDefaultOptions(). + # :param annotationGroups: List of annotation groups for top-level elements. + # New point annotation groups are appended to this list. + # """ + # # create endocardium and epicardium groups + # fm = region.getFieldmodule() + # icnGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("Inferior cardiac nerve")) + # daGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("Dorsal ansa subclavia")) + # vaGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("Ventral ansa subclavia")) + # # c8Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("C8 segment of cervical spinal cord")) + # t1Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("first thoracic spinal cord segment")) + # t2Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("second thoracic spinal cord segment")) + # t3Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("third thoracic spinal cord segment")) + # tstGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("thoracic sympathetic trunk")) + # stellateGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("cervicothoracic ganglion")) + # + # nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES) + # + # ############################ + # # annotation fiducial points + # ############################ + # markerID = 10 + # mesh = fm.findMeshByDimension(3) + # cache = fm.createFieldcache() + # elementtemplate = mesh.createElementtemplate() + # elementtemplate.setElementShapeType(Element.SHAPE_TYPE_CUBE) + # element = mesh.createElement(markerID, elementtemplate) + # markerGroup = findOrCreateFieldGroup(fm, "marker") + # markerName = findOrCreateFieldStoredString(fm, name="marker_name") + # markerLocation = findOrCreateFieldStoredMeshLocation(fm, mesh, name="marker_location") + # + # markerPoints = findOrCreateFieldNodeGroup(markerGroup, nodes).getNodesetGroup() + # markerTemplateInternal = nodes.createNodetemplate() + # markerTemplateInternal.defineField(markerName) + # markerTemplateInternal.defineField(markerLocation) + # + # addMarker = {"name": "stellate-test", "xi": [0.0, 1.0, 0.0]} + # nodeIdentifier = markerID + # if addMarker: + # markerPoint = markerPoints.createNode(markerID, markerTemplateInternal) + # cache.setNode(markerPoint) + # markerName.assignString(cache, addMarker["name"]) + # element = mesh.createElement(markerID, elementtemplate) + # markerLocation.assignMeshLocation(cache, element, addMarker["xi"]) + # markerID += 1 + + def createArm(halfArmArcAngleRadians, elementLengths, armAngle, armAngleConst, elementsCount, dipMultiplier, armCount, armIndex): """ Create single arm unit. @@ -408,6 +527,8 @@ def createArm(halfArmArcAngleRadians, elementLengths, armAngle, armAngleConst, e elementsCount1, elementsCount2, elementsCount3 = elementsCount [elementLength, elementWidth, elementHeight] = elementLengths + shorterArmEnd = True + xnodes_ds1 = [] xnodes_ds2 = [] dx_ds1 = [elementLength, 0.0, 0.0] @@ -452,8 +573,11 @@ def createArm(halfArmArcAngleRadians, elementLengths, armAngle, armAngleConst, e x1 = dvertex[0] x2 = dvertex[1] else: - x1 = (elementLength*e1) - x2 = ((e2 - 1) * elementWidth ) + if e1 == elementsCount1 and shorterArmEnd: # and e2 == 1:# armEnd + x1 = 0.5*(elementLength+elementWidth) + elementLength*(e1-1) + else: + x1 = elementLength*e1 + x2 = (e2 - 1) * elementWidth x.append([x1, x2, x3]) # DERIVATIVES @@ -466,8 +590,11 @@ def createArm(halfArmArcAngleRadians, elementLengths, armAngle, armAngleConst, e ds2 = [dcent[0], -dcent[1], dcent[2]] if (e2 == 0) else dcent ds2 = setMagnitude(ds2, dipMag) ds1 = rotateAboutZAxis(ds2, -math.pi / 2) - elif e1 == elementsCount1 and e2 == elementsCount2-1: + elif e1 == elementsCount1 and e2 == elementsCount2-1: # armEnd + ds1 = [elementWidth,0,0] ds2 = [0, 1 * (elementLength + elementWidth), 0] + if shorterArmEnd: + ds2 = [0, 0.5 * (elementLength + elementWidth), 0] xnodes_ds1.append(ds1) xnodes_ds2.append(ds2) nid += 1 @@ -497,4 +624,5 @@ def createArm(halfArmArcAngleRadians, elementLengths, armAngle, armAngleConst, e xnodes_ds1[j] = rotateAboutZAxis(xnodes_ds1[j], armAngle) xnodes_ds2[j] = rotateAboutZAxis(xnodes_ds2[j], armAngle) - return (x, xnodes_ds1, xnodes_ds2, rmVertexNodes) \ No newline at end of file + return (x, xnodes_ds1, xnodes_ds2, rmVertexNodes) + From 07cbe01bb3e3e06333deac275d79eb07da1e43ad Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Tue, 15 Sep 2020 10:45:46 +1200 Subject: [PATCH 02/11] With face groups for fitting --- .../meshtypes/meshtype_3d_stellate1.py | 215 +++++++++++------- 1 file changed, 132 insertions(+), 83 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index e0327065..91eb4a7b 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -1,6 +1,5 @@ """ Generates a 3-D planar stellate mesh with cross arms radiating from a central node, and variable numbers of elements along each arm. -Ability to change between generic mesh or species-specific set, which involves changing parameter set. """ from __future__ import division @@ -32,6 +31,7 @@ def getParameterSetNames(): return [ 'Default', 'Mouse 1', + 'Long Mouse', 'Mouse Mean 1'] @classmethod @@ -41,14 +41,18 @@ def getDefaultOptions(cls, parameterSetName='Default'): options['Base parameter set'] = parameterSetName isMouse = 'Mouse' in parameterSetName + isLongMouse = 'Long Mouse' in parameterSetName if isMouse: options['Numbers of elements along arms'] = [4,2,2] + if isLongMouse: + options['Numbers of elements along arms'] = [5,2,2] else: - options['Numbers of elements along arms'] = [4,3,3] - options['Element length along arm'] = 1.0 - options['Element width across arm'] = 0.5 - options['Element thickness'] = 0.5 + options['Numbers of elements along arms'] = [4,2,2] + options['Element length around central wheel'] = 0.8 + options['Element length along arm'] = 0.8 + options['Element width across arm'] = 0.3 + options['Element thickness'] = 0.1 options['Refine'] = False options['Refine number of elements along arm'] = 1 options['Refine number of elements across arm'] = 1 @@ -62,6 +66,7 @@ def getOrderedOptionNames(): return [ 'Numbers of elements along arms', + 'Element length around central wheel', 'Element length along arm', 'Element width across arm', 'Element thickness', @@ -82,6 +87,7 @@ def checkOptions(cls, options): options[key] = 1 for key in [ + 'Element length around central wheel', 'Element length along arm', 'Element width across arm', 'Element thickness']: @@ -109,10 +115,12 @@ def generateBaseMesh(cls, region, options): :param options: Dict containing options. See getDefaultOptions(). :return: None """ - - isMouse = 'Mouse' in options['Base parameter set'] + isDefault = 'Default' in options['Base parameter set'] + isMouse = 'Mouse' in options['Base parameter set'] and 'Long' not in options['Base parameter set'] + isLongMouse = 'Long Mouse' in options['Base parameter set'] armCount = 3 + elementLengthCentral = options['Element length around central wheel'] elementLengths = [options['Element length along arm'], options['Element width across arm'], options['Element thickness']] @@ -144,31 +152,65 @@ def generateBaseMesh(cls, region, options): markerTemplateInternal.defineField(markerName) markerTemplateInternal.defineField(markerLocation) - # addMarker = {"name": "stellate-test", "xi": [0.0, 1.0, 0.0]} # markers with element number and xi position - allMarkers = { "Inferior cardiac nerve" : {"elementID": 10, "xi": [0.50, 0.0, 0.5]}, - "Ventral ansa subclavia" : {"elementID": 12, "xi": [0.50, 1.0, 0.5]}, - "Dorsal ansa subclavia" : {"elementID": 14, "xi": [0.50, 0.0, 0.5]}, - "C8 segment of cervical spinal cord" : {"elementID": 16, "xi": [0.50, 1.0, 0.5]}, - "first thoracic spinal cord segment" : {"elementID": 1, "xi": [1.0, 0.0, 0.5]}, - "second thoracic spinal cord segment" : {"elementID": 2, "xi": [1.0, 0.0, 0.5]}, - "third thoracic spinal cord segment" : {"elementID": 3, "xi": [1.0, 0.0, 0.5]}, - "thoracic sympathetic trunk" : {"elementID": 4, "xi": [1.0, 1.0, 0.5]} - } + # for numElem = [4,2,2] + allMarkers = {} + if isMouse: + allMarkers = { "Inferior cardiac nerve" : {"elementID": 10, "xi": [0.50, 0.0, 0.5]}, + "Ventral ansa subclavia" : {"elementID": 12, "xi": [0.50, 1.0, 0.5]}, + "Dorsal ansa subclavia" : {"elementID": 14, "xi": [0.50, 0.0, 0.5]}, + "Cervical spinal nerve 8" : {"elementID": 16, "xi": [0.50, 1.0, 0.5]}, + "Thoracic spinal nerve 1" : {"elementID": 1, "xi": [1.0, 0.0, 0.5]}, + "Thoracic spinal nerve 2" : {"elementID": 2, "xi": [1.0, 0.0, 0.5]}, + "Thoracic spinal nerve 3" : {"elementID": 3, "xi": [1.0, 0.0, 0.5]}, + "Thoracic sympathetic nerve trunk" : {"elementID": 4, "xi": [1.0, 1.0, 0.5]} + } + if isLongMouse: + allMarkers = { "Inferior cardiac nerve" : {"elementID": 12, "xi": [0.50, 0.0, 0.5]}, + "Ventral ansa subclavia" : {"elementID": 14, "xi": [0.50, 1.0, 0.5]}, + "Dorsal ansa subclavia" : {"elementID": 16, "xi": [0.50, 0.0, 0.5]}, + "Cervical spinal nerve 8" : {"elementID": 18, "xi": [0.50, 1.0, 0.5]}, + "Thoracic spinal nerve 1" : {"elementID": 1, "xi": [1.0, 0.0, 0.5]}, + "Thoracic spinal nerve 2" : {"elementID": 3, "xi": [0.5, 0.0, 0.5]}, + "Thoracic spinal nerve 3" : {"elementID": 4, "xi": [0.5, 0.0, 0.5]}, + "Thoracic sympathetic nerve trunk" : {"elementID": 5, "xi": [1.0, 1.0, 0.5]} + } + + # left, top, bottom face annotations for user + left2Group = AnnotationGroup(region, get_stellate_term("interArm-2-3")) + left3Group = AnnotationGroup(region, get_stellate_term("interArm-2-3")) + top1Group = AnnotationGroup(region, get_stellate_term("interArm-1-2")) + top2Group = AnnotationGroup(region, get_stellate_term("interArm-1-2")) + bottom1Group = AnnotationGroup(region, get_stellate_term("interArm-1-3")) + bottom3Group = AnnotationGroup(region, get_stellate_term("interArm-1-3")) + stellateGroup = AnnotationGroup(region, get_stellate_term("cervicothoracic ganglion")) + # annotationGroups = [ left2Group, left3Group, top1Group, top2Group, bottom1Group, bottom3Group, stellateGroup ] + annotationGroups = [ left2Group, top1Group, bottom1Group, stellateGroup ] + + left2MeshGroup = left2Group.getMeshGroup(mesh) + left3MeshGroup = left3Group.getMeshGroup(mesh) + top1MeshGroup = top1Group.getMeshGroup(mesh) + top2MeshGroup = top2Group.getMeshGroup(mesh) + bottom1MeshGroup = bottom1Group.getMeshGroup(mesh) + bottom3MeshGroup = bottom3Group.getMeshGroup(mesh) + stellateMeshGroup = stellateGroup.getMeshGroup(mesh) # Create nodes numNodesPerArm = [0] - halfArmArcAngleRadians = math.pi / armCount - dipMultiplier = 1 #elementLengths[1] * 1.2 * 1.5 + dipMultiplier = 1 nodeIdentifier = 1 minArmAngle = 2 * math.pi / armCount + halfArmArcAngleRadians = minArmAngle/2 xx = [] xds1 = [] xds2 = [] x_in_nodes = [] for na in range(armCount): elementsCount_i = [elementsCount1[na], elementsCount2, elementsCount3] - x, ds1, ds2, nWheelEdge = createArm(halfArmArcAngleRadians, elementLengths, minArmAngle * na, minArmAngle, elementsCount_i, dipMultiplier, armCount, na) + # armAngleIn = minArmAngle * na + # if armCount == 3 and na == armCount-1: + # halfArmArcAngleRadians = math.pi/2 #math.pi + math.pi/(2*armCount) + x, ds1, ds2, nWheelEdge = createArm(halfArmArcAngleRadians, elementLengths, elementLengthCentral, elementsCount_i, dipMultiplier, armCount, na) for ix in range(len(x)): if na == 0 or ix not in nWheelEdge: node = nodes.createNode(nodeIdentifier, nodetemplate) @@ -417,10 +459,26 @@ def generateBaseMesh(cls, region, options): result = element.setNodesByIdentifier(eft1, nodeIdentifiers) result3 = element.setScaleFactors(eft1, scalefactors) if scalefactors else None + # add to meshGroup + stellateMeshGroup.addElement(element) + if isMouse: + if (na == 0 and e2 == 0): + bottom1MeshGroup.addElement(element) + elif (na == 2 and e2 == 1): + bottom3MeshGroup.addElement(element) + elif (na == 0 and e2 == 1): + top1MeshGroup.addElement(element) + elif (na == 1 and e2 == 0): + top2MeshGroup.addElement(element) + elif (na == 1 and e2 == 1): + left2MeshGroup.addElement(element) + elif (na == 2 and e2 == 0): + left3MeshGroup.addElement(element) + ############################ # annotation fiducial points ############################ - if isMouse: + if allMarkers: for key in allMarkers: if elementIdentifier == allMarkers[key]["elementID"]: elementID = allMarkers[key]["elementID"] @@ -435,7 +493,7 @@ def generateBaseMesh(cls, region, options): elementIdentifier += 1 - return [] + return annotationGroups #[] @classmethod def refineMesh(cls, meshrefinement, options): @@ -451,59 +509,50 @@ def refineMesh(cls, meshrefinement, options): meshrefinement.refineAllElementsCubeStandard3d(refineElementsCount1, refineElementsCount2, refineElementsCount3) - # @classmethod - # def defineFaceAnnotations(cls, region, options, annotationGroups): - # """ - # Add point annotation groups from the 1D mesh. - # :param region: Zinc region containing model. - # :param options: Dict containing options. See getDefaultOptions(). - # :param annotationGroups: List of annotation groups for top-level elements. - # New point annotation groups are appended to this list. - # """ - # # create endocardium and epicardium groups - # fm = region.getFieldmodule() - # icnGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("Inferior cardiac nerve")) - # daGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("Dorsal ansa subclavia")) - # vaGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("Ventral ansa subclavia")) - # # c8Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("C8 segment of cervical spinal cord")) - # t1Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("first thoracic spinal cord segment")) - # t2Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("second thoracic spinal cord segment")) - # t3Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("third thoracic spinal cord segment")) - # tstGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("thoracic sympathetic trunk")) - # stellateGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("cervicothoracic ganglion")) - # - # nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES) - # - # ############################ - # # annotation fiducial points - # ############################ - # markerID = 10 - # mesh = fm.findMeshByDimension(3) - # cache = fm.createFieldcache() - # elementtemplate = mesh.createElementtemplate() - # elementtemplate.setElementShapeType(Element.SHAPE_TYPE_CUBE) - # element = mesh.createElement(markerID, elementtemplate) - # markerGroup = findOrCreateFieldGroup(fm, "marker") - # markerName = findOrCreateFieldStoredString(fm, name="marker_name") - # markerLocation = findOrCreateFieldStoredMeshLocation(fm, mesh, name="marker_location") - # - # markerPoints = findOrCreateFieldNodeGroup(markerGroup, nodes).getNodesetGroup() - # markerTemplateInternal = nodes.createNodetemplate() - # markerTemplateInternal.defineField(markerName) - # markerTemplateInternal.defineField(markerLocation) - # - # addMarker = {"name": "stellate-test", "xi": [0.0, 1.0, 0.0]} - # nodeIdentifier = markerID - # if addMarker: - # markerPoint = markerPoints.createNode(markerID, markerTemplateInternal) - # cache.setNode(markerPoint) - # markerName.assignString(cache, addMarker["name"]) - # element = mesh.createElement(markerID, elementtemplate) - # markerLocation.assignMeshLocation(cache, element, addMarker["xi"]) - # markerID += 1 - - -def createArm(halfArmArcAngleRadians, elementLengths, armAngle, armAngleConst, elementsCount, dipMultiplier, armCount, armIndex): + @classmethod + def defineFaceAnnotations(cls, region, options, annotationGroups): + """ + Add point annotation groups from the 1D mesh. + :param region: Zinc region containing model. + :param options: Dict containing options. See getDefaultOptions(). + :param annotationGroups: List of annotation groups for top-level elements. + New point annotation groups are appended to this list. + """ + # create groups + fm = region.getFieldmodule() + left2Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-2-3")) + left3Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-2-3")) + top1Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-1-2")) + top2Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-1-2")) + bottom1Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-1-3")) + bottom3Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-1-3")) + stellateGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("cervicothoracic ganglion")) + + mesh2d = fm.findMeshByDimension(2) + is_exterior = fm.createFieldIsExterior() + is_exterior_face_xi2_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI2_0)) + is_exterior_face_xi2_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI2_1)) + + is_left2 = left2Group.getFieldElementGroup(mesh2d) + is_left3 = left3Group.getFieldElementGroup(mesh2d) + is_left_face = fm.createFieldOr(fm.createFieldAnd(is_left2, is_exterior_face_xi2_1), fm.createFieldAnd(is_left3, is_exterior_face_xi2_0)) + leftStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("interArm-2-3 face")) + leftStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_left_face) + + is_top1 = top1Group.getFieldElementGroup(mesh2d) + is_top2 = top2Group.getFieldElementGroup(mesh2d) + is_top_face = fm.createFieldOr(fm.createFieldAnd(is_top1, is_exterior_face_xi2_1), fm.createFieldAnd(is_top2, is_exterior_face_xi2_0)) + topStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("interArm-1-2 face")) + topStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_top_face) + + is_bottom1 = bottom1Group.getFieldElementGroup(mesh2d) + is_bottom3 = bottom3Group.getFieldElementGroup(mesh2d) + is_bottom_face = fm.createFieldOr(fm.createFieldAnd(is_bottom1, is_exterior_face_xi2_0), fm.createFieldAnd(is_bottom3, is_exterior_face_xi2_1)) + bottomStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("interArm-1-3 face")) + bottomStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_bottom_face) + + +def createArm(halfArmArcAngleRadians, elementLengths, elementLengthCentral, elementsCount, dipMultiplier, armCount, armIndex): """ Create single arm unit. Base length of element is 1. @@ -511,8 +560,7 @@ def createArm(halfArmArcAngleRadians, elementLengths, armAngle, armAngleConst, e Minimum arm length is 2 elements. :param halfArmArcAngleRadians: angle arising from base node (rad) :param elementLengths: [Element length along arm, half Element width across arm, Element thickness] - :param armAngle: angle from x axis of the arm about origin (rad) - :param armAngleConst: minimum angle from x axis of the first arm about origin (rad) + :param elementLengthCentral: Element length around central wheel :param elementsCount: list of numbers of elements along arm length, across width and through thickness directions :param dipMultiplier: factor that wheel nodes protrude by, relative to unit length :param armCount: number of arms in body @@ -528,12 +576,13 @@ def createArm(halfArmArcAngleRadians, elementLengths, armAngle, armAngleConst, e [elementLength, elementWidth, elementHeight] = elementLengths shorterArmEnd = True + armAngle = 2*halfArmArcAngleRadians*armIndex + armAngleConst = 2*halfArmArcAngleRadians xnodes_ds1 = [] xnodes_ds2 = [] dx_ds1 = [elementLength, 0.0, 0.0] dx_ds2 = [0.0, elementWidth, 0.0] - wheelDvMult = [0.5, 0.75] nodes_per_layer = (elementsCount1 + 1) * (elementsCount2 + 1) - 2 # discount 2 armEnd corners x = [] @@ -548,14 +597,14 @@ def createArm(halfArmArcAngleRadians, elementLengths, armAngle, armAngleConst, e else: rmVertexNodes = nCentre + [0, nodes_per_layer, 2* (elementsCount1+1) - 1, 2* (elementsCount1+1) - 1 + nodes_per_layer ] - dcent = [elementLength * math.cos(armAngleConst / 2), elementLength * math.sin(armAngleConst / 2), 0.0] - dvertex = [elementLength * dipMultiplier * math.cos(halfArmArcAngleRadians), - elementLength * dipMultiplier * math.sin(halfArmArcAngleRadians)] + dcent = [elementLengthCentral * math.cos(armAngleConst / 2), elementLengthCentral * math.sin(armAngleConst / 2), 0.0] + dvertex = [elementLengthCentral * dipMultiplier * math.cos(halfArmArcAngleRadians), + elementLengthCentral * dipMultiplier * math.sin(halfArmArcAngleRadians)] - dipLength = 0.5*(elementLength + elementWidth)*dipMultiplier + dipLength = 0.5*(elementLengthCentral + elementWidth)*dipMultiplier dvertex = [dipLength * math.cos(halfArmArcAngleRadians), dipLength * math.sin(halfArmArcAngleRadians)] - dipMag = 2*dipLength - elementLength + dipMag = 2*dipLength - elementLengthCentral nid = 0 for e3 in range(elementsCount3 + 1): From 796f6921e69596f5f8c88ce0539c4d890507d522 Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Fri, 18 Sep 2020 08:50:19 +1200 Subject: [PATCH 03/11] Tidy up --- .../meshtypes/meshtype_3d_stellate1.py | 85 ++++++++----------- 1 file changed, 35 insertions(+), 50 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index 91eb4a7b..5f8acc8d 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -30,9 +30,7 @@ def getName(): def getParameterSetNames(): return [ 'Default', - 'Mouse 1', - 'Long Mouse', - 'Mouse Mean 1'] + 'Mouse 1'] @classmethod def getDefaultOptions(cls, parameterSetName='Default'): @@ -176,23 +174,16 @@ def generateBaseMesh(cls, region, options): "Thoracic sympathetic nerve trunk" : {"elementID": 5, "xi": [1.0, 1.0, 0.5]} } - # left, top, bottom face annotations for user - left2Group = AnnotationGroup(region, get_stellate_term("interArm-2-3")) - left3Group = AnnotationGroup(region, get_stellate_term("interArm-2-3")) - top1Group = AnnotationGroup(region, get_stellate_term("interArm-1-2")) - top2Group = AnnotationGroup(region, get_stellate_term("interArm-1-2")) - bottom1Group = AnnotationGroup(region, get_stellate_term("interArm-1-3")) - bottom3Group = AnnotationGroup(region, get_stellate_term("interArm-1-3")) + # arm group annotations for user + arm1Group = AnnotationGroup(region, get_stellate_term("stellate arm 1")) + arm2Group = AnnotationGroup(region, get_stellate_term("stellate arm 2")) + arm3Group = AnnotationGroup(region, get_stellate_term("stellate arm 3")) stellateGroup = AnnotationGroup(region, get_stellate_term("cervicothoracic ganglion")) - # annotationGroups = [ left2Group, left3Group, top1Group, top2Group, bottom1Group, bottom3Group, stellateGroup ] - annotationGroups = [ left2Group, top1Group, bottom1Group, stellateGroup ] - - left2MeshGroup = left2Group.getMeshGroup(mesh) - left3MeshGroup = left3Group.getMeshGroup(mesh) - top1MeshGroup = top1Group.getMeshGroup(mesh) - top2MeshGroup = top2Group.getMeshGroup(mesh) - bottom1MeshGroup = bottom1Group.getMeshGroup(mesh) - bottom3MeshGroup = bottom3Group.getMeshGroup(mesh) + annotationGroups = [ arm1Group, arm2Group, arm3Group, stellateGroup ] + + arm1MeshGroup = arm1Group.getMeshGroup(mesh) + arm2MeshGroup = arm2Group.getMeshGroup(mesh) + arm3MeshGroup = arm3Group.getMeshGroup(mesh) stellateMeshGroup = stellateGroup.getMeshGroup(mesh) # Create nodes @@ -462,18 +453,12 @@ def generateBaseMesh(cls, region, options): # add to meshGroup stellateMeshGroup.addElement(element) if isMouse: - if (na == 0 and e2 == 0): - bottom1MeshGroup.addElement(element) - elif (na == 2 and e2 == 1): - bottom3MeshGroup.addElement(element) - elif (na == 0 and e2 == 1): - top1MeshGroup.addElement(element) - elif (na == 1 and e2 == 0): - top2MeshGroup.addElement(element) - elif (na == 1 and e2 == 1): - left2MeshGroup.addElement(element) - elif (na == 2 and e2 == 0): - left3MeshGroup.addElement(element) + if na == 0: + arm1MeshGroup.addElement(element) + elif na == 1: + arm2MeshGroup.addElement(element) + elif na == 2: + arm3MeshGroup.addElement(element) ############################ # annotation fiducial points @@ -520,35 +505,35 @@ def defineFaceAnnotations(cls, region, options, annotationGroups): """ # create groups fm = region.getFieldmodule() - left2Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-2-3")) - left3Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-2-3")) - top1Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-1-2")) - top2Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-1-2")) - bottom1Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-1-3")) - bottom3Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("interArm-1-3")) stellateGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("cervicothoracic ganglion")) + arm1Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("stellate arm 1")) + arm2Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("stellate arm 2")) + arm3Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("stellate arm 3")) mesh2d = fm.findMeshByDimension(2) is_exterior = fm.createFieldIsExterior() is_exterior_face_xi2_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI2_0)) is_exterior_face_xi2_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI2_1)) - is_left2 = left2Group.getFieldElementGroup(mesh2d) - is_left3 = left3Group.getFieldElementGroup(mesh2d) - is_left_face = fm.createFieldOr(fm.createFieldAnd(is_left2, is_exterior_face_xi2_1), fm.createFieldAnd(is_left3, is_exterior_face_xi2_0)) - leftStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("interArm-2-3 face")) + is_arm1 = arm1Group.getFieldElementGroup(mesh2d) + is_arm2 = arm2Group.getFieldElementGroup(mesh2d) + is_arm3 = arm3Group.getFieldElementGroup(mesh2d) + is_left_face = fm.createFieldOr( + fm.createFieldAnd(is_arm2, is_exterior_face_xi2_1), + fm.createFieldAnd(is_arm3, is_exterior_face_xi2_0)) + leftStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("stellate face 2-3")) leftStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_left_face) - is_top1 = top1Group.getFieldElementGroup(mesh2d) - is_top2 = top2Group.getFieldElementGroup(mesh2d) - is_top_face = fm.createFieldOr(fm.createFieldAnd(is_top1, is_exterior_face_xi2_1), fm.createFieldAnd(is_top2, is_exterior_face_xi2_0)) - topStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("interArm-1-2 face")) + is_top_face = fm.createFieldOr( + fm.createFieldAnd(is_arm1, is_exterior_face_xi2_1), + fm.createFieldAnd(is_arm2, is_exterior_face_xi2_0)) + topStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("stellate face 1-2")) topStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_top_face) - is_bottom1 = bottom1Group.getFieldElementGroup(mesh2d) - is_bottom3 = bottom3Group.getFieldElementGroup(mesh2d) - is_bottom_face = fm.createFieldOr(fm.createFieldAnd(is_bottom1, is_exterior_face_xi2_0), fm.createFieldAnd(is_bottom3, is_exterior_face_xi2_1)) - bottomStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("interArm-1-3 face")) + is_bottom_face = fm.createFieldOr( + fm.createFieldAnd(is_arm1, is_exterior_face_xi2_0), + fm.createFieldAnd(is_arm3, is_exterior_face_xi2_1)) + bottomStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("stellate face 3-1")) bottomStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_bottom_face) @@ -622,7 +607,7 @@ def createArm(halfArmArcAngleRadians, elementLengths, elementLengthCentral, elem x1 = dvertex[0] x2 = dvertex[1] else: - if e1 == elementsCount1 and shorterArmEnd: # and e2 == 1:# armEnd + if e1 == elementsCount1 and shorterArmEnd: x1 = 0.5*(elementLength+elementWidth) + elementLength*(e1-1) else: x1 = elementLength*e1 From 42ee4ae1b8e649989739a378de05a2b21d851e1b Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Fri, 18 Sep 2020 08:53:26 +1200 Subject: [PATCH 04/11] Update stellate_terms --- .../annotation/stellate_terms.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/scaffoldmaker/annotation/stellate_terms.py diff --git a/src/scaffoldmaker/annotation/stellate_terms.py b/src/scaffoldmaker/annotation/stellate_terms.py new file mode 100644 index 00000000..08a6ec24 --- /dev/null +++ b/src/scaffoldmaker/annotation/stellate_terms.py @@ -0,0 +1,25 @@ +""" +Common resource for stellate annotation terms. +""" + +# convention: preferred name, preferred id, followed by any other ids and alternative names +stellate_terms = [ + ( "stellate arm 1", None), + ( "stellate arm 2", None), + ( "stellate arm 3", None), + ( "stellate face 2-3", None), + ( "stellate face 1-2", None), + ( "stellate face 3-1", None), + ( "cervicothoracic ganglion", "UBERON:2441", "FMA:6469", "ILX:733799") + ] + +def get_stellate_term(name : str): + """ + Find term by matching name to any identifier held for a term. + Raise exception if name not found. + :return ( preferred name, preferred id ) + """ + for term in stellate_terms: + if name in term: + return ( term[0], term[1] ) + raise NameError("Stellate annotation term '" + name + "' not found.") From ee71a0d5c0a838c86536285348528417dbd728fb Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Mon, 21 Sep 2020 15:08:25 +1200 Subject: [PATCH 05/11] Add soma markers --- .../meshtypes/meshtype_3d_stellate1.py | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index 5f8acc8d..8710f5d3 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -161,7 +161,15 @@ def generateBaseMesh(cls, region, options): "Thoracic spinal nerve 1" : {"elementID": 1, "xi": [1.0, 0.0, 0.5]}, "Thoracic spinal nerve 2" : {"elementID": 2, "xi": [1.0, 0.0, 0.5]}, "Thoracic spinal nerve 3" : {"elementID": 3, "xi": [1.0, 0.0, 0.5]}, - "Thoracic sympathetic nerve trunk" : {"elementID": 4, "xi": [1.0, 1.0, 0.5]} + "Thoracic sympathetic nerve trunk" : {"elementID": 4, "xi": [1.0, 1.0, 0.5]}, + "Soma_Inferior cardiac nerve": {"elementID": 10, "xi": [0.0, 0.50, 0.5]}, + "Soma_Ventral ansa subclavia" : {"elementID": 12, "xi": [0.0, 0.50, 0.5]}, + "Soma_Dorsal ansa subclavia" : {"elementID": 14, "xi": [0.00, 0.50, 0.5]}, + "Soma_Cervical spinal nerve 8" : {"elementID": 16, "xi": [0.0, 0.50, 0.5]}, + "Soma_Thoracic spinal nerve 1" : {"elementID": 1, "xi": [1.0, 0.50, 0.5]}, + "Soma_Thoracic spinal nerve 2" : {"elementID": 2, "xi": [1.0, 0.50, 0.5]}, + "Soma_Thoracic spinal nerve 3" : {"elementID": 3, "xi": [1.0, 0.50, 0.5]}, + "Soma_Thoracic sympathetic nerve trunk" : {"elementID": 4, "xi": [0.50, 1.0, 0.5]} } if isLongMouse: allMarkers = { "Inferior cardiac nerve" : {"elementID": 12, "xi": [0.50, 0.0, 0.5]}, @@ -171,7 +179,15 @@ def generateBaseMesh(cls, region, options): "Thoracic spinal nerve 1" : {"elementID": 1, "xi": [1.0, 0.0, 0.5]}, "Thoracic spinal nerve 2" : {"elementID": 3, "xi": [0.5, 0.0, 0.5]}, "Thoracic spinal nerve 3" : {"elementID": 4, "xi": [0.5, 0.0, 0.5]}, - "Thoracic sympathetic nerve trunk" : {"elementID": 5, "xi": [1.0, 1.0, 0.5]} + "Thoracic sympathetic nerve trunk" : {"elementID": 5, "xi": [1.0, 1.0, 0.5]}, + "Soma_Inferior cardiac nerve": {"elementID": 12, "xi": [0.0, 0.50, 0.5]}, + "Soma_Ventral ansa subclavia": {"elementID": 14, "xi": [0.0, 0.50, 0.5]}, + "Soma_Dorsal ansa subclavia": {"elementID": 16, "xi": [0.00, 0.50, 0.5]}, + "Soma_Cervical spinal nerve 8": {"elementID": 18, "xi": [0.0, 0.50, 0.5]}, + "Soma_Thoracic spinal nerve 1": {"elementID": 1, "xi": [1.0, 0.50, 0.5]}, + "Soma_Thoracic spinal nerve 2": {"elementID": 3, "xi": [0.50, 0.50, 0.5]}, + "Soma_Thoracic spinal nerve 3": {"elementID": 4, "xi": [0.50, 0.50, 0.5]}, + "Soma_Thoracic sympathetic nerve trunk": {"elementID": 5, "xi": [0.50, 1.0, 0.5]} } # arm group annotations for user From 545d30a2da9bcb0768523231bea94248ec411abe Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Wed, 23 Sep 2020 10:01:29 +1200 Subject: [PATCH 06/11] With marker positions as proportion of arms, and calculated outside element-building loop; other small fixes. --- .../annotation/stellate_terms.py | 6 - .../meshtypes/meshtype_3d_stellate1.py | 178 +++++++++--------- 2 files changed, 85 insertions(+), 99 deletions(-) diff --git a/src/scaffoldmaker/annotation/stellate_terms.py b/src/scaffoldmaker/annotation/stellate_terms.py index 08a6ec24..22904589 100644 --- a/src/scaffoldmaker/annotation/stellate_terms.py +++ b/src/scaffoldmaker/annotation/stellate_terms.py @@ -4,12 +4,6 @@ # convention: preferred name, preferred id, followed by any other ids and alternative names stellate_terms = [ - ( "stellate arm 1", None), - ( "stellate arm 2", None), - ( "stellate arm 3", None), - ( "stellate face 2-3", None), - ( "stellate face 1-2", None), - ( "stellate face 3-1", None), ( "cervicothoracic ganglion", "UBERON:2441", "FMA:6469", "ILX:733799") ] diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index 8710f5d3..422a31d6 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -8,8 +8,8 @@ from opencmiss.zinc.element import Element from opencmiss.zinc.field import Field from opencmiss.zinc.node import Node -from scaffoldmaker.annotation.stellate_terms import get_stellate_term from scaffoldmaker.annotation.annotationgroup import AnnotationGroup, findOrCreateAnnotationGroupForTerm, getAnnotationGroupForTerm +from scaffoldmaker.annotation.stellate_terms import get_stellate_term from scaffoldmaker.meshtypes.scaffold_base import Scaffold_base from scaffoldmaker.utils.eftfactory_bicubichermitelinear import eftfactory_bicubichermitelinear from scaffoldmaker.utils.meshrefinement import MeshRefinement @@ -30,16 +30,16 @@ def getName(): def getParameterSetNames(): return [ 'Default', - 'Mouse 1'] + 'Mouse 1', + 'Mouse 2'] @classmethod def getDefaultOptions(cls, parameterSetName='Default'): - # isMouse = 'Mouse' in parameterSetName #options['Base parameter set'] options = {} options['Base parameter set'] = parameterSetName isMouse = 'Mouse' in parameterSetName - isLongMouse = 'Long Mouse' in parameterSetName + isLongMouse = parameterSetName == 'Mouse 2' if isMouse: options['Numbers of elements along arms'] = [4,2,2] @@ -47,7 +47,7 @@ def getDefaultOptions(cls, parameterSetName='Default'): options['Numbers of elements along arms'] = [5,2,2] else: options['Numbers of elements along arms'] = [4,2,2] - options['Element length around central wheel'] = 0.8 + options['Element width central'] = 0.8 options['Element length along arm'] = 0.8 options['Element width across arm'] = 0.3 options['Element thickness'] = 0.1 @@ -55,7 +55,6 @@ def getDefaultOptions(cls, parameterSetName='Default'): options['Refine number of elements along arm'] = 1 options['Refine number of elements across arm'] = 1 options['Refine number of elements through thickness'] = 1 - # cls.updateSubScaffoldOptions(options) return options @@ -64,7 +63,7 @@ def getOrderedOptionNames(): return [ 'Numbers of elements along arms', - 'Element length around central wheel', + 'Element width central', 'Element length along arm', 'Element width across arm', 'Element thickness', @@ -72,7 +71,6 @@ def getOrderedOptionNames(): 'Refine number of elements along arm', 'Refine number of elements across arm', 'Refine number of elements through thickness' - ] @classmethod @@ -85,7 +83,7 @@ def checkOptions(cls, options): options[key] = 1 for key in [ - 'Element length around central wheel', + 'Element width central', 'Element length along arm', 'Element width across arm', 'Element thickness']: @@ -103,8 +101,6 @@ def checkOptions(cls, options): if numberOfElements < 2: options[armCountsKey][i] = 2 - # cls.updateSubScaffoldOptions(options) - @classmethod def generateBaseMesh(cls, region, options): """ @@ -115,10 +111,10 @@ def generateBaseMesh(cls, region, options): """ isDefault = 'Default' in options['Base parameter set'] isMouse = 'Mouse' in options['Base parameter set'] and 'Long' not in options['Base parameter set'] - isLongMouse = 'Long Mouse' in options['Base parameter set'] + isLongMouse = options['Base parameter set'] == 'Mouse 2' armCount = 3 - elementLengthCentral = options['Element length around central wheel'] + elementLengthCentral = options['Element width central'] elementLengths = [options['Element length along arm'], options['Element width across arm'], options['Element thickness']] @@ -151,55 +147,55 @@ def generateBaseMesh(cls, region, options): markerTemplateInternal.defineField(markerLocation) # markers with element number and xi position - # for numElem = [4,2,2] allMarkers = {} if isMouse: - allMarkers = { "Inferior cardiac nerve" : {"elementID": 10, "xi": [0.50, 0.0, 0.5]}, - "Ventral ansa subclavia" : {"elementID": 12, "xi": [0.50, 1.0, 0.5]}, - "Dorsal ansa subclavia" : {"elementID": 14, "xi": [0.50, 0.0, 0.5]}, - "Cervical spinal nerve 8" : {"elementID": 16, "xi": [0.50, 1.0, 0.5]}, - "Thoracic spinal nerve 1" : {"elementID": 1, "xi": [1.0, 0.0, 0.5]}, - "Thoracic spinal nerve 2" : {"elementID": 2, "xi": [1.0, 0.0, 0.5]}, - "Thoracic spinal nerve 3" : {"elementID": 3, "xi": [1.0, 0.0, 0.5]}, - "Thoracic sympathetic nerve trunk" : {"elementID": 4, "xi": [1.0, 1.0, 0.5]}, - "Soma_Inferior cardiac nerve": {"elementID": 10, "xi": [0.0, 0.50, 0.5]}, - "Soma_Ventral ansa subclavia" : {"elementID": 12, "xi": [0.0, 0.50, 0.5]}, - "Soma_Dorsal ansa subclavia" : {"elementID": 14, "xi": [0.00, 0.50, 0.5]}, - "Soma_Cervical spinal nerve 8" : {"elementID": 16, "xi": [0.0, 0.50, 0.5]}, - "Soma_Thoracic spinal nerve 1" : {"elementID": 1, "xi": [1.0, 0.50, 0.5]}, - "Soma_Thoracic spinal nerve 2" : {"elementID": 2, "xi": [1.0, 0.50, 0.5]}, - "Soma_Thoracic spinal nerve 3" : {"elementID": 3, "xi": [1.0, 0.50, 0.5]}, - "Soma_Thoracic sympathetic nerve trunk" : {"elementID": 4, "xi": [0.50, 1.0, 0.5]} - } - if isLongMouse: - allMarkers = { "Inferior cardiac nerve" : {"elementID": 12, "xi": [0.50, 0.0, 0.5]}, - "Ventral ansa subclavia" : {"elementID": 14, "xi": [0.50, 1.0, 0.5]}, - "Dorsal ansa subclavia" : {"elementID": 16, "xi": [0.50, 0.0, 0.5]}, - "Cervical spinal nerve 8" : {"elementID": 18, "xi": [0.50, 1.0, 0.5]}, - "Thoracic spinal nerve 1" : {"elementID": 1, "xi": [1.0, 0.0, 0.5]}, - "Thoracic spinal nerve 2" : {"elementID": 3, "xi": [0.5, 0.0, 0.5]}, - "Thoracic spinal nerve 3" : {"elementID": 4, "xi": [0.5, 0.0, 0.5]}, - "Thoracic sympathetic nerve trunk" : {"elementID": 5, "xi": [1.0, 1.0, 0.5]}, - "Soma_Inferior cardiac nerve": {"elementID": 12, "xi": [0.0, 0.50, 0.5]}, - "Soma_Ventral ansa subclavia": {"elementID": 14, "xi": [0.0, 0.50, 0.5]}, - "Soma_Dorsal ansa subclavia": {"elementID": 16, "xi": [0.00, 0.50, 0.5]}, - "Soma_Cervical spinal nerve 8": {"elementID": 18, "xi": [0.0, 0.50, 0.5]}, - "Soma_Thoracic spinal nerve 1": {"elementID": 1, "xi": [1.0, 0.50, 0.5]}, - "Soma_Thoracic spinal nerve 2": {"elementID": 3, "xi": [0.50, 0.50, 0.5]}, - "Soma_Thoracic spinal nerve 3": {"elementID": 4, "xi": [0.50, 0.50, 0.5]}, - "Soma_Thoracic sympathetic nerve trunk": {"elementID": 5, "xi": [0.50, 1.0, 0.5]} + xProportion = {} + xProportion['ICN'] = 0.9 + xProportion['VA'] = 0.9 + xProportion['DA'] = 0.9 + xProportion['C8'] = 0.9 + xProportion['T1'] = 0.25 + xProportion['T2'] = 0.5 + xProportion['T3'] = 0.75 + xProportion['TST'] = 1 + armNumber = {} + armNumber['ICN'] = 2 + armNumber['VA'] = 2 + armNumber['DA'] = 3 + armNumber['C8'] = 3 + armNumber['T1'] = 1 + armNumber['T2'] = 1 + armNumber['T3'] = 1 + armNumber['TST'] = 1 + nerveAbbrev = list(xProportion.keys()) + elementIndex = {} + xi1 = {} + for nerve in nerveAbbrev: + elementIndex[nerve] = int(xProportion[nerve] * elementsCount1[armNumber[nerve]-1]) + xi1[nerve] = 1 if xProportion[nerve] == 1 else xProportion[nerve] * elementsCount1[armNumber[nerve]-1] - elementIndex[nerve] + elementIndex[nerve] += 1 if xProportion[nerve] < 1 else 0 + j = 10 + + allMarkers = { "Inferior cardiac nerve" : {"elementID": elementIndex['ICN']+2*elementsCount1[0], "xi": [xi1['ICN'], 0.0, 0.5]}, + "Ventral ansa subclavia" : {"elementID": elementIndex['VA']+2*elementsCount1[0]+elementsCount1[1], "xi": [xi1['VA'], 1.0, 0.5]}, + "Dorsal ansa subclavia" : {"elementID": elementIndex['DA']+2*(elementsCount1[0]+elementsCount1[1]), "xi": [xi1['DA'], 0.0, 0.5]}, + "Cervical spinal nerve 8" : {"elementID": elementIndex['C8']+2*(elementsCount1[0]+elementsCount1[1])+elementsCount1[2], "xi": [xi1['C8'], 1.0, 0.5]}, + "Thoracic spinal nerve 1" : {"elementID": elementIndex['T1'], "xi": [xi1['T1'], 0.0, 0.5]}, + "Thoracic spinal nerve 2" : {"elementID": elementIndex['T2'], "xi": [xi1['T2'], 0.0, 0.5]}, + "Thoracic spinal nerve 3" : {"elementID": elementIndex['T3'], "xi": [xi1['T3'], 0.0, 0.5]}, + "Thoracic sympathetic nerve trunk" : {"elementID": elementIndex['TST'], "xi": [xi1['TST'], 1.0, 0.5]}, } # arm group annotations for user - arm1Group = AnnotationGroup(region, get_stellate_term("stellate arm 1")) - arm2Group = AnnotationGroup(region, get_stellate_term("stellate arm 2")) - arm3Group = AnnotationGroup(region, get_stellate_term("stellate arm 3")) + armNames, faceNames = getUnlabelledStellateArmNames(armCount) + armGroups = [AnnotationGroup(region, armNames[0]), + AnnotationGroup(region, armNames[1]), + AnnotationGroup(region, armNames[2])] stellateGroup = AnnotationGroup(region, get_stellate_term("cervicothoracic ganglion")) - annotationGroups = [ arm1Group, arm2Group, arm3Group, stellateGroup ] + annotationGroups = armGroups.copy() + annotationGroups.append(stellateGroup) - arm1MeshGroup = arm1Group.getMeshGroup(mesh) - arm2MeshGroup = arm2Group.getMeshGroup(mesh) - arm3MeshGroup = arm3Group.getMeshGroup(mesh) + armMeshGroups = [a.getMeshGroup(mesh) for a in armGroups] stellateMeshGroup = stellateGroup.getMeshGroup(mesh) # Create nodes @@ -214,9 +210,6 @@ def generateBaseMesh(cls, region, options): x_in_nodes = [] for na in range(armCount): elementsCount_i = [elementsCount1[na], elementsCount2, elementsCount3] - # armAngleIn = minArmAngle * na - # if armCount == 3 and na == armCount-1: - # halfArmArcAngleRadians = math.pi/2 #math.pi + math.pi/(2*armCount) x, ds1, ds2, nWheelEdge = createArm(halfArmArcAngleRadians, elementLengths, elementLengthCentral, elementsCount_i, dipMultiplier, armCount, na) for ix in range(len(x)): if na == 0 or ix not in nWheelEdge: @@ -233,7 +226,6 @@ def generateBaseMesh(cls, region, options): xds1.append(ds1) xds2.append(ds2) - # Create elements bicubichermitelinear = eftfactory_bicubichermitelinear(mesh, useCrossDerivatives) eft = bicubichermitelinear.createEftNoCrossDerivatives() #createEftBasic() @@ -271,13 +263,12 @@ def generateBaseMesh(cls, region, options): nwPrev[1], no2 + em - 1 + nplUq, nCentre[1], bni + (4 * em) - 2] else: - # nplPrev = int(numNodesPerArm[na]/2) - elementsCount1[na-1] - 2 nplPrev = int(numNodesPerArm[na]/2) - 2 no2 = elementsCount1[na]-1 no3 = int(numNodesPerArm[na+1]/2) - 3 nwPrev = [cumNumNodesPerArm[na-1] + 2*(elementsCount1[na-1]), cumNumNodesPerArm[na-1] + 2*(elementsCount1[na-1]) + nplPrev] - start = cumNumNodesPerArm[na] - 3 # -4 + 1 + start = cumNumNodesPerArm[na] - 3 nodeIdentifiers = [nwPrev[0], start, nCentre[0], start + no2, nwPrev[1], start + no3, @@ -444,7 +435,6 @@ def generateBaseMesh(cls, region, options): # rounded ends of arms. Collapse xi2 at xi1 = 1 eft1 = bicubichermitelinear.createEftNoCrossDerivatives() remapEftNodeValueLabel(eft1, [2, 4, 6, 8], Node.VALUE_LABEL_D_DS2, []) - # remapEftNodeValueLabel(eft1, [2, 5], Node.VALUE_LABEL_D_DS2, []) if e2 == 0: remapEftNodeValueLabel(eft1, [2, 6], Node.VALUE_LABEL_D_DS1, [(Node.VALUE_LABEL_D_DS2, [])]) @@ -468,33 +458,28 @@ def generateBaseMesh(cls, region, options): # add to meshGroup stellateMeshGroup.addElement(element) - if isMouse: - if na == 0: - arm1MeshGroup.addElement(element) - elif na == 1: - arm2MeshGroup.addElement(element) - elif na == 2: - arm3MeshGroup.addElement(element) - - ############################ - # annotation fiducial points - ############################ - if allMarkers: - for key in allMarkers: - if elementIdentifier == allMarkers[key]["elementID"]: - elementID = allMarkers[key]["elementID"] - xi = allMarkers[key]["xi"] - addMarker = {"name": key, "xi": allMarkers[key]["xi"]} - - markerPoint = markerPoints.createNode(nodeIdentifier, markerTemplateInternal) - nodeIdentifier += 1 - cache.setNode(markerPoint) - markerName.assignString(cache, addMarker["name"]) - markerLocation.assignMeshLocation(cache, element, addMarker["xi"]) + armMeshGroups[na].addElement(element) elementIdentifier += 1 - return annotationGroups #[] + ############################ + # annotation fiducial points + ############################ + if isMouse: + for key in allMarkers: + + xi = allMarkers[key]["xi"] + addMarker = {"name": key, "xi": allMarkers[key]["xi"]} + + markerPoint = markerPoints.createNode(nodeIdentifier, markerTemplateInternal) + nodeIdentifier += 1 + cache.setNode(markerPoint) + markerName.assignString(cache, addMarker["name"]) + elementID = allMarkers[key]["elementID"] + element = mesh.findElementByIdentifier(elementID) + markerLocation.assignMeshLocation(cache, element, addMarker["xi"]) + + return annotationGroups @classmethod def refineMesh(cls, meshrefinement, options): @@ -521,10 +506,12 @@ def defineFaceAnnotations(cls, region, options, annotationGroups): """ # create groups fm = region.getFieldmodule() + armCount = len(options['Numbers of elements along arms']) stellateGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("cervicothoracic ganglion")) - arm1Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("stellate arm 1")) - arm2Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("stellate arm 2")) - arm3Group = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("stellate arm 3")) + armNames, faceNames = getUnlabelledStellateArmNames(armCount) + arm1Group = getAnnotationGroupForTerm(annotationGroups, armNames[0]) + arm2Group = getAnnotationGroupForTerm(annotationGroups, armNames[1]) + arm3Group = getAnnotationGroupForTerm(annotationGroups, armNames[2]) mesh2d = fm.findMeshByDimension(2) is_exterior = fm.createFieldIsExterior() @@ -537,21 +524,26 @@ def defineFaceAnnotations(cls, region, options, annotationGroups): is_left_face = fm.createFieldOr( fm.createFieldAnd(is_arm2, is_exterior_face_xi2_1), fm.createFieldAnd(is_arm3, is_exterior_face_xi2_0)) - leftStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("stellate face 2-3")) + leftStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, faceNames[1]) leftStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_left_face) is_top_face = fm.createFieldOr( fm.createFieldAnd(is_arm1, is_exterior_face_xi2_1), fm.createFieldAnd(is_arm2, is_exterior_face_xi2_0)) - topStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("stellate face 1-2")) + topStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, faceNames[0]) topStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_top_face) is_bottom_face = fm.createFieldOr( fm.createFieldAnd(is_arm1, is_exterior_face_xi2_0), fm.createFieldAnd(is_arm3, is_exterior_face_xi2_1)) - bottomStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, get_stellate_term("stellate face 3-1")) + bottomStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, faceNames[-1]) bottomStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_bottom_face) +def getUnlabelledStellateArmNames(armCount): + armNames = [("stellate arm %d"%(d), None) for d in range(1,armCount+1)] + faceNames = [("stellate face %d-%d"%(d, d+1), None) for d in range(1,armCount+1)] + faceNames[-1] = ("stellate face %d-1"%(armCount), None) + return armNames, faceNames def createArm(halfArmArcAngleRadians, elementLengths, elementLengthCentral, elementsCount, dipMultiplier, armCount, armIndex): """ @@ -561,7 +553,7 @@ def createArm(halfArmArcAngleRadians, elementLengths, elementLengthCentral, elem Minimum arm length is 2 elements. :param halfArmArcAngleRadians: angle arising from base node (rad) :param elementLengths: [Element length along arm, half Element width across arm, Element thickness] - :param elementLengthCentral: Element length around central wheel + :param elementLengthCentral: Radial element length about central node. :param elementsCount: list of numbers of elements along arm length, across width and through thickness directions :param dipMultiplier: factor that wheel nodes protrude by, relative to unit length :param armCount: number of arms in body From d5d709b3eb7bc9f9efd5f6d92f209da4a178362b Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Thu, 24 Sep 2020 09:42:47 +1200 Subject: [PATCH 07/11] Remove Mouse 2 --- src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index 422a31d6..f00bf4b8 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -30,8 +30,7 @@ def getName(): def getParameterSetNames(): return [ 'Default', - 'Mouse 1', - 'Mouse 2'] + 'Mouse 1'] @classmethod def getDefaultOptions(cls, parameterSetName='Default'): @@ -39,12 +38,9 @@ def getDefaultOptions(cls, parameterSetName='Default'): options['Base parameter set'] = parameterSetName isMouse = 'Mouse' in parameterSetName - isLongMouse = parameterSetName == 'Mouse 2' if isMouse: options['Numbers of elements along arms'] = [4,2,2] - if isLongMouse: - options['Numbers of elements along arms'] = [5,2,2] else: options['Numbers of elements along arms'] = [4,2,2] options['Element width central'] = 0.8 @@ -110,8 +106,7 @@ def generateBaseMesh(cls, region, options): :return: None """ isDefault = 'Default' in options['Base parameter set'] - isMouse = 'Mouse' in options['Base parameter set'] and 'Long' not in options['Base parameter set'] - isLongMouse = options['Base parameter set'] == 'Mouse 2' + isMouse = 'Mouse' in options['Base parameter set'] armCount = 3 elementLengthCentral = options['Element width central'] From 6ef7604d43293fb9e5ddddda458ed0800e9848e4 Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Thu, 24 Sep 2020 11:34:11 +1200 Subject: [PATCH 08/11] Style fixes. --- .../meshtypes/meshtype_3d_stellate1.py | 58 ++++++------------- 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index f00bf4b8..772bb334 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -182,13 +182,10 @@ def generateBaseMesh(cls, region, options): } # arm group annotations for user - armNames, faceNames = getUnlabelledStellateArmNames(armCount) - armGroups = [AnnotationGroup(region, armNames[0]), - AnnotationGroup(region, armNames[1]), - AnnotationGroup(region, armNames[2])] + armTerms, _ = getAutomaticArmFaceTerms(armCount) + armGroups = [AnnotationGroup(region, armTerm) for armTerm in armTerms] stellateGroup = AnnotationGroup(region, get_stellate_term("cervicothoracic ganglion")) - annotationGroups = armGroups.copy() - annotationGroups.append(stellateGroup) + annotationGroups = [stellateGroup] + armGroups armMeshGroups = [a.getMeshGroup(mesh) for a in armGroups] stellateMeshGroup = stellateGroup.getMeshGroup(mesh) @@ -457,9 +454,7 @@ def generateBaseMesh(cls, region, options): elementIdentifier += 1 - ############################ # annotation fiducial points - ############################ if isMouse: for key in allMarkers: @@ -503,42 +498,25 @@ def defineFaceAnnotations(cls, region, options, annotationGroups): fm = region.getFieldmodule() armCount = len(options['Numbers of elements along arms']) stellateGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("cervicothoracic ganglion")) - armNames, faceNames = getUnlabelledStellateArmNames(armCount) - arm1Group = getAnnotationGroupForTerm(annotationGroups, armNames[0]) - arm2Group = getAnnotationGroupForTerm(annotationGroups, armNames[1]) - arm3Group = getAnnotationGroupForTerm(annotationGroups, armNames[2]) - mesh2d = fm.findMeshByDimension(2) is_exterior = fm.createFieldIsExterior() is_exterior_face_xi2_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI2_0)) is_exterior_face_xi2_1 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI2_1)) - - is_arm1 = arm1Group.getFieldElementGroup(mesh2d) - is_arm2 = arm2Group.getFieldElementGroup(mesh2d) - is_arm3 = arm3Group.getFieldElementGroup(mesh2d) - is_left_face = fm.createFieldOr( - fm.createFieldAnd(is_arm2, is_exterior_face_xi2_1), - fm.createFieldAnd(is_arm3, is_exterior_face_xi2_0)) - leftStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, faceNames[1]) - leftStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_left_face) - - is_top_face = fm.createFieldOr( - fm.createFieldAnd(is_arm1, is_exterior_face_xi2_1), - fm.createFieldAnd(is_arm2, is_exterior_face_xi2_0)) - topStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, faceNames[0]) - topStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_top_face) - - is_bottom_face = fm.createFieldOr( - fm.createFieldAnd(is_arm1, is_exterior_face_xi2_0), - fm.createFieldAnd(is_arm3, is_exterior_face_xi2_1)) - bottomStellateGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, faceNames[-1]) - bottomStellateGroup.getMeshGroup(mesh2d).addElementsConditional(is_bottom_face) - -def getUnlabelledStellateArmNames(armCount): - armNames = [("stellate arm %d"%(d), None) for d in range(1,armCount+1)] - faceNames = [("stellate face %d-%d"%(d, d+1), None) for d in range(1,armCount+1)] - faceNames[-1] = ("stellate face %d-1"%(armCount), None) - return armNames, faceNames + armTerms, faceTerms = getAutomaticArmFaceTerms(armCount) + + armGroups = [getAnnotationGroupForTerm(annotationGroups, armTerm) for armTerm in armTerms] + isArm =[armGroup.getFieldElementGroup(mesh2d) for armGroup in armGroups] + for arm in range(armCount): + is_face = fm.createFieldOr( + fm.createFieldAnd(isArm[arm - 1], is_exterior_face_xi2_1), + fm.createFieldAnd(isArm[arm], is_exterior_face_xi2_0)) + faceGroup = findOrCreateAnnotationGroupForTerm(annotationGroups, region, faceTerms[arm - 1]) + faceGroup.getMeshGroup(mesh2d).addElementsConditional(is_face) + +def getAutomaticArmFaceTerms(armCount): + armTerms = [("stellate arm %d"%(i), None) for i in range(1,armCount+1)] + faceTerms = [("stellate face %d-%d" % (i, (i % armCount) + 1), None) for i in range(1, armCount + 1)] + return armTerms, faceTerms def createArm(halfArmArcAngleRadians, elementLengths, elementLengthCentral, elementsCount, dipMultiplier, armCount, armIndex): """ From 632c038cc8747babb68d60220fcadad410c30397 Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Thu, 24 Sep 2020 11:57:37 +1200 Subject: [PATCH 09/11] Specify 'stellate' or 'cervicothoracic ganglion' depending on choice of scaffold --- src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index 772bb334..c0473b87 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -30,7 +30,7 @@ def getName(): def getParameterSetNames(): return [ 'Default', - 'Mouse 1'] + 'Mouse cervicothoracic ganglion 1'] @classmethod def getDefaultOptions(cls, parameterSetName='Default'): @@ -184,11 +184,13 @@ def generateBaseMesh(cls, region, options): # arm group annotations for user armTerms, _ = getAutomaticArmFaceTerms(armCount) armGroups = [AnnotationGroup(region, armTerm) for armTerm in armTerms] - stellateGroup = AnnotationGroup(region, get_stellate_term("cervicothoracic ganglion")) - annotationGroups = [stellateGroup] + armGroups + wholeScaffoldGroup = AnnotationGroup(region, ("stellate", None)) + if isMouse: + wholeScaffoldGroup = AnnotationGroup(region, get_stellate_term("cervicothoracic ganglion")) + annotationGroups = [wholeScaffoldGroup] + armGroups armMeshGroups = [a.getMeshGroup(mesh) for a in armGroups] - stellateMeshGroup = stellateGroup.getMeshGroup(mesh) + stellateMeshGroup = wholeScaffoldGroup.getMeshGroup(mesh) # Create nodes numNodesPerArm = [0] @@ -497,7 +499,6 @@ def defineFaceAnnotations(cls, region, options, annotationGroups): # create groups fm = region.getFieldmodule() armCount = len(options['Numbers of elements along arms']) - stellateGroup = getAnnotationGroupForTerm(annotationGroups, get_stellate_term("cervicothoracic ganglion")) mesh2d = fm.findMeshByDimension(2) is_exterior = fm.createFieldIsExterior() is_exterior_face_xi2_0 = fm.createFieldAnd(is_exterior, fm.createFieldIsOnFace(Element.FACE_TYPE_XI2_0)) From 8df9408b783ab5551a4e69f6be5e393c972d1c61 Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Fri, 25 Sep 2020 09:07:40 +1200 Subject: [PATCH 10/11] Rename wholeScaffold to stellate. Improve efficiency. --- src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index c0473b87..832bc7e2 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -184,13 +184,14 @@ def generateBaseMesh(cls, region, options): # arm group annotations for user armTerms, _ = getAutomaticArmFaceTerms(armCount) armGroups = [AnnotationGroup(region, armTerm) for armTerm in armTerms] - wholeScaffoldGroup = AnnotationGroup(region, ("stellate", None)) + stellateTerm = get_stellate_term("cervicothoracic ganglion") if isMouse else ("stellate", None) + stellateGroup = AnnotationGroup(region, stellateTerm) if isMouse: - wholeScaffoldGroup = AnnotationGroup(region, get_stellate_term("cervicothoracic ganglion")) - annotationGroups = [wholeScaffoldGroup] + armGroups + stellateGroup = AnnotationGroup(region, get_stellate_term("cervicothoracic ganglion")) + annotationGroups = [stellateGroup] + armGroups armMeshGroups = [a.getMeshGroup(mesh) for a in armGroups] - stellateMeshGroup = wholeScaffoldGroup.getMeshGroup(mesh) + stellateMeshGroup = stellateGroup.getMeshGroup(mesh) # Create nodes numNodesPerArm = [0] From ee7db4fd16743bfdb70db5a822362abd803e7d41 Mon Sep 17 00:00:00 2001 From: Shelley Fong Date: Fri, 25 Sep 2020 09:15:06 +1200 Subject: [PATCH 11/11] Remove unecessary lines. --- src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py index 832bc7e2..dd94ea15 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_stellate1.py @@ -186,8 +186,6 @@ def generateBaseMesh(cls, region, options): armGroups = [AnnotationGroup(region, armTerm) for armTerm in armTerms] stellateTerm = get_stellate_term("cervicothoracic ganglion") if isMouse else ("stellate", None) stellateGroup = AnnotationGroup(region, stellateTerm) - if isMouse: - stellateGroup = AnnotationGroup(region, get_stellate_term("cervicothoracic ganglion")) annotationGroups = [stellateGroup] + armGroups armMeshGroups = [a.getMeshGroup(mesh) for a in armGroups]