Axis Designations in SetMarquee Operation

The GetMarquee operation allows us to use axis designations (e.g. left, top) to specify the relative settings for the return coordinates. The SetMarquee operation has no equivalent.

I have a window with an image above using left, top and a graph below using its own axes (e.g. hleft, hbottom). I would like to regenerate a previously drawn marquee with SetMarquee based on coordinates returned from GetMarquee relative to (left, top) rather than relative to the entire window.

The feature request is therefore to allow this type of language.

SetMarquee/W=.../A=(left/right axis, top/bottom axis) left, top, right, bottom

 

Update: it seems like the following approach works (until this wish is granted). In an earlier version of this post, the code didn't work because I wasn't converting from pixel coordinates to point coordinates.

 

function setMarqueeByAx(winN,vertAxN,vertBottom,vertTop,horAxN,horLeft,horRight)
	String vertAxN,horAxN,winN
	Variable vertBottom,vertTop,horLeft,horRight
	
	if (strlen(winN) < 1)
		winN=winname(0,1)
	endif
	
	if (strlen(vertAxN) < 1)
		vertAxN = "left"
	endif
	
	if (strlen(horAxN) < 1)
		horAxN = "bottom"
	endif
	 
	getwindow $winN, psizeDC
	Variable pixHorRange = V_right-V_left
	getwindow $winN, psize
	Variable pntsHorRange = V_right-V_left  
	Variable pntsPerPix = pntsHorRange / pixHorRange  //ratio seems to always be equal for vertical, so just using horizontal for calculation of the conversion factor
	Variable bottom=pixelFromAxisVal(winN,vertAxN,vertBottom)*pntsPerPix
	Variable top=pixelFromAxisVal(winN,vertAxN,vertTop)*pntsPerPix
	Variable left=pixelFromAxisVal(winN,horAxN,horLeft)*pntsPerPix
	Variable right=pixelFromAxisVal(winN,horAxN,horRight)*pntsPerPix
		
	SetMarquee/W=$winN left, top, right, bottom
end

 

In reply to by gsb

gsb wrote:

Update: it seems like the following approach works (until this wish is granted). In an earlier version of this post, the code didn't work because I wasn't converting from pixel coordinates to point coordinates.

Thanks. I am using a structure and a function call to populate either marquee or drawing coordinates.

// structure to collect marquee or hRoI coordinates
Structure MarqueeCoordinates
	variable hasmarquee
	variable hasdrawing
	variable paleft
	variable paright
	variable patop
	variable pabottom
	variable pgleft
	variable pgright
	variable pgtop
	variable pgbottom
EndStructure

// fill the structure
Function GetMCCoordinates(mc)
	Struct MarqueeCoordinates &mc
	
	GetMarquee/W=$k_graphName/Z
	mc.hasmarquee = v_flag
	DrawAction/W=$k_graphName/L=ProgFront getgroup=hRoI, extractOutline
	mc.hasdrawing = v_flag
	
	variable pntsh, pxlsh, pntsppxl

	// hRoI drawing overrides marquee
	if (mc.hasdrawing == 1)
		wave w_polyx, w_polyy
		mc.pgleft=w_polyx[0]
		mc.pgright=w_polyx[1]
		mc.pgtop=w_polyy[1]
		mc.pgbottom=w_polyy[2]
		getwindow $k_graphName, psizeDC
		pxlsh = V_right-V_left
		getwindow $k_graphName, psize
		pntsh = V_right-V_left  
		pntsppxl = pntsh / pxlsh
		mc.paleft = PixelFromAxisVal(k_graphName,"left",mc.pgleft)*pntsppxl
		mc.patop = PixelFromAxisVal(k_graphName,"top",mc.pgtop)*pntsppxl
		mc.paright = PixelFromAxisVal(k_graphName,"left",mc.pgright)*pntsppxl
		mc.pabottom = PixelFromAxisVal(k_graphName,"top",mc.pgbottom)*pntsppxl
		killwaves/Z w_polyx, w_polyy
		return 0
	endif	
	
	// no hRoI drawing or marquee
	if (mc.hasmarquee == 0)
		mc.paleft = NaN; mc.patop = NaN; mc.paright = NaN; mc.pabottom = NaN
		mc.pgleft = NaN; mc.pgtop = NaN; mc.pgright = NaN; mc.pgbottom = NaN
		return 0
	endif
	
	// marquee
	mc.paleft = v_left
	mc.paright = v_right
	mc.patop = v_top
	mc.pabottom = v_bottom	
	GetMarquee/W=$k_graphName/Z left,top
	mc.pgleft = v_left
	mc.pgright = v_right
	mc.pgtop = v_top
	mc.pgbottom = v_bottom	
	return 0
end

I can draw a marquee on an image to restrict a histogram region. I need the graph coordinates to compute the image mask. I can get those and the absolute coordinates from the GetMarquee operation. As needed, I lock down the RoI as a drawing (hRoI). For this function, I also need the graph coordinates. When all is done, I can clear the RoI drawing. I want to restore the marquee to those coordinates. But I need the absolute coordinates to do a SetMarquee. Unfortunately ... :-( ... , the extractOutline flag pulls the drawing using graph coordinates, not absolute coordinates.

Hence, the desire to have SetMarquee be aware of placements in graph coordinates as (most) other operations also are.

Jeff- I have just implemented in Igor 9:

SetMarquee/HAX=axisname/VAX=axisname left, top, right, bottom

Using separate flags allows you to mix points and axis coordinates. That might or might not be particularly useful, but seems to me that unnecessary restrictions will only generate future enhancement requests :)

John: Thanks. I would have thought with one flag to handle the independent option with star or blank ...

/AX=(left,*)   ... or ...  /AX=(left,)   // set vertical on the axis titled left and horizontal as absolute top/bottom

/AX=(*,*) ... or ... /AX=()   // clear all axes designations (set to absolute)

 

I use the GetMarquee left, top operation for a marquee on an image. Why does it return values of v_left ... that are offset by -0.5? For example, when I force it to set at what I think is left=0, top=0, I read back -0.5, -0.5 rather than 0, 0?!?! I presume the right and bottom are also "offset" by -0.5 because the values also end with 0.5 (e.g. 615.5 rather than 615 or 616).

Is the marquee coordinates to be read as being "left and above the next whole number pixel" in this case?

How will this be handled for the new flags with the /HAX=top and /LAX=left designations? What will be the value when we would use SetMarquee/HAX=left 0,... to place the marquee at 0,0 and then read it back using GetMarquee left, top? Will we get v_left = 0 or will we get v_left = -0.5?

Jim: I'll pull out a working example from my Image Tools package and try to post it by later this week or weekend.

Ok. I think I have it figured out. Help me here where I am wrong. This is for an image in a window.

GetMarquee - returns window coordinates as integer numbers
GetMarquee left, top - returns graph coordinates as real numbers

SetMarquee - takes window coordinates as integer numbers OR rounds inputs to integer numbers

The result is that I cannot position the marquee to WHOLE NUMBER (integer) values of a position in image pixels.

GetMarquee
--> Window: 138  212  395  451
GetMarquee left, top
--> Graph: 497.126  513.508  1528.5  1473.26
// try to force to whole number pixels in graph (e.g. 498, 513, 1529, 1473)
SetMarquee 137.889, 212.205, 394.881, 451.42
GetMarquee
--> Window: 138  212  395  451
GetMarquee left, top
--> Graph: 497.126  513.508  1528.5  1473.26

I'll work with this new knowledge in my code.

Thanks!