murthylab / fly-vr

FlyVR is code for design and control of multisensory virtual reality experiments for flies.
https://github.com/murthylab/fly-vr
3 stars 5 forks source link

Feature to get an experiment to automatically stop after all playlist items have been played #19

Closed davidt0x closed 2 years ago

davidt0x commented 2 years ago

Feature to get an experiment to automatically stop after all playlist items have been played (e.g. line of code we can write into an experiment.py), instead of manually clicking the UI button.

nzjrs commented 2 years ago

for context: https://github.com/murthylab/fly-vr/issues/15

blocked by 'who decides the end in a general case in a multi backend experiment with different playlists'? the longest union of playlists when all were stopped? ultimately there was not enough state to know that there was no possibility for an externa API call to not continue playing by switching to another item, so I elected to allow such logic to be in the python code if one does an Experment.py experiment, or in the yaml explicitly based on time - because if done explicitly in the yaml which will contain all stims for all backends the writer of the yaml at that time has the best and most correct definition of when the total experiment is finished

mwangq commented 2 years ago

Ah!! @nzjrs thanks so much for bringing this to my attention. I was able to get this to work in the time/do stanza, but I have not figured out how to implement this in the experiment.py file. Following your example in flyvr design I tried to write something that shows a stimulus a few times (randomly picking) and then stops the experiment but Max and I couldn't figure out how to get the experiment to stop... exp_a_stop.txt

