Millisecond Forums

Presenting stimuli of absolute sizes (e.g. in cm)

https://forums.millisecond.com/Topic14608.aspx

By katbo - 10/14/2014

Sometimes it is necessary to make sure all presented stimuli are of the same absolute size (e.g. a square with width/height of 4cm) on different monitors. In order to accomplish this, a calibration procedure is needed to calculate the pixel to (e.g.) mm  ratio on the monitor a script runs on.

Attached to this message is such a calibration script (Inquisit 4). The zip-file includes one script "AbsoluteSizing.iqx" with the actual calibration procedure and an example script "SizingDemo.iqx" to demonstrate how to use the calibration script to produce a square of a particular size (e.g. 5cm).

Here is an overview of how the calibration procedure works (the same information is also included in the scripts themselves):

(1) <include> script "AbsoluteSizing.iqx"
The code of the calibration script "AbsoluteSizing.iqx" can be be included into any other script (e.g. SizingDemo.iqx) using:
<include>
/file = "AbsoluteSizing.iqx"
</include>


All the elements of "AbsoluteSizing.iqx" are then accessible to the script (e.g. SizingDemo.iqx) and do not have to be re-written.

(2) Calibration Procedure: Underlying idea
The general idea of the calibration procedure itself is to adjust a given line on the monitor screen to be as long as the short side of a US letter-sized piece of paper (8 1/2 inches or ~21.6cm ).  The calibration instructions on the screen read as follows:

<item instructions>
/1 = "Take an 8 1/2 x 11 inch paper (US Letter Size) and
adjust the line on your screen to be 8 1/2 inches (~21.6cm) long.

To increase the line: press '>' on your keyboard
To decrease the line: press '<' on your keyboard

When you are done, press <ENTER>."

</item>


(3) Calculation of 'pixel per mm' ratio
This calibration procedure results in calculating the ratio of pixels per mm on the current monitor:

<expressions>
/ratio_pxpermm = values.linelength_px/215.9
</expressions>

Values.linelength_px is the final length of the comparison line in pixels when it measured 8 1/2 inches or 215.9mm.

NOTE: If the pixel to inches ratio should be calculated instead, the expression would need to be edited to: /ratio_pxperinch = values.linelength_px/8.5

(4) Definition of stimuli of absolute sizes
To present a stimulus of a certain size, the stimulus sizes need to be explicitly coded in pixels.

Take, for example, the square of "SizingDemo.iqx".
Under Editable values, the size of the square is defined as:
<values>
/squaresize = 50
</values>


with values.squaresize setting the desired size of the square to 50mm (5cm). Because the calibration script calculates the pixel/mm ratio it is necessary to set the absolute sizes in mm (and not inches or cm or anything else). If the calibration script calculates the pixel/inch ratio instead, the absolute sizes need to be coded in inches.

The square itself is coded as follows. Note the width and height definitions: they are written explicitly in pixel units (px). The product of (values.squaresize x expressions.ratio_pxpermm) calculates the pixel length that a square of 50mm requires on the current monitor.

<shape square>
/shape = rectangle
/width = 1px * values.squaresize * expressions.ratio_pxpermm
/height = 1px * values.squaresize * expressions.ratio_pxpermm
/color = blue
/position = (50%, 50%)
</shape>


And that's it. More information is included into the demo scripts. If you have any further questions, please, let us know.

cheers,
katja from Millisecond Software
By Reshan - 3/27/2016

Hi, I found the "AbsoluteSizing" script was extremely helpful. However, I am still struggling to maintain a constant distance (in mm) between two pictures presented simultaneously, across different monitor displays?

How would I write the script for the /position?  


Below is the relevant script: (Please note, I modified the "Absolute Sizing script", so it uses a credit card instead of a piece of paper):

<values>
/linelength_px= 250
/imageheight= 119.25
/imagewidth = 100
</values>

<expressions>
/ratio_pxpermm = values.linelength_px/85.60
</expressions>

<picture nonaffFace1rightgap2>
/items= ("fi_000_tw1.bmp", "fi_000_tw2.bmp", "fi_000_tw3.bmp", "fi_000_tw4.bmp")
/select = noreplace
/position= (80, 50)
/size = (1px * values.imagewidth * expressions.ratio_pxpermm, 1 px * values.imageheight * expressions.ratio_pxpermm)
</picture>

<picture affFace1leftgap2>
/items = ("fi_000_tw3.bmp", "fi_000_tw4.bmp", "fi_000_tw5.bmp", "fi_000_tw6.bmp")
/select= picture.nonaffface1rightgap2.currentindex
/position= (20, 50)
/size = (1px * values.imagewidth * expressions.ratio_pxpermm, 1 px * values.imageheight * expressions.ratio_pxpermm)
</picture>


