Keisuke Sehara
/
STM32_Whisking
fast-feedback virtual target task code on STM Nucleo
trial.cpp
- Committer:
- gwappa
- Date:
- 2018-07-02
- Revision:
- 19:50663f8815b8
- Parent:
- 17:0b241aa1f5b6
- Child:
- 20:4c06d3041337
File content as of revision 19:50663f8815b8:
#include "trial.h" #include "rig.h" #include "IO.h" #include "random.h" #include "events.h" const uint64_t MicrosecondsInSecond = 1000000; void TrialFlag::reset() { cued = false; responded = false; reset = false; } void writeToSerial() { if (reset) { IO::write("reset"); } else if (cued) { IO::write(responded? "hit":"miss"); } else { IO::write(responded? "catch":"reject"); } } void Trial::reset(const Task& task){ // reset score flag.reset(); // set delay duration delay_dur_ms = task.delay_min_ms.value + random::exponential(task.delay_var_ms.value, task.delay_var_ms.value*3); aud_ticker_cycle = MicrosecondsInSecond/(task.aud_tick_hz.value * 2); // generate visual stimulus visualOut.setEnabled(false); vis_dur_us = 0; vis_onset_us = 0; switch (task.mode.value) { case Pair: vis_onset_us = ms_to_us(task.pre_min_ms.value); vis_dur_us = ms_to_us(task.vis_avg_ms.value); visualOut.setEnabled(true); visualOut.setOnset(vis_onset_us); visualOut.setDuration(vis_dur_us); rewardOut.setOnset(ms_to_us(task.reward_on_ms.value)); rewardOut.setDuration(ms_to_us(task.reward_dur_ms.value)); break; case Report: case Associate: assignRandomStim(task); // fallthrough case Motion: case MotionAlt: rewardOut.setOnset(0); rewardOut.setDuration(ms_to_us(task.reward_dur_ms.value)); break; } // reset interrupt events licking_events.clear(); whisking_events.clear(); } void Trial::assignRandomStim(const Task& task) { const uint32_t phasedur_us = ms_to_us(task.aud_dur_ms.value); const uint32_t minonset_us = ms_to_us(task.pre_min_ms.value); const uint32_t respdur_us = ms_to_us(task.resp_dur_ms.value); const uint32_t avgdur_us = ms_to_us(task.vis_avg_ms.value); const uint32_t mindur_us = ms_to_us(task.vis_min_ms.value); const double failure_perc = (task.vis_fail_perc.value > 0)? ((double)(task.vis_fail_perc.value)):1e-6; const double onsetvar = (double)(phasedur_us - minonset_us - respdur_us - mindur_us); const double taudenom = ::log(100.0) - ::log(failure_perc); const double ftau = onsetvar/taudenom; const uint32_t tau = (uint32_t)(ftau + 0.5); const uint32_t onset_us = random::exponential(tau, onsetvar+10) + minonset_us; const uint32_t maxonset_us = onsetvar + minonset_us; if (onset_us < maxonset_us) { // generate duration const uint32_t durvar = maxonset_us - onset_us; const uint32_t dur_us = random::exponential(avgdur_us - mindur_us, durvar) + mindur_us; visualOut.setEnabled(true); visualOut.setDuration(dur_us); visualOut.setOnset(onset_us); vis_dur_us = dur_us; vis_onset_us = onset_us; } else { // no pulse visualOut.setEnabled(false); vis_dur_us = 0; vis_onset_us = 0; } } void Trial::markTrialStart() { starting = timer.read_ms(); trialStart.run(); timer.start(); } void Trial::markEndOfWait() { cuestarting = timer.read_ms(); waiting = cuestarting - starting; } void Trial::markTrialEnd() { trialEnd.run(); trialEnd.wait(); writeToSerial(); timer.stop(); timer.reset(); } void Trial::writeToSerial() { IO::write("%c",IO::RESULT_HEADER); flag.writeToSerial(); IO::write(";wait%u", waiting); if (visualOut.isEnabled() && (response != Responses::Reset)) { IO::write(";visual(onset%u,duration%u)",vis_onset_us,vis_dur_us); } trialtime_t zero = (flag.reset)? starting : cuestarting; IO::write(";whisk"); whisking_events.writeToSerial(zero); IO::write(";lick"); licking_events.writeToSerial(zero); IO::write(";\r\n"); }