fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Mon Jun 25 13:20:00 2018 +0000
Revision:
13:8ea85a33e37a
Parent:
12:06ea96546af1
Child:
14:af3adf5d5ddf
add random pulse feature

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 2:0c241937eabd 5
gwappa 11:897ecd5413e0 6 const uint64_t MicrosecondsInSecond = 1000000;
gwappa 11:897ecd5413e0 7
gwappa 2:0c241937eabd 8 void Trial::reset(const Task& task){
gwappa 2:0c241937eabd 9 // reset score
gwappa 2:0c241937eabd 10 response = TrialFlags::Clear;
gwappa 2:0c241937eabd 11
gwappa 2:0c241937eabd 12 // set delay duration
gwappa 5:849446d19406 13 delay_dur_ms = task.delay_min_ms.value
gwappa 5:849446d19406 14 + random::exponential(task.delay_var_ms.value, task.delay_var_ms.value*3);
gwappa 2:0c241937eabd 15
gwappa 11:897ecd5413e0 16 aud_ticker_cycle = MicrosecondsInSecond/(task.aud_tick_hz.value * 2);
gwappa 11:897ecd5413e0 17
gwappa 13:8ea85a33e37a 18 // generate visual stimulus
gwappa 13:8ea85a33e37a 19 if ((task.mode.value == Report) || (task.mode.value == Associate)) {
gwappa 13:8ea85a33e37a 20 assignRandomStim(task);
gwappa 13:8ea85a33e37a 21 } else {
gwappa 13:8ea85a33e37a 22 vis_cued = false;
gwappa 13:8ea85a33e37a 23 vis_dur_ms = 0;
gwappa 13:8ea85a33e37a 24 vis_onset_ms = 0;
gwappa 13:8ea85a33e37a 25 }
gwappa 2:0c241937eabd 26
gwappa 3:991c6d5ce19d 27 // reset interrupt events
gwappa 3:991c6d5ce19d 28 licking_events.clear();
gwappa 3:991c6d5ce19d 29 whisking_events.clear();
gwappa 2:0c241937eabd 30 }
gwappa 2:0c241937eabd 31
gwappa 13:8ea85a33e37a 32 void Trial::assignRandomStim(const Task& task)
gwappa 13:8ea85a33e37a 33 {
gwappa 13:8ea85a33e37a 34 const uint32_t phasedur_us = ms_to_us(task.aud_dur_ms.value);
gwappa 13:8ea85a33e37a 35 const uint32_t respdur_us = ms_to_us(task.resp_dur_ms.value);
gwappa 13:8ea85a33e37a 36 const uint32_t mindur_us = ms_to_us(task.vis_min_ms.value);
gwappa 13:8ea85a33e37a 37 const double failure_perc = (double)(task.vis_fail_perc.value);
gwappa 13:8ea85a33e37a 38
gwappa 13:8ea85a33e37a 39 const double validphase = (double)(phasedur_us - respdur_us - mindur_us);
gwappa 13:8ea85a33e37a 40 const double taudenom = 2.0 - ::log(failure_perc);
gwappa 13:8ea85a33e37a 41 const uint32_t tau = (uint32_t)(validphase/taudenom + 0.5);
gwappa 13:8ea85a33e37a 42 const uint32_t onset = random::exponential(tau, validphase);
gwappa 13:8ea85a33e37a 43
gwappa 13:8ea85a33e37a 44 if (onset < validphase) {
gwappa 13:8ea85a33e37a 45 // generate duration
gwappa 13:8ea85a33e37a 46 const uint32_t durvar = validphase - onset;
gwappa 13:8ea85a33e37a 47 const uint32_t duration = random::unif(durvar) + mindur_us;
gwappa 13:8ea85a33e37a 48
gwappa 13:8ea85a33e37a 49 visualOut.setDuration(duration);
gwappa 13:8ea85a33e37a 50 visualOut.setOnset(onset);
gwappa 13:8ea85a33e37a 51
gwappa 13:8ea85a33e37a 52 vis_cued = true;
gwappa 13:8ea85a33e37a 53 vis_dur_ms = (duration + 500)/1000;
gwappa 13:8ea85a33e37a 54 vis_onset_ms = (onset + 500)/1000;
gwappa 13:8ea85a33e37a 55 } else {
gwappa 13:8ea85a33e37a 56 // no pulse; wait for the user to call stop??
gwappa 13:8ea85a33e37a 57 visualOut.setOnset(onset + 1000000);
gwappa 13:8ea85a33e37a 58
gwappa 13:8ea85a33e37a 59 vis_cued = false;
gwappa 13:8ea85a33e37a 60 vis_dur_ms = 0;
gwappa 13:8ea85a33e37a 61 vis_onset_ms = 0;
gwappa 13:8ea85a33e37a 62 }
gwappa 13:8ea85a33e37a 63 }
gwappa 13:8ea85a33e37a 64
gwappa 11:897ecd5413e0 65 void Trial::markTrialStart() {
gwappa 11:897ecd5413e0 66 starting = timer.read_ms();
gwappa 12:06ea96546af1 67 trialStart.run();
gwappa 11:897ecd5413e0 68 timer.start();
gwappa 11:897ecd5413e0 69 }
gwappa 11:897ecd5413e0 70
gwappa 11:897ecd5413e0 71 void Trial::markEndOfWait() {
gwappa 11:897ecd5413e0 72 cuestarting = timer.read_ms();
gwappa 11:897ecd5413e0 73 waiting = cuestarting - starting;
gwappa 11:897ecd5413e0 74 }
gwappa 11:897ecd5413e0 75
gwappa 11:897ecd5413e0 76 void Trial::markTrialEnd() {
gwappa 12:06ea96546af1 77 trialEnd.run();
gwappa 11:897ecd5413e0 78 trialEnd.wait();
gwappa 11:897ecd5413e0 79 writeToSerial();
gwappa 11:897ecd5413e0 80 timer.stop();
gwappa 11:897ecd5413e0 81 timer.reset();
gwappa 11:897ecd5413e0 82 }
gwappa 11:897ecd5413e0 83
gwappa 2:0c241937eabd 84 void Trial::writeToSerial() {
gwappa 2:0c241937eabd 85 switch(response){
gwappa 2:0c241937eabd 86 #define WRITE_SCORE(SC,REPR) case SC: IO::write("%c%s;",IO::RESULT_HEADER,REPR); break;
gwappa 2:0c241937eabd 87 WRITE_SCORE(Responses::Hit, "hit")
gwappa 2:0c241937eabd 88 WRITE_SCORE(Responses::Miss, "miss")
gwappa 2:0c241937eabd 89 WRITE_SCORE(Responses::Catch, "catch")
gwappa 2:0c241937eabd 90 WRITE_SCORE(Responses::Reject, "reject")
gwappa 2:0c241937eabd 91 WRITE_SCORE(Responses::Reset, "reset")
gwappa 2:0c241937eabd 92 #undef WRITE_SCORE
gwappa 8:973dcd190672 93 case Responses::NA:
gwappa 8:973dcd190672 94 default:
gwappa 8:973dcd190672 95 IO::write("%c%s(%x);",IO::RESULT_HEADER,"na",response);
gwappa 2:0c241937eabd 96 }
gwappa 2:0c241937eabd 97
gwappa 3:991c6d5ce19d 98 IO::write("wait%u",waiting);
gwappa 13:8ea85a33e37a 99
gwappa 13:8ea85a33e37a 100 if (vis_cued) {
gwappa 13:8ea85a33e37a 101 IO::write(";visual(onset%u,duration%u)",vis_onset_ms,vis_dur_ms);
gwappa 13:8ea85a33e37a 102 }
gwappa 13:8ea85a33e37a 103
gwappa 3:991c6d5ce19d 104 trialtime_t zero = (response == Responses::Reset)? starting : cuestarting;
gwappa 3:991c6d5ce19d 105 IO::write(";whisk");
gwappa 3:991c6d5ce19d 106 whisking_events.writeToSerial(zero);
gwappa 3:991c6d5ce19d 107 IO::write(";lick");
gwappa 3:991c6d5ce19d 108 licking_events.writeToSerial(zero);
gwappa 4:fcf597f82632 109 IO::write(";\r\n");
gwappa 2:0c241937eabd 110 }