displaying slices from a 3D wave

I have 3D waves and so far to display a z-slice ive been using the rather bulky
duplicate/O/R=[][][z] 3D_wave 2D_wave
newimage 2D_wave


which seems obtuse considering the data already exists, but I cant seem to quickly call up the slice in any other way. What is the correct method here? Eventually I want to make a function which loads the image and uses a slider to move thru them (half way there)..
According to the Manual
// Extract a layer of a 3D wave into a 2D wave
wave0_2D = wave0_3D[p][q][0] // Extract layer 0 into 2D wave

is another method. Replace the [0] with the z-layer index you want. It should save you the frequent Duplicate operation once you have created your 2D destination wave. It's too bad that the general purpose MatrixOP operation does not seem to handle this case.
That really does the same thing tho, doesnt it? Rebuilds a 2D matrix by taking data from a pre-existing 3D matrix. I am starting to wonder tho if IGOR actually recopies the data, or if the 2D wave is just a new address for the limited set.

Even then, would be nice not to have to go thru the hoops, something like

display; appendimage 3D_wave[][][z]
or better
newimage 3D_wave[][][z]
daggaz wrote:
That really does the same thing tho, doesnt it? Rebuilds a 2D matrix by taking data from a pre-existing 3D matrix. I am starting to wonder tho if IGOR actually recopies the data, or if the 2D wave is just a new address for the limited set.

When you make a new wave (whether using Duplicate or Make), Igor copies the data.

Along with the approaches already mentioned, you can use the ImageTransform operation with the getPlane keyword and then rename the M_ImagePlane output wave that the operation creates. You should use either ImageTransform or the Duplicate command you originally posted as those should be faster than using a wave assignment statement.

daggaz wrote:

Even then, would be nice not to have to go thru the hoops, something like

display; appendimage 3D_wave[][][z]
or better
newimage 3D_wave[][][z]

You can display a 1-D subrange of a wave using the Display operation, but subrange display isn't supported for images. However, if you are just trying to change the plane of a wave that is displayed in an image, use the ModifyImage operation with the plane keyword. Please read the documentation for this keyword to understand exactly what we mean by "plane".

There is also a package that adds a plane slider to an image. To get this, select an image, then select the Analysis->Packages->Image Processing menu item. This will #include the image processing procedures and compile them. Once that happens, then select the Image->Add Slider menu item.
Thanks for the modifyimage work-around, that makes things faster.


Otherwise, I thought I had the slider figured out, but no (ive done other buttons with few problems).

My main function initiates wave names based on a single variable laser, then starts a panel/subpanel and puts up the first graphs, as well as loads a slider. The slider should move thru the variable z, which affects which graphs get put into the subpanels. My problem is that I cant seem to pass any variables, waves, or strings to the slider proc function, and I dont want to make the variables in this case global, because I expect this function to be run in multiple instances with similiar data sets in the same experiment. Is this even possible or am I going at it the wrong way entirely? In pseudo-code:

function wave_viewer(laser)
variable laser
variable z = 0
string laser_name = num2str(laser)
wave1_name = foo1 + laser_name + num2str(z)
wave w1 = $wave1_name
wave2_name = foo2 + laser_name + num2str(z)
wave w2 = $wave2_name
etc..
newpanel mainpanel
newpanel subpanel1
display w1 mainpanel#subpanel1
slider slide_z value= z proc=slider_function
end

function slider_function(required fields)
blahblah
if yes
  update all graphs based on z
endif
end


A couple of comments:

1. If you load the Image Processing procedures (Analysis Menu->Packages->Image Processing) you will get an Image menu from which you can choose to add a slider to an image that displays a layer of a 3D wave or choose a 3D Wave display which presents all 3 orthogonal slices at once.

2. It may not be so obvious but the fastest way to scroll through the data (which does not involve duplication) is displaying orthogonal slices in Gizmo.

A.G.
WaveMetrics, Inc.
Yes thanks, I did look thru the image viewer functions earlier (and they are nice), but I am still interested in learning to code the slider myself because:

a) Its good to know how it is done
b) There are other data types besides 3D stacks which such a function would be very useful for.

(I did think about stacking things regardless just to use the function, but what if it is x-scaled waves and not 2D images)
Ok I dropped any hope of running more than one incidence of this function, and just passed a wave/global variable to the slider proc function containing the critical value for naming subsequent waves.

It worked, but looked really glitchy, so I tried to incorporate the modifyimage trick, in order to avoid all the duplication steps, but now I am getting an error: there are no graphs or the graph does not exist.

I used the line
modifyimage/W=control_panel_name#graph_xy main_wave , plane=(z)


where the window path works using the display command, main_wave is name of the graph (thru a $string), and z is the value set by the slider. I also tried to replace main_wave with its string $main_wave_name but no dice. Any ideas?
daggaz wrote:

I used the line
modifyimage/W=control_panel_name#graph_xy main_wave , plane=(z)




Here is a full example:

make/n=(10,10,10) ddd=enoise(1)
display
newimage/host=graph0 ddd
modifyimage/w=graph0#g0 ddd plane=3


This suggests that you check either the value you are passing for /W or the image instance.

I hope this helps,

AG
I still cant get it to work, have tried many different variations. Displaying the slice created by duplicating works fine, here i commented those parts out and try to use the modifyimage comman instead on the 3D wave
#pragma rtGlobals=3     // Use modern global access method and strict wave access.
function PSF_slide(laser)
variable laser

