# Programatically use "Specify Geometry" (Python)

**URL:** <https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941>\
**Category:** Support\
**Tags:** segmentation\
**Created:** [July 27, 2021, 10:06am UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941 "2021-07-27T10:06:05Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alex\_Vergara](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/alex_vergara/32/15205_2.png) [@Alex\_Vergara](https://discourse.slicer.org/u/Alex_Vergara)\
**Post date:** [July 27, 2021, 10:06am UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/1 "2021-07-27T10:06:05Z")

</div>

Hello

I want to control programatically this option “Specify Geometry”

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/4/3/434d93e8bd11758b4afb46f337a8f9aea13ea480.png)

Basically reassign a new source volume to the segmentation  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/b/cbb55177f454b7b9e7c9dd87d6ca9bd3e54044d0.png)

I have tried to use

```python
            newsegmNode = shNode.GetItemDataNode(newsegmID)
            newsegmNode.SetReferenceImageGeometryParameterFromVolumeNode(
                DERSNode.data)
            newsegmNode.CreateDefaultDisplayNodes()
            newsegmNode.CreateBinaryLabelmapRepresentation()

```

But it just changes the Master Volume, not the source volume. I want the segmentation to be revoxelized in the new source volume.

Is there a way to achieve this?

Regards

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [July 27, 2021, 6:58pm UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/2 "2021-07-27T18:58:25Z")

</div>

If you already have a binary labelmap then setting a reference image geometry will have no effect.

One option is to create closed surface representation, delete the binary labelmap representation, then create binary labelmap representation (it will be generated from the closed surface representation, using the reference image geometry).

