gentnerlab / pyoperant

python package for operant conditioning
BSD 3-Clause "New" or "Revised" License
13 stars 15 forks source link

rewrite experiment protocols to use nested iterators instead of state machine #84

Open neuromusic opened 9 years ago

neuromusic commented 9 years ago

based on conversation with @MarvinT & @wohlmp, the goal here is to rewrite the basic experiment protocol.

this will involve defining objects to handle Blocks and Trials that we will iterate over. e.g.

blocks = BlockHandler(subject)
for block in blocks:
    trials = TrialHandler(block)
    for trial in trials:
        trial.run()

importantly, BlockHandler & TrialHandler would be objects maintaining the logic of generating blocks and trials, respectively, from simple generation (e.g. random) to complex generation (e.g. multiple-staircase procedures or switching between tasks depending on past performance)

combined with #83, this should make it way easier to create new behavioral tasks without needing to inherit or rewrite the base experiment logic

further, this should help fix #69 #83 #41

would love thoughts on this from @siriuslee, too

neuromusic commented 9 years ago

see also #85

siriuslee commented 9 years ago

I definitely think this would be a good idea. How would you suggest this work? Would these classes be instantiated in the renewed config file? Would the previous block and trial iterators be rewritten as classes to be used/ inherited from? Also, how would they replace the state machine? It seems trial.run() would involve one.

I like all of the ideas laid out in those other issues and it seems like they could address most of the hitches I found when implementing our experiment.

On Fri Dec 19 2014 at 12:05:50 PM Justin Kiggins notifications@github.com wrote:

see also #85 https://github.com/gentnerlab/pyoperant/issues/85

— Reply to this email directly or view it on GitHub https://github.com/gentnerlab/pyoperant/issues/84#issuecomment-67690049.

neuromusic commented 9 years ago

Marvin has the vision for this rewrite, so I'll defer to him, but based on our conversation earlier...

Would the previous block and trial iterators be rewritten as classes to be used/inherited from? Yes, exactly.

Also, how would they replace the state machine? It seems trial.run() would involve one. In my attempts to be extensible we really have a mess of multiple state machines running. We would probably keep the highest-level one that toggles between the Idle state and the Sleep and Session states. Within the Session, we would use the nice readable iterators as shown above. And inside of Trial, we would need some kind of logic for doing the Stimulus->Response->Consequence flow, which doesn't necessarily need to happen as a "state machine" per se.

(as an aside, this might also be good time to look into running a Trial in its own thread. see #14)

Would these classes be instantiated in the renewed config file? Maybe. This is the BIG QUESTION with all of this... what features get incorporated into the core? which ones can be changed by manipulating a config file? and which ones necessitate inheriting and customizing core components?

I think that everyone using this will have trials that can be organized into blocks. That much of the logic can definitely be standardized. Users need room to define and generate blocks (this is what @wohlmp is dealing with currently that motivated this conversation) and room to define and generate trials.

siriuslee commented 9 years ago

What is the current status of this update? I'd be interested in helping out but would like to know of any progress in either planning or coding.

neuromusic commented 9 years ago

I'm just leaving this here, as it might serve to be useful... https://github.com/hsharrison/experimentator