fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Mon Jun 25 17:43:40 2018 +0000
Revision:
15:20f7f737c256
Parent:
14:af3adf5d5ddf
Child:
16:33c17c62840e
fix weird behavior and validate visual stim duration

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