Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

[solved] Sketchpad and Canvas question

edited November 2013 in OpenSesame

Hey guys,

My question is pretty straightforward - I'm just trying to copy a sketchpad into a canvas so I can run canvas.show() in some inline code.

I have the following code in my script (engage_disengage is the name of my sketchpad):

my_canvas = self.experiment.copy_sketchpad('engage_disengage')
my_canvas.show()

I get a run-time error with the above code - it tells me that it can't run the command because engage_disengage does not have a canvas attribute? Was I supposed to convert the sketchpad to a canvas type at some point!

As always, thanks for the help!

-Ricky

Comments

  • edited 10:52AM

    Hi Ricky,

    Assuming that you indeed have a sketchpad item named engage_disengage in your experiment, the problem is likely because the canvas of engage_disengage hasn't been prepared yet at the moment that you call the copy_sketchpad() function.

    More specifically, if you were to place this code in the prepare phase before the engage_disengage sketchpad, then you will get this error message, because you are trying to copy a canvas that hasn't been constructed yet. If you place this code in the run phase or after the sketchpad, then you should be fine.

    For more information about the prepare-run strategy, see:

    Cheers!
    Sebastiaan

  • edited 10:52AM

    Hey Sebastian,

    Thanks, I actually had the sketchpad in the unused items section because I was trying to load it exclusively from inline script code because I was worried about lag time in loading the sketchpad after a certain trigger had been hit in inline code the step before in the sequence, but reading over that it looks like load time is pretty negligible given that the sketchpad is prepared beforehand..

    Anways, thanks!

    -Ricky

  • edited 10:52AM

    Hello again,

    I'm having a similar issue to the one above (hence resurrecting the post), I'm trying to copy a sketchpad item ('stripes') into an inline script item ('ongoing-script') which already contains a canvas ('trial_display').

    I need the sketchpad to overlay the canvas whilst still showing the canvas item beneath - basically so that the lines on the sketchpad disrupt the lines on the 'trial_display' canvas.

    I'm just having a little trouble copying the canvas - specifically what to write where in the script entry...

    Any pointers would be great!

    Thanks,

    Lee

  • edited 10:52AM

    Hi Lee,

    A canvas object is not transparent, so you cannot combine the content of two canvas objects. What you can do, is first copy the canvas from a sketchpad and then draw extra things on it, like so:

    my_canvas = self.copy_sketchpad('sketchpad1')
    my_canvas.fixdot()
    my_canvas.show()
    

    But the reverse is not possible, i.e. you cannot first draw things onto a canvas and then add the contents of another canvas. So my recommendation would be to restructure the code so that you don't need to superimpose two canvas objects, which is usually possible.

    Otherwise, in principle it is possible to 'hack' your code together by delving into the OpenSesame internals. For example, for the psycho back-end, every canvas has a stim_list, which you can copy and combine with the stim_list from another canvas. This is a back-end-specific hack though, I wouldn't do it unless it's really necessary.

    from openexp.canvas import canvas
    # Copy canvas objects from two sketchpads
    my_canvas1 = self.copy_sketchpad('sketchpad1')
    my_canvas2 = self.copy_sketchpad('sketchpad2')
    # Create a new empty canvas
    my_canvas3 = canvas(exp)
    # And copy all stimuli from the other canvas objects, except for the
    # first stimulus of my_canvas2, which is a background rectangle.
    # This will only work for the psycho backend!
    my_canvas3.stim_list = my_canvas1.stim_list + my_canvas2.stim_list[1:]
    my_canvas3.show()
    

    Cheers!
    Sebastiaan

  • edited November 2013

    Hmmm, this is actually related to a previous problem (http://forum.cogsci.nl/index.php?p=/discussion/619/solved-changing-polygon-linestyle#Item_5), but so far I haven't been able to create the workaround you suggested and make it work the way I need.

    The canvas 'trial_display' shows all of the primary stimuli, the 'stripes' will be a secondary stimulus (i.e. "press key X when the primary image is disrupted" so they only need to occur twice in each of the last two sessions.

    I had thought to just copy the sketchpad stripes and present it over the top of the trial_display canvas, but all I get is the 'stripes screen' wedged between two presentations of the primary stimuli... I have also tried this as a solution http://www.cogsci.nl/forum/index.php?p=/discussion/156/open-question-on-how-to-make-a-sketchpad-object-partly-transparent/p1, but in reverse, however I can't make it work either.

    I have decided to post the script via pastebin as a last resort (I have started collecting data on the first condition for this experiment, so time has become a factor in making this work... I am now a desperate chap!)

    Pastebin here

    Hopefully you can see the problem, I need to show the sketchpad on top of the canvas [trial_display] whilst still being able to see the stimuli beneath... thus the image pairs will have 'broken lines' as you previously suggested.

    Many thanks!

    Lee

  • edited 10:52AM

    Hi Lee,

    You are first showing trial_display and then stripes. As I explained above, this will not cause the contents of both canvas objects to be combined, but will first cause (only) trial_display to be shown, followed by (only) stripes.

    In your case, it's probably easiest to draw the white vertical stripes on your trial_display with something like the following script:

    # Draw vertical stripes
    trial_display.set_penwidth(50)
    for x in range(0, 2*trial_display.xcenter(), 100):
        trial_display.line(x, 0, x, trial_display.ycenter()*2, color='white')
    

    That way you don't have to bother with copying a sketchpad, etc. Does that make sense?

    As an aside, you have put all your code in the prepare phase of your inline_script items. Although this may work, it is good style to use the prepare phase only for preparatory stuff, and not for stimulus presentation, etc. See also:

    Cheers!
    Sebastiaan

  • edited 10:52AM

    Sebastiaan,

    That looks similar to a Bresenham algorithm (I think!) which I saw somewhere in my trying-to-find-a-solution research. I'll give it a try and let you know what happens.

    As for the prepare-run, I presume then that if I move all of my stimulus presentation to the run phase it will reduce any timing lag I'm experiencing?

    Best,

    Lee

  • edited 10:52AM

    As for the prepare-run, I presume then that if I move all of my stimulus presentation to the run phase it will reduce any timing lag I'm experiencing?

    Not necessarily, but it will avoid problems when you combine your inline scripts with other items that do follow the prepare-run strategy.

  • edited November 2013

    I've incorporated the script snippet into my experiment as:

    # Draw vertical stripes
    trial_display.set_penwidth(10)
    for x in range(64, 2*trial_display.xcenter(), 30):
        trial_display.line(x, 256, x, 512, color='white')
    

    This covers the area I require.

    I've taken a picture - its not great, but you can see vertical grey lines between each white stripe. This isn't ideal as it adds 'accidental stimuli' to the screen, rendering any responses ambiguous... Just wondering if there is anything that can be done about this as I haven't a clue (aside from changing the instructions to "press key X when image is disrupted").

    image

    It also causes a huge pause just before it is shown which is a massive clue to the participant that something is going to happen and also messes up the timing. I've tried putting it in both the prepare and run phases - seems to work better in the run phase.

    Hopefully this will be the last issue I have - it's the LAST stimulus... so frustrating!

    Thanks,

    Lee

    P.S. I also put all of my display code in the run phase as suggested - much neater!

  • edited 10:52AM

    Yes, I see them. I suspect that these gray lines result from the way that Expyriment (and PsychoPy for that matter) draws the stimuli, using OpenGL. This sometimes causes a bit of fuzziness, which in this case appears to be especially bothersome. I don't know if there's anything that can be done about it really, except disabling OpenGL under the back-end preferences or switching to the legacy back-end.

    Given these gray lines and the speed issue, perhaps you would be better off using a semitransparent image as a mask. For example, you could create an image that is the size of your stimuli and is transparent except for some white vertical stripes. Then you could draw this image (mask.png) on top of your stimuli, instead of drawing the masking lines one-by-one as I suggested previously:

    trial_display.image(exp.get_file('mask.png'))
    

    And to make sure that the timing is identical between mask and non-mask trials, you could show a completely transparent image as a dummy mask on non-mask trials. Is that an idea?

    Cheers!
    Sebastiaan

  • edited 10:52AM

    I used Paint.Net to make the stripe.png files (a different version for different sessions - I don't need participants practicing now...) and it works like a charm.

    Very many thanks, that has made me a happy chap!

    Best,

    Lee

Sign In or Register to comment.

agen judi bola , sportbook, casino, togel, number game, singapore, tangkas, basket, slot, poker, dominoqq, agen bola. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 50.000 ,- bonus cashback hingga 10% , diskon togel hingga 66% bisa bermain di android dan IOS kapanpun dan dimana pun. poker , bandarq , aduq, domino qq , dominobet. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 10.000 ,- bonus turnover 0.5% dan bonus referral 20%. Bonus - bonus yang dihadirkan bisa terbilang cukup tinggi dan memuaskan, anda hanya perlu memasang pada situs yang memberikan bursa pasaran terbaik yaitu http://45.77.173.118/ Bola168. Situs penyedia segala jenis permainan poker online kini semakin banyak ditemukan di Internet, salah satunya TahunQQ merupakan situs Agen Judi Domino66 Dan BandarQ Terpercaya yang mampu memberikan banyak provit bagi bettornya. Permainan Yang Di Sediakan Dewi365 Juga sangat banyak Dan menarik dan Peluang untuk memenangkan Taruhan Judi online ini juga sangat mudah . Mainkan Segera Taruhan Sportbook anda bersama Agen Judi Bola Bersama Dewi365 Kemenangan Anda Berapa pun akan Terbayarkan. Tersedia 9 macam permainan seru yang bisa kamu mainkan hanya di dalam 1 ID saja. Permainan seru yang tersedia seperti Poker, Domino QQ Dan juga BandarQ Online. Semuanya tersedia lengkap hanya di ABGQQ. Situs ABGQQ sangat mudah dimenangkan, kamu juga akan mendapatkan mega bonus dan setiap pemain berhak mendapatkan cashback mingguan. ABGQQ juga telah diakui sebagai Bandar Domino Online yang menjamin sistem FAIR PLAY disetiap permainan yang bisa dimainkan dengan deposit minimal hanya Rp.25.000. DEWI365 adalah Bandar Judi Bola Terpercaya & resmi dan terpercaya di indonesia. Situs judi bola ini menyediakan fasilitas bagi anda untuk dapat bermain memainkan permainan judi bola. Didalam situs ini memiliki berbagai permainan taruhan bola terlengkap seperti Sbobet, yang membuat DEWI365 menjadi situs judi bola terbaik dan terpercaya di Indonesia. Tentunya sebagai situs yang bertugas sebagai Bandar Poker Online pastinya akan berusaha untuk menjaga semua informasi dan keamanan yang terdapat di POKERQQ13. Kotakqq adalah situs Judi Poker Online Terpercayayang menyediakan 9 jenis permainan sakong online, dominoqq, domino99, bandarq, bandar ceme, aduq, poker online, bandar poker, balak66, perang baccarat, dan capsa susun. Dengan minimal deposit withdraw 15.000 Anda sudah bisa memainkan semua permaina pkv games di situs kami. Jackpot besar,Win rate tinggi, Fair play, PKV Games