Sign up Calendar Latest Topics
 
 
 


Reply
  Author   Comment  
aboharbf

Member
Registered:
Posts: 97
Reply with quote  #1 
Hey All,

I have a userloop task that works well, but requires me to manually stop it once I've gotten enough trials. I would like to either take advantage of the spaces in the panel (if userloop has access to them) or know which functions to introduce to the userloop or timing file to bring about this functionality.

Edit: In the same vein, I want to control something in the userloop using a variable from the timing file (set through the edittable variables table). I would think to approach this by asking the userloop to grab the variable from the edditables

switch = str2double(TrialRecord.Editable.switch);

Issue is the userloop is read first, which means TrialRecord is empty. Is there some conditional to distinguish the 'pre-Run' read to the 'post-run' read, and I can move operations dependent on timing file variables to the latter?

Thanks a lot.
0
Jaewon

Administrator
Registered:
Posts: 971
Reply with quote  #2 
See the second table in the following manual page.

https://monkeylogic.nimh.nih.gov/docs_TrialRecordStructure.html

If you set TrialRecord.Quit to true in the userloop, the task ends as soon as the userloop returns.

If you set TrialRecord.Pause to true in the userloop, you have to wait until a trial is finished. It is because the trial has already begun, when the userloop is called.

-----

Regarding to accessing editables from the userloop, I think you are not returning properly at the first userloop call. The userloop is called once, before a task starts (before the pause menu shows up). For this very first call, the userloop function is supposed to return immediately with the list of timing file names.

There is an example task written in the 'task\userloop\3 access editables from userloop' directory for this situation. Also you can take a look at the following manual page and the 'task\userloop\1 dms with userloop\dms_userloop.m' file.

https://monkeylogic.nimh.nih.gov/docs_CreatingTask.html#Userloop
0
aboharbf

Member
Registered:
Posts: 97
Reply with quote  #3 
Hey Jaewon,

Thanks a ton for the answer. I had all of the userloop running in its entirety in the pre-screen time, adding a field check for the edittables structure (as in the example you pointed out) fixed it. 

In regards to the TrailRecord.Quit, I used the following:

if block > MLConfig.TotalNumberOfBlocksToRun
TrialRecord.Quit = 1;
return
end

It does quit the task, but results in an error.

Index exceeds the number of array elements (0).

Error in mltaskobject/subsref (line 229)
case 'Info', for m=1:narr, varargout{m} = obj.(s(2).subs)(s(1).subs{1}(m)).(s(3).subs); end

Error in fixate_reward_runtime (line 970)
stim_start=TaskObject(sample).Info.stimStart;

Error in run_trial (line 124)
runtime(MLConfig,TrialRecord,TaskObject,TrialData);

Error in monkeylogic/UIcallback (line 828)
result = run_trial(MLConfig,datafile);

Error while evaluating UIControl Callback.



Running this on the Jan 14th 2019 version, build 167. I see the chain involves a variable I am defined based on TaskObject

Edit: I see the error is caused by a structure I'm not providing for the final trial that needs to be run. Is there a reason for the behavior being coded like this? If a block is 6 trials, and you want to run 2, why not stop it before trial 13? I've basically gotten that by implementing the below:

if ((correct_trial_count+1)/total_conditions) == MLConfig.TotalNumberOfBlocksToRun
TrialRecord.Pause = 1;
end

0
Jaewon

Administrator
Registered:
Posts: 971
Reply with quote  #4 
Quitting immediately after the userloop was added later. Please update your NIMH ML.
0
aboharbf

Member
Registered:
Posts: 97
Reply with quote  #5 
After testing it, Quit seems to work as described, Pause still waits until after the first trial of n+1 blocks (n = what you set in the panel).
0
Jaewon

Administrator
Registered:
Posts: 971
Reply with quote  #6 
I told you about the behavior of the Pause above. Technically Quit should wait till the end of a trial, too, when it is set in the userloop. Allowing the immediate break makes the task flow kind of messy, but I added it just for convenience.

You can set those flags (Quit and Pause) in the timing files and alert_function, too. In the timing file, the result of the current trial is not registered yet, so you need to count both TrialRecord.TrialErrors and the result of the current trial. In the alert_function, you can count just TrialRecord.TrialErrors.
https://monkeylogic.nimh.nih.gov/board/read.php?2,6,6#msg-6


0
aboharbf

Member
Registered:
Posts: 97
Reply with quote  #7 
Ah I see, I would have imagined both pause and quit would not intentionally play a different number of trials prior to enacting their functions, and that pause adding an additional trial was by mistake.

the alert_function is fantastic, and was just what I needed for something else. For now I'll try to run w/ quit in the userloop and see it how goes. Thanks a lot.
0
Jaewon

Administrator
Registered:
Posts: 971
Reply with quote  #8 
Making an exception in TrialRecord.Quit's behavior is so confusing, so I am reverting the change. From now on, you have to wait till the end of a trial, to see the effect of both TrialRecord.Pause and TrialRecord.Quit.

Instead, to stop tasks immediately after a userloop, assign a negative number, like -1, to TrialRecord.NextBlock during the userloop.
0
Previous Topic | Next Topic
Print
Reply

Quick Navigation:

Easily create a Forum Website with Website Toolbox.