(sorry for the .txt file, it won't let me drag a .py in) I tried these in line 40 Experiment._shared_state.signal_stop().join(timeout=5) // AttributeError: type object 'Experiment' has no attribute '_shared_state' Experiment.stop() // just doesn't stop self.stop() // also doesn't work - sorry I forgot to write down the error message for this

nzjrs commented 2 years ago

Ah!! @nzjrs thanks so much for bringing this to my attention. I was able to get this to work in the time/do stanza, but I have not figured out how to implement this in the experiment.py file. Following your example in flyvr design I tried to write something that shows a stimulus a few times (randomly picking) and then stops the experiment but Max and I couldn't figure out how to get the experiment to stop... exp_a_stop.txt

(sorry for the .txt file, it won't let me drag a .py in) I tried these in line 40 Experiment._shared_state.signal_stop().join(timeout=5) // AttributeError: type object 'Experiment' has no attribute '_shared_state' Experiment.stop() // just doesn't stop self.stop() // also doesn't work - sorry I forgot to write down the error message for this

ok, this seems like a bug where the Experiment object does not have _shared_state set. Are you launching this the normal flyvr.exe way, or are you launching the experiment process manually?

If launching manually, this line should be called https://github.com/murthylab/fly-vr/blob/9c3bca18c8c4dda2ac97f82ea727c29c722ac4c6/flyvr/fictrac/fictrac_driver.py#L122

which means that Experiment.stop() should not crash.

mwangq commented 2 years ago

hmmm I was launching the normal way. Here's the command from Cmder:

flyvr -c config_avd_items.yml -e exp_a_stop.py --fictrac_version 2

nzjrs commented 2 years ago

ok, can you check the log to see if it prints this message

https://github.com/murthylab/fly-vr/blob/9c3bca18c8c4dda2ac97f82ea727c29c722ac4c6/flyvr/fictrac/fictrac_driver.py#L111

mwangq commented 2 years ago

are you referring to this type of log?

fictrac-20220211_141159.log

no, I don't see any mention of "experiment"

nzjrs commented 2 years ago

no, not that log. the console output.

On Fri, 11 Feb 2022 at 21:25, mwangq @.***> wrote:

are you referring to this type of log?

fictrac-20220211_141159.log https://github.com/murthylab/fly-vr/files/8051442/fictrac-20220211_141159.log

no, I don't see any mention of "experiment"

— Reply to this email directly, view it on GitHub https://github.com/murthylab/fly-vr/issues/19#issuecomment-1036593114, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAKHI2YHWDXROWR75NLJUDU2VWDFANCNFSM5N3QYDQA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

mwangq commented 2 years ago

which line should I test with (in the .py file), is it this one: Experiment.stop() ?

not Experiment._shared_state.signal_stop().join(timeout=5) ?

will report back in a few...

nzjrs commented 2 years ago

which line should I test with (in the .py file), is it this one: Experiment.stop() ?

not Experiment._shared_state.signal_stop().join(timeout=5) ?

will report back in a few...

self.stop() but if there isn't a log of the experiment being initialized then there is a bug somewhere else

mwangq commented 2 years ago

oof. I did a bunch of testing and it is unclear to me what the pattern/problem/output is.

with the .py file I wrote above (where I try to play some audio, and after some number of times playing, I want to stop the experiment), with Experiment.stop() the initialization line shows up in the console: flyvr.fictrac.FicTracDriver : INFO initialized experiment <exp_a_stop._MyExperiment object at 0x000001B37F05C488> and also this error:

Process Process-3:
Traceback (most recent call last):
  File "C:\Users\murthylab\miniconda3\envs\flyvr\lib\multiprocessing\process.py", line 297, in _bootstrap
    self.run()
  File "C:\Users\murthylab\miniconda3\envs\flyvr\lib\multiprocessing\process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "c:\fly-vr\flyvr\fictrac\fictrac_driver.py", line 189, in run
    self.experiment.process_state(data_copy)
  File "exp_a_stop.py", line 40, in process_state
    Experiment.stop()
TypeError: stop() missing 1 required positional argument: 'self'

with self.stop(), SOMETIMES experiment is there flyvr.fictrac.FicTracDriver : INFO initialized experiment <exp_a_stop._MyExperiment object at 0x00000209EC20D408> but it ignores the exp file and just plays the playlist in order on repeat!

OTHER TIMES it does not work at all, most recently using: exp_a_stop.txt config_a_items.txt I used the same config and decided to just write a super basic experiment "stop experiment after 10 sec" and this resulted in the same below error. exp_stop_self.txt

Process Process-3:
Traceback (most recent call last):
  File "c:\fly-vr\flyvr\control\experiment.py", line 265, in new_from_python_file
    exp = getattr(mod, 'experiment')
AttributeError: 'NoneType' object has no attribute 'experiment'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\murthylab\miniconda3\envs\flyvr\lib\multiprocessing\process.py", line 297, in _bootstrap
    self.run()
  File "C:\Users\murthylab\miniconda3\envs\flyvr\lib\multiprocessing\process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "c:\fly-vr\flyvr\fictrac\fictrac_driver.py", line 109, in run
    setup_experiment(options)
  File "c:\fly-vr\flyvr\common\build_arg_parser.py", line 181, in setup_experiment
    _experiment_obj = Experiment.new_from_python_file(options.experiment_file)
  File "c:\fly-vr\flyvr\control\experiment.py", line 270, in new_from_python_file
    raise RuntimeError('experiment python file must define single variable of type Experiment')
RuntimeError: experiment python file must define single variable of type Experiment

also - just to make sure i wasn't going crazy - I also ran an audiovisual set (audiovisual playlist and randomization in experiment.py file) from yesterday and this worked...

nzjrs commented 2 years ago

Calling Experiment.stop() isn't going to work, I wrote that just to unambiguously convey the function name. It's not a class or static method so it's self.stop()

Strange that the bug seems not reliably reproducible.

nzjrs commented 2 years ago

Oh and it also could be that RuntimeError: experiment python file must.... is the error that gets printed if there is a syntax error or exception in or before __init__()

Easiest way to check for syntax errors is from memory, just to run the experiment.py aka $ python experiment.py - I'm pretty sure it will no-op but at least the interpreter checks the syntax.

mwangq commented 2 years ago

ah! thanks for the suggestion. yeah there was an extra space creating an indent issues. got self.stop( ) to work. thanks so much!