In [1]:
import itk

from itkwidgets import view

In [2]:
PixelType = itk.F
Dimension = 3
    
# Read tre file
tubesReader = itk.SpatialObjectReader[Dimension].New()
tubesReader.SetFileName("data/Normal071-VascularNetwork.tre")
tubesReader.Update()
tubes = tubesReader.GetGroup()

# Read mra image
mraReader = itk.ImageFileReader[itk.Image[PixelType, Dimension]].New()
mraReader.SetFileName("data/Normal071-MRA.mha")
mraReader.Update()
mra = mraReader.GetOutput()

In [3]:
print("Number of objects = ", tubes.GetNumberOfChildren())

sobj = tubes.GetChildren(0, "VesselTube")
baseSO = sobj[0]

print("Children are all maintained as base spatial object types - not as tubes, groups, landmarks, etc.")
print("  You can print info about the object:")
print(baseSO)
print("  But you cannot call member functions in derived classes (e.g., TubeSO member functions):")
print(baseSO.GetNumberOfPoints())   # This command fails


Number of objects =  265
Children are all maintained as base spatial object types - not as tubes, groups, landmarks, etc.
  You can print info about the object:
TubeSpatialObject (000001DF91ADDDD0)
  TubeSpatialObject(000001DF91ADDDD0)
  End Type : 1
  Parent Point : -1
  Root : 1
  PointBasedSpatialObject(000001DF91ADDDD0)
  Number of points: 4330
  RTTI typeinfo:   class itk::TubeSpatialObject<3,class itk::TubeSpatialObjectPoint<3> >
  Reference Count: 3
  Modified Time: 4477
  Debug: Off
  Object Name: 
  Observers: 
    none
  Source: (none)
  Source output name: (none)
  Release Data: Off
  Data Released: False
  Global Release Data: Off
  PipelineMTime: 0
  UpdateMTime: 0
  RealTimeStamp: 0 seconds 
  Id:0
  TypeName:VesselTubeSpatialObject
  ParentId:265
  Parent:000001DF962CFB10
  LargestPossibleRegion:ImageRegion (000001DF91ADDF10)
  Dimension: 3
  Index: [0, 0, 0]
  Size: [0, 0, 0]

  RequestedRegion:ImageRegion (000001DF91ADDF48)
  Dimension: 3
  Index: [0, 0, 0]
  Size: [0, 0, 0]

  BufferedRegion:ImageRegion (000001DF91ADDF80)
  Dimension: 3
  Index: [0, 0, 0]
  Size: [0, 0, 0]

  My Bounding Box In Object Space:
  BoundingBox (000001DF8FBAE030)
  RTTI typeinfo:   class itk::BoundingBox<unsigned __int64,3,double,class itk::VectorContainer<unsigned __int64,class itk::Point<double,3> > >
  Reference Count: 2
  Modified Time: 26
  Debug: Off
  Object Name: 
  Observers: 
    none
  Bounding Box: ( 0,0 0,0 0,0  )

  My Bounding Box In World Space:
  BoundingBox (000001DF8FBAE0D0)
  RTTI typeinfo:   class itk::BoundingBox<unsigned __int64,3,double,class itk::VectorContainer<unsigned __int64,class itk::Point<double,3> > >
  Reference Count: 2
  Modified Time: 27
  Debug: Off
  Object Name: 
  Observers: 
    none
  Bounding Box: ( 0,0 0,0 0,0  )

  Family Bounding Box In Object Space:
  BoundingBox (000001DF8FBAE210)
  RTTI typeinfo:   class itk::BoundingBox<unsigned __int64,3,double,class itk::VectorContainer<unsigned __int64,class itk::Point<double,3> > >
  Reference Count: 2
  Modified Time: 28
  Debug: Off
  Object Name: 
  Observers: 
    none
  Bounding Box: ( 0,0 0,0 0,0  )

  Family Bounding Box In World Space:
  BoundingBox (000001DF8FBAECB0)
  RTTI typeinfo:   class itk::BoundingBox<unsigned __int64,3,double,class itk::VectorContainer<unsigned __int64,class itk::Point<double,3> > >
  Reference Count: 2
  Modified Time: 29
  Debug: Off
  Object Name: 
  Observers: 
    none
  Bounding Box: ( 0,0 0,0 0,0  )

  Object to World Transform: AffineTransform (000001DF8BD8AAA0)
  RTTI typeinfo:   class itk::AffineTransform<double,3>
  Reference Count: 2
  Modified Time: 4475
  Debug: Off
  Object Name: 
  Observers: 
    none
  Matrix: 
    1 0 0 
    0 1 0 
    0 0 1 
  Offset: [0, 0, 0]
  Center: [0, 0, 0]
  Translation: [0, 0, 0]
  Inverse: 
    1 0 0 
    0 1 0 
    0 0 1 
  Singular: 0

  Object to World Transform Inverse: AffineTransform (000001DF8BCFF4A0)
  RTTI typeinfo:   class itk::AffineTransform<double,3>
  Reference Count: 2
  Modified Time: 4476
  Debug: Off
  Object Name: 
  Observers: 
    none
  Matrix: 
    1 0 0 
    0 1 0 
    0 0 1 
  Offset: [-0, -0, -0]
  Center: [0, 0, 0]
  Translation: [0, 0, 0]
  Inverse: 
    1 0 0 
    0 1 0 
    0 0 1 
  Singular: 0

  Object to Parent Transform: AffineTransform (000001DF90ED99A0)
  RTTI typeinfo:   class itk::AffineTransform<double,3>
  Reference Count: 2
  Modified Time: 4469
  Debug: Off
  Object Name: 
  Observers: 
    none
  Matrix: 
    1 0 0 
    0 1 0 
    0 0 1 
  Offset: [0, 0, 0]
  Center: [0, 0, 0]
  Translation: [0, 0, 0]
  Inverse: 
    1 0 0 
    0 1 0 
    0 0 1 
  Singular: 0

  Object to Parent Transform Inverse: AffineTransform (000001DF8DD54C10)
  RTTI typeinfo:   class itk::AffineTransform<double,3>
  Reference Count: 2
  Modified Time: 4470
  Debug: Off
  Object Name: 
  Observers: 
    none
  Matrix: 
    1 0 0 
    0 1 0 
    0 0 1 
  Offset: [-0, -0, -0]
  Center: [0, 0, 0]
  Translation: [0, 0, 0]
  Inverse: 
    1 0 0 
    0 1 0 
    0 0 1 
  Singular: 0



  Object properties: 
  ChildrenList:0
  DefaultInsideValue:1
  DefaultOutsideValue:0

  But you cannot call member functions in derived classes (e.g., TubeSO member functions):
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-933be521a384> in <module>
      8 print(baseSO)
      9 print("  But you cannot call member functions in derived classes (e.g., TubeSO member functions):")
