fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Sat Jun 30 12:28:18 2018 +0000
Revision:
16:33c17c62840e
Parent:
15:20f7f737c256
Child:
17:0b241aa1f5b6
add delay for reward in the Pair paradigm

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gwappa 2:0c241937eabd 1 #include "trial.h"
gwappa 11:897ecd5413e0 2 #include "rig.h"
gwappa 2:0c241937eabd 3 #include "IO.h"
gwappa 2:0c241937eabd 4 #include "random.h"
gwappa 14:af3adf5d5ddf 5 #include "events.h"
gwappa 2:0c241937eabd 6
gwappa 11:897ecd5413e0 7 const uint64_t MicrosecondsInSecond = 1000000;
gwappa 11:897ecd5413e0 8
gwappa 2:0c241937eabd 9 void Trial::reset(const Task& task){
gwappa 2:0c241937eabd 10 // reset score
gwappa 2:0c241937eabd 11 response = TrialFlags::Clear;
gwappa 2:0c241937eabd 12
gwappa 2:0c241937eabd 13 // set delay duration
gwappa 5:849446d19406 14 delay_dur_ms = task.delay_min_ms.value
gwappa 5:849446d19406 15 + random::exponential(task.delay_var_ms.value, task.delay_var_ms.value*3);
gwappa 2:0c241937eabd 16
gwappa 11:897ecd5413e0 17 aud_ticker_cycle = MicrosecondsInSecond/(task.aud_tick_hz.value * 2);
gwappa 11:897ecd5413e0 18
gwappa 13:8ea85a33e37a 19 // generate visual stimulus
gwappa 15:20f7f737c256 20 visualOut.setEnabled(false);
gwappa 16:33c17c62840e 21 vis_dur_us = 0;
gwappa 16:33c17c62840e 22 vis_onset_us = 0;
gwappa 15:20f7f737c256 23
gwappa 15:20f7f737c256 24 switch (task.mode.value) {
gwappa 15:20f7f737c256 25 case Pair:
gwappa 16:33c17c62840e 26 vis_onset_us = ms_to_us(task.pre_min_ms.value);
gwappa 16:33c17c62840e 27 vis_dur_us = ms_to_us(task.vis_avg_ms.value);
gwappa 15:20f7f737c256 28 visualOut.setEnabled(true);
gwappa 16:33c17c62840e 29 visualOut.setOnset(vis_onset_us);
gwappa 16:33c17c62840e 30 visualOut.setDuration(vis_dur_us);
gwappa 16:33c17c62840e 31 rewardOut.setOnset(ms_to_us(task.reward_on_ms.value));
gwappa 16:33c17c62840e 32 rewardOut.setDuration(ms_to_us(task.reward_dur_ms.value));
gwappa 15:20f7f737c256 33 break;
gwappa 15:20f7f737c256 34 case Report:
gwappa 15:20f7f737c256 35 case Associate:
gwappa 16:33c17c62840e 36 assignRandomStim(task);
gwappa 14:af3adf5d5ddf 37 visualOut.attachTurnOnCallback(&events::gate);
gwappa 16:33c17c62840e 38 // fallthrough
gwappa 16:33c17c62840e 39 case Motion:
gwappa 16:33c17c62840e 40 case MotionAlt:
gwappa 16:33c17c62840e 41 rewardOut.setOnset(0);
gwappa 16:33c17c62840e 42 rewardOut.setDuration(ms_to_us(task.reward_dur_ms.value));
gwappa 15:20f7f737c256 43 break;
gwappa 13:8ea85a33e37a 44 }
gwappa 2:0c241937eabd 45
gwappa 3:991c6d5ce19d 46 // reset interrupt events
gwappa 3:991c6d5ce19d 47 licking_events.clear();
gwappa 3:991c6d5ce19d 48 whisking_events.clear();
gwappa 2:0c241937eabd 49 }
gwappa 2:0c241937eabd 50
gwappa 13:8ea85a33e37a 51 void Trial::assignRandomStim(const Task& task)
gwappa 13:8ea85a33e37a 52 {
gwappa 13:8ea85a33e37a 53 const uint32_t phasedur_us = ms_to_us(task.aud_dur_ms.value);
gwappa 15:20f7f737c256 54 const uint32_t minonset_us = ms_to_us(task.pre_min_ms.value);
gwappa 13:8ea85a33e37a 55 const uint32_t respdur_us = ms_to_us(task.resp_dur_ms.value);
gwappa 14:af3adf5d5ddf 56 const uint32_t avgdur_us = ms_to_us(task.vis_avg_ms.value);
gwappa 13:8ea85a33e37a 57 const uint32_t mindur_us = ms_to_us(task.vis_min_ms.value);
gwappa 15:20f7f737c256 58 const double failure_perc = (task.vis_fail_perc.value > 0)? ((double)(task.vis_fail_perc.value)):1e-6;
gwappa 13:8ea85a33e37a 59
gwappa 15:20f7f737c256 60 const double onsetvar = (double)(phasedur_us - minonset_us - respdur_us - mindur_us);
gwappa 14:af3adf5d5ddf 61 const double taudenom = ::log(100.0) - ::log(failure_perc);
gwappa 15:20f7f737c256 62 const double ftau = onsetvar/taudenom;
gwappa 14:af3adf5d5ddf 63 const uint32_t tau = (uint32_t)(ftau + 0.5);
gwappa 15:20f7f737c256 64 const uint32_t onset = random::exponential(tau, onsetvar) + minonset_us;
gwappa 13:8ea85a33e37a 65
gwappa 15:20f7f737c256 66 if (onset < onsetvar) {
gwappa 13:8ea85a33e37a 67 // generate duration
gwappa 15:20f7f737c256 68 const uint32_t durvar = onsetvar - onset;
gwappa 15:20f7f737c256 69 const uint32_t duration = random::exponential(avgdur_us - mindur_us, durvar) + mindur_us;
gwappa 13:8ea85a33e37a 70
gwappa 15:20f7f737c256 71 visualOut.setEnabled(true);
gwappa 13:8ea85a33e37a 72 visualOut.setDuration(duration);
gwappa 13:8ea85a33e37a 73 visualOut.setOnset(onset);
gwappa 13:8ea85a33e37a 74
gwappa 16:33c17c62840e 75 vis_dur_us = duration;
gwappa 16:33c17c62840e 76 vis_onset_us = onset;
gwappa 13:8ea85a33e37a 77 } else {
gwappa 15:20f7f737c256 78 // no pulse
gwappa 15:20f7f737c256 79 visualOut.setEnabled(false);
gwappa 16:33c17c62840e 80 vis_dur_us = 0;
gwappa 16:33c17c62840e 81 vis_onset_us = 0;
gwappa 13:8ea85a33e37a 82 }
gwappa 13:8ea85a33e37a 83 }
gwappa 13:8ea85a33e37a 84
gwappa 11:897ecd5413e0 85 void Trial::markTrialStart() {
gwappa 11:897ecd5413e0 86 starting = timer.read_ms();
gwappa 12:06ea96546af1 87 trialStart.run();
gwappa 11:897ecd5413e0 88 timer.start();
gwappa 11:897ecd5413e0 89 }
gwappa 11:897ecd5413e0 90
gwappa 11:897ecd5413e0 91 void Trial::markEndOfWait() {
gwappa 11:897ecd5413e0 92 cuestarting = timer.read_ms();
gwappa 11:897ecd5413e0 93 waiting = cuestarting - starting;
gwappa 11:897ecd5413e0 94 }
gwappa 11:897ecd5413e0 95
gwappa 11:897ecd5413e0 96 void Trial::markTrialEnd() {
gwappa 12:06ea96546af1 97 trialEnd.run();
gwappa 11:897ecd5413e0 98 trialEnd.wait();
gwappa 11:897ecd5413e0 99 writeToSerial();
gwappa 11:897ecd5413e0 100 timer.stop();
gwappa 11:897ecd5413e0 101 timer.reset();
gwappa 11:897ecd5413e0 102 }
gwappa 11:897ecd5413e0 103
gwappa 2:0c241937eabd 104 void Trial::writeToSerial() {
gwappa 2:0c241937eabd 105 switch(response){
gwappa 2:0c241937eabd 106 #define WRITE_SCORE(SC,REPR) case SC: IO::write("%c%s;",IO::RESULT_HEADER,REPR); break;
gwappa 2:0c241937eabd 107 WRITE_SCORE(Responses::Hit, "hit")
gwappa 2:0c241937eabd 108 WRITE_SCORE(Responses::Miss, "miss")
gwappa 2:0c241937eabd 109 WRITE_SCORE(Responses::Catch, "catch")
gwappa 2:0c241937eabd 110 WRITE_SCORE(Responses::Reject, "reject")
gwappa 2:0c241937eabd 111 WRITE_SCORE(Responses::Reset, "reset")
gwappa 2:0c241937eabd 112 #undef WRITE_SCORE
gwappa 8:973dcd190672 113 case Responses::NA:
gwappa 8:973dcd190672 114 default:
gwappa 8:973dcd190672 115 IO::write("%c%s(%x);",IO::RESULT_HEADER,"na",response);
gwappa 2:0c241937eabd 116 }
gwappa 2:0c241937eabd 117
gwappa 3:991c6d5ce19d 118 IO::write("wait%u",waiting);
gwappa 13:8ea85a33e37a 119
gwappa 16:33c17c62840e 120 if (visualOut.isEnabled() && (response != Responses::Reset)) {
gwappa 16:33c17c62840e 121 IO::write(";visual(onset%u,duration%u)",vis_onset_us,vis_dur_us);
gwappa 13:8ea85a33e37a 122 }
gwappa 13:8ea85a33e37a 123
gwappa 3:991c6d5ce19d 124 trialtime_t zero = (response == Responses::Reset)? starting : cuestarting;
gwappa 3:991c6d5ce19d 125 IO::write(";whisk");
gwappa 3:991c6d5ce19d 126 whisking_events.writeToSerial(zero);
gwappa 3:991c6d5ce19d 127 IO::write(";lick");
gwappa 3:991c6d5ce19d 128 licking_events.writeToSerial(zero);
gwappa 4:fcf597f82632 129 IO::write(";\r\n");
gwappa 2:0c241937eabd 130 }