I have made a bit of code that allows a user to select a region of a 2D image plot with the marquee around a peak of intensity in the image. The user right clicks and selects "Fit peak". The region selected by the marquee is duplicated and displayed in a new window, then a 2D Gaussian is fitted to the peak with the resultant fit contour appended to the peak data. I want to then label the peak in the original data plot using the output parameters x0 and y0 from the fit (stored in W_coeff) to give the location for the tag label. The problem is that the tag label requires the linear array index for specifying the location:
Tag [flags] [traceOrAxisName, xAttach [, textStr ]]
where xAttach is the x-value for 1D but the linear array for a 2D wave. In the dialogue (right-click on image > add annotation) you can specify the scaled x and y positions and it determines the array linear index. I was wondering if anyone knows how to calculate this?
You have to calculate it using DimDelta() and DimOffset(). The documentation for the x2pnt() function gives an expression for computing point numbers from the scaled X or Y values.
On the other hand, can you just do the curve fit on a subrange of the original data? If you use graph cursors instead of a marquee, then it's easy to get row and column numbers instead of scaled X and Y values.
Hi John, thanks for the reply. I think either I don't understand your answer or I didn't phrase my question well! I guess I didn't really need all the introduction at the start... Anyway the crux of the problem is I have x and y coordinates for a point on a 2D plot and I want to programmatically add a tag at this point. I have no trouble converting between point number and scaled dim posn using the method explained in the x2pnt help and vice versa. The problem is that for the tag label you need the "array linear index" this is the p number as if the matrix were written out by concatenating each column into a 1D wave. To see what I mean, open an image in Igor and add annotation > tag, under the position tab you can enter manually the x and y points. Then the "p = " box updates automatically. So you need 1 single number to define its location on the image rather than the x and y point numbers or scaled position.
While I'm not all that familiar with the Tag operation, to get the 'linear index into the array' for a 2D wave you need to know that Igor stores the data in column-major format.
This means that the linear index for the point at row i and column j is given by j * nRows + i.
On the other hand, can you just do the curve fit on a subrange of the original data? If you use graph cursors instead of a marquee, then it's easy to get row and column numbers instead of scaled X and Y values.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
May 31, 2012 at 09:08 am - Permalink
May 31, 2012 at 09:57 am - Permalink
This means that the linear index for the point at row i and column j is given by j * nRows + i.
May 31, 2012 at 12:26 pm - Permalink
make/O/N=(20,30) twod=p+q
setscale x -1,1, "m" twod
setscale y 20,30, "m" twod
newimage twod
Tag/C/N=text0/X=0/Y=-33.33 twod, 0, "x=\\OX , y=\\OY"
MoveTagToXY(0.25,24)
End
Macro MoveTagToXY(x,y)
Variable x=0, y=24
Variable tagX= TagXForImageXY(twoD,x,y)
Tag/C/N=text0 twod, tagX
End
Function TagXForImageXY(image, x, y)
Wave image
Variable x, y
// x = DimOffset(image,0) + row * DimDelta(image,0)
// y = DimOffset(image,1) + col * DimDelta(image,1)
// solving for row and col:
Variable row= (x - DimOffset(image,0)) / DimDelta(image,0)
Variable col= (y - DimOffset(image,1)) / DimDelta(image,1)
// now treat image as a one-dimensional wave
Variable point = row + col * DimSize(image,0)
// Tag takes X scaled value. Yes, this is a bit kludgy.
Variable tagX= DimOffset(image,0)+ point * DimDelta(image,0)
return tagX
End
--Jim Prouty
Software Engineer, WaveMetrics, Inc.
May 31, 2012 at 12:39 pm - Permalink