---> 10 print(baseSO.GetNumberOfPoints())   # This command fails

AttributeError: 'itkSpatialObject3' object has no attribute 'GetNumberOfPoints'

In [4]:
print("One option is to downcast each object in the children list, as needed")

import itkExtras

baseSOTyped = itkExtras.down_cast(baseSO)

print("  Now we can call member functions of the derived class")
print(baseSOTyped.GetNumberOfPoints())   # This command succeeds on the down-casted variable


One option is to downcast each object in the children list, as needed
  Now we can call member functions of the derived class
4330

In [5]:
print("Use CastSpatialObject class to convert base spatial objects of a particular type...")
castSO = itk.CastSpatialObjectFilter[3].New()
castSO.SetInput(tubes)
tubesSO = castSO.GetTubes()


Use CastSpatialObject class to convert base spatial objects of a particular type...

In [6]:
print("Then you can access its member functions...")
tube = tubesSO[0]
tube.GetPoints()[1].GetPositionInObjectSpace()


Then you can access its member functions...
Out[6]:
itkPointD3 ([121.292, 94.4135, 0.313261])

In [7]:
p = list(map(lambda x: tube.GetPoint(x).GetPositionInObjectSpace(), range(tube.GetNumberOfPoints())))
i = list(map(lambda x: mra.TransformPhysicalPointToIndex( x ), p ))

In [ ]:
for x in i:
    mra.SetPixel(x, 10000)
    
view(mra)

In [ ]: