SetVariable: linking limits to the scaling of an image

Hello,

I've been working on a user interface for a family of procedures that I commonly use to analyze transmission electron microscopy (TEM) images.

Part of that interface includes a Line Profile Tool that is more TEM image oriented - a somewhat simplified and extended version of Wavemetrics' Image Line Profile tool.

One of the reasons I wanted to create my own line profile tool is that the the built-in Line Profile interface does not handle scaled images, i.e. the width of the profile is always in pixels. In my interface the limits option for the SetVariable that sets the width is set to not exceed to not exceed the scaled size of the image (DimDelta(imWave,0)*DimSize(imWave,0)), and to increment by half the scaling increment (0.5*DimDelta(imWave,0)). Here, imWave refers to the wave that holds the image.

It occurred to me that if I rescale the image, I may not automatically update the limits of the SetVariable field. Am I correct?

If that is the case, how can I ensure that the limits of the SetVariable field are linked to the scaling of the image that is being displayed?

I posted the full code as a project here: http://www.igorexchange.com/project/SimpLiFi

The part that is concerned is here:

SetVariable profWidthVar, pos={236,8}, size={90,15}, proc=QHAADFSetProfWidthProc
SetVariable profWidthVar, title="Width"
SetVariable profWidthVar, help={"Width over which to average profile"}
SetVariable profWidthVar, limits={0,sqrt(2)*DimDelta(imWave,0)*DimSize(imWave,0),DimDelta(imWave,0)}, value=root:Packages:QHAADF:LineProfile:swidth
You could set a window hook on the graph that responds to the resize event, and then update your SetVariable control from within the window hook.
When you say rescale the image... do you mean change the wave scaling? If so, would you do it via the Data Browser, in code via setscale operation, or some other means?
Yes, by changing the scaling of the image I do indeed mean the wave scaling, i.e. through a SetScale operation on the wave that contains the image data, and not to resize the window that displays the image.
Sorry, I misread what you had originally written. A window hook won't be of use if you're changing the wave's scaling.

You should be able to use SetFormula to get this to work.
For example:
Function recalculate(wave0)
    WAVE wave0
    print "recalculate called"
End

Function test()
    Variable/G root:dummy1
    Make/N=(100, 200) root:imageWave = enoise(10)
    SetFormula root:dummy1, "recalculate(root:imageWave)"
    SetScale x, 0, 10, root:imageWave
End


Execute test() and notice that you get the print out indicating that recalculate was called. If you execute the SetScale command again, recalculate is called again. You would make the changes to the SetVariable control in the recalculate() function.

Note that you're setting yourself up for potential debugging nightmares by using dependencies like this.
I might suggest something other than a hook function that senses an action in the window or a dependency to the wave scale.

Create a Function that does only two things ... It reads the current scale of imWave and sets global variables (gimScale and gimDelta) with that value.

Define the limits of the setvariable by the global variables.

NVAR root:Packages:MyTEMPackage:gimScale
NVAR root:Packages:MyTEMPackage:gimDelta
setvariable myimScale, limits={gimScale,0,gimDelta}


Create a window hook function. Attach it as a hook to the image graph and to the panel. The hook function will get an "activate" event. Have the activate event call the above function and then go to sleep.

Every time you activate the window or the panel, the globals will update, and thus the set variable limits will be updated.

I _think_ that this should work. I _think_ that I used this trick in the past. I _think_ that you cannot just blindly update the setvariable limits in the hook function because the call itself will (re)activate the hook function, leading to an infinite time loop.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
Thank you all for your replies.

I ended up using jjweimer's suggestion, and created this function

Function QHAADFUpdForImScale()

    NVAR gimDelta = root:Packages:QHAADF:LineProfile:gimDelta
    NVAR gimScale = root:Packages:QHAADF:LineProfile:gimScale
    WAVE imWave = $WMGetImageWave(WMTopImageGraph())
   
    gimDelta = DimDelta(imWave,0)
    gimScale = DimDelta(imWave,0)*DimSize(imWave,0)
   
    SetVariable profWidthVar, win=QHAADFLineProfileGraph, limits={0,sqrt(2)*gimScale,0.5*gimDelta}

End


that I call from the hook functions I've placed on both the window that displays the image and the window that displays the line profile.
Three notes ...

* You might want to put a return 0 at the end of your function call. This is a bit of "good coding practice".

* I am not certain that you really need to recall the setvariable within the function. I _think_ that you can set up the setvariable one time in your panel creation using the globals. Then, you can change the globals somewhere else and the limits will be adjusted.

* If you do end up continuing to change the setvariable within the function call itself, you do not need global variables at all. The only reason to use the globals is to avoid that you need to re-invoke the setvariable call each time the hook function is called. I suspect you may otherwise be running the case where, you activate the graph, that calls the hook, that calls the setvariable, that activates the panel, that calls the hook, that calls the setvariable, that activates the panel, that calls the hook ...

So a few changes and tests might be in line before you call it entirely fail safe.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
kpantzas wrote:
*SNIP*
...that I call from the hook functions I've placed on both the window that displays the image and the window that displays the line profile.


Several replies ago, you mentioned that the scaling is changed by a SetScale operation. Is there a reason not to call your function (QHAADFUpdForImScale) that updates the SetVar immediately after SetScale?
jtigor wrote:
kpantzas wrote:
*SNIP*
...that I call from the hook functions I've placed on both the window that displays the image and the window that displays the line profile.


Several replies ago, you mentioned that the scaling is changed by a SetScale operation. Is there a reason not to call your function (QHAADFUpdForImScale) that updates the SetVar immediately after SetScale?


I was guessing the reason was to avoid problems in those cases when someone manually types the setscale change on the command line?????

But otherwise, I would have to wonder as well.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH