Exemplo n.º 1
0
def setPathParameters(region, nodeValueLabels, nodeValues, editGroupName=None):
    '''
    Set node parameters for coordinates field in path from listed values.
    :param nodeValueLabels: List of nodeValueLabels to set e.g. [ Node.VALUE_LABEL_VALUE, Node.VALUE_LABEL_D_DS1 ]
    :param nodeValues: List of values for each type e.g. [ xlist, d1list ]
    :param editGroupName: Optional name of existing or new Zinc group to record modified nodes in.
    '''
    fieldmodule = region.getFieldmodule()
    coordinates = fieldmodule.findFieldByName('coordinates').castFiniteElement()
    componentsCount = coordinates.getNumberOfComponents()
    # following requires at least one value label and node, assumes consistent values and components counts
    nodeValueLabelsCount = len(nodeValueLabels)
    nodesCount = len(nodeValues[0])
    nodes = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
    assert nodesCount == nodes.getSize()
    with ChangeManager(fieldmodule):
        if editGroupName:
            editGroup = findOrCreateFieldGroup(fieldmodule, editGroupName, managed=True)
            editNodeGroup = editGroup.getFieldNodeGroup(nodes)
            if not editNodeGroup.isValid():
                editNodeGroup = editGroup.createFieldNodeGroup(nodes)
            editNodesetGroup = editNodeGroup.getNodesetGroup()
        cache = fieldmodule.createFieldcache()
        nodeIter = nodes.createNodeiterator()
        node = nodeIter.next()
        n = 0
        while node.isValid():
            cache.setNode(node)
            for v in range(nodeValueLabelsCount):
                coordinates.setNodeParameters(cache, -1, nodeValueLabels[v], 1, nodeValues[v][n])
            if editGroupName:
                editNodesetGroup.addNode(node)
            node = nodeIter.next()
            n += 1
def zinc_write_element_xi_marker_file(outFile, region, allMarkers,
                                      nodeIdentifier):
    fm = region.getFieldmodule()
    fm.beginChange()
    nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
    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()
    markerTemplate = nodes.createNodetemplate()
    markerTemplate.defineField(markerName)
    markerTemplate.defineField(markerLocation)

    for key in allMarkers:
        addMarker = {"name": key + " projected", "xi": allMarkers[key]["xi"]}

        markerPoint = markerPoints.createNode(nodeIdentifier, markerTemplate)
        cache.setNode(markerPoint)
        markerName.assignString(cache, addMarker["name"])
        elementID = allMarkers[key]["elementID"]
        element = mesh.findElementByIdentifier(elementID)
        result = markerLocation.assignMeshLocation(cache, element,
                                                   addMarker["xi"])
        nodeIdentifier += 1

    fm.endChange()
    region.writeFile(outFile)
    return
Exemplo n.º 3
0
 def __init__(self,
              region,
              field,
              selectionGroupName=None,
              scalingMode=DerivativeScalingMode.ARITHMETIC_MEAN,
              editGroupName=None):
     '''
     :param selectionGroupName: Optional name of group to limit smoothing to nodes in group.
     Only element edges including those nodes are included in smoothing.
     '''
     self._region = region
     self._field = field.castFiniteElement()
     componentsCount = self._field.getNumberOfComponents()
     assert self._field.isValid()
     self._selectionGroupName = selectionGroupName
     self._selectionGroup = None
     self._selectionNodes = None
     self._scalingMode = scalingMode
     self._editGroupName = editGroupName
     self._fieldmodule = self._region.getFieldmodule()
     for dimension in range(3, 0, -1):
         self._mesh = self._fieldmodule.findMeshByDimension(dimension)
         if self._mesh.getSize() > 0:
             break
     self._nodes = self._fieldmodule.findNodesetByFieldDomainType(
         Field.DOMAIN_TYPE_NODES)
     # edited nodes are added to the edit nodeset group, if group is supplied
     if editGroupName:
         editGroup = findOrCreateFieldGroup(self._fieldmodule,
                                            editGroupName,
                                            managed=True)
         editNodeGroup = editGroup.getFieldNodeGroup(self._nodes)
         if not editNodeGroup.isValid():
             editNodeGroup = editGroup.createFieldNodeGroup(self._nodes)
         self._editNodesetGroup = editNodeGroup.getNodesetGroup()
     else:
         self._editNodesetGroup = None
     # edges define curves with 4 expressions for x1, d1, x2, d2, followed by the arcLength
     # each expression is a list of terms.
     # each term contains a list of global node id, value label, version, element identifier, scale factor or None
     # edges are mapped from sorted start and end node
     self._edgesMap = {}
     # map global nodeid, derivative, version to list of EdgeCurve
     self._derivativeMap = {}
     if selectionGroupName:
         self._selectionGroup = self._fieldmodule.findFieldByName(
             selectionGroupName).castGroup()
         if not self._selectionGroup.isValid():
             print('DerivativeSmoothing: Selection group not found')
             return
         self._selectionNodes = self._selectionGroup.getFieldNodeGroup(
             self._nodes).getNodesetGroup()
         if (not self._selectionNodes.isValid()) or (
                 self._selectionNodes.getSize() == 0):
             print('DerivativeSmoothing: No nodes selected for smoothing')
             return
     self.addElementEdges()
Exemplo n.º 4
0
 def test_field_group(self):
     """
     Test creation of group fields.
     """
     context = Context("test")
     region = context.createRegion()
     fieldmodule = region.getFieldmodule()
     group_name = "bob"
     group = findOrCreateFieldGroup(fieldmodule, group_name)
     self.assertTrue(group.isValid())
     self.assertTrue(group.isManaged())
     nodes = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
     node_group = findOrCreateFieldNodeGroup(group, nodes)
     self.assertTrue(node_group.isValid())
     self.assertFalse(node_group.isManaged())
     node_group_name = group_name + "." + nodes.getName()
     self.assertEqual(node_group_name, node_group.getName())
def zinc_write_element_xi_file(outFile, xyz, allMarkers):
    context = Context("Example")
    outputRegion = context.getDefaultRegion()
    fm = outputRegion.getFieldmodule()
    fm.beginChange()
    cache = fm.createFieldcache()
    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)
    markerNodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_DATAPOINTS)
    markerGroup = findOrCreateFieldGroup(fm, "marker")
    markerName = findOrCreateFieldStoredString(fm, name="marker_name")
    markerPoints = findOrCreateFieldNodeGroup(markerGroup,
                                              markerNodes).getNodesetGroup()
    markerTemplate = markerPoints.createNodetemplate()
    markerTemplate.defineField(markerName)
    markerTemplate.defineField(coordinates)

    nodeIdentifier = 1
    for ix in xyz:
        node = nodes.createNode(nodeIdentifier, nodetemplate)
        cache.setNode(node)
        coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, ix)
        nodeIdentifier += 1

    nodeIdentifier = 1
    for key in allMarkers:
        addMarker = {"name": key, "xyz": allMarkers[key]}
        node = markerPoints.createNode(nodeIdentifier, markerTemplate)
        cache.setNode(node)
        coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1,
                                      addMarker['xyz'])
        markerName.assignString(cache, addMarker["name"])
        nodeIdentifier += 1

    fm.endChange()
    outputRegion.writeFile(outFile)
