PsychoPy: make trials happen with keypress until routine ends at time x - psychopy

I have a routine with multiple possible trials (in a loop), and the participant must press a key to go to the next trial. I want these trials to go on (with keypresses) until a certain time has passed of the routine, say 5 seconds, regardless of how many possible trials are left in my conditionsFile. At the 5-second mark, the routine should end.
(If this is relevant: each trial is only displayed once.)
I've tried a few things, all of which only end up making the routine skip to the next trial after 5 seconds, but still going through all the possible trials, i.e. not ending the routine at 5 s.
For example, I've tried adding:
# ------Prepare to start Routine "Images"-------
continueRoutine = True
routineTimer.add(5)
and then
# -------Run Routine "Images"-------
while continueRoutine and routineTimer.getTime() > 0:
I've also tried adding this to the while sequence from above:
if image.status == STARTED:
# is it time to stop? (based on global clock, using actual start)
if tThisFlipGlobal > image.tStartRefresh + 5.0-frameTolerance:
# keep track of stop time/frame for later
image.tStop = t # not accounting for scr refresh
image.frameNStop = frameN # exact frame index
win.timeOnFlip(image, 'tStopRefresh') # time at next scr refresh
image.setAutoDraw(False)
Can anyone help?

Related

Will this timer code work for calling Python function every X seconds?