Thank you so much! 

By Dave - 3/27/2016

The approach for position is the same as for size. You'll probably want to take the center of the screen as your anchor and compute the absolute position of the left and right stimulus relative to the center.

Attached is a modification of the original example from this thread. In addition to the square, a circle is displayed. The distance between the center of the square and the center of the circle is 10cm.

<values>
/ squaresize = 50
/ distance = 100
</values>

<shape square>
/shape = rectangle
/width = 1px * values.squaresize * expressions.ratio_pxpermm
/height = 1px * values.squaresize * expressions.ratio_pxpermm
/color = blue
/ hposition = 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 50%
</shape>

<shape circle>
/shape = circle
/width = 1px * values.squaresize * expressions.ratio_pxpermm
/height = 1px * values.squaresize * expressions.ratio_pxpermm
/color = green
/ hposition = 1px * (display.canvaswidth/2) + (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 50%
</shape>

By jm560@sussex.ac.uk - 4/13/2017

Dave - Monday, March 28, 2016
The approach for position is the same as for size. You'll probably want to take the center of the screen as your anchor and compute the absolute position of the left and right stimulus relative to the center.

Attached is a modification of the original example from this thread. In addition to the square, a circle is displayed. The distance between the center of the square and the center of the circle is 10cm.

<values>
/ squaresize = 50
/ distance = 100
</values>

<shape square>
/shape = rectangle
/width = 1px * values.squaresize * expressions.ratio_pxpermm
/height = 1px * values.squaresize * expressions.ratio_pxpermm
/color = blue
/ hposition = 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 50%
</shape>

<shape circle>
/shape = circle
/width = 1px * values.squaresize * expressions.ratio_pxpermm
/height = 1px * values.squaresize * expressions.ratio_pxpermm
/color = green
/ hposition = 1px * (display.canvaswidth/2) + (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 50%
</shape>


Hi,
I have been using this very helpful post on calibrating stimuli so that they appear the same size across different screens/resolutions. It works perfectly for my picture stimuli but I can't work out how to do it for my text stimuli. I have letters on a screen that I need to appear at a constant size (1cm). I have posted below what that part of script looks like. At the moment this just seems to change the position. I've tried to put the reszing code where the fontsize is defined and the script will not run. If I set the text size in pt would this be constant across screens?

<values>
/squaresize = 50
/imageheight= 30
/imagewidth = 30
/lettersize = 10
</values>

<text Ll1filler>
/ items = ("O")
/ fontstyle = ("Arial Black", 2%, false, false, false, false)
/ txcolor = darkgray
/ select =sequence
/ txbgcolor = black
/ position = (50%, 37%)
/ size = (1px * values.lettersize * expressions.ratio_pxpermm)
</text>

I also want to make the location of the letters constant across screens - I have tried using the same approach as previously asked but it keeps displaying the following error messages,
/2 is not a valid attribute.
Expression '1px*(display.canvaswidth/2' is invalid. Unmatched parenthesis.

<text Ll1filler>
/ items = ("O")
/ fontstyle = ("Arial Black", 2%, false, false, false, false)
/ txcolor = darkgray
/ select =sequence
/ txbgcolor = black
/ position = (1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm, 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm)
</text>

Any help would be appreciated!,
Thanks
By Dave - 4/14/2017

jm560@sussex.ac.uk - Friday, April 14, 2017
Dave - Monday, March 28, 2016
The approach for position is the same as for size. You'll probably want to take the center of the screen as your anchor and compute the absolute position of the left and right stimulus relative to the center.

Attached is a modification of the original example from this thread. In addition to the square, a circle is displayed. The distance between the center of the square and the center of the circle is 10cm.

<values>
/ squaresize = 50
/ distance = 100
</values>

<shape square>
/shape = rectangle
/width = 1px * values.squaresize * expressions.ratio_pxpermm
/height = 1px * values.squaresize * expressions.ratio_pxpermm
/color = blue
/ hposition = 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 50%
</shape>

<shape circle>
/shape = circle
/width = 1px * values.squaresize * expressions.ratio_pxpermm
/height = 1px * values.squaresize * expressions.ratio_pxpermm
/color = green
/ hposition = 1px * (display.canvaswidth/2) + (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 50%
</shape>


Hi,
I have been using this very helpful post on calibrating stimuli so that they appear the same size across different screens/resolutions. It works perfectly for my picture stimuli but I can't work out how to do it for my text stimuli. I have letters on a screen that I need to appear at a constant size (1cm). I have posted below what that part of script looks like. At the moment this just seems to change the position. I've tried to put the reszing code where the fontsize is defined and the script will not run. If I set the text size in pt would this be constant across screens?

<values>
/squaresize = 50
/imageheight= 30
/imagewidth = 30
/lettersize = 10
</values>

<text Ll1filler>
/ items = ("O")
/ fontstyle = ("Arial Black", 2%, false, false, false, false)
/ txcolor = darkgray
/ select =sequence
/ txbgcolor = black
/ position = (50%, 37%)
/ size = (1px * values.lettersize * expressions.ratio_pxpermm)
</text>

I also want to make the location of the letters constant across screens - I have tried using the same approach as previously asked but it keeps displaying the following error messages,
/2 is not a valid attribute.
Expression '1px*(display.canvaswidth/2' is invalid. Unmatched parenthesis.

<text Ll1filler>
/ items = ("O")
/ fontstyle = ("Arial Black", 2%, false, false, false, false)
/ txcolor = darkgray
/ select =sequence
/ txbgcolor = black
/ position = (1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm, 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm)
</text>

Any help would be appreciated!,
Thanks

<text Ll1filler>
/ items = ("O")
/ fontstyle = ("Arial Black", expressions.fontsize, false, false, false, false)
/ txcolor = darkgray
/ select =sequence
/ txbgcolor = black
/ hposition = 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm

</text>

<expressions>
/ fontsize = 1px * values.lettersize * expressions.ratio_pxpermm
</expressions>

would be the way to do it.
By jm560@sussex.ac.uk - 4/14/2017

Dave - Friday, April 14, 2017
jm560@sussex.ac.uk - Friday, April 14, 2017
Dave - Monday, March 28, 2016
The approach for position is the same as for size. You'll probably want to take the center of the screen as your anchor and compute the absolute position of the left and right stimulus relative to the center.

Attached is a modification of the original example from this thread. In addition to the square, a circle is displayed. The distance between the center of the square and the center of the circle is 10cm.

<values>
/ squaresize = 50
/ distance = 100
</values>

<shape square>
/shape = rectangle
/width = 1px * values.squaresize * expressions.ratio_pxpermm
/height = 1px * values.squaresize * expressions.ratio_pxpermm
/color = blue
/ hposition = 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 50%
</shape>

<shape circle>
/shape = circle
/width = 1px * values.squaresize * expressions.ratio_pxpermm
/height = 1px * values.squaresize * expressions.ratio_pxpermm
/color = green
/ hposition = 1px * (display.canvaswidth/2) + (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 50%
</shape>


Hi,
I have been using this very helpful post on calibrating stimuli so that they appear the same size across different screens/resolutions. It works perfectly for my picture stimuli but I can't work out how to do it for my text stimuli. I have letters on a screen that I need to appear at a constant size (1cm). I have posted below what that part of script looks like. At the moment this just seems to change the position. I've tried to put the reszing code where the fontsize is defined and the script will not run. If I set the text size in pt would this be constant across screens?

<values>
/squaresize = 50
/imageheight= 30
/imagewidth = 30
/lettersize = 10
</values>

<text Ll1filler>
/ items = ("O")
/ fontstyle = ("Arial Black", 2%, false, false, false, false)
/ txcolor = darkgray
/ select =sequence
/ txbgcolor = black
/ position = (50%, 37%)
/ size = (1px * values.lettersize * expressions.ratio_pxpermm)
</text>

I also want to make the location of the letters constant across screens - I have tried using the same approach as previously asked but it keeps displaying the following error messages,
/2 is not a valid attribute.
Expression '1px*(display.canvaswidth/2' is invalid. Unmatched parenthesis.

<text Ll1filler>
/ items = ("O")
/ fontstyle = ("Arial Black", 2%, false, false, false, false)
/ txcolor = darkgray
/ select =sequence
/ txbgcolor = black
/ position = (1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm, 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm)
</text>

Any help would be appreciated!,
Thanks

<text Ll1filler>
/ items = ("O")
/ fontstyle = ("Arial Black", expressions.fontsize, false, false, false, false)
/ txcolor = darkgray
/ select =sequence
/ txbgcolor = black
/ hposition = 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm
/ vposition = 1px * (display.canvaswidth/2) - (values.distance/2) * expressions.ratio_pxpermm

</text>

<expressions>
/ fontsize = 1px * values.lettersize * expressions.ratio_pxpermm
</expressions>

would be the way to do it.

Thank you so much - works perfectly!