Another option is to resample the labelmap representation as it is done [here](https://github.com/Slicer/Slicer/blob/0094e9a35bd266cc8b0e677858dabce797c9928f/Modules/Loadable/Segmentations/Widgets/qMRMLSegmentationGeometryWidget.cxx#L495-L517). I’ll add this code as a method to the `vtkSlicerSegmentationGeometryLogic` class to make it more easily accessible from Python.

---

<div class="post-metadata">

**Author:** ![Alex\_Vergara](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/alex_vergara/32/15205_2.png) [@Alex\_Vergara](https://discourse.slicer.org/u/Alex_Vergara)\
**Post date:** [July 28, 2021, 8:27am UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/3 "2021-07-28T08:27:03Z")

</div>

OK, I have tried the first approach

```python
newsegmNode.CreateClosedSurfaceRepresentation()
newsegmNode.GetSegmentation().SetMasterRepresentationName(closedSurfaceReprName)
newsegmNode.SetReferenceImageGeometryParameterFromVolumeNode(DERSNode.data)
newsegmNode.CreateBinaryLabelmapRepresentation()
newsegmNode.GetSegmentation().SetMasterRepresentationName(binaryLabelmapReprName)

```

But it doesn’t worked, it still has the old voxelization, is there something wrong here in this code snippet?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [July 28, 2021, 12:36pm UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/4 "2021-07-28T12:36:35Z")

</div>

You missed the step of deleting the labelmap representation.

---

<div class="post-metadata">

**Author:** ![Alex\_Vergara](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/alex_vergara/32/15205_2.png) [@Alex\_Vergara](https://discourse.slicer.org/u/Alex_Vergara)\
**Post date:** [July 29, 2021, 8:33am UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/5 "2021-07-29T08:33:43Z")

</div>

I though that setting the master representation would delete any other representation. OK I have tried this

```python
newsegmNode.CreateClosedSurfaceRepresentation()
newsegmNode.GetSegmentation().SetMasterRepresentationName(closedSurfaceReprName)
newsegmNode.RemoveBinaryLabelmapRepresentation()
newsegmNode.SetReferenceImageGeometryParameterFromVolumeNode(DERSNode.data)
newsegmNode.CreateBinaryLabelmapRepresentation()
newsegmNode.GetSegmentation().SetMasterRepresentationName(binaryLabelmapReprName)

```

But still no success, I mean the master representation has changed, but  
doing with the code I get these volumes

| Segment | Number of voxels [voxels] | Volume [cm3] |
| --- | --- | --- |
| 1-Anterior | 758 | 65.3669 |
| 2-Lateral | 80 | 6.89889 |
| 3-Posterior | 220 | 18.9719 |
| 4-Inferior | 137 | 11.8143 |

Now doing it manually I get (the correct values)

| Segment | Number of voxels [voxels] | Volume [cm3] |
| --- | --- | --- |
| 1-Anterior | 788 | 67.954 |
| 2-Lateral | 113 | 9.74468 |
| 3-Posterior | 254 | 21.904 |
| 4-Inferior | 165 | 14.229 |

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 3, 2021, 4:31pm UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/6 "2021-08-03T16:31:21Z")

</div>

> [@Alex\_Vergara](#):
>
> Now doing it manually I get (the correct values)

What steps do you do manually and how?

---

<div class="post-metadata">

**Author:** ![Alex\_Vergara](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/alex_vergara/32/15205_2.png) [@Alex\_Vergara](https://discourse.slicer.org/u/Alex_Vergara)\
**Post date:** [August 4, 2021, 1:16pm UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/7 "2021-08-04T13:16:04Z")

</div>

click on specify geometry  
select a diferent node  
click OK

Usually the new node has been modified by registration so I need the segmentation to account for the grid deformation

---

<div class="post-metadata">

**Author:** ![Alex\_Vergara](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/alex_vergara/32/15205_2.png) [@Alex\_Vergara](https://discourse.slicer.org/u/Alex_Vergara)\
**Post date:** [August 12, 2021, 12:36pm UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/8 "2021-08-12T12:36:11Z")

</div>

OK, I will describe more the steps

take two (n\>1 actually but lets take 2 for simplicity) same patient CT, obtained at different days, segment a structure in one of them.  
Purpose: obtain the volume evolution in time of the structure.

- Option 1:  
Segment the same structure in the second CT.  
Advantage: Each segmentation has the geometry of the respective time CT  
Disadvantage: Not scalable for many time points and many structures

- Option 2:  
Segment in the first CT; Elastic transform the second; measure  
Advantage: Easily scalable  
Disadvantage: The volume does not change in time because the original segmentation is not recalculated for the geometry of the rest of the time points

- Option 3:  
Segment in the first CT; get the elastic transformation without modifying the second; get the inverse of that transformation and apply to the respective segmentation; measure  
Advantage: Easily scalable  
Disadvantage: The volume does not change in time because the original segmentation is not recalculated for the geometry of the rest of the time points

I tried to do options 2 and 3 without success, because the lines above doesn’t produce the same result as the option 1 (I can live with some % difference due to difference in segmentation, but not more than 20% as showed).  
Doing the master geometry change manually does the trick in both 2 and 3 as showed. So I need to reproduce this programatically.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 12, 2021, 6:09pm UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/9 "2021-08-12T18:09:48Z")

</div>

> [@Alex\_Vergara](#):
>
> Disadvantage: The volume does not change in time because the original segmentation is not recalculated for the geometry of the rest of the time points

Do you mean that you use Segment Statistics to compute the volume, but the transform is only taken into account if you harden it?

> [@Alex\_Vergara](#):
>
> Doing the master geometry change manually does the trick in both 2 and 3 as showed. So I need to reproduce this programatically.

In recent Slicer Preview Releases, you can use [vtkSlicerSegmentationGeometryLogic::ResampleLabelmapsInSegmentationNode](https://github.com/Slicer/Slicer/blob/1a692bf36e9c99c47661fbf5fdba0fd3c3e72f95/Modules/Loadable/Segmentations/Logic/vtkSlicerSegmentationGeometryLogic.h#L63) method to resample the labelmap. However, in recent Slicer Preview Releases, Segment Statistics module already hardens any transforms on a copy of the segmentation node, so the volume computation should be correct.

---

<div class="post-metadata">

**Author:** ![Edgaras\_Misiulis](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/edgaras_misiulis/32/16583_2.png) [@Edgaras\_Misiulis](https://discourse.slicer.org/u/Edgaras_Misiulis)\
**Post date:** [September 12, 2022, 7:47am UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/10 "2022-09-12T07:47:05Z")

</div>

Hello,

how to access the  
vtkSlicerSegmentationGeometryLogic  
and ResampleLabelmapsInSegmentationNode from python?

Thank you

---

<div class="post-metadata">

**Author:** ![Edgaras\_Misiulis](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/edgaras_misiulis/32/16583_2.png) [@Edgaras\_Misiulis](https://discourse.slicer.org/u/Edgaras_Misiulis)\
**Post date:** [September 12, 2022, 8:49am UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/11 "2022-09-12T08:49:52Z")

</div>

found a good example about it here:

> [@Change segmentation oversampling factor](https://discourse.slicer.org/t/change-segmentation-oversampling-factor/19025/5):
>
> @lassoan Thanks for your help again! The source code of vtkSlicerSegmentationGeometryLogic::ResampleLabelmapsInSegmentationNode is really helpful, and I finally completed this function correctly based on the source code. The issues aren’t technical issues, and since it works right now, there’s no needs to worry about upgrading. For those who are interested, here is my code. segmentIDs = vtk.vtkStringArray() segmentationNode.GetSegmentation().GetSegmentIDs(segmentIDs) #Create desired geometry…

---

<div class="post-metadata">

**Author:** ![AnabelVazquez](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@AnabelVazquez](https://discourse.slicer.org/u/AnabelVazquez)\
**Post date:** [June 24, 2024, 10:39am UTC](https://discourse.slicer.org/t/programatically-use-specify-geometry-python/18941/12 "2024-06-24T10:39:54Z")

</div>

Hi,

I have a dataset of 65 patients, each with a CT volume and its segmentation node (containing two labels: pancreas and lesion).

I’m preprocessing this dataset using Python.

I have cropped and resized the original CT images to the bounding box of the pancreas + lesion area. This cropping and resizing was performed using the Radiomics library with a BSpline interpolator.

Next, I’m trying to generate a segmentation scene with this new volume and its segmentation node. I call Slicer with a subprocess, load the segmentation node and the cropped volume in Slicer, and then associate the segmentation node with the cropped volume. This is to resize the segmentations to match the spacing of the cropped volume. I specify the geometry using the SetReferenceImageGeometryParameterFromVolumeNode(volume) command, which works well for most cases. However, for 2 cases, I encounter issues:

 ![imagen](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/8/3/83743ed001d1591a95c312cae2ddcd84027758a0.png)  
[Here I show an example of 3 cases preproceessed with python, reading the volume and segmentation node with sitk: 1 works correctly and the next 2 cases have a half spacing of the reference volume after appliying this:  
 ![Captura de pantalla 2024-06-24 123855](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/9/9/99bb5b460f0db3e0cabb773e542ce6deaa775c2b.png)  
]

When I open the Slicer scene and perform this process manually, I get the correct results.

Why might this be happening? Is there another command I need to include?

Thanks for your help.
