-
Notifications
You must be signed in to change notification settings - Fork 0
/
ChronicScript.s2s
4863 lines (4611 loc) · 170 KB
/
ChronicScript.s2s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
'FLAG REGISTRY: qhWaitingToJump%,qhWaitingToStartTrial%,qhInTrial%,qhWaitingForStimFinish%,qhWaitingForTrialFinish%,qhFinishTrial%,qhBehavOnly%,qhRecordingAndBehavior%,qhRecordingOnly%
'
'TODO save Log file incrementally
'
#include "include/chron_include.s2s" ' helper functions for chronic recording
StartupScript();
' SETUP GLOBAL VARIABLES
if 1 then 'This lets us fold away the variable set up for ease of viewing while editing!
const VERBOSELOG% := 1; '1 = normal debugging; 2= time/filesize debugging; ; 3= handler flag debugging
var ltime%:=-1;
' set IDs for toolbar buttons
const HANDLERID% := 0;
const FINISHEXPERIMENTID% := 1;
const PAUSEBLOCKID% := 3;
const STOPBLOCKID% := 4;
const LOOPSEARCHID% := 7;
const CHOOSESEARCHID% := 8;
const STOPRECID% := 12;
const ADJGAINSID% := 13;
const RESTRTSOMECHANSID% := 14;
const STARTEPOCHID% := 15;
const QUICKSTART1ID% := 17;
const SELECTACTIVESTIMSID% := 30;
const CLOSEOPCHECKWINID% := 34;
const CHECKOPERANTDATAID% := 35;
const CARCANCELID% := 37;
const CARID% := 38;
const SOFTREFID% := 39;
const SESVIEWID% := 40;
const MAXWAVCHANS% := 48;
var expPathRoot$ := "";
var stimLibPath$ := "";
var type1401% := 0;
var host$ := LCase$(System$("COMPUTERNAME"));
docase
case InStr("ibon", host$) then
type1401% := 5;
expPathRoot$ := "D:\\Experiments\\raw\\";
stimLibPath$ := "D:\\Experiments\\stimlib\\";
case InStr("paukstis", host$) then
type1401% := 7;
expPathRoot$ := "E:\\experiments\\raw\\";
stimLibPath$ := "E:\\experiments\\stimlib\\";
' case InStr("manu", host$) then
' var type1401% := 4;
' const MAXWAVCHANS% := 16;
' var expPathRoot$ := "F:\\Experiments\\raw\\";
' var stimLibPath$ := "F:\\Experiments\\stimlib\\";
case InStr("burung", host$) then
type1401% := 7;
expPathRoot$ := "F:\\Experiments\\raw\\";
stimLibPath$ := "F:\\Experiments\\stimlib\\";
' else
'
' retFPS%:=FilePathSet(expPathRoot$,0,"Select data folder.");
' if retFPS% < 0 then
' PrintLog(Print$("No file path set...exiting script. Error: %s",Error$(retFPS%)));
' halt;
' else
' expPathRoot$ := FilePath$();
' endif;
'
' retFPS%:=FilePathSet(expPathRoot$,0,"Select stimulus library.");
' if retFPS% < 0 then
' PrintLog(Print$("No file path set...exiting script. Error: %s",Error$(retFPS%)));
' halt;
' else
' stimLibPath$ := FilePath$();
' endif;
endcase;
' define paths
const defaultFPS% := 2; '1=use testchron, 2=use crappy windows dialogue, 3=let user type in name of folder in c:/experiments/
var seqPath$ := GetScriptPath$() + "sequencer\\";
var seqfile$;
var subjectpath$ := "";
subjectpath$ := PickSubjectPath$(defaultFPS%);
FilePathSet(subjectpath$);
PrintLog("Subject path (and current path) set to: %s\n\n", subjectpath$);
var stimPath$ := subjectpath$+"stims\\";
var dataPathRoot$ := subjectpath$+"data\\";
var dataPathPenetration$,dataPathRecordingSite$,dataPathEpoch$;
var subjectID$ :=Left$(Right$(subjectpath$,Len(subjectpath$)-19),Len(Right$(subjectpath$,Len(subjectpath$)-19))-1); 'TODO: fix and make robust to changes in path length
' define available sequencer files
var chronNOseq$ := seqPath$ + "chron_seq_NeurOnly.pls";
var chronNBseq2AC$ := seqPath$ + "chron_seq_2ac_VR.pls";
var chronNBseq2ACPS$ := seqPath$ + "chron_seq_2ac_VR-peckstop.pls";
var chronNBseqGNG$ := seqPath$ + "chron_seq_gng.pls";
var chronNBseqGNGPS$ := seqPath$ + "chron_seq_gng-peckstop.pls";
var chronNBseq$ := chronNBseq2AC$; '2ac is default (see DoSubjectInfo%() for switch)
' file variables
const NUMMAXIMUMTICKS% := -1; ' with v8 64bit .smrx files, no upper bound. 2147483647 for v7
const MAXCHANSPERFILE% := 400; 'default is 32, max for spike 6+ is 400
const MAXFILEMINS% := -1; 'set to <0 if you want to programmatically control based on sampling frequency etc. See CheckFileSizeLengthNTOD%()
const audioPWAKey$ := "a"; 'this is label for play wave area.
const trialAvailKeyCue$ := "S"; 'this jumps the sequencer to a place where it is ready to do a trial and turns on the cue light
const trialPauseKey$ := "P"; 'this jumps the sequencer to a place where it is Paused
const trialNightNightKey$ := "N"; 'this jumps the sequencer to shut off the operant apparatus and halt the sequencer
const trialResetKey$ := "R"; 'this jumps the sequencer to turn all outputs off except the house light
var firsttimestampcodes%[4],timestampcodes%[4];
ArrConst(firsttimestampcodes%[],243); 'this will be the unique code for the first timestamp on the textmark channel
ArrConst(timestampcodes%[],244); 'this will be the unique code for timestamps on the textmark channel
var once%:=1; 'I think this is for the first trial only (TODO: check this and rename with more descriptive name)
' ADC variables
var nWavChans%;
var savedWFChans%[MAXWAVCHANS%+1];
var currChanMap%[MAXWAVCHANS%+4]; '+1 for size at index 0 and +3 for crazy indexing in savedWFChans% due to chans 30, 31, 32 being reserved
var swc%;
'need to change this depending on which 1401 we use '4 for manu '5 for chronic rig '7 for burung 'BURUNGHACK
var GainList$[4];
GainList$[0] := "1";
GainList$[1] := "2";
GainList$[2] := "5";
GainList$[3] := "10";
var whichGainCtrl% := 3; 'This value will be the DEFAULT See AdjustGains%, 0=1x, 1=2x, 2=5x, 3=10x (given by GainList$)
var sampleRate% := 31250;
var sampleRate32ch% := 20000;
var burstMode% := 1; '-1: ignore, 0: off, 1: on
var BehavOnlysampleRate% := 40000; 'To record BOS/whatever else is going on in box (40K might be too high, but can easily delete Behav only waveform chans if no bos on em
var usecpertime;
var timeperADC;
var seqPerMs;
' Audio IO variables
' The 1401 hardware can only output intervals that are a multiple of 0.2usec. Instead of dealing with this all, we need to resample all stimuli to
' 40,000Hz before Spike2 ever sees them. As this corresponds to an exact integer interval (25usec), there should be no problem at all in reading it into Spike2,
' playing it back at the desired rate, and reading it into Matlab later.
' (Spike2 could really use some better documentation about this.)
const REQUESTEDaudioOutRate% := 40000;
if REQUESTEDaudioOutRate% <> 40000 then
WarnDlg("REQUESTEDaudioOutRate == %d NOT 40000","REQUESTEDaudioOutRate == %d NOT 40000");
endif
var REALaudioOutRate; 'This will hold the value returned by PlayWaveSpeed()
var maxStimMins% := 16; 'only used to constrain the buffer size.
' ^Limit of Power 1401 with 256Mb RAM @ 44100Hz is around 18 mins.
' If over, script will crash on 'PlayWaveCopy' and you will need to restart spike2, not just the script, to fix it.
if maxStimMins% > 18 then
WarnDlg("Play wave buffer set too large.",Print$("You requested a %d min buffer.\nThe empirical limit is 18 mins. Don't ask why, I don't know.\nResetting to 18 min audout buffer.",maxStimMins%));
maxStimMins%:=18;
endif
var audBuffSize% := REQUESTEDaudioOutRate%*60*maxStimMins%; 'in sampling units
var stimsz%; 'get from chandata, use to calc exact time to send to sequencer to give exact num dat points
var stimtimeSec; 'calc from stimsz% and REALaudioOutRate to calc seq steps to send to sequencer
var micport% := 31;
var BOmicchannel% := 25;
var dosavemicchannelduringBO% := 0; 'if this is set to 1, port 31 is recorded and saved along with the marker data (default is 0 to save disk space)
' display and handle vars***
var swXLow:=1.0, swYLow:=0.0,swXHigh:=100.0,swYHigh:=100.0;
var ymin[MAXWAVCHANS%+4], ymax[MAXWAVCHANS%+4];
ArrConst(ymin, -1.0);ArrConst(ymax, 1.0);
var optimizey% :=0;
var lastEpochView$ := "";
var datahandle%;
var opDatHandle%:=-1;
var opDatName$:="";
var doAllTrialsFile% := 1;
var AllTrialsHandle%:=-1;
var AllTrialsName$:= subjectpath$+subjectID$+".AllTrials";
var subjectInfoName$:=subjectpath$+subjectID$+".SubjectInfo";
var subjectInfoHandle% := -1;
var currWFChan%[17],currVChan%[17],currCARChan%[17];
currCARChan%[0]:=0;
var numCARs%:=0;
' time-of-day (TOD) loop variables
var dontuseTODStartStop% := 0;
var secondsSinceMinute%,minutessincemidnight%;
var beginHours%:= 0;
var beginMins%:=1;
var endHours%:= 23;
var endMins%:=59;
var beginningOfDayInminutessincemidnight% := beginHours%*60 + beginMins%;
var endOfDayInminutessincemidnight%;
if dontuseTODStartStop% = 1 then
endOfDayInminutessincemidnight% := 9999; 'The day will never end!!!
else
endOfDayInminutessincemidnight% := endHours%*60 + endMins%;
endif
var qisNight% := 0;
var wentToSleep%:=0;
PrintLog("\nStart of Day Time: %d:%d.\nEnd of Day Time: %d:%d\n\n\n",beginHours%,beginMins%,endHours%,endMins%); 'put here in case cancel button is hit on setupsubjectpath
' file info variables
var fDate$ :=Date$(2,2,1,1,"-");
var fTime$ :=Time$(1,7,0,":");
var FileInfo$ := "Date:"+fDate$+"Time:"+fTime$; 'fileinfo$ will be inserted into the file comments using filecomment$()
' penetration variables
var penetrationInfo$ := "Null";
var penetrationNum%;
var currpencomments$ := "";
' electrode variables
var electrodeInfo$ := "Null";
var currElectrode$ := "";
var infoFileTrodeType%;
var trodeType%;
var eTrodeList$[11];
eTrodeList$[0]:="16 - 2x2 tetrode (F16) - NeuroNexus";
eTrodeList$[1]:="16 - 1x16 singles (F16) - NeuroNexus";
eTrodeList$[2]:="32ch - Poly3 - NeuroNexus";
eTrodeList$[3]:="1 - single Platinum Iridium - GentnerCo.";
eTrodeList$[4]:="1 to 1 (16) - Chan # matches port #";
eTrodeList$[5]:="1 to 1 (32) - Chan # matches port #";
eTrodeList$[6]:="24 - 1x16 singles + LFP - NeuroNexus";
eTrodeList$[7]:="16 - 1x16 singles (H16) - NeuroNexus";
eTrodeList$[8]:="32 - 1x32 singles (A32) - NeuroNexus";
eTrodeList$[9]:="32 - 4x8 N-Form - Modular Bionics";
eTrodeList$[10]:="16 - 1x16 singles (A16) - NeuroNexus";
var eTrodeComments$:="";
var eTrodeImpedance$:="";
var eTrodeID$:="";
' site variables
var recordingSiteInfo$:="Null";
var recordingSiteNum%;
var currsitecomments$ := "";
' epoch variables
var epochInfo$:="Null";
var epochNum%:=0;
var currepochcomments$ := "";
var datafilenumber% := 0;
var currentEpochStartDateTime$ := "";
' stimuli variables
const MAXSTIMS% := 2000;
const MAXMCSTIMS% := 1000000;
const stimExt$ := ".wav";
var numStimFiles%, stimFileNames$[maxStims%], searchStimsEnabled%[maxStims%],blockStimsEnabled%[maxStims%],stimTimes[maxStims%];
var dolongstim%:=0, stimfh%:=-1, startT, stopT, skip;
var currentStimLength:=0.0, currentStimName$:="",currentStimClass%,currentStimPcntReinf%,currentStimPcntTo%;
var currStim%:=-1,lastStim%:=-1;
var maxstimlength;
var relE,relENO;
var tmcode%[4]; 'textmark codes: 0=stimcode,1=stimclass,2=correctiontrial(1=correction,0=not correction),3=currently unused
'DK: {during the MC task, tmcode%[2] used to be used to indicate stimulus type - I think it interferred with correction trial encoding, but I don't think I ever used correction trials so no big deal.}
ArrConst(tmcode%[],0);
var stimClasses%[MAXSTIMS%],stimPctPres[maxStims%],stimPctReinf%[maxStims%],stimPctTo%[maxStims%],stimCodes%[maxStims%];
var totpres%:=0;
var rndplist%[MAXSTIMS%]; 'Arbitrary length, might need to be bigger if there are really maxStims% number of stims
var desPctPres[MAXSTIMS%],desPctReinf%[MAXSTIMS%],desPctTo%[MAXSTIMS%];
ArrConst(desPctPres[],-1.0);
ArrConst(desPctReinf%[],-1);
ArrConst(desPctTo%[],-1);
' stimulus selection variables
const MAXBLOCKTRIALS% := 10000;
var blockPlaylist%[MAXBLOCKTRIALS%];
ArrConst(blockPlaylist%[],-1);
var numBlockRepeats% := 1;
const MAXREPEATS%:=999;
var blockTrialNum%:=0;
var blockPos%;
var totBlockTrials%:=0;
const NUMSHUFFLES%:=99999;
var blockNum% := 0;
var trialFailures% := 0;
var totalRunSecs := 0.0;
var searchInd%:=-1;
' trial variables
var behType$ := "2AC"; 'this should actually be a subject variable
var RESPWIN := 2.0; 'response window duration in seconds
var FEED := 2.0; 'feed duration in seconds
var TIMEOUT := 10.0; 'timeout duration in seconds
var ITI := 2.0; 'intertrial interval in seconds
var ITINO;
var MINITINO := 8.0; 'minimum intertrial interval in seconds for neural recording only
var MAXITINO := 10.0; 'maximum intertrial interval in seconds for neural recording only
var relS := -60.0; 'pretrigger save seconds
var correctionTrialsOn% := 0; 'default is no correction trials (set in SEsetupStimSelectStyle%()
var doCorrectionTrial% := 0;
var doFeedCorrectionTrials% := 0;
var peckStopOn% := 0;
var currtrialstarttime := -1.0;
var trialoutcome%[5]; '0 = accuracy, 1 = class , 2 = correction, 3 = selection, 4 = reinforced
ArrConst(trialoutcome%,-1);
var feedRatioMax% := 1; '
' trial scheduling variables
var qTrialAvailability% := 1; '0 = trials unavailable, 1 = trials available
var trialAvailablityMins%[2];
trialAvailablityMins%[0] := 0; 'off minutes
trialAvailablityMins%[1] := 99999; 'on minutes
var lastAvailabilityCycleStartMSM% := -1; 'will denote the time (in minutes since midnight) of the last trial availability cycle start time
' protocol variables
var protocoltype$ := "normal";
var protocolmode% := -1; 'initialized to -1 so that if the protocol doesn't update it, it gets passed to PickMode()
var protocolstimselectionstyle% := -1;
var protFileName$;
var protFileFullName$ := "none";
var stimFileName$;
var stimFileFullName$ := "";
' setstim variables
var qdosetstims% := 0;
var qneednewset%:=-1;
var qusepreviousset%:=-1;
var numsetstimclasses% := 6;
var ssCriterionLength% := 20;
var ssCriterionCorrect%[1];
resize ssCriterionCorrect%[numsetstimclasses%+1];
ssCriterionCorrect%[0] := 6;
ssCriterionCorrect%[1] := 15;
ssCriterionCorrect%[2] := 15;
ssCriterionCorrect%[3] := 0;
ssCriterionCorrect%[4] := 0;
ssCriterionCorrect%[5] := 15;
ssCriterionCorrect%[6] := 15;
var ssCriterionReached%[1];
resize ssCriterionReached%[numsetstimclasses%+1];
ssCriterionReached%[0] := numsetstimclasses%;
ssCriterionReached%[1] := 0;
ssCriterionReached%[2] := 0;
ssCriterionReached%[3] := 0;
ssCriterionReached%[4] := 0;
ssCriterionReached%[5] := 0;
ssCriterionReached%[6] := 0;
var lastNIndex%[1];
resize lastNIndex%[numsetstimclasses%+1];
var lastN%[1][1];
resize lastN%[numsetstimclasses%+1][ssCriterionLength%];
ArrConst(lastN%[][],0);
var ssnumsets%[3];
ArrConst(ssnumsets%[],1);
var mastersetstimfile$ := "nomastersetstimfile";
var currsetstimfile$ := "nocurrsetstimfile";
var numfoundcurrsetstimfiles%:=0;
var foundcurrsetstimfiles$[100];
var currsetstimparamsfile$ := "D:\\experiments\\stimlib\\defaultsetstimsparamsfile.m";
var mastersetstimNum%:=0;
var setstimNum%:=0;
' MCstim variables
var qMC% := 0;
var MCmaxnummots%:=0,MCminnummots%:=0;
var MCclassoneMaxnummots%:=0,MCclassonePctReinf%:=0,MCclassonePctTo%:=0;
var MCclasstwoMaxnummots%:=0,MCclasstwoPctReinf%:=0,MCclasstwoPctTo%:=0;
var MCclassthreeMaxnummots%:=0,MCclassthreePctReinf%:=0,MCclassthreePctTo%:=0;
var MCallowLR%:=0;
var MCallowambig%:=0;
var MCtotnum%:=0;
var MCstimClasses%[MAXMCSTIMS%]; 'This will hold the class of each created MC stim (aligns with MCstimFilenames$)
var MCstimFilenames$[MAXMCSTIMS%];
var MCnumMots%[MAXMCSTIMS%];
' analysis/check variables
var tempdatafilename$,tempdatafilepath$;
var currSeekTime := -1;
var lastEventTime := -1;
var lastTrialEndTime := -0.5;
var lastSizeCheckTime := -1;
var secondsBTSizeChecks := 30; 'Set this to a reasonable number.
'secondsBTSizeChecks - if too big will slow down the code, too little and you might miss going over the size limit
'w/17 wf channels @25Khz, 10 mins ~500Mb, therefore checking size every 30 seconds should give ~25Mb resolution
var opData%[MAXSTIMS%][6]; 'Each row is a diff stim, columns are: num presentations, num correct, num feeds, num incorrect, num TOS, num no responses
' flag variables, denoted with a prefixed 'q' and CamelCase
var qSearching% := 0;
var qLoop% := 0;
var qNeedNewBlock% := 0;
var qDoBlocks% := 0;
var qAskUserBlockParams% := 1;
var qSelectRandly% := 0;
var qPausedBlock% := 0;
var qStopBlock% := 0;
var qProtocolFileSetup% := 0;
' handler variables, denoted with a prefixed 'qh' and CamelCase
var qhRecordingAndBehavior% := 0;
var qhRecordingOnly% := 0;
var qhBehavOnly% := 0;
var qhInTrial% := 0;
var qhInEpoch% := 0;
var qhWaitingToJump% := 0;
var qhWaitingToStartTrial% := 0;
var qhWaitingForStimFinish% := 0;
var qhWaitingForTrialFinish%:= 0;
var qhFinishTrial% := 0;
'
endif
'RUN THE SCRIPT
FilePathSet(dataPathRoot$,0,1);
SetupToolbar();
ToolbarState("WaitInToolbar");
PL("Entering Toolbar");
Toolbar("toolbar running",1+2+4+8+16+32+64+128+256+512,0);
PL("Exiting Toolbar");
halt; 'the script is finished
' FUNCTIONS AND PROCEDURES
' SETUP
proc SetupToolbar()
ToolbarSet(HANDLERID%,"",Handler%);
ToolbarSet(FINISHEXPERIMENTID%,"Finish experiment|0x1b|<esc>",QuitScript%);
ToolbarSet(STOPRECID%,"Stop Recording Epoch||",doStopEpoch%);
ToolbarEnable(STOPRECID%,0);
'ToolbarSet(PAUSEBLOCKID%,"Pause block||",PauseBlock%);
'ToolbarEnable(PAUSEBLOCKID%,0);
'ToolbarSet(STOPBLOCKID%,"Stop block||",doStopBlock%);
'ToolbarEnable(STOPBLOCKID%,0);
'ToolbarSet(LOOPSEARCHID%,"Loop this search stim",doSetLoop%);
'SetLoop(0,0);
'ToolbarSet(CHOOSESEARCHID%,"Choose search stims",ChooseSearchStims%);
ToolbarSet(ADJGAINSID%,"Adjust Gains",doAdjustGains%);
ToolbarEnable(ADJGAINSID%,0);
'ToolbarSet(RESTRTSOMECHANSID%,"Restart w/Subset of Chans",RestartSubsetChans%);
'ToolbarEnable(RESTRTSOMECHANSID%,0);
ToolbarSet(STARTEPOCHID%,"Start Epoch",doStartEpoch%);
ToolbarSet(SELECTACTIVESTIMSID%,"SelectActiveStims",DoSelectActiveStims%);
ToolbarEnable(SELECTACTIVESTIMSID%,0);
ToolbarSet(CHECKOPERANTDATAID%,"Behavior Summary",CheckOpdata%);
ToolbarEnable(CHECKOPERANTDATAID%,0);
ToolbarSet(CLOSEOPCHECKWINID%,"Close Behavior Checks",CloseOperantDataCheckWindows%);
ToolbarEnable(CLOSEOPCHECKWINID%,0);
ToolbarSet(SOFTREFID%,"Setup Software Referencing",SoftRefSetup%);
ToolbarEnable(SOFTREFID%,0);
ToolbarSet(CARID%,"Setup CAR",CARSetup%);
ToolbarEnable(CARID%,0);
ToolbarSet(CARCANCELID%,"Cancel all CARs",CARCancel%);
ToolbarEnable(CARCANCELID%,0);
ToolbarSet(SESVIEWID%,"Load Last View",DoLoadEpcView%);
ToolbarEnable(SESVIEWID%,0);
'ToolbarSet(QUICKSTART1ID%,"QuickNBRPA",QuickNBRPA%); 'TODO: need to update QuickNBRPA% to use infofile etc
'TODO: have separate recording protocol files (diff than stim protocol file...) where we read in all info and just get up and recording?
ToolbarEnable(QUICKSTART1ID%,1);
end
'
func Handler%() 'Anything on the scale of the current script instance
'This is the idle function run by the main script toolbar
if VERBOSELOG%=3 then
if SampleStatus() = 2 then
var s%;
s% := MaxTime();
if s% > ltime% + 3 then 'do this roughly every 3 seconds
ltime% := s%;
PL("Current Flag Variables:\n");
PrintLog("qSearching%:\t%d\n",qSearching%);
PrintLog("qLoop%:\t%d\n",qLoop%);
PrintLog("qNeedNewBlock%:\t%d\n",qNeedNewBlock%);
PrintLog("qDoBlocks%:\t%d\n",qDoBlocks%);
PrintLog("qSelectRandly%:\t%d\n",qSelectRandly%);
PrintLog("qPausedBlock%:\t%d\n",qPausedBlock%);
PrintLog("qStopBlock%:\t%d\n",qStopBlock%);
PrintLog("qProtocolFileSetup%:\t%d\n",qProtocolFileSetup%);
PrintLog("qhRecordingAndBehavior%:\t%d\n",qhRecordingAndBehavior%);
PrintLog("qhRecordingOnly%:\t%d\n",qhRecordingOnly%);
PrintLog("qhBehavOnly%:\t%d\n",qhBehavOnly%);
PrintLog("qhInTrial%:\t%d\n",qhInTrial%);
PrintLog("qhInEpoch%:\t%d\n",qhInEpoch%);
PrintLog("qhWaitingToJump%:\t%d\n",qhWaitingToJump%);
PrintLog("qhWaitingToStartTrial%:\t%d\n",qhWaitingToStartTrial%);
PrintLog("qhWaitingForStimFinish%:\t%d\n",qhWaitingForStimFinish%);
PrintLog("qhWaitingForTrialFinish%:\t%d\n",qhWaitingForTrialFinish%);
PrintLog("qhFinishTrial%:\t%d\n",qhFinishTrial%);
PrintLog("\n\n");
endif
endif
endif
docase
case qhInTrial% = 1 then 'being in a trial trumps all else - do all the other checks outside of a trial
return HTrial%();
case HcEpoch%() = 1 then 'should be in an Epoch
return HEpoch%(); 'return anything but 1 to abort the script
else
ToolbarText("Click on Start Epoch to...Start a Recording Epoch...");
endcase
return 1;
end
'
func HcEpoch%() 'Hc for 'Handler check'
'if qTrialAvailability% = 0 then 'this means we're in an epoch and we just don't have trials available.
' return 1;
'else
return qhInEpoch%;
'endif
end
'
func HEpoch%()
'
if HcNight%(beginningOfDayInminutessincemidnight%,endOfDayInminutessincemidnight%) = 1 then 'it is nighttime - no trials available - no datafile open - house lights off
return HdoNight%();
endif
'
if HcTrialsAvailable%() = 1 then
return HdoTrials%();
else
return HdoTrialsoff%(); 'turn cue light off etc etc
endif
'
PrintLog("Not sure how you got here, aborting script.\nIn HEpoch%()\n");
return 0'should never get here
'
end
'
func HcNight%(beginningOfDayInminutessincemidnight%,endOfDayInminutessincemidnight%)
TimeDate(secondsSinceMinute%,minutessincemidnight%);
if (minutessincemidnight% > endOfDayInminutessincemidnight%) or (minutessincemidnight% < beginningOfDayInminutessincemidnight%) then
'we're in the nighttime bit
qisNight% := 1;
return 1
else
qisNight% := 0;
return 0
endif
end
'
func HdoNight%()
if SampleStatus() = 2 then 'sampling is still happening and so this is the first time we've passed the nighttime check - close down the datafile etc
lastAvailabilityCycleStartMSM% := -1;
SampleKey(trialNightNightKey$);
Yield(5);
StopRecordingandSave%(0); 'I think this happens before the sequencer gets to shut the light off, adding a pause before this.
PL(Print$("It's nighttime, waiting for %02d:%02d to restart",beginHours%,beginMins%));
ToolbarText(Print$("It's nighttime, waiting for %02d:%02d to restart",beginHours%,beginMins%));
else ' can get here if sampling is off when the bird is in trialsavailable=0 condition, still need to reset stuff for morning.
lastAvailabilityCycleStartMSM% := -1;
'PL(Print$("It's nighttime, waiting for %02d:%02d to restart",beginHours%,beginMins%)); 'WOAH THAT MAKES A HUGE TEXTFILE!
ToolbarText(Print$("It's nighttime, waiting for %02d:%02d to restart",beginHours%,beginMins%));
'anything we want to do in here while looping at nighttime? TODO: YES! MAKE SURE LIGHTS ARE OFF!!
endif
return 1
end
'
func HcTrialsAvailable%()
TimeDate(secondsSinceMinute%,minutessincemidnight%);
if lastAvailabilityCycleStartMSM% = -1 then 'the default is to start with a 'trials on' sequence
lastAvailabilityCycleStartMSM% := minutessincemidnight%;
qTrialAvailability% := 1;
endif
if minutessincemidnight% >= lastAvailabilityCycleStartMSM% + trialAvailablityMins%[qTrialAvailability%] then 'reset cycle, flip availability
lastAvailabilityCycleStartMSM% := minutessincemidnight%;
if qTrialAvailability% = 1 then
qTrialAvailability% := 0;
return 0
else
PL(Print$("Starting the next TrialsAvailableOn sequence. Trials will continue for the next %d minutes",trialAvailablityMins%[1]));
qTrialAvailability% := 1;
return 1;
endif
else
return qTrialAvailability%
endif
end
'
func HdoTrialsoff%()
var trialPauseTime; 'don't know if I'll ever need this, but don't forget that it exists
if SampleStatus() = 2 then 'sampling is happening, there is a datafile being written to - pause the sequencer and turn the datafile off!
PL(Print$("Pausing the sequencer and starting the next TrialsAvailableOff sequence. Trials will restart in %d minutes",trialAvailablityMins%[0]));
trialPauseTime:=SampleKey(trialPauseKey$); 'this pauses the sequencer (puts it to PTPK section), will unpause when script passes 'S' again
StopRecordingandSave%(0);
else
var hHTA%,mHTA%,sHTA%;
HoursMinsSecs((lastAvailabilityCycleStartMSM% + trialAvailablityMins%[qTrialAvailability%])*60,hHTA%,mHTA%,sHTA%);
ToolbarText(Print$("Looping in trialsoff, waiting until %02d:%02d",hHTA%,mHTA%));
'anything we want to do in here while looping in trialsoff?
endif
return 1;
end
'
'
'
'***BEGIN: DoTrial Code***
'
'
func HdoTrials%()
if SampleStatus() <> 2 then 'no sampling happening, so start it!
if HStartSampling%() <> 1 then
PL("Data File Setup Failed: Returning to Toolbar");
ZeroAllFlags();
ToolbarState("WaitInToolbar");
return 1;
else
return 1;
endif
else 'already sampling
return HPreTrial%();
endif
return 1
end
'
func HStartSampling%()
'
var ret%,iIR%,usersView%,chttl$,hchan%,hssSuccess%:=0,retPWSpd;
'var chanspec%[4];
ToolbarState("StartSampling");
'
FilePathSet(dataPathEpoch$);
ret%:=FilePathSet(dataPathEpoch$,1);
if ret%=0 then
usersView%:=View();
'
datahandle%:=FileNew(0,0); 'Main Datafile is created here
if datahandle%>=0 then 'all went well, set some display options
'XRange(-1,30);
SampleAutoFile(0);
View(datahandle%).DrawMode(-1,14); 'text draw mode??
View(datahandle%).Draw(0,10);
View(datahandle%).Window(swXLow,swYLow,swXHigh,swYHigh);
View(datahandle%).WindowVisible(1);
FrontView(datahandle%);
if qhBehavOnly% then
View(datahandle%).WindowTitle$("Sampled Behavioral Data");
ChanTitle$(30,"stimulus");
ChanTitle$(micport%,"Aud. Stim.");
DrawMode(micport%, 9, 256, 1, 96, 96, 1, 0);
else
View(datahandle%).WindowTitle$("Sampled Data");
docase
case(trodeType% = 0) then
for iIR%:=1 to currChanMap%[0] do
View(datahandle%).YRange(iIR%,ymin[iIR%],ymax[iIR%]);
'PrintLog("ymin[%d]:%g \tymax[%d]:%g\n", iIR%, ymin[iIR%], iIR%, ymax[iIR%]);
chttl$ := Print$("Port %d", currChanMap%[iIR%]);
ChanTitle$(iIR%,chttl$);
if(iIR%<5) then
ChanColour(iIR%,1,9);
else
if (iIR%<9) then
ChanColour(iIR%,1,10);
else
if (iIR%<13) then
ChanColour(iIR%,1,11);
else
ChanColour(iIR%,1,12);
endif
endif
endif
next;
ChanTitle$(currChanMap%[0],"Aud. Stim.");
DrawMode(currChanMap%[0], 9, 256, 1, 96, 96, 1, 0);
case(trodeType% = 1 or trodeType% = 4 or trodeType% = 6 or trodeType% = 7 or trodeType% = 8 or trodeType% = 10) then
for iIR%:=1 to currChanMap%[0] do
if currChanMap%[iIR%] <> -1 then
View(datahandle%).YRange(iIR%,ymin[iIR%],ymax[iIR%]);
'PrintLog("ymin[%d]:%g \tymax[%d]:%g\n", iIR%, ymin[iIR%], iIR%, ymax[iIR%]);
chttl$ := Print$("Port %d", currChanMap%[iIR%]);
ChanTitle$(iIR%,chttl$);
endif
next;
ChanTitle$(currChanMap%[0],"Aud. Stim.");
DrawMode(currChanMap%[0], 9, 256, 1, 96, 96, 1, 0);
case(trodeType% = 2 or trodeType% = 5) then
for iIR%:=1 to currChanMap%[0]+4 do
if currChanMap%[iIR%] <> -1 then
View(datahandle%).YRange(iIR%,ymin[iIR%],ymax[iIR%]);
'PrintLog("ymin[%d]:%g \tymax[%d]:%g\n", iIR%, ymin[iIR%], iIR%, ymax[iIR%]);
chttl$ := Print$("Port %d", currChanMap%[iIR%]);
ChanTitle$(iIR%,chttl$);
endif
' if(iIR%<30) then
' if (iR% mod 3)=0 then
' ChanColour(iIR%,1,9);
' else
' if (iIR%=33) then
' ChanColour(iIR%,1,4);
' else
' if (iIR%=32) then
' ChanColour(iIR%,1,5);
' else
' ChanColour(iIR%,1,6);
' endif
' endif
' endif
next;
ChanTitle$(currChanMap%[0]+4,"Aud. Stim.");
DrawMode(currChanMap%[0]+4, 9, 256, 1, 96, 96, 1, 0);
case(trodeType% = 3) then
for iIR%:=1 to nWavChans% do
if currChanMap%[iIR%] <> -1 then
View(datahandle%).YRange(iIR%,ymin[iIR%],ymax[iIR%]);
'PrintLog("ymin[%d]:%g \tymax[%d]:%g\n", iIR%, ymin[iIR%], iIR%, ymax[iIR%]);
chttl$ := Print$("Port %d", currChanMap%[iIR%-1]);
ChanTitle$(iIR%,chttl$);
endif
next;
ChanTitle$(currChanMap%[0],"Aud. Stim.");
DrawMode(currChanMap%[0], 9, 256, 1, 96, 96, 1, 0);
else
PrintLog("ERROR: Not sure which electrode type is being used. Channels are probably labeled incorrectly. trodeType% is: %d \n",trodeType%)
endcase
ChanTitle$(30,"stimulus textmark");
endif
'if find resource file to use, apply it
var epochDirFiles$[10];
var retFAR%;
FilePathSet(dataPathEpoch$);
if FileList(epochDirFiles$[],-1,"epochView.s2r") = 1 then
retFAR% := FileApplyResource(epochDirFiles$[0]);
else
XRange(-1,30);
endif
'
ret% := SampleStart(); 'Actually start sampling here
if ret%<0 then
PrintLog("ERROR: Error starting sampling: %s",Error$(ret%));
else
SampleWrite(1); 'write the data to disk
seqPerMs:=SampleSeqClock(1); 'get sequencer tick period
PL(Print$("\nSampling was started at %s",FileTime$(1,7,0,":")));
SampleText(Print$("date_%s_filetime_%f",GetTimeStamp$(),MaxTime()),-1,firsttimestampcodes%[]);
datafilenumber%+=1;
once%:=1;
hssSuccess%:=1;
'
tempdatafilepath$ := View(datahandle%).FileName$(1)+View(datahandle%).FileName$(2);
tempdatafilename$ := View(datahandle%).FileName$(3)+View(datahandle%).FileName$(4);
PL(Print$("Recording Initialized. Temp datafile: %s",tempdatafilepath$+tempdatafilename$));
'
retPWSpd := PlayWaveSpeed(audioPWAKey$,1.0,0,REALaudioOutRate);
PL(Print$("PlayWaveSpeed() confirms audio playback at %f Hz (REALaudioOutRate)",REALaudioOutRate));
usecpertime := SampleUsPerTime();
PL(Print$("SampleUsPerTime() shows %4.2f uspertime, which gives a max file time of %4.2f minutes",usecpertime,NUMMAXIMUMTICKS% * usecpertime * 1.0e-6 / 60.0));
'
' if not qhBehavOnly% then
' if VERBOSELOG% then PL(Print$("Attempting to set conditioner gains to %sx",GainList$[whichGainCtrl%])); endif
' AdjustGains%(whichGainCtrl%); 'default is 10x
' endif
'
View(datahandle%).CursorNew(0,1); 'Stim start
View(datahandle%).CursorNew(0,2); 'Stim end
if qhRecordingAndBehavior% or qhBehavOnly% then
View(datahandle%).CursorNew(0,3); 'response
View(datahandle%).CursorNew(0,4); 'end of response window
endif;
View(datahandle%).CursorNew(0,5); 'end of ITI
View(datahandle%).CursorVisible(-1,0);
'
currSeekTime := -0.5;
lastEventTime := -0.5;
lastTrialEndTime := -0.5; 'don't need for record only
'
if qhRecordingOnly% then
VAR waitNO := 1.0; 'seconds to wait before starting neural only stim presentation
Seconds(0);
While Seconds() < waitNO do 'record a bit of blank space at the beginning of a neural only recording
ToolbarText(Print$("Neural Only Recordings will start in %6.2f seconds",waitNO-Seconds()));
Draw();
wend;
endif;
'
endif
else
PrintLog("\n****\nERROR: Couldn't create new data file. error is: %s\nReturning to Toolbar.\n****\n\n",Error$(ret%));
WarnDlg("Couldn't create new data file.","Couldn't create new data file.\nIs the 1401 on?\nDidn't think so, don't worry it happens to the best of us!\nBack to Toolbar.");
endif;
else
PrintLog("ERROR: Failed to create or set the directory to put the data file in. error is: %s\n",Error$(ret%));
WarnDlg("ERROR: couldn't set directory","ERROR: Failed to create or set the directory to put the data file in.\nBack to Toolbar.");
endif;
return hssSuccess%
end
'
'
'************************************************************************************************************************************************
'
'***BEGIN: PreTrial Code***
'
'
func HPreTrial%()
'pick stim, load it, send trial available key to sequencer then wait until bird pecks
'var timeSinceLastSizeCheck:=View(datahandle%).Maxtime()-lastSizeCheckTime;
'if (timeSinceLastSizeCheck > secondsBTSizeChecks or lastSizeCheckTime = -1) then 'Only check the size once every x minutes
' lastSizeCheckTime := View(datahandle%).MaxTime();
' if CheckOkFileSize%() <> 1 then 'check every n minutes (there is some overhead associated)
' StopRecordingandSave%(0);
' return 1;
' endif
'endif
docase
case qhWaitingToJump% = 1 then
return HWaitingToJump%();
case qhWaitingToStartTrial% = 1 then
return HWaitingToStartTrial%();'in here, qhInTrial% gets set to 1 and further entrances into the handler get shunted off to HTrial%()
else
qhWaitingToJump% := HInitTrial%();
return 1;
endcase
return 1;
end
'
'
'func CheckOkFileSize%()
'var maxfilebytes% := 2000000000; '2 GB
'var fudge := 0.975; '50 MB
'var currFileSize;
'var currhandle%;
''
'if SampleStatus() <> 2 then 'sampling's not happening
' PrintLog("ERROR: this function should never be called if not sampling.\nHALTING.");
' return -1;
'else
' currhandle% := View();
' View(datahandle%);
' currFileSize := FileSize();
' if VERBOSELOG%=1 then PL(Print$("size of: %s is %d bytes",tempdatafilename$,Ceil(currFileSize)));endif
' if currFileSize > (maxfilebytes%*fudge) then '2Gb file size limit - 50Mb fudge factor
' View(currhandle%);
' return 0;
' else
' View(currhandle%);
' return 1;
' endif
'endif
'end
func HWaitingToJump%()
if VERBOSELOG%=1 then PL("in: HWaitingToJump%"); endif
var trialAvailableTime; 'don't know if I'll ever need this, but don't forget that it exists
if SampleSeqVar(5)<>1 then 'this is important, keeps script from stepping on sequencer's toes re:feed, TO, ITI dur
if VERBOSELOG%=1 then PL("Sending trialAvailKeyCue$ to sequencer."); endif
trialAvailableTime:=SampleKey(trialAvailKeyCue$); 'this triggers the sequencer to begin looking for a center key peck to begin a trial
qhWaitingToJump%:=0;
qhWaitingToStartTrial%:=1;
endif;
return 1;
end
'
func HWaitingToStartTrial%()
'TODO: check to see if bird is singing - if so, add a DigMark so that triggered recording starts
'
if CheckDigChan%(60) = 1 then ' '60' is the code in the sequencer for starting stim output
qhInTrial% := 1;
View(datahandle%).CursorVisible(-1,0); 'reset cursors for new trial
View(datahandle%).Cursor(1,lastEventTime);
View(datahandle%).CursorVisible(1,1);
View(datahandle%).SampleText(Print$("%f",MaxTime()),-1,timestampcodes%[]); 'this has 1sec resolution. To get better resolution, will need to compare time of '<' marker with the time of the start of sampling.
if VERBOSELOG%=1 then PL("Stimulus playback started."); endif
'
SampleText(currentStimName$,-1,tmcode%[]); 'write label to textmark channel
ToolbarText(Print$("Stim %s playing",currentStimName$));
qhWaitingToStartTrial%:=0;
qhWaitingForTrialFinish%:=1;
qhInTrial%:=1;
else
'waiting for the bird to peck - used to have a bunch of checks here, but these should be performed outside of this function
endif;
return 1;
end
'
func HInitTrial%()
var itSuccess%:=0,fn$;
var classFromSeq%,pctnofeedFromSeq,pctnotoFromSeq,corrCountFromSeq%,corrThreshFromSeq%;
var itiSeqSteps%,timeoutSeqSteps%,feedSeqSteps%,respwinSeqSteps%;
'
FilePathSet(stimPath$);
'reset all currrent stim variables
currentStimLength:=0.0;
currentStimClass%:=-1;
currentStimPcntReinf%:=-1;
currentStimPcntTo%:=-1;
'
currStim%:=SelectNextStim%();
'
docase
case currStim% = -1 then
if VERBOSELOG% then PL("Just got back from SelectNextStim%:\tMC stim chosen\n"); endif
case currStim% = -2 then
itSuccess% := 2;
return itSuccess%; 'Block Setup Cancelled
case currStim% < -2 then
PL("Just got back from SelectNextStim%:\tError Selecting Stim\n");
PL("in InitTrial()\t:something went wrong loading the stim");
itSuccess% := 0;
return itSuccess%;
endcase
'
if qMC% <> 1 then
fn$:=stimFileNames$[currStim%];
else
fn$:=MCstimFilenames$[MCtotnum%];
endif
currentStimLength:=UploadStim(fn$);
FilePathSet(dataPathRoot$);
if currentStimLength>0.0 then
currentStimName$:=Left$(fn$,InStr(fn$,".smrx")-1);
if qMC% <> 1 then
currentStimClass%:=stimClasses%[currStim%];
if doCorrectionTrial% = 1 and doFeedCorrectionTrials% <> 1 then
currentStimPcntReinf% := 0;
else
currentStimPcntReinf%:=stimPctReinf%[currStim%];
endif
currentStimPcntTo%:=stimPctTo%[currStim%];
else
currentStimClass%:=MCstimClasses%[MCtotnum%];
docase
case MCstimClasses%[MCtotnum%] = 1 then
currentStimPcntReinf%:= MCclassonePctReinf%;
currentStimPcntTo%:= MCclassonePctTo%;
case MCstimClasses%[MCtotnum%] = 2 then
currentStimPcntReinf%:= MCclasstwoPctReinf%;
currentStimPcntTo%:= MCclasstwoPctTo%;
case MCstimClasses%[MCtotnum%] = 3 then
currentStimPcntReinf%:= MCclassthreePctReinf%;
currentStimPcntTo%:= MCclassthreePctTo%;
endcase
endif
'
if qhBehavOnly% or qhRecordingAndBehavior% then
itiSeqSteps%:=ITI/seqPerMs*1000; 'number of seq ticks in ITI seconds
else
ITINO := rand(MINITINO,MAXITINO-MINITINO); 'pick a random intertrial interval from [MINITINO:MAXITINO]
itiSeqSteps%:=ITINO/seqPerMs*1000; 'number of seq ticks in ITI seconds
endif
'
SampleSeqVar(4,itiSeqSteps%);'send sequencer itiSeqSteps%
feedSeqSteps%:=FEED/seqPerMs*1000; 'should give number of seq ticks in FEED seconds
SampleSeqVar(11,feedSeqSteps%);'send sequencer feedSeqSteps%
timeoutSeqSteps%:=TIMEOUT/seqPerMs*1000; 'should give number of seq ticks in TIMEOUT seconds
SampleSeqVar(13,timeoutSeqSteps%);'send sequencer timeoutSeqSteps%
respwinSeqSteps%:=RESPWIN/seqPerMs*1000; 'should give number of seq ticks in RESPWIN seconds
SampleSeqVar(20,respwinSeqSteps%);'send sequencer respwinSeqSteps%
SampleSeqVar(29,feedRatioMax%);'send sequencer upper bound for variable ratio reinforcement
if VERBOSELOG% then PL("Sequencer Loaded with Operant Variables\n"); endif
'
'update sequencer with current trial's values
SampleSeqVar(22,GetEffectiveStimClass%(currentStimClass%)); 'set class in sequencer
setBrandVar(1.0-(currentStimPcntReinf%/100.0),25);'set percent 'no reinforcement' in sequencer 'function in chron_include.s2s that converts a percentage to a variable that BRAND can use
setBrandVar(1.0-(currentStimPcntTo%/100.0),26);'set percent 'no timeout' in sequencer 'function in chron_include.s2s that converts a percentage to a variable that BRAND can use
'
classFromSeq%:=SampleSeqVar(22); 'get class from sequencer
pctnofeedFromSeq:=SampleSeqVar(25); 'get percent reinforcement in sequencer
pctnotoFromSeq:=SampleSeqVar(26); 'get percent timeouts in sequencer
corrCountFromSeq%:=SampleSeqVar(27); 'get class from sequencer
corrThreshFromSeq%:=SampleSeqVar(28); 'get threshold from sequencer
if VERBOSELOG% then PL(Print$("classFromSeq%= %d\t pctnofeedFromSeq = %d\t pctnotoFromSeq = %d\t corrCountFromSeq = %d\t corrThreshFromSeq = %d",classFromSeq%,pctnofeedFromSeq,pctnotoFromSeq,corrCountFromSeq%,corrThreshFromSeq%)); endif
'
docase 'TODO: fix trialerrors so that they reset in the right places 'BH needs to be taken into account here
case qMC% = 1 then
if qhRecordingAndBehavior% or qhBehavOnly% then
PL(Print$("Stim %s loaded",currentStimName$));
ToolbarText(Print$("Random MC Stim Selection... Stim %s loaded, waiting for trial to be initiated. Using Protocol File: %s",currentStimName$,protFileName$));
else
if qhRecordingOnly% then
PL(Print$("Random MC Stim Selection... Stim %s loaded. Using Protocol File: %s",currentStimName$,protFileName$));
else
PL("What mode are you in??");