fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Mon Jul 02 08:26:44 2018 +0000
Revision:
19:50663f8815b8
Parent:
17:0b241aa1f5b6
Child:
20:4c06d3041337
try changing the flag system over to a set of booleans

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