Exemplo n.º 6
0
    def generateBaseMesh(cls, region, options):
        """
        Generate the base tricubic Hermite mesh. See also generateMesh().
        :param region: Zinc region to define model in. Must be empty.
        :param options: Dict containing options. See getDefaultOptions().
        :return: None
        """
        parameterSetName = options['Base parameter set']
        isDefault = 'Default' in parameterSetName
        isMouse = 'Mouse' in parameterSetName
        isMean = 'mean' in parameterSetName

        fm = region.getFieldmodule()
        nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
        coordinates = findOrCreateFieldCoordinates(fm)
        mesh = fm.findMeshByDimension(3)
        cache = fm.createFieldcache()
        nodetemplate = nodes.createNodetemplate()
        nodetemplate.defineField(coordinates)
        nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                              Node.VALUE_LABEL_VALUE, 1)
        nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                              Node.VALUE_LABEL_D_DS1, 1)
        nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                              Node.VALUE_LABEL_D_DS2, 1)

        armCount = 3
        elementLengthCentral = options['Element width central']
        elementLengths = [
            options['Element length along arm'],
            options['Element width across arm'], options['Element thickness']
        ]
        elementsCountsAlongArms = options['Numbers of elements along arms']
        elementsCount2 = 2
        elementsCount3 = 1
        useCrossDerivatives = False
        # arm group annotations for user
        armTerms, _ = getAutomaticArmFaceTerms(armCount)
        armGroups = [AnnotationGroup(region, armTerm) for armTerm in armTerms]
        stellateTerm = get_stellate_term(
            "cervicothoracic ganglion") if isMouse else ("stellate", None)
        stellateGroup = AnnotationGroup(region, stellateTerm)
        annotationGroups = [stellateGroup] + armGroups
        armMeshGroups = [a.getMeshGroup(mesh) for a in armGroups]
        stellateMeshGroup = stellateGroup.getMeshGroup(mesh)

        # markers with element number and xi position
        allMarkers = {}
        if isMouse:
            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] *
                    elementsCountsAlongArms[armNumber[nerve] - 1])
                xi1[nerve] = 1 if xProportion[nerve] == 1 else xProportion[
                    nerve] * elementsCountsAlongArms[armNumber[nerve] -
                                                     1] - elementIndex[nerve]
                elementIndex[nerve] += 1 if xProportion[nerve] < 1 else 0

            allMarkers = {
                "Inferior cardiac nerve": {
                    "elementID":
                    elementIndex['ICN'] + 2 * elementsCountsAlongArms[0],
                    "xi": [xi1['ICN'], 0.0, 0.5]
                },
                "Ventral ansa subclavia": {
                    "elementID":
                    elementIndex['VA'] + 2 * elementsCountsAlongArms[0] +
                    elementsCountsAlongArms[1],
                    "xi": [xi1['VA'], 1.0, 0.5]
                },
                "Dorsal ansa subclavia": {
                    "elementID":
                    elementIndex['DA'] + 2 *
                    (elementsCountsAlongArms[0] + elementsCountsAlongArms[1]),
                    "xi": [xi1['DA'], 0.0, 0.5]
                },
                "Cervical spinal nerve 8": {
                    "elementID":
                    elementIndex['C8'] + 2 *
                    (elementsCountsAlongArms[0] + elementsCountsAlongArms[1]) +
                    elementsCountsAlongArms[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]
                },
            }
            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)

        # Create nodes
        nodeIdentifier = 1
        minArmAngle = 2 * math.pi / armCount
        halfArmArcAngleRadians = minArmAngle / 2
        if not isMean:
            dipMultiplier = 1
            for na in range(armCount):
                elementsCount_i = [
                    elementsCountsAlongArms[na], elementsCount2, elementsCount3
                ]
                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)
                        cache.setNode(node)
                        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
        else:
            x_dx_all = cls.mouseMeanMesh['meshEdits']
            xyz_all = [x[0] for x in x_dx_all]
            dxyz = [[x[1], x[2]] for x in x_dx_all]
            nodeIdentifier = 1
            for i, nx in enumerate(xyz_all):
                node = nodes.createNode(nodeIdentifier, nodetemplate)
                cache.setNode(node)
                coordinates.setNodeParameters(cache, -1,
                                              Node.VALUE_LABEL_VALUE, 1, nx)
                coordinates.setNodeParameters(cache, -1,
                                              Node.VALUE_LABEL_D_DS1, 1,
                                              dxyz[i][0])
                coordinates.setNodeParameters(cache, -1,
                                              Node.VALUE_LABEL_D_DS2, 1,
                                              dxyz[i][1])
                nodeIdentifier += 1
        nodesCountsPerArm = [0] + [((elementsCount2 + 1) * e + 1) * 2
                                   for e in elementsCountsAlongArms]

        # Create elements
        bicubichermitelinear = eftfactory_bicubichermitelinear(
            mesh, useCrossDerivatives)
        eft = bicubichermitelinear.createEftNoCrossDerivatives(
        )  #createEftBasic()
        elementtemplate = mesh.createElementtemplate()
        elementtemplate.setElementShapeType(Element.SHAPE_TYPE_CUBE)
        elementtemplate.defineField(coordinates, -1, eft)
        elementtemplateX = mesh.createElementtemplate()
        elementtemplateX.setElementShapeType(Element.SHAPE_TYPE_CUBE)
        elementIdentifier = 1

        cumNodesCountsPerArm = [
            sum(nodesCountsPerArm[:i + 1])
            for i in range(len(nodesCountsPerArm))
        ]
        nCentre = [
            elementsCountsAlongArms[0] + 1,
            int(nodesCountsPerArm[1] / 2) + elementsCountsAlongArms[0] + 1
        ]
        for na in range(armCount):
            for e3 in range(elementsCount3):
                for e2 in range(elementsCount2):
                    for e1 in range(elementsCountsAlongArms[na]):
                        scalefactors = None
                        ### NODES ###
                        no2 = (elementsCountsAlongArms[na] + 1)
                        no3 = (elementsCount2 + 1) * no2 - 2
                        offset = (cumNodesCountsPerArm[na])
                        bni = e3 * no3 + e2 * no2 + e1 + 1 + offset
                        if e2 == 0:
                            if e1 == 0 and na > 0:  # and na < armCount -1: # wheelSouth
                                nWh = cumNodesCountsPerArm[na - 1] + (
                                    2 * elementsCountsAlongArms[na - 1]) + 2
                                nplUq = int(
                                    nodesCountsPerArm[na + 1] / 2
                                ) - elementsCountsAlongArms[
                                    na]  # unused nodes at centre and shared edge
                                npl = int(
                                    nodesCountsPerArm[na + 1] /
                                    2)  #  nodes at centre and shared edge
                                if na < armCount - 1:
                                    cn = cumNodesCountsPerArm[
                                        na] + elementsCountsAlongArms[na] - 2
                                    no2 = cumNodesCountsPerArm[na]
                                    em = elementsCountsAlongArms[na]
                                    nwPrev = [
                                        nWh,
                                        nWh + int(nodesCountsPerArm[na] / 2)
                                    ]  # previous arm's edge, depends on armCount.
                                    nodeIdentifiers = [
                                        nwPrev[0], no2 + 1, nCentre[0],
                                        no2 + em, nwPrev[1],
                                        no2 + em - 1 + nplUq, nCentre[1],
                                        bni + (4 * em) - 2
                                    ]
                                else:
                                    nplPrev = int(
                                        nodesCountsPerArm[na] / 2) - 2
                                    no2 = elementsCountsAlongArms[na] - 1
                                    no3 = int(
                                        nodesCountsPerArm[na + 1] / 2) - 3
                                    nwPrev = [
                                        cumNodesCountsPerArm[na - 1] + 2 *
                                        (elementsCountsAlongArms[na - 1]),
                                        cumNodesCountsPerArm[na - 1] + 2 *
                                        (elementsCountsAlongArms[na - 1]) +
                                        nplPrev
                                    ]
                                    start = cumNodesCountsPerArm[na] - 3
                                    nodeIdentifiers = [
                                        nwPrev[0], start, nCentre[0],
                                        start + no2, nwPrev[1], start + no3,
                                        nCentre[1], start + no2 + no3
                                    ]
                            elif e1 == elementsCountsAlongArms[
                                    na] - 1:  # armEnd, south
                                if na == 0:
                                    nodeIdentifiers = [
                                        bni, bni + no2 - 1, bni + no2,
                                        bni + no3, bni + no2 + no3 - 1,
                                        bni + no2 + no3
                                    ]
                                else:
                                    no3 = armCount * elementsCountsAlongArms[
                                        na] - 1
                                    no2 = elementsCountsAlongArms[na]
                                    if na > 1:
                                        bni -= 4
                                        no3 -= 1
                                    nodeIdentifiers = [
                                        bni - 1, bni + no2 - 2, bni + no2 - 1,
                                        bni + no3 - 1, bni + no2 - 2 + no3,
                                        bni + no2 + no3 - 1
                                    ]
                            elif na > 0 and e1 > 0:  #  [na=1+, e1=1+, e2=0] for len=3+
                                bni -= 1 + ((armCount + 1) * (na - 1))
                                no2 = elementsCountsAlongArms[na]
                                no3 = armCount * no2 - (na - 1) - 1
                                nodeIdentifiers = [
                                    bni, bni + 1, bni + no2 - 1, bni + no2,
                                    bni + no3, bni + no3 + 1,
                                    bni + no2 + no3 - 1, bni + no2 + no3
                                ]
                            else:
                                nodeIdentifiers = [
                                    bni, bni + 1, bni + no2 - 1, bni + no2,
                                    bni + no3, bni + no3 + 1,
                                    bni + no2 + no3 - 1, bni + no2 + no3
                                ]
                        else:
                            if e1 == 0 and na > 0:  # and na < armCount -1: # wheelNorth
                                if na < armCount - 1:
                                    bni -= armCount
                                    npl = int(
                                        nodesCountsPerArm[na + 1] / 2) - 2
                                    no2 = elementsCountsAlongArms[na]
                                    nodeIdentifiers = [
                                        nCentre[0], bni + 1, bni + no2 + 1,
                                        bni + no2 + 2, nCentre[1],
                                        bni + npl + 1, bni + npl + no2 + 1,
                                        bni + npl + no2 + 2
                                    ]
                                else:  # last arm
                                    bni = cumNodesCountsPerArm[na] - 2 - (
                                        armCount - elementsCountsAlongArms[na])
                                    nodeIdentifiers = [
                                        nCentre[0], bni + 1, 1, bni + no2,
                                        nCentre[1], bni + no3 - 2,
                                        int(nodesCountsPerArm[1] / 2) + 1,
                                        bni + no2 + no3 - armCount
                                    ]
                            elif e1 == elementsCountsAlongArms[
                                    na] - 1:  # armEnd north
                                if na > 0:
                                    no2 = elementsCountsAlongArms[na]
                                    nplUq = int(
                                        nodesCountsPerArm[na + 1] / 2) - 2
                                    if na > 1:
                                        adj = na - 1
                                        bni -= armCount * na + (
                                            armCount -
                                            elementsCountsAlongArms[na]) + 1
                                        if elementsCountsAlongArms[na] < 3:
                                            bni += 1
                                        if elementsCountsAlongArms[na] > 3:
                                            bni -= elementsCountsAlongArms[
                                                na] - 3
                                        no2 += 1 - adj
                                        no3 = nplUq - adj
                                        nodeIdentifiers = [
                                            bni, bni + 1, bni + no2, bni + no3,
                                            bni + no3 + 1, bni + no2 + no3
                                        ]
                                    else:
                                        bni -= armCount
                                        nodeIdentifiers = [
                                            bni, bni + 1, bni + no2 + 1,
                                            bni + nplUq, bni + nplUq + 1,
                                            bni + no2 + nplUq + 1
                                        ]
                                else:
                                    nodeIdentifiers = [
                                        bni - 1, bni, bni + no2 - 1,
                                        bni + no3 - 1, bni + no3,
                                        bni + no2 + no3 - 1
                                    ]

                            elif na > 0 and e1 > 0:  #  [na=1+, e1=1+, e2=1] for len=3+
                                adj = na - 1
                                bni -= armCount * na + adj
                                no2 -= adj
                                k = armCount * elementsCountsAlongArms[na] - na
                                nodeIdentifiers = [
                                    bni, bni + 1, bni + no2, bni + no2 + 1,
                                    bni + k, bni + k + 1, bni + no2 + k,
                                    bni + no2 + k + 1
                                ]
                            else:
                                nodeIdentifiers = [
                                    bni - 1, bni, bni + no2 - 1, bni + no2,
                                    bni + no3 - 1, bni + no3,
                                    bni + no2 + no3 - 1, bni + no2 + no3
                                ]

                        if e1 == 0:  # wheel
                            eft1 = bicubichermitelinear.createEftNoCrossDerivatives(
                            )
                            if armCount == 3:
                                if e2 == 0:
                                    setEftScaleFactorIds(eft1, [1], [])
                                    scalefactors = [-1.0]
                                    scaleEftNodeValueLabels(
                                        eft1, [1, 5], [
                                            Node.VALUE_LABEL_D_DS1,
                                            Node.VALUE_LABEL_D_DS2
                                        ], [1])
                                    ns = [3, 7]
                                else:
                                    ns = [1, 5]
                                if na == 0:
                                    remapEftNodeValueLabel(
                                        eft1, ns, Node.VALUE_LABEL_D_DS1,
                                        [(Node.VALUE_LABEL_D_DS1, []),
                                         (Node.VALUE_LABEL_D_DS2, [])])
                                    if e2 == 0:
                                        setEftScaleFactorIds(eft1, [1], [])
                                        scalefactors = [-1.0]
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS1, [1])])
                                elif na == 1:
                                    setEftScaleFactorIds(eft1, [1], [])
                                    scalefactors = [-1.0]
                                    remapEftNodeValueLabel(
                                        eft1, ns, Node.VALUE_LABEL_D_DS1,
                                        [(Node.VALUE_LABEL_D_DS1, [1])])
                                    if e2 == 0:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS2, [1])])
                                    elif e2 == 1:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS1, [1]),
                                             (Node.VALUE_LABEL_D_DS2, [1])])
                                elif na == 2:
                                    setEftScaleFactorIds(eft1, [1], [])
                                    scalefactors = [-1.0]
                                    remapEftNodeValueLabel(
                                        eft1, ns, Node.VALUE_LABEL_D_DS1,
                                        [(Node.VALUE_LABEL_D_DS2, [1])])
                                    if e2 == 0:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS1, []),
                                             (Node.VALUE_LABEL_D_DS2, [])])
                                    elif e2 == 1:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS1, [])])
                            elif armCount == 4:
                                if e2 == 0:
                                    setEftScaleFactorIds(eft1, [1], [])
                                    scalefactors = [-1.0]
                                    scaleEftNodeValueLabels(
                                        eft1, [1, 5], [
                                            Node.VALUE_LABEL_D_DS1,
                                            Node.VALUE_LABEL_D_DS2
                                        ], [1])
                                    ns = [3, 7]
                                else:
                                    ns = [1, 5]
                                if na == 0:
                                    remapEftNodeValueLabel(
                                        eft1, ns, Node.VALUE_LABEL_D_DS1,
                                        [(Node.VALUE_LABEL_D_DS1, []),
                                         (Node.VALUE_LABEL_D_DS2, [])])
                                    if e2 == 0:
                                        setEftScaleFactorIds(eft1, [1], [])
                                        scalefactors = [-1.0]
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS1, [1])])
                                elif na == 1:
                                    setEftScaleFactorIds(eft1, [1], [])
                                    scalefactors = [-1.0]
                                    remapEftNodeValueLabel(
                                        eft1, ns, Node.VALUE_LABEL_D_DS1,
                                        [(Node.VALUE_LABEL_D_DS1, [1]),
                                         (Node.VALUE_LABEL_D_DS2, [])])
                                    if e2 == 0:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS2, [1])])
                                    else:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS1, [1])])
                                elif na == 2:
                                    setEftScaleFactorIds(eft1, [1], [])
                                    scalefactors = [-1.0]
                                    remapEftNodeValueLabel(
                                        eft1, ns, Node.VALUE_LABEL_D_DS1,
                                        [(Node.VALUE_LABEL_D_DS1, [1]),
                                         (Node.VALUE_LABEL_D_DS2, [1])])
                                    if e2 == 0:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS1, [])])
                                    else:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS2, [1])])
                                elif na == 3:
                                    setEftScaleFactorIds(eft1, [1], [])
                                    scalefactors = [-1.0]
                                    remapEftNodeValueLabel(
                                        eft1, ns, Node.VALUE_LABEL_D_DS1,
                                        [(Node.VALUE_LABEL_D_DS1, []),
                                         (Node.VALUE_LABEL_D_DS2, [1])])
                                    if e2 == 0:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS2, [])])
                                    else:
                                        remapEftNodeValueLabel(
                                            eft1, ns, Node.VALUE_LABEL_D_DS2,
                                            [(Node.VALUE_LABEL_D_DS1, [])])

                        elif e1 < (elementsCountsAlongArms[na] - 1):
                            eft1 = eft
                            elementtemplate1 = elementtemplate
                        else:
                            # rounded ends of arms. Collapse xi2 at xi1 = 1
                            eft1 = bicubichermitelinear.createEftNoCrossDerivatives(
                            )
                            remapEftNodeValueLabel(eft1, [2, 4, 6, 8],
                                                   Node.VALUE_LABEL_D_DS2, [])
                            if e2 == 0:
                                remapEftNodeValueLabel(
                                    eft1, [2, 6], Node.VALUE_LABEL_D_DS1,
                                    [(Node.VALUE_LABEL_D_DS2, [])])
                                nodeIdentifiers = [
                                    nodeIdentifiers[0], nodeIdentifiers[2],
                                    nodeIdentifiers[1], nodeIdentifiers[3],
                                    nodeIdentifiers[5], nodeIdentifiers[4]
                                ]
                            else:  # e2 == 1
                                setEftScaleFactorIds(eft1, [1], [])
                                scalefactors = [-1.0]
                                remapEftNodeValueLabel(
                                    eft1, [4, 8], Node.VALUE_LABEL_D_DS1,
                                    [(Node.VALUE_LABEL_D_DS2, [1])])
                            ln_map = [1, 2, 3, 2, 4, 5, 6, 5]
                            remapEftLocalNodes(eft1, 6, ln_map)

                        if eft1 is not eft:
                            elementtemplateX.defineField(coordinates, -1, eft1)
                            elementtemplate1 = elementtemplateX

                        element = mesh.createElement(elementIdentifier,
                                                     elementtemplate1)
                        result = element.setNodesByIdentifier(
                            eft1, nodeIdentifiers)
                        result3 = element.setScaleFactors(
                            eft1, scalefactors) if scalefactors else None

                        # add to meshGroup
                        stellateMeshGroup.addElement(element)
                        armMeshGroups[na].addElement(element)

                        elementIdentifier += 1

        # 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
    def generateBaseMesh(cls, region, options):
        """
        Generate the base tricubic Hermite mesh. See also generateMesh().
        :param region: Zinc region to define model in. Must be empty.
        :param options: Dict containing options. See getDefaultOptions().
        :return: annotationGroups
        """
        centralPath = options['Central path']
        elementsCountAround = options['Number of elements around']
        elementsCountAlong = options['Number of elements along']
        elementsCountThroughWall = options['Number of elements through wall']
        wallThickness = options['Wall thickness']
        mucosaRelThickness = options['Mucosa relative thickness']
        submucosaRelThickness = options['Submucosa relative thickness']
        circularRelThickness = options[
            'Circular muscle layer relative thickness']
        longitudinalRelThickness = options[
            'Longitudinal muscle layer relative thickness']
        useCrossDerivatives = options['Use cross derivatives']
        useCubicHermiteThroughWall = not (options['Use linear through wall'])

        firstNodeIdentifier = 1
        firstElementIdentifier = 1

        # Central path
        esophagusTermsAlong = [
            None, 'cervical part of esophagus', 'thoracic part of esophagus',
            'abdominal part of esophagus'
        ]
        arcLengthOfGroupsAlong = []
        for i in range(len(esophagusTermsAlong)):
            tmpRegion = region.createRegion()
            centralPath.generate(tmpRegion)
            cxGroup, cd1Group, cd2Group, cd3Group, cd12Group, cd13Group = \
                extractPathParametersFromRegion(tmpRegion, [Node.VALUE_LABEL_VALUE, Node.VALUE_LABEL_D_DS1,
                                                            Node.VALUE_LABEL_D_DS2, Node.VALUE_LABEL_D_DS3,
                                                            Node.VALUE_LABEL_D2_DS1DS2, Node.VALUE_LABEL_D2_DS1DS3],
                                                groupName=esophagusTermsAlong[i])
            arcLength = 0.0
            for e in range(len(cxGroup) - 1):
                arcLength += interp.getCubicHermiteArcLength(
                    cxGroup[e], cd1Group[e], cxGroup[e + 1], cd1Group[e + 1])
            arcLengthOfGroupsAlong.append(arcLength)

            if i == 0:
                cx = cxGroup
                cd1 = cd1Group
                cd2 = cd2Group
                cd3 = cd3Group
                cd12 = cd12Group
                cd13 = cd13Group

            del tmpRegion

        # Sample central path
        sx, sd1, se, sxi, ssf = interp.sampleCubicHermiteCurves(
            cx, cd1, elementsCountAlong)
        sd2, sd12 = interp.interpolateSampleCubicHermite(
            cd2, cd12, se, sxi, ssf)
        sd3, sd13 = interp.interpolateSampleCubicHermite(
            cd3, cd13, se, sxi, ssf)

        centralPathLength = arcLengthOfGroupsAlong[0]
        elementAlongLength = centralPathLength / elementsCountAlong

        elementsCountAlongGroups = []
        groupLength = 0.0
        e = 0
        elementsCount = 1
        length = elementAlongLength
        for i in range(1, len(esophagusTermsAlong)):
            groupLength += arcLengthOfGroupsAlong[i]
            if e == elementsCountAlong - 2:
                elementsCount += 1
                elementsCountAlongGroups.append(elementsCount)
            else:
                while length < groupLength:
                    elementsCount += 1
                    e += 1
                    length += elementAlongLength

                # check which end is grouplength closer to
                distToUpperEnd = abs(length - groupLength)
                distToLowerEnd = abs(groupLength -
                                     (length - elementsCountAlong))
                if distToLowerEnd < distToUpperEnd:
                    elementsCount -= 1
                    elementsCountAlongGroups.append(elementsCount)
                    e -= 1
                    length -= elementAlongLength
                else:
                    elementsCountAlongGroups.append(elementsCount)
            elementsCount = 0

        majorRadiusElementList = sd2
        minorRadiusElementList = sd3

        # Create annotation groups along esophagus
        esophagusGroup = AnnotationGroup(region,
                                         get_esophagus_term("esophagus"))
        cervicalGroup = AnnotationGroup(
            region, get_esophagus_term("cervical part of esophagus"))
        thoracicGroup = AnnotationGroup(
            region, get_esophagus_term("thoracic part of esophagus"))
        abdominalGroup = AnnotationGroup(
            region, get_esophagus_term("abdominal part of esophagus"))

        annotationGroupAlong = [[esophagusGroup, cervicalGroup],
                                [esophagusGroup, thoracicGroup],
                                [esophagusGroup, abdominalGroup]]

        annotationGroupsAlong = []
        for i in range(len(elementsCountAlongGroups)):
            elementsCount = elementsCountAlongGroups[i]
            for n in range(elementsCount):
                annotationGroupsAlong.append(annotationGroupAlong[i])

        annotationGroupsAround = []
        for i in range(elementsCountAround):
            annotationGroupsAround.append([])

        # Groups through wall
        longitudinalMuscleGroup = AnnotationGroup(
            region,
            get_esophagus_term("esophagus smooth muscle longitudinal layer"))
        circularMuscleGroup = AnnotationGroup(
            region,
            get_esophagus_term("esophagus smooth muscle circular layer"))
        submucosaGroup = AnnotationGroup(
            region, get_esophagus_term("submucosa of esophagus"))
        mucosaGroup = AnnotationGroup(region,
                                      get_esophagus_term("esophagus mucosa"))

        if elementsCountThroughWall == 1:
            relativeThicknessList = [1.0]
            annotationGroupsThroughWall = [[]]
        else:
            relativeThicknessList = [
                mucosaRelThickness, submucosaRelThickness,
                circularRelThickness, longitudinalRelThickness
            ]
            annotationGroupsThroughWall = [[mucosaGroup], [submucosaGroup],
                                           [circularMuscleGroup],
                                           [longitudinalMuscleGroup]]

        xToSample = []
        d1ToSample = []
        for n2 in range(elementsCountAlong + 1):
            # Create inner points
            cx = [0.0, 0.0, elementAlongLength * n2]
            axis1 = [vector.magnitude(majorRadiusElementList[n2]), 0.0, 0.0]
            axis2 = [0.0, vector.magnitude(minorRadiusElementList[n2]), 0.0]
            xInner, d1Inner = geometry.createEllipsePoints(cx,
                                                           2 * math.pi,
                                                           axis1,
                                                           axis2,
                                                           elementsCountAround,
                                                           startRadians=0.0)
            xToSample += xInner
            d1ToSample += d1Inner

        d2ToSample = [[0.0, 0.0, elementAlongLength]
                      ] * (elementsCountAround * (elementsCountAlong + 1))

        # Sample along length
        xInnerRaw = []
        d2InnerRaw = []
        xToWarp = []
        d1ToWarp = []
        d2ToWarp = []
        flatWidthList = []
        xiList = []

        for n1 in range(elementsCountAround):
            xForSamplingAlong = []
            d2ForSamplingAlong = []
            for n2 in range(elementsCountAlong + 1):
                idx = n2 * elementsCountAround + n1
                xForSamplingAlong.append(xToSample[idx])
                d2ForSamplingAlong.append(d2ToSample[idx])
            xSampled, d2Sampled = interp.sampleCubicHermiteCurves(
                xForSamplingAlong,
                d2ForSamplingAlong,
                elementsCountAlong,
                arcLengthDerivatives=True)[0:2]
            xInnerRaw.append(xSampled)
            d2InnerRaw.append(d2Sampled)

        # Re-arrange sample order & calculate dx_ds1 and dx_ds3 from dx_ds2
        for n2 in range(elementsCountAlong + 1):
            xAround = []
            d2Around = []

            for n1 in range(elementsCountAround):
                x = xInnerRaw[n1][n2]
                d2 = d2InnerRaw[n1][n2]
                xAround.append(x)
                d2Around.append(d2)

            d1Around = []
            for n1 in range(elementsCountAround):
                v1 = xAround[n1]
                v2 = xAround[(n1 + 1) % elementsCountAround]
                d1 = d2 = [v2[c] - v1[c] for c in range(3)]
                arcLengthAround = interp.computeCubicHermiteArcLength(
                    v1, d1, v2, d2, True)
                dx_ds1 = [c * arcLengthAround for c in vector.normalise(d1)]
                d1Around.append(dx_ds1)
            d1Smoothed = interp.smoothCubicHermiteDerivativesLoop(
                xAround, d1Around)

            xToWarp += xAround
            d1ToWarp += d1Smoothed
            d2ToWarp += d2Around

            # Flat width and xi
            flatWidth = 0.0
            xiFace = []
            for n1 in range(elementsCountAround):
                v1 = xAround[n1]
                d1 = d1Smoothed[n1]
                v2 = xAround[(n1 + 1) % elementsCountAround]
                d2 = d1Smoothed[(n1 + 1) % elementsCountAround]
                flatWidth += interp.getCubicHermiteArcLength(v1, d1, v2, d2)
            flatWidthList.append(flatWidth)

            for n1 in range(elementsCountAround + 1):
                xi = 1.0 / elementsCountAround * n1
                xiFace.append(xi)
            xiList.append(xiFace)

        # Project reference point for warping onto central path
        sxRefList, sd1RefList, sd2ProjectedListRef, zRefList = \
            tubemesh.getPlaneProjectionOnCentralPath(xToWarp, elementsCountAround, elementsCountAlong,
                                                     centralPathLength, sx, sd1, sd2, sd12)

        # Warp points
        segmentAxis = [0.0, 0.0, 1.0]
        closedProximalEnd = False

        innerRadiusAlong = []
        for n2 in range(elementsCountAlong + 1):
            firstNodeAlong = xToWarp[n2 * elementsCountAround]
            midptSegmentAxis = [0.0, 0.0, elementAlongLength * n2]
            radius = vector.magnitude(firstNodeAlong[c] - midptSegmentAxis[c]
                                      for c in range(3))
            innerRadiusAlong.append(radius)

        xWarpedList, d1WarpedList, d2WarpedList, d3WarpedUnitList = \
            tubemesh.warpSegmentPoints(xToWarp, d1ToWarp, d2ToWarp, segmentAxis, sxRefList, sd1RefList,
                                       sd2ProjectedListRef, elementsCountAround, elementsCountAlong,
                                       zRefList, innerRadiusAlong, closedProximalEnd)

        # Create coordinates and derivatives
        transitElementList = [0] * elementsCountAround
        xList, d1List, d2List, d3List, curvatureList = \
            tubemesh.getCoordinatesFromInner(xWarpedList, d1WarpedList, d2WarpedList, d3WarpedUnitList,
                                             [wallThickness]*(elementsCountAlong+1), relativeThicknessList,
                                             elementsCountAround, elementsCountAlong, elementsCountThroughWall,
                                             transitElementList)

        # Create flat coordinates
        xFlat, d1Flat, d2Flat = tubemesh.createFlatCoordinates(
            xiList, flatWidthList, length, wallThickness,
            relativeThicknessList, elementsCountAround, elementsCountAlong,
            elementsCountThroughWall, transitElementList)

        # Create nodes and elements
        xOrgan = []
        d1Organ = []
        d2Organ = []
        nodeIdentifier, elementIdentifier, annotationGroups = \
            tubemesh.createNodesAndElements(region, xList, d1List, d2List, d3List, xFlat, d1Flat, d2Flat,
                                            xOrgan, d1Organ, d2Organ, None, elementsCountAround, elementsCountAlong,
                                            elementsCountThroughWall, annotationGroupsAround, annotationGroupsAlong,
                                            annotationGroupsThroughWall, firstNodeIdentifier, firstElementIdentifier,
                                            useCubicHermiteThroughWall, useCrossDerivatives, closedProximalEnd)

        # annotation fiducial points
        fm = region.getFieldmodule()
        fm.beginChange()
        mesh = fm.findMeshByDimension(3)
        cache = fm.createFieldcache()

        markerGroup = findOrCreateFieldGroup(fm, "marker")
        markerName = findOrCreateFieldStoredString(fm, name="marker_name")
        markerLocation = findOrCreateFieldStoredMeshLocation(
            fm, mesh, name="marker_location")

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

        markerNames = [
            "proximodorsal midpoint on serosa of upper esophageal sphincter",
            "proximoventral midpoint on serosa of upper esophageal sphincter",
            "distal point of lower esophageal sphincter serosa on the greater curvature of stomach",
            "distal point of lower esophageal sphincter serosa on the lesser curvature of stomach"
        ]

        totalElements = elementIdentifier
        radPerElementAround = math.pi * 2.0 / elementsCountAround
        elementAroundHalfPi = int(0.25 * elementsCountAround)
        xi1HalfPi = (math.pi * 0.5 - radPerElementAround *
                     elementAroundHalfPi) / radPerElementAround
        elementAroundPi = int(0.5 * elementsCountAround)
        xi1Pi = (math.pi -
                 radPerElementAround * elementAroundPi) / radPerElementAround

        markerElementIdentifiers = [
            elementsCountAround * elementsCountThroughWall -
            elementAroundHalfPi, elementAroundHalfPi + 1 +
            elementsCountAround * (elementsCountThroughWall - 1),
            totalElements - elementsCountAround,
            totalElements - elementsCountAround + elementAroundPi
        ]

        markerXis = [[1.0 - xi1HalfPi, 0.0, 1.0], [xi1HalfPi, 0.0, 1.0],
                     [0.0, 1.0, 1.0], [xi1Pi, 1.0, 1.0]]

        for n in range(len(markerNames)):
            markerGroup = findOrCreateAnnotationGroupForTerm(
                annotationGroups, region, get_esophagus_term(markerNames[n]))
            markerElement = mesh.findElementByIdentifier(
                markerElementIdentifiers[n])
            markerXi = markerXis[n]
            cache.setMeshLocation(markerElement, markerXi)
            markerPoint = markerPoints.createNode(nodeIdentifier,
                                                  markerTemplateInternal)
            nodeIdentifier += 1
            cache.setNode(markerPoint)
            markerName.assignString(cache, markerGroup.getName())
            markerLocation.assignMeshLocation(cache, markerElement, markerXi)
            for group in [esophagusGroup, markerGroup]:
                group.getNodesetGroup(nodes).addNode(markerPoint)

        fm.endChange()

        return annotationGroups
