Adding a field to JSON file from extension

I would like to implement a way to distinguish anatomical landmarks from constructed landmarks such as semi-landmarks generated by curve resampling or from the modules in our SlicerMorph extension. Some methods we use outside of Slicer handle analysis of these two types of points differently so it’s helpful to have this property saved along with the points themselves.

What would be the best way to go about this? I don’t see a simple way to do this from the extension, so maybe an extra point property/JSON field would be required? It would be helpful for our extension, but may be more broadly useful since analyzing semi-landmarks is fairly common.

@muratmaga @pieper @lassoan

@cpinter has implemented this for SlicerHeart recently. You can store any number of additional properties as static “measurements”.

For example:

markupsNode = getNode('F')

# Create a VTK array that contains the custom data
landmarkTypesArray = vtk.vtkDoubleArray()
for controlPointIndex in range(markupsNode.GetNumberOfControlPoints()):
    landmarkTypesArray.InsertNextValue(1 if controlPointIndex % 3 else 0)

# Add the landmark array as static measurement
landmarkTypes = slicer.vtkMRMLStaticMeasurement()
landmarkTypes.SetName('LandmarkType2')
landmarkTypes.SetUnits('')
landmarkTypes.SetPrintFormat("")
landmarkTypes.SetControlPointValues(landmarkTypesArray)
markupsNode.AddMeasurement(landmarkTypes)

These measurements can be used in other measurements and can be used for coloring curves. It could be used for coloring control points; and could be displayed in the control points table.

Measurement results are stored in the json file in measurements section like this:

{
...
    "markups": [
        {
            "type": "Fiducial",
            "coordinateSystem": "LPS",
            "locked": false,
            "labelFormat": "%N-%d",
            "controlPoints": [
                {
                    "id": "1",
                    "label": "F-1",
                    "description": "",
                    "associatedNodeID": "",
                    "position": [-72.46376811594203, 10.869565217391298, 0.0],
                    "orientation": [-1.0, -0.0, -0.0, -0.0, -1.0, -0.0, 0.0, 0.0, 1.0],
                    "selected": true,
                    "locked": false,
                    "visibility": true,
                    "positionStatus": "defined"
                },
                {
                    "id": "2",
                    "label": "F-2",
                    "description": "",
                    "associatedNodeID": "",
                    "position": [-29.89130434782608, -44.384057971014517, 0.0],
                    "orientation": [-1.0, -0.0, -0.0, -0.0, -1.0, -0.0, 0.0, 0.0, 1.0],
                    "selected": true,
                    "locked": false,
                    "visibility": true,
                    "positionStatus": "defined"
                },
...
            ],
            "measurements": [
                {
                    "name": "LandmarkType",
                    "enabled": true,
                    "value": 0.0,
                    "printFormat": "%.0f",
                    "controlPointValues": [
                        0.0,
                        1.0,
                        1.0,
                        0.0,
                        1.0,
                        1.0,
                        0.0,
                        1.0,
                        1.0
                    ]
                }
            ],
            "display": {
                ...
    ]
}

When this json file is manually edited then this data organization makes it easy to add/remove these additional properties, but it is difficult to add/remove points or find values of custom properties.

This is all very new, so we can still modify anything (change API, file format, add convenience functions, etc.) as needed.

Thanks @lassoan, I think this should work for what we need!

The API might change in the near future, depending on how well it all works for us and what feedback we get from other developers. So, let us know if you have any feedback (either that you like it is or you would like some improvements).

1 Like