I have a Python thread, and in it, I attempt to call a function, wait X seconds after it finishes, then repeats indefinitely (runs as a Windows service).
I am using the code below. Based on the code below, since I am incrementing "count" every minute, theoretically, is there a case where this could "overflow" if it runs for a long time (like if I lowered it down to every 2 seconds or something very small)?
Is this method overkill if all I need to do is wait till the function finishes and then do it again after approximately (doesn't have to be precise) X seconds?
Code:
def g_tick():
t = time.time()
count = 0
while True:
count += 1
logging.debug(f"Count is: {count}")
yield max(t + count*60 - time.time(), 0) # 1 Minute Intervals (300/60 secs)
g = g_tick()
while True:
try:
processor_work() # this function does work and returns when complete
except Exception as e:
log_msg = f"An exception occurred while processing tickets due to: {e}"
logging.exception(log_msg)
time.sleep(next(g))

PedSelectOutPut routing pedestrians inconsistently

I am simulating the passenger changeover process in metros using the Anylogic Pedestrian Library.
When passengers enter the vehicle, a seat is assigned to them from the seats available near the door (within a given distance) they entered the vehicle through, using a function called lookForSeat. If there is no more free seat available, their boolean parameter wantToSit is set to false and they will stay standing.
The parameter wantToSit is predefined for the Passenger Agent, with default value randomtrue(0.8). But even if I set it to default value = 1, I get the same error.
Then, passengers are separated using a PedSelectOutput block:
Condition 1: if ped.WantToSit = true --> they are sent to their
assigned seat coordinates (PointNode 'seatPoint', null by default)
Condition 2: true (thus, ped.WantToSit = false) --> they stay in the
standing area in the vehicle, no assigned seatPoint necessary in this case.
Now, it works pretty well, but when the majority of the seats is already occupied, suddenly the PedSelectOutput block directs a passenger with ped.wantToSit to its seating point, which gives null and I get the NullPointerException error.
Attached you find the function, the settings of PedSelectOutput and the log from the command.
As it can be seen, the PedSelectOutput sends the passenger through exit 1 (which gives the error due to calling the coordinates of a "null"), despite ped.wantToSit = false.
Any ideas, what is going wrong? For me it really looks like the function is working properly - I have been changing it the whole day until I realized that something in the PedSelectOutput block goes wrong.
Thank you in advance!
Pic 1: pedSelectOutput block and the command with the log
Pic 2: the function lookForSeat assigning the seats from the seat Collection
The problem here is a subtle one, which has caused me many hours of debugging as well. What you need to understand is that the on exit code is only executed once the agent already has a path to which it is going to exit. i.e. the selectOutput and subsequent blocks are already evaluated and only once it is determined that the agent can move to the next block then the on exit code is called. But the agent will continue on its chosen path that has been determined before the on exit code has been executed.
See the small example below:
I have a pedestrian with a variable that is true by default and a select output that checks this value
If I ran the model all pedestrians exit at the top option, as expected
If I change the variable to false on the On Exit code I might expect that all pedestrians will now exit at the second option
But they don't there is no change....
If I add the code to the on enter code then it does..

GtkTreeView stops updating unless I change the focus of the window

I have a GtkTreeView object that uses a GtkListStore model that is constantly being updated as follows:
Get new transaction
Feed data into numpy array
Convert numbers to formatted strings, store in pandas dataframe
Add updated token info to GtkListStore via GtkListStore.set(titer, liststore_cols, liststore_data), where liststore_data is the updated info, liststore_cols is the name of the columns (both are lists).
Here's the function that updates the ListStore:
# update ListStore
titer = ls_full.get_iter(row)
liststore_data = []
[liststore_data.append(df.at[row, col])
for col in my_vars['ls_full'][3:]]
# check for NaN value, add a (space) placeholder is necessary
for i in range(3, len(liststore_data)):
if liststore_data[i] != liststore_data[i]:
liststore_data[i] = " "
liststore_cols = []
[liststore_cols.append(my_vars['ls_full'].index(col) + 1)
for col in my_vars['ls_full'][3:]]
ls_full.set(titer, liststore_cols, liststore_data)
Class that gets the messages from the websocket:
class MyWebsocketClient(cbpro.WebsocketClient):
# class exceptions to WebsocketClient
def on_open(self):
# sets up ticker Symbol, subscriptions for socket feed
self.url = "wss://ws-feed.pro.coinbase.com/"
self.channels = ['ticker']
self.products = list(cbp_symbols.keys())
def on_message(self, msg):
# gets latest message from socket, sends off to be processed
if "best_ask" and "time" in msg:
# checks to see if token price has changed before updating
update_needed = parse_data(msg)
if update_needed:
update_ListStore(msg)
else:
print(f'Bad message: {msg}')
When the program first starts, the updates are consistent. Each time a new transaction comes in, the screen reflects it, updating the proper token. However, after a random amount of time - seen it anywhere from 5 minutes to over an hour - the screen will stop updating, unless I change the focus of the window (either activate or inactive). This does not last long, though (only enough to update the screen once). No other errors are being reported, memory usage is not spiking (constant at 140 MB).
How can I troubleshoot this? I'm not even sure where to begin. The data back-ends seem to be OK (data is never corrupted nor lags behind).
As you've said in the comments that it is running in a separate thread then i'd suggest wrapping your "update liststore" function with GLib.idle_add.
from gi.repository import GLib
GLib.idle_add(update_liststore)
I've had similar issues in the past and this fixed things. Sometimes updating liststore is fine, sometimes it will randomly spew errors.
Basically only one thread should update the GUI at a time. So by wrapping in GLib.idle_add() you make sure your background thread does not intefer with the main thread updating the GUI.

Catchpoint pause vs. waitForNoRequest - What's the difference?

I have a test that was alerting because it was taking extra time for an asset to load. We changed from waitForNoRequest to a pause (at Catchpoint's suggestion). That did not seem to have the expected effect of waiting for things to load. We increased the pause from 3000 to 12000 and that helped to allow the page to load and stop the alert. We noticed some more alerts, so I tried to increase the pause to something like 45000 and it would not allow me to pause for that long.
So the main question here is - what functionality does both of these different features provide? What do I gain by pausing instead of waiting, if anything?
Here's the test, data changed to protect company specific info. Step 3 is where we had some failures and we switched between pause and wait.
// Step - 1
open("https://website.com/")
waitForNoRequest("2000")
click("//*[#id=\"userid\"]")
type("//*[#id=\"userid\"]", "${username}")
setStepName("Step1-Login-")
// Step - 2
clickMouseAndWait("//*[#id=\"continue\"]")
waitForVisible("//*[#id=\"challenge-password\"]")
click("//*[#id=\"challenge-password\"]")
type("//*[#id=\"challenge-password\"]", "${password}")
setStepName("Step2-Login-creds")
// Step - 3
clickMouseAndWait("//*[#id=\"signIn\"]")
setStepName("Step3-dashboard")
waitForTitle("Dashboard")
waitForNoRequest("3000")
click("//*[#id=\"account-header-wrapper\"]")
waitForVisible("//*[#id=\"logout-link\"]")
click("//*[#id=\"logout-link\"]")
// Step - 4
clickAndWait("//*[text()=\"Sign Out\"]")
waitForTitle("Login - ")
verifyTextPresent("You have been logged out.")
setStepName("Step5-Logout")
Rachana here, I’m a member of the Technical Service Team here at Catchpoint, I’ll be happy to answer your questions.
Please find the differences below between waitForNoRequest and Pause commands:
Pause
Purpose: This command pauses the script execution for a specified amount of time, whether there are HTTP/s requests downloading or not. Time value is provided in milliseconds, it can range between 100 to 30,000 ms.
Explanation: This command is used when the agent needs to wait for a set amount of time and this is not impacted by the way the requests are loaded before proceeding to the next step or command. Only a parameter is required for this action.
WaitForNoRequest
Purpose: This commands waits for a specified amount of time, when there was no HTTP/s requests downloading. The wait time parameter can range between 1,000 to 5,000 ms.
Explanation: The only parameter for this action is a wait time. The agent will wait for that specified amount of time before moving onto the next step/command. Which will, in return, allow necessary requests more time to load after document complete.
For instance when you add waitforNoRequest(5000), initially agent waits 5000 ms after doc complete for any network activity. During that period if there is any network activity, then the agent waits another 5000 ms for the next network activity to end and the process goes on until no other request loads within the specified timeframe(5000 ms).
A pause command with 12000 ms, gives exactly 12 seconds to load the page. After 12 seconds the script execution will continue to next command no matter the page is loaded or not.
Since waitForNoRequest has a max time value of 5000 ms, you can tell the agent to wait for a gap of 5 seconds when there is no network activity. In this case, the page did not have any network activity for 3 seconds and hence proceeded to the next action. The page was not loaded completely and the script failed.
I tried to increase the pause to something like 45000 and it would not allow me to pause for that long.
We allow a maximum of 30 seconds pause time hence 45 seconds will not work.
Please reach out to our support team and we’ll be glad to connect you with our scripting SMEs and help you with any scripting needs you might have.

set fixation events in psychopy/ioHub for eyelink dataviewer

I am using psychopy and iohub to collect eyetracking data collection with the eyelink (sr research) system. I would like to be able to set two things up: fixation events (where fixation for 100ms at a certain point is required for the next part of the task/new trial to occur) and "interest areas": basically, areas that are pre-defined regions so that I can analyze gaze duration in specific regions. The code I'm using is just the generic stuff I got psychopy for eyetracking (I'm no coding expert) and I can't figure out how to modify it to do these two things.
Thanks!
In your question, "fixation events" and "interest areas" seem to be effectively the same thing from a calculation point of view.
I guess the essence is that on every frame, you check the current gaze position, and monitor if a fixation within the relevant AOI has lasted at least 100 ms, or whatever duration is required.
I'm assuming you're using Builder
Pseudo-code:
Begin Routine:
fixation_started = False
Each Frame:
if gaze position is in AOI: # pseudo-code
if not fixation_started:
fixation_start_time = t
fixation_started = True
# else fixation has started, so check duration:
elif t - fixation_start_time > 0.100:
# do whatever, as this fixation has exceeded 100 ms
else: # subject is looking elsewhere:
fixation_started = False