Exemplo n.º 8
0
    def generateBaseMesh(cls, region, options):
        """
        Generate the base tricubic Hermite mesh.
        :param region: Zinc region to define model in. Must be empty.
        :param options: Dict containing options. See getDefaultOptions().
        :return: list of AnnotationGroup
        """
        # set dependent outer diameter used in atria2
        options['Aorta outer plus diameter'] = options[
            'LV outlet inner diameter'] + 2.0 * options[
                'LV outlet wall thickness']
        elementsCountAroundAtrialSeptum = options[
            'Number of elements around atrial septum']
        elementsCountAroundLeftAtriumFreeWall = options[
            'Number of elements around left atrium free wall']
        elementsCountAroundLeftAtrium = elementsCountAroundLeftAtriumFreeWall + elementsCountAroundAtrialSeptum
        elementsCountAroundRightAtriumFreeWall = options[
            'Number of elements around right atrium free wall']
        elementsCountAroundRightAtrium = elementsCountAroundRightAtriumFreeWall + elementsCountAroundAtrialSeptum
        useCrossDerivatives = False

        fm = region.getFieldmodule()
        coordinates = findOrCreateFieldCoordinates(fm)
        cache = fm.createFieldcache()

        mesh = fm.findMeshByDimension(3)

        # generate heartventriclesbase1 model and put atria1 on it
        ventriclesAnnotationGroups = MeshType_3d_heartventriclesbase1.generateBaseMesh(
            region, options)
        atriaAnnotationGroups = MeshType_3d_heartatria1.generateBaseMesh(
            region, options)
        annotationGroups = mergeAnnotationGroups(ventriclesAnnotationGroups,
                                                 atriaAnnotationGroups)
        lFibrousRingGroup = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region, get_heart_term("left fibrous ring"))
        rFibrousRingGroup = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region, get_heart_term("right fibrous ring"))

        # annotation fiducial points
        markerGroup = findOrCreateFieldGroup(fm, "marker")
        markerName = findOrCreateFieldStoredString(fm, name="marker_name")
        markerLocation = findOrCreateFieldStoredMeshLocation(
            fm, mesh, name="marker_location")

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

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

        nodeIdentifier = max(1, getMaximumNodeIdentifier(nodes) + 1)

        # discover left and right fibrous ring nodes from ventricles and atria
        # because nodes are iterated in identifier order, the lowest and first are on the lv outlet cfb, right and left on lower outer layers
        # left fibrous ring
        lavNodeId = [[[], []], [[], []]]  # [n3][n2][n1]
        iter = lFibrousRingGroup.getNodesetGroup(nodes).createNodeiterator()
        # left fibrous ring, bottom row
        cfbNodeId = iter.next().getIdentifier()
        cfbLeftNodeId = iter.next().getIdentifier()
        for n1 in range(elementsCountAroundLeftAtrium):
            lavNodeId[0][0].append(iter.next().getIdentifier())
        lavNodeId[1][0].append(cfbNodeId)
        lavNodeId[1][0].append(cfbLeftNodeId)
        for n1 in range(elementsCountAroundLeftAtriumFreeWall - 1):
            lavNodeId[1][0].append(iter.next().getIdentifier())
        for n1 in range(elementsCountAroundAtrialSeptum - 1):
            lavNodeId[1][0].append(None)  # no outer node on interatrial septum
        # left fibrous ring, top row
        for n1 in range(elementsCountAroundLeftAtrium):
            lavNodeId[0][1].append(iter.next().getIdentifier())
        for n1 in range(elementsCountAroundLeftAtriumFreeWall + 1):
            lavNodeId[1][1].append(iter.next().getIdentifier())
        for n1 in range(elementsCountAroundAtrialSeptum - 1):
            lavNodeId[1][1].append(None)  # no outer node on interatrial septum
        # right fibrous ring
        ravNodeId = [[[], []], [[], []]]  # [n3][n2][n1]
        iter = rFibrousRingGroup.getNodesetGroup(nodes).createNodeiterator()
        cfbNodeId = iter.next().getIdentifier()
        cfbRightNodeId = iter.next().getIdentifier()
        # right fibrous ring, bottom row
        for n1 in range(elementsCountAroundRightAtrium):
            ravNodeId[0][0].append(iter.next().getIdentifier())
        for n1 in range(elementsCountAroundRightAtriumFreeWall - 1):
            ravNodeId[1][0].append(iter.next().getIdentifier())
        ravNodeId[1][0].append(cfbRightNodeId)
        ravNodeId[1][0].append(cfbNodeId)
        for n1 in range(elementsCountAroundAtrialSeptum - 1):
            ravNodeId[1][0].append(None)  # no outer node on interatrial septum
        # right fibrous ring, top row
        for n1 in range(elementsCountAroundRightAtrium):
            ravNodeId[0][1].append(iter.next().getIdentifier())
        cfbUpperNodeId = iter.next().getIdentifier(
        )  # cfb from left will be first
        for n1 in range(elementsCountAroundRightAtriumFreeWall):
            ravNodeId[1][1].append(iter.next().getIdentifier())
        ravNodeId[1][1].append(cfbUpperNodeId)
        for n1 in range(elementsCountAroundAtrialSeptum - 1):
            ravNodeId[1][1].append(None)  # no outer node on interatrial septum

        #for n2 in range(2):
        #    print('n2', n2)
        #    print('lavNodeId[0]', lavNodeId[0][n2])
        #    print('lavNodeId[1]', lavNodeId[1][n2])
        #    print('ravNodeId[0]', ravNodeId[0][n2])
        #    print('ravNodeId[1]', ravNodeId[1][n2])

        #################
        # Create elements
        #################

        lFibrousRingMeshGroup = lFibrousRingGroup.getMeshGroup(mesh)
        rFibrousRingMeshGroup = rFibrousRingGroup.getMeshGroup(mesh)

        elementIdentifier = getMaximumElementIdentifier(mesh) + 1

        elementtemplate1 = mesh.createElementtemplate()
        elementtemplate1.setElementShapeType(Element.SHAPE_TYPE_CUBE)

        # create fibrous ring elements

        bicubichermitelinear = eftfactory_bicubichermitelinear(
            mesh,
            useCrossDerivatives,
            linearAxis=2,
            d_ds1=Node.VALUE_LABEL_D_DS1,
            d_ds2=Node.VALUE_LABEL_D_DS3)
        eftFibrousRing = bicubichermitelinear.createEftBasic()

        # left fibrous ring, starting at crux / collapsed posterior interatrial sulcus
        cruxElementId = None
        for e in range(-1, elementsCountAroundLeftAtriumFreeWall):
            eft1 = eftFibrousRing
            n1 = e
            nids = [
                lavNodeId[0][0][n1], lavNodeId[0][0][n1 + 1],
                lavNodeId[0][1][n1], lavNodeId[0][1][n1 + 1],
                lavNodeId[1][0][n1], lavNodeId[1][0][n1 + 1],
                lavNodeId[1][1][n1], lavNodeId[1][1][n1 + 1]
            ]
            scalefactors = None
            meshGroups = [lFibrousRingMeshGroup]

            if e == -1:
                # interatrial groove straddles left and right atria, collapsed to 6 node wedge
                nids[0] = ravNodeId[0][0][
                    elementsCountAroundRightAtriumFreeWall]
                nids[2] = ravNodeId[0][1][
                    elementsCountAroundRightAtriumFreeWall]
                nids.pop(6)
                nids.pop(4)
                eft1 = bicubichermitelinear.createEftNoCrossDerivatives()
                setEftScaleFactorIds(eft1, [1], [])
                scalefactors = [-1.0]
                remapEftNodeValueLabel(eft1, [1, 3], Node.VALUE_LABEL_D_DS1,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [])])
                remapEftNodeValueLabel(eft1, [2, 4], Node.VALUE_LABEL_D_DS1,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [1])])
                remapEftNodeValueLabel(eft1, [5, 6, 7, 8],
                                       Node.VALUE_LABEL_D_DS1, [])
                # reverse d3 on cfb:
                remapEftNodeValueLabel(eft1, [5], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [1])])
                remapEftNodeValueLabel(eft1, [6], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, [0]),
                                        (Node.VALUE_LABEL_D_DS3, [1])])
                remapEftNodeValueLabel(eft1, [7], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [])])
                remapEftNodeValueLabel(eft1, [8], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [])])
                ln_map = [1, 2, 3, 4, 5, 5, 6, 6]
                remapEftLocalNodes(eft1, 6, ln_map)
                meshGroups += [rFibrousRingMeshGroup]
            elif e == 0:
                # general linear map d3 adjacent to collapsed sulcus
                eft1 = bicubichermitelinear.createEftNoCrossDerivatives()
                setEftScaleFactorIds(eft1, [1], [])
                scalefactors = [-1.0]
                # reverse d1, d3 on cfb, left cfb:
                scaleEftNodeValueLabels(
                    eft1, [6],
                    [Node.VALUE_LABEL_D_DS1, Node.VALUE_LABEL_D_DS3], [1])
                remapEftNodeValueLabel(eft1, [5], Node.VALUE_LABEL_D_DS1,
                                       [(Node.VALUE_LABEL_D_DS1, [1])])
                remapEftNodeValueLabel(eft1, [5], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [1])])
                remapEftNodeValueLabel(eft1, [7], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [])])
            elif e == 1:
                # reverse d1, d3 on left cfb:
                eft1 = bicubichermitelinear.createEftNoCrossDerivatives()
                setEftScaleFactorIds(eft1, [1], [])
                scalefactors = [-1.0]
                remapEftNodeValueLabel(eft1, [5], Node.VALUE_LABEL_D_DS1,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [])])
                remapEftNodeValueLabel(eft1, [5], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS3, [1])])
            elif e == (elementsCountAroundLeftAtriumFreeWall - 1):
                # general linear map d3 adjacent to collapsed sulcus
                eft1 = bicubichermitelinear.createEftNoCrossDerivatives()
                setEftScaleFactorIds(eft1, [1], [])
                scalefactors = [-1.0]
                remapEftNodeValueLabel(eft1, [6, 8], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [])])

            result = elementtemplate1.defineField(coordinates, -1, eft1)
            element = mesh.createElement(elementIdentifier, elementtemplate1)
            result2 = element.setNodesByIdentifier(eft1, nids)
            result3 = element.setScaleFactors(
                eft1, scalefactors) if scalefactors else None
            #print('create element fibrous ring left', elementIdentifier, result, result2, result3, nids)
            elementIdentifier += 1

            for meshGroup in meshGroups:
                meshGroup.addElement(element)

        # right fibrous ring, starting at crux / collapsed posterior interatrial sulcus
        for e in range(-1, elementsCountAroundRightAtriumFreeWall):
            eft1 = eftFibrousRing
            n1 = e
            nids = [
                ravNodeId[0][0][n1], ravNodeId[0][0][n1 + 1],
                ravNodeId[0][1][n1], ravNodeId[0][1][n1 + 1],
                ravNodeId[1][0][n1], ravNodeId[1][0][n1 + 1],
                ravNodeId[1][1][n1], ravNodeId[1][1][n1 + 1]
            ]
            scalefactors = None
            meshGroups = [rFibrousRingMeshGroup]

            if e == -1:
                # interatrial groove straddles left and right atria, collapsed to 6 node wedge
                nids[0] = lavNodeId[0][0][
                    elementsCountAroundLeftAtriumFreeWall]
                nids[2] = lavNodeId[0][1][
                    elementsCountAroundLeftAtriumFreeWall]
                nids.pop(6)
                nids.pop(4)
                eft1 = bicubichermitelinear.createEftNoCrossDerivatives()
                setEftScaleFactorIds(eft1, [1], [])
                scalefactors = [-1.0]
                remapEftNodeValueLabel(eft1, [1, 3], Node.VALUE_LABEL_D_DS1,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [])])
                remapEftNodeValueLabel(eft1, [2, 4], Node.VALUE_LABEL_D_DS1,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [1])])
                remapEftNodeValueLabel(eft1, [5, 6, 7, 8],
                                       Node.VALUE_LABEL_D_DS1, [])
                remapEftNodeValueLabel(eft1, [5, 7], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [])])
                remapEftNodeValueLabel(eft1, [6, 8], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [])])
                ln_map = [1, 2, 3, 4, 5, 5, 6, 6]
                remapEftLocalNodes(eft1, 6, ln_map)
                meshGroups += [lFibrousRingMeshGroup]
                cruxElementId = elementIdentifier
            elif e == 0:
                # general linear map d3 adjacent to collapsed crux/posterior sulcus
                eft1 = bicubichermitelinear.createEftNoCrossDerivatives()
                setEftScaleFactorIds(eft1, [1], [])
                scalefactors = [-1.0]
                remapEftNodeValueLabel(eft1, [5, 7], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [])])
            elif e == (elementsCountAroundRightAtriumFreeWall - 2):
                # reverse d1, d3 on right cfb:
                eft1 = bicubichermitelinear.createEftNoCrossDerivatives()
                setEftScaleFactorIds(eft1, [1], [])
                scalefactors = [-1.0]
                remapEftNodeValueLabel(eft1, [6], Node.VALUE_LABEL_D_DS1,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [1])])
                remapEftNodeValueLabel(eft1, [6], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS3, [1])])
            elif e == (elementsCountAroundRightAtriumFreeWall - 1):
                # general linear map d3 adjacent to collapsed cfb/anterior sulcus
                eft1 = bicubichermitelinear.createEftNoCrossDerivatives()
                setEftScaleFactorIds(eft1, [1], [])
                scalefactors = [-1.0]
                # reverse d1, d3 on right cfb, cfb:
                scaleEftNodeValueLabels(
                    eft1, [5],
                    [Node.VALUE_LABEL_D_DS1, Node.VALUE_LABEL_D_DS3], [1])
                remapEftNodeValueLabel(eft1, [6], Node.VALUE_LABEL_D_DS1,
                                       [(Node.VALUE_LABEL_D_DS1, [1])])
                remapEftNodeValueLabel(eft1, [6], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [1])])
                remapEftNodeValueLabel(eft1, [8], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [])])

            result = elementtemplate1.defineField(coordinates, -1, eft1)
            element = mesh.createElement(elementIdentifier, elementtemplate1)
            result2 = element.setNodesByIdentifier(eft1, nids)
            result3 = element.setScaleFactors(
                eft1, scalefactors) if scalefactors else None
            #print('create element fibrous ring right', elementIdentifier, result, result2, result3, nids)
            elementIdentifier += 1

            for meshGroup in meshGroups:
                meshGroup.addElement(element)

        # fibrous ring septum:
        meshGroups = [lFibrousRingMeshGroup, rFibrousRingMeshGroup]
        for e in range(elementsCountAroundAtrialSeptum):
            eft1 = eftFibrousRing
            nlm = e - elementsCountAroundAtrialSeptum
            nlp = nlm + 1
            nrm = -e
            nrp = nrm - 1
            nids = [
                lavNodeId[0][0][nlm], lavNodeId[0][0][nlp],
                lavNodeId[0][1][nlm], lavNodeId[0][1][nlp],
                ravNodeId[0][0][nrm], ravNodeId[0][0][nrp],
                ravNodeId[0][1][nrm], ravNodeId[0][1][nrp]
            ]

            eft1 = bicubichermitelinear.createEftNoCrossDerivatives()
            setEftScaleFactorIds(eft1, [1], [])
            scalefactors = [-1.0]
            if e == 0:
                # general linear map d3 adjacent to collapsed posterior interventricular sulcus
                scaleEftNodeValueLabels(eft1, [5, 6, 7, 8],
                                        [Node.VALUE_LABEL_D_DS1], [1])
                scaleEftNodeValueLabels(eft1, [6, 8], [Node.VALUE_LABEL_D_DS3],
                                        [1])
                remapEftNodeValueLabel(eft1, [1, 3], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [])])
                remapEftNodeValueLabel(eft1, [5, 7], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, []),
                                        (Node.VALUE_LABEL_D_DS3, [1])])
            elif e == (elementsCountAroundAtrialSeptum - 1):
                # general linear map d3 adjacent to cfb
                scaleEftNodeValueLabels(eft1, [5, 6, 7, 8],
                                        [Node.VALUE_LABEL_D_DS1], [1])
                scaleEftNodeValueLabels(eft1, [5, 7], [Node.VALUE_LABEL_D_DS3],
                                        [1])
                remapEftNodeValueLabel(eft1, [2, 4], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [])])
                remapEftNodeValueLabel(eft1, [6, 8], Node.VALUE_LABEL_D_DS3,
                                       [(Node.VALUE_LABEL_D_DS1, [1]),
                                        (Node.VALUE_LABEL_D_DS3, [1])])
            else:
                scaleEftNodeValueLabels(
                    eft1, [5, 6, 7, 8],
                    [Node.VALUE_LABEL_D_DS1, Node.VALUE_LABEL_D_DS3], [1])

            result = elementtemplate1.defineField(coordinates, -1, eft1)
            element = mesh.createElement(elementIdentifier, elementtemplate1)
            result2 = element.setNodesByIdentifier(eft1, nids)
            result3 = element.setScaleFactors(
                eft1, scalefactors) if scalefactors else None
            #print('create element fibrous ring septum', elementIdentifier, result, result2, result3, nids)
            elementIdentifier += 1

            for meshGroup in meshGroups:
                meshGroup.addElement(element)

        # annotation fiducial points
        cruxElement = mesh.findElementByIdentifier(cruxElementId)
        cruxXi = [0.5, 0.5, 1.0]
        cache.setMeshLocation(cruxElement, cruxXi)
        result, cruxCoordinates = coordinates.evaluateReal(cache, 3)
        markerPoint = markerPoints.createNode(nodeIdentifier,
                                              markerTemplateInternal)
        nodeIdentifier += 1
        cache.setNode(markerPoint)
        markerName.assignString(cache, "crux of heart")
        markerLocation.assignMeshLocation(cache, cruxElement, cruxXi)

        return annotationGroups
