variable stimuli duration but two kinds of fixed ISI in PsychoPy - python

I'm totally new to PsychoPy and I'm working with Builder. I'm not familiar with Python coding at all.
I have audio stimuli that have variable durations. In each trial, I want the second stimulus to start 500ms or 1500ms after the end of the first stimulus. Is there a way to do this in Builder? If I have to do it on Coder, what should I do?
Thank you very much!

Absolutely. Think of 500ms and 1500ms as two different conditions that you loop over in addition. These two conditions are crossed with the different durations.
In you conditions file, where you have the different durations (or you could just do that using a random function of course), for every duration add two rows with a column "soa" (or whatever you want to call it) with the two values 500ms and 1500ms. In the builder interface you can choose whether order of presentation should be sequential, randomized within block or fully randomized across all trials (not just within block). Also, if you don't want it balanced (e.g. 20% 1500ms and 80% 500ms), you can just add the appropriate number of rows to achieve this balance (1 out of 5 is 1500 ms).
Nearly all demos handles trials in this way, so take a look in Builder --> Demos, click on the loop and see how it's done there. Also, read the relevant section of the online documentation and see a video tutorial also incorporating it.

In concrete terms, when you add a Sound component in Builder, you just need to add an expression in the "Start (time)" field that takes account of the duration of the first sound stimulus and the ISI for this trial.
So if you have a column for the ISI in the conditions file as Jonas suggests (let's say it is called "ISI") and a Sound component for the first auditory stimulus (called, say, "sound1"), then you could put this in the Start field of the second sound stimulus:
$sound1.getDuration() + ISI
The $ symbol indicates that this line is to be interpreted as a Python code expression and not as a literal duration.
This assumes that sound1 starts at the very beginning of a trial. If it starts, say 1 second into the trial, then just add a constant to the expression:
$1.0 + sound1.getDuration() + ISI
Your ISI column should contain values in seconds. If you prefer milliseconds, then do this:
$sound1.getDuration() + ISI/1000.0

Related

Is there way to force SUMO to load vehicles every X seconds (time steps)

I am using planner to plan vehicle routes, i create plan every X seconds (usually 20), for that i need vehicles loaded before they enter network (e.g. from time 0 to 20). For now i accomplish this by parsing the routes.rou.xml file, but i would like to be able to do this using TraCI.
I read at: https://sumo.dlr.de/docs/Simulation/VehicleInsertion.html, that vehicles are loaded in chunks, but by setting "--route-steps 0" i can load all vehicles at once (all of them are in traci.simulation.getLoadedIDList() at time step 0), which is not ideal for longer simulation with thousands of cars, but even with the vehicles loaded, I am unable to find any function to retrieve their time of departure. At: https://sumo.dlr.de/docs/TraCI/Vehicle_Value_Retrieval.html#Device_and_LaneChangeModel_Parameter_Retrieval_0x7e I didnt find any variable corresponding to departure time of vehicle and traci.vehicle.getParameter(vehicle_id, 'depart') returns empty string.
So i would like to know how to either force SUMO to load vehicles every X seconds (time steps), or find time of departure of vehicle (found by their id) using TraCI.
If I understand your question correctly you want to force sumo to always read ahead the route file for at least X seconds and to retrieve the intended departure time via traci. I am afraid both things are currently not possible. The --route-steps you mentioned allows to configure the look ahead in a way but only to define the chunk size sumo reads so --route-steps 100 will read 0 to 100 first then 100 to 200 and so on. So most of the time you may have the required look ahead but not always. Furthermore you cannot retrieve intended departure via traci yet, but there is at least an open ticket for that: https://github.com/eclipse/sumo/issues/7693. Maybe leave a comment there so that people know it is still needed. Until then parsing the route file is your only option, unfortunately.

Interpretation of the default time system within Simpy

so I have more of a general question that I can't wrap my head around, and I haven't seen explicitely explained within the docs. So let's take a random two events from my simulation (what they exactly are shouldn't matter in the scope of this question)
10.1622 Customer02: Do something
13.6176 Customer08: Do somethiing
The first column is the internal time these events took place. Can I ask someone to explain what is the interpretation of these numbers? Are these simply meant to be real world seconds, meaning that 3.5~~ real world seconds passed between the first event and the second in the simulation and that the first event took place 10 real world seconds into the simulation?
What is the practice if I want times in my simulation (like interval between customers arriving, the time it takes to serve a customer) etc. to be expressed in real-world time? Let's say I have a variable "intervalbetweencustomers" which is set at "10.0" at the moment. If I want it to have the value of a real-world minute, how do i do that?
The "tick" of the simpy clock can be in any unit you want (seconds, minutes, hours, ect)
Tick are not integers so you can have half a tick.
Just pick a unit and convert everything to that unit when you need a time related parameter for a simpy function like env.timeout
simpy does not have a time units as a parameter so any conversion you will need to do yourself. There are python libraries if you need to convert dates, or the difference between two dates, to a number

I am unable to randomize blocks in my Psychopy study? What can I do?

:slight_smile:
What are you trying to achieve?:
I am currently doing a reaction time and accuracy task that involves comparing visually presented numerical information and auditory numerical information. The visually presented numerical information will be presented in three forms - Arabic numerals (e.g 5), number words (e.g five), and non-symbolic magnitude (a picture of 5 dots). Both visual numerical information and auditory numerical information will be presented sequentially. After the presentation of the 2nd stimulus, participants are to respond if these two stimuli are conveying the same information or not. They are supposed to press “a” if the numerical information is the same and “l” if it’s different.
Apart from varying the format of the visual numerical stimuli I am presenting, I also intend to vary the stimulus onset asynchrony (SOA)/time interval between the two stimuli. I have 7 levels of time intervals/SOAs (plus minus 750, 250 and 500, and 0ms), resulting in me creating my experiment in such a manner (see attached picture).
One set of fixation_cross and VA_750ms (for example) constitutes a block. Hence, in total, there are 7 blocks here (only 4 are pictured though). I have already randomized the trials within each block. The next step for me is to randomize the presentation of these blocks, with one block denoting one level of SOA/time interval (e.g +750ms). To do this, I’ve placed a loop around all the blocks, with this loop titled “blocknames” in the picture. While the experiment still works fine, randomization still doesn’t occur.
I understand that there was a post addressing the randomization of blocks, but I felt that it was more specific to experiments that only have one routine. This is not very feasible for my case considering that I would have to vary the time interval between two numerical stimuli within a trial.
What did you try to make it work?:
Nevertheless, I’ve tried to create an excel file with the names of the excel files in each condition - across all routines, the excel files actually contain the same information, but they’re just named differently according to what the condition name is (e.g AV500ms, VA750ms). In this case, the experiment still works, but the blocks are still not being randomized.
What specifically went wrong when you tried that?:
With the same excel file, I also tried to label my conditions as $condsFile instead of using the exact document location, but this was what I got instead.
At the same time, I was wondering if I could incorporate my SOA/time interval levels into Excel instead - how would this be carried out in Builder?
This might be some useful background info on my Psychopy software and laptop.
OS (e.g. Win10): Win 10
PsychoPy version (e.g. 1.84.x): 2020.1.3
Standard Standalone? (y/n) Yes,
I apologize if this might have been posted a few times. However, I’ve tried to apply these solutions according to what my experiment requires, but to no avail. I’m also quite a new user to Psychopy and am not very sure on how to proceed from here as well. Would really appreciate any advice on this!
This isn't really a programming question per se, as it can be addressed entirely by using the graphical Builder interface of PsychoPy. In the future, you should probably address such questions to the dedicated support forum at https://discourse.psychopy.org rather than here at Stack Overflow.
In essence, your experiment should have a much simpler structure. Embed your two trial routines within a trials loop. After that loop, insert your break routine. Lastly, embed the whole lot within an outer blocks loop. i.e. your experiment will show only three routines and two loops, not the very long structure you currently have. The nested loops means the two trial routines will run on very trial, while the break routine will run only once per block.
The key aspect to controlling the block order is the outer blocks loop. Connect it to a conditions file that looks like this:
condition_file
block_1.csv
block_2.csv
block_3.csv
block_4.csv
block_5.csv
block_6.csv
block_7.csv
And set the loop to be be "random".
In the inner trials loop, put the variable name $condition_file in the conditions file field. So you now will have the order of blocks randomised across your subjects.
The other key aspect you need to learn is to control more of the task using variables contained within each of your conditions files. e.g. you are currently creating a separate routine for each ISI value (e.g. AV500ms and AV750ms). Instead, you should just have a single routine, called say AV. Make the timings of the stimulus components within that routine be controlled by a variable from your conditions file.
A key principle of programming is DRY: Don't Repeat Yourself (and although you aren't directly programming, under the hood, PsychoPy Builder will generate a Python program for you). Creating multiple routines that differ only in one respect is an indicator that things are not being specified optimally. By having only one routine, if you need to alter it in some way, you only have to do it once, rather than repeat it 7 times. The latter approach is very fragile and hard to maintain, and can easily lead to errors.
There is a resource on controlling blocks of trials here:
https://www.psychopy.org/builder/blocksCounterbalance.html

what steps I should follow to identify the difference in the time

I have an excel, where a start and end time is given of a particular user and I have to take out the difference using python, The doubt I have is the start and the end time is given one below the another.
I am confused how do I separate the start and end time of user and then calculate the difference.
snap of the data
what steps should I take or the logic I should use?
This video should help along with the functionality of your code here
For logic, you could use a for loop to parse through each line using for i in range(sheet.nrows) or something near that and every time it runs the loop add a number to the counter, if the numbers odd save the value to a start time list or dictand if the values even save the value to an end time list or dict

How can I use machine learning to convert orientation sensor data into movement events?

I built a device based on a microcontroller with some sensors attached to it, one of them is an orientation sensor that currently delivers information about pitch, yaw, roll and acceleration for x,y,z. I would like to be able to detect movement "events" when the device is well... moved around.
For example I would like to detect a "repositioned" event which basically would consist of series of other events - "up" (picked up), "move" (moved in air to some other point), "down" (device put back down).
Since I am just starting to figure out how to make it possible I would like to ask if I am getting the right ideas or wasting my time.
My idea is currently that I use the data I probed to create a dataset and try to use machine learning to detect if each element belongs to one of the events I am trying to detect. So basically I took the device and first rotated it on table a few times, then picked it up several times, then moved it in the air and finally put it down several times. This generated a set of data that has a structure like that:
yaw,pitch,roll,accelx,accely,accelz,state
-140,178,178,17,-163,-495,stand
110,-176,-166,-212,-97,-389,down
118,-177,178,123,16,-146,up
166,-174,-171,-375,-145,-929,up
157,-178,178,4,-61,-259,down
108,177,-177,-55,76,-516,move
152,178,-179,35,98,-479,stand
175,177,-178,-30,-168,-668,move
100,177,178,-42,26,-447,stand
-14,177,179,42,-57,-491,stand
-155,177,179,28,-57,-469,stand
92,-173,-169,347,-373,-305,down
[...]
the last "state" column is added by me - I added this after each test movement type and then shuffled the rows.
I got about 450 records this way and the idea is to use the machine learning to predict the "state" column for each record coming from the running device, then I could queue up the outcomes and if in some short period the "up" events are majority I can take it the device is being picked up.
Maybe instead of using each reading as a data row I should rather take the last 10 readings (lets say) and try to predict what happens per column - i.e. if I know last 10 yaw readings were the changes during I was moving the device up I should rather use this data - so 10 readings from each of the 6 columns is processed as row and then I have 6 results - again the ratio of result types may make it possible to detect the "movement" event that happened during these 10 readings.
I am currently about 30% into an online ML course and enjoying it but I'd really like to hear some comments from more experienced people.
Are my ideas a reasonable solution or am I totally failing to understand how I can use ML? If so, what resources shall I use to get myself started?
Your idea to regroup the reading seems interesting. But it all depends on how often you get a record and how you plan on grouping them.
If you get a record every 10-100ms, it could be a good idea to group them since it will help to have more accurate data reducing noise. You could take the mean of each column to get rid of that noise and help your classifier to better classify your different states.
Otherwise if you have a record every second, I think it's a bad idea to regroup the records since you will most certainely mix several actions together.
The best way would be to try out both ways if you have the time ^^

Categories