diff --git a/README.md b/README.md
index 1bf6e3a..2ebb046 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-# OpenScope visual loop:
-A temporary repository for the OpenScope visual loop project
+# OpenScope V2 species:
+A temporary repository for the OpenScope V2 species project
# Installation
@@ -25,56 +25,37 @@ A temporary repository for the OpenScope visual loop project
5. Download required video clips from movie_clips.zip and extract into the data directory.
-# Input files
-The software requires two sets of input files. There should be a set of text files present under `data/stimulus_orderings` that indicate the display order of video clips for different phases of the experiment.
-
-In addition, there should be a set of video clips (stored as raw .npy files).
-
These clips must be downloaded and extracted into the data folder from [full_movies.zip](https://weizmannacil-my.sharepoint.com/:u:/g/personal/daniel_deitch_weizmann_ac_il/EbetUfh76FtBtDkpqd-7gAEB43WxjSCKutxW8sJtvIfCiA?e=LPY5ND) and stored in the path `data/full_movies`.
-
-For debugging purposes please download shortened versions of the movie clips from [short_movies.zip](https://weizmannacil-my.sharepoint.com/:u:/g/personal/daniel_deitch_weizmann_ac_il/EZzpjTqcXG9Bn4Xe-u9pgXIBHzLbIWfmtd8xKI4lvwIwvQ?e=uLVxT0) and extracted into the data folder and store them in the path `data/short_movies`.
-
# Running the scripts
1. Activate the environment:
`conda activate allen_stimulus`
- 3. Run the stimulus_loop.py script (for group A input 0 and for group B input 1):
-
`python stimulus_loop.py 0`
+ 3. Run the stimulus_v2species_2p.py script for 2P stimuli:
+
`python stimulus_v2species_2p.py`
+
+ 4. Run the stimulus_v2species_2p.py script for ephys stimuli:
+
`python stimulus_v2species_ephys.py`
-# Debugging mode
-To run the script `stimulus_loop.py` in debugging mode, comment out line 50 and uncomment line 57.
-
This will change the path of the movie clips from their full length version (i.e., 30 sec) to their shortened version (5 sec) with helpful labels.
# Stimulus design
-The experiment consists of two phases in which different sets of 30 sec long natural movies will be presented:
- - Phase 1 consists of two natural movies (i.e., movie01 and movie02) and a constant gray screen (i.e., movie00).
- - Phase 2 consists of 50 natural movies (i.e., movie03-movie52) and a constant gray screen (i.e., movie00).
-
-Animals are assigned into two groups (A and B), each presented with the movies in different order.
-
In both groups, a total of 230 movies will be presented for a total time of 115 min:
- 1. For group A:
- - Phase 1:
- - 50 presentations of movie01 (25 min)
- - 10 presentations of movie00 (5 min)
- - 50 alternations between movie01 and movie02 (25 min)
- - 10 presentations of movie00 (5 min)
-
- - Phase 2:
- - 20 presentations of movie03 (10 min)
- - 10 presentations of movie00 (5 min)
- - 50 sequential presentations of movie03 to movie52 (25 min)
- - 10 presentations of movie00 (5 min)
- - 20 alternations between movie03 and movie52 (10 min)
-
- 2. For group B:
- - Phase 1:
- - 50 alternations between movie01 and movie02 (25 min)
- - 10 presentations of movie00 (5 min)
- - 50 presentations of movie01 (25 min)
- - 10 presentations of movie00 (5 min)
-
- - Phase 2:
- - 20 presentations of movie03 (10 min)
- - 10 presentations of movie00 (5 min)
- - 50 presentations of movie52 (25 min)
- - 10 presentations of movie00 (5 min)
- - 20 alternations between movie03 and movie52 (10 min)
+The experiment consists of both ephys (Neuropixels) and calcium imaging (2P imaging with Gcamp viral vectors) recordings, in separate mice. Neuropixels recordings consist of 4 simultaneous probes across V1, covering the extent of the visual field map. 2P imaging recordings consist of 12 FOVs, imaged 4 at a time, also across the span of the visual field of V1.
+
+The stimuli used for Neuropixels and 2P are similar, with the exception of full-field flashes, which rquire temporally precise responses and are therefor only used with Neuropixels recordings. Warping is applied to the monitor.
+
+Gabor Patches: Small drifting grating patches tiling the monitor, used to map receptive fields. Each patch is 20 degrees, with 10 degree overlap. TF and SF are fixed but orientation varies (0, 45,90).
+
+Drifting Gratings: Typical drifting gratings, with 5 TF (1.0, 2.0, 4.0, 8.0, 15.0) and 5 SF (0.02, 0.04, 0.08, 0.16, 0.32), and 4 orientations (0,45,90,135).
+
+Full-field flash: Full-field bright or dark flashes.
+
+Due to technical constraints, the duration of 2P recordings is more limited than Neuropixels recordings, so the number of repeated trials varies by stimulus modality.
+
+
+
+For stimulus_v2species_2p.py, these parameters are currently hard-coded:
+* nb_runs_ephys_rf = 10
+* nb_run_gratings = 15
+
+For stimulus_v2species_ephys.py, these parameters are currently hard-coded:
+* nb_runs_ephys_rf = 20
+* nb_run_gratings = 15
+* nb_run_flash = 150
diff --git a/cluster_hab/day1.py b/cluster_hab/day1.py
deleted file mode 100755
index 44e2ad9..0000000
--- a/cluster_hab/day1.py
+++ /dev/null
@@ -1,99 +0,0 @@
-"""
-Habituation Day 1.
-
-Total: 606 seconds = 10.1 min
-
-"""
-
-from psychopy import visual
-from camstim import Stimulus, SweepStim, MovieStim
-from camstim import Foraging
-from camstim import Window, Warp
-
-# Create display window
-window = visual.Window(fullscr=True,
- monitor='Gamma1.Luminance50',
- screen=0,
- #warp=Warp.Spherical,
- )
-
-############ Stimulus definitions #############################################
-# Natual Movie 2
-nm2_path = r"//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Movie_TOE2.npy"
-
-nm2 = MovieStim(movie_path=nm2_path,
- window=window,
- frame_length=2.0/60.0,
- size=(1920, 1080),
- start_time=0.0,
- stop_time=None,
- flip_v=True,
- runs=4,)
-
-# Drifting gratings
-dg = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'TF': ([1.0, 2.0], 1),
- 'SF': ([0.04], 2),
- 'Ori': (range(0, 270, 45), 3),
- },
- sweep_length=2.0,
- start_time=0.0,
- blank_length=1.0,
- blank_sweeps=5,
- runs=5,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Locally Sparse Noise
-lsn_path = "//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/sparse_noise_no_boundary_16x28_scaled.npy"
-
-lsn = MovieStim(movie_path=lsn_path,
- window=window,
- frame_length=0.5,
- size=(1260, 720),
- start_time=0.0,
- stop_time=None,
- runs=1,)
-
-# Set display sequences
-nm2_ds = [(60, 180)]
-dg_ds = [(225, 441)]
-lsn_ds = [(486, 606)]
-
-nm2.set_display_sequence(nm2_ds)
-dg.set_display_sequence(dg_ds)
-lsn.set_display_sequence(lsn_ds)
-
-############ SweepStim Setup ##################################################
-# kwargs
-params = {
-}
-
-# create SweepStim instance
-ss = SweepStim(window,
- stimuli=[nm2, dg, lsn],
- pre_blank_sec=0,
- post_blank_sec=0,
- params=params,
- )
-
-# add in foraging so we can track wheel, potentially give rewards, etc
-f = Foraging(window=window,
- auto_update=False,
- params=params,
- nidaq_tasks={'digital_input': ss.di,
- 'digital_output': ss.do,}) #share di and do with SS
-ss.add_item(f, "foraging")
-
-# run it
-ss.run()
\ No newline at end of file
diff --git a/cluster_hab/day2.py b/cluster_hab/day2.py
deleted file mode 100755
index b66cf86..0000000
--- a/cluster_hab/day2.py
+++ /dev/null
@@ -1,128 +0,0 @@
-"""
-Habituation Day 2.
-
-Total: 1175 seconds = 19.6 min
-
-"""
-import os
-from psychopy import visual
-from camstim import Stimulus, SweepStim, MovieStim, NaturalScenes
-from camstim import Foraging
-from camstim import Window, Warp
-
-# Create display window
-window = visual.Window(fullscr=True,
- monitor='Gamma1.Luminance50',
- screen=0,
- #warp=Warp.Spherical,
- )
-
-############ Stimulus definitions #############################################
-
-# Locally Sparse Noise
-lsn8_path = r"//allen/aibs/mat/michaelbu/Locally_Sparse_Noise_Trimmed/short/lsn_mat_8x14_short.npy"
-
-lsn8 = MovieStim(movie_path=lsn8_path,
- window=window,
- frame_length=0.25,
- size=(1260, 720),
- start_time=0.0,
- stop_time=None,
- runs=1,)
-
-# Natural Scenes
-scenes_folder = "//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Natural Images"
-image_files = [os.path.join(scenes_folder, f) for f in os.listdir(scenes_folder) if \
- len(f) > 4 and f[-4:] in ['.jpg','.png','.tif','tiff']]
-
-ns = NaturalScenes(image_path_list=image_files,
- window=window,
- sweep_length=0.50,
- start_time=0.0,
- stop_time=None,
- blank_length=0.0,
- blank_sweeps=10,
- runs=3,
- shuffle=True,)
-
-# Drifting gratings
-dg = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'TF': ([2.0, 4.0], 1),
- 'SF': ([0.04], 2),
- 'Ori': (range(0, 360, 45), 3),
- },
- sweep_length=2.0,
- start_time=0.0,
- blank_length=1.0,
- blank_sweeps=8,
- runs=5,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Static Gratings
-sg = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'SF': ([0.02, 0.08, 0.32], 1),
- 'Ori': (range(0, 180, 30), 2),
- },
- sweep_length=0.5,
- start_time=0.0,
- blank_length=0.0,
- blank_sweeps=10,
- runs=5,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Set display sequences
-lsn8_ds = [(90, 390)]
-ns_ds = [(480, 675)]
-dg_ds = [(765, 1035)]
-sg_ds = [(1125, 1175)]
-
-lsn8.set_display_sequence(lsn8_ds)
-ns.set_display_sequence(ns_ds)
-dg.set_display_sequence(dg_ds)
-sg.set_display_sequence(sg_ds)
-
-############ SweepStim Setup ##################################################
-# kwargs
-params = {
-}
-
-# create SweepStim instance
-ss = SweepStim(window,
- stimuli=[lsn8, ns, dg, sg],
- pre_blank_sec=0,
- post_blank_sec=0,
- params=params,
- )
-
-# add in foraging so we can track wheel, potentially give rewards, etc
-f = Foraging(window=window,
- auto_update=False,
- params=params,
- nidaq_tasks={'digital_input': ss.di,
- 'digital_output': ss.do,}) #share di and do with SS
-ss.add_item(f, "foraging")
-
-# run it
-ss.run()
diff --git a/cluster_hab/day3.py b/cluster_hab/day3.py
deleted file mode 100755
index eaf0567..0000000
--- a/cluster_hab/day3.py
+++ /dev/null
@@ -1,153 +0,0 @@
-"""
-Habituation Day 3.
-
-Total: 1822 seconds = 30.4 min
-
-"""
-import os
-from psychopy import visual
-from camstim import Stimulus, SweepStim, MovieStim, NaturalScenes
-from camstim import Foraging
-from camstim import Window, Warp
-
-# Create display window
-window = visual.Window(fullscr=True,
- monitor='Gamma1.Luminance50',
- screen=0,
- #warp=Warp.Spherical,
- )
-
-############ Stimulus definitions #############################################
-# Natual Movie 1
-nm2_path = r"//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Movie_TOE2.npy"
-
-nm2 = MovieStim(movie_path=nm2_path,
- window=window,
- frame_length=2.0/60.0,
- size=(1920, 1080),
- start_time=0.0,
- stop_time=None,
- flip_v=True,
- runs=5,)
-
-# Natural Scenes
-scenes_folder = "//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Natural Images"
-image_files = [os.path.join(scenes_folder, f) for f in os.listdir(scenes_folder) if \
- len(f) > 4 and f[-4:] in ['.jpg','.png','.tif','tiff']]
-
-ns = NaturalScenes(image_path_list=image_files,
- window=window,
- sweep_length=0.50,
- start_time=0.0,
- stop_time=None,
- blank_length=0.0,
- blank_sweeps=20,
- runs=5,
- shuffle=True,)
-
-# Drifting gratings
-dg = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'TF': ([1.0, 2.0, 4.0, 8.0], 1),
- 'SF': ([0.04], 2),
- 'Ori': (range(0, 360, 90), 3),
- },
- sweep_length=2.0,
- start_time=0.0,
- blank_length=1.0,
- blank_sweeps=15,
- runs=7,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Locally Sparse Noise
-lsn8_path = r"//allen/aibs/mat/michaelbu/Locally_Sparse_Noise_Trimmed/short/lsn_mat_8x14_short.npy"
-
-lsn8 = MovieStim(movie_path=lsn8_path,
- window=window,
- frame_length=0.25,
- size=(1260, 720),
- start_time=0.0,
- stop_time=None,
- runs=1,)
-
-# Static Gratings
-sg = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'SF': ([0.02, 0.04, 0.08, 0.16, 0.32], 1),
- 'Ori': (range(0, 180, 30), 2),
- },
- sweep_length=0.5,
- start_time=0.0,
- blank_length=0.0,
- blank_sweeps=20,
- runs=7,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Locally Sparse Noise
-lsn4_path = "//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/sparse_noise_no_boundary_16x28_scaled.npy"
-
-lsn4 = MovieStim(movie_path=lsn4_path,
- window=window,
- frame_length=0.25,
- size=(1260, 720),
- start_time=0.0,
- stop_time=None,
- runs=1,)
-
-# Set display sequences
-nm2_ds = [(90, 240)]
-ns_ds = [(330, 640)]
-dg_ds = [(730, 1087)]
-lsn8_ds = [(1177, 1417)]
-sg_ds = [(1407, 1512)]
-lsn4_ds = [(1602, 1822)]
-
-nm2.set_display_sequence(nm2_ds)
-ns.set_display_sequence(ns_ds)
-dg.set_display_sequence(dg_ds)
-lsn8.set_display_sequence(lsn8_ds)
-sg.set_display_sequence(sg_ds)
-lsn4.set_display_sequence(lsn4_ds)
-
-############ SweepStim Setup ##################################################
-# kwargs
-params = {}
-
-# create SweepStim instance
-ss = SweepStim(window,
- stimuli=[nm2, ns, dg, lsn8, sg, lsn4],
- pre_blank_sec=0,
- post_blank_sec=0,
- params=params,
- )
-
-# add in foraging so we can track wheel, potentially give rewards, etc
-f = Foraging(window=window,
- auto_update=False,
- params=params,
- nidaq_tasks={'digital_input': ss.di,
- 'digital_output': ss.do,}) #share di and do with SS
-ss.add_item(f, "foraging")
-
-# run it
-ss.run()
diff --git a/cluster_hab/day4.py b/cluster_hab/day4.py
deleted file mode 100755
index a41bfb4..0000000
--- a/cluster_hab/day4.py
+++ /dev/null
@@ -1,184 +0,0 @@
-"""
-Habituation Day 4.
-Short bursts of fast presentations
-
-Total: 2386 seconds = 39.8 minutes
-
-"""
-import os
-from psychopy import visual
-from camstim import Stimulus, SweepStim, MovieStim, NaturalScenes
-from camstim import Foraging
-from camstim import Window, Warp
-
-# Create display window
-window = visual.Window(fullscr=True,
- monitor='Gamma1.Luminance50',
- screen=0,
- #warp=Warp.Spherical,
- )
-
-############ Stimulus definitions #############################################
-# 1 Hz flash for 10 sec
-leak0 = Stimulus(visual.GratingStim(window, tex=None, color=0,
- size=(1920,1200), units="pix"),
- sweep_params={"Color":([-1,1], 0)},
- sweep_length=0.5,
- start_time=0.0,
- runs=10,)
-# 0.5 Hz flash for 10 sec
-leak1 = Stimulus(visual.GratingStim(window, tex=None, color=0,
- size=(1920,1200), units="pix"),
- sweep_params={"Color":([-1,1], 0)},
- sweep_length=0.25,
- start_time=10.0,
- runs=20,)
-
-# Natual Movie 1
-# nm1_path = r"//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Movie_TOE1.npy"
-#
-# nm1 = MovieStim(movie_path=nm1_path,
-# window=window,
-# frame_length=2.0/60.0,
-# size=(1920, 1080),
-# start_time=0.0,
-# stop_time=None,
-# flip_v=True,
-# runs=4,)
-
-# Natual Movie 2
-nm2_path = r"//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Movie_TOE2.npy"
-
-nm2 = MovieStim(movie_path=nm2_path,
- window=window,
- frame_length=2.0/60.0,
- size=(1920, 1080),
- start_time=0.0,
- stop_time=None,
- flip_v=True,
- runs=4,)
-
-# Natural Scenes
-scenes_folder = "//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Natural Images"
-image_files = [os.path.join(scenes_folder, f) for f in os.listdir(scenes_folder) if \
- len(f) > 4 and f[-4:] in ['.jpg','.png','.tif','tiff']]
-
-ns = NaturalScenes(image_path_list=image_files,
- window=window,
- sweep_length=0.25,
- start_time=0.0,
- stop_time=None,
- blank_length=0.0,
- blank_sweeps=50,
- runs=5,
- shuffle=True,)
-
-# Drifting gratings
-dg = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'TF': ([1.0, 2.0, 8.0, 15.0], 1),
- 'SF': ([0.04], 2),
- 'Ori': (range(0, 360, 45), 3),
- },
- sweep_length=2.0,
- start_time=0.0,
- blank_length=1.0,
- blank_sweeps=15,
- runs=2,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Locally Sparse Noise
-lsn8_path = r"//allen/aibs/mat/michaelbu/Locally_Sparse_Noise_Trimmed/short/lsn_mat_8x14_short.npy"
-
-lsn8 = MovieStim(movie_path=lsn8_path,
- window=window,
- frame_length=0.25,
- size=(1260, 720),
- start_time=0.0,
- stop_time=None,
- runs=1,)
-
-# Static Gratings
-sg = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'SF': ([0.02, 0.04, 0.08, 0.16, 0.32], 1),
- 'Ori': (range(0, 180, 30), 2),
- 'Phase': ([0, 0.5], 3),
- },
- sweep_length=0.25,
- start_time=0.0,
- blank_length=0.0,
- blank_sweeps=25,
- runs=7,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Locally Sparse Noise
-lsn4_path = "//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/sparse_noise_no_boundary_16x28_scaled.npy"
-
-lsn4 = MovieStim(movie_path=lsn4_path,
- window=window,
- frame_length=0.25,
- size=(1260, 720),
- start_time=0.0,
- stop_time=None,
- runs=1,)
-
-# Set display sequences
-# nm1_ds = [(2197, 2317)]
-nm2_ds = [(499, 619),(2197, 2317)]
-ns_ds = [(679, 829), (1453, 1603)]
-dg_ds = [(1159, 1363), (1903, 2107)]
-lsn8_ds = [(919, 1099)]
-sg_ds = [(300, 409), (2377, 2486)]
-lsn4_ds = [(90, 210), (1693, 1813)]
-
-# nm1.set_display_sequence(nm1_ds)
-nm2.set_display_sequence(nm2_ds)
-ns.set_display_sequence(ns_ds)
-dg.set_display_sequence(dg_ds)
-lsn8.set_display_sequence(lsn8_ds)
-sg.set_display_sequence(sg_ds)
-lsn4.set_display_sequence(lsn4_ds)
-
-############ SweepStim Setup ##################################################
-# kwargs
-params = {}
-
-# create SweepStim instance
-ss = SweepStim(window,
- stimuli=[leak0, leak1, nm2, ns, dg, lsn8, sg, lsn4],
- pre_blank_sec=0,
- post_blank_sec=0,
- params=params,
- )
-
-# add in foraging so we can track wheel, potentially give rewards, etc
-f = Foraging(window=window,
- auto_update=False,
- params=params,
- nidaq_tasks={'digital_input': ss.di,
- 'digital_output': ss.do,}) #share di and do with SS
-ss.add_item(f, "foraging")
-
-# run it
-ss.run()
diff --git a/cluster_hab/day5.py b/cluster_hab/day5.py
deleted file mode 100755
index ee16b28..0000000
--- a/cluster_hab/day5.py
+++ /dev/null
@@ -1,210 +0,0 @@
-"""
-Habituation Day 5.
-Short bursts of fast presentations
-
-Total: 3003 seconds = 50.0 minutes
-
-"""
-import os
-from psychopy import visual
-from camstim import Stimulus, SweepStim, MovieStim, NaturalScenes
-from camstim import Foraging
-from camstim import Window, Warp
-
-# Create display window
-window = visual.Window(fullscr=True,
- monitor='Gamma1.Luminance50',
- screen=0,
- #warp=Warp.Spherical,
- )
-
-############ Stimulus definitions #############################################
-# 1 Hz flash for 10 sec
-leak0 = Stimulus(visual.GratingStim(window, tex=None, color=0,
- size=(1920,1200), units="pix"),
- sweep_params={"Color":([-1,1], 0)},
- sweep_length=0.5,
- start_time=0.0,
- runs=10,)
-# 0.5 Hz flash for 10 sec
-leak1 = Stimulus(visual.GratingStim(window, tex=None, color=0,
- size=(1920,1200), units="pix"),
- sweep_params={"Color":([-1,1], 0)},
- sweep_length=0.25,
- start_time=10.0,
- runs=20,)
-
-# Natual Movie 1
-# nm1_path = r"//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Movie_TOE1.npy"
-#
-# nm1 = MovieStim(movie_path=nm1_path,
-# window=window,
-# frame_length=2.0/60.0,
-# size=(1920, 1080),
-# start_time=0.0,
-# stop_time=None,
-# flip_v=True,
-# runs=5,)
-
-# Natual Movie 2
-nm2_path = r"//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Movie_TOE2.npy"
-
-nm2 = MovieStim(movie_path=nm2_path,
- window=window,
- frame_length=2.0/60.0,
- size=(1920, 1080),
- start_time=0.0,
- stop_time=None,
- flip_v=True,
- runs=5,)
-
-# Natural Scenes
-scenes_folder = "//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/Natural Images"
-image_files = [os.path.join(scenes_folder, f) for f in os.listdir(scenes_folder) if \
- len(f) > 4 and f[-4:] in ['.jpg','.png','.tif','tiff']]
-
-ns = NaturalScenes(image_path_list=image_files,
- window=window,
- sweep_length=0.25,
- start_time=0.0,
- stop_time=None,
- blank_length=0.0,
- blank_sweeps=80,
- runs=10,
- shuffle=True,)
-
-# Drifting gratings type 1
-dg1 = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'TF': ([1.0, 2.0, 4.0, 8.0, 15.0], 1),
- 'SF': ([0.04], 2),
- 'Ori': (range(0, 360, 45), 3),
- },
- sweep_length=2.0,
- start_time=0.0,
- blank_length=1.0,
- blank_sweeps=20,
- runs=4,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Drifting gratings type 2
-dg2 = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'TF': ([1.0, 4.0, 15.0], 1),
- 'SF': ([0.04], 2),
- 'Ori': (range(45, 360, 90), 3),
- },
- sweep_length=2.0,
- start_time=0.0,
- blank_length=1.0,
- blank_sweeps=20,
- runs=5,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Locally Sparse Noise
-lsn8_path = r"//allen/aibs/mat/michaelbu/Locally_Sparse_Noise_Trimmed/short/lsn_mat_8x14_short.npy"
-
-lsn8 = MovieStim(movie_path=lsn8_path,
- window=window,
- frame_length=0.25,
- size=(1260, 720),
- start_time=0.0,
- stop_time=None,
- runs=1,)
-
-# Static Gratings
-sg = Stimulus(visual.GratingStim(window,
- pos=(0, 0),
- units='deg',
- size=(250, 250),
- mask="None",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Contrast': ([0.8], 0),
- 'SF': ([0.02, 0.04, 0.08, 0.16, 0.32], 1),
- 'Ori': (range(0, 180, 30), 2),
- 'Phase': ([0, 0.25, 0.5], 3),
- },
- sweep_length=0.25,
- start_time=0.0,
- blank_length=0.0,
- blank_sweeps=25,
- runs=19,
- shuffle=True,
- save_sweep_table=True,
- )
-
-# Locally Sparse Noise
-lsn4_path = "//allen/programs/braintv/workgroups/neuralcoding/Saskia/Visual Stimuli 151207/sparse_noise_no_boundary_16x28_scaled.npy"
-
-lsn4 = MovieStim(movie_path=lsn4_path,
- window=window,
- frame_length=0.25,
- size=(1260, 720),
- start_time=0.0,
- stop_time=None,
- runs=1,)
-
-# Set display sequences
-lsn8_ds = [(90,330)]
-sg_ds = [(390,671), (2534,2697)]
-lsn4_ds = [(731,1131)]
-nm2_ds = [(1191,1341), (2324,2474)]
-dg1_ds = [(1401, 1905)]
-ns_ds = [(1965,2264)]
-nm1_ds = [(2324, 2474)]
-dg2_ds = [(2757,2946)]
-
-# nm1.set_display_sequence(nm1_ds)
-nm2.set_display_sequence(nm2_ds)
-ns.set_display_sequence(ns_ds)
-dg1.set_display_sequence(dg1_ds)
-dg2.set_display_sequence(dg2_ds)
-lsn8.set_display_sequence(lsn8_ds)
-sg.set_display_sequence(sg_ds)
-lsn4.set_display_sequence(lsn4_ds)
-
-############ SweepStim Setup ##################################################
-# kwargs
-params = {}
-
-# create SweepStim instance
-ss = SweepStim(window,
- stimuli=[leak0, leak1, nm2, ns, dg1, dg2, lsn8, sg, lsn4],
- pre_blank_sec=0,
- post_blank_sec=0,
- params=params,
- )
-
-# add in foraging so we can track wheel, potentially give rewards, etc
-f = Foraging(window=window,
- auto_update=False,
- params=params,
- nidaq_tasks={'digital_input': ss.di,
- 'digital_output': ss.do,}) #share di and do with SS
-ss.add_item(f, "foraging")
-
-# run it
-ss.run()
diff --git a/data/stimulus_orderings/movie_order_groupA.txt b/data/stimulus_orderings/movie_order_groupA.txt
deleted file mode 100644
index c9ab687..0000000
--- a/data/stimulus_orderings/movie_order_groupA.txt
+++ /dev/null
@@ -1,230 +0,0 @@
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-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
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
diff --git a/data/stimulus_orderings/movie_order_groupB.txt b/data/stimulus_orderings/movie_order_groupB.txt
deleted file mode 100644
index b9eb447..0000000
--- a/data/stimulus_orderings/movie_order_groupB.txt
+++ /dev/null
@@ -1,230 +0,0 @@
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
-52
-3
diff --git a/data/stimulus_orderings/movie_order_groupTEST.txt b/data/stimulus_orderings/movie_order_groupTEST.txt
deleted file mode 100644
index dd76fe4..0000000
--- a/data/stimulus_orderings/movie_order_groupTEST.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-10
-20
-30
-40
-50
diff --git a/data/stimulus_orderings/rig_hab_day1_groupA.txt b/data/stimulus_orderings/rig_hab_day1_groupA.txt
deleted file mode 100644
index 6e09974..0000000
--- a/data/stimulus_orderings/rig_hab_day1_groupA.txt
+++ /dev/null
@@ -1,120 +0,0 @@
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
diff --git a/data/stimulus_orderings/rig_hab_day1_groupB.txt b/data/stimulus_orderings/rig_hab_day1_groupB.txt
deleted file mode 100644
index ce58c30..0000000
--- a/data/stimulus_orderings/rig_hab_day1_groupB.txt
+++ /dev/null
@@ -1,120 +0,0 @@
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
diff --git a/data/stimulus_orderings/rig_hab_day3_groupA.txt b/data/stimulus_orderings/rig_hab_day3_groupA.txt
deleted file mode 100644
index 7ee9a6e..0000000
--- a/data/stimulus_orderings/rig_hab_day3_groupA.txt
+++ /dev/null
@@ -1,180 +0,0 @@
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
diff --git a/data/stimulus_orderings/rig_hab_day3_groupB.txt b/data/stimulus_orderings/rig_hab_day3_groupB.txt
deleted file mode 100644
index b86e11c..0000000
--- a/data/stimulus_orderings/rig_hab_day3_groupB.txt
+++ /dev/null
@@ -1,180 +0,0 @@
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
diff --git a/data/stimulus_orderings/rig_hab_day5_groupA.txt b/data/stimulus_orderings/rig_hab_day5_groupA.txt
deleted file mode 100644
index 8afb3d6..0000000
--- a/data/stimulus_orderings/rig_hab_day5_groupA.txt
+++ /dev/null
@@ -1,240 +0,0 @@
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
diff --git a/data/stimulus_orderings/rig_hab_day5_groupB.txt b/data/stimulus_orderings/rig_hab_day5_groupB.txt
deleted file mode 100644
index 13b2adc..0000000
--- a/data/stimulus_orderings/rig_hab_day5_groupB.txt
+++ /dev/null
@@ -1,240 +0,0 @@
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-1
-2
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
-3
diff --git a/images/stim_overview.png b/images/stim_overview.png
new file mode 100644
index 0000000..997a5f5
Binary files /dev/null and b/images/stim_overview.png differ
diff --git a/stimulus_loop.py b/stimulus_loop.py
deleted file mode 100644
index 8e9997c..0000000
--- a/stimulus_loop.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# -*- coding: utf-8 -*-
-# Stimulus design
-#
-# The experiment consists of two phases in which different sets of 30 sec long natural movies will be presented:
-# - Phase 1 consists of two natural movies (i.e., movie01 and movie02) and a constant gray screen (i.e., movie00).
-# - Phase 2 consists of 50 natural movies (i.e., movie03-movie52) and a constant gray screen (i.e., movie00).
-#
-# Animals are assigned into two groups (A and B), each presented with the movies in different order.
-# In both groups, a total of 230 movies will be presented for a total time of 115 min:
-# 1. For group A:
-# - Phase 1:
-# - 50 presentations of movie01 (25 min)
-# - 10 presentations of movie00 (5 min)
-# - 50 alternations between movie01 and movie02 (25 min)
-# - 10 presentations of movie00 (5 min)
-#
-# - Phase 2:
-# - 20 presentations of movie03 (10 min)
-# - 10 presentations of movie00 (5 min)
-# - 50 sequential presentations of movie03 to movie52 (25 min)
-# - 10 presentations of movie00 (5 min)
-# - 20 alternations between movie03 and movie52 (10 min)
-#
-# 2. For group B:
-# - Phase 1:
-# - 50 alternations between movie01 and movie02 (25 min)
-# - 10 presentations of movie00 (5 min)
-# - 50 presentations of movie01 (25 min)
-# - 10 presentations of movie00 (5 min)
-#
-# - Phase 2:
-# - 20 presentations of movie03 (10 min)
-# - 10 presentations of movie00 (5 min)
-# - 50 presentations of movie52 (25 min)
-# - 10 presentations of movie00 (5 min)
-# - 20 alternations between movie03 and movie52 (10 min)
-import psychopy.visual
-import camstim
-import argparse
-import numpy as np
-from psychopy import monitors
-from camstim import SweepStim, Foraging, Window, Warp, MovieStim
-import glob
-import logging
-import yaml
-import os
-
-
-def make_movie_stimulus(movie_paths, order, window):
- """Generate a Stimulus that plays a series of movie clips in a specified order."""
-
- # Convert the order into a list of display sequence tuples. There should be one display sequence list per movie
- # clip. Each display sequence list contains a set of tuples of the form (start_second, stop_second). Theses tuples
- # define the start and stop time for when to play the clip and are determined by the order vector
- movie_length = 30 # in seconds
- frame_rate = 30.0
-
- all_starts = np.arange(0, movie_length * len(order), movie_length).astype(float)
- display_sequences = []
- for i in np.unique(order):
- display_sequences.append(list(zip(all_starts[order == i], all_starts[order == i] + movie_length)))
-
- # Load each movie clip into its own MovieStim object. The display sequence will be set later so the clips play
- # in the correct order.
- stims = []
- unique_movies = np.unique(order)
- num_movies = len(unique_movies)
- for i in range(num_movies):
- current_movie_id = unique_movies[i]
- # If the order index is less than the number of movie clips, load the movie clip.
- if i < len(movie_paths):
-
- # The movie clips should be 30 seconds long and should be played at 30 fps.
- s = MovieStim(movie_path=movie_paths[current_movie_id],
- window=window,
- frame_length=1.0 / frame_rate,
- size=(1920, 1080),
- start_time=0.0,
- stop_time=None,
- flip_v=True, runs=len(display_sequences[i]))
- s.set_display_sequence(display_sequences[i])
-
- else:
- raise ValueError("Order index is greater than the number of movie clips.")
-
- stims.append(s)
-
- last_time = all_starts[-1] + movie_length
-
- return stims, last_time
-
-def create_receptive_field_mapping(number_runs = 15):
- x = np.arange(-40,45,10)
- y = np.arange(-40,45,10)
- position = []
- for i in x:
- for j in y:
- position.append([i,j])
-
- stimulus = Stimulus(visual.GratingStim(window,
- units='deg',
- size=20,
- mask="circle",
- texRes=256,
- sf=0.1,
- ),
- sweep_params={
- 'Pos':(position, 0),
- 'Contrast': ([0.8], 4),
- 'TF': ([4.0], 1),
- 'SF': ([0.08], 2),
- 'Ori': ([0,45,90], 3),
- },
- sweep_length=0.25,
- start_time=0.0,
- blank_length=0.0,
- blank_sweeps=0,
- runs=number_runs,
- shuffle=True,
- save_sweep_table=True,
- )
- stimulus.stim_path = r"C:\\not_a_stim_script\\create_receptive_field_mapping.stim"
-
- return stimulus
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser("mtrain")
- parser.add_argument("json_path", nargs="?", type=str, default="")
-
- args, _ = parser.parse_known_args() # <- this ensures that we ignore other arguments that might be needed by camstim
-
- # print args
- if args.json_path == "":
- logging.warning("No json path provided, using default parameters. THIS IS NOT THE EXPECTED BEHAVIOR FOR PRODUCTION RUNS")
- json_params = {}
- else:
- with open(args.json_path, 'r') as f:
- # we use the yaml package here because the json package loads as unicode, which prevents using the keys as parameters later
- json_params = yaml.load(f)
- logging.info("Loaded json parameters from mtrain")
- # end of mtrain part
-
- data_folder = json_params.get('data_folder', os.path.abspath("data"))
-
- # An integer representing the experiment group. Defaults to test group (value of 2).
- group = json_params.get('stimulus_orderings', 'movie_order_groupTEST')
-
- opto_disabled = json_params.get('disable_opto', True)
- dev_mode = json_params.get("dev_mode", True)
-
- # Paths to the movie clip files to load.
- movie_clip_files = glob.glob(os.path.join(data_folder, 'full_movies','*.npy'))
-
- # Load the movie clip order for each experimental group as provided by the Ziv lab:
- order = (np.loadtxt(os.path.join(data_folder, 'stimulus_orderings', group+".txt")).astype(int))
-
- dist = 15.0
- wid = 52.0
-
- # create a monitor
- if dev_mode:
- monitor = monitors.Monitor('testMonitor', distance=dist, width=wid)
- else:
- monitor = "Gamma1.Luminance50"
-
- # Create display window
- window = Window(fullscr=True, # Will return an error due to default size. Ignore.
- monitor=monitor, # Will be set to a gamma calibrated profile by MPE
- screen=0,
- warp=Warp.Spherical
- )
-
- stims, last_time = make_movie_stimulus(movie_clip_files, order, window)
-
- # We create the receptive field mapping stimulus
- gabors_rf_20 = create_receptive_field_mapping(8)
- gabors_rf_20_ds = [(last_time, last_time+640)]
- gabors_rf_20.set_display_sequence(gabors_rf_20_ds)
- stims.append(gabors_rf_20)
-
- ss = SweepStim(window,
- stimuli=stims,
- # pre_blank_sec=1,
- # post_blank_sec=1,
- params={},
- )
-
- # add in foraging so we can track wheel, potentially give rewards, etc
- f = Foraging(window = window,
- auto_update = False,
- params= {}
- )
-
- ss.add_item(f, "foraging")
-
- ss.run()
diff --git a/stimulus_v2species_2p.py b/stimulus_v2species_2p.py
new file mode 100644
index 0000000..4fc19ad
--- /dev/null
+++ b/stimulus_v2species_2p.py
@@ -0,0 +1,232 @@
+# -*- coding: utf-8 -*-
+# Stimulus design
+#
+# Please write here any comments or notes about the stimulus design
+# that are relevant for the experiment.
+import psychopy.visual
+import camstim
+import argparse
+import numpy as np
+from psychopy import monitors, visual
+from camstim import SweepStim, Foraging, Window, Warp
+import glob
+import logging
+import yaml
+import os
+from camstim.sweepstim import Stimulus
+from itertools import product
+
+## This is the RF mapping stim
+def create_receptive_field_mapping(window, number_runs = 5):
+ x = np.arange(-40,45,10)
+ y = np.arange(-40,45,10)
+ position = []
+ for i in x:
+ for j in y:
+ position.append([i,j])
+
+ stimulus = Stimulus(visual.GratingStim(window,
+ units='deg',
+ size=20,
+ mask="circle",
+ texRes=256,
+ sf=0.1,
+ ),
+ sweep_params={
+ 'Pos':(position, 0),
+ 'Contrast': ([0.8], 4),
+ 'TF': ([4.0], 1),
+ 'SF': ([0.08], 2),
+ 'Ori': ([0,45,90, ], 3),
+ },
+ sweep_length=0.25,
+ start_time=0.0,
+ blank_length=0.0,
+ blank_sweeps=0,
+ runs=number_runs,
+ shuffle=True,
+ save_sweep_table=True,
+ )
+ stimulus.stim_path = r"C:\\not_a_stim_script\\receptive_field_block.stim"
+
+ return stimulus
+
+## This is drifting gratings
+def create_gratingStim(window, number_runs = 5):
+ stimulus_grating = Stimulus(visual.GratingStim(
+ window,
+ pos=(0, 0),
+ units='deg',
+ size=(250, 250),
+ mask="None",
+ texRes=256,
+ sf=0.1,
+ ),
+ sweep_params={
+ 'Contrast': ([0.8], 0),
+ 'TF': ([1.0, 2.0, 4.0, 8.0, 15.0], 1),
+ 'SF': ([0.02, 0.04, 0.08, 0.16, 0.32], 2),
+ 'Ori': (range(0, 180, 45), 3),
+ },
+ sweep_length=1,
+ start_time=0.0,
+ blank_length=1.25,
+ blank_sweeps=0,
+ runs=number_runs,
+ shuffle=True,
+ save_sweep_table=True,
+ )
+ stimulus_grating.stim_path = r"C:\\not_a_stim_script\\drifting_gratings_field_block.stim"
+
+ return stimulus_grating
+
+#this gets total conditions for stimuli defined above
+def count_total_conditions(stimulus):
+ """
+ Given a camstim Stimulus object, return the number of unique parameter combinations.
+ """
+ sweep_params = stimulus.sweep_params
+ param_values = []
+
+ for key, (values, _) in sweep_params.items():
+ # Ensure range is converted to list
+ if type(values).__name__ == 'range':
+ values = list(values)
+ param_values.append(values)
+
+ total_conditions = len(list(product(*param_values)))
+ return total_conditions
+
+
+#this gets trial duration for stimuli defined above
+def get_trial_duration_seconds(stimulus):
+ """
+ Returns the duration of one full trial (sweep + blank) in seconds.
+ """
+ sweep_length = getattr(stimulus, 'sweep_length', 0)
+ blank_length = getattr(stimulus, 'blank_length', 0)
+ return sweep_length + blank_length
+
+############################################################################## main code block
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("mtrain")
+ parser.add_argument("json_path", nargs="?", type=str, default="")
+
+ args, _ = parser.parse_known_args() # <- this ensures that we ignore other arguments that might be needed by camstim
+
+ # print args
+ if args.json_path == "":
+ logging.warning("No json path provided, using default parameters. THIS IS NOT THE EXPECTED BEHAVIOR FOR PRODUCTION RUNS")
+ json_params = {}
+ else:
+ with open(args.json_path, 'r') as f:
+ # we use the yaml package here because the json package loads as unicode, which prevents using the keys as parameters later
+ json_params = yaml.load(f)
+ logging.info("Loaded json parameters from mtrain")
+ # end of mtrain part
+
+ # An integer representing the experiment group. Defaults to test group (value of 2).
+ dev_mode = json_params.get('dev_mode', True)
+ num_reps = json_params.get('num_reps', 1)
+ print("num_reps is: ",num_reps)
+ inter_block_interval = json_params.get('inter_block_interval', 10)
+
+ dist = 15.0
+ wid = 52.0
+
+ if dev_mode:
+ my_monitor = monitors.Monitor(name='Test')
+ my_monitor.setSizePix((800,600))
+ my_monitor.setWidth(wid)
+ my_monitor.setDistance(dist)
+ my_monitor.saveMon()
+ win = Window(size=[800,600], # [1024,768],
+ fullscr=False,
+ screen=0,
+ monitor= my_monitor,
+ warp=Warp.Spherical,
+ color= "gray",
+ units = 'deg'
+ )
+ else:
+ win = Window(
+ fullscr=True,
+ screen=0,
+ monitor='Gamma1.Luminance50',
+ warp=Warp.Spherical,
+ )
+
+
+ #define number of trials for each stim type
+ nb_runs_ephys_rf = 10
+ nb_run_gratings = 15
+
+
+ ephys_rf_stim = create_receptive_field_mapping(win, number_runs=nb_runs_ephys_rf)
+ drifting_grating_stim = create_gratingStim(win, number_runs=nb_run_gratings)
+
+ print(
+ "ephys_rf, total conditions: ", count_total_conditions(ephys_rf_stim),
+ ", and trial duration: ", get_trial_duration_seconds(ephys_rf_stim))
+
+ print(
+ "gratings, total conditions: ", count_total_conditions(drifting_grating_stim),
+ ", and trial duration: ", get_trial_duration_seconds(drifting_grating_stim))
+
+ All_stim = []
+
+ # Add RF code from ephys
+ current_time = 0
+ if num_reps == 1:
+ length_rf_seconds = 10 #for testing purposes
+ else:
+ length_rf_seconds = (
+ count_total_conditions(ephys_rf_stim)
+ *get_trial_duration_seconds(ephys_rf_stim)
+ *nb_runs_ephys_rf
+ )
+
+ ephys_rf_stim.set_display_sequence([(current_time, current_time+length_rf_seconds)])
+
+ All_stim.append(ephys_rf_stim)
+ print("length_rf_minutes: ",length_rf_seconds/60)
+
+ # drifting_grating_stim
+ if num_reps == 1:
+ length_drifting_grating_seconds = 10
+ else:
+ length_drifting_grating_seconds = (
+ count_total_conditions(drifting_grating_stim)
+ *get_trial_duration_seconds(drifting_grating_stim)
+ *nb_run_gratings
+ )
+
+ current_time = current_time+length_rf_seconds+inter_block_interval
+
+ drifting_grating_stim.set_display_sequence([(current_time, current_time+length_drifting_grating_seconds)])
+
+ All_stim.append(drifting_grating_stim)
+ print("length_drifting_grating_minutes: ",length_drifting_grating_seconds/60)
+
+
+
+
+ pre_blank = 0
+ post_blank = 0
+ ss = SweepStim(win,
+ stimuli=All_stim,
+ pre_blank_sec= pre_blank,
+ post_blank_sec= post_blank,
+ params={},
+ )
+
+ # add in foraging so we can track wheel, potentially give rewards, etc
+ f = Foraging(window = win,
+ auto_update = False,
+ params= {}
+ )
+
+ ss.add_item(f, "foraging")
+
+ ss.run()
diff --git a/stimulus_v2species_ephys.py b/stimulus_v2species_ephys.py
new file mode 100644
index 0000000..b6f542d
--- /dev/null
+++ b/stimulus_v2species_ephys.py
@@ -0,0 +1,285 @@
+# -*- coding: utf-8 -*-
+# Stimulus design
+#
+# Please write here any comments or notes about the stimulus design
+# that are relevant for the experiment.
+import psychopy.visual
+import camstim
+import argparse
+import numpy as np
+from psychopy import monitors, visual
+from camstim import SweepStim, Foraging, Window, Warp
+import glob
+import logging
+import yaml
+import os
+from camstim.sweepstim import Stimulus
+from itertools import product
+
+## This is the RF mapping stim
+def create_receptive_field_mapping(window, number_runs = 5):
+ x = np.arange(-40,45,10)
+ y = np.arange(-40,45,10)
+ position = []
+ for i in x:
+ for j in y:
+ position.append([i,j])
+
+ stimulus = Stimulus(visual.GratingStim(window,
+ units='deg',
+ size=20,
+ mask="circle",
+ texRes=256,
+ sf=0.1,
+ ),
+ sweep_params={
+ 'Pos':(position, 0),
+ 'Contrast': ([0.8], 4),
+ 'TF': ([4.0], 1),
+ 'SF': ([0.08], 2),
+ 'Ori': ([0,45,90,], 3),
+ },
+ sweep_length=0.25,
+ start_time=0.0,
+ blank_length=0.0,
+ blank_sweeps=0,
+ runs=number_runs,
+ shuffle=True,
+ save_sweep_table=True,
+ )
+ stimulus.stim_path = r"C:\\not_a_stim_script\\receptive_field_block.stim"
+
+ return stimulus
+
+## This is drifting gratings
+def create_gratingStim(window, number_runs = 5):
+ stimulus_grating = Stimulus(visual.GratingStim(
+ window,
+ pos=(0, 0),
+ units='deg',
+ size=(250, 250),
+ mask="None",
+ texRes=256,
+ sf=0.1,
+ ),
+ sweep_params={
+ 'Contrast': ([0.8], 0),
+ 'TF': ([1.0, 2.0, 4.0, 8.0, 15.0], 1),
+ 'SF': ([0.02, 0.04, 0.08, 0.16, 0.32], 2),
+ 'Ori': (range(0, 360, 90), 3),
+ },
+ sweep_length=1,
+ start_time=0.0,
+ blank_length=1.25,
+ blank_sweeps=0,
+ runs=number_runs,
+ shuffle=True,
+ save_sweep_table=True,
+ )
+ stimulus_grating.stim_path = r"C:\\not_a_stim_script\\drifting_gratings_field_block.stim"
+
+ return stimulus_grating
+
+## This is drifting gratings
+def create_full_field_flash(window, number_runs = 5):
+ stimulus_flash = Stimulus(visual.GratingStim(
+ window,
+ pos=(0, 0),
+ units='deg',
+ size=(250, 250),
+ mask="None",
+ texRes=256,
+ sf=0.0,
+ ),
+ sweep_params={
+ 'Contrast': ([0.8], 0),
+ 'TF': ([4.0], 1),
+ 'SF': ([0.00], 2),
+ 'Ori': (range(0, 180, 45), 3),
+ },
+ sweep_length=0.25,
+ start_time=0.0,
+ blank_length=2,
+ blank_sweeps=0,
+ runs=number_runs,
+ shuffle=True,
+ save_sweep_table=True,
+ )
+ stimulus_flash.stim_path = r"C:\\not_a_stim_script\\flash_field_block.stim"
+
+ return stimulus_flash
+
+
+#this gets total conditions for stimuli defined above
+def count_total_conditions(stimulus):
+ """
+ Given a camstim Stimulus object, return the number of unique parameter combinations.
+ """
+ sweep_params = stimulus.sweep_params
+ param_values = []
+
+ for key, (values, _) in sweep_params.items():
+ # Ensure range is converted to list
+ if type(values).__name__ == 'range':
+ values = list(values)
+ param_values.append(values)
+
+ total_conditions = len(list(product(*param_values)))
+ return total_conditions
+
+
+#this gets trial duration for stimuli defined above
+def get_trial_duration_seconds(stimulus):
+ """
+ Returns the duration of one full trial (sweep + blank) in seconds.
+ """
+ sweep_length = getattr(stimulus, 'sweep_length', 0)
+ blank_length = getattr(stimulus, 'blank_length', 0)
+ return sweep_length + blank_length
+
+ ############################################################################## main code block
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser("mtrain")
+ parser.add_argument("json_path", nargs="?", type=str, default="")
+
+ args, _ = parser.parse_known_args() # <- this ensures that we ignore other arguments that might be needed by camstim
+
+ # print args
+ if args.json_path == "":
+ logging.warning("No json path provided, using default parameters. THIS IS NOT THE EXPECTED BEHAVIOR FOR PRODUCTION RUNS")
+ json_params = {}
+ else:
+ with open(args.json_path, 'r') as f:
+ # we use the yaml package here because the json package loads as unicode, which prevents using the keys as parameters later
+ json_params = yaml.load(f)
+ logging.info("Loaded json parameters from mtrain")
+ # end of mtrain part
+
+ # An integer representing the experiment group. Defaults to test group (value of 2).
+ dev_mode = json_params.get('dev_mode', True)
+ num_reps = json_params.get('num_reps', 1)
+ print("num_reps is: ",num_reps)
+
+ inter_block_interval = json_params.get('inter_block_interval', 10)
+
+ dist = 15.0
+ wid = 52.0
+
+ if dev_mode:
+ my_monitor = monitors.Monitor(name='Test')
+ my_monitor.setSizePix((800,600))
+ my_monitor.setWidth(wid)
+ my_monitor.setDistance(dist)
+ my_monitor.saveMon()
+ win = Window(size=[800,600], # [1024,768],
+ fullscr=False,
+ screen=0,
+ monitor= my_monitor,
+ warp=Warp.Spherical,
+ color= "gray",
+ units = 'deg'
+ )
+ else:
+ win = Window(
+ fullscr=True,
+ screen=0,
+ monitor='Gamma1.Luminance50',
+ warp=Warp.Spherical,
+ )
+
+
+ nb_runs_ephys_rf = 20
+ nb_run_gratings = 15
+ nb_run_flash = 150
+
+ ephys_rf_stim = create_receptive_field_mapping(win, number_runs=nb_runs_ephys_rf)
+ drifting_grating_stim = create_gratingStim(win, number_runs=nb_run_gratings)
+ flash_stim = create_full_field_flash(win, number_runs=nb_run_flash)
+
+ print(
+ "ephys_rf, total conditions: ", count_total_conditions(ephys_rf_stim),
+ ", and trial duration: ", get_trial_duration_seconds(ephys_rf_stim))
+
+ print(
+ "gratings, total conditions: ", count_total_conditions(drifting_grating_stim),
+ ", and trial duration: ", get_trial_duration_seconds(drifting_grating_stim))
+
+ print(
+ "FLASH, total conditions: ", count_total_conditions(flash_stim),
+ ", and trial duration: ", get_trial_duration_seconds(flash_stim))
+
+ All_stim = []
+
+ # Add RF code from ephys
+ current_time = 0
+ if num_reps == 1:
+ length_rf_seconds = 10 #for testing purposes
+ else:
+ length_rf_seconds = (
+ count_total_conditions(ephys_rf_stim)
+ *get_trial_duration_seconds(ephys_rf_stim)
+ *nb_runs_ephys_rf
+ )
+
+ ephys_rf_stim.set_display_sequence([(current_time, current_time+length_rf_seconds)])
+
+ All_stim.append(ephys_rf_stim)
+ print("length_rf_minutes: ",length_rf_seconds/60)
+
+ # drifting_grating_stim
+ if num_reps == 1:
+ length_drifting_grating_seconds = 10
+ else:
+ length_drifting_grating_seconds = (
+ count_total_conditions(drifting_grating_stim)
+ *get_trial_duration_seconds(drifting_grating_stim)
+ *nb_run_gratings
+ )
+
+ current_time = current_time+length_rf_seconds+inter_block_interval
+
+ drifting_grating_stim.set_display_sequence([(current_time, current_time+length_drifting_grating_seconds)])
+
+ All_stim.append(drifting_grating_stim)
+ print("length_drifting_grating_minutes: ",length_drifting_grating_seconds/60)
+
+
+ # flash_stim
+ if num_reps == 1:
+ length_flash_seconds = 10
+ else:
+ length_flash_seconds = (
+ count_total_conditions(flash_stim)
+ *get_trial_duration_seconds(flash_stim)
+ *nb_run_flash
+ )
+
+ current_time = current_time+length_flash_seconds+inter_block_interval
+
+ flash_stim.set_display_sequence([(current_time, current_time+length_flash_seconds)])
+
+ All_stim.append(flash_stim)
+ print("length_flash_minutes: ",length_flash_seconds/60)
+
+
+
+ pre_blank = 0
+ post_blank = 0
+ ss = SweepStim(win,
+ stimuli=All_stim,
+ pre_blank_sec= pre_blank,
+ post_blank_sec= post_blank,
+ params={},
+ )
+
+ # add in foraging so we can track wheel, potentially give rewards, etc
+ f = Foraging(window = win,
+ auto_update = False,
+ params= {}
+ )
+
+ ss.add_item(f, "foraging")
+
+ ss.run()