Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Create 3D Slicer subject hierarchy from BodyParts3D
# Source data can be obtained from (tested with partof_BP3D_4.0_obj_99)
# These input file must be loaded into the scene:
# - partof_inclusion_relation_list.txt and partof_element_parts.txt (loaded as Table nodes)
# - OBJ files
shNode = slicer.mrmlScene.GetSubjectHierarchyNode()
sceneItemID = shNode.GetSceneItemID()
def getItemParentsFmaIds(shNode, itemShItemId):
existingParentShItemId = shNode.GetItemParent(itemShItemId)
existingParentFmaIds = []
while existingParentShItemId != sceneItemID:
existingParentFmaIds.append(shNode.GetItemUID(existingParentShItemId, "FMA"))
existingParentShItemId = shNode.GetItemParent(existingParentShItemId)
return existingParentFmaIds
# Create partof hierarchy
inclusionListTable = getNode('partof_inclusion_relation_list').GetTable()
parentIdArray = inclusionListTable.GetColumnByName('parent id')
parentNameArray = inclusionListTable.GetColumnByName('parent name')
childIdArray = inclusionListTable.GetColumnByName('child id')
childNameArray = inclusionListTable.GetColumnByName('child name')
for i in range(inclusionListTable.GetNumberOfRows()):
parentFmaId = parentIdArray.GetValue(i)
parentShItemId = shNode.GetItemByUID("FMA", parentFmaId)
if not parentShItemId:
parentShItemId = shNode.CreateFolderItem(sceneItemID, parentNameArray.GetValue(i))
shNode.SetItemUID(parentShItemId, "FMA", parentFmaId)
childFmaId = childIdArray.GetValue(i)
childShItemId = shNode.GetItemByUID("FMA", childFmaId)
if not childShItemId:
childShItemId = shNode.CreateFolderItem(sceneItemID, childNameArray.GetValue(i))
shNode.SetItemUID(childShItemId, "FMA", childFmaId)
existingParentFmaIds = getItemParentsFmaIds(shNode, childShItemId)
if parentFmaId in existingParentFmaIds:
# this parent is already a parent of the current item
# Update part list with names and FMA IDs
partsListTable = getNode('partof_element_parts').GetTable()
fmaIdArray = partsListTable.GetColumnByName('concept id')
filenameArray = partsListTable.GetColumnByName('element file id')
for i in range(partsListTable.GetNumberOfRows()):
partNode = slicer.mrmlScene.GetFirstNodeByName(filenameArray.GetValue(i))
if not partNode:
parentFmaId = fmaIdArray.GetValue(i)
parentShItemId = shNode.GetItemByUID("FMA", parentFmaId)
if not parentShItemId:
# this hierarchy is not found in the SH tree
itemShItemId = shNode.GetItemByDataNode(partNode)
existingParentFmaIds = getItemParentsFmaIds(shNode, itemShItemId)
newParentFmaIds = getItemParentsFmaIds(shNode, parentShItemId)
if len(newParentFmaIds)>len(existingParentFmaIds):
# New parent is more specific than the current (parent has more nesting levels)
shNode.SetItemParent(itemShItemId, parentShItemId)
# systemFmaIds = ['FMA7152', 'FMA7157', 'FMA7158', 'FMA7159', 'FMA7161', 'FMA7482', 'FMA9668', 'FMA7160', 'FMA72979']
# nonSystemFmaIds = ['FMA7154','FMA7184','FMA7185','FMA7186','FMA7187','FMA7188','FMA74657','FMA79063','FMA228642','FMA231424']
# for fmaId in systemFmaIds:
# shNode.RemoveItem(shNode.GetItemByUID("FMA", fmaId))
# Limitation: this terminology is not a tree, therefore it is not possible to build a tree without loss of data or duplication of data
# Example: some structures are not part of any "system"
# FMA20394 human body FJ1294
# FMA7154 head FJ1294
# FMA24728 face FJ1294
# FMA54450 left eye FJ1294
# FMA49051 left inferior oblique FJ1294
# Example: some structures are part of multiple non-system branches
# FMA20394 human body [FJ2810]
# FMA72979 integumentary system [FJ2810]
# FMA74657 integument [FJ2810]
# FMA7163 skin [FJ2810]
# Example: some structures are part of multiple system branches
# FMA20394 human body FJ1737
# FMA7157 nervous system FJ1737
# FMA55675 neuraxis FJ1737
# FMA7647 spinal cord FJ1737
# FMA78497 central canal of spinal cord FJ1737
# FMA242675 ventricular system of neuraxis FJ1737
# FMA75007 cavity of neuraxis FJ1737
# FMA20394 human body FJ2593
# FMA7152 alimentary system FJ2593
# FMA71132 gastrointestinal tract FJ2593
# FMA7200 small intestine FJ2593
# FMA7208 ileum FJ2593
# FMA14966 distal part of ileum FJ2593
# FMA49179 lower gastrointestinal tract FJ2593
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment