# SlicerQR Development

**URL:** <https://discourse.slicer.org/t/slicerqr-development/15954>\
**Category:** Development\
**Tags:** registration, build, segmentation, dicom, python\
**Created:** [February 11, 2021, 3:59pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954 "2021-02-11T15:59:22Z")\
**Posts on this page:** 20\
**Page:** 7

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [May 21, 2021, 7:09pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/164 "2021-05-21T19:09:48Z")

</div>

> [@lassoan](#):
>
> You can [choose a different rendering preset](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#show-volume-rendering-automatically-when-a-volume-is-loaded) and [set rendering technique to `slicer.vtkMRMLViewNode.Composite`](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#show-volume-rendering-using-maximum-intensity-projection)

@lasson, thanks you so much that worked! 🙂

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [May 26, 2021, 5:31pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/165 "2021-05-26T17:31:10Z")

</div>

@jcfr

Hello JC, I’m looking to remove slice planes rendering in the 3D view because I want to replace it with a surface render. How can I clear that out?

Thanks.

---

<div class="post-metadata">

**Author:** ![jamesobutler](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jamesobutler/32/7511_2.png) [@jamesobutler](https://discourse.slicer.org/u/jamesobutler)\
**Post date:** [May 26, 2021, 5:42pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/166 "2021-05-26T17:42:03Z")

</div>

@spycolyf I believe you are looking for the following example in the Slicer Script repository titled [Show slice views in 3D window](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#show-slice-views-in-3d-window). You had posted previously an image (seen below) which was detailing volume rendering being shown at the same time as Slice views showing in the 3D View.  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/0/5/05886d8642bbae3a5fb60581ba64a1eee0e6ff47.png).

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [June 8, 2021, 5:29pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/167 "2021-06-08T17:29:02Z")

</div>

@lassoan

Could you extract from 1/159 to 43/159 of this topic to a new topic, “Slicer Module Local Installation Footprint” (for want of a much better name)?

Thanks.

---

<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:** [June 8, 2021, 5:52pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/168 "2021-06-08T17:52:01Z")

</div>

Done. The new topic is here:

> [@Slicer custom application deployment to many computers](https://discourse.slicer.org/t/slicer-custom-application-deployment-to-many-computers/18019):
>
> @jcfr @pieper @lassoan @superlib Good Morning. I’m starting to think about how to deploy SlicerQR to 25,000 PCs across the Mayo Enterprise. After building the package, it consists of over 7000 files at a total size of over 700MB. It would be seriously frowned-upon to propose deploying it to 25,000 PCs. So, my question is: Would there be any disadvantages to placing the installation in 1 place on a file share and have the users execute SlicerQR from a folder there? Would there be conflicts with …

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [June 23, 2021, 8:05pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/169 "2021-06-23T20:05:58Z")

</div>

@jcfr @pieper @lassoan

Hello JC,

Whenever the user zooms and pans, and then pushes the EnableWLButton to window/level, the zoom and pan resets forcing the user to zoom and pan all over again. The code that causes this is…

`self._parameterNode.SetParameter("WindowLevelEnabled", "true" if self.ui.EnableWLButton.checked else "false")`

How do I use the WL widget without resetting the zoom and pan?

Thanks

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [June 23, 2021, 8:20pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/170 "2021-06-23T20:20:17Z")

</div>

This doesn’t happen in regular slicer so it must be something to do with your customizations not handling the end of the pan/zoom interactions.

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [June 23, 2021, 8:35pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/171 "2021-06-23T20:35:49Z")

</div>

Yes, that;s true. Slicer does not have this issue. However @jcfr implements many if the UI actions using the self.\_parameterNode.SetParameter function and each of them reset my views, Here are all of those features that use the self.\_parameterNode.SetParameter function, each resetting my views…

```auto
    self._parameterNode.SetParameter("ReferenceMarkersVisible", "true" if self.ui.ShowReferenceMarkersButton.checked else "false")
    self._parameterNode.SetParameter("SlabEnabled", "true" if slabEnabled else "false")
    self._parameterNode.SetParameter("SlabMode", QReadsLogic.slabModeToString(self.slabModeButtonGroup.checkedId()))
    self._parameterNode.SetParameter("SlabThicknessInMm", str(self.ui.SlabThicknessSliderWidget.value))
    self._parameterNode.SetParameter("InverseGray", "true" if self.ui.InverseGrayButton.checked else "false")
    self._parameterNode.SetParameter("Zoom", self.ui.ZoomComboBox.currentText)
    self._parameterNode.SetParameter("OrientationMarkerType",
      str(slicer.util.getNodesByClass('vtkMRMLAbstractViewNode')[0].GetOrientationMarkerType()))
    self._parameterNode.SetParameter("RulerVisible", "true" if self.ui.RulerVisibleButton.checked else "false")
    self._parameterNode.SetParameter("OrientationMarkerType", str(nextOrientationMarkerType))

```

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [June 23, 2021, 9:04pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/172 "2021-06-23T21:04:53Z")

</div>

> [@spycolyf](#):
>
> `SetParameter`

OK, might have something to do with this…

```auto
def setParameterNode(self, inputParameterNode):
    """
    Set and observe parameter node.
    Observation is needed because when the parameter node is changed then the GUI must be updated immediately.
    """
    if inputParameterNode:
      self.logic.setDefaultParameters(inputParameterNode)

    # Unobserve previously selected parameter node and add an observer to the newly selected.
    # Changes of parameter node are observed so that whenever parameters are changed by a script or any other module
    # those are reflected immediately in the GUI.
    if self._parameterNode is not None:
      self.removeObserver(self._parameterNode, vtk.vtkCommand.ModifiedEvent, self.updateGUIFromParameterNode)
    self._parameterNode = inputParameterNode
    if self._parameterNode is not None:
      self.addObserver(self._parameterNode, vtk.vtkCommand.ModifiedEvent, self.updateGUIFromParameterNode)

    # Initial GUI update
    self.updateGUIFromParameterNode()

```

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [June 23, 2021, 9:10pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/173 "2021-06-23T21:10:10Z")

</div>

@jcfr, is there a way to, for instance, enable he window/level widget without resetting the views?

Thanks

---

<div class="post-metadata">

**Author:** ![mau\_igna\_06](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mau_igna_06/32/9056_2.png) [@mau\_igna\_06](https://discourse.slicer.org/u/mau_igna_06)\
**Post date:** [June 23, 2021, 9:46pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/174 "2021-06-23T21:46:53Z")

</div>

Hi Doug, I looked at the code here:

> <https://github.com/KitwareMedical/SlicerQReads/blob/d40ce875aa49f396fc8fe2b578e477d6cd02894f/Modules/Scripted/QReads/QReads.py>

This two functions or calls may have something to do with the causes of view-reset you are looking for:

```auto
centerSlice
sliceLogic.FitSliceToAll()

```

I started looking for keywords in code as reset and found that. I also looked for ‘sliceLogic’ mentions as it may be related to the cause of your problem.

Hope this helps

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [June 24, 2021, 1:13am UTC](https://discourse.slicer.org/t/slicerqr-development/15954/175 "2021-06-24T01:13:29Z")

</div>

> [@spycolyf](#):
>
> `self._parameterNode`

OK, thanks @mau_igna_06, I’ll have a look at that. But since only self.\_parameterNode.SetParameter calls cause this slice view reset behavior, I’m suspecting it’s the setParameterNode function causing it.

Have a look…

Each of the following calls reset the views…

```auto
    self._parameterNode.SetParameter("ReferenceMarkersVisible", "true" if self.ui.ShowReferenceMarkersButton.checked else "false")
    self._parameterNode.SetParameter("SlabEnabled", "true" if slabEnabled else "false")
    self._parameterNode.SetParameter("SlabMode", QReadsLogic.slabModeToString(self.slabModeButtonGroup.checkedId()))
    self._parameterNode.SetParameter("SlabThicknessInMm", str(self.ui.SlabThicknessSliderWidget.value))
    self._parameterNode.SetParameter("InverseGray", "true" if self.ui.InverseGrayButton.checked else "false")
    self._parameterNode.SetParameter("Zoom", self.ui.ZoomComboBox.currentText)
    self._parameterNode.SetParameter("OrientationMarkerType",
      str(slicer.util.getNodesByClass('vtkMRMLAbstractViewNode')[0].GetOrientationMarkerType()))
    self._parameterNode.SetParameter("RulerVisible", "true" if self.ui.RulerVisibleButton.checked else "false")
    self._parameterNode.SetParameter("OrientationMarkerType", str(nextOrientationMarkerType))

```

Do you think the following function is the culprit? It does a removeObserver followed by an add observer

```auto
def setParameterNode(self, inputParameterNode):
    """
    Set and observe parameter node.
    Observation is needed because when the parameter node is changed then the GUI must be updated immediately.
    """
    if inputParameterNode:
      self.logic.setDefaultParameters(inputParameterNode)

    # Unobserve previously selected parameter node and add an observer to the newly selected.
    # Changes of parameter node are observed so that whenever parameters are changed by a script or any other module
    # those are reflected immediately in the GUI.
    if self._parameterNode is not None:
      self.removeObserver(self._parameterNode, vtk.vtkCommand.ModifiedEvent, self.updateGUIFromParameterNode)
    self._parameterNode = inputParameterNode
    if self._parameterNode is not None:
      self.addObserver(self._parameterNode, vtk.vtkCommand.ModifiedEvent, self.updateGUIFromParameterNode)

    # Initial GUI update
    self.updateGUIFromParameterNode()

```

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [July 12, 2021, 5:52pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/176 "2021-07-12T17:52:09Z")

</div>

@lassoan, @jcfr , @pieper

Good afternoon everyone,

All of this time I’ve been focused on optimizing everything for CT. Now that that’s all prefect, MR and PET images have issues. For both PET and MR, the initial W/L’s are messed up and I can’t adjust it manually. They both look like this…

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/f/c/fc6c90836fc69040c07038689c3771530bfa1581.jpeg)

This looks like overflow or underflow of some sort. I was expecting the W/L to be initially read from the header.

Any hint as I begin to investigate the Python code?

Thanks

---

<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 12, 2021, 6:01pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/177 "2021-07-12T18:01:03Z")

</div>

In fact, the window/level is from the DICOM header - from the first slice. However, for whole-body images the first slice is often almost empty, so it could be better to use the center slice instead - see:

> <https://github.com/Slicer/Slicer/issues/5140>
>
> When loading a DICOM series, default window/level is taken from the first slice.… In some cases, window/level is different for each slice, and since first slice usually does not contain typical anatomy, its window/level may not be ideal for the object of interest. Instead, it could be better to use the center slice's window/level values.
> 
> See more information here: https://discourse.slicer.org/t/recent-improvements-in-window-level-management/7284/9
> 
> Slicer version: Slicer-4.11.0-2020-08-26

The transparency for low values is a feature of the colormap. You should be able to change the colormap and/or adjust the window/level. If you show multiple series (e.g., PET and CT) then left-click-and-drag may adjust the other volume that you expect.

We have improved PET/CT default colormap selection - see [these commits](https://github.com/Slicer/Slicer/search?q=PET&type=commits). I would recommend to try PET/CT loading in recent Slicer Preview Release and if you like the changes then update your custom application to use a recent master version of Slicer and use the DICOM module for load DICOM data.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [July 12, 2021, 6:20pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/178 "2021-07-12T18:20:28Z")

</div>

You should also have a look at the PET related extensions (just type PET in the extension search box) and in particular the dicom plugin:

> **[QIICR/Slicer-PETDICOMExtension](https://github.com/QIICR/Slicer-PETDICOMExtension)**
>
> 3D Slicer extension containing tools for importing DICOM PET series - QIICR/Slicer-PETDICOMExtension

[https://www.slicer.org/wiki/Documentation/Nightly/Extensions/PET-IndiC](https://www.slicer.org/wiki/Documentation/Nightly/Extensions/PET-IndiC)

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [July 12, 2021, 7:13pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/179 "2021-07-12T19:13:04Z")

</div>

> [@spycolyf](#):
>
> I was expecting the W/L to be initially read from the header.
> 
> Any hint as I begin to investigate the Python code?

By default, the windows level is automatically adjusted:

> <https://github.com/KitwareMedical/SlicerQReads/blob/d40ce875aa49f396fc8fe2b578e477d6cd02894f/Modules/Scripted/QReads/QReads.py#L371-L372>

Otherwise, here is the relevant function called when brightness/contract are updated or is one of the preset is selected:

> <https://github.com/KitwareMedical/SlicerQReads/blob/d40ce875aa49f396fc8fe2b578e477d6cd02894f/Modules/Scripted/QReads/QReads.py#L579-L593>

Here are the window level presets:

> <https://github.com/KitwareMedical/SlicerQReads/blob/d40ce875aa49f396fc8fe2b578e477d6cd02894f/Modules/Scripted/QReads/QReads.py#L457-L463>

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [July 12, 2021, 7:17pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/180 "2021-07-12T19:17:08Z")

</div>

To ensure the community can help you, you may also consider updating the code base [KitwareMedical/SlicerQReads](https://github.com/KitwareMedical/SlicerQReads) to include your recent updates (e.g Volume Cropper, …) or sharing a link to the relevant fork including the changes.

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [July 12, 2021, 7:24pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/181 "2021-07-12T19:24:05Z")

</div>

@lassoan - FYI: I’m on Slicer version 4.13. Also, for those particular images the first W/L setting is center=8438.388323078, width=16876.776646156 which is comparable to the middle slices.

So it does appear that it’s reading it from the header.

@pieper - 1) It does the same thing with MR series, Is the PET extension necessary for getting the PET W/L fixed?

---

<div class="post-metadata">

**Author:** ![spycolyf](https://avatars.discourse-cdn.com/v4/letter/s/f17d59/32.png) [@spycolyf](https://discourse.slicer.org/u/spycolyf)\
**Post date:** [July 12, 2021, 7:34pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/182 "2021-07-12T19:34:25Z")

</div>

> [@jcfr](#):
>
> To ensure the community can help you, you may also consider updating the code base [KitwareMedical/SlicerQReads](https://github.com/KitwareMedical/SlicerQReads) to include your recent updates (e.g Volume Cropper, …) or sharing a link to the relevant fork including the changes.

JC, yes I wish I could, I’ll have to clear that with management. I’ll try to get up the courage to ask. They do not have the appetite to hear about more issues as this “should have been released a long time ago.” But I hear you loud and clear because I could definitely use the help from the slicer community and this may happen after I get this used and loved by the physician users. Without this help, it’s a real struggle. But, these (w/l) are the kinds of issues that will turn them off and frustrate them completely on first use.

But, to reiterate, I’d love to do what you say, so we are in the same boat. I’ll keep trying to encourage management.

Thanks

---

<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 12, 2021, 7:43pm UTC](https://discourse.slicer.org/t/slicerqr-development/15954/183 "2021-07-12T19:43:15Z")

</div>

Probably the only issue is that you use a color table that maps very bright voxels to be transparent. There several beautiful PET color tables (those that are specified in the DICOM standard and a few others). Is there a particular reason you don’t use those? Which color table do you use?

[Previous page](https://discourse.slicer.org/t/slicerqr-development/15954.md?page=6)

[Next page](https://discourse.slicer.org/t/slicerqr-development/15954.md?page=8)