make/o/d/n=1 laser_wave = laser  // should just make this a global variable i suppose..
string laser_name = num2str(laser)
variable z = 0
string line_x_name = "w_" + laser_name + "_x_" + num2str(z)
wave line_x = $line_x_name
string line_y_name = "w_" + laser_name + "_y_" + num2str(z)
wave line_y = $line_y_name
string mainwave_name = "w_" + laser_name
wave main_wave = $mainwave_name
duplicate/o/r=[][][z] main_wave slice_z
variable dim_z = dimsize(main_wave,2)
string control_panel_name = "Line Profiles: " + laser_name

NewPanel/K=0/N=line_profile_main/W=(0,0,1040,400) as control_panel_name
NewPanel/K=2/N=graph_x/Host=line_profile_main/W=(10,10,410,210)
NewPanel/K=2/N=graph_y/Host=line_profile_main/W=(630,10,1030,210)
NewPanel/K=2/N=graph_xy/Host=line_profile_main/W=(420,10,620,210)
slider slider_z win=line_profile_main, pos={420,220}, live=0,limits={0,(dim_z),1},vert = 0, variable=z,size={200,30},ticks=10,proc=PSF_slider_control
//SetVariable/Z setvar_z win=control_panel_name, bodyWidth=60,noproc, fsize = 16,limits={0,(dim_z),1},size={100,40},pos={470,290}, title="Z-Slice" ,value=z,proc=PSF_setvar
display/K=2/FG=(FL,FT,FR,FB)/Host=line_profile_main#graph_x line_x
display/K=2/FG=(FL,FT,FR,FB)/Host=line_profile_main#graph_y line_y
display/K=2/FG=(FL,FT,FR,FB)/Host=line_profile_main#graph_xy; appendimage main_wave     //slice_z
end

Function PSF_slider_control(slider_z, z, event) : SliderControl
    String slider_z // name of this slider control
    Variable z  // value of slider
    Variable event  // bit field: bit 0: value set; 1: mouse down,    2: mouse up, 3: mouse moved

    wave laser_wave
    string laser_name = num2str(laser_wave[0])
    string line_x_name = "w_" + laser_name + "_x_" + num2str(z)
    wave line_x = $line_x_name
    string line_y_name = "w_" + laser_name + "_y_" + num2str(z)
    wave line_y = $line_y_name
    string mainwave_name = "w_" + laser_name
   
    wave main_wave = $mainwave_name
    duplicate/o/r=[][][z] main_wave slice_z
    variable dim_z = dimsize(main_wave,2)
            if(event %& 0x1) // bit 0, value set
                display/K=2/FG=(FL,FT,FR,FB)/Host=line_profile_main#graph_x line_x
                display/K=2/FG=(FL,FT,FR,FB)/Host=line_profile_main#graph_y line_y
                //display/K=2/FG=(FL,FT,FR,FB)/Host=line_profile_main#graph_xy; appendimage slice_z
                display/K=2/FG=(FL,FT,FR,FB)/Host=line_profile_main#graph_xy
                modifyimage/W=line_profile_main#graph_xy main_wave , plane=(z)
               
            endif  
                                   

no matter how I try to code it, I get the first image up fine, then moving the slider kills the image and gives me the error.

also of strange note, the images looked very glitchy when i moved the slider so i tried adding the /live=0 flag to at least kill the intermediate images. now the slice_z image transitions extremely smoothly as i move the slider (using duplicate method) which is nice, but i thought this flag should stop all updates until the user has stopped moving the slider?? the two other graphs (not shown in this code, but different pre-existing waves being displayed according to z) are still glitchy tho.
I played with this a little and I think there are two problems with the modifyimage line:

modifyimage/W=line_profile_main#graph_xy main_wave , plane=(z)

First, you need to specify the path to the graph displaying the image. The line above gives the host panel and subpanel, but not the graph. In your function PSF_slide(laser), you actually created a graph window in a subpanel. In this case the graph name seems to be "G0". So the window spec should be

/W=line_profile_main#graph_xy#G0

Second you need to give the image instance name. In this case it is stored in the string variable mainwave_name. So the image name is

$mainwave_name

Try this for the modifyimage command

modifyimage/W=line_profile_main#graph_xy#G0 $mainwave_name , plane=(z)

Finally comment out the line immediately above the line with modifyimage...

display/K=2/FG=(FL,FT,FR,FB)/Host=line_profile_main#graph_xy

This seems to be the cause of your image disappearing from the graph window.

Hope this is useful. Given my recent track record, this could be bogus advice.
Thank you! That fixed everything. Strange tho, I had tested all the paths both in the code using display, and from the command line.
daggaz wrote:
Strange tho, I had tested all the paths both in the code using display, and from the command line.


Were you using $mainwave_name? If you tested modifyimage with "mainwave_name" or "mainwave", you would still receive an error, although slightly different from the one caused by the Win path.

PS Glad this worked for you.
No, I had earlier a wave statement : wave main_wave = $mainwave_name so I was just using main_wave. This worked fine with the display command, so I assumed it was not part of the problem.

Edit. Oh, I mean in the code. From the command line I used the actual wave name, of course, as the variables arent global in this case.
One of the things you have to get used to is that wave names and trace names are not the same. It's confusing because trace names are usually derived from wave names, so they are often the same name. But if you use something like Wave mainwave = $nameofmainwave, then mainwave is a wave reference. That's a pointer to a wave, not something that can be used as a trace name.

To understand the difference between traces and waves, consider that you can have waves, say wave0, with the same names in different data folders. The both result in a trace with the same name, wave0. If you put them both on the same graph, then you get two traces with names wave0 and wave0#1.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com