Exemplo n.º 9
0
def main_writerotatefile(data_path):
    plot = False
    concave_hull = True if 'concave_hull' in data_path else False
    # fiducial points are in the new xml file with separate marker field
    fids_in_xml = False if concave_hull else True

    files = os.listdir(data_path)
    files = [f for f in files if f.endswith('.ex')]

    max_soma = 5
    all_nerves = [
        'Inferior cardiac nerve', 'Ventral ansa subclavia',
        'Dorsal ansa subclavia', 'Cervical spinal nerve 8',
        'Thoracic spinal nerve 1', 'Thoracic spinal nerve 2',
        'Thoracic spinal nerve 3', 'Thoracic sympathetic nerve trunk',
        'Thoracic ansa'
    ]
    bodyname = ['Cervicalganglion', 'stellate']

    fdict = {sample: {} for sample in files}

    write_this = False
    for sample in files:
        print(sample)
        lr_groups = True
        output_suffix = '_LR.exf'
        short_name = sample.split('_')[0] if not concave_hull else sample
        fmag = sample.split('_')[1].upper()
        full_body = True
        xyz_sm = []
        txt = []
        in_file = data_path + sample
        if not os.path.exists(data_path + 'exf_output\\'):
            os.mkdir(data_path + 'exf_output\\')
        mapclient_workflow_path = 'scaffoldfitter_output\\scaffoldfitter_geofit_folder\\exp_data\\'

        with open(in_file, 'r') as f_in:
            if '10x' not in sample.lower() and not concave_hull:
                full_body = False
            out_file = data_path + 'exf_output\\' + short_name + (
                '_fragment_%s' % (fmag) * (not full_body)) + output_suffix
            possibleGroups = [] if concave_hull else all_nerves + [
                'Soma %d' % (i) for i in range(1, 6)
            ] + ['T3 paravertebral ganglion', 'Cervicothoracic ganglion']
            all_node_num, xyz_all, _, xyzGroups, _, xyz_marker, marker_names, marker_nodenum, _ = zinc_read_exf_file(
                data_path + sample, 2, 0, 1, [], possibleGroups, 3)
            xyz_n = {m: xyz_marker[im] for im, m in enumerate(marker_names)}
            xyz_all_dict = {n: xyz_all[n - 1] for n in all_node_num}
            if not full_body:
                nervename = []
                for key in xyzGroups.keys():
                    if key in all_nerves:
                        nervename.append(key)

                for nn in nervename:
                    xyz_n_0 = xyzGroups[nn]
                    xyz_n[nn] = xyz_n_0
            try:
                xyz_st = xyzGroups['Cervicothoracic ganglion']
            except:
                xyz_st = [xyz_all_dict[key] for key in xyz_all_dict.keys()]
            xyz_t3 = []
            xyz_t3Rot = []
            try:
                xyz_t3 = xyzGroups['T3 paravertebral ganglion']
                print('T3 paravertebral ganglion present')
            except:
                pass
            # there may be more than one soma
            num_soma = 0
            if not concave_hull:
                for key in xyzGroups:
                    if 'soma' in key.lower():
                        num_soma += 1

            for i in range(num_soma):
                # print('soma '+str(i+1))
                crd = xyzGroups['Soma ' + str(i + 1)]
                xyz_sm.extend([[c[0], c[1], c[2], i + 1] for c in crd])

            if full_body:
                if not concave_hull:
                    x = [(ix[0]) for ix in xyz_st]
                    y = [(ix[1]) for ix in xyz_st]
                    z = [(ix[2]) for ix in xyz_st]
                    centroid = [np.mean(x), np.mean(y), np.mean(z)]
                    xsm = [[]] * num_soma
                    ysm = [[]] * num_soma
                    zsm = [[]] * num_soma
                    isoma = [[]] * num_soma
                    for i in range(num_soma):
                        xsm[i] = [(ix[0]) for ix in xyz_sm if ix[3] == i + 1]
                        ysm[i] = [(ix[1]) for ix in xyz_sm if ix[3] == i + 1]
                        zsm[i] = [(ix[2]) for ix in xyz_sm if ix[3] == i + 1]
                        isoma[i] = i + 1
                    try:
                        xy_ICN = xyz_n['Inferior cardiac nerve']
                    except:
                        # print('no iCN. using Ventral ansa for system rotation')
                        xy_ICN = xyz_n['Ventral ansa subclavia']
                    xy_nerve_fids = [
                        xyz_n['Dorsal ansa subclavia'], xy_ICN,
                        xyz_n['Thoracic sympathetic nerve trunk']
                    ]

                    [
                        x, y, z, xsm, ysm, zsm, xyz_st, xyz_sm, xyz_t3, fdict,
                        xyz_n, xy_nerve_end, _
                    ] = flip_system(x, y, z, xsm, ysm, zsm, xy_nerve_fids,
                                    xyz_t3, centroid, num_soma, fdict, xyz_n,
                                    sample, 0)
                    centroid = [np.mean(x), np.mean(y), np.mean(z)]

                [xyz_stRot, theta] = rotate_points(xyz_st, [], [])
                [xyz_smRot, theta] = rotate_points(xyz_sm, theta, [])
                if xyz_t3:
                    [xyz_t3Rot, theta] = rotate_points(xyz_t3, theta, [])
                xyz_nRot = xyz_n.copy()
                for key in xyz_n:
                    if xyz_n[key]:
                        [nrot, theta] = rotate_points([xyz_n[key]], theta, [])
                        xyz_nRot[key] = nrot[0]
                        try:
                            [newcoord,
                             theta] = rotate_points([fdict[sample][key]],
                                                    theta, [])
                            fdict[sample][key] = newcoord[0]
                            for i in range(num_soma):
                                [sout, theta] = rotate_points(
                                    [fdict[sample]['Soma%s' % (str(i + 1))]],
                                    theta, [])
                                fdict[sample]['Soma%s' %
                                              (str(i + 1))] = sout[0]
                        except:
                            pass

                x = [(ix[0]) for ix in xyz_stRot]
                y = [(ix[1]) for ix in xyz_stRot]
                z = [(ix[2]) for ix in xyz_stRot]
                centroid = [np.mean(x), np.mean(y), np.mean(z)]
                xsm = [[]] * num_soma
                ysm = [[]] * num_soma
                zsm = [[]] * num_soma
                isoma = [[]] * num_soma
                for i in range(num_soma):
                    xsm[i] = [(ix[0]) for ix in xyz_smRot if ix[3] == i + 1]
                    ysm[i] = [(ix[1]) for ix in xyz_smRot if ix[3] == i + 1]
                    zsm[i] = [(ix[2]) for ix in xyz_smRot if ix[3] == i + 1]
                    isoma[i] = i + 1

            else:
                xyz_smRot_2D = xyz_sm  # [[xsm[i], ysm[i], zsm[i]] for i in range(len(xsm))]
                xyz_stRot = xyz_st.copy()
                xyz_nRot = xyz_n.copy()
                x = [(ix[0]) for ix in xyz_stRot]
                y = [(ix[1]) for ix in xyz_stRot]
                z = [(ix[2]) for ix in xyz_stRot]
                xsm = [[]] * num_soma
                ysm = [[]] * num_soma
                zsm = [[]] * num_soma
                isoma = [[]] * num_soma
                for i in range(num_soma):
                    xsm[i] = [(ix[0]) for ix in xyz_smRot_2D if ix[3] == i + 1]
                    ysm[i] = [(ix[1]) for ix in xyz_smRot_2D if ix[3] == i + 1]
                    zsm[i] = [(ix[2]) for ix in xyz_smRot_2D if ix[3] == i + 1]
                    isoma[i] = i + 1
                lr_groups = False

        # soma cx to nerves - INNERVATIONS
        cx_soma = {}
        if not concave_hull:
            xname = sample.split('.ex')[0]
            xml_path = data_path + 'xml\\'
            cx_soma = parse_xml_find_soma_ID(xml_path + xname)

        if lr_groups:
            cx = centroid[0]
            cy = centroid[1]

            if full_body:
                # parse through all stellate nodes between selected fiducials of every contour layer
                # LEFT: Dorsal ansa / C8 to Ventral ansa / inferior cardiac nerve
                # TOP: iCN/VA to trunk (or rightmost top nodes of rotated stellate)
                # BOTTOM: C8/DA to trunk or rightmost bottom nodes
                [nleft, ntop,
                 nbottom] = lefttopbottom_by_fiducials(x, y, z, xyz_nRot,
                                                       'by_order', sample,
                                                       plot)

        if lr_groups or not full_body:
            # write with zinc
            context = Context('Example')
            region = context.getDefaultRegion()
            fm = region.getFieldmodule()
            fm.beginChange()
            nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
            coordinates = findOrCreateFieldCoordinates(fm, 'data_coordinates')
            nodetemplate = nodes.createNodetemplate()
            nodetemplate.defineField(coordinates)
            nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                                  Node.VALUE_LABEL_VALUE, 1)
            # stellate face groups
            armGroup12 = findOrCreateFieldGroup(fm, 'stellate face 1-2')
            armGroup23 = findOrCreateFieldGroup(fm, 'stellate face 2-3')
            armGroup31 = findOrCreateFieldGroup(fm, 'stellate face 3-1')
            armGroup12Name = findOrCreateFieldStoredString(
                fm, name='stellate face 1-2')
            armGroup23Name = findOrCreateFieldStoredString(
                fm, name='stellate face 2-3')
            armGroup31Name = findOrCreateFieldStoredString(
                fm, name='stellate face 3-1')
            armGroup12Nodes = findOrCreateFieldNodeGroup(
                armGroup12, nodes).getNodesetGroup()
            armGroup23Nodes = findOrCreateFieldNodeGroup(
                armGroup23, nodes).getNodesetGroup()
            armGroup31Nodes = findOrCreateFieldNodeGroup(
                armGroup31, nodes).getNodesetGroup()

            markerNodes = fm.findNodesetByFieldDomainType(
                Field.DOMAIN_TYPE_DATAPOINTS)
            markerGroup = findOrCreateFieldGroup(fm, 'marker')
            markerName = findOrCreateFieldStoredString(fm,
                                                       name='marker_data_name')
            markerPoints = findOrCreateFieldNodeGroup(
                markerGroup, markerNodes).getNodesetGroup()
            marker_coordinates = findOrCreateFieldCoordinates(
                fm, 'marker_data_coordinates')
            markerTemplate = markerPoints.createNodetemplate()
            markerTemplate.defineField(marker_coordinates)
            markerTemplate.setValueNumberOfVersions(marker_coordinates, -1,
                                                    Node.VALUE_LABEL_VALUE, 1)
            markerTemplate.defineField(markerName)

            cache = fm.createFieldcache()

            for nID0, xyz in enumerate(xyz_stRot):
                nID = nID0 + 1
                if nID in nleft:
                    node = armGroup23Nodes.createNode(nID, nodetemplate)
                    cache.setNode(node)
                    coordinates.setNodeParameters(cache, -1,
                                                  Node.VALUE_LABEL_VALUE, 1,
                                                  xyz)
                elif nID in ntop:
                    node = armGroup12Nodes.createNode(nID, nodetemplate)
                    cache.setNode(node)
                    coordinates.setNodeParameters(cache, -1,
                                                  Node.VALUE_LABEL_VALUE, 1,
                                                  xyz)
                elif nID in nbottom:
                    node = armGroup31Nodes.createNode(nID, nodetemplate)
                    cache.setNode(node)
                    coordinates.setNodeParameters(cache, -1,
                                                  Node.VALUE_LABEL_VALUE, 1,
                                                  xyz)
                else:  # nothing
                    node = nodes.createNode(nID, nodetemplate)
                    cache.setNode(node)
                    coordinates.setNodeParameters(cache, -1,
                                                  Node.VALUE_LABEL_VALUE, 1,
                                                  xyz)

            nID = 1000001
            for i, key in enumerate(xyz_n):
                if xyz_n[key] and 'junction' not in key.lower():
                    if full_body:
                        xyz = find_closest_end(x, y, z, xyz_nRot[key])
                    else:  # use junction point
                        for nkey in xyz_nRot:
                            if 'junction' in nkey.lower() and key.lower(
                            ) in nkey.lower():
                                xyz = xyz_nRot[nkey]
                    node = markerPoints.createNode(nID, markerTemplate)
                    cache.setNode(node)
                    marker_coordinates.setNodeParameters(
                        cache, -1, Node.VALUE_LABEL_VALUE, 1, xyz)
                    markerName.assignString(cache, key)
                    nID += 1
            written_soma_connections = []
            for j in range(num_soma):
                soma_id = 'Soma ' + str(j + 1)
                for key in cx_soma[soma_id]:
                    possible_nerve = cx_soma[soma_id][key]
                    if possible_nerve:
                        soma_nerve = possible_nerve[0]
                        if (soma_nerve not in written_soma_connections):
                            soma_inn_name = 'Soma_' + soma_nerve
                            xys = [
                                np.mean(xsm[j]),
                                np.mean(ysm[j]),
                                np.mean(zsm[j])
                            ]
                            node = markerPoints.createNode(nID, markerTemplate)
                            cache.setNode(node)
                            marker_coordinates.setNodeParameters(
                                cache, -1, Node.VALUE_LABEL_VALUE, 1, xys)
                            markerName.assignString(cache, soma_inn_name)
                            written_soma_connections.append(soma_nerve)
                            nID += 1

            fm.endChange()
            region.writeFile(out_file)

            # write to mapclient workflow
            m_out = mapclient_workflow_path + short_name + output_suffix
            shutil.copyfile(out_file, m_out)

        else:  # do not write anything for files without LR groups
            pass

    return
