# Change data probe to view MIP HU

**URL:** https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516
**Category:** Feature requests
**Created:** [October 24, 2018, 1:16am UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516 "2018-10-24T01:16:04Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![mag](https://avatars.discourse-cdn.com/v4/letter/m/58f4c7/32.png) [@mag](https://discourse.slicer.org/u/mag)
#### Post date: [October 24, 2018, 1:16am UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/1 "2018-10-24T01:16:04Z")

</div>

Hi, I’m looking at very small features on CTA scans and there are 2 things I’d like data probe to do but it doesn’t and I’m not sure how to modify it to get the behaviour I want.

1. When I am in one of the slice viewers, e.g. the red one, and scroll up and down with the mouse wheel or the arrows in a fixed point, data probe does not update the HU nor the position. I have to move the mouse in the viewer for data probe to update. Is there a way to make it update even when the mouse position has not changed but the slice has?

2. I am visualizing MIP in the slice views with this [code](https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Thick_slab_reconstruction_and_maximum.2Fminimum_intensity_volume_projections), however when I move the mouse around one of the slice viewer, the scalar value that I see in data probe in the left bottom corner is still the HU of the single slice, not the one of the MIP. Is there a way to change this behaviour? (I have attached an example in case it’s not clear: in the screenshot I am looking at a 5 mm MIP. The mouse arrow is not captured but I was pointing at the red slice exactly on the intersection of the yellow and green axes. I’d like data probe to show me the HU of the MIP view, so something around 300, but it shows me the HU of the single slice which is 7)

Thank you for any help,

Marta

---

<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: [October 31, 2018, 3:42am UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/2 "2018-10-31T03:42:08Z")

</div>

Hi Marta,

Sorry for not getting a response sooner!

Regarding 1) what you are describing is behavior that is like the same as [issue 3262](https://issues.slicer.org/view.php?id=3262) in Slicer’s issue tracker. I have added a note to that issue specifying with your experience as a way to increase its likelihood of it getting fixed in the future.

Regarding 2) I’m not exactly sure what is going on there. I would point you to using the [SimpleFilters](https://www.slicer.org/wiki/Documentation/4.10/Modules/SimpleFilters) module which makes it easy to generate projections and use other volume filters. You would set the output volume to be a new volume, and DataProbe should provide you updated results when you move your mouse position over this output volume.

---

<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: [October 31, 2018, 4:52am UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/3 "2018-10-31T04:52:38Z")

</div>

> [@mag](#):
>
> HU of the single slice, not the one of the MIP. Is there a way to change this behaviour?

Since thick slice feature is not exposed on the GUI, we most likely not update the data probe’s behavior for now. However, you can print pixel value of the resliced image by copy-pasting this code snippet into the Python interactor:

```auto
def onMouseMoved(observer,eventid):  
  xyz = [0,0,0]
  crosshairNode.GetCursorPositionXYZ(xyz)
  pixelValue = reslice.GetOutput().GetScalarComponentAsDouble(int(xyz[0]),int(xyz[1]), int(xyz[2]), 0)
  print("{0} -> {1}".format(xyz, pixelValue))

sliceNode = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeRed')
appLogic = slicer.app.applicationLogic()
sliceLogic = appLogic.GetSliceLogic(sliceNode)
sliceLayerLogic = sliceLogic.GetBackgroundLayer()
reslice = sliceLayerLogic.GetReslice()

crosshairNode=slicer.util.getNode('Crosshair') 
crosshairNode.AddObserver(slicer.vtkMRMLCrosshairNode.CursorPositionModifiedEvent, onMouseMoved)

```

Why do you need the MIP value?

---

<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: [November 1, 2018, 2:17pm UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/4 "2018-11-01T14:17:17Z")

</div>

@mag To provide you with an update, the issue described in 1) I can now confirm is solved thanks to a fix by @lassoan. You can download and install today’s nightly build and it will have that fix.

---

<div class="post-metadata">

### Author: ![mag](https://avatars.discourse-cdn.com/v4/letter/m/58f4c7/32.png) [@mag](https://discourse.slicer.org/u/mag)
#### Post date: [November 1, 2018, 7:53pm UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/5 "2018-11-01T19:53:19Z")

</div>

> [@jamesobutler](#):
>
> issue 3262

That’s awesome, thanks so much!

---

<div class="post-metadata">

### Author: ![mag](https://avatars.discourse-cdn.com/v4/letter/m/58f4c7/32.png) [@mag](https://discourse.slicer.org/u/mag)
#### Post date: [November 1, 2018, 8:04pm UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/6 "2018-11-01T20:04:36Z")

</div>

I am extending an existing study and need to determine the location of maximum contrast enhancement in some vascular segments. The way the previous research fellow did it was to look at 5 mm MIP to find the maximum HU on the axial view, then refine the location by scrolling up and down single slices, so I am trying to follow the exact same steps even if with a different software. Once I have the point of interest I create a small spherical segment and get the average HU at that position.

---

<div class="post-metadata">

### Author: ![mag](https://avatars.discourse-cdn.com/v4/letter/m/58f4c7/32.png) [@mag](https://discourse.slicer.org/u/mag)
#### Post date: [January 7, 2019, 10:16pm UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/7 "2019-01-07T22:16:25Z")

</div>

Hi,

I have come back to this problem after some time and I’d have some more questions if anybody has time to help.  
Last time when I had to look at the MIPs I used to copy the code that Andras posted into the Python interactor whenever I needed it. However I would like to have it in my script so that when I click my custom button to display the MIP this code is automatically executed. Also, I’d like to add some code such that when I click my custom button to return to the non-MIP visualization, Slicer stops printing the mouse position/HU in the interactor.

I already had the buttons to show/disable MIPs. So I tried to just add the onMouseMoved function to print mouse position/HU, but I get an error about the number of arguments every time I move the mouse (see screenshot) and I don’t understand why.

In the widget code I have:

[…]

```
    self.showMIPRedButton = qt.QPushButton("MIP Red")
    self.showMIPRedButton.toolTip = "Show MIP in red viewer"
    self.showMIPRedButton.enabled = True
    self.parametersFormLayout.addRow(self.showMIPRedButton)

    self.undoMIPButton = qt.QPushButton("Default view")
    self.undoMIPButton.toolTip = "Reset view to default mode"
    self.undoMIPButton.enabled = True
    self.layout.addWidget(self.undoMIPButton)

    self.showMIPRedButton.connect('clicked(bool)', self.onShowMIPRedButton)
    self.undoMIPButton.connect('clicked(bool)', self.onUndoMIPButton)

def onShowMIPRedButton(self):
    logic = probeMIPLogic()
    logic.showMIPRed(self.inputSelector.currentNode())

def onUndoMIPButton(self):
    logic = probeMIPLogic()
    logic.MIPreset()

```

And then in the logic code:

```
    # ======== FROM ANDRAS POST ======== #
def onMouseMoved(observer,eventid):
    xyz = [0,0,0]
    crosshairNode.GetCursorPositionXYZ(xyz)
    pixelValue = reslice.GetOutput().GetScalarComponentAsDouble(int(xyz[0]),int(xyz[1]), int(xyz[2]), 0)
    print("{0} -> {1}".format(xyz, pixelValue))
    # ==================================== #

def showMIPRed(self, inputVolume):
    """ Show maximum intensity projection in Red slice viewer. Does not change scalar volume, only modifies
    viewing settings.
        """
    sliceNode = None
    sliceLogic = None
    vtkMRMLSliceNode = 'vtkMRMLSliceNodeRed'
    sliceNode = slicer.mrmlScene.GetNodeByID(vtkMRMLSliceNode)
    if sliceNode:
        appLogic = slicer.app.applicationLogic()
    if appLogic:
        sliceLogic = appLogic.GetSliceLogic(sliceNode)
    if not sliceNode or not sliceLogic:
        print "Err"
        return
    sliceLayerLogic = sliceLogic.GetBackgroundLayer()
    self.reslice = sliceLayerLogic.GetReslice()
    self.reslice.SetSlabModeToMax()
    self.reslice.SetSlabNumberOfSlices(20)
    self.reslice.SetSlabSliceSpacingFraction(1)
    sliceNode.Modified()

    # ======== FROM ANDRAS POST ======== #
    crosshairNode=slicer.util.getNode('Crosshair')
    crosshairNode.AddObserver(slicer.vtkMRMLCrosshairNode.CursorPositionModifiedEvent, self.onMouseMoved)
    # =================================== #
    return

def MIPreset(self):
    """ Reset slice viewers to default setting (no MIP).
        """
    print "Disabling MIP in the slice viewers"
    sliceNode = None
    sliceLogic = None
    for slice_color in ["Green", "Red", "Yellow"]:
        vtkMRMLSliceNode = 'vtkMRMLSliceNode' + slice_color
        sliceNode = slicer.mrmlScene.GetNodeByID(vtkMRMLSliceNode)
        if sliceNode:
            appLogic = slicer.app.applicationLogic()
        if appLogic:
            sliceLogic = appLogic.GetSliceLogic(sliceNode)
        if not sliceNode or not sliceLogic:
            print "Err"
            return
        sliceLayerLogic = sliceLogic.GetBackgroundLayer()
        reslice = sliceLayerLogic.GetReslice()
        reslice.SetSlabModeToMax()
        reslice.SetSlabNumberOfSlices(1)
        reslice.SetSlabSliceSpacingFraction(1)
        sliceNode.Modified()
    return

```

Thanks in advance for any help!

 ![screenshot](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/0/f/0f36ca4afaee0bfe6fa95e4cba98863b08086172.png)

---

<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: [January 7, 2019, 11:46pm UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/8 "2019-01-07T23:46:29Z")

</div>

`def onMouseMoved(observer,eventid):`  
Previously it was a simple function. If you have made it a method of a class you will need `self` as an argument like other methods such as `showMIPRed`. The error you’re having is because of the mismatch of expected arguments.

Try changing to `def onMouseMoved(self, observer, eventid)`.

---

<div class="post-metadata">

### Author: ![mag](https://avatars.discourse-cdn.com/v4/letter/m/58f4c7/32.png) [@mag](https://discourse.slicer.org/u/mag)
#### Post date: [January 8, 2019, 12:14am UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/9 "2019-01-08T00:14:05Z")

</div>

That’s right, sorry. As you can tell I’m a very beginner at Python.  
I am still a bit confused though because when I call the method in this line

```
crosshairNode.AddObserver(slicer.vtkMRMLCrosshairNode.CursorPositionModifiedEvent, self.onMouseMoved)

```

I’m not specifying any argument at all. How does onMouseMoved know what observer and eventid are? Is it AddObserver who passes these argument to onMouseMoved? And if so how can I pass crosshairNode to onMouseMoved without having to specifying eventid and observer which I don’t have?

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: [January 8, 2019, 3:54am UTC](https://discourse.slicer.org/t/change-data-probe-to-view-mip-hu/4516/10 "2019-01-08T03:54:29Z")

</div>

The easiest way is to store variables in the object (for example, you can store the crosshair node in self.crosshairNode variable).

You can use lambda functions to pass arbitrary additional arguments to callback functions. If you need to access the caller object then you can use the technique described [here](https://www.slicer.org/wiki/Documentation/Nightly/Developers/Python_scripting#How_can_I_access_callData_argument_in_a_VTK_object_observer_callback_function).
