# Thresholding automation

**URL:** <https://discourse.slicer.org/t/thresholding-automation/31069>\
**Category:** Development\
**Created:** [August 9, 2023, 3:23pm UTC](https://discourse.slicer.org/t/thresholding-automation/31069 "2023-08-09T15:23:58Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![William](https://avatars.discourse-cdn.com/v4/letter/w/b19c9b/32.png) [@William](https://discourse.slicer.org/u/William)\
**Post date:** [August 9, 2023, 3:23pm UTC](https://discourse.slicer.org/t/thresholding-automation/31069/1 "2023-08-09T15:23:58Z")

</div>

**What I am trying to do:**

In 3d slicer I have several volumes loaded (they show in the data tab) for each of these I would like to automatically perform a threshold segmentation. Each should receive two separate threshold segmentations, the first at 8.00-8.00 and the second 20.00-20.00 (these correspond to the grayscale values of specific labels within the volume, nothing special about these values furthermore). I then want each to be saved, with a unique name that corresponds to the volume they were segmented from, as a compressed nifti i.e. " .nii.gz".

**What I have so far:**

```auto
1 # Threshold automation
2 # v1.0
3
4 # Get the list of loaded volumes from the Data module
5 loadedVolumes = slicer.util.getNodesByClass('vtkMRMLScalarVolumeNode')
6
7 # Define threshold ranges
8 threshold_ranges = [(8.00, 8.00), (20.00, 20.00)]
9
10 # Iterate through loaded volumes
11 for volume in loadedVolumes:
12 volume_name = volume.GetName()
13
14 # Create a directory to save the segmented results
15 output_dir = os.path.join("path/goes/here", "SegmentedVolumes")
16 os.makedirs(output_dir, exist_ok=True)
17
18 # Iterate through threshold ranges
19 for idx, (lower, upper) in enumerate(threshold_ranges):
20    
21 # Create segmentation node
22 segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
23 segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(volume)
24 segmentationNode.CreateDefaultDisplayNodes()
25 segmentationNode.GetSegmentation().AddEmptySegment(volume_name+"_"+str( idx))
26
27 # Create segment editor widget for effects
28 segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
29 segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
30 segmentEditorWidget.setSegmentationNode(segmentationNode)
31        
32 # Create a threshold effect for the segmentation
33 segmentEditorWidget.setActiveEffectByName("Threshold")
34 effect = segmentEditorWidget.activeEffect()
35 effect.setParameter("MinimumThreshold", lower)
36 effect.setParameter("MaximumThreshold", upper)
37 effect.self().onApply()
38
39 # Save the segmented volume as a .nii.gz file
40 output_file = os.path.join(output_dir, f'{volume_name}_Threshold_{idx}.nii.gz')
41 slicer.util.saveNode(segmentationNode, output_file)
42        
43 # Reset
44 slicer.mrmlScene.RemoveNode(segmentEditorNode)

```

**The error that I get:**

```auto
Traceback (most recent call last):
  File "<string>", line 35, in <module>
AttributeError: 'NoneType' object has no attribute 'setParameter'

```

I am not sure how to resolve this, I am clearly doing _something_ wrong, I am just puzzled as to what as, as far as I am aware, setParameter should work like this, implying that it isn’t the direct cause of this error.

Any help with this is appreciated, I’d rather not have to do this manually for hundreds of volumes 🫠

---

<div class="post-metadata">

**Author:** ![William](https://avatars.discourse-cdn.com/v4/letter/w/b19c9b/32.png) [@William](https://discourse.slicer.org/u/William)\
**Post date:** [August 9, 2023, 7:15pm UTC](https://discourse.slicer.org/t/thresholding-automation/31069/2 "2023-08-09T19:15:35Z")

</div>

I am on my commute home with a strong cup of coffee and I think I have identified the (several) problems. Once I am home I will try out what I think the probable solution is and report it back here.

So for anyone reading this thread, don’t use your time on my problem quite yet!

---

<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 9, 2023, 7:26pm UTC](https://discourse.slicer.org/t/thresholding-automation/31069/3 "2023-08-09T19:26:43Z")

</div>

If you have a label image (where each discrete value corresponds to a structure) then you can load the image directly as a segmentation.

You only need thresholding if you want to map a range of values (e.g., any values between 20 and 50) to a single segment.