Exemplo n.º 10
0
    def __init__(self, sourceRegion, targetRegion, sourceAnnotationGroups=[]):
        '''
        Assumes targetRegion is empty.
        :param sourceAnnotationGroups: List of AnnotationGroup for source mesh in sourceRegion.
        A copy containing the refined elements is created by the MeshRefinement.
        '''
        self._sourceRegion = sourceRegion
        self._sourceFm = sourceRegion.getFieldmodule()
        self._sourceCache = self._sourceFm.createFieldcache()
        self._sourceCoordinates = findOrCreateFieldCoordinates(self._sourceFm)
        # get range of source coordinates for octree range
        self._sourceFm.beginChange()
        sourceNodes = self._sourceFm.findNodesetByFieldDomainType(
            Field.DOMAIN_TYPE_NODES)
        minimumsField = self._sourceFm.createFieldNodesetMinimum(
            self._sourceCoordinates, sourceNodes)
        result, minimums = minimumsField.evaluateReal(self._sourceCache, 3)
        assert result == ZINC_OK, 'MeshRefinement failed to get minimum coordinates'
        maximumsField = self._sourceFm.createFieldNodesetMaximum(
            self._sourceCoordinates, sourceNodes)
        result, maximums = maximumsField.evaluateReal(self._sourceCache, 3)
        assert result == ZINC_OK, 'MeshRefinement failed to get maximum coordinates'
        xrange = [(maximums[i] - minimums[i]) for i in range(3)]
        edgeTolerance = 0.5 * (max(xrange))
        if edgeTolerance == 0.0:
            edgeTolerance = 1.0
        minimums = [(minimums[i] - edgeTolerance) for i in range(3)]
        maximums = [(maximums[i] + edgeTolerance) for i in range(3)]
        minimumsField = None
        maximumsField = None
        self._sourceMesh = self._sourceFm.findMeshByDimension(3)
        self._sourceNodes = self._sourceFm.findNodesetByFieldDomainType(
            Field.DOMAIN_TYPE_NODES)
        self._sourceElementiterator = self._sourceMesh.createElementiterator()
        self._octree = Octree(minimums, maximums)

        self._targetRegion = targetRegion
        self._targetFm = targetRegion.getFieldmodule()
        self._targetFm.beginChange()
        self._targetCache = self._targetFm.createFieldcache()
        self._targetCoordinates = findOrCreateFieldCoordinates(self._targetFm)

        self._targetNodes = self._targetFm.findNodesetByFieldDomainType(
            Field.DOMAIN_TYPE_NODES)
        self._nodetemplate = self._targetNodes.createNodetemplate()
        self._nodetemplate.defineField(self._targetCoordinates)

        self._targetMesh = self._targetFm.findMeshByDimension(3)
        self._targetBasis = self._targetFm.createElementbasis(
            3, Elementbasis.FUNCTION_TYPE_LINEAR_LAGRANGE)
        self._targetEft = self._targetMesh.createElementfieldtemplate(
            self._targetBasis)
        self._targetElementtemplate = self._targetMesh.createElementtemplate()
        self._targetElementtemplate.setElementShapeType(
            Element.SHAPE_TYPE_CUBE)
        result = self._targetElementtemplate.defineField(
            self._targetCoordinates, -1, self._targetEft)

        self._nodeIdentifier = 1
        self._elementIdentifier = 1
        # prepare annotation group map
        self._sourceAnnotationGroups = sourceAnnotationGroups
        self._annotationGroups = []
        self._sourceAndTargetMeshGroups = []
        self._sourceAndTargetNodesetGroups = []
        for sourceAnnotationGroup in sourceAnnotationGroups:
            targetAnnotationGroup = AnnotationGroup(
                self._targetRegion, sourceAnnotationGroup.getTerm())
            self._annotationGroups.append(targetAnnotationGroup)
            # assume have only highest dimension element or node/point annotation groups:
            if sourceAnnotationGroup.hasMeshGroup(self._sourceMesh):
                self._sourceAndTargetMeshGroups.append(
                    (sourceAnnotationGroup.getMeshGroup(self._sourceMesh),
                     targetAnnotationGroup.getMeshGroup(self._targetMesh)))
            else:
                self._sourceAndTargetNodesetGroups.append(
                    (sourceAnnotationGroup.getNodesetGroup(self._sourceNodes),
                     targetAnnotationGroup.getNodesetGroup(self._targetNodes)))

        # prepare element -> marker point list map
        self.elementMarkerMap = {}
        sourceMarkerGroup = findOrCreateFieldGroup(self._sourceFm, "marker")
        sourceMarkerName = findOrCreateFieldStoredString(self._sourceFm,
                                                         name="marker_name")
        sourceMarkerLocation = findOrCreateFieldStoredMeshLocation(
            self._sourceFm, self._sourceMesh, name="marker_location")
        sourceMarkerNodes = findOrCreateFieldNodeGroup(
            sourceMarkerGroup, sourceNodes).getNodesetGroup()
        nodeIter = sourceMarkerNodes.createNodeiterator()
        node = nodeIter.next()
        while node.isValid():
            self._sourceCache.setNode(node)
            element, xi = sourceMarkerLocation.evaluateMeshLocation(
                self._sourceCache, self._sourceMesh.getDimension())
            if element.isValid():
                elementIdentifier = element.getIdentifier()
                markerName = sourceMarkerName.evaluateString(self._sourceCache)
                markerList = self.elementMarkerMap.get(elementIdentifier)
                if not markerList:
                    markerList = []
                    self.elementMarkerMap[elementIdentifier] = markerList
                markerList.append((markerName, xi, node.getIdentifier()))
            node = nodeIter.next()
        if self.elementMarkerMap:
            self._targetMarkerGroup = findOrCreateFieldGroup(
                self._targetFm, "marker")
            self._targetMarkerName = findOrCreateFieldStoredString(
                self._targetFm, name="marker_name")
            self._targetMarkerLocation = findOrCreateFieldStoredMeshLocation(
                self._targetFm, self._targetMesh, name="marker_location")
            self._targetMarkerNodes = findOrCreateFieldNodeGroup(
                self._targetMarkerGroup, self._targetNodes).getNodesetGroup()
            self._targetMarkerTemplate = self._targetMarkerNodes.createNodetemplate(
            )
            self._targetMarkerTemplate.defineField(self._targetMarkerName)
            self._targetMarkerTemplate.defineField(self._targetMarkerLocation)
