Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
Binary file added cleo/.DS_Store

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like other one above, shouldn't be committed

Binary file not shown.
6 changes: 3 additions & 3 deletions cleo/ephys/lfp.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these changes are not from your changes, but rather differences with master branch. Make sure to merge master into this branch to avoid stuff like this

Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ def connect_to_neuron_group(self, neuron_group: NeuronGroup, **kwparams):
self._init_wslfp_calc(neuron_group, **kwparams)

buf_len_ampa, buf_len_gaba = self._get_buf_lens_for_wslfp(
self._wslfps[neuron_group], **kwparams
self._wslfps[neuron_group]
)
self._t_ampa_bufs[neuron_group] = deque(maxlen=buf_len_ampa)
self._I_ampa_bufs[neuron_group] = deque(maxlen=buf_len_ampa)
Expand All @@ -633,8 +633,8 @@ def _get_buf_lens_for_wslfp(self, wslfp_calc, **kwparams):
try:
sample_period = self.probe.sim.io_processor.sample_period
except AttributeError: # probably means sim doesn't have io_processor
raise RuntimeError(
"RWSLFPSignalFromPSCs needs to know the sampling period."
raise Exception(
"RSWLFPSignalFromPSCs needs to know the sampling period."
" Either set the simulator's IO processor before injecting"
f" {self.probe.name} or "
f" specify it on injection: .inject({self.probe.name}"
Expand Down
20 changes: 8 additions & 12 deletions cleo/ephys/spiking.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here. your GECI code shouldn't affect any of this ephys code, so it's a red flag that there are changes here. Fix by git merge origin master

Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,6 @@ def connect_to_neuron_group(self, neuron_group: NeuronGroup, **kwparams):
# spike sorters don't sort by multi-channel recall; we only do this
# for computational efficiency, to not get super distant neurons

# needed even if no neurons are recorded
if not self._prev_t:
self._prev_t = self.probe.sim.network.t
if self._mu_eap is None:
self._mu_eap = np.zeros((0, self.n_channels))

n2keep = np.sum(where_to_keep)
if n2keep == 0:
warnings.warn(
Expand All @@ -277,8 +271,14 @@ def connect_to_neuron_group(self, neuron_group: NeuronGroup, **kwparams):
assert len(self.i_ng_by_i_probe) == i_probe_start
self.i_ng_by_i_probe.extend(list(zip([neuron_group] * n2keep, i2keep)))

if not self._prev_t:
self._prev_t = self.probe.sim.network.t

# store neuron-channel mean and stdev of EAPs to use in subclasses
self._mu_eap = np.concatenate((self._mu_eap, snr[where_to_keep]), axis=0)
if self._mu_eap is None:
self._mu_eap = snr[where_to_keep]
else:
self._mu_eap = np.concatenate((self._mu_eap, snr[where_to_keep]), axis=0)

return snr[where_to_keep].max(axis=1), new_i_probe

Expand Down Expand Up @@ -642,11 +642,7 @@ def sorted_units_snr(self) -> Float[np.ndarray, "{self.n_sorted}"]:
return self._mu_eap[self._i_probe_by_i_sorted]

def connect_to_neuron_group(self, neuron_group, **kwparams):
connect_result = super().connect_to_neuron_group(neuron_group, **kwparams)
if connect_result is None:
# No neurons with high-enough multi-channel recall to record
return
snr, i_probe = connect_result
snr, i_probe = super().connect_to_neuron_group(neuron_group, **kwparams)
n_recorded_ng = len(snr)
# filter by SNR (measured on peak channel)
above_cutoff = snr >= self.snr_cutoff
Expand Down
Binary file added cleo/imaging/.DS_Store
Binary file not shown.
44 changes: 18 additions & 26 deletions cleo/imaging/__init__.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's annoying to manually maintain the list of imports as opposed to a star import, but its necessary to make the package user-friendly for IDE auto-completion, etc.
https://share.gemini.google/emE6YjITX02y

Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
"""Contains Scope and sensors for two-photon microscopy"""
from cleo.imaging.scope import Scope, target_neurons_in_plane
from cleo.imaging.sensors import (
GECI,
CalBindingActivationModel,
CalciumModel,
DoubExpCalBindingActivation,
DynamicCalcium,
ExcitationModel,
LightExcitation,
NullBindingActivation,
NullExcitation,
PreexistingCalcium,
Sensor,
gcamp3,
gcamp6_rs06,
gcamp6_rs09,
gcamp6f,
gcamp6s,
geci,
jgcamp7b,
jgcamp7c,
jgcamp7f,
jgcamp7s,
ogb_1,
)
from cleo.imaging.sensors import *

try:
from cleo.imaging.sensors import (
gcamp3,
gcamp6s,
gcamp6f,
gcamp6_rs06,
gcamp6_rs09,
jGCaMP7s,
jGCaMP7f,
jGCaMP7b,
jGCaMP7c,
jRGECO1a,
ogb_1,
)
except ImportError:
pass
12 changes: 12 additions & 0 deletions cleo/imaging/gecis.csv

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure names are the way they are in literature (e.g., GCaMP3 instead of gcamp3). There is code that automatically turns those into names that are good for Python/Brian, called in _create_geci_fn()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the citation column used for? Why are they all Dana2019? There are at least 3 different papers we could cite here...where the GECI was originally presented, where we get params from, and where we get the excitation spectrum from

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does the excitation spectrum have a 1 at 488? That would be green, as in the emission, right? We need the wavelengths used to excite the indicator. Which would be infrared for 2p imaging. We should have the data we need with Zhang 2023, Extended Data Fig. 5c, gray line.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are the params for the imaging power-brightness curve? Also in Zhang 2023 Extended Data Fig. 5. Will need to fit for different GECIs. Where is the code Stefano used to do that? I thought he extracted data from those plots and fit those Hill function params. That definitely needs to be in notebooks/

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name,type,citation,notes,extra_doc,blank,K_d,n_H,dFF_max,sigma_noise_rel,dFF_1AP_rel,ca_amp,t_on,t_off,spectrum
gcamp3,GECI,Dana2019,,,"",345,2.4,11.8,1.2,0.3,0.05,20,200,"[(488, 1.0)]"
gcamp6s,GECI,Dana2019,,,"",144,2.9,28.8,1.0,1.0,0.1,50,400,"[(488, 1.0)]"
gcamp6f,GECI,Dana2019,,,"",375,2.3,28.2,1.1,0.7,0.1,20,150,"[(488, 1.0)]"
gcamp6_rs06,GECI,Dana2019,,,"",375,2.3,28.2,1.1,0.7,0.1,20,150,"[(488, 1.0)]"
gcamp6_rs09,GECI,Dana2019,,,"",375,2.3,28.2,1.1,0.7,0.1,20,150,"[(488, 1.0)]"
jGCaMP7s,GECI,Dana2019,,,"",144,2.9,28.8,1.0,1.0,0.1,50,400,"[(488, 1.0)]"
jGCaMP7f,GECI,Dana2019,,,"",375,2.3,28.2,1.1,0.7,0.1,20,150,"[(488, 1.0)]"
jGCaMP7b,GECI,Dana2019,,,"",375,2.3,28.2,1.1,0.7,0.1,20,150,"[(488, 1.0)]"
jGCaMP7c,GECI,Dana2019,,,"",375,2.3,28.2,1.1,0.7,0.1,20,150,"[(488, 1.0)]"
jRGECO1a,GECI,Dana2019,,,"",375,2.3,28.2,1.1,0.7,0.1,20,150,"[(561, 1.0)]"
ogb_1,GECI,Dana2019,,,"",205,1.0,14.0,1.0,1.0,0.1,50,400,"[(488, 1.0)]"
41 changes: 41 additions & 0 deletions cleo/imaging/run_network_sweep.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this isn't done, we wouldn't want to merge it into master yet. In any case, this would go somewhere else, probably notebooks.

Also, it's unclear what this is for...if it's to show how the GECI affects runtime, then why is there a sweep of stimulus intensities?

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import time
import numpy as np

# Simple template for benchmarking full network simulation sweeps
def benchmark_network_sweep():
# 1. Define the sweep range (e.g., light intensity in mW/mm^2 or pulse duration in ms)
stimulus_intensities = [0.1, 0.5, 1.0, 5.0, 10.0]

print("=" * 60)
print(" Starting Cleo Network Simulation Sweep Benchmark")
print("=" * 60)

results = {}

for intensity in stimulus_intensities:
print(f"\n[+] Running network simulation for Intensity = {intensity}...")

start_time = time.time()

# -------------------------------------------------------------
# TODO: Insert your Cleo network execution call here
# Example:
# sim.run(100 * ms)
# -------------------------------------------------------------

# Temporary placeholder delay to verify script structure
time.sleep(0.5)

elapsed_time = time.time() - start_time
results[intensity] = elapsed_time

print(f" -> Completed in {elapsed_time:.3f} seconds.")

print("\n" + "=" * 60)
print(" SWEEP BENCHMARK SUMMARY")
print("=" * 60)
for intensity, exec_time in results.items():
print(f" Intensity: {intensity:5.1f} | Execution Time: {exec_time:.3f} s")

if __name__ == "__main__":
benchmark_network_sweep()
Loading
Loading