From 9bab3c10a3e4c40cb7176eb8779bb4da5d0a25c5 Mon Sep 17 00:00:00 2001 From: kaeldai Date: Mon, 29 Apr 2024 23:44:45 -0700 Subject: [PATCH] Fixing filter_movie/ example --- .gitignore | 3 + .../filternet/default_setters/cell_loaders.py | 6 +- examples/filter_movie/README.md | 60 +- examples/filter_movie/build_network.py | 128 ++- ...ion.json => config.simulation_custom.json} | 6 +- .../config.simulation_greyscreen.json | 39 + .../config.simulation_naturalscenes.json | 40 + .../config.simulation_touchofevil.json | 44 + examples/filter_movie/create_movie.py | 868 ++++++++++++++++++ .../filter_movie/network/lgn_node_types.csv | 6 +- examples/filter_movie/network/lgn_nodes.h5 | Bin 8264 -> 26259 bytes 11 files changed, 1168 insertions(+), 32 deletions(-) rename examples/filter_movie/{config.simulation.json => config.simulation_custom.json} (86%) create mode 100644 examples/filter_movie/config.simulation_greyscreen.json create mode 100644 examples/filter_movie/config.simulation_naturalscenes.json create mode 100644 examples/filter_movie/config.simulation_touchofevil.json create mode 100644 examples/filter_movie/create_movie.py diff --git a/.gitignore b/.gitignore index fa653cb2..533f199b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,9 @@ docs/tutorial/sim_ch* docs/tutorial/sim_dyn_syn examples/**/output*/** examples/bio_simulated_annealing/updated_weights/* +examples/filter_movie/boc/* +examples/filter_movie/bob_images/* +examples/filter_movie/movies/* /.eggs benchmarks/.asv **/x86_64/** diff --git a/bmtk/simulator/filternet/default_setters/cell_loaders.py b/bmtk/simulator/filternet/default_setters/cell_loaders.py index 23a0c7fe..ac6f7b0c 100644 --- a/bmtk/simulator/filternet/default_setters/cell_loaders.py +++ b/bmtk/simulator/filternet/default_setters/cell_loaders.py @@ -203,11 +203,7 @@ def default_cell_loader(node, template_name, dynamics_params): cell = sep_ts_onoff_cell elif model_name == 'LGNOnOFFCell': - wts = [node['weight_dom_0'], node['weight_dom_1']] - kpeaks = [node['kpeaks_dom_0'], node['kpeaks_dom_1']] - delays = [node['delay_dom_0'], node['delay_dom_1']] - # transfer_function = ScalarTransferFunction('s') - temporal_filter = TemporalFilterCosineBump(wts, kpeaks, delays) + temporal_filter = TemporalFilterCosineBump(t_weights, t_kpeaks, t_delays) spatial_filter_on = GaussianSpatialFilter(sigma=node['sigma_on'], origin=origin, translate=translate) on_linear_filter = SpatioTemporalFilter(spatial_filter_on, temporal_filter, amplitude=20) diff --git a/examples/filter_movie/README.md b/examples/filter_movie/README.md index 1dfd7799..040cd4ab 100644 --- a/examples/filter_movie/README.md +++ b/examples/filter_movie/README.md @@ -1,2 +1,58 @@ -This example shows how a user can provide any movie file saved as .npy to simulate LGN responses. -The input simply needs to be an (x,y,t) that describes frames over time. See the config that has an attribute under INPUTS called "data_file" which points to the desirve npy movie. +# FilterNet simulations from arbitary movies + +One optional type of visual stimuli into the FilterNet simulation can be a movie generated by the modeler. The input file should be a .npy or .npz file made from a matrix of size `(frames, rows, columns)`. It should be grey-scaled single channel (LGN Model was not optimized for color movies). And the movies arrays can either be a floating-point type-matrix with contrast values normalized between [-1.0, +1.0], or an integer (uint8) with values between [0, 255]. + + +In this network example we will show multiple ways of creating and playing custom movie files. Two examples are movies generated from the Allen Brain Observatory experiments and one just a grey-screen movie. + + +## Generating movie files + +Because the movie .npy files can get pretty big, you must first generate these files using the `create_movie.py` script. + +### Natural Scenes + +As part of the Brain Observatory experiments mice we shown a sequence of 118 different static images in a randomized order. To recreate this experiment for FilterNet we will uses the following command to generate a movie from 20 of the different images. + +```bash + $ python create_movie.py --n-images=20 --images-per-sec=10 --greyscreen-pre=500.0 natural-scenes +``` + +with the following options +* **--n-images=20** - Uses only 20 of the 118 images in the Brain Observatory data set. +* **--images-per-sec=10** - Show 10 images every second (eg. the screen changes every 100 ms). +* **--greyscreen-pre=500.0** - Adds a grey-screen fro 500 ms at the beginning of the movie. + +The .npy file will be saved to the *movies/* folder. To run FilterNet to generate retinal-thalamic spike trains generated from this movie you can use the `config.simulation_naturalscenes.json` config file: + +```bash + $ python run_filternet.py config.simulation_naturalscenes.json +``` + +Resulting spike-trains and rates file will be saved to the *output_naturalscenes/* folder as specified in the config. + +### Natural Movies (eg. Touch of Evil) + +For more naturalistic style movies, the Brain Observatory experiments included showing clips from the Orson Wells films "Touch of Evil", with two clips at 30 seconds and one clip at 120 seconds. To use this input with FilterNet we need to not only convert the movie files to .npy. But we must also resize to fit our model's field-size (120x240) as-well-as upscale the film to 1000 fps. We can do this with the following command: + +```bash +$ python create_movie.py touch-of-evil +``` + +The resulting npy file will be saved to the *movies/* folder. As you can run + +```bash +$ python run_filternet.py config.simulation_touchofevil.json +``` + +To run FilterNet against 3 seconds of the 30 second clip and save the output to the *output_naturalmovie/* folder. + +### Grey Screen + +The `config.simulation_greyscreen.json` will run against of movie consisting of nothing but a static grey screen, which can be a useful check of our model. To generate the appropiate movie npy file run the following command + +```bash +$ python create_movie.py greyscreen +``` + + diff --git a/examples/filter_movie/build_network.py b/examples/filter_movie/build_network.py index a63985f4..b88cfa92 100644 --- a/examples/filter_movie/build_network.py +++ b/examples/filter_movie/build_network.py @@ -1,22 +1,114 @@ +import os +import pickle import numpy as np + from bmtk.builder import NetworkBuilder -field_size = (304, 608) # size of movie screen (pixels) -cell_grid = (5, 5) # place cells in a grid layout of NxM -xs, ys = np.meshgrid(np.linspace(0, field_size[0], num=cell_grid[0]), np.linspace(0, field_size[1], num=cell_grid[1])) - -lgn_net = NetworkBuilder('lgn') -lgn_net.add_nodes( - N=cell_grid[0]*cell_grid[1], - ei='e', - model_type='virtual', - model_template='lgnmodel:LGNOnOFFCell', - dynamics_params='lgn_on_off_model.json', - sigma_on=(2.0, 2.0), - sigma_off=(4.0, 4.0), - x=xs.flatten(), - y=ys.flatten() -) - -lgn_net.save_nodes(output_dir='network') \ No newline at end of file +X_grids = 2 # 15 +Y_grids = 2 # 10 +X_len = 240.0 # In linear degrees +Y_len = 120.0 # In linear degrees + + +def generate_positions_grids(N, X_grids, Y_grids, X_len, Y_len): + width_per_tile = X_len/X_grids + height_per_tile = Y_len/Y_grids + + X = np.zeros(N * X_grids * Y_grids) + Y = np.zeros(N * X_grids * Y_grids) + + counter = 0 + for i in range(X_grids): + for j in range(Y_grids): + X_tile = np.random.uniform(i*width_per_tile, (i+1) * width_per_tile, N) + Y_tile = np.random.uniform(j*height_per_tile, (j+1) * height_per_tile, N) + X[counter*N:(counter+1)*N] = X_tile + Y[counter*N:(counter+1)*N] = Y_tile + counter += 1 + return np.column_stack((X, Y)) + + +def get_filter_spatial_size(N, X_grids, Y_grids, size_range): + spatial_sizes = np.zeros(N * X_grids * Y_grids) + counter = 0 + for i in range(X_grids): + for j in range(Y_grids): + if len(size_range) == 1: + sizes = np.ones(N) * size_range[0] + else: + sizes = np.random.triangular(size_range[0], size_range[0] + 1, size_range[1], N) + spatial_sizes[counter * N:(counter + 1) * N] = sizes + counter += 1 + + return spatial_sizes + + +lgn_models = [ + { + 'N': 8, + 'ei': 'e', + 'model_type': 'virtual', + 'model_template': 'lgnmodel:tOFF_TF15', + 'size_range': [2, 10], + 'dynamics_params': 'tOFF_TF15_3.44215357_-2.11509939_8.27421573_20.0_0.0_ic.json' + }, + { + 'N': 8, + 'ei': 'e', + 'model_type': 'virtual', + 'model_template': 'lgnmodel:sONsOFF_001', + 'size_range': [6], + 'dynamics_params': 'sOFF_TF4_3.5_-2.0_10.0_60.0_15.0_ic.json', + 'non_dom_params': 'sON_TF4_3.5_-2.0_30.0_60.0_25.0_ic.json', + 'sf_sep': 6.0 + }, + { + 'N': 5, + 'ei': 'e', + 'model_type': 'virtual', + 'model_template': 'lgnmodel:sONtOFF_001', + 'size_range': [9], + 'dynamics_params': 'tOFF_TF8_4.222_-2.404_8.545_23.019_0.0_ic.json', + 'non_dom_params': 'sON_TF4_3.5_-2.0_30.0_60.0_25.0_ic.json', + 'sf_sep': 4.0 + } +] + +lgn = NetworkBuilder('lgn') +for params in lgn_models: + # Get position of lgn cells and keep track of the averaged location + # For now, use randomly generated values + total_N = params['N'] * X_grids * Y_grids + + # Get positional coordinates of cells + positions = generate_positions_grids(params['N'], X_grids, Y_grids, X_len, Y_len) + + # Get spatial filter size of cells + filter_sizes = get_filter_spatial_size(params['N'], X_grids, Y_grids, params['size_range']) + + lgn.add_nodes( + N=total_N, + ei=params['ei'], + model_type=params['model_type'], + model_template=params['model_template'], + x=positions[:, 0], + y=positions[:, 1], + dynamics_params=params['dynamics_params'], + + # TODO: Come up with better name than non-dominate parameters (spatial-params?) + non_dom_params=params.get('non_dom_params', None), + + # TODO: See if it's possible to calculate spatial sizes during simulation. + spatial_size=filter_sizes, + + # NOTE: If tuning angle is not defined, then it will be randomly generated during the simulation. But + # when evaluating a large network many times it will be more efficent to store it in the nodes file. + tuning_angle=np.random.uniform(0.0, 360.0, total_N), + + # TODO: Can sf-sperator be stored in the params json file. + sf_sep=params.get('sf_sep', None) + ) + +lgn.build() +lgn.save(output_dir='network') diff --git a/examples/filter_movie/config.simulation.json b/examples/filter_movie/config.simulation_custom.json similarity index 86% rename from examples/filter_movie/config.simulation.json rename to examples/filter_movie/config.simulation_custom.json index 6a068244..152a0723 100644 --- a/examples/filter_movie/config.simulation.json +++ b/examples/filter_movie/config.simulation_custom.json @@ -22,11 +22,7 @@ "input_type": "movie", "module": "movie", "data_file": "$INPUT_DIR/test_scene.npy", - "frame_rate": 1000.0, - "evaluation_options": { - "t_min": 3.0, - "t_max": 4.0 - } + "frame_rate": 1000.0 } }, diff --git a/examples/filter_movie/config.simulation_greyscreen.json b/examples/filter_movie/config.simulation_greyscreen.json new file mode 100644 index 00000000..e6beedd0 --- /dev/null +++ b/examples/filter_movie/config.simulation_greyscreen.json @@ -0,0 +1,39 @@ +{ + "manifest": { + "$BASE_DIR": ".", + "$OUTPUT_DIR": "$BASE_DIR/output_greyscreen", + "$INPUT_DIR": "$BASE_DIR/movies" + }, + + "run": { + "tstop": 2000.0, + "dt": 0.1 + }, + + "target_simulator": "LGNModel", + + "conditions": { + "jitter_lower": 1.0, + "jitter_upper": 1.0 + }, + + "inputs": { + "movie_input": { + "input_type": "movie", + "module": "movie", + "data_file": "$INPUT_DIR/grey_screen.2000ms.1000fps.normalized.npy", + "frame_rate": 1000.0 + } + }, + + "output": { + "output_dir": "$OUTPUT_DIR", + "log_file": "log.txt", + "rates_csv": "rates.csv", + "spikes_csv": "spikes.csv", + "spikes_h5": "spikes.h5", + "overwrite_output_dir": true + }, + + "network": "config.circuit.json" +} diff --git a/examples/filter_movie/config.simulation_naturalscenes.json b/examples/filter_movie/config.simulation_naturalscenes.json new file mode 100644 index 00000000..4c62dd11 --- /dev/null +++ b/examples/filter_movie/config.simulation_naturalscenes.json @@ -0,0 +1,40 @@ +{ + "manifest": { + "$BASE_DIR": ".", + "$OUTPUT_DIR": "$BASE_DIR/output_natural_scenes", + "$INPUT_DIR": "$BASE_DIR/movies" + }, + + "run": { + "tstop": 2500.0, + "dt": 0.1 + }, + + "target_simulator": "LGNModel", + + "conditions": { + "jitter_lower": 1.0, + "jitter_upper": 1.0 + }, + + "inputs": { + "movie_input": { + "input_type": "movie", + "module": "movie", + "data_file": "$INPUT_DIR/ns_20images.set00.2500ms.1000fps.10ips.npy", + "frame_rate": 1000.0, + "normalize": true + } + }, + + "output": { + "output_dir": "$OUTPUT_DIR", + "log_file": "log.txt", + "rates_csv": "rates.csv", + "spikes_csv": "spikes.csv", + "spikes_h5": "spikes.h5", + "overwrite_output_dir": true + }, + + "network": "config.circuit.json" +} diff --git a/examples/filter_movie/config.simulation_touchofevil.json b/examples/filter_movie/config.simulation_touchofevil.json new file mode 100644 index 00000000..6edf9976 --- /dev/null +++ b/examples/filter_movie/config.simulation_touchofevil.json @@ -0,0 +1,44 @@ +{ + "manifest": { + "$BASE_DIR": ".", + "$OUTPUT_DIR": "$BASE_DIR/output_natural_movies_one", + "$INPUT_DIR": "$BASE_DIR/movies" + }, + + "run": { + "tstop": 3000.0, + "dt": 0.1 + }, + + "target_simulator": "LGNModel", + + "conditions": { + "jitter_lower": 1.0, + "jitter_upper": 1.0 + }, + + "inputs": { + "movie_input": { + "input_type": "movie", + "module": "movie", + "data_file": "$INPUT_DIR/natural_movie_one.29700ms.120x240.npy", + "frame_rate": 1000.0, + "normalize": true, + "evaluation_options": { + "t_min": 0.0, + "t_max": 3.0 + } + } + }, + + "output": { + "output_dir": "$OUTPUT_DIR", + "log_file": "log.txt", + "rates_csv": "rates.csv", + "spikes_csv": "spikes.csv", + "spikes_h5": "spikes.h5", + "overwrite_output_dir": true + }, + + "network": "config.circuit.json" +} diff --git a/examples/filter_movie/create_movie.py b/examples/filter_movie/create_movie.py new file mode 100644 index 00000000..dc25cda3 --- /dev/null +++ b/examples/filter_movie/create_movie.py @@ -0,0 +1,868 @@ +import os +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +# import matplotlib.image as mpimg +import json +from PIL import Image +import argparse +import logging + +# from create_configs import create_lgnmodel_config +from allensdk.core.brain_observatory_cache import BrainObservatoryCache + +# logger = logging.Logger(__name__) + +# def get_natural_scenes(output_dir='bob_images'): +# """Fetches the 118 Brain Obs natural scene images from the data, saves them in npy format""" +# if not os.path.exists(output_dir): +# os.mkdir(output_dir) + +# boc = BrainObservatoryCache(manifest_file='boc/manifest.json') +# data_set = boc.get_ophys_experiment_data(501498760) +# scenes = data_set.get_stimulus_template('natural_scenes') + +# for i in range(0, len(scenes)): +# scene = scenes[i] +# base_name = os.path.join(output_dir, 'scene.{:03d}.gray_{}x{}'.format(i, scene.shape[0], scene.shape[1])) +# plt.imsave('{}.png'.format(base_name), scene, cmap='gray') +# np.save('{}.npy'.format(base_name), scene) + + +# def create_gray_screen(output_dir='bob_images', res_y=918, res_x=1174): +# """Creates grey-screen for BOb natural scene images""" +# if not os.path.exists(output_dir): +# os.mkdir(output_dir) +# base_name = os.path.join(output_dir, 'gray_screen.{}x{}'.format(res_y, res_x)) + +# gray_screen = np.full((res_y, res_x), fill_value=201.0) +# plt.imsave(base_name + '.png', gray_screen, cmap='gray', vmin=0, vmax=256) +# np.save(base_name + '.npy', gray_screen) + + +# """ +# def create_movies(images_per_movie=10, res_y=918, res_x=1174, movie_set=1): +# movies_dir = 'movies_set{:02d}'.format(movie_set) +# if not os.path.exists(movies_dir): +# os.mkdir(movies_dir) + +# gray_screen = np.array(Image.open('gray_screen/gray_screen.{}x{}.png'.format(res_y, res_x)).convert('L')) +# gray_block = np.array([gray_screen for _ in range(45)]) + +# movie_files = [] +# image_files = [] +# image_nums = [] +# images_perm = np.random.permutation(range(118)) +# for set_n, start_idx in enumerate(range(0, len(images_perm), images_per_movie)): +# end_idx = np.min((start_idx + images_per_movie, len(images_perm))) +# n_images = end_idx - start_idx + +# file_name = 'movie_{}.{}_images.{}x{}.60fps.npy'.format(set_n, n_images, res_y, res_x) +# movie_arr = np.zeros((60 * n_images, res_y, res_x), dtype=np.int) +# for movie_offset, img_idx in enumerate(range(start_idx, end_idx)): +# # imag_off +# image_file = 'images/scene.{:03d}.gray_{}x{}.png'.format(img_idx, res_y, res_x) +# im = np.array(Image.open(image_file).convert('L')) +# img_block = np.array([im for _ in range(15)]) + +# offset = movie_offset * 60 +# movie_arr[offset:offset + 45, :, :] = gray_block +# movie_arr[(offset + 45):(offset + 60), :, :] = img_block + +# movie_files.append(file_name) +# print(img_idx) +# image_nums.append(img_idx) +# image_files.append(image_file) + +# np.save(os.path.join(movies_dir, file_name), movie_arr) + +# pd.DataFrame({ +# 'movie_file': movie_files, +# 'image_number': image_nums, +# 'image_file': image_files +# }).to_csv(os.path.join(movies_dir, 'movies_metadata.csv'), sep=' ', index=False) +# """ + +# """ +# def create_movie_allns(res_y=918, res_x=1174): +# movies_dir = 'movie_all_ns' +# if not os.path.exists(movies_dir): +# os.mkdir(movies_dir) + +# gray_screen = np.array(Image.open('gray_screen/gray_screen.{}x{}.png'.format(res_y, res_x)).convert('L')) +# gray_block = np.array([gray_screen for _ in range(30)]) + +# full_movie = np.zeros((30 + 118 * 15, res_y, res_x), dtype=np.int) +# full_movie[0:30, :, :] = gray_block + +# image_files = [] +# image_nums = [] +# np.random.seed(100) +# images_perm = np.random.permutation(range(118)) +# for image_num, image_id in enumerate(images_perm): +# image_file = 'images/scene.{:03d}.gray_{}x{}.png'.format(image_id, res_y, res_x) +# im = np.array(Image.open(image_file).convert('L')) +# im_block = np.array([im for _ in range(15)]) + +# offset = 30 + image_num * 15 +# full_movie[offset:(offset + 15), :, :] = im_block + +# image_files.append(image_file) +# image_nums.append(image_num) + +# pd.DataFrame({ +# 'movie_file': 'all_natural_scenes.trial00.60fp.npy', +# 'image_number': image_nums, +# 'image_file': image_files +# }).to_csv(os.path.join(movies_dir, 'movies_metadata.csv'), sep=' ', index=False) + +# np.save(os.path.join(movies_dir, 'all_natural_scenes.trial00.60fp.npy'), full_movie) +# """ + + +# def check_movie(movie_file): +# # movie_file = 'movie_all_ns/all_natural_scenes.trial00.60fp.npy' +# movie_array = np.load(movie_file) +# plt.figure() +# plt.imshow(movie_array[30, :, :], cmap='gray') + +# plt.figure() +# plt.imshow(movie_array[29, :, :], cmap='gray') + +# plt.figure() +# plt.imshow(movie_array[59, :, :], cmap='gray') + +# plt.figure() +# plt.imshow(movie_array[60, :, :], cmap='gray') + +# plt.figure() +# plt.imshow(movie_array[-1, :, :], cmap='gray') + +# plt.show() + + +# def create_ns_movie(n_images=118, ips=10, fps=1000.0, res_row=120, res_col=240, gs_pre=500, gs_post=100, rng_seed=None, +# images_dir='bob_images', output_dir='movies', overwrite=True, create_config=True, normalize=True, +# config_dir='lgnmodel_configs'): +# frames_per_image = int(float(fps) / ips) # num of frames that will be given to each image +# frames_per_gs_pre = int(gs_pre / 1000.0 * fps) # num frames for initial gray screen +# frames_per_gs_post = int(gs_post / 1000.0 * fps) # num frames for ending gray screen +# n_frames = frames_per_gs_pre + frames_per_image*n_images + frames_per_gs_post +# set_num = '{:02d}'.format(0) +# total_time = n_frames/float(fps)*1000.0 + +# # Find the movie path, make sure not to overwrite existing movie files +# if not os.path.exists(output_dir): +# os.mkdir(output_dir) + +# movie_path = os.path.join(output_dir, 'ns_{}images.set{}.{}ms.{}fps.{}ips.normalized.npy'.format( +# n_images, set_num, int(total_time), int(fps), int(ips) +# )) + +# if not overwrite and os.path.exists(movie_path): +# for i in range(1, 100): +# set_num = '{:02d}'.format(i) +# movie_path = 'movies/ns_{}images.set{}.{}ms.{}fps.{}ips{}.npy'.format( +# n_images, set_num, int(total_time), int(fps), int(ips), '.normalized' if normalize else '' +# ) +# if not os.path.exists(movie_path): +# break +# else: +# raise ValueError('Could not create valid movie path.') + +# if create_config: +# if not os.path.exists(config_dir): +# os.makedirs(config_dir) + +# base_name = 'ns_{}images_set{}_{}fps_{}ips{}'.format(n_images, set_num, int(fps), int(ips), +# '_normalized' if normalize else '') + +# config_file = 'ns_{}images.{}fps.{}ips.set{}{}.json'.format(n_images, int(fps), int(ips), set_num, +# '.normalized' if normalize else '') +# config_path = os.path.join(config_dir, config_file) +# json.dump( +# { +# 'movie_file': movie_path, +# 'fps': fps, +# 'duration': total_time / 1000.0, +# 'gray_screen': gs_pre / 1000.0, +# 'output_dir': os.path.join('lgnmodel_results', 'output_{}'.format(base_name)), +# 'force_overwrite': True, +# 'normalized': normalize, +# 'res_row': res_row, +# 'res_col': res_col, +# 'base_name': 'ns_{}images.{}ms.{}fps.{}ips.set{}{}'.format( +# n_images, int(total_time), int(fps), int(ips), set_num, '.normalized' if normalize else '' +# ), +# 'n_trials': 5 +# }, +# open(config_path, 'w'), +# indent=2 +# ) +# # base_name = 'ns_{}images_set{}_{}fps_{}ips{}'.format(n_images, set_num, int(fps), int(ips), +# # '_normalized' if normalize else '') +# # create_lgnmodel_config( +# # config_path=os.path.join('lgnmodel_configs', 'config.filternet.{}.json'.format(base_name)), +# # output_dir=os.path.join('lgnmodel_results', 'output_{}'.format(base_name)), +# # duration=float(total_time), +# # movie_path=os.path.basename(movie_path), +# # fps=fps, +# # res_row=res_row, +# # res_col=res_col +# # ) +# # create_pointnet_config( +# # config_path=os.path.join('pointnet_configs', 'config.pointnet.{}.json'.format(base_name)), +# # output_dir=os.path.join('pointnet_results', 'output_{}'.format(base_name)), +# # duration=float(total_time), +# # lgn_spikes_path=os.path.join('lgnmodel_results', 'output_{}'.format(base_name), 'spikes.h5') +# # ) + + +# # Keep track of the order and placement of the images, metadata will be written to csv +# csv_path = movie_path[:-4] + '.metadata.csv' +# img_names = [] +# frames_ids = [] +# image_times = [] + +# if frames_per_gs_pre > 0: +# img_names.append('grayscreen') +# frames_ids.append((0, frames_per_gs_pre)) +# image_times.append((0, frames_per_gs_pre/float(fps))) + +# output_mat = np.zeros((n_frames, res_row, res_col), dtype=float) +# mat_beg = frames_per_gs_pre +# if rng_seed: +# np.random.seed(rng_seed) +# images_perm = np.random.permutation(range(n_images)) +# for image_num, image_id in enumerate(images_perm): +# # Find the image and convert to a 120x240 matrix +# # img_path = movie_jpegs[i] +# img_path = os.path.join(images_dir, 'scene.{:03d}.gray_918x1174.png'.format(image_id)) +# pic = Image.open(img_path).convert('L') +# pic = pic.resize((res_col, res_row)) # PIL the row/col order is swapped +# pic_data = np.asarray(pic) +# if normalize: +# pic_data = pic_data.astype(dtype=float) * 2.0 / 255.0 - 1.0 + +# mat_end = mat_beg + frames_per_image +# output_mat[mat_beg:mat_end, :, :] = pic_data + +# # keep track of metadata +# img_names.append(img_path[len(images_dir)+1:]) +# frames_ids.append((mat_beg, mat_end)) +# image_times.append((mat_beg/float(fps), mat_end/float(fps))) + +# mat_beg = mat_end + +# np.save(movie_path, output_mat) + +# if frames_per_gs_post > 0: +# img_names.append('grayscreen') +# f_beg = n_frames - frames_per_gs_post +# f_end = n_frames +# frames_ids.append((f_beg, f_end)) +# image_times.append((f_beg/float(fps), f_end/float(fps))) + +# pd.DataFrame({ +# 'image_id': img_names, +# 'begin_frame': [f[0] for f in frames_ids], +# 'end_frame': [f[1] for f in frames_ids], +# 'begin_time': [t[0] for t in image_times], +# 'end_time': [t[1] for t in image_times] +# }).to_csv(csv_path, sep=' ', index=False) + + +# ''' +# def create_ns_movie(n_images=118, fps=1000, res_row=120, res_col=240, images_dur=.25, gs_pre=.5, gs_post=.1, +# rng_seed=None, output_dir='movies', images_dir='bob_images', create_config=True, +# config_dir='lgnmodel_configs', n_trials=1, normalize=False): +# """Creates a movie based on the natural-scene images taken from Brain Observatory sessions, randomized. Also +# creates a stimulus table + +# :param n_images: number of images taken from bob to show +# :param fps: frame-per-second +# :param res_y: y resolution +# :param res_x: x resultion +# :param images_dur: time (seconds) each image is shown. +# :param gray_screen_dur: time (seconds) of initial grey-screen +# :param rng_seed: seed for randomization +# :param output_dir: directory where movie (and stimulus table) will +# :param images_dir: directory of the BOb images +# :param create_config: creates a config for running lgnmodel +# :param config_dir: directory where lgnmodel config will be saved too. +# :param n_trials: used for lgnmodel config. +# :param normalize: normalize movie from [0, 255] --> [-1, 1] +# :return: +# """ + +# ips = int(1.0/images_dur) +# total_time = gs_pre + images_dur*n_images + gs_post + +# base_name = 'ns_{}images_{}fps_{}ips'.format(n_images, int(fps), int(ips)) +# trial_num = 0 +# for trial_num in range(100): +# tmp_dir = os.path.join(output_dir, '{}_set{:02d}'.format(base_name, trial_num)) +# if not os.path.exists(tmp_dir): +# output_dir = tmp_dir +# break + +# movie_file = 'ns_{}images.{}fps.{}ips.{}x{}.set{:02d}{}.npy'.format(n_images, fps, int(ips), res_y, res_x, +# trial_num, '.normalized' if normalize else '') + +# if rng_seed is not None: +# np.random.seed(rng_seed) + +# n_frames_pre = int(gs_pre * fps) +# n_frames_images = int(images_dur * fps) +# n_frames_post = int(gs_post * fps) +# full_movie = np.zeros((n_frames_pre + n_images*n_frames_images + n_frames_post, res_row, res_col), +# dtype=np.int if normalize else np.float) + +# stimulus_table = { +# 'image_file': [], +# 'image_id': [], +# 'start_time': [], +# 'stop_time': [], +# 'n_frames': [], +# 'movie_file': movie_file, +# 'block_number': np.arange(n_images + int(n_frames_pre != 0) + int(n_frames_post != 0)) +# } + +# curr_frame = 0 +# if n_frames_pre > 0: +# if normalize: +# gray_screen = np.full((res_y, res_x), 0.0, dtype=np.float) +# else: +# gray_screen = np.full((res_y, res_x), 127, dtype=np.integer) + +# gray_block = np.array([gray_screen for _ in range(n_frames_gray)]) +# full_movie[curr_frame:(curr_frame + n_frames_gray), :, :] = gray_block + +# stimulus_table['image_file'].append('gray_screen') +# stimulus_table['image_id'].append(-1) +# stimulus_table['n_frames'].append(n_frames_gray) +# stimulus_table['start_time'].append(float(curr_frame) / fps) +# stimulus_table['stop_time'].append(float(curr_frame + n_frames_gray) / fps) +# curr_frame += n_frames_gray + +# images_perm = np.random.permutation(range(n_images)) +# for image_num, image_id in enumerate(images_perm): +# # image_file = os.path.join(images_dir, 'scene.{:03d}.gray_{}x{}.png'.format(image_id, res_y, res_x)) +# image_file = 'scene.{:03d}.gray_918x1174.png'.format(image_id) +# img_path = os.path.join(images_dir, image_file) +# pic = Image.open(img_path).convert('L') +# pic = pic.resize((res_col, res_row)) # PIL the row/col order is swapped +# pic_data = np.asarray(pic) +# ## im = np.array(Image.open(image_file).convert('L')) +# if normalize: +# pic_data = pic_data.astype(dtype=np.float) * 2.0 / 255.0 - 1.0 + +# # im_block = np.array([im for _ in range(n_frames_images)]) +# full_movie[curr_frame:(curr_frame + n_frames_images), :, :] = pic_data + +# stimulus_table['image_file'].append(image_file) +# stimulus_table['image_id'].append(image_id) +# stimulus_table['n_frames'].append(n_frames_images) +# stimulus_table['start_time'].append(float(curr_frame) / fps) +# stimulus_table['stop_time'].append(float(curr_frame + n_frames_images) / fps) + +# curr_frame += n_frames_images + +# os.makedirs(output_dir) +# np.save(os.path.join(output_dir, movie_file), full_movie) +# pd.DataFrame(data=stimulus_table).to_csv(os.path.join(output_dir, 'stimulus_table.csv'), sep=' ', index=False) + +# if create_config: +# if not os.path.exists(config_dir): +# os.makedirs(config_dir) + +# config_file = 'ns_{}images.{}fps.{}ips.set{:02d}{}.json'.format(n_images, int(fps), int(ips), trial_num, +# '.normalized' if normalize else '') +# config_path = os.path.join(config_dir, config_file) +# json.dump( +# { +# 'movie_file': os.path.join(output_dir, movie_file), +# 'fps': fps, +# 'duration': total_time, +# 'gray_screen': gray_screen_dur, +# 'output_dir': os.path.join('lgnmodel_results', 'output_{}'.format(base_name)), +# 'force_overwrite': True, +# 'normalized': normalize, +# 'res_row': res_y, +# 'res_col': res_x, +# 'base_name': 'ns_{}images.{}ms.{}fps.{}ips.set{:02d}{}'.format( +# n_images, int(total_time), int(fps), int(ips), trial_num, '.normalized' if normalize else '' +# ), +# 'n_trials': n_trials +# }, +# open(config_path, 'w'), +# indent=2 +# ) +# ''' + +# """ +# def get_natural_movies(movie_name='natural_movie_one', output_dir='movies'): +# if not os.path.exists(output_dir): +# os.mkdir(output_dir) +# # base_name = os.path.join(output_dir, movie_name) + +# # print('HERE') +# # exit() + +# boc = BrainObservatoryCache(manifest_file='boc/manifest.json') +# data_set = boc.get_ophys_experiment_data(506248008) +# for movie_name in ['natural_movie_one', 'natural_movie_two']: +# # print(movie_name) +# movie = data_set.get_stimulus_template(movie_name) +# t, y, x = movie.shape +# time = int(t / 30) +# print(t, y, x) +# exit() + +# fname = os.path.join(output_dir, '{}.{}s.30fps.{}x{}.npy'.format(movie_name, time, y, x)) +# # np.save(fname, movie) + +# boc = BrainObservatoryCache(manifest_file='boc/manifest.json') +# data_set = boc.get_ophys_experiment_data(649409874) +# for movie_name in ['natural_movie_three']: +# # print(movie_name) +# movie = data_set.get_stimulus_template(movie_name) +# t, y, x = movie.shape +# print(t, y, x) +# exit() + +# time = int(t / 30) +# fname = os.path.join(output_dir, '{}.{}s.30fps.{}x{}.npy'.format(movie_name, time, y, x)) +# np.save(fname, movie) +# # print(movie.shape) + + +# def natural_movie_1000Hz_gs(output_dir='.', fps=1000): +# boc = BrainObservatoryCache(manifest_file='boc/manifest.json') +# data_set = boc.get_ophys_experiment_data(649409874) +# # data_set = boc.get_ophys_experiment_data(506248008) + +# nframes_gs = int(fps * .5) +# nframes_screen = int(fps * 3.0) + +# # movie_3sec_gs = np.zeros((int(1000*3.5), 304, 608), dtype=np.uint8) +# movie_3sec_gs = np.full((int(1000 * 3.5), 304, 608), fill_value=127.5, dtype=np.float) + +# for movie_name in ['natural_movie_three']: +# movie = data_set.get_stimulus_template(movie_name) +# t, y, x = movie.shape + +# movie_3sec = movie[:90, :, :] +# movie_3sec_1000hz = movie_3sec.repeat(34, axis=0)[:3000] +# # print(movie_3sec_1000hz.shape) +# # exit() +# # print(movie.repeat(33, axis=0)) +# # exit() + +# movie_3sec_gs[500:, :, :] = movie_3sec_1000hz # movie[:90, :, :] +# print(movie_3sec_gs) +# print(movie_3sec_gs.shape) +# # exit() + +# fname = os.path.join(output_dir, '{}.3500ms.gs.30fps.{}x{}.npy'.format(movie_name, y, x)) +# np.save(fname, movie_3sec_gs) +# """ + + +# def get_touchofevil_movies(output_dir='movies', create_config=True, config_dir='lgnmodel_configs'): +# """Fetches the BOb touch-of-evil (natural movies), and converts them to npy format for using with lgnmodel + +# :param output_dir: +# :param create_config: +# :param config_dir: +# """ +# boc = BrainObservatoryCache(manifest_file='boc/manifest.json') +# data_set = boc.get_ophys_experiment_data(506248008) + +# movie = data_set.get_stimulus_template('natural_movie_one') +# t, x, y = movie.shape +# movie_name = 'natural_movie_one.30s.30fps.304x608.orig.npy' +# movie_path = os.path.join(output_dir, movie_name) +# np.save(movie_path, movie) +# if create_config: +# if not os.path.exists(config_dir): +# os.makedirs(config_dir) + +# json.dump( +# { +# 'movie_file': movie_path, +# 'fps': 30, +# 'duration': t / 30.0, +# 'gray_screen': 0.0, +# 'output_dir': os.path.join('results_lgnmodel', 'output_natural_movie_one_30fps_orig'), +# 'force_overwrite': True, +# 'normalized': False, +# 'res_row': x, +# 'res_col': y, +# 'base_name': 'natural_movie_one_30fps_orig', +# 'n_trials': 1 +# }, +# open(os.path.join(config_dir, 'natural_movie_one.30s.30fps.304x608.orig.json'), 'w'), +# indent=2 +# ) + +# movie = data_set.get_stimulus_template('natural_movie_two') +# t, x, y = movie.shape +# movie_name = 'natural_movie_two.30s.30fps.304x608.orig.npy' +# movie_path = os.path.join(output_dir, movie_name) +# np.save(movie_path, movie) +# if create_config: +# json.dump( +# { +# 'movie_file': movie_path, +# 'fps': 30, +# 'duration': t / 30.0, +# 'gray_screen': 0.0, +# 'output_dir': os.path.join('results_lgnmodel', 'output_natural_movie_two_30fps_orig'), +# 'force_overwrite': True, +# 'normalized': False, +# 'res_row': x, +# 'res_col': y, +# 'base_name': 'natural_movie_two_30fps_orig', +# 'n_trials': 1 +# }, +# open(os.path.join(config_dir, 'natural_movie_two.30s.30fps.304x608.orig.json'), 'w'), +# indent=2 +# ) + +# data_set = boc.get_ophys_experiment_data(649409874) +# movie = data_set.get_stimulus_template('natural_movie_three') +# t, x, y = movie.shape +# movie_name = 'natural_movie_three.30s.30fps.304x608.orig.npy' +# movie_path = os.path.join(output_dir, movie_name) +# np.save(movie_path, movie) +# if create_config: +# json.dump( +# { +# 'movie_file': movie_path, +# 'fps': 30, +# 'duration': t / 30.0, +# 'gray_screen': 0.0, +# 'output_dir': os.path.join('results_lgnmodel', 'output_natural_movie_three_30fps_orig'), +# 'force_overwrite': True, +# 'normalized': False, +# 'res_row': x, +# 'res_col': y, +# 'base_name': 'natural_movie_three_30fps_orig', +# 'n_trials': 1 +# }, +# open(os.path.join(config_dir, 'natural_movie_three.120s.30fps.304x608.orig.json'), 'w'), +# indent=2 +# ) + + +# def convert_movies(output_dir='movies', movie_name='natural_movie_one'): +# movie_path = '{}.{}s.30fps.304x608.orig.npy'.format(movie_name, '120' if movie_name.endswith('three') else '30') +# m_data = np.load(os.path.join(output_dir, movie_path)) # .astype(np.float) + +# movie_updated = np.full((int(30 * 3.5), 304, 608), fill_value=127, dtype=np.uint8) +# movie_updated[15:, :, :] = m_data[:30 * 3, :, :] +# movie_updated_path = '{}.3s_gs.30fps.304x608.orig.npy'.format(movie_name) +# np.save(os.path.join(output_dir, movie_updated_path), movie_updated) + +# movie_norm = np.zeros((int(30 * 3.5), 304, 608)) +# movie_norm[15:, :, :] = (m_data[:30 * 3, :, :] * 2.0) / 255.0 - 1.0 +# movie_norm_path = '{}.3s_gs.30fps.304x608.normalized.npy'.format(movie_name) +# np.save(os.path.join(output_dir, movie_norm_path), movie_norm) + + +# def upscale_movie(output_dir='movies', movie_name='natural_movie_one', fps=1000): +# movie_path = '{}.{}s.30fps.304x608.orig.npy'.format(movie_name, '120' if movie_name.endswith('three') else '30') +# m_data = np.load(os.path.join(output_dir, movie_path)) +# m_data = m_data[:(30 * 3), :, :] +# m_data = m_data.repeat(34, axis=0)[:(fps * 3)] + +# movie_updated = np.full((int(fps * 3.5), 304, 608), fill_value=127, dtype=np.uint8) +# movie_updated[int(fps * 0.5):, :, :] = m_data[:(fps * 3), :, :] +# movie_updated_path = '{}.3s_gs.1000fps.304x608.orig.npy'.format(movie_name) +# np.save(os.path.join(output_dir, movie_updated_path), movie_updated) + +# movie_norm = np.zeros((int(fps * 3.5), 304, 608)) +# movie_norm[int(fps * 0.5):, :, :] = (m_data[:(fps * 3), :, :] * 2.0) / 255.0 - 1.0 +# movie_norm_path = '{}.3s_gs.1000fps.304x608.normalized.npy'.format(movie_name) +# np.save(os.path.join(output_dir, movie_norm_path), movie_norm) + + +def get_natural_scenes(output_dir='bob_images'): + """Fetches the 118 Brain Obs natural scene images from the data, saves them in npy format""" + logging.info(f'Saving "natural_scenes" grey-screen images to {output_dir}') + if not os.path.exists(output_dir): + os.mkdir(output_dir) + + boc = BrainObservatoryCache(manifest_file='boc/manifest.json') + data_set = boc.get_ophys_experiment_data(501498760) + scenes = data_set.get_stimulus_template('natural_scenes') + + for i in range(0, len(scenes)): + scene = scenes[i] + base_name = os.path.join(output_dir, 'scene.{:03d}.gray_{}x{}'.format(i, scene.shape[0], scene.shape[1])) + file_name = f'{base_name}.png' + if not os.path.exists(file_name): + plt.imsave('{}.png'.format(base_name), scene, cmap='gray') + np.save('{}.npy'.format(base_name), scene) + + +def create_ns_movie(n_images=118, ips=10, fps=1000.0, res_row=120, res_col=240, gs_pre=500, gs_post=100, rng_seed=None, + images_dir='bob_images', output_dir='movies', movie_file=None, overwrite=True, normalize=False): + frames_per_image = int(float(fps) / ips) # num of frames that will be given to each image + frames_per_gs_pre = int(gs_pre / 1000.0 * fps) # num frames for initial gray screen + frames_per_gs_post = int(gs_post / 1000.0 * fps) # num frames for ending gray screen + n_frames = frames_per_gs_pre + frames_per_image*n_images + frames_per_gs_post + set_num = '{:02d}'.format(0) + total_time = n_frames/float(fps)*1000.0 + + # Find the movie path, make sure not to overwrite existing movie files + if not os.path.exists(output_dir): + os.mkdir(output_dir) + + if movie_file is not None: + movie_path = movie_file if os.path.isabs(movie_file) else os.path.join(output_dir, movie_file) + else: + movie_path = os.path.join(output_dir, 'ns_{}images.set{}.{}ms.{}fps.{}ips{}.npy'.format( + n_images, set_num, int(total_time), int(fps), int(ips), '.normalized' if normalize else '' + )) + + if not overwrite and os.path.exists(movie_path): + for i in range(1, 100): + set_num = '{:02d}'.format(i) + movie_path = 'movies/ns_{}images.set{}.{}ms.{}fps.{}ips{}.npy'.format( + n_images, set_num, int(total_time), int(fps), int(ips), '.normalized' if normalize else '' + ) + if not os.path.exists(movie_path): + break + else: + raise ValueError('Could not create valid movie path.') + + + # Keep track of the order and placement of the images, metadata will be written to csv + csv_path = movie_path[:-4] + '.metadata.csv' + img_names = [] + frames_ids = [] + image_times = [] + + if frames_per_gs_pre > 0: + img_names.append('grayscreen') + frames_ids.append((0, frames_per_gs_pre)) + image_times.append((0, frames_per_gs_pre/float(fps))) + + output_mat = np.zeros((n_frames, res_row, res_col), dtype=float if normalize else np.uint8) + mat_beg = frames_per_gs_pre + if rng_seed: + np.random.seed(rng_seed) + images_perm = np.random.permutation(range(n_images)) + for image_num, image_id in enumerate(images_perm): + # Find the image and convert to a 120x240 matrix + # img_path = movie_jpegs[i] + img_path = os.path.join(images_dir, 'scene.{:03d}.gray_918x1174.png'.format(image_id)) + pic = Image.open(img_path).convert('L') + pic = pic.resize((res_col, res_row)) # PIL the row/col order is swapped + pic_data = np.asarray(pic) + if normalize: + pic_data = pic_data.astype(dtype=float) * 2.0 / 255.0 - 1.0 + + mat_end = mat_beg + frames_per_image + output_mat[mat_beg:mat_end, :, :] = pic_data + + # keep track of metadata + img_names.append(img_path[len(images_dir)+1:]) + frames_ids.append((mat_beg, mat_end)) + image_times.append((mat_beg/float(fps), mat_end/float(fps))) + + mat_beg = mat_end + + np.save(movie_path, output_mat) + + if frames_per_gs_post > 0: + img_names.append('grayscreen') + f_beg = n_frames - frames_per_gs_post + f_end = n_frames + frames_ids.append((f_beg, f_end)) + image_times.append((f_beg/float(fps), f_end/float(fps))) + + pd.DataFrame({ + 'image_id': img_names, + 'begin_frame': [f[0] for f in frames_ids], + 'end_frame': [f[1] for f in frames_ids], + 'begin_time': [t[0] for t in image_times], + 'end_time': [t[1] for t in image_times] + }).to_csv(csv_path, sep=' ', index=False) + + +def check_movie(movie_file, frames=None): + movie_array = np.load(movie_file) + logging.info(f'Movie {movie_file} has dimensions {movie_array.shape} and data-type {movie_array.dtype}.') + + if movie_array.dtype in [np.float64, float]: + vmin, vmax = -1.0, 1.0 + else: + vmin, vmax = 0, 256 + + if frames is None: + frames = np.linspace(0, movie_array.shape[0]-1, 5).astype(int) + + fig, axes = plt.subplots(1, len(frames), figsize=(16, 5)) + for idx, frame_num in enumerate(frames): + axes[idx].imshow(movie_array[frame_num, :, :], cmap='gray', vmin=vmin, vmax=vmax) + axes[idx].set_title(f'frame #{frame_num}', fontsize='xx-small') + axes[idx].get_yaxis().set_visible(False) + + plt.show() + + +def create_gray_screen_movie(grey_screen_time, output_dir='movies', movie_file=None, fps=1000.0, res_row=120, + res_col=240, normalize=False): + """Creates grey-screen for BOb natural scene images""" + n_frames = int(grey_screen_time*fps/1000.0) + + if movie_file is not None: + movie_path = movie_file if os.path.isabs(movie_file) else os.path.join(output_dir, movie_file) + else: + movie_path = os.path.join( + output_dir, + 'grey_screen.{}ms.{}fps{}.npy'.format(grey_screen_time, int(fps), '.normalized' if normalize else '') + ) + + if not os.path.exists(output_dir): + os.mkdir(output_dir) + + if normalize: + gs_mat = np.full((n_frames, res_row, res_col), fill_value=0.0, dtype=float) + else: + gs_mat = np.full((n_frames, res_row, res_col), fill_value=127, dtype=np.uint8) + + np.save(movie_path, gs_mat) + + +def get_touchofevil_movies(output_dir='movies', res_row=120, res_col=240, fps=1000, normalize=False): + frame_conv = int(np.floor(fps/30.0)) + def convert_movie(name, movie): + t, x, y = movie.shape + n_frames = frame_conv * t + movie_updated = np.zeros((n_frames, res_row, res_col), dtype=np.uint8) + c_frame = 0 + for frame in range(t): + # Resize resolution + img = Image.fromarray(movie[frame, :, :], mode='L') + img = img.resize((res_col, res_row)) + img_data = np.asarray(img) + if normalize: + img_data = img_data.astype(dtype=float) * 2.0 / 255.0 - 1.0 + + # Upscale frame rate + movie_updated[c_frame:(c_frame + frame_conv), :, :] = img_data + c_frame += frame_conv + + np.save('{}/{}.{}ms.{}x{}{}.npy'.format(output_dir, name, c_frame, res_row, res_col, '.normalize' if normalize else ''), movie_updated) + + boc = BrainObservatoryCache(manifest_file='boc/manifest.json') + data_set = boc.get_ophys_experiment_data(506248008) + movie = data_set.get_stimulus_template('natural_movie_one') + convert_movie('natural_movie_one', movie) + + movie = data_set.get_stimulus_template('natural_movie_two') + convert_movie('natural_movie_two', movie) + + data_set = boc.get_ophys_experiment_data(649409874) + movie = data_set.get_stimulus_template('natural_movie_three') + convert_movie('natural_movie_three', movie) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Generate a movie from Allen Brain Observatory Data.') + parser.add_argument('movie_type', type=str, nargs=1, choices=['grey-screen', 'natural-scenes', 'touch-of-evil', 'natural-movies', 'check'], + help='Options: grey-screen, natural-scenes, touch-of-evil, natural-movies') + parser.add_argument('--bob-images-dir', type=str, nargs=1, default='bob_images', help='Directory where Natural Scene image files will be stored.') + parser.add_argument('--n-images', type=int, nargs='?', default=118, help='Number of natural-scenes to use (118 unique available).') + parser.add_argument('--images-per-sec', type=int, nargs='?', default=4, help='Number of unique images to show each second') + parser.add_argument('--greyscreen-pre', type=int, nargs='?', default=500, help='Adds a grey-screen to beginning of movie, in ms.') + parser.add_argument('--greyscreen-post', type=int, nargs='?', default=0, help='Adds a grey-screen to end of movie, in ms.') + parser.add_argument('--greyscreen-time', type=float, nargs='?', default=2000, help='Time, in ms, for a grey-screen movie.') + + parser.add_argument('--fps', type=float, nargs='?', default=1000., help='Frames-per-second of movie.') + parser.add_argument('--res-row', type=int, nargs='?', default=120, help='Resolution of the number of rows (x) of movie.') + parser.add_argument('--res-col', type=int, nargs='?', default=240, help='Resolution of the number of columns (y) of movie.') + parser.add_argument('--rng-seed', type=int, nargs='?', default=None, help='Random seed number, used by natural-scenes for determining order.') + parser.add_argument('--movies-dir', type=str, nargs='?', default='movies', help='Directory where movie will be saved too.') + parser.add_argument('--movie-path', type=str, nargs='?', default=None, help='Specify the npy filename of the generated movie. By default will be autogenerated.') + parser.add_argument('--normalize', action='store_true', help='If flag is turned on the movie file will having floating-point values between (-1.0, +1.0). Otherwise movie will be an integer matrix with values [0, 255].') + args = parser.parse_args() + + + logging.basicConfig(level=logging.INFO, format='%(asctime)s: %(message)s') + + movie_type = args.movie_type[0] + if movie_type == 'natural-scenes': + get_natural_scenes(output_dir=args.bob_images_dir) + + create_ns_movie( + n_images=args.n_images, + ips=args.images_per_sec, + fps=args.fps, + res_row=args.res_row, + res_col=args.res_col, + gs_pre=args.greyscreen_pre, + gs_post=args.greyscreen_post, + rng_seed=args.rng_seed, + images_dir=args.bob_images_dir, + output_dir=args.movies_dir, + overwrite=True, + normalize=args.normalize + ) + elif movie_type == 'grey-screen': + create_gray_screen_movie( + grey_screen_time=args.greyscreen_time, + output_dir=args.movies_dir, + movie_file=args.movie_path, + fps=args.fps, + res_row=args.res_row, + res_col=args.res_col, + normalize=args.normalize + ) + elif movie_type in ['natural-movies', 'touch-of-evil']: + get_touchofevil_movies( + output_dir=args.movies_dir, + res_row=args.res_row, + res_col=args.res_col, + fps=args.fps, + normalize=args.normalize + ) + + elif movie_type == 'check': + check_movie(args.movie_path) + + + + exit() + + + # Get Bob images, create grey-screen, and create movie from natural scenes + get_natural_scenes() + # create_gray_screen() + # create_ns_movie(n_images=118, fps=1000.0, create_config=True, normalize=True) + # create_ns_movie(ips=4, overwrite=False) + create_ns_movie(n, ips=4, overwrite=False) + + # get_touchofevil_movies() + + # check_movie('natural_scenes_full_00/movie_natural_scenes.60fps.918x1174.npy') + # get_natural_movies() + # a = np.array([[2, 4, 6, 8], [2, 4, 6, 8]]) + # print(a) + # print(a.repeat(3, axis=1)) + # exit() + + # natural_movie_1000Hz_gs() + + # get_movies() + # convert_movies(movie_name='natural_movie_one') + # upscale_movie(movie_name='natural_movie_one') + # convert_movies(movie_name='natural_movie_three') + # upscale_movie(movie_name='natural_movie_three') + # convert_movies(movie_name='natural_movie_two') + # upscale_movie(movie_name='natural_movie_two') + diff --git a/examples/filter_movie/network/lgn_node_types.csv b/examples/filter_movie/network/lgn_node_types.csv index 886e206c..a8cc86ab 100644 --- a/examples/filter_movie/network/lgn_node_types.csv +++ b/examples/filter_movie/network/lgn_node_types.csv @@ -1,2 +1,4 @@ -node_type_id dynamics_params sigma_off model_template model_type ei sigma_on -100 lgn_on_off_model.json "(4.0, 4.0)" lgnmodel:LGNOnOFFCell virtual e "(2.0, 2.0)" +node_type_id ei dynamics_params model_type non_dom_params sf_sep model_template +100 e tOFF_TF15_3.44215357_-2.11509939_8.27421573_20.0_0.0_ic.json virtual lgnmodel:tOFF_TF15 +101 e sOFF_TF4_3.5_-2.0_10.0_60.0_15.0_ic.json virtual sON_TF4_3.5_-2.0_30.0_60.0_25.0_ic.json 6.0 lgnmodel:sONsOFF_001 +102 e tOFF_TF8_4.222_-2.404_8.545_23.019_0.0_ic.json virtual sON_TF4_3.5_-2.0_30.0_60.0_25.0_ic.json 4.0 lgnmodel:sONtOFF_001 diff --git a/examples/filter_movie/network/lgn_nodes.h5 b/examples/filter_movie/network/lgn_nodes.h5 index b0ac5327b99dd3812a441504ff1d7586dc7b152e..2b1d6b9c05793660ec2254a4ab6072092af20350 100644 GIT binary patch literal 26259 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