Created
March 30, 2020 22:12
-
-
Save lassoan/26e438c63e8249806958a408fb42c54a to your computer and use it in GitHub Desktop.
Create 3D Slicer subject hierarchy from BodyParts3D
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Source data can be obtained from http://lifesciencedb.jp/bp3d/ (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 | |
continue | |
shNode.SetItemParent(childShItemId,parentShItemId) | |
# 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: | |
continue | |
parentFmaId = fmaIdArray.GetValue(i) | |
parentShItemId = shNode.GetItemByUID("FMA", parentFmaId) | |
if not parentShItemId: | |
# this hierarchy is not found in the SH tree | |
continue | |
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