REM >5-nmCAM REM REM<<<<<<>>>>>>> REM Description of task:- REM Phase one (attention) - Light presented in one of five spatial locations REM Ratty must detect light by nose poking hole in which light appears - delay starts REM Phase two - Ratty is presented with a choice where two lights are presented REM Ratty must poke hole which was the same as hole that was presented in Phase one REM Ratty gets two pellets. REM 22-Jul-99 Implemented session time limit (2.5h). Doesn't abort ongoing trials, REM but stops the box after the current trial has finished. REM 28-Sept-99 Ratty is getting too fat....bigbonus has been reduced to 1 pellet. REM 7-Oct-99 Performance dropping with 1 pellet. Increased to 2 again. REM 23-Nov-99 Changed from AttMem to CAM with incorporation of independent starting of REM boxes. And option not to print. REM And aborting didn't kill all timers. Now it does. REM 18-April-00 Changed display box to incorporate number incorrect trials. REM REM 23 May 2000. Variable number of stimuli in choice phase. REM 03 Sept 00 Extra measures incorporated - # panel pushes during each delay (and mean) REM and number of responses in each hole during delay (in order to REM assist mediating analysis). REM 03 Sept 00 Problems - I've prgmed it so the number of panel pushes and responses to REM same and other holes during delay are recorded in the log file (trial by REM trial analysis). REM 24 Sept 00 For some reason, forgot to include mag lat for each trial. Thats added now. REM Thought I had done it but hadn't. Must have overwritten in the process REM of copying prgms. Anyway, done it on 16-10-00. REM For mediating purposes, need to know which holes ratty pokes during delay period. REM How the hell am I going to do this???!!! REM 29 Sept 00 Have now included a third file (response file) which records location of REM nosepoke during delay. REM REM 27 Feb 01 Attempting to include houselight as a distractor stimulus ie. houselight must go REM on and off throughout the delay interval. Can't do it! Will see Rudy. REM 13 Mar 01 Rudy sorted out flashing houselight during delay period. REM 26 Jun 03 Traylights made more sensible (see 5-CAM). REM 30 Jun 04 Requirement for rat to poke >1 time per stimulus in phase 1: npokes_per_stimulus()% REM This number of pokes must occur within the limited hold period, or the trial is terminated without reward. REM 13 Sep 04 Olivia says program fails to load ("Bad program"). Longest lines shortened REM (lines too long = commonest cause of that error when loading?) REM This version of Cam does not time out when ratty is anticipating. REM For new training version, initally one light will be presented as choice REM with central pellet prior to multiple choice phase. REM Rudy sorted out delays so that delay is random in REM in quadruples. 08-01-01 LIBRARY ".ProgLibs.Arachnid" LIBRARY ".ProgLibs.Ascii" LIBRARY ".ProgLibs.BoxConst" LIBRARY ".ProgLibs.DateTime" LIBRARY ".ProgLibs.Filename" LIBRARY ".ProgLibs.Random" LIBRARY ".ProgLibs.Spool" LIBRARY ".ProgLibs.UI" progname$ = "CAM Task" version_date$ = "12-Jan-2000" printing%=0 PROCinit PROCkill_all PROCfive_hole_boxes_yogi MODE 12 dummy% = RND(-TIME) PROCbox_set_up matching%=yes% PROCget_parameters PROCdisplay_startup FOR box% = 1 TO nboxes% started%(box%) = no% finished%(box%) = no% PROCpipe_fkey(box%,1,0,"FNabort_box(",box%,E%) NEXT PROCpipe_keybd(0,0,0,"FNcam_keyboard_handler(",0,E%) PROCwait(E%):*AE PROCkill_all END REM _______________________________________________________ DEF PROCbox_set_up ntrials% = 100 max_responses% = 1000 REM How many responses to record. Have to try it and see - memory-dependent. ndelay_options% = 4 initial_iti_timer% = 0 * nboxes% darkness_iti_timer% = 1 * nboxes% limited_hold_timer% = 2 * nboxes% pellet_dispenser_timer% = 3 * nboxes% choice_limited_hold_timer% = 4 * nboxes% timeout_timer% = 5 * nboxes% delay_timer% = 6 * nboxes% eating_timer% = 7 * nboxes% stimulus_timer% = 8 * nboxes%: REM first/second stage stim. timer houselight_flash_timer% = 9 * nboxes%: REM timers for houselight flashing REM _____________________________________ parameters/session info DIM rat_id$(nboxes%) DIM session_number%(nboxes%) DIM treatment$(nboxes%) DIM delay_option%(nboxes%,ndelay_options%) DIM max_delay%(nboxes%) DIM time_out%(nboxes%) DIM stimulus_duration%(nboxes%) DIM choice_duration%(nboxes%) DIM brightness_level%(nboxes%): REM not implemented DIM flashing_houselight%(nboxes%) DIM limited_hold%(nboxes%) DIM choice_limited_hold%(nboxes%) DIM darkness_iti%(nboxes%) DIM training%(nboxes%) :REM if yes, phase 1 only (and rewarded); if no, phase 1 -> phase 2. DIM numtrials%(nboxes%) DIM min_phase2_stim%(nboxes%) DIM max_phase2_stim%(nboxes%) DIM npokes_per_stimulus%(nboxes%) REM ____________________________stuff we're recording for phase 1 DIM panels_during_initial_iti%(nboxes%,ntrials%) :REM # panel-pushes while waiting for stim. onset DIM panels_during_delay%(nboxes%,ntrials%) :REM # panel pushes during delay DIM anticipatory_nosepokes%(nboxes%,ntrials%) :REM number of pokes in any hole before stim. onset DIM offered_hole%(nboxes%,ntrials%) :REM which hole did the light come on in? (1-5) DIM chosen_hole%(nboxes%,ntrials%) :REM where did the rat go? (0=omission) DIM num_correct_phase1_pokes%(nboxes%,ntrials%) :REM number of pokes in correct hole (30 June 2004) DIM num_incorrect_phase1_pokes%(nboxes%,ntrials%) :REM number of pokes in incorrect hole (30 June 2004) DIM latency_to_detect_light%(nboxes%,ntrials%) :REM from light onset -> poke (0=it was in already) (invalid if omission) DIM record_correct_response%(nboxes%,ntrials%) :REM did the rat manage to complete phase 1? DIM record_incorrect_response%(nboxes%,ntrials%) :REM superfluous DIM record_omissions%(nboxes%,ntrials%) :REM superfluous DIM perseverative_nosepokes_to_same_hole%(nboxes%,ntrials%) :REM #pokes in correct hole after stim. offset DIM perseverative_nosepokes_to_all_other_holes%(nboxes%,ntrials%) :REM total #pokes in all other holes after stim. offset DIM latency_to_panelpush%(nboxes%,ntrials%) :REM time from light-poke -> collect reward (training) or just poke (testing) at panel DIM percent_accuracy%(nboxes%) :REM superfluous DIM phase1_correct%(nboxes%) DIM phase1_incorrect%(nboxes%) DIM phase1_omissions%(nboxes%) DIM training_pellets%(nboxes%) REM ____________________________stuff we're recording for phase 2 DIM programmed_delay%(nboxes%,ntrials%) DIM experienced_delay%(nboxes%,ntrials%) :REM how long a delay did it *get*? DIM num_phase2_stimuli%(nboxes%,ntrials%) DIM false_holes%(nboxes%,ntrials%,nholes%) :REM the distractor holes in phase 2 - each slot is filled by 1 (on) or 0 (off). DIM phase2_chosen_hole%(nboxes%,ntrials%) :REM which hole did it go to? (0=omission) DIM recorded_responses%(nboxes%) :REM how many individual responses have we recorded for this box? DIM response_trial%(nboxes%,max_responses%) :REM which trial was it on? DIM response_location%(nboxes%, max_responses%) :REM which holes did it go to. DIM latency_to_respond%(nboxes%,ntrials%) :REM time from stim2 onset -> poke (anywhere) DIM choice_omissions%(nboxes%,ntrials%) DIM phase2_omissions%(nboxes%) :REM superfluous DIM total_pellets%(nboxes%) DIM phase2_numpellets%(nboxes%) DIM phase2_correct%(nboxes%) DIM phase2_incorrect%(nboxes%) DIM collecting_bigbonus_latency%(nboxes%,ntrials%) REM _________________________________________ flags and internal variables DIM started%(nboxes%) DIM finished%(nboxes%) DIM trial%(nboxes%) DIM nosepoke_state%(nboxes%) DIM stim1_on_at%(nboxes%) DIM stim1_off_at%(nboxes%) DIM delay_pushed%(nboxes%) DIM stim2_on_at%(nboxes%) DIM stim2_off_at%(nboxes%) DIM delay_began_at%(nboxes%) DIM session_began_at%(nboxes%) :REM to limit session time DIM current_trial_group_delay_order%(nboxes%, ndelay_options%) :REM holds current order of delays across a group of trials dont_care% = 0 :REM not interested in NP want_panelpush1% = 1 :REM Awaiting push at the panel at start of phase 1 initial_iti% = 2 :REM panel-push done, hanging around before stimulus stim1_on% = 3 :REM first stimulus is being presented OR stimulus has gone off but still in limited hold period darkness% = 4 :REM rat failed, awaiting new trial delay% = 5 :REM rat succeeded, delay before phase 2 delay_done% = 6 :REM rat succeeded, delay is finished, must panel-push for phase 2 presentation stim2_on% = 7 :REM phase 2 stimuli are on, awaiting choice OR stim off but in lim hold :REM anything but the correct response leads to darkness collecting_bigbonus% = 8 :REM it made the correct response; now waiting for it to collect the two pellets eating_up% = 9 :REM 5s to eat in the light; :REM after this it gets darkness and a new trial begins finished_state%=10 aborted_state%=11 overall_limit% = 150 :REM in minutes, the default overall session limit time initial_iti% = 500: REM iti time between panel push and onset of light signal timeout% = 500 pulse% = 10: REM pellet dispenser pulse pellet_gap% = 10 phase_1_numpellets% = 1 phase_2_numpellets% = 2 eating_time% = 500 :REM for Phase 2 BigBonus yes% = 1 no% = 0 DIM yesno$(1): yesno$(yes%) = "Y": yesno$(no%) = "N" ENDPROC DEF PROCget_parameters LOCAL box%, d% CLS COLOUR 5 PRINT TAB(5) "==================================================================" PRINT TAB(5) " Combined Attention and Working Memory Task " PRINT TAB(5) " Variable Choice (Match or Non-Match) " PRINT TAB(5) "==================================================================" COLOUR 7 date_time_code$ = FNdate_time_code PRINT:PRINT "Date/Time: ";date_time_code$ matching% = FNask_yes_no("Use MATCHING task? (Answering no gives NON-MATCHING) [YN]: ") PRINT overall_limit% = FNget_num_param("Overall session time limit (min)",overall_limit%,1,4*60) FOR box% =1 TO nboxes% REPEAT COLOUR 3:PRINT ''"Box number ";box%:COLOUR 7 rat_id$(box%) = FNget_str_param("Enter rat ID (NO COMMAS):", "???") session_number%(box%) = FNget_num_param("Enter session number", 1, 1, 1000) numtrials%(box%) = FNget_num_param("Number of trials",100,1,100) stimulus_duration%(box%) = FNget_num_param("Enter stimulus duration (csec)", 70, 70, 6000) limited_hold%(box%) = FNget_num_param("Enter limited hold (csec)", 500, 500, 6000) FOR d% = 1 TO ndelay_options% delay_option%(box%,d%) = FNget_num_param("Enter delay option "+STR$(d%)+" of "+STR$(ndelay_options%)+" (csec)", 0, 0, 6000) NEXT brightness_level%(box%) = FNget_num_param("NOT IMPLEMENTED - Enter level of brightness (1 to 10)", 10, 1, 10) flashing_houselight%(box%) = FNget_num_param("Flashing light distractor? (0=no, 1=yes)", 0, 0, 1) choice_duration%(box%) = FNget_num_param("Enter choice duration (csec)", 300, 100, 6000) darkness_iti%(box%) = FNget_num_param("Enter (darkness) inter trial interval (csec)", 1000, 200, 3000) choice_limited_hold%(box%) = FNget_num_param("Enter choice limited hold (csec)", 500, 500, 6000) min_phase2_stim%(box%) = FNget_num_param("Enter MINIMUM number of distractor stimuli in phase 2", 2, 1, nholes%) max_phase2_stim%(box%) = FNget_num_param("Enter MAXIMUM number of distractor stimuli in phase 2", 2, 1, nholes%) training%(box%) = FNget_num_param("Training? (0=no, 1=yes)", 0, 0, 1) treatment$(box%) = FNget_str_param("Treatment (NO COMMAS):", "Not specified") npokes_per_stimulus%(box%) = FNget_num_param("Number of pokes required per stimulus", 1, 1, 10) UNTIL FNask_yes_no("Are all task parameters correct?")=1 NEXT ENDIF PRINT' COLOUR 5 OSCLI("CAT") REPEAT PRINT datafile$ = FNget_filename("DATA FILE - Filename for output") logfile$ = FNget_filename("TEXT LOGFILE - Filename for output") responsefile$ = FNget_filename("RESPONSE FILE - Filename for output") IF (datafile$=logfile$ OR datafile$=responsefile$ OR logfile$=responsefile$) THEN PRINT"--- Unacceptable, can't have the same name for two." UNTIL NOT (datafile$=logfile$ OR datafile$=responsefile$ OR logfile$=responsefile$) COLOUR 3 PRINT''"YABADABADOO!!" PRINT "------------" PRINT'"Ensure rats in boxes. Press a key to start.";:COLOUR 7:IFGET ENDPROC DEF PROCstart_the_box(box%) LOCAL hole% trial%(box%) = 0 :REM FNstart_trial increments it to 1 for the first trial finished%(box%) = 0 nosepoke_state%(box%) = dont_care% FOR hole% = 1 TO nholes% PROCpipe_switch(nosepoke%(box%,hole%), On, 1, "FNnosepoke("+STR$(hole%)+",",box%,E%) NEXT PROCpipe_switch(panelpush%(box%), On, 1, "FNpanelpush(", box%, E%) PROCstart_session(box%) ENDPROC DEF PROCstart_session(box%) LOCAL dummy% PROCsingle_pellet(pellet_dispenser%(box%)) training_pellets%(box%) += 1 session_began_at%(box%) = TIME dummy% = FNstart_trial(box%, 1) ENDPROC DEF FNstart_trial(box%, R%) IF R%=0 =0 IF trial%(box%) = numtrials%(box%) OR TIME-session_began_at%(box%)>overall_limit%*60*100 THEN PROCset_state(box%,finished_state%) PROCfinished(box%) ELSE trial%(box%) += 1 PROCswitch_on(houselight%(box%),E%) REM PROCswitch_off(traylight%(box%),E%) PROCswitch_on(traylight%(box%),E%) :REM 26 June 2003 PROCset_state(box%, want_panelpush1%) PROCdisplay_box(box%) ENDIF =0 DEF PROCset_initial_iti(box%) PROCswitch_off(traylight%(box%),E%): REM 26 June 2003 PROCset_state(box%, initial_iti%) PROCpipe_timer(box% + initial_iti_timer%, initial_iti%, 0, "FNoffer_stimulus_1(",box%, E%) ENDPROC DEF FNoffer_stimulus_1(box%, R%) IF R% = 0 THEN = 0 LOCAL loop% PROCset_state(box%, dont_care%) :REM Rudolf's paranoia offered_hole%(box%,trial%(box%)) = FNrandom_integer(1,5) PROCswitch_on(aperturelight%(box%, offered_hole%(box%,trial%(box%))), E%) stim1_on_at%(box%) = TIME :REM time when light comes on PROCset_state(box%, stim1_on%) :REM deals with all nosepoking! PROCpipe_timer(box% + limited_hold_timer%, limited_hold%(box%), 0, "FNlimited_hold_up(", box%, E%) PROCpipe_timer(box% + stimulus_timer%, stimulus_duration%(box%), 0, "FNturn_off_stimulus_1(", box%, E%) :REM RNC, 12 Jan 2000 = 0 DEF FNturn_off_stimulus_1(box%, R%) REM RNC, 12 Jan 2000 IF R%=0 =0 PROCswitch_off(aperturelight%(box%, offered_hole%(box%, trial%(box%))), E%) REM leaves state unchanged (is still stim1_on%) =0 DEF FNlimited_hold_up(box%, R%) IF R% = 0 THEN = 0 PROCset_darkness(box%) record_omissions%(box%,trial%(box%)) += 1 phase1_omissions%(box%) +=1 = 0 DEF FNnew_trial(box%, R%) IF R% = 0 THEN = 0 PROCswitch_on(houselight%(box%), E%) PROCswitch_off(traylight%(box%), E%) PROCpipe_switch(panelpush%(box%),On, 1, "FNinter_trial_interval(", box%, E%) = 0 DEF PROCchoice_phase(box%) REM _____Rat has panel-poked at the end of the memory delay. PROCswitch_off(traylight%(box%),E%) REM _____Now give it Phase 2 choice, ie. choice lights come on REM Now, assign appropriate number of distractor holes, choosing them at random. LOCAL hole%, num_stim%, temp% num_stim% = FNrandom_integer( min_phase2_stim%(box%), max_phase2_stim%(box%) ) IF num_stim% > nholes% THEN num_stim% = nholes% num_phase2_stimuli%(box%,trial%(box%)) = num_stim% false_holes%(box%,trial%(box%),offered_hole%(box%,trial%(box%))) =yes% REM always want the offered hole included... :-) IF num_stim% > 1 THEN FOR temp%=1 TO num_stim%-1 REPEAT hole% = FNrandom_integer(1, nholes%) :REM picks a hole UNTIL false_holes%(box%,trial%(box%),hole%) = no% REM In principle, NASTY code. Slim potential for infinite loop, but never in practice. false_holes%(box%,trial%(box%),hole%) = yes% NEXT ENDIF FOR hole% = 1 TO nholes% IF false_holes%(box%,trial%(box%),hole%)=yes% THEN PROCswitch_on(aperturelight%(box%, hole%), E%) NEXT stim2_on_at%(box%) = TIME: REM Time when choice stimuli are presented PROCset_state(box%, stim2_on%) PROCpipe_timer(box% + choice_limited_hold_timer%, choice_limited_hold%(box%), 0, "FNchoice_limited_hold_up(",box%, E%) PROCpipe_timer(box% + stimulus_timer%, choice_duration%(box%), 0, "FNturn_off_choice_stimuli(", box%, E%) :REM RNC, 12 Jan 2000 ENDPROC DEF FNturn_off_choice_stimuli(box%, R%) REM RNC, 12 Jan 2000 IF R%=0 =0 LOCAL hole% FOR hole% = 1 TO nholes% PROCswitch_off(aperturelight%(box%, hole%), E%) NEXT =0 DEF FNchoice_limited_hold_up(box%, R%) IF R% = 0 THEN = 0 PROCset_darkness(box%) choice_omissions%(box%,trial%(box%)) += 1 phase2_omissions%(box%) +=1 = 0 REM ======================================================================== REM Nosepoke code REM Nosepoke *duration* is ignored. REM ======================================================================== DEF PROCset_state(box%, state%) nosepoke_state%(box%) = state% REM PROCcheck_np(box%) REM *** Removing the call to PROCcheck_np removes artefactual nosepoking REM on state changes. 22/6/99 RNC. PROCdisplay_state(box%) ENDPROC DEF PROCcheck_np(box%) LOCAL dummy%, hole% FOR hole% = 1 TO nholes% IF FNswitch(nosepoke%(box%,hole%),E%)=On THEN dummy%=FNnosepoke(hole%,box%,1) NEXT IF FNswitch(panelpush%(box%),E%)=On THEN dummy%=FNpanelpush(box%,1) ENDPROC DEF FNnosepoke(hole%,box%,R%) IF R%=0 =0 REM In this program, we're not interested in NP duration, so never look at leaving the magazine. CASE nosepoke_state%(box%) OF WHEN dont_care%: REM not interested in NP REM NOTHING. WHEN want_panelpush1%: REM Awaiting push at the panel at start of phase 1 REM NOTHING. WHEN initial_iti%: REM panel-push done, hanging around before stimulus anticipatory_nosepokes%(box%,trial%(box%)) +=1 WHEN stim1_on%: REM first stimulus is being presented IF chosen_hole%(box%, trial%(box%)) <> 0 THEN REM 30-June-2004: FIRST response latency_to_detect_light%(box%,trial%(box%)) = TIME - stim1_on_at%(box%) chosen_hole%(box%, trial%(box%)) = hole% ENDIF IF hole% = offered_hole%(box%,trial%(box%)) THEN REM 30-Jun-2004: require >1 poke, potentially num_correct_phase1_pokes%(box%,trial%(box%)) += 1 IF num_correct_phase1_pokes%(box%,trial%(box%)) >= npokes_per_stimulus%(box%) THEN REM 30-June-2004: correct, and has made *enough* correct responses PROCkill_timer(box% + limited_hold_timer%, E%) PROCswitch_off_all_holes(box%) record_correct_response%(box%,trial%(box%)) = yes% phase1_correct%(box%) += 1 IF training%(box%) THEN PROCspaced_pellet(pellet_dispenser%(box%), phase_1_numpellets%, pellet_dispenser_timer%+box%, pellet_gap%) training_pellets%(box%) += phase_1_numpellets% ENDIF PROCswitch_on(traylight%(box%), E%): REM 26 June 2003 REM switch on traylight whether or not they get a training pellet (to encourage them to REM panelpush at the start of the delay - not obligatory) stim1_off_at%(box%) = TIME delay_pushed%(box%) = no% PROCset_delay(box%) ELSE REM 30-June-2004: correct, but must carry on going! ENDIF ELSE REM incorrect PROCkill_timer(box% + limited_hold_timer%, E%) PROCswitch_off_all_holes(box%) num_incorrect_phase1_pokes%(box%,trial%(box%)) += 1 :REM 30-June-2004 record_incorrect_response%(box%,trial%(box%)) = yes% phase1_incorrect%(box%) += 1 PROCset_darkness(box%) ENDIF PROCdisplay_box(box%) WHEN darkness%: REM rat failed, awaiting new trial WHEN delay%: REM rat succeeded, delay before phase 2 PROCrecord_response(box%,hole%) IF hole% = offered_hole%(box%, trial%(box%)) THEN perseverative_nosepokes_to_same_hole%(box%, trial%(box%)) += 1 ELSE perseverative_nosepokes_to_all_other_holes%(box%, trial%(box%)) += 1 ENDIF WHEN delay_done%: REM rat succeeded, delay is finished, must panel-push for phase 2 presentation PROCrecord_response(box%,hole%) IF hole% = offered_hole%(box%, trial%(box%)) THEN perseverative_nosepokes_to_same_hole%(box%,trial%(box%)) += 1 ELSE perseverative_nosepokes_to_all_other_holes%(box%,trial%(box%)) += 1 ENDIF WHEN stim2_on%: REM phase 2 stimuli are on, awaiting choice latency_to_respond%(box%,trial%(box%)) = TIME - stim2_on_at%(box%) PROCkill_timer(box% + choice_limited_hold_timer%, E%) PROCswitch_off_all_holes(box%) phase2_chosen_hole%(box%,trial%(box%)) = hole% IF matching%=yes% THEN REM Matching. CASE hole% OF WHEN offered_hole%(box%,trial%(box%)): PROCspaced_pellet(pellet_dispenser%(box%), phase_2_numpellets%, pellet_dispenser_timer%+box%, pellet_gap%) total_pellets%(box%) += phase_2_numpellets% stim2_off_at%(box%) = TIME phase2_correct%(box%) +=1 PROCswitch_on(traylight%(box%), E%) :REM 26 June 2003 PROCdisplay_box(box%) PROCset_state(box%,collecting_bigbonus%) OTHERWISE: REM IF offered_hole%(box%,trial%(box%),hole%)=yes% THEN phase2_incorrect%(box%) +=1 REM ENDIF PROCset_darkness(box%) ENDCASE ELSE REM Non-matching IF false_holes%(box%,trial%(box%),hole%)=yes% AND hole%<>offered_hole%(box%,trial%(box%)) THEN REM Rat has picked "distractor" hole, which is correct REM Slight kludge there because false_hole%() is true REM for the original hole (see false hole assignment code) REM Looks daft, but there you go. Should work. PROCspaced_pellet(pellet_dispenser%(box%), phase_2_numpellets%, pellet_dispenser_timer%+box%, pellet_gap%) total_pellets%(box%) += phase_2_numpellets% stim2_off_at%(box%) = TIME phase2_correct%(box%) +=1 PROCswitch_on(traylight%(box%), E%) :REM 26 June 2003 PROCdisplay_box(box%) PROCset_state(box%,collecting_bigbonus%) ELSE REM Rat picked original hole, or unlit hole. Wrong! phase2_incorrect%(box%) +=1 PROCset_darkness(box%) ENDIF ENDIF WHEN collecting_bigbonus%: REM it made the correct response; now waiting for it to collect the two pellets REM NOTHING. WHEN eating_up%: REM NOTHING. ENDCASE =0 DEF FNpanelpush(box%, R%) IF R%=0 =0 CASE nosepoke_state%(box%) OF WHEN dont_care%: REM not interested in NP REM NOTHING. WHEN want_panelpush1%: REM Awaiting push at the panel at start of phase 1 PROCset_initial_iti(box%) WHEN initial_iti%: REM panel-push done, hanging around before stimulus panels_during_initial_iti%(box%,trial%(box%)) += 1 WHEN stim1_on%: REM first stimulus is being presented REM NOTHING. WHEN darkness%: REM rat failed, awaiting new trial REM NOTHING. WHEN delay%: REM rat succeeded, delay before phase 2 REM count # panel pushes during each delay ie. for each trial panels_during_delay%(box%,trial%(box%)) +=1 IF delay_pushed%(box%) <> yes% THEN latency_to_panelpush%(box%,trial%(box%)) = TIME - stim1_off_at%(box%) delay_pushed%(box%) = yes% ENDIF PROCswitch_off(traylight%(box%), E%) REM 26 June 2003 - switch off once training pellets collected (or equivalent if not training) WHEN delay_done%: REM rat succeeded, delay is finished, must panel-push for phase 2 presentation REM first, stop the houselight flashing... IF flashing_houselight%(box%) = yes% THEN PROCstop_flash_line(houselight%(box%), box% + houselight_flash_timer%) PROCswitch_on(houselight%(box%), E%) ENDIF experienced_delay%(box%,trial%(box%)) = TIME - delay_began_at%(box%) IF delay_pushed%(box%) <> yes% THEN latency_to_panelpush%(box%,trial%(box%)) = TIME - stim1_off_at%(box%) ENDIF PROCchoice_phase(box%) WHEN stim2_on%: REM phase 2 stimuli are on, awaiting choice REM NOTHING. WHEN collecting_bigbonus%: REM it made the correct response; now waiting for it to collect the two pellets collecting_bigbonus_latency%(box%,trial%(box%)) = TIME - stim2_off_at%(box%) PROCswitch_off(traylight%(box%), E%) :REM 26 June 2003 PROCset_state(box%, eating_up%) PROCpipe_timer(eating_timer% + box%, eating_time%, 0, "FNhas_eaten(", box%, E%) WHEN eating_up%: REM NOTHING. ENDCASE =0 DEF PROCrecord_response(box%, location%) LOCAL r% IF recorded_responses%(box%) = max_responses% THEN COLOUR white% PRINTTAB(0,0);"--- Exceeded maximum number of recorded responses for box ";box%;" ---"; ENDPROC ELSE REM PRINT TAB(0,0);"--- recording response in hole ";location%;" for box ";box%; recorded_responses%(box%) += 1 r% = recorded_responses%(box%) response_trial%(box%, r%) = trial%(box%) response_location%(box%, r%) = location% ENDIF ENDPROC DEF PROCswitch_off_all_holes(box%) LOCAL h% FOR h%=1 TO nholes% PROCswitch_off(aperturelight%(box%, h%), E%) NEXT ENDPROC DEF PROCset_darkness(box%) PROCswitch_off_all_holes(box%) PROCswitch_off(houselight%(box%), E%) PROCswitch_off(traylight%(box%), E%) PROCset_state(box%, darkness%) PROCpipe_timer(darkness_iti_timer% + box%, darkness_iti%(box%), 0, "FNstart_trial(", box%, E%) ENDPROC DEF PROCset_delay(box%) REM PROCswitch_on(traylight%(box%), E%) REM -- 26 June 2003: why was the traylight switched on at the *start* of the delay? REM -- doesn't make much sense; should come on at the *end* of the delay, REM -- which is when the rat must nosepoke at the back panel. REM -- Traylight may already be on (if training pellets have been given), or not - leave it REM -- in either case. PROCset_state(box%, delay%) delay_began_at%(box%) = TIME programmed_delay%(box%,trial%(box%)) = FNget_programmed_delay(box%) IF programmed_delay%(box%,trial%(box%))>0 THEN PROCpipe_timer(delay_timer%+box%, programmed_delay%(box%,trial%(box%)), 0, "FNdelay_finished(", box%, E%) ELSE dummy% = FNdelay_finished(box%,1) ENDIF IF flashing_houselight%(box%) = yes% THEN PROCstart_flash_line(houselight%(box%), box% + houselight_flash_timer%, 25, 25) REM start flashing the houselight (25 cs on, 25 cs off; gives 2 Hz cycle) ENDIF ENDPROC DEF FNget_programmed_delay(box%) LOCAL current_trial_within_group%, loop%, subloop%, count%, chosen_number% LOCAL temp_delay_used%(): DIM temp_delay_used%(ndelay_options%) :REM initialized to zero automatically current_trial_within_group% = ((trial%(box%)-1) MOD ndelay_options%) + 1 REM this will be 1/2/3/4 in a group of 4 delays IF current_trial_within_group% = 1 THEN REM in first trial of a group, so fill current_trial_group_delay_order%(,) REM with the delays, in an order that's chosen randomly for this group of trials FOR loop% = 1 TO ndelay_options% chosen_number% = FNrandom_integer(1, 1 + ndelay_options% - loop%) count% = 0 FOR subloop% = 1 TO ndelay_options% IF temp_delay_used%(subloop%) = 0 THEN count% += 1 IF count% = chosen_number% THEN REM we have chosen! temp_delay_used%(subloop%) = 1 current_trial_group_delay_order%(box%, loop%) = delay_option%(box%, subloop%) ENDIF ENDIF NEXT NEXT ENDIF = current_trial_group_delay_order%(box%, current_trial_within_group%) DEF FNdelay_finished(box%, R%) IF R%=0 =0 REM light stays on REM -- 26 June 2003: panel light doesn't *stay* on here, it *comes* on here, REM -- because it means "please push now". PROCswitch_on(traylight%(box%), E%) PROCset_state(box%, delay_done%) =0 DEF FNhas_eaten(box%, R%) IF R%=0 =0 PROCset_darkness(box%) =0 DEF PROCfinished(box%) LOCAL hole%, i% PROCswitch_off_all_holes(box%) PROCswitch_off(houselight%(box%), E%) PROCswitch_off(traylight%(box%), E%) FOR hole% = 1 TO nholes% PROCkill_switch(nosepoke%(box%,hole%), E%) NEXT PROCkill_switch(panelpush%(box%), E%) REM ... any timers outstanding? Shouldn't be. finished%(box%) = yes% FOR i%=1 TO nboxes% IF finished%(i%) <> yes% THEN ENDPROC NEXT REM Now all boxes have finished. PROCkill_all REM Output. LOCAL ch%,t%,r%,d$ ch% = OPENOUT(datafile$) REM Don't have lines longer than about 160 chars; BASIC can't load it ("Bad program"). PROCprint_string(ch%,"PROGNAME,DATE_TIME,RAT,BOX,SESSION,STIM_DUR,LIM_HOLD,BRIGHTNESS,CHOICE_DUR,DARK_TIME,") PROCprint_string(ch%,"CHOICE_LIMHOLD,TRAINING,PHASE1_PEL,PHASE2_PEL,TREATMENT,") PROCprint_string(ch%,"NPOKESPERSTIM,") PROCprint_string(ch%,"TRIAL,PANEL_ITI,ANTICIP,OFFERED,CHOSEN,DETECT_LATENCY,NPOKES_CORRECT_PHASE1,NPOKES_INCORRECT_PHASE1,PHASE1_COMPLETED") PROCprint_string(ch%,"PERSEV_SAME,PERSEV_OTHER,PUSH_LATENCY,") PROCprint_string(ch%,"PANEL_DELAY,PROG_DELAY,EXP_DELAY,NUM_PHASE2_STIMULI") FOR hole%=1 TO nholes% PROCprint_string(ch%,",FALSE_"+STR$(hole%)) NEXT PROCprint_line(ch%,",PHASE2_CHOSEN,PHASE2_LAT,MAG_LAT") FOR box% = 1 TO nboxes% FOR t% = 1 TO trial%(box%) PROCprint_string(ch%, progname$+"("+version_date$+"),"+date_time_code$+","+rat_id$(box%)+","+STR$(box%)) PROCprint_string(ch%, ","+STR$(session_number%(box%))+","+STR$(stimulus_duration%(box%))+","+STR$(limited_hold%(box%))) PROCprint_string(ch%, ","+STR$(brightness_level%(box%))+","+STR$(choice_duration%(box%))) PROCprint_string(ch%, ","+STR$(darkness_iti%(box%))+","+STR$(choice_limited_hold%(box%))+","+STR$(training%(box%))) PROCprint_string(ch%, ","+STR$(phase_1_numpellets%)+","+STR$(phase_2_numpellets%)+","+treatment$(box%)) PROCprint_string(ch%, ","+STR$(npokes_per_stimulus%(box%))) PROCprint_string(ch%, ","+STR$(t%)) PROCprint_string(ch%, ","+STR$(panels_during_initial_iti%(box%,t%))) PROCprint_string(ch%, ","+STR$(anticipatory_nosepokes%(box%,t%))) PROCprint_string(ch%, ","+STR$(offered_hole%(box%,t%))) PROCprint_string(ch%, ","+STR$(chosen_hole%(box%,t%))) PROCprint_string(ch%, ","+STR$(latency_to_detect_light%(box%,t%))) PROCprint_string(ch%, ","+STR$(num_correct_phase1_pokes%(box%,t%))) PROCprint_string(ch%, ","+STR$(num_incorrect_phase1_pokes%(box%,t%))) PROCprint_string(ch%, ","+STR$(record_correct_response%(box%,t%))) :REM phase 1 completed? PROCprint_string(ch%, ","+STR$(perseverative_nosepokes_to_same_hole%(box%,t%))) PROCprint_string(ch%, ","+STR$(perseverative_nosepokes_to_all_other_holes%(box%,t%))) PROCprint_string(ch%, ","+STR$(latency_to_panelpush%(box%,t%))) PROCprint_string(ch%, ","+STR$(panels_during_delay%(box%,t%))) PROCprint_string(ch%, ","+STR$(programmed_delay%(box%,t%))) PROCprint_string(ch%, ","+STR$(experienced_delay%(box%,t%))) PROCprint_string(ch%, ","+STR$(num_phase2_stimuli%(box%,t%))) REM print Y or N for each distractor hole FOR hole%=1 TO nholes% PROCprint_string(ch%, ","+yesno$(false_holes%(box%,t%,hole%))) NEXT PROCprint_string(ch%, ","+STR$(phase2_chosen_hole%(box%,t%))) PROCprint_string(ch%, ","+STR$(latency_to_respond%(box%,t%))) PROCprint_line(ch%, ","+STR$(collecting_bigbonus_latency%(box%,t%))) NEXT NEXT CLOSE#ch% ch% = OPENOUT(responsefile$) PROCprint_string(ch%,"PROGNAME,DATE_TIME,RAT,BOX,") PROCprint_line(ch%,"RESPONSE_NUM,RESPONSE_TRIAL,RESPONSE_LOCATION") FOR box% = 1 TO nboxes% d$ = progname$ + "," + date_time_code$ + "," + rat_id$(box%) + "," + STR$(box%) + "," IF recorded_responses%(box%)>0 THEN FOR r% = 1 TO recorded_responses%(box%) PROCprint_string(ch%, d$ + STR$(r%)) PROCprint_string(ch%, "," + STR$(response_trial%(box%,r%))) PROCprint_line(ch%, "," + STR$(response_location%(box%,r%))) NEXT ENDIF NEXT CLOSE#ch% LOCAL phase1_correct% LOCAL tot_anticip_np%,tot_per_same_np%,tot_per_other_np%,tot_per_np% LOCAL mean_detection_latency,mean_panelpush_latency,mean_choice_latency, LOCAL mean_magazine_latency,mean_experienced_delay,tot_experienced_delay LOCAL tot_pellets%,tot_detection_latency,tot_panelpush_latency LOCAL tot_choice_latency,tot_magazine_latency LOCAL tempcount% LOCAL panelcount%: REM panelpushes during delay LOCAL delay_np_to_same_hole_count% LOCAL delay_np_to_other_holes_count% REM Don't use % sign 'cos we want mean with decimal point-floating point variable REM not integer. PRINT: PRINT: PRINT: PRINT: PRINT: PRINT: PRINT: PRINT: PRINT: PRINT: PRINT PRINT: PRINT COLOUR 5 PRINT"Session Complete" PRINT printing% = FNask_yes_no("Do you want to print the results?") IF printing%=1 THEN VDU 2 OSCLI("SPOOL "+logfile$) PRINT"=====================================================================" PRINT"!";progname$;", by Yogi/Rudolf, ";version_date$ PRINT"Finished at ";TIME$ PRINT"Date/time code: ";date_time_code$ PRINT"=====================================================================" REM example of per-session information PRINT"Overall time limit (min): ";overall_limit% FOR box%=1 TO nboxes% COLOUR 7 phase1_correct%=0 PRINT"----------------------------------------------------------------------" PRINT"Session Parameters" PRINT"----------------------------------------------------------------------" PRINT"BOX: ";box% PRINT"Rat ID: ";rat_id$(box%) PRINT"Session: ";session_number%(box%) PRINT"No. of trials: ";numtrials%(box%) PRINT"Stim duration: ";stimulus_duration%(box%) PRINT"limited hold: ";limited_hold%(box%) FOR d% = 1 TO ndelay_options% PRINT"Delays: ";delay_option%(box%, d%) NEXT PRINT"Brightness: ";brightness_level%(box%) PRINT"Choice duration:";choice_duration%(box%) PRINT"Choice lim hold:";choice_limited_hold%(box%) PRINT"Darkness iti: ";darkness_iti%(box%) PRINT"Minimum # phase 2 stim: ";min_phase2_stim%(box%) PRINT"Maximum # phase 2 stim: ";max_phase2_stim%(box%) PRINT"Training?: ";training%(box%) PRINT"Treatment: ";treatment$(box%) PRINT"Number of pokes required per phase 1 stimulus: ";npokes_per_stimulus%(box%) PRINT PRINT"_______________________________________________________________________" PRINT: PRINT"Session Information for Attention Phase (Phase 1)" PRINT"-----------------------------------------------------------------------" PRINT: PRINT"Corr detections: ";phase1_correct%(box%) PRINT"Percent accuracy: "; IF (phase1_correct%(box%) + phase1_incorrect%(box%)) <> 0 THEN PRINT 100*phase1_correct%(box%)/(phase1_correct%(box%) + phase1_incorrect%(box%));"%" ELSE COLOUR 1:PRINT"Division by 0 - Illegal Operation":COLOUR 7 ENDIF PRINT"INcorr detections: ";phase1_incorrect%(box%) PRINT"Percent inaccuracy: "; IF (phase1_incorrect%(box%) + phase1_correct%(box%)) <> 0 THEN PRINT 100*phase1_incorrect%(box%)/(phase1_incorrect%(box%) + phase1_correct%(box%));"%" ELSE COLOUR 1:PRINT"Division by 0 - Illegal Operation":COLOUR 7 ENDIF PRINT"Omissions: ";phase1_omissions%(box%) tot_anticip_np% = 0 tot_per_same_np% = 0 tot_per_other_np% = 0 tot_per_np% = 0 tot_detection_latency = 0 mean_detection_latency = 0 tot_panelpush_latency = 0 mean_panelpush_latency = 0 tot_choice_latency = 0 mean_choice_latency = 0 tot_magazine_latency = 0 mean_magazine_latency = 0 tot_experienced_delay = 0 mean_experienced_delay = 0 tot_pellets% = 0 FOR t% = 1 TO trial%(box%) tot_anticip_np% += anticipatory_nosepokes%(box%,t%) tot_per_same_np% += perseverative_nosepokes_to_same_hole%(box%,t%) tot_per_other_np% += perseverative_nosepokes_to_all_other_holes%(box%,t%) tot_per_np% = tot_per_same_np% + tot_per_other_np% tot_detection_latency += latency_to_detect_light%(box%,t%) tot_panelpush_latency += latency_to_panelpush%(box%,t%) tot_choice_latency += latency_to_respond%(box%,t%) tot_magazine_latency += collecting_bigbonus_latency%(box%,t%) REM panelpush_latency is time between light detection and first panel REM push at start of delay (in five choice task, this would be mag lat). NEXT IF trial%(box%) <> 0 THEN mean_detection_latency = tot_detection_latency / trial%(box%) mean_panelpush_latency = tot_panelpush_latency / trial%(box%) ENDIF PRINT"Ant responses: ";tot_anticip_np% PRINT"During delay:" PRINT"Per resp to same hole: ";tot_per_same_np% PRINT"Per resp to other holes:";tot_per_other_np% PRINT"Total per responses: ";tot_per_np% PRINT"Mean response latency: ";mean_detection_latency PRINT"Mean panelpush latency: ";mean_panelpush_latency REM --------------------------------------------------------------- REM *** Must check that denominator is not zero. REM --------------------------------------------------------------- PRINT"_________________________________________________________________________" PRINT: PRINT"Session Information for Working Memory Phase (Phase 2)" PRINT"-------------------------------------------------------------------------" PRINT"Corr choice: ";phase2_correct%(box%) PRINT"Percent choice accuracy: "; IF (phase2_correct%(box%) + phase2_incorrect%(box%)) <> 0 THEN PRINT 100*phase2_correct%(box%)/(phase2_correct%(box%) + phase2_incorrect%(box%));"%" ELSE COLOUR 1:PRINT"Division by 0 - Illegal Operation":COLOUR 7 ENDIF PRINT"INcorr choice: ";phase2_incorrect%(box%) PRINT"Percent ch inaccuracy: "; IF (phase2_incorrect%(box%) + phase2_correct%(box%)) <> 0 THEN PRINT 100*phase2_incorrect%(box%)/(phase2_incorrect%(box%) + phase2_correct%(box%));"%" ELSE COLOUR 1:PRINT"Division by 0 - Illegal Operation":COLOUR 7 ENDIF PRINT"Choice omissions: ";phase2_omissions%(box%) IF trial%(box%) <> 0 THEN mean_choice_latency = tot_choice_latency / trial%(box%) mean_magazine_latency = tot_magazine_latency / trial%(box%) ENDIF PRINT"Mean choice lat: ";mean_choice_latency;"csec" PRINT"Mean magazine lat: ";mean_magazine_latency;"csec" PRINT FOR d% = 1 TO ndelay_options% tot_experienced_delay = 0 tempcount% = 0 panelcount% = 0 delay_np_to_same_hole_count% = 0 delay_np_to_other_holes_count% = 0 tempsucceededfirststage% = 0 tempsucceededsecondstage% = 0 FOR t% = 1 TO trial%(box%) IF programmed_delay%(box%,t%) = delay_option%(box%,d%) THEN tot_experienced_delay += experienced_delay%(box%,t%) tempcount% += 1 panelcount% += panels_during_delay%(box%, d%) delay_np_to_same_hole_count% += perseverative_nosepokes_to_same_hole%(box%, d%) delay_np_to_other_holes_count% += perseverative_nosepokes_to_all_other_holes%(box%, d%) IF phase2_chosen_hole%(box%,t%)<>0 THEN tempsucceededfirststage% += 1 IF phase2_chosen_hole%(box%,t%)=offered_hole%(box%,t%) THEN tempsucceededsecondstage% += 1 ENDIF NEXT IF tempcount% > 0 THEN PRINT "For prgm delay ";delay_option%(box%,d%);" cs, ";tempcount%;" trials, mean delay: ";tot_experienced_delay/tempcount%;"cs." ELSE PRINT "For prgm delay ";delay_option%(box%,d%);"cs, there were no trials." ENDIF IF (tempsucceededfirststage%>0) THEN PRINT "For prgm delay ";delay_option%(box%,d%);"cs, responded: ";tempsucceededfirststage%;" trials, correct: "; PRINT;tempsucceededsecondstage%;" trials, scored: ";(100*tempsucceededsecondstage%/tempsucceededfirststage%);"%" REM PRINT "For prgm delay ";delay_option%(box%,d%);"cs, mean panelpushes: ";panelcount%/tempcount%;" during delay." REM PRINT "For prgm delay ";delay_option%(box%,d%);"cs, mean np to same hole - ";delay_np_to_same_hole_count%/tempcount%;" during delay." REM PRINT "For prgm delay ";delay_option%(box%,d%);"cs, mean np to other holes - ";delay_np_to_other_holes_count%/tempcount%;" during delay." ELSE PRINT "For prgm delay ";delay_option%(box%,d%);" cs, the rat never responded on phase 2." ENDIF PRINT NEXT tot_pellets% = total_pellets%(box%) + training_pellets%(box%) PRINT: PRINT"_______________________________________________________________________" PRINT: PRINT"Total number of pellets: "; tot_pellets%;" (";FNfood_mass(tot_pellets%);" g)" PRINT"_______________________________________________________________________" PRINT PRINT " #choice stim -- #Trials with this #stim -- #Correct trials -- %accuracy" REM 01234567890123456789012345678901234567890123456789012345678901234567890123456789 PRINT "_______________________________________________________________________" REM stimcount% is number of choice stimuli (1-5) FOR stimcount%=1 TO nholes% phase2_accuracy_var = 0 phase2_trialcount% = 0 phase2_successcount% = 0 FOR t%=1 TO trial%(box%) IF num_phase2_stimuli%(box%, t%)=stimcount% AND phase2_chosen_hole%(box%,t%)<>0 THEN phase2_trialcount% += 1 IF phase2_chosen_hole%(box%, t%) = offered_hole%(box%, t%) THEN phase2_successcount% += 1 ENDIF ENDIF NEXT IF phase2_trialcount%>0 THEN phase2_accuracy_var=(phase2_successcount%/phase2_trialcount%) ELSE phase2_accuracy_var=-99 :REM else division by zero ENDIF PRINT TAB(1);stimcount%;TAB(17);phase2_trialcount%;TAB(44);phase2_successcount%;TAB(63);phase2_accuracy_var NEXT PRINT PRINT"***********************************************************************" PRINT"***********************************************************************" NEXT OSCLI("SPOOL") VDU 3 PRINT '"Done." ENDPROC DEF PROCdisplay_startup MODE 12 COLOUR 5 PRINT TAB(5) " " PRINT TAB(5) " Combined Attention and Working Memory Task " PRINT TAB(5) " Variable Choice " PRINT TAB(5) " " PRINT progname$;" by Rudolf/Yogi. Version of ";version_date$ date_time_code$ = FNdate_time_code PRINT "Press 1-";nboxes%;" to start each box." PRINT "Press F1-F";nboxes%;" to abort boxes manually." PRINT:PRINT "Date/Time: ";date_time_code$ PRINT "Session limit is ";overall_limit%;" min." PRINT"Box Trial State #C #I #M #C #I #M " PRINT"-----------------------------------------------------------------------------" REM 0123456789012345678901234567890123456789012345678901234567890123456789 display_firstline%=VPOS ENDPROC DEF FNdisplay_line(box%) = display_firstline% + (box%-1)*3 DEF PROCdisplay_box(box%) line% = FNdisplay_line(box%) PRINTTAB(0,line%);box%; PRINTTAB(5,line%);trial%(box%); PRINTTAB(36,line%);phase1_correct%(box%); PRINTTAB(41,line%);phase1_incorrect%(box%); PRINTTAB(46,line%);phase1_omissions%(box%); PRINTTAB(51,line%);phase2_correct%(box%); PRINTTAB(56,line%);phase2_incorrect%(box%); PRINTTAB(61,line%);phase2_omissions%(box%); REM Additional stuff here PROCdisplay_state(box%) ENDPROC DEF PROCdisplay_state(box%) line% = FNdisplay_line(box%) COLOUR 3 PRINTTAB(12,line%); CASE nosepoke_state%(box%) OF WHEN dont_care%: PRINT "Nothing much " WHEN want_panelpush1%: PRINT "Awaiting panel-push " WHEN initial_iti%: PRINT "Initial ITI " WHEN stim1_on%: PRINT "Stimulus 1 on " WHEN darkness%: PRINT "DARKNESS....New trial " WHEN delay%: PRINT "Memory delay " WHEN delay_done%: PRINT "OK, now poke! " WHEN stim2_on%: PRINT "Choice stimuli " WHEN collecting_bigbonus%: PRINT "You won. Eat up. " WHEN eating_up%: PRINT "Munch. Munch. Munch " WHEN finished_state%: PRINT "--- Finished --- " WHEN aborted_state%: PRINT "*** ABORTED *** " ENDCASE ENDPROC DEF FNabort_box(box%,bogus%) :REM checked for AC IF bogus%=0 =0 PROCset_state(box%,aborted_state%) PROCkill_timer(initial_iti_timer% + box%, E%) PROCkill_timer(darkness_iti_timer% + box%, E%) PROCkill_timer(limited_hold_timer% + box%, E%) PROCkill_timer(pellet_dispenser_timer% + box%, E%) PROCkill_timer(choice_limited_hold_timer% + box%, E%) PROCkill_timer(timeout_timer% + box%, E%) PROCkill_timer(delay_timer% + box%, E%) PROCkill_timer(eating_timer% + box%, E%) PROCfinished(box%) =0 DEF FNcam_keyboard_handler(no_idea%, bogus%) IF bogus%=0 =0 LOCAL key%, dummy%, b% key% = GET IF key%>=ASC("1") AND key%<=ASC("9") THEN b%=key%-ASC("0") ELSE =0 IF b%>nboxes% THEN =0 IF started%(b%)=yes% OR finished%(b%)=yes% THEN =0 started%(b%)=yes% PROCstart_the_box(b%) =0