diff --git a/__pycache__/utils.cpython-310.pyc b/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000..ca48001 Binary files /dev/null and b/__pycache__/utils.cpython-310.pyc differ diff --git a/__pycache__/utils.cpython-312.pyc b/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000..92f7f8f Binary files /dev/null and b/__pycache__/utils.cpython-312.pyc differ diff --git a/calculate_psths.py b/calculate_psths.py deleted file mode 100644 index 5205bc6..0000000 --- a/calculate_psths.py +++ /dev/null @@ -1,138 +0,0 @@ - -# %% Script Parameters - -url = 'https://uni-bonn.sciebo.de/s/oTfGigwXQ4g0raW' -filename = 'data.nc' - -# %% Download Data -# Exercise (Example): Make a download_data(url, filename) function: - -def download_data(url, filename): - from pathlib import Path - import owncloud - - client = owncloud.Client.from_public_link(url) - client.get_file('/', filename) - - if Path(filename).exists(): - print('Download Succeeded.') - - return None - - -download_data(url=url, filename=filename) - -# %% Load Data -# Exercise: Make a `load_data(filename)` function, returning the `dset` variable. - - - -# %% Extract Experiment-Level Data -# Exercise: Make an `extract_trials(filename)` function, returning the `trials` variable. - -import xarray as xr - -dset = xr.load_dataset(filename) -trials = dset[['contrast_left', 'contrast_right', 'stim_onset']].to_dataframe() -trials - -# %% Extract Spike-Time Data -# Exercise: Make an `extract_spikes(filename)` function, returning the `spikes` variable. - -import xarray as xr - -dset = xr.load_dataset(filename) -spikes = dset[['spike_trial', 'spike_cell', 'spike_time']].to_dataframe() -spikes - - -# %% Extract Cell-Level Data -# Exercise: Make an `extract_cells(filename)` function, returning the `cells` variable. - -import xarray as xr - -dset = xr.load_dataset(filename) -cells = dset['brain_groups'].to_dataframe() -cells - -# %% Merge and Compress Extracted Data -# Exercise: Make a `merge_data(trials, cells, spikes)` function, returning the `merged` variable. - -import pandas as pd -merged = pd.merge(left=cells, left_index=True, right=spikes, right_on='spike_cell') -merged = pd.merge(left=trials, right=merged, left_index=True, right_on='spike_trial').reset_index(drop=True) -merged.columns -merged = (merged - .rename(columns=dict( - brain_groups="brain_area", - spike_trial="trial_id", - spike_cell="cell_id", - spike_time="time" - )) - [[ - 'trial_id', - 'contrast_left', - 'contrast_right', - 'stim_onset', - 'cell_id', - 'brain_area', - 'time' - ]] - .astype(dict( - brain_area = 'category', - )) - # -) -merged.info() - - -# %% Calculate Time Bins for PSTH -# Exercise: Make a `compute_time_bins(time, bin_interval)` function, returning the `time_bins` variable. - -import numpy as np -time = merged['time'] -time = np.round(time, decimals=6) # Round time to the nearest microsecond, to reduce floating point errors. -bin_interval = 0.05 -time_bins = np.floor(time /bin_interval) * bin_interval # Round down to the nearest time bin start -time_bins - - -# %% filter out stimuli with contrast on the right. -# No function needed here for this exercise. - -filtered = merged[merged['contrast_right'] == 0] -print(f"Filtered out {len(merged) - len(filtered)} ({len(filtered) / len(merged):.2%}) of spikes in dataset.") -filtered - -# %% Make PSTHs -# Exercise: Make a `compute_psths(data, time_bins)` function here, returning the `psth` variable. - -psth = ( - filtered - .groupby([time_bins, 'trial_id', 'contrast_left', 'cell_id', 'brain_area'], observed=True, ) - .size() - .rename('spike_count') - .reset_index() -) -psth -psth = ( - psth - .groupby(['time', 'contrast_left', 'brain_area'], observed=True) - .spike_count - .mean() - .rename('avg_spike_count') - .reset_index() -) -psth -psth['avg_spike_rate'] = psth['avg_spike_count'] * bin_interval -psth - - -# %% Plot PSTHs -# Make a `plot_psths(psth)` function here, returning the `g` variable. -import seaborn as sns -g = sns.FacetGrid(data=psth, col='brain_area', col_wrap=2) -g.map_dataframe(sns.lineplot, x='time', y='avg_spike_count', hue='contrast_left') -g.add_legend() -g.savefig('PSTHs.png') - diff --git a/exercise1.md b/docs/exercise1.md similarity index 100% rename from exercise1.md rename to docs/exercise1.md diff --git a/exercise2.md b/docs/exercise2.md similarity index 100% rename from exercise2.md rename to docs/exercise2.md diff --git a/environment.yaml b/environment.yaml deleted file mode 100644 index fdae823..0000000 Binary files a/environment.yaml and /dev/null differ diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..5020a6d Binary files /dev/null and b/environment.yml differ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..540db27 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,7 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "psth" +version = "0.0.1" \ No newline at end of file diff --git a/scripts/calculate_psths.py b/scripts/calculate_psths.py new file mode 100644 index 0000000..3e49b1b --- /dev/null +++ b/scripts/calculate_psths.py @@ -0,0 +1,104 @@ + +# %% Script Parameters +import xarray as xr +import pandas as pd +import numpy as np +import seaborn as sns +url = 'https://uni-bonn.sciebo.de/s/oTfGigwXQ4g0raW' +filename = 'data.nc' + +from psth import utils + + + + +#from netCDF4 import Dataset +# %% Download Data +# Exercise (Example): Make a download_data(url, filename) function: + + + + +utils.download_data(url=url, filename=filename) + +# %% Load Data +# Exercise: Make a `load_data(filename)` function, returning the `dset` variable. + + + + +dset=utils.load_data(filename) +print(type(dset)) + + + + + +# %% Extract Experiment-Level Data +# Exercise: Make an `extract_trials(filename)` function, returning the `trials` variable. + + + + + +trials = utils.extract_trials(dset) + +# %% Extract Spike-Time Data +# Exercise: Make an `extract_spikes(filename)` function, returning the `spikes` variable. + + + + +spikes = utils.extract_spikes(dset) + + +# %% Extract Cell-Level Data +# Exercise: Make an `extract_cells(filename)` function, returning the `cells` variable. + + + +cells = utils.extract_cells(dset) + +# %% Merge and Compress Extracted Data +# Exercise: Make a `merge_data(trials, cells, spikes)` function, returning the `merged` variable. + + + + + + + +merged= utils.merge_data(trials, cells, spikes) + + +# %% Calculate Time Bins for PSTH +# Exercise: Make a `compute_time_bins(time, bin_interval)` function, returning the `time_bins` variable. + + + +time_bins = utils.compute_time_bins(merged['time'], bin_interval=0.05) + +# %% filter out stimuli with contrast on the right. +# No function needed here for this exercise. + +filtered = merged[merged['contrast_right'] == 0] +print(f"Filtered out {len(merged) - len(filtered)} ({len(filtered) / len(merged):.2%}) of spikes in dataset.") +filtered + +# %% Make PSTHs +# Exercise: Make a `compute_psths(data, time_bins)` function here, returning the `psth` variable. +#data=filtered +import inspect + +psth = utils.compute_psths(filtered, time_bins, 0.05) +# %% Plot PSTHs +# Make a `plot_psths(psth)` function here, returning the `g` variable. + + + + + + +utils.plot_psths(psth) + +# %% diff --git a/src/psth/__init__.py b/src/psth/__init__.py new file mode 100644 index 0000000..9f9161b --- /dev/null +++ b/src/psth/__init__.py @@ -0,0 +1 @@ +from . import utils \ No newline at end of file diff --git a/src/psth/__pycache__/__init__.cpython-312.pyc b/src/psth/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..1fce065 Binary files /dev/null and b/src/psth/__pycache__/__init__.cpython-312.pyc differ diff --git a/src/psth/__pycache__/utils.cpython-312.pyc b/src/psth/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000..2c7e7ad Binary files /dev/null and b/src/psth/__pycache__/utils.cpython-312.pyc differ diff --git a/src/psth/utils.py b/src/psth/utils.py new file mode 100644 index 0000000..e6e36d7 --- /dev/null +++ b/src/psth/utils.py @@ -0,0 +1,101 @@ +import xarray as xr +import numpy as np +import pandas as pd +import seaborn as sns + +def download_data(url, filename): + from pathlib import Path + import owncloud + + client = owncloud.Client.from_public_link(url) + client.get_file('/', filename) + + if Path(filename).exists(): + print('Download Succeeded.') + + return None + +def load_data(filename): + dset=xr.open_dataset(filename) + return dset + + +def extract_trials(dset): + trials = dset[['contrast_left', 'contrast_right', 'stim_onset']].to_dataframe() + return trials + +def extract_spikes(dset): + spikes = dset[['spike_trial', 'spike_cell', 'spike_time']].to_dataframe() + return spikes + +def extract_cells(dset): + cells = dset['brain_groups'].to_dataframe() + return cells + + +def merge_data(trials, cells, spikes): + merged = pd.merge(left=cells, left_index=True, right=spikes, right_on='spike_cell') + merged = pd.merge(left=trials, right=merged, left_index=True, right_on='spike_trial').reset_index(drop=True) + merged.columns + merged = (merged + .rename(columns=dict( + brain_groups="brain_area", + spike_trial="trial_id", + spike_cell="cell_id", + spike_time="time" + )) + [[ + 'trial_id', + 'contrast_left', + 'contrast_right', + 'stim_onset', + 'cell_id', + 'brain_area', + 'time' + ]] + .astype(dict( + brain_area = 'category', + )) + # + ) + return merged + + +def compute_time_bins(time,bin_interval=0.05): + #time = merged['time'] + time = np.round(time, decimals=6) # Round time to the nearest microsecond, to reduce floating point errors. + + time_bins = np.floor(time /bin_interval) * bin_interval # Round down to the nearest time bin start + return time_bins + + +def compute_psths(data, time_bins, bin_interval): + psth = ( + data + .groupby([time_bins, 'trial_id', 'contrast_left', 'cell_id', 'brain_area'], observed=True, ) + .size() + .rename('spike_count') + .reset_index() + ) + psth + psth = ( + psth + .groupby(['time', 'contrast_left', 'brain_area'], observed=True) + .spike_count + .mean() + .rename('avg_spike_count') + .reset_index() + ) + psth + psth['avg_spike_rate'] = psth['avg_spike_count'] * bin_interval + return psth + + + +def plot_psths(psth): + + g = sns.FacetGrid(data=psth, col='brain_area', col_wrap=2) + g.map_dataframe(sns.lineplot, x='time', y='avg_spike_count', hue='contrast_left') + g.add_legend() + g.savefig('PSTHs.png') + return None