Exemplo n.º 11
0
    def generateBaseMesh(region, options):
        """
        Generate the base tricubic Hermite mesh. See also generateMesh().
        :param region: Zinc region to define model in. Must be empty.
        :param options: Dict containing options. See getDefaultOptions().
        :return: List of AnnotationGroup
        """

        baseParameterSetName = options['Base parameter set']
        isHuman = 'Human' in baseParameterSetName
        isRat = 'Rat' in baseParameterSetName

        centralPath = options['Central path']
        full = not options['Lower half']
        elementsCountAcrossMajor = options['Number of elements across major']
        if not full:
            elementsCountAcrossMajor //= 2
        elementsCountAcrossMinor = options['Number of elements across minor']
        elementsCountAcrossShell = options['Number of elements across shell']
        elementsCountAcrossTransition = options['Number of elements across transition']
        elementsCountAlongAbdomen = options['Number of elements in abdomen']
        elementsCountAlongHead = options['Number of elements in head']
        elementsCountAlongNeck = options['Number of elements in neck']
        elementsCountAlongThorax = options['Number of elements in thorax']
        shellRadiusProportion = options['Shell thickness proportion']
        shellProportion = 1/(1/shellRadiusProportion-1)*(elementsCountAcrossMajor/2/elementsCountAcrossShell - 1)
        discontinuity = options['Discontinuity on the core boundary']
        useCrossDerivatives = options['Use cross derivatives']

        elementsCountAlong = elementsCountAlongAbdomen + elementsCountAlongThorax + elementsCountAlongNeck + elementsCountAlongHead

        fieldmodule = region.getFieldmodule()
        coordinates = findOrCreateFieldCoordinates(fieldmodule)
        mesh = fieldmodule.findMeshByDimension(3)

        bodyGroup = AnnotationGroup(region, get_body_term("body"))
        coreGroup = AnnotationGroup(region, get_body_term("core"))
        non_coreGroup = AnnotationGroup(region, get_body_term("non core"))
        abdomenGroup = AnnotationGroup(region, get_body_term("abdomen"))
        thoraxGroup = AnnotationGroup(region, get_body_term("thorax"))
        neckGroup = AnnotationGroup(region, get_body_term("neck core"))
        headGroup = AnnotationGroup(region, get_body_term("head core"))
        annotationGroups = [bodyGroup, coreGroup, non_coreGroup, abdomenGroup, thoraxGroup, neckGroup, headGroup]

        cylinderCentralPath = CylinderCentralPath(region, centralPath, elementsCountAlong)

        cylinderShape = CylinderShape.CYLINDER_SHAPE_FULL

        base = CylinderEnds(elementsCountAcrossMajor, elementsCountAcrossMinor, elementsCountAcrossShell,
                            elementsCountAcrossTransition, shellProportion,
                            [0.0, 0.0, 0.0], cylinderCentralPath.alongAxis[0], cylinderCentralPath.majorAxis[0],
                            cylinderCentralPath.minorRadii[0])
        cylinder1 = CylinderMesh(fieldmodule, coordinates, elementsCountAlong, base,
                                 cylinderShape=cylinderShape,
                                 cylinderCentralPath=cylinderCentralPath, useCrossDerivatives=False)

        # body coordinates
        bodyCoordinates = findOrCreateFieldCoordinates(fieldmodule, name="body coordinates")
        tmp_region = region.createRegion()
        tmp_fieldmodule = tmp_region.getFieldmodule()
        tmp_body_coordinates = findOrCreateFieldCoordinates(tmp_fieldmodule, name="body coordinates")
        tmp_cylinder = CylinderMesh(tmp_fieldmodule, tmp_body_coordinates, elementsCountAlong, base,
                                 cylinderShape=cylinderShape,
                                 cylinderCentralPath=cylinderCentralPath, useCrossDerivatives=False)
        sir = tmp_region.createStreaminformationRegion()
        srm = sir.createStreamresourceMemory()
        tmp_region.write(sir)
        result, buffer = srm.getBuffer()
        sir = region.createStreaminformationRegion()
        srm = sir.createStreamresourceMemoryBuffer(buffer)
        region.read(sir)

        del srm
        del sir
        del tmp_body_coordinates
        del tmp_fieldmodule
        del tmp_region

        # Groups of different parts of the body
        is_body = fieldmodule.createFieldConstant(1)
        bodyMeshGroup = bodyGroup.getMeshGroup(mesh)
        bodyMeshGroup.addElementsConditional(is_body)

        coreMeshGroup = coreGroup.getMeshGroup(mesh)

        # core group
        e1a = elementsCountAcrossShell
        e1z = elementsCountAcrossMinor - elementsCountAcrossShell - 1
        e2a = elementsCountAcrossShell
        e2b = e2a + elementsCountAcrossTransition
        e2z = elementsCountAcrossMajor - elementsCountAcrossShell - 1
        e2y = e2z - elementsCountAcrossTransition
        e1oc = elementsCountAcrossMinor - 2*elementsCountAcrossShell - 2*elementsCountAcrossTransition
        e2oc = elementsCountAcrossMajor - 2*elementsCountAcrossShell - 2*elementsCountAcrossTransition
        e2oCore = e2oc * e1oc + 2 * elementsCountAcrossTransition * (e2oc + e1oc)
        elementsCountAround = cylinder1.getElementsCountAround()
        e2oShell = elementsCountAround * elementsCountAcrossShell
        e2o = e2oCore + e2oShell
        elementId = cylinder1.getElementIdentifiers()
        for e3 in range(elementsCountAlong):
            for e2 in range(elementsCountAcrossMajor):
                for e1 in range(elementsCountAcrossMinor):
                    coreElement = ((e2 >= e2a) and (e2 <= e2z)) and ((e1 >= e1a) and (e1 <= e1z))
                    if coreElement:
                        elementIdentifier = elementId[e3][e2][e1]
                        if elementIdentifier:
                            element = mesh.findElementByIdentifier(elementIdentifier)
                            coreMeshGroup.addElement(element)

        is_non_core = fieldmodule.createFieldNot(coreGroup.getGroup())
        non_coreMeshGroup = non_coreGroup.getMeshGroup(mesh)
        non_coreMeshGroup.addElementsConditional(is_non_core)

        abdomenMeshGroup = abdomenGroup.getMeshGroup(mesh)
        thoraxMeshGroup = thoraxGroup.getMeshGroup(mesh)
        neckMeshGroup = neckGroup.getMeshGroup(mesh)
        headMeshGroup = headGroup.getMeshGroup(mesh)
        meshGroups = [abdomenMeshGroup, thoraxMeshGroup, neckMeshGroup, headMeshGroup]

        abdomenRange = [1, elementsCountAlongAbdomen*e2o]
        thoraxRange = [abdomenRange[1]+1, abdomenRange[1]+elementsCountAlongThorax*e2o]
        neckRange = [thoraxRange[1]+1, thoraxRange[1] + elementsCountAlongNeck*e2o]
        headRange = [neckRange[1]+1, elementsCountAlong*e2o]
        groupsRanges = [abdomenRange, thoraxRange, neckRange, headRange]

        totalElements = e2o*elementsCountAlong
        for elementIdentifier in range(1, totalElements+1):
            element = mesh.findElementByIdentifier(elementIdentifier)
            if coreMeshGroup.containsElement(element):
                ri = 0
                for groupRange in groupsRanges:
                    if (elementIdentifier >= groupRange[0]) and (elementIdentifier <= groupRange[1]):
                        meshGroups[ri].addElement(element)
                        break
                    ri += 1

        if discontinuity:
            # create discontinuity in d3 on the core boundary
            nodes = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
            elementtemplate = mesh.createElementtemplate()
            undefineNodetemplate = nodes.createNodetemplate()
            undefineNodetemplate.undefineField(coordinates)
            nodetemplate = nodes.createNodetemplate()
            fieldcache = fieldmodule.createFieldcache()
            with ChangeManager(fieldmodule):
                localNodeIndexes = [1, 2, 3, 4]
                valueLabel = Node.VALUE_LABEL_D_DS3
                for e3 in range(elementsCountAlong):
                    for e2 in range(elementsCountAcrossMajor):
                        for e1 in range(elementsCountAcrossMinor):
                            regularRowElement = (((e2 >= e2b) and (e2 <= e2y)) and ((e1 == e1a - 1) or (e1 == e1z + 1)))
                            non_coreFirstLayerElement = (e2 == e2a - 1) or regularRowElement or (e2 == e2z + 1)
                            elementIdentifier = elementId[e3][e2][e1]
                            if elementIdentifier and non_coreFirstLayerElement:
                                element = mesh.findElementByIdentifier(elementIdentifier)
                                eft = element.getElementfieldtemplate(coordinates, -1)
                                nodeIds = get_element_node_identifiers(element, eft)
                                for localNodeIndex in localNodeIndexes:
                                    node = element.getNode(eft, localNodeIndex)
                                    nodetemplate.defineFieldFromNode(coordinates, node)
                                    versionsCount = nodetemplate.getValueNumberOfVersions(coordinates, -1, valueLabel)
                                    if versionsCount == 1:
                                        fieldcache.setNode(node)
                                        result0, x = coordinates.getNodeParameters(fieldcache, -1, Node.VALUE_LABEL_VALUE, 1, 3)
                                        result0, d1 = coordinates.getNodeParameters(fieldcache, -1, Node.VALUE_LABEL_D_DS1, 1, 3)
                                        result0, d2 = coordinates.getNodeParameters(fieldcache, -1, Node.VALUE_LABEL_D_DS2, 1, 3)
                                        result0, d3 = coordinates.getNodeParameters(fieldcache, -1, valueLabel, 1, 3)
                                        result1 = node.merge(undefineNodetemplate)
                                        result2 = nodetemplate.setValueNumberOfVersions(coordinates, -1, valueLabel, 2)
                                        result3 = node.merge(nodetemplate)
                                        result4 = coordinates.setNodeParameters(fieldcache, -1, Node.VALUE_LABEL_VALUE, 1, x)
                                        result4 = coordinates.setNodeParameters(fieldcache, -1, Node.VALUE_LABEL_D_DS1, 1, d1)
                                        result4 = coordinates.setNodeParameters(fieldcache, -1, Node.VALUE_LABEL_D_DS2, 1, d2)
                                        result4 = coordinates.setNodeParameters(fieldcache, -1, valueLabel, 1, d3)
                                        result5 = coordinates.setNodeParameters(fieldcache, -1, valueLabel, 2, d3)
                                remapEftNodeValueLabelsVersion(eft, localNodeIndexes, [valueLabel], 2)
                                result1 = elementtemplate.defineField(coordinates, -1, eft)
                                result2 = element.merge(elementtemplate)
                                result3 = element.setNodesByIdentifier(eft, nodeIds)
        else:
            fieldcache = fieldmodule.createFieldcache()

        # Annotation fiducial point
        markerGroup = findOrCreateFieldGroup(fieldmodule, "marker")
        markerName = findOrCreateFieldStoredString(fieldmodule, name="marker_name")
        markerLocation = findOrCreateFieldStoredMeshLocation(fieldmodule, mesh, name="marker_location")
        markerBodyCoordinates = findOrCreateFieldCoordinates(fieldmodule, name="marker_body_coordinates")
        nodes = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
        markerPoints = findOrCreateFieldNodeGroup(markerGroup, nodes).getNodesetGroup()
        markerTemplateInternal = nodes.createNodetemplate()
        markerTemplateInternal.defineField(markerName)
        markerTemplateInternal.defineField(markerLocation)
        markerTemplateInternal.defineField(markerBodyCoordinates)
        #
        middleLeft = elementsCountAcrossMinor//2
        topElem = elementsCountAcrossMajor - 1
        middleRight = middleLeft - 1
        neckFirstElem = elementsCountAlongAbdomen+elementsCountAlongThorax
        thoraxFirstElem = elementsCountAlongAbdomen
        middleDown = elementsCountAcrossMajor//2 - 1

        # organ landmarks groups
        apexOfHeart = heart_terms.get_heart_term('apex of heart')
        leftAtriumEpicardiumVenousMidpoint = heart_terms.get_heart_term('left atrium epicardium venous midpoint')
        rightAtriumEpicardiumVenousMidpoint = heart_terms.get_heart_term('right atrium epicardium venous midpoint')
        apexOfUrinaryBladder = bladder_terms.get_bladder_term('apex of urinary bladder')
        leftUreterJunctionWithBladder = bladder_terms.get_bladder_term('left ureter junction with bladder')
        rightUreterJunctionWithBladder = bladder_terms.get_bladder_term('right ureter junction with bladder')
        urethraJunctionWithBladderDorsal = bladder_terms.get_bladder_term('urethra junction of dorsal bladder neck')
        urethraJunctionWithBladderVentral = bladder_terms.get_bladder_term('urethra junction of ventral bladder neck')
        gastroesophagalJunctionOnLesserCurvature = stomach_terms.get_stomach_term('esophagogastric junction along the lesser curvature on serosa')
        limitingRidgeOnGreaterCurvature = stomach_terms.get_stomach_term('limiting ridge at the greater curvature on serosa')
        pylorusOnGreaterCurvature = stomach_terms.get_stomach_term('gastroduodenal junction along the greater curvature on serosa')
        junctionBetweenFundusAndBodyOnGreaterCurvature = stomach_terms.get_stomach_term("fundus-body junction along the greater curvature on serosa")
        apexOfLeftLung = lung_terms.get_lung_term('apex of left lung')
        ventralBaseOfLeftLung = lung_terms.get_lung_term('ventral base of left lung')
        dorsalBaseOfLeftLung = lung_terms.get_lung_term('dorsal base of left lung')
        apexOfRightLung = lung_terms.get_lung_term('apex of right lung')
        ventralBaseOfRightLung = lung_terms.get_lung_term('ventral base of right lung')
        dorsalBaseOfRightLung = lung_terms.get_lung_term('dorsal base of right lung')
        laterodorsalTipOfMiddleLobeOfRightLung = lung_terms.get_lung_term('laterodorsal tip of middle lobe of right lung')
        apexOfRightLungAccessoryLobe = lung_terms.get_lung_term('apex of right lung accessory lobe')
        ventralBaseOfRightLungAccessoryLobe = lung_terms.get_lung_term('ventral base of right lung accessory lobe')
        dorsalBaseOfRightLungAccessoryLobe = lung_terms.get_lung_term('dorsal base of right lung accessory lobe')
        medialBaseOfLeftLung = lung_terms.get_lung_term("medial base of left lung")
        medialBaseOfRightLung = lung_terms.get_lung_term("medial base of right lung")
        brainstemDorsalMidlineCaudalPoint = brainstem_terms.get_brainstem_term('brainstem dorsal midline caudal point')
        brainstemDorsalMidlineCranialPoint = brainstem_terms.get_brainstem_term('brainstem dorsal midline cranial point')
        brainstemVentralMidlineCaudalPoint = brainstem_terms.get_brainstem_term('brainstem ventral midline caudal point')
        brainstemVentralMidlineCranialPoint = brainstem_terms.get_brainstem_term('brainstem ventral midline cranial point')

        # marker coordinates. In future we want to have only one table for all species.
        if isRat:
            bodyMarkerPoints = [
                {"group": ("left hip joint", ''), "x": [0.367, 0.266, 0.477]},
                {"group": ("right hip joint", ''), "x": [-0.367, 0.266, 0.477]},
                {"group": ("left shoulder joint", ''), "x": [0.456, -0.071, 2.705]},
                {"group": ("right shoulder joint", ''), "x": [-0.456, -0.071, 2.705]},
                {"group": ("along left femur", ''), "x": [0.456, 0.07, 0.633]},
                {"group": ("along right femur", ''), "x": [-0.456, 0.07, 0.633]},
                {"group": ("along left humerus", ''), "x": [0.423, -0.173, 2.545]},
                {"group": ("along right humerus", ''), "x": [-0.423, -0.173, 2.545]},
                {"group": apexOfUrinaryBladder, "x": [-0.124, -0.383, 0.434]},
                {"group": leftUreterJunctionWithBladder, "x": [-0.111, -0.172, 0.354]},
                {"group": rightUreterJunctionWithBladder, "x": [-0.03, -0.196, 0.363]},
                {"group": urethraJunctionWithBladderDorsal, "x": [-0.03, -0.26, 0.209]},
                {"group": urethraJunctionWithBladderVentral, "x": [-0.037, -0.304, 0.203]},
                {"group": brainstemDorsalMidlineCaudalPoint, "x": [-0.032, 0.418, 2.713]},
                {"group": brainstemDorsalMidlineCranialPoint, "x": [-0.017, 0.203, 2.941]},
                {"group": brainstemVentralMidlineCaudalPoint, "x": [-0.028, 0.388, 2.72]},
                {"group": brainstemVentralMidlineCranialPoint, "x": [-0.019, 0.167, 2.95]},
                {"group": apexOfHeart, "x": [0.096, -0.128, 1.601]},
                {"group": leftAtriumEpicardiumVenousMidpoint, "x": [0.127, -0.083, 2.079]},
                {"group": rightAtriumEpicardiumVenousMidpoint, "x": [0.039, -0.082, 2.075]},
                {"group": apexOfLeftLung, "x": [0.172, -0.175, 2.337]},
                {"group": ventralBaseOfLeftLung, "x": [0.274, -0.285, 1.602]},
                {"group": dorsalBaseOfLeftLung, "x": [0.037, 0.31, 1.649]},
                {"group": apexOfRightLung, "x": [-0.086, -0.096, 2.311]},
                {"group": ventralBaseOfRightLung, "x": [0.14, -0.357, 1.662]},
                {"group": dorsalBaseOfRightLung, "x": [-0.054, 0.304, 1.667]},
                {"group": laterodorsalTipOfMiddleLobeOfRightLung, "x": [-0.258, -0.173, 2.013]},
                {"group": apexOfRightLungAccessoryLobe, "x": [0.041, -0.063, 1.965]},
                {"group": ventralBaseOfRightLungAccessoryLobe, "x": [0.143, -0.356, 1.66]},
                {"group": dorsalBaseOfRightLungAccessoryLobe, "x": [0.121, -0.067, 1.627]},
                {"group": gastroesophagalJunctionOnLesserCurvature, "x": [0.12, 0.009, 1.446]},
                {"group": limitingRidgeOnGreaterCurvature, "x": [0.318, 0.097, 1.406]},
                {"group": pylorusOnGreaterCurvature, "x": [0.08, -0.111, 1.443]},
            ]
        elif isHuman:
            bodyMarkerPoints = [
                {"group": urethraJunctionWithBladderDorsal, "x": [-0.0071, -0.2439, 0.1798]},
                {"group": urethraJunctionWithBladderVentral, "x": [-0.007, -0.2528, 0.1732]},
                {"group": leftUreterJunctionWithBladder, "x": [0.1074, 0.045, 0.1728]},
                {"group": rightUreterJunctionWithBladder, "x": [-0.1058, 0.0533, 0.1701]},
                {"group": apexOfUrinaryBladder, "x": [0.005, 0.1286, 0.1264]},
                {"group": brainstemDorsalMidlineCaudalPoint, "x": [0.0068, 0.427, 2.7389]},
                {"group": brainstemDorsalMidlineCranialPoint, "x": [0.008, -0.0231, 3.0778]},
                {"group": brainstemVentralMidlineCaudalPoint, "x": [0.0054, 0.3041, 2.7374]},
                {"group": brainstemVentralMidlineCranialPoint, "x": [0.0025, -0.2308, 3.091]},
                {"group": apexOfHeart, "x": [0.1373, -0.1855, 1.421]},
                {"group": leftAtriumEpicardiumVenousMidpoint, "x": [0.0024, 0.1452, 1.8022]},
                {"group": rightAtriumEpicardiumVenousMidpoint, "x": [-0.0464, 0.0373, 1.7491]},
                {"group": apexOfLeftLung, "x": [0.0655, -0.0873, 2.3564]},
                {"group": apexOfRightLung, "x": [-0.088, -0.0363, 2.3518]},
                {"group": laterodorsalTipOfMiddleLobeOfRightLung, "x": [-0.2838, -0.0933, 1.9962]},
                {"group": ventralBaseOfLeftLung, "x": [0.219, -0.2866, 1.4602]},
                {"group": medialBaseOfLeftLung, "x": [0.0426, -0.0201, 1.4109]},
                {"group": ventralBaseOfRightLung, "x": [-0.2302, -0.2356, 1.3926]},
                {"group": medialBaseOfRightLung, "x": [-0.0363, 0.0589, 1.3984]},
                {"group": dorsalBaseOfLeftLung, "x": [0.1544, 0.2603, 1.3691]},
                {"group": dorsalBaseOfRightLung, "x": [0.0369, -0.2524, 0.912]},
                {"group": gastroesophagalJunctionOnLesserCurvature, "x": [-0.0062, -0.3259, 0.8586]},
                {"group": pylorusOnGreaterCurvature, "x": [-0.0761, -0.3189, 0.8663]},
                {"group": junctionBetweenFundusAndBodyOnGreaterCurvature, "x": [0.1884, -0.1839, 0.9639]},
            ]

        nodeIdentifier = cylinder1._endNodeIdentifier
        findMarkerLocation = fieldmodule.createFieldFindMeshLocation(markerBodyCoordinates, bodyCoordinates, mesh)
        findMarkerLocation.setSearchMode(FieldFindMeshLocation.SEARCH_MODE_EXACT)
        for bodyMarkerPoint in bodyMarkerPoints:
            markerPoint = markerPoints.createNode(nodeIdentifier, markerTemplateInternal)
            fieldcache.setNode(markerPoint)
            markerBodyCoordinates.assignReal(fieldcache, bodyMarkerPoint["x"])
            markerName.assignString(fieldcache, bodyMarkerPoint["group"][0])

            element, xi = findMarkerLocation.evaluateMeshLocation(fieldcache, 3)
            markerLocation.assignMeshLocation(fieldcache, element, xi)
            nodeIdentifier += 1

        return annotationGroups
