Closed ebrahimebrahim closed 1 year ago
From @Leengit :
The contents of the p3 files are as follows. I will keep working at this, but if you already know ... what kind of mrmlNode should each be and how does one create a node of that type from the Python structure (rather than from a filename).
1127_LANDMARKS.p3 contains {'discrete': {'rightalarim': (133, 99, 237), 'leftalarim': (133, 96, 298), 'nosetip': (141, 56, 267), 'nasalspine': (136, 104, 268), 'columella': (132, 75, 267), 'carina': (0, 341, 252), 'baseoftongue': (137, 263, 280), 'epiglottistip': (136, 284, 274), 'subglottis': (91, 302, 267), 'tvc': (101, 294, 260), 'choana': (156, 214, 273)}, 'continuous': {'rightalarim': (133.29999999999973, 99.37013992433099, 237.3193730389399), 'leftalarim': (132.85399999999981, 96.051621440773, 298.2621213681027), 'nosetip': (141.34799999999973, 56.35792638569425, 267.3925249854944), 'nasalspine': (135.85099999999977, 103.92125098749622, 268.21846736362437), 'columella': (131.65399999999977, 74.96691384396992, 267.01326573023056), 'carina': (0.0009999999997489795, 340.81079581697264, 252.45392431982694), 'baseoftongue': (137.08699999999976, 263.02261556651064, 280.38847546586624), 'epiglottistip': (136.37099999999975, 284.06096925433707, 274.45728211271336), 'subglottis': (90.5759999999998, 301.74919952066676, 267.21343033717534), 'tvc': (101.49599999999975, 294.33257408439755, 259.9105826774852), 'choana': (156.08799999999974, 213.89800703053945, 272.9276031164828)}}
1127_AREAS.p3 contains {'areas': <class 'numpy.ndarray'>.shape=(200,), 'hydraulic_diameters': <class 'numpy.ndarray'>.shape=(200,)}
1127_CENTERLINE.p3 contains [<class 'numpy.ndarray'>.shape=(200, 3), <class 'numpy.ndarray'>.shape=(200, 3)]
1127_CENTERLINE.p3 contains [<class 'numpy.ndarray'>.shape=(200, 3), <class 'numpy.ndarray'>.shape=(200, 3)]
1127_AREAS.p3 contains {'areas': <class 'numpy.ndarray'>.shape=(200,), 'hydraulic_diameters': <class 'numpy.ndarray'>.shape=(200,)}
1127_AREAS.p3 contains <class 'numpy.ndarray'>.shape=(500,)
mean_landmarks.p3 contains {'nasalspine': 0.0, 'choana': 0.34061623, 'epiglottistip': 0.59999835, 'tvc': 0.73034596, 'subglottis': 0.75204575, 'carina': 1.0}
@Leengit In reply to the above here's what I know:
_LANDMARKS.p3
should be identical to the fcsv landmarks found in the landmarks/
directory. We would visualize this with fiducial nodes.processed_
version of those things, e.g. centerline
vs processed_centerline
or area
vs processed_area
. It looks like it comes down to this line of processing, which is this mysterious function that has a docstring claiming we should abandon it. So I wonder if we should include the processed_
things at all. @jiaoyining do you know?_CENTERLINE.p3
is, I'm assuming, a sequence of points along a curve. There are two arrays actually. Seems they are saved here. The first of the two arrays is probably the points along a curve, which we can represent in slicer as a curve node. The second is called normals
so I'm assuming it's a sequence of vectors along the curve.... is that correct @jiaoyining?_AREAS.p3
I suppose refers to the "cross-sectional area (A) and the hydraulic diameter (D)" talked about in this paper. Since there are 200 of each and 200 centerline points, I guess these are sampled along the centerline points and correspond to them. @jiaoyining is this correct?For programmatically creating and populating markup nodes I recommend looking over the markups section of the script repository. For example this could work for the _LANDMARKS.p3
:
markups_node = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode")
slicer.util.updateMarkupsControlPointsFromArray(markups_node, array)
where array
is an Nx3 array of points. But this doesn't add the labels, so maybe instead adding the points one by one with this approach will work better.
The centerline is perhaps best represented as a curve node, so something like what's shown here.
As for visualizing the list of centerline curve normal vectors, that may be a tough one. I think the markups module does not have this feature, but see some options in the comment here. Basically you either have to add glyphs way down at the vtk level, or you'd have to get extra creative with the transforms visualization feature.
How to visually depict the areas and diameters in _AREAS.p3
? These are just a bunch of numbers corresponding to the centerline points, so maybe they can be represented as a fiducial node with the centerline points being the pointlist and with the labels on those points being a text representation of the numerical area and diameter values. This is just an idea ... I think it would look pretty cool this way but I haven't thought it all the way through.
@Leengit In reply to the above here's what I know:
_LANDMARKS.p3
should be identical to the fcsv landmarks found in thelandmarks/
directory. We would visualize this with fiducial nodes.- I don't know what's the difference between things and the
processed_
version of those things, e.g.centerline
vsprocessed_centerline
orarea
vsprocessed_area
. It looks like it comes down to this line of processing, which is this mysterious function that has a docstring claiming we should abandon it. So I wonder if we should include theprocessed_
things at all. @jiaoyining do you know?
The processed things might be needed when there are off-line centerline points. But temporarily it is not used because the centerline estimation function woks fine for the current data we have. It should be fine if you don't include it now.
_CENTERLINE.p3
is, I'm assuming, a sequence of points along a curve. There are two arrays actually. Seems they are saved here. The first of the two arrays is probably the points along a curve, which we can represent in slicer as a curve node. The second is callednormals
so I'm assuming it's a sequence of vectors along the curve.... is that correct @jiaoyining?
Correct. 'normals' are the normal vectors of the curve on the points (first array).
_AREAS.p3
I suppose refers to the "cross-sectional area (A) and the hydraulic diameter (D)" talked about in this paper. Since there are 200 of each and 200 centerline points, I guess these are sampled along the centerline points and correspond to them. @jiaoyining is this correct?
Correct.
For programmatically creating and populating markup nodes I recommend looking over the markups section of the script repository. For example this could work for the
_LANDMARKS.p3
:markups_node = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode") slicer.util.updateMarkupsControlPointsFromArray(markups_node, array)
where
array
is an Nx3 array of points. But this doesn't add the labels, so maybe instead adding the points one by one with this approach will work better.The centerline is perhaps best represented as a curve node, so something like what's shown here.
As for visualizing the list of centerline curve normal vectors, that may be a tough one. I think the markups module does not have this feature, but see some options in the comment here. Basically you either have to add glyphs way down at the vtk level, or you'd have to get extra creative with the transforms visualization feature.
How to visually depict the areas and diameters in
_AREAS.p3
? These are just a bunch of numbers corresponding to the centerline points, so maybe they can be represented as a fiducial node with the centerline points being the pointlist and with the labels on those points being a text representation of the numerical area and diameter values. This is just an idea ... I think it would look pretty cool this way but I haven't thought it all the way through.
@jiaoyining Thanks for confirming!
Marc has just described for us what would be a useful visual here for quality checks:
We should show
The result would look something like the image in the right here:
@jiaoyining Hi Yining, I am working with the ./centerline/*_CENTERLINE.p3
file and I am having trouble figuring out the coordinate system of the points. They don't appear to be lined up with any images (not CT, nor the laplace solution image). Do you happen to know in what coordinates those points are supposed to be?
I figured it out. The centerline is in KJI coordinates, so a permutation is needed to get IJK and then a transformation from IJK to RAS can be done to align everything in Slicer's coordinate system. The IJK-to-RAS info can be taken from the input CT scan nrrd file.
Great! Sorry, I forgot to answer your question. There's reverse_coords function for landmarks and centerline in the code but I didn't know the exact name of the coordinate system.
The VPAWVisualize module should have functionality to visualize the p3 files generated by the pediatric_airway_atlas pipelines.
These would be files with the following name pattern:
UPDATE: See comment below for the suggested visualization to create here.