REM >AutoShap REM REM Autoshaping, by RNC/YC REM Started 19 Sep 99. Up and running on 20 Sep 99. progname$="AutoShap" version_date$="14 Dec 99" debug%=0 :REM Shortens all intervals so you don't go mad waiting. touch_debug%=0 :REM Internal reports from touchscreen library. REM Things to do: REM - change wall pellet dispenser back to central dispenser when the hardware's ready REM - dispenser changed on 29-sept-99 YC REM - check magazine IR positioning REM - IR detectors and touchscreen both have the problem that there isn't one "off" signal REM for each "on" signal. IR detector problem must be due to Arachnid temporal resolution. REM Touchscreen problem may be due to the superlabel system: if you touch an area and move REM your finger out of the area before removing it from the screen, you don't get the off REM signal. Same in reverse for "on". Is this fixable? Check touchscreen manual. REM - am writing off one mysterious crash when the program was re-run manually! REM REM Revision history REM ================ REM REM - Policy decision, 20-Sep-99: record events but not their durations. REM (You get a ridiculous rate of events of very short duration otherwise, i.e. 1cs REM probably an electrical instability, and not behaviourally interesting. REM Also, Arachnid doesn't manage one "off" event for every "on" event. REM It'll be hard enough to read anyway.) REM - Policy decision: the "food latency" will be recorded even for CON presentations. REM Just for symmetry... REM - Probe and omission test are written by modifying acquisition functions, and adding REM task% to detect which task we're in. That's why a lot of the functions begin REM "acquisition_" even when they do three things. Acquisition is considered the default. REM REM - Probe differences: REM * PROCacquisition_give_stimulus gives both (by passing both% to PROCstimulus_on) REM * FNwhich_stimulus_to_give returns both% REM * PROCstimulus_on plots both (necessary so they appear simultaneously) REM * FNacquisition_stimulus_done skips over second stimpres% REM * cs_approach_total% and con_approach_total% are always incremented by first approaches (in FNcs_beam and FNcon_beam) REM * startup code split: acquisition sets task$, gets its info and calls PROCshared_startup. REM * PROCprobe does similarly. REM * PROCacquisition_setup_display modified to show current task. REM * My methods said "a 30-min probe trial consisting of 20 trials", but meant "a probe test consisting of 20 trials". REM * Data output code: reports task$; stimpres%=1 skipped over in PROCreport_useful_data REM REM - Omission differences REM * food_prevented%(box%) set to no% at the start of every trial, in FNacquisition_give_stimulus REM * food_prevented%(box%) checked in FNacquisition_stimulus_done REM * CS beam break (FNcs_beam) as the first approach sets food_prevented%(box%)=yes%. Occurs on CON trials too, which doesn't matter. REM * If the animal approaches CON first, then CS, food is *not* prevented. REM Probably want to check this policy, but I'm happy with that. REM * If the animal touches the CS but did not break the CS beam as its first beambreak, food is *not* prevented. REM Probably want to check this policy, but that's where my money's going. REM * PROComission calls shared startup code. REM * Data output fine as it is. Note that "FOOD_LATENCY" doesn't mean that there was any food. REM REM - Query - if the rat's already on the back panel when the VI expires, is it OK REM to begin? I'd think so, and this'd speed things up. Have implemented this REM in FNacquisition_wait_for_panel, and it applies to acquisition/probe/omission. REM However, if the panel actually got stuck down, then the task would whistle through REM all trials instead of waiting around (and perhaps attracting the experimenter's REM attention). // Have now checked TJB's code; it would have gone straight on if the REM rat was already on the panel. REM REM - TJB's probe task had a VI of 10-40s between trials and was identical to acquisition/omission REM in structure (interval, wait for panel, present stimuli for 10s). Same here. REM REM - the "visible black on black" problem with the LCDs was fixed by replacing GCOL 0 REM by GCOL 0,0,0. REM REM - Stimulus size seems fine. REM REM - 14 Dec 99. REM Pretraining was using a VI 0-15 s (i.e. mean 7.5 s, 8/min); should have been 0-40 s (mean 20 s, 3/min). PROCinit :REM Arachnid init PROCkill_all :REM Arachnid init LIBRARY ".ProgLibs.Filename" LIBRARY ".ProgLibs.DateTime" LIBRARY ".ProgLibs.ASCII" LIBRARY ".ProgLibs.Arachnid" LIBRARY ".ProgLibs.BoxConst" LIBRARY ".ProgLibs.JP" :REM touchscreen input library LIBRARY ".ProgLibs.YogiLib" :REM contains Yogi's box constants; also a lot of LCD output code PROCyogi_touchscreen_boxes LIBRARY ".CenesLib.ScreenLib" :REM Cenes' library for multiple screens LIBRARY ".ProgLibs.UI" PROCdefine_colours LIBRARY ".ProgLibs.Random" MODE 12 PRINT "Initializing screens, please wait..." PROCyogi_multiscreen_init CLS REM ------------------------------------------------------ Parameters pretrain_duration% = 15 * 60 * 100 pretrain_min_interval% = 0 pretrain_max_interval% = 40 * 100 acquisition_min_interval% = 10 * 100 acquisition_max_interval% = 40 * 100 stimulus_duration% = 10 * 100 IF debug%=1 THEN pretrain_max_interval% = 4 * 100 pretrain_duration% = 1 * 60 * 100 acquisition_min_interval% = 2 * 100 acquisition_max_interval% = 4 * 100 stimulus_duration% = 3 * 100 ENDIF max_trials% = 250 max_events% = 100000 :REM Number of individual (i.e. tedious) responses that will be recorded, across *all* boxes. REM ------------------------------------------------------ Variables REM from user... DIM rat_name$(nboxes%) DIM first_trial_num%(nboxes%) DIM last_trial_num%(nboxes%) DIM cs_side$(nboxes%) :REM CS+ on L or R? REM internal... DIM started%(nboxes%) DIM finished%(nboxes%) DIM start_time%(nboxes%) DIM pellets_given%(nboxes%) DIM state%(nboxes%) :REM see state constants below DIM trial%(nboxes%) :REM overall current trial number DIM stimpres%(nboxes%) :REM first or second stimulus presentation of the trial? 0 or 1 DIM trialorder%(nboxes%,max_trials%) :REM is this a CS/CON or a CON/CS trial? (cs_first% or con_first%) DIM cs_touching%(nboxes%) :REM is it touching the CS at this instant? DIM con_touching%(nboxes%) :REM is it touching the CON at this instant? DIM has_approached%(nboxes%) :REM has the first approach been made yet? DIM state_start_time%(nboxes%):REM for latency calculations: when this state (stim on, await panel, VI) began DIM has_fed%(nboxes%) DIM feeding_trial%(nboxes%) DIM feeding_stimpres%(nboxes%):REM for food collection, which is in the ITI of the subsequent trial - keeps track of where food came from DIM food_prevented%(nboxes%) :REM for omission task REM recorded information of particular interest... REM 3D arrays are (box, trial, stimpres). DIM vi_length%(nboxes%, max_trials%, 1) DIM panel_latency%(nboxes%, max_trials%, 1) DIM stimulus_presented%(nboxes%, max_trials%, 1) DIM first_approach%(nboxes%, max_trials%, 1) DIM first_approach_latency%(nboxes%, max_trials%, 1) DIM cs_approach_total%(nboxes%) DIM con_approach_total%(nboxes%) DIM food_latency%(nboxes%, max_trials%, 1) :REM from pellet delivery to collection (as long as collection within next VI). 0 for CON. DIM completed_trials%(nboxes%) REM also recorded: start_time%() REM recorded information of the "bucket" kind DIM current_event%(nboxes%) DIM event_location%(nboxes%, max_events%) DIM event_trial%(nboxes%, max_events%) DIM event_stimpres%(nboxes%, max_events%) DIM event_state%(nboxes%, max_events%) DIM event_starttime%(nboxes%, max_events%) REM mechanisms for event recording LOC_PANEL% = 1 LOC_CS_BEAM% = 2 LOC_CON_BEAM% = 3 LOC_CS_CONTACT% = 4 LOC_CON_CONTACT% = 5 LOC_MAGAZINE% = 6 REM ------------------------------------------------------ Constants yes%=1: no% =0 cs_first% = 0: con_first% = 1 left% = 1: right% = 2 nothing% = 0: cs% = 1: con% = 2: both% = 3 DIM stimulus_description$(3) stimulus_description$(nothing%)="None" : stimulus_description$(cs%)="CS" stimulus_description$(con%)="CON" : stimulus_description$(3)="Both" REM Important that cs% and con% are non-zero, because these constants are used to record the animal's approach - default is 0. REM NB also important that both% does not equal left% or right% ignoring_state% = 0 iti_state% = 1 waiting_for_backpanel_state% = 2 stimulus_state% = 3 finished_state% = 4 REM ------------------------------------------------------ TIMERS pretrain_vi_timer% = nboxes% * 0 pretrain_overall_timer% = nboxes% * 1 acquisition_vi_timer% = nboxes% * 2 acquisition_stim_timer% = nboxes% * 3 clock_timer% = nboxes% * 4 + 1 ON ERROR PROCfuckup :REM when using LCDs, is a possibility that you never see the error message otherwise. COLOUR yellow% PRINT PRINT "Autoshaping." PRINT " by Rudolf Cardinal." PRINT " '";progname$;"', ";version_date$ PRINT PRINT "Please select the Task of the Day:" COLOUR white% PRINT PRINT " 1. Pretraining (free pellets)." PRINT " 2. Acquisition." PRINT " 3. Probe." PRINT " 4. Omission." PRINT pretraining% = 1: acquisition% = 2: probe% = 3: omission% = 4 COLOUR red% task% = FNget_num_param("Choose",0,1,4) CASE task% OF WHEN pretraining%: PROCpretraining WHEN acquisition%: PROCacquisition WHEN probe%: PROCprobe WHEN omission%: PROComission OTHERWISE: VDU7:PRINT '"Error.":END ENDCASE END REM ------------------------------------------------------------------------------ DEF PROCfuckup ON ERROR OFF PROCswitch_vdu(-1) PRINT "* Program aborted - error ";ERR;" at line ";ERL; REPORT PRINT END ENDPROC REM ================================================================================ DEF PROCpretraining REM ================================================================================ LOCAL i% CLS COLOUR red% PRINT "PRETRAINING." PRINT FOR i%=1 TO nboxes% PRINT "Enter rat name for box ";i%;": "; INPUT ""rat_name$(i%) NEXT PRINT PRINT PRINT "Press a key to turn the boxes on..." IF GET CLS PRINT "PRETRAINING." IF debug%=1 COLOUR yellow%:PRINT"--- DEBUGGING!!! ---":COLOUR red% PRINT PRINT "OK. Pellets in the box. Redistribute them, put the rat in," PRINT "wait for the pellets to be eaten, then press the box's number to" PRINT "start the VI schedule." PRINT " Function keys F1-F";nboxes%;" will abort the boxes." PRINT REM Houselights on, four free pellets. FOR i%=1 TO nboxes% started%(i%) = no% finished%(i%) = no% PROCswitch_on(houselight%(i%), E%) PROCfast_pellet(central_pellet_dispenser%(i%), 4) pellets_given%(i%) += 4 PROCpipe_fkey(i%, 1, 0, "FNpretrain_finished(", i%, E%) PROCpretrain_update_status(i%) NEXT PROCpipe_keybd(0,0,0,"FNpretrain_keyboard_handler(",0,E%) PROCpipe_timer(clock_timer%, 100, 100, "FNpretrain_clock_tick(",0,E%) REM PROCwait(E%): *AE PROCignore_serial_error_wait ENDPROC DEF FNpretrain_keyboard_handler(no_idea%, bogus%) IF bogus%=0 =0 LOCAL key%, 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% start_time%(b%) = TIME PROCpretrain_start_schedule(b%) =0 DEF PROCpretrain_start_schedule(box%) REM Begin VI 0-40s schedule of pellet delivery for 15 min, then end. LOCAL dummy% PROCpipe_timer(box% + pretrain_overall_timer%, pretrain_duration%, 0, "FNpretrain_finished(", box%, E%) dummy% = FNpretrain_vi_point(box%, 1) PROCpretrain_update_status(box%) REM that gives the first pellet of the schedule immediately ENDPROC DEF FNpretrain_vi_point(box%, bogus%) IF bogus%=0 =0 PROCsingle_pellet(central_pellet_dispenser%(box%)) pellets_given%(box%) += 1 PROCpretrain_update_status(box%) PROCpipe_timer(box% + pretrain_vi_timer%, FNrandom_integer(pretrain_min_interval%, pretrain_max_interval%), 0, "FNpretrain_vi_point(", box%, E%) =0 DEF FNpretrain_finished(box%, bogus%) IF bogus%=0 =0 LOCAL i% finished%(box%) = yes% PROCkill_timer(box% + pretrain_vi_timer%, E%) PROCkill_timer(box% + pretrain_overall_timer%, E%) :REM because we could be here through the timer or a keyboard abort PROCswitch_off(houselight%(box%), E%) FOR i%=1 TO nboxes% IF finished%(box%) <> yes% THEN =0 NEXT PROCpretrain_all_finished =0 DEF PROCpretrain_all_finished CLS PROCkill_all PRINT "Pretraining all finished." ENDPROC DEF PROCpretrain_update_status(box%) LOCAL p, v COLOUR red% PRINT TAB(0, FNpretrain_display_line(box%));"Box ";box%;" (rat ";rat_name$(box%);") "; p = POS v = VPOS PRINT SPC(70 - p);TAB(p,v); COLOUR white% IF started%(box%)=no% PRINT "- Press ";box%;" to start.":ENDPROC IF finished%(box%)=yes% PRINT "- All done. Waiting for other boxes to finish.":ENDPROC PRINT "has had ";pellets_given%(box%);" pellets so far." ENDPROC DEF FNpretrain_clock_tick(junk%, bogus%) IF bogus%=0 =0 LOCAL box% COLOUR magenta% FOR box%=1 TO nboxes% IF started%(box%)=yes% AND finished%(box%)=no% THEN PRINT TAB(70,FNpretrain_display_line(box%));FNtimestring(TIME - start_time%(box%)) ENDIF NEXT COLOUR white% =0 DEF FNpretrain_display_line(box%) =12 + 2*box% DEF FNtimestring(t%) REM incoming: time to be displayed, in cs REM outgoing: display as "32:01" (min/sec left) LOCAL m%,s%,t$ m%=(t%/100) DIV 60 s%=(t%/100) MOD 60 t$="" IF m%<10 THEN t$+=" " t$+=STR$(m%)+":" IF s%<10 THEN t$+="0" t$+=STR$(s%) =t$ REM ================================================================================ DEF PROCacquisition REM ================================================================================ LOCAL i% CLS task$ = "Acquisition" PRINT "ACQUISITION." PRINT FOR i%=1 TO nboxes% PRINT "Enter rat name for box ";i%;": "; INPUT ""rat_name$(i%) cs_side$(i%) = FNget_letter_param("Is the CS+ on the left or right? (L/R)","LR","") first_trial_num%(i%) = FNget_num_param("Enter the first trial's number (e.g. 1 or 51) :",1,1,100) last_trial_num%(i%) = FNget_num_param("Enter the last trial's number (e.g. 50 or 100) :",first_trial_num%(i%)+49,first_trial_num%(i%),max_trials%) NEXT PROCshared_startup ENDPROC DEF PROCshared_startup LOCAL default_stem$ PRINT PRINT OSCLI("CAT") PRINT default_stem$ = rat_name$(1) + "-" + STR$(first_trial_num%(1)) datafile$ = FNget_filename_default("DATA FILE - enter filename (no spaces etc.)","D"+default_stem$) logfile$ = FNget_filename_default("TEXT LOG - enter filename (no spaces etc.)","L"+default_stem$) eventfile$ = FNget_filename_default("EVENT LOG - enter filename (no spaces etc.)","E"+default_stem$) date_time$ = FNdate_time_code PRINT PRINT"Ready to run, press a key to start..." IF GET PROCacquisition_setup_display FOR box%=1 TO nboxes% started%(box%) = no% finished%(box%) = no% PROCswitch_on(houselight%(box%), E%) PROCpipe_switch(central_mag_nosepoke%(box%), Over,1, "FNmagazine_entry(", box%, E%) PROCpipe_switch(floor_panel%(box%), Over,1, "FNbackpanel(", box%, E%) PROCpipe_switch(FNcs_beam_line(box%), Over,1, "FNcs_beam(", box%, E%) PROCpipe_switch(FNcon_beam_line(box%), Over,1, "FNcon_beam(", box%, E%) PROCpipe_fkey(box%, 1, 0, "FNacquisition_abort(", box%, E%) PROCstimulus_touch_areas(box%) PROCregister_superlabel_handler(FNwhich_touchscreen(box%),"FNscreen_touched("+STR$(box%)+",") REM --- Rig up first trial here. trial%(box%) = first_trial_num%(box%) stimpres%(box%) = 0 trialorder%(box%,trial%(box%)) = FNrandom_integer(0,1) PROCacquisition_set_state(box%, ignoring_state%) NEXT PROCpipe_timer(clock_timer%, 100, 100, "FNacquisition_clock_tick(",0,E%) PROCpipe_keybd(0,0,0,"FNacquisition_keyboard_handler(",0,E%) REM PROCwait(E%): *AE PROCignore_serial_error_wait ENDPROC DEF PROCacquisition_set_state(box%, st%) state%(box%) = st% state_start_time%(box%) = TIME PROCacquisition_update_status(box%) ENDPROC DEF FNacquisition_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% start_time%(b%)=TIME dummy% = FNacquisition_start_vi(b%, 1) =0 DEF FNacquisition_start_vi(box%, bogus%) IF bogus%=0 =0 LOCAL v% PROCacquisition_set_state(box%, iti_state%) v% = FNrandom_integer(acquisition_min_interval%, acquisition_max_interval%) vi_length%(box%, trial%(box%), stimpres%(box%)) = v% PROCpipe_timer(box% + acquisition_vi_timer%, v%, 0, "FNacquisition_wait_for_panel(", box%, E%) =0 DEF FNacquisition_wait_for_panel(box%, bogus%) IF bogus%=0 =0 PROCacquisition_set_state(box%, waiting_for_backpanel_state%) IF FNswitch(floor_panel%(box%),E%)=On THEN PROCacquisition_give_stimulus(box%) REM No waiting! This method (rather than calling FNbackpanel) means that no extra REM event gets recorded for the panel (which is sensible) but we get right on with the task. =0 DEF PROCacquisition_give_stimulus(box%) LOCAL stim% stim% = FNwhich_stimulus_to_give(box%,trialorder%(box%,trial%(box%)),stimpres%(box%)) IF task% = probe% THEN PROCstimulus_on(box%, both%) ELSE PROCstimulus_on(box%, FNstimulus_side(box%, stim%) ) ENDIF PROCacquisition_set_state(box%, stimulus_state%) has_approached%(box%) = no% food_prevented%(box%) = no% stimulus_presented%(box%, trial%(box%), stimpres%(box%)) = stim% has_fed%(box%) = no% feeding_trial%(box%) = trial%(box%) feeding_stimpres%(box%) = stimpres%(box%) PROCpipe_timer(box% + acquisition_stim_timer%, stimulus_duration%, 0, "FNacquisition_stimulus_done(", box%, E%) ENDPROC DEF FNacquisition_stimulus_done(box%, bogus%) IF bogus%=0 =0 PROCstimulus_off(box%, both%) IF FNwhich_stimulus_to_give(box%, trialorder%(box%,trial%(box%)), stimpres%(box%))=cs% AND food_prevented%(box%)<>yes% THEN REM Note that this will not trigger during probe trials. PROCsingle_pellet(central_pellet_dispenser%(box%)) pellets_given%(box%) += 1 ENDIF REM --- Rig up subsequent trials here. IF stimpres%(box%)=0 AND task%<>probe% THEN REM Have just finished first stimpres of trial. stimpres%(box%) = 1 ELSE completed_trials%(nboxes%) += 1 REM Have just finished a whole trial IF trial%(box%) = last_trial_num%(box%) THEN REM Box is all done. PROCacquisition_finished(box%) =0 ELSE REM Start a new trial. trial%(box%) += 1 stimpres%(box%) = 0 trialorder%(box%,trial%(box%)) = FNrandom_integer(0,1) ENDIF ENDIF LOCAL dummy% dummy% = FNacquisition_start_vi(box%, 1) =0 DEF FNacquisition_abort(box%, bogus%) IF bogus%=0 =0 PROCacquisition_finished(box%) =0 DEF PROCstimulus_on(box%, side%) PROClcd(FNwhich_lcd(box%)) REM Now do the drawing REM See YOGILIB for details of internal coordinate system (0-1000 X, 0-800 Y) IF side%=left% THEN x_offset% = 0 ELSE x_offset% = 666 GCOL white% PROCstimulus_rectangle(x_offset%) IF side%=both% THEN PROCstimulus_rectangle(0) :REM This makes the probe test plot both (NB both%<>left%) PROCupdate_lcd(FNwhich_lcd(box%)) PROCscreen :REM back to monitor ENDPROC DEF PROCstimulus_off(box%, side%) PROClcd(FNwhich_lcd(box%)) REM Now do the drawing REM See YOGILIB for details of internal coordinate system (0-1000 X, 0-800 Y) IF side%=left% THEN x_offset% = 0 ELSE x_offset% = 666 GCOL 0,0,0: REM GCOL black% gives a visible "black" PROCstimulus_rectangle(x_offset%) IF side%=both% THEN PROCstimulus_rectangle(0) :REM This makes the probe test plot both (NB both%<>left%) PROCupdate_lcd(FNwhich_lcd(box%)) PROCscreen :REM back to monitor ENDPROC DEF PROCstimulus_rectangle(x_offset%) RECTANGLE FILL FNx_coord(30 + x_offset%, lcd_system%), FNy_coord(100, lcd_system%), FNx_coord(270, lcd_system%), FNy_coord(600, lcd_system%) REM ?bottom x, ?bottom y, width, heightENDPROC DEF PROCstimulus_touch_areas(box%) LOCAL channel% channel% = FNwhich_touchscreen(box%) PROCdefine_origin_bottom_left(channel%) PROCpoint_mode(channel%) PROCenable_superlabels(channel%) PROCdisable_coords_in_superlabels(channel%) PROCenable_stylus_status(touchscreen_channel%) :REM now touchscreen reports on and off events REM Now two regions, "L" and "R" REM parameters are channel, left, right, bottom, top, name PROCdefine_superlabel(channel%, FNx_coord(30,touch_system%), FNx_coord(300,touch_system%), FNy_coord(100,touch_system%), FNy_coord(700,touch_system%), "L") PROCdefine_superlabel(channel%, FNx_coord(30+666,touch_system%), FNx_coord(300+666,touch_system%), FNy_coord(100,touch_system%), FNy_coord(700,touch_system%), "R") ENDPROC DEF FNwhich_lcd(box%) REM boxes numbered 1-n, screens numbered 0-(n-1). =box%-1 DEF FNwhich_touchscreen(box%) =box%-1 DEF FNbackpanel(box%, bogus%) IF bogus%=0 =0 PROCacquisition_display_switches(box%) IF FNswitch(floor_panel%(box%),E%)=Off THEN =0 PROCrecord_event(box%,LOC_PANEL%) CASE state%(box%) OF WHEN waiting_for_backpanel_state%: panel_latency%(box%, trial%(box%), stimpres%(box%)) = TIME - state_start_time%(box%) REM This event will only ever occur once per stimulus. PROCacquisition_give_stimulus(box%) OTHERWISE: REM Not interested. ENDCASE =0 DEF FNcs_beam(box%, bogus%) IF bogus%=0 =0 PROCacquisition_display_switches(box%) IF FNswitch(FNcs_beam_line(box%),E%)=Off THEN =0 REM Otherwise animal has entered CS beam. PROCrecord_event(box%,LOC_CS_BEAM%) CASE state%(box%) OF WHEN stimulus_state%: IF has_approached%(box%)=no% THEN REM First approach during this stimulus. first_approach%(box%, trial%(box%), stimpres%(box%)) = cs% first_approach_latency%(box%, trial%(box%), stimpres%(box%)) = TIME - state_start_time%(box%) IF FNwhich_stimulus_to_give(box%,trialorder%(box%,trial%(box%)),stimpres%(box%))=cs% OR task%=probe% THEN REM CS to CS approach. cs_approach_total%(box%) += 1 IF task%=omission% THEN food_prevented%(box%)=yes% ENDIF has_approached%(box%) = yes% ENDIF OTHERWISE: REM not interested. ENDCASE =0 DEF FNcon_beam(box%, bogus%) IF bogus%=0 =0 PROCacquisition_display_switches(box%) IF FNswitch(FNcon_beam_line(box%),E%)=Off THEN =0 REM Otherwise animal has entered CON beam. PROCrecord_event(box%,LOC_CON_BEAM%) CASE state%(box%) OF WHEN stimulus_state%: IF has_approached%(box%)=no% THEN REM First approach during this stimulus. first_approach%(box%, trial%(box%), stimpres%(box%)) = con% first_approach_latency%(box%, trial%(box%), stimpres%(box%)) = TIME - state_start_time%(box%) IF FNwhich_stimulus_to_give(box%,trialorder%(box%,trial%(box%)),stimpres%(box%))=con% OR task%=probe% THEN REM CON to CON approach. con_approach_total%(box%) += 1 ENDIF has_approached%(box%) = yes% ENDIF OTHERWISE: REM not interested ENDCASE =0 DEF FNmagazine_entry(box%, bogus%) IF bogus%=0 =0 LOCAL t%, s% PROCacquisition_display_switches(box%) IF FNswitch(central_mag_nosepoke%(box%),E%)=Off THEN =0 PROCrecord_event(box%,LOC_MAGAZINE%) CASE state%(box%) OF WHEN iti_state%: IF trial%(box%)=first_trial_num%(box%) AND stimpres%(box%)=0 THEN =0 REM haven't had any food yet IF has_fed%(box%)=no% THEN food_latency%(box%, feeding_trial%(box%), feeding_stimpres%(box%)) = TIME - state_start_time%(box%) has_fed%(box%)=yes% ENDIF OTHERWISE: ENDCASE =0 DEF FNscreen_touched(box%, label$, on_off%) REM Label will be "L" or "R" IF on_off% = 0 THEN REM going off, don't do much CASE label$ OF WHEN cs_side$(box%): cs_touching%(box%) = no% OTHERWISE: con_touching%(box%) = no% ENDCASE ELSE REM going on, much more interesting, oh yes. CASE label$ OF WHEN cs_side$(box%): PROCrecord_event(box%,LOC_CS_CONTACT%):cs_touching%(box%) = yes% OTHERWISE: PROCrecord_event(box%,LOC_CON_CONTACT%):con_touching%(box%) = yes% ENDCASE ENDIF PROCacquisition_display_switches(box%) =0 DEF PROCacquisition_finished(box%) finished%(box%) = yes% PROCacquisition_set_state(box%, finished_state%) PROCswitch_off(houselight%(box%), E%) PROCkill_timer(acquisition_vi_timer% + box%, E%) PROCkill_timer(acquisition_stim_timer% + box%, E%) PROCkill_switch(central_mag_nosepoke%(box%), E%) PROCkill_switch(FNcs_beam_line(box%), E%) PROCkill_switch(FNcon_beam_line(box%), E%) PROCkill_switch(floor_panel%(box%), E%) PROClcd(FNwhich_lcd(box%)):CLS:CLG:PROCupdate_lcd(FNwhich_lcd(box%)):PROCscreen LOCAL box% FOR box%=1 TO nboxes% IF finished%(box%)<>yes% THEN ENDPROC NEXT PROCkill_all CLS PRINT "All done." PROCreport_useful_data PROCreport_events PROCreport_log ENDPROC DEF PROCacquisition_setup_display CLS COLOUR red% PRINT "AUTOSHAPING - ";:COLOUR white%:PRINT task$:COLOUR red% IF debug%=1 COLOUR yellow%:PRINT"--- DEBUGGING!!! ---":COLOUR red% PRINT PRINT "Press 1-";nboxes%;" to start the boxes, and F1-F";nboxes%;" to abort them." PRINT "The second line of the display for each box shows which sensors are" PRINT "activated, according to the following key:" PRINT " M = food magazine B+ = CS beam B- = CON beam" PRINT " P = back panel C+ = CS touched C- = CON touched" PRINT PRINT COLOUR green% REM 01234567890123456789012345678901234567890123456789012345678901234567890123456789 PRINT "Box Rat CS side Trial Stim 1/2 Stimulus State" PRINT "______________________________________________________________________________" display_firstline%=VPOS COLOUR white% ENDPROC DEF PROCacquisition_update_status(box%) LOCAL p, v v = FNacquisition_display_line(box%) PRINT TAB(0,v);box%; PRINT TAB(4,v);rat_name$(box%); PRINT TAB(13,v);cs_side$(box%); PRINT TAB(22,v);trial%(box%); PRINT TAB(29,v);:IF stimpres%(box%)=0 THEN PRINT;"First ";:ELSE PRINT;"Second"; PRINT TAB(40,v);stimulus_description$( FNwhich_stimulus_to_give(box%,trialorder%(box%,trial%(box%)),stimpres%(box%)) );" "; PROCacquisition_display_state(box%) PROCacquisition_display_switches(box%) ENDPROC DEF PROCacquisition_display_state(box%) PRINT TAB(51,FNacquisition_display_line(box%)); COLOUR yellow% CASE state%(box%) OF WHEN ignoring_state%: PRINT "Please start the box." WHEN waiting_for_backpanel_state%: PRINT "Waiting for rat " WHEN stimulus_state%: PRINT "Stimulus on " WHEN iti_state%: PRINT "In interval... " WHEN finished_state%: PRINT "* Finished. " ENDCASE COLOUR white% ENDPROC DEF PROCacquisition_display_switches(box%) LOCAL v v = FNacquisition_display_line(box%)+1 COLOUR green% PRINT TAB(10,v);:IF FNswitch(central_mag_nosepoke%(box%),E%)=On THEN PRINT"M";: ELSE PRINT" "; PRINT TAB(12,v);:IF FNswitch(FNcs_beam_line(box%),E%)=On THEN PRINT"B+";: ELSE PRINT" "; PRINT TAB(15,v);:IF FNswitch(FNcon_beam_line(box%),E%)=On THEN PRINT"B-";: ELSE PRINT" "; PRINT TAB(18,v);:IF FNswitch(floor_panel%(box%),E%)=On THEN PRINT"P";: ELSE PRINT" "; PRINT TAB(20,v);:IF cs_touching%(box%)=yes% THEN PRINT"C+";: ELSE PRINT" "; PRINT TAB(23,v);:IF con_touching%(box%)=yes% THEN PRINT"C-";: ELSE PRINT" "; COLOUR white% ENDPROC DEF FNacquisition_display_line(box%) =display_firstline% + 3*(box%-1) DEF FNacquisition_clock_tick(junk%, bogus%) IF bogus%=0 =0 LOCAL box% COLOUR magenta% FOR box%=1 TO nboxes% IF started%(box%)=yes% AND finished%(box%)=no% THEN PRINT TAB(70,FNacquisition_display_line(box%)+1);FNtimestring(TIME - start_time%(box%)); ENDIF NEXT COLOUR white% =0 DEF FNwhich_stimulus_to_give(box%, trialorder%, stimpres%) IF task%=probe% THEN =both% IF trialorder%=cs_first% AND stimpres%=0 THEN =cs% IF trialorder%=cs_first% AND stimpres%=1 THEN =con% IF trialorder%=con_first% AND stimpres%=0 THEN =con% IF trialorder%=con_first% AND stimpres%=1 THEN =cs% VDU7:PRINT"Awful error in FNwhich_stimulus_to_give." =0 DEF FNstimulus_side(box%, type%) IF cs_side$(box%) = "L" AND type% = cs% THEN =left% IF cs_side$(box%) = "L" AND type% = con% THEN =right% IF cs_side$(box%) = "R" AND type% = cs% THEN =right% IF cs_side$(box%) = "R" AND type% = con% THEN =left% VDU7:PRINT"Awful error in FNstimulus_side." =0 DEF FNcs_beam_line(box%) IF cs_side$(box%) = "L" THEN =left_sensor_nosepoke%(box%) ELSE =right_sensor_nosepoke%(box%) DEF FNcon_beam_line(box%) IF cs_side$(box%) = "R" THEN =left_sensor_nosepoke%(box%) ELSE =right_sensor_nosepoke%(box%) DEF PROCrecord_event(box%, location%) LOCAL event% current_event%(box%) += 1 event% = current_event%(box%) IF event% > max_events% THEN VDU 7:PRINT TAB(0,0); "Maximum number of events recorded!":ENDPROC event_location%(box%, event%) = location% event_trial%(box%, event%) = trial%(box%) event_stimpres%(box%, event%) = stimpres%(box%) event_state%(box%, event%) = state%(box%) event_starttime%(box%, event%) = TIME - state_start_time%(box%) ENDPROC DEF PROCreport_useful_data LOCAL ch%,box%,t%,sp% ch% = OPENOUT(datafile$) PROCprint_string(ch%,"PROGNAME,TASK,DATE_TIME,") PROCprint_string(ch%,"RAT,BOX,CS_SIDE,TRIAL,STIMPRES,") PROCprint_line(ch%,"VI_LENGTH,PANEL_LATENCY,STIMULUS_PRESENTED,FIRST_APPROACH,FIRST_APP_LATENCY,FOOD_LATENCY") FOR box% = 1 TO nboxes% FOR t% = first_trial_num%(nboxes%) TO trial%(box%) FOR sp% = 0 TO 1 IF NOT(sp%=1 AND task%=probe%) THEN PROCprint_string(ch%,progname$+","+task$+","+date_time$+",") PROCprint_string(ch%,rat_name$(box%)+","+STR$(box%)+","+cs_side$(box%)+","+STR$(t%)+","+STR$(sp%)+",") PROCprint_string(ch%,STR$(vi_length%(box%,t%,sp%))+","+STR$(panel_latency%(box%,t%,sp%))+",") PROCprint_string(ch%,stimulus_description$(stimulus_presented%(box%,t%,sp%))+",") PROCprint_string(ch%,stimulus_description$(first_approach%(box%,t%,sp%))+",") PROCprint_string(ch%,STR$(first_approach_latency%(box%,t%,sp%))+",") PROCprint_line(ch%,STR$(food_latency%(box%,t%,sp%))) ENDIF NEXT NEXT NEXT CLOSE#ch% ENDPROC DEF PROCreport_events LOCAL ch%,box%,e% ch% = OPENOUT(eventfile$) PROCprint_line(ch%,"DATE_TIME,RAT,BOX,EVENT,TRIAL,STIMPRES,STATE,LOCATION,STARTTIME") FOR box% = 1 TO nboxes% FOR e% = 1 TO current_event%(box%) PROCprint_string(ch%,date_time$+","+rat_name$(box%)+",") PROCprint_string(ch%,STR$(box%)+","+STR$(e%)+","+STR$(event_trial%(box%,e%))+",") PROCprint_string(ch%,STR$(event_stimpres%(box%,e%))+","+STR$(event_location%(box%,e%))+",") PROCprint_line(ch%,STR$(event_starttime%(box%,e%))) NEXT NEXT CLOSE#ch% ENDPROC DEF PROCreport_log COLOUR white% IF debug%=0 THEN VDU 2 OSCLI("SPOOL "+logfile$) PRINT"=====================================================================" PRINT"!";progname$;", by Rudolf Cardinal, ";version_date$ PRINT"TASK - ";task$ PRINT"Finished at ";TIME$ PRINT"Date/time code: ";date_time$ IF debug%=1 COLOUR yellow%:PRINT"--- DEBUGGING!!! ---":COLOUR white% PRINT"=====================================================================" PRINT"Stimulus duration (s) = ";stimulus_duration%/100 PRINT"VI ranged from ";acquisition_min_interval%/100;"s to ";acquisition_max_interval%/100;"s" PRINT PRINT"Box Rat Side First trial# Last# Completed# CS approach CON appr." PRINT"-------------------------------------------------------------------------------" REM 01234567890123456789012345678901234567890123456789012345678901234567890123456789 FOR box%=1 TO nboxes% PRINT TAB(0);box%; PRINT TAB(5);rat_name$(box%); PRINT TAB(11);cs_side$(box%); PRINT TAB(17);first_trial_num%(box%); PRINT TAB(32);trial%(box%); PRINT TAB(41);completed_trials%(box%); PRINT TAB(56);cs_approach_total%(box%); PRINT TAB(70);con_approach_total%(box%) NEXT PRINT OSCLI("SPOOL") VDU 3 OSCLI("SETTYPE "+logfile$+" TEXT") COLOUR white% ENDPROC REM ================================================================================ DEF PROCprobe REM ================================================================================ LOCAL i% CLS task$ = "Probe" PRINT "PROBE." PRINT FOR i%=1 TO nboxes% PRINT "Enter rat name for box ";i%;": "; INPUT ""rat_name$(i%) cs_side$(i%) = FNget_letter_param("Is the CS+ on the left or right? (L/R)","LR","") first_trial_num%(i%) = FNget_num_param("Enter the first trial's number (usually 1) :",1,1,100) last_trial_num%(i%) = FNget_num_param("Enter the last trial's number (usually 20) :",first_trial_num%(i%)+19,first_trial_num%(i%),max_trials%) NEXT PROCshared_startup ENDPROC REM ================================================================================ DEF PROComission REM ================================================================================ LOCAL i% CLS task$ = "Omission" PRINT "OMISSION." PRINT FOR i%=1 TO nboxes% PRINT "Enter rat name for box ";i%;": "; INPUT ""rat_name$(i%) cs_side$(i%) = FNget_letter_param("Is the CS+ on the left or right? (L/R)","LR","") first_trial_num%(i%) = FNget_num_param("Enter the first trial's number (e.g. 1 or 51) :",1,1,100) last_trial_num%(i%) = FNget_num_param("Enter the last trial's number (e.g. 50 or 100) :",first_trial_num%(i%)+49,first_trial_num%(i%),max_trials%) NEXT PROCshared_startup ENDPROC