Exemplo n.º 12
0
    def generateBaseMesh(cls, region, options):
        """
        Generate the base tricubic Hermite mesh. See also generateMesh().
        :param region: Zinc region to define model in. Must be empty.
        :param options: Dict containing options. See getDefaultOptions().
        :return: None
        """
        parameterSetName = options['Base parameter set']
        isCat = 'Cat 1' in parameterSetName
        isHuman = 'Human 1' in parameterSetName
        isMouse = 'Mouse 1' in parameterSetName
        isRat = 'Rat 1' in parameterSetName
        isPig = 'Pig 1' in parameterSetName
        isSheep = 'Sheep 1' in parameterSetName

        centralPath = options['Central path']
        brainstemPath = cls.centralPathDefaultScaffoldPackages['Brainstem 1']
        elementsCountAcrossMajor = options['Number of elements across major']
        elementsCountAcrossMinor = options['Number of elements across minor']
        elementsCountAlong = options['Number of elements along']

        # Cross section at Z axis
        halfBrainStem = False
        if halfBrainStem:
            elementsCountAcrossMajor //= 2
        elementsPerLayer = (
            (elementsCountAcrossMajor - 2) *
            elementsCountAcrossMinor) + (2 * (elementsCountAcrossMinor - 2))

        fm = region.getFieldmodule()
        cache = fm.createFieldcache()
        coordinates = findOrCreateFieldCoordinates(fm)
        mesh = fm.findMeshByDimension(3)

        # Annotation groups
        brainstemGroup = AnnotationGroup(region,
                                         get_brainstem_term('brainstem'))
        brainstemMeshGroup = brainstemGroup.getMeshGroup(mesh)
        midbrainGroup = AnnotationGroup(region, get_brainstem_term('midbrain'))
        midbrainMeshGroup = midbrainGroup.getMeshGroup(mesh)
        ponsGroup = AnnotationGroup(region, get_brainstem_term('pons'))
        ponsMeshGroup = ponsGroup.getMeshGroup(mesh)
        medullaGroup = AnnotationGroup(region,
                                       get_brainstem_term('medulla oblongata'))
        medullaMeshGroup = medullaGroup.getMeshGroup(mesh)
        annotationGroups = [
            brainstemGroup, midbrainGroup, ponsGroup, medullaGroup
        ]

        annotationGroupAlong = [[brainstemGroup, midbrainGroup],
                                [brainstemGroup, ponsGroup],
                                [brainstemGroup, medullaGroup]]

        # point markers
        # centralCanal = findOrCreateAnnotationGroupForTerm(annotationGroups, region,
        #                                                        get_brainstem_term('central canal of spinal cord'))
        # cerebralAqueduct = findOrCreateAnnotationGroupForTerm(annotationGroups, region,
        #                                                        get_brainstem_term('cerebral aqueduct'))
        # foramenCaecum = findOrCreateAnnotationGroupForTerm(annotationGroups, region,
        #                                                        get_brainstem_term('foramen caecum of medulla oblongata'))
        dorsalMidCaudalGroup = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region,
            get_brainstem_term('brainstem dorsal midline caudal point'))
        ventralMidCaudalGroup = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region,
            get_brainstem_term('brainstem ventral midline caudal point'))
        dorsalMidCranGroup = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region,
            get_brainstem_term('brainstem dorsal midline cranial point'))
        ventralMidCranGroup = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region,
            get_brainstem_term('brainstem ventral midline cranial point'))
        dorsalMidMedullaPonsJunction = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region,
            get_brainstem_term(
                'brainstem dorsal midline pons-medulla junction'))
        ventralMidMedullaPonsJunction = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region,
            get_brainstem_term(
                'brainstem ventral midline pons-medulla junction'))
        dorsalMidMidbrainPonsJunction = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region,
            get_brainstem_term(
                'brainstem dorsal midline midbrain-pons junction'))
        ventralMidMidbrainPonsJunction = findOrCreateAnnotationGroupForTerm(
            annotationGroups, region,
            get_brainstem_term(
                'brainstem ventral midline midbrain-pons junction'))

        #######################
        # CREATE MAIN BODY MESH
        #######################
        cylinderShape = CylinderShape.CYLINDER_SHAPE_FULL if not halfBrainStem else CylinderShape.CYLINDER_SHAPE_LOWER_HALF

        # Body coordinates
        cylinderCentralPath = CylinderCentralPath(region, centralPath,
                                                  elementsCountAlong)
        base = CylinderEnds(elementsCountAcrossMajor,
                            elementsCountAcrossMinor,
                            centre=[0.0, 0.0, 0.0],
                            alongAxis=cylinderCentralPath.alongAxis[0],
                            majorAxis=cylinderCentralPath.majorAxis[0],
                            minorRadius=cylinderCentralPath.minorRadii[0])

        cylinder1 = CylinderMesh(fm,
                                 coordinates,
                                 elementsCountAlong,
                                 base,
                                 cylinderShape=cylinderShape,
                                 cylinderCentralPath=cylinderCentralPath,
                                 useCrossDerivatives=False)

        brainstem_coordinates = findOrCreateFieldCoordinates(
            fm, name="brainstem coordinates")

        # Brain coordinates
        tmp_region = region.createRegion()
        tmp_fm = tmp_region.getFieldmodule()
        tmp_brainstem_coordinates = findOrCreateFieldCoordinates(
            tmp_fm, name="brainstem coordinates")

        cylinderCentralPath1 = CylinderCentralPath(tmp_region, brainstemPath,
                                                   elementsCountAlong)

        base1 = CylinderEnds(elementsCountAcrossMajor,
                             elementsCountAcrossMinor,
                             centre=[0.0, 0.0, 0.0],
                             alongAxis=cylinderCentralPath1.alongAxis[0],
                             majorAxis=cylinderCentralPath1.majorAxis[0],
                             minorRadius=cylinderCentralPath1.minorRadii[0])

        cylinder2 = CylinderMesh(tmp_fm,
                                 tmp_brainstem_coordinates,
                                 elementsCountAlong,
                                 base1,
                                 cylinderShape=cylinderShape,
                                 cylinderCentralPath=cylinderCentralPath1,
                                 useCrossDerivatives=False)

        # Write two coordinates
        sir = tmp_region.createStreaminformationRegion()
        srm = sir.createStreamresourceMemory()
        tmp_region.write(sir)
        result, buffer = srm.getBuffer()

        sir = region.createStreaminformationRegion()
        srm = sir.createStreamresourceMemoryBuffer(buffer)
        region.read(sir)

        del srm
        del sir
        del tmp_fm
        del tmp_brainstem_coordinates
        del tmp_region

        # Annotating groups
        iRegionBoundaries = [
            int(6 * elementsCountAlong / 15),
            int(13 * elementsCountAlong / 15)
        ]
        for elementIdentifier in range(1, mesh.getSize() + 1):
            element = mesh.findElementByIdentifier(elementIdentifier)
            brainstemMeshGroup.addElement(element)
            if elementIdentifier > (iRegionBoundaries[-1] * elementsPerLayer):
                midbrainMeshGroup.addElement(element)
            elif (elementIdentifier >
                  (iRegionBoundaries[0] * elementsPerLayer)) and (
                      elementIdentifier <=
                      (iRegionBoundaries[-1] * elementsPerLayer)):
                ponsMeshGroup.addElement(element)
            else:
                medullaMeshGroup.addElement(element)

        ################
        # point markers
        ################
        pointMarkers = [
            {
                "group": dorsalMidCaudalGroup,
                "marker_brainstem_coordinates": [0.0, 1.0, 0.0]
            },
            {
                "group": ventralMidCaudalGroup,
                "marker_brainstem_coordinates": [0.0, -1.0, 0.0]
            },
            {
                "group": dorsalMidCranGroup,
                "marker_brainstem_coordinates": [0.0, 1.0, 8.0]
            },
            {
                "group": ventralMidCranGroup,
                "marker_brainstem_coordinates": [0.0, -1.0, 8.0]
            },
            {
                "group": dorsalMidMedullaPonsJunction,
                "marker_brainstem_coordinates": [0.0, 1.0, 3.0]
            },
            {
                "group": ventralMidMedullaPonsJunction,
                "marker_brainstem_coordinates": [0.0, -1.0, 3.0]
            },
            {
                "group": dorsalMidMidbrainPonsJunction,
                "marker_brainstem_coordinates": [0.0, 1.0, 6.0]
            },
            {
                "group": ventralMidMidbrainPonsJunction,
                "marker_brainstem_coordinates": [0.0, -1.0, 6.0]
            },
        ]

        markerGroup = findOrCreateFieldGroup(fm, "marker")
        markerName = findOrCreateFieldStoredString(fm, name="marker_name")
        markerLocation = findOrCreateFieldStoredMeshLocation(
            fm, mesh, name="marker_location")

        nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
        markerPoints = findOrCreateFieldNodeGroup(markerGroup,
                                                  nodes).getNodesetGroup()
        markerBrainstemCoordinates = findOrCreateFieldCoordinates(
            fm, name="marker_body_coordinates")
        markerTemplateInternal = nodes.createNodetemplate()
        markerTemplateInternal.defineField(markerName)
        markerTemplateInternal.defineField(markerLocation)
        markerTemplateInternal.defineField(markerBrainstemCoordinates)

        cache = fm.createFieldcache()

        brainstemNodesetGroup = brainstemGroup.getNodesetGroup(nodes)

        nodeIdentifier = max(1, getMaximumNodeIdentifier(nodes) + 1)
        findMarkerLocation = fm.createFieldFindMeshLocation(
            markerBrainstemCoordinates, brainstem_coordinates, mesh)
        findMarkerLocation.setSearchMode(
            FieldFindMeshLocation.SEARCH_MODE_EXACT)

        for pointMarker in pointMarkers:
            group = pointMarker["group"]
            markerPoint = markerPoints.createNode(nodeIdentifier,
                                                  markerTemplateInternal)
            cache.setNode(markerPoint)

            markerBrainstemCoordinates.assignReal(
                cache, pointMarker["marker_brainstem_coordinates"])
            markerName.assignString(cache, group.getName())

            element, xi = findMarkerLocation.evaluateMeshLocation(cache, 3)
            markerLocation.assignMeshLocation(cache, element, xi)
            group.getNodesetGroup(nodes).addNode(markerPoint)
            brainstemNodesetGroup.addNode(markerPoint)
            nodeIdentifier += 1

        return annotationGroups
Exemplo n.º 13
0
def zinc_write_element_xi_marker_file(region,
                                      allMarkers,
                                      xiNodeInfo,
                                      regionD,
                                      nodeIdentifierStart,
                                      coordinates,
                                      outFile=[]):
    fm = region.getFieldmodule()
    if outFile:
        fm.beginChange()
    # if xiNodeInfo['nodeType'] == 'nodes':
    nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
    mesh = fm.findMeshByDimension(3)
    mesh1d = fm.findMeshByDimension(1)
    cache = fm.createFieldcache()

    xiNodeName = findOrCreateFieldStoredString(fm, name=xiNodeInfo['nameStr'])
    xiNodeLocation = findOrCreateFieldStoredMeshLocation(
        fm, mesh, name="elementxi_location")
    xiNodeTemplate = nodes.createNodetemplate()
    xiNodeTemplate.defineField(xiNodeLocation)
    xiNodeTemplate.defineField(coordinates)
    xiNodeTemplate.setValueNumberOfVersions(coordinates, -1,
                                            Node.VALUE_LABEL_VALUE, 1)
    xiNodeTemplate.setValueNumberOfVersions(coordinates, -1,
                                            Node.VALUE_LABEL_D_DS1, 1)
    xiNodeTemplate.setValueNumberOfVersions(coordinates, -1,
                                            Node.VALUE_LABEL_D_DS2, 1)
    xiNodeTemplate.setValueNumberOfVersions(coordinates, -1,
                                            Node.VALUE_LABEL_D_DS3, 1)
    xiMeshGroup = AnnotationGroup(
        region, ('tracts_xi_elements', None)).getMeshGroup(mesh1d)

    nodeIdentifier = nodeIdentifierStart
    for key in allMarkers:
        xiNodeGroup = findOrCreateFieldGroup(
            fm, xiNodeInfo['groupName'] + '_' + key)
        xiNodePoints = findOrCreateFieldNodeGroup(xiNodeGroup,
                                                  nodes).getNodesetGroup()
        addxiNode = {"name": key, "xi": allMarkers[key]["xi"]}
        xiNodePoint = xiNodePoints.createNode(nodeIdentifier, xiNodeTemplate)
        xiNodePoint.merge(xiNodeTemplate)
        cache.setNode(xiNodePoint)
        elementID = allMarkers[key]["elementID"]
        element = mesh.findElementByIdentifier(elementID)
        result = xiNodeLocation.assignMeshLocation(cache, element,
                                                   addxiNode["xi"])
        result = coordinates.setNodeParameters(cache, -1,
                                               Node.VALUE_LABEL_VALUE, 1,
                                               list(regionD[key]['centre']))
        try:
            result = coordinates.setNodeParameters(
                cache, -1, Node.VALUE_LABEL_D_DS1, 1,
                list(regionD[key]['axes'][0]))
            result = coordinates.setNodeParameters(
                cache, -1, Node.VALUE_LABEL_D_DS2, 1,
                list(regionD[key]['axes'][1]))
            result = coordinates.setNodeParameters(
                cache, -1, Node.VALUE_LABEL_D_DS3, 1,
                list(regionD[key]['axes'][2]))
        except:
            result = coordinates.setNodeParameters(cache, -1,
                                                   Node.VALUE_LABEL_D_DS1, 1,
                                                   [1, 0, 0])
            result = coordinates.setNodeParameters(cache, -1,
                                                   Node.VALUE_LABEL_D_DS2, 1,
                                                   [0, 1, 0])
            result = coordinates.setNodeParameters(cache, -1,
                                                   Node.VALUE_LABEL_D_DS3, 1,
                                                   [0, 0, 1])

        nodeIdentifier += 1

    # write 1D elements between embedded nodes
    if True:
        mesh1d = fm.findMeshByDimension(1)
        elementIdentifier = 55555555
        basis1d = fm.createElementbasis(
            1, Elementbasis.FUNCTION_TYPE_CUBIC_HERMITE)
        eft1d = mesh1d.createElementfieldtemplate(basis1d)
        elementtemplate = mesh1d.createElementtemplate()
        elementtemplate.setElementShapeType(Element.SHAPE_TYPE_LINE)
        result = elementtemplate.defineField(coordinates, -1, eft1d)
        element = mesh1d.createElement(elementIdentifier, elementtemplate)
        result = element.setNodesByIdentifier(
            eft1d, [nodeIdentifierStart, nodeIdentifier - 1])
        xiMeshGroup.addElement(element)

    if outFile:
        fm.endChange()
        region.writeFile(outFile)

    return region
Exemplo n.º 14
0
 nodetemplate.setValueNumberOfVersions(norm, -1,
                                       Node.VALUE_LABEL_VALUE, 1)
 # mesh1d = fmCh.findMeshByDimension(1)
 mesh2d = fmCh.findMeshByDimension(2)
 # basis1d = fmCh.createElementbasis(1, Elementbasis.FUNCTION_TYPE_LINEAR_LAGRANGE)
 # eft1d = mesh1d.createElementfieldtemplate(basis1d)
 basisTri = fmCh.createElementbasis(
     2, Elementbasis.FUNCTION_TYPE_LINEAR_SIMPLEX)
 eftTri = mesh2d.createElementfieldtemplate(basisTri)
 elementtemplate = mesh2d.createElementtemplate()
 elementtemplate.setElementShapeType(Element.SHAPE_TYPE_TRIANGLE)
 result = elementtemplate.defineField(coordinates, -1, eftTri)
 cache = fmCh.createFieldcache()
 # create nodes
 if outline:
     exteriorGroup = findOrCreateFieldGroup(
         fmCh, 'brainstem_exterior_obsolete')
     exteriorPoints = findOrCreateFieldNodeGroup(
         exteriorGroup, nodes).getNodesetGroup()
     medullaGroup = findOrCreateFieldGroup(
         fmCh, 'medulla oblongata_exterior')
     medullaPoints = findOrCreateFieldNodeGroup(
         medullaGroup, nodes).getNodesetGroup()
     ponsGroup = findOrCreateFieldGroup(fmCh, 'pons_exterior')
     ponsPoints = findOrCreateFieldNodeGroup(
         ponsGroup, nodes).getNodesetGroup()
     midbrainGroup = findOrCreateFieldGroup(fmCh,
                                            'midbrain_exterior')
     midbrainPoints = findOrCreateFieldNodeGroup(
         midbrainGroup, nodes).getNodesetGroup()
     extNodetemplate = exteriorPoints.createNodetemplate()
     extNodetemplate.defineField(coordinates)
    def generateBaseMesh(cls, region, options):
        '''
        Generate the base tricubic Hermite mesh. See also generateMesh().
        :param region: Zinc region to define model in. Must be empty.
        :param options: Dict containing options. See getDefaultOptions().
        :return: annotationGroups
        '''
        fm = region.getFieldmodule()
        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)
        nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                              Node.VALUE_LABEL_D_DS1, 1)
        nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                              Node.VALUE_LABEL_D_DS2, 1)
        nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                              Node.VALUE_LABEL_D_DS3, 1)

        mesh = fm.findMeshByDimension(3)
        cache = fm.createFieldcache()

        elementsCount1 = 2
        elementsCount2 = 4
        elementsCount3 = 4

        # Annotation fiducial point
        markerGroup = findOrCreateFieldGroup(fm, "marker")
        markerName = findOrCreateFieldStoredString(fm, name="marker_name")
        markerLocation = findOrCreateFieldStoredMeshLocation(
            fm, mesh, name="marker_location")

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

        # Create nodes
        nodeIdentifier = 1
        lNodeIds = []
        d1 = [0.5, 0.0, 0.0]
        d2 = [0.0, 0.5, 0.0]
        d3 = [0.0, 0.0, 1.0]
        for n3 in range(elementsCount3 + 1):
            lNodeIds.append([])
            for n2 in range(elementsCount2 + 1):
                lNodeIds[n3].append([])
                for n1 in range(elementsCount1 + 1):
                    lNodeIds[n3][n2].append([])
                    if n3 < elementsCount3:
                        if (n1 == 0) and ((n2 == 0) or (n2 == elementsCount2)):
                            continue
                    else:
                        if (n2 == 0) or (n2 == elementsCount2) or (n1 == 0):
                            continue
                    node = nodes.createNode(nodeIdentifier, nodetemplate)
                    cache.setNode(node)
                    x = [0.5 * (n1 - 1), 0.5 * (n2 - 1), 1.0 * n3]
                    coordinates.setNodeParameters(cache, -1,
                                                  Node.VALUE_LABEL_VALUE, 1, x)
                    coordinates.setNodeParameters(cache, -1,
                                                  Node.VALUE_LABEL_D_DS1, 1,
                                                  d1)
                    coordinates.setNodeParameters(cache, -1,
                                                  Node.VALUE_LABEL_D_DS2, 1,
                                                  d2)
                    coordinates.setNodeParameters(cache, -1,
                                                  Node.VALUE_LABEL_D_DS3, 1,
                                                  d3)
                    lNodeIds[n3][n2][n1] = nodeIdentifier
                    nodeIdentifier += 1

        # Create elements
        mesh = fm.findMeshByDimension(3)
        eftfactory = eftfactory_tricubichermite(mesh, None)
        eftRegular = eftfactory.createEftBasic()

        elementtemplateRegular = mesh.createElementtemplate()
        elementtemplateRegular.setElementShapeType(Element.SHAPE_TYPE_CUBE)
        elementtemplateRegular.defineField(coordinates, -1, eftRegular)

        elementtemplateCustom = mesh.createElementtemplate()
        elementtemplateCustom.setElementShapeType(Element.SHAPE_TYPE_CUBE)

        lungGroup = AnnotationGroup(region, get_lung_term("lung"))
        leftLungGroup = AnnotationGroup(region, get_lung_term("left lung"))
        rightLungGroup = AnnotationGroup(region, get_lung_term("right lung"))
        annotationGroups = [leftLungGroup, rightLungGroup, lungGroup]

        lungMeshGroup = lungGroup.getMeshGroup(mesh)
        leftLungMeshGroup = leftLungGroup.getMeshGroup(mesh)
        rightLungMeshGroup = rightLungGroup.getMeshGroup(mesh)

        eft1 = eftfactory.createEftWedgeCollapseXi1Quadrant([1, 5])
        eft2 = eftfactory.createEftWedgeCollapseXi1Quadrant([3, 7])
        eft3 = eftfactory.createEftWedgeCollapseXi2Quadrant([5, 6])
        eft4 = eftfactory.createEftWedgeCollapseXi2Quadrant([7, 8])
        eft5 = eftfactory.createEftWedgeCollapseXi1Quadrant([5, 7])
        eft6 = eftfactory.createEftTetrahedronCollapseXi1Xi2Quadrant(8, 2)
        eft7 = eftfactory.createEftTetrahedronCollapseXi1Xi2Quadrant(6, 3)

        elementIdentifier = 1
        for e3 in range(elementsCount3):
            for e2 in range(elementsCount2):
                for e1 in range(elementsCount1):
                    eft = eftRegular
                    nodeIdentifiers = [
                        lNodeIds[e3][e2][e1], lNodeIds[e3][e2][e1 + 1],
                        lNodeIds[e3][e2 + 1][e1], lNodeIds[e3][e2 + 1][e1 + 1],
                        lNodeIds[e3 + 1][e2][e1], lNodeIds[e3 + 1][e2][e1 + 1],
                        lNodeIds[e3 + 1][e2 + 1][e1],
                        lNodeIds[e3 + 1][e2 + 1][e1 + 1]
                    ]
                    scalefactors = None
                    if (e3 < elementsCount3 - 1):
                        if (e2 == 0) and (e1 == 0):
                            # Back wedge elements
                            nodeIdentifiers.pop(4)
                            nodeIdentifiers.pop(0)
                            eft = eft1
                            scalefactors = [-1.0]
                        elif (e2 == elementsCount2 - 1) and (e1 == 0):
                            # Front wedge elements
                            nodeIdentifiers.pop(6)
                            nodeIdentifiers.pop(2)
                            eft = eft2
                    else:
                        if (e2 == 0) and (e1 == 1):
                            # Top back wedge elements
                            nodeIdentifiers.pop(5)
                            nodeIdentifiers.pop(4)
                            eft = eft3
                        elif (e2 == elementsCount2 - 1) and (e1 == 1):
                            # Top front wedge elements
                            nodeIdentifiers.pop(7)
                            nodeIdentifiers.pop(6)
                            eft = eft4
                            scalefactors = [-1.0]
                        elif (e2 == 1) and (e1 == 0):
                            # Top middle back wedge element
                            nodeIdentifiers.pop(6)
                            nodeIdentifiers.pop(4)
                            eft = eft5
                        elif (e2 == 2) and (e1 == 0):
                            # Top middle front wedge element
                            nodeIdentifiers.pop(6)
                            nodeIdentifiers.pop(4)
                            eft = eft5
                        if (e2 == 0) and (e1 == 0):
                            # Top back tetrahedron element
                            nodeIdentifiers.pop(6)
                            nodeIdentifiers.pop(5)
                            nodeIdentifiers.pop(4)
                            nodeIdentifiers.pop(0)
                            eft = eft6
                            scalefactors = [-1.0]
                        if (e2 == elementsCount2 - 1) and (e1 == 0):
                            # Top front tetrahedron element
                            nodeIdentifiers.pop(7)
                            nodeIdentifiers.pop(6)
                            nodeIdentifiers.pop(4)
                            nodeIdentifiers.pop(2)
                            eft = eft7
                            scalefactors = [-1.0]

                    if eft is eftRegular:
                        element = mesh.createElement(elementIdentifier,
                                                     elementtemplateRegular)
                    else:
                        elementtemplateCustom.defineField(coordinates, -1, eft)
                        element = mesh.createElement(elementIdentifier,
                                                     elementtemplateCustom)
                    element.setNodesByIdentifier(eft, nodeIdentifiers)
                    if scalefactors:
                        element.setScaleFactors(eft, scalefactors)
                    elementIdentifier += 1
                    leftLungMeshGroup.addElement(element)
                    lungMeshGroup.addElement(element)

        # Apex annotation point
        idx = elementsCount1 * elementsCount2 * (
            elementsCount3 - 1) + elementsCount1 * (elementsCount2 // 2)
        element1 = mesh.findElementByIdentifier(idx)
        markerPoint = markerPoints.createNode(nodeIdentifier,
                                              markerTemplateInternal)
        nodeIdentifier += 1
        cache.setNode(markerPoint)
        markerName.assignString(cache, 'apex of left lung')
        markerLocation.assignMeshLocation(cache, element1, [1.0, 1.0, 1.0])

        return annotationGroups