From c5fc6aebe89376846ea0db04047f3684d9a87e9c Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Fri, 13 Sep 2024 16:22:58 -0400 Subject: [PATCH 1/4] change from proto to more standard implementation --- neuro_py/__init__.py | 21 +--- neuro_py/__init__.pyi | 27 ++++ neuro_py/behavior/__init__.py | 16 +-- neuro_py/behavior/__init__.pyi | 54 ++++++++ neuro_py/behavior/cheeseboard.py | 9 +- neuro_py/behavior/get_trials.py | 11 -- neuro_py/behavior/kinematics.py | 15 +-- neuro_py/behavior/linear_positions.py | 12 -- neuro_py/behavior/linearization_pipeline.py | 9 -- .../behavior/well_traversal_classification.py | 24 +--- neuro_py/ensemble/__init__.py | 14 +-- neuro_py/ensemble/__init__.pyi | 31 +++++ neuro_py/ensemble/assembly.py | 15 --- neuro_py/ensemble/assembly_reactivation.py | 92 -------------- neuro_py/ensemble/explained_variance.py | 10 +- neuro_py/ensemble/similarity_index.py | 13 +- neuro_py/ensemble/similaritymat.py | 9 -- neuro_py/io/__init__.py | 5 +- neuro_py/io/__init__.pyi | 71 +++++++++++ neuro_py/io/loading.py | 38 ------ neuro_py/io/saving.py | 16 +-- neuro_py/lfp/CSD.py | 35 +++--- neuro_py/lfp/__init__.py | 7 +- neuro_py/lfp/__init__.pyi | 21 ++++ neuro_py/lfp/preprocessing.py | 8 -- neuro_py/lfp/spectral.py | 8 -- neuro_py/lfp/theta_cycles.py | 13 +- neuro_py/plotting/__init__.py | 5 +- neuro_py/plotting/__init__.pyi | 23 ++++ neuro_py/plotting/events.py | 13 +- neuro_py/plotting/figure_helpers.py | 13 -- neuro_py/process/__init__.py | 18 +-- neuro_py/process/__init__.pyi | 115 ++++++++++++++++++ neuro_py/process/batch_analysis.py | 11 -- neuro_py/process/correlations.py | 12 -- neuro_py/process/intervals.py | 15 --- neuro_py/process/peri_event.py | 22 ---- neuro_py/process/precession_utils.py | 13 -- neuro_py/process/pychronux.py | 14 --- neuro_py/process/utils.py | 20 +-- neuro_py/session/__init__.py | 4 +- neuro_py/session/__init__.pyi | 19 +++ neuro_py/session/locate_epochs.py | 17 +-- neuro_py/spikes/__init__.py | 4 +- neuro_py/spikes/__init__.pyi | 13 ++ neuro_py/spikes/spike_tools.py | 22 +--- neuro_py/stats/__init__.py | 6 +- neuro_py/stats/__init__.pyi | 34 ++++++ neuro_py/stats/regression.py | 10 -- neuro_py/stats/stats.py | 24 +--- neuro_py/stats/system_identifier.py | 80 ++++++------ neuro_py/tuning/__init__.py | 5 +- neuro_py/tuning/__init__.pyi | 45 +++++++ neuro_py/tuning/fields.py | 25 ---- neuro_py/tuning/maps.py | 8 -- 55 files changed, 562 insertions(+), 652 deletions(-) create mode 100644 neuro_py/__init__.pyi create mode 100644 neuro_py/behavior/__init__.pyi create mode 100644 neuro_py/ensemble/__init__.pyi create mode 100644 neuro_py/io/__init__.pyi create mode 100644 neuro_py/lfp/__init__.pyi create mode 100644 neuro_py/plotting/__init__.pyi create mode 100644 neuro_py/process/__init__.pyi create mode 100644 neuro_py/session/__init__.pyi create mode 100644 neuro_py/spikes/__init__.pyi create mode 100644 neuro_py/stats/__init__.pyi create mode 100644 neuro_py/tuning/__init__.pyi diff --git a/neuro_py/__init__.py b/neuro_py/__init__.py index 76a7bce..e21bb75 100644 --- a/neuro_py/__init__.py +++ b/neuro_py/__init__.py @@ -1,20 +1,3 @@ -from lazy_loader import attach as _attach +import lazy_loader as lazy -_proto_all_ = [ - "behavior", - "ensemble", - "io", - "lfp", - "plotting", - "process", - "session", - "spikes", - "stats", - "tuning", -] - -__getattr__, __dir__, __all__ = _attach( - __name__, submodules=_proto_all_ -) - -del _attach +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/__init__.pyi b/neuro_py/__init__.pyi new file mode 100644 index 0000000..2937a9c --- /dev/null +++ b/neuro_py/__init__.pyi @@ -0,0 +1,27 @@ + +__all__ = [ + "behavior", + "ensemble", + "io", + "lfp", + "plotting", + "process", + "session", + "spikes", + "stats", + "tuning", +] + + +from . import ( + behavior, + ensemble, + io, + lfp, + plotting, + process, + session, + spikes, + stats, + tuning, +) \ No newline at end of file diff --git a/neuro_py/behavior/__init__.py b/neuro_py/behavior/__init__.py index d47b79a..e21bb75 100644 --- a/neuro_py/behavior/__init__.py +++ b/neuro_py/behavior/__init__.py @@ -1,15 +1,3 @@ -from . import cheeseboard -from . import get_trials -from . import linear_positions -from . import linearization_pipeline -from . import kinematics -from . import well_traversal_classification +import lazy_loader as lazy -__all__ = [ - "cheeseboard", - "get_trials", - "linear_positions", - "linearization_pipeline", - "kinematics", - "well_traversal_classification", -] +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/behavior/__init__.pyi b/neuro_py/behavior/__init__.pyi new file mode 100644 index 0000000..3e86acb --- /dev/null +++ b/neuro_py/behavior/__init__.pyi @@ -0,0 +1,54 @@ +__all__ = [ + "plot_grid_with_circle_and_random_dots", + "get_linear_maze_trials", + "get_t_maze_trials", + "get_w_maze_trials", + "get_cheeseboard_trials", + "get_openfield_trials", + "get_velocity", + "get_speed", + "linearize_position", + "find_laps", + "peakdetz", + "find_good_laps", + "get_linear_track_lap_epochs", + "find_good_lap_epochs", + "NodePicker", + "paired_distances", + "enter_exit_target", + "enter_exit_target_dio", + "shift_well_enters", + "segment_path", + "find_last_non_center_well", + "get_correct_inbound_outbound", + "score_inbound_outbound", +] + +from .cheeseboard import plot_grid_with_circle_and_random_dots +from .get_trials import ( + get_cheeseboard_trials, + get_linear_maze_trials, + get_openfield_trials, + get_t_maze_trials, + get_w_maze_trials, +) +from .kinematics import get_speed, get_velocity +from .linear_positions import ( + find_good_lap_epochs, + find_good_laps, + find_laps, + get_linear_track_lap_epochs, + linearize_position, + peakdetz, +) +from .linearization_pipeline import NodePicker +from .well_traversal_classification import ( + enter_exit_target, + enter_exit_target_dio, + find_last_non_center_well, + get_correct_inbound_outbound, + paired_distances, + score_inbound_outbound, + segment_path, + shift_well_enters, +) diff --git a/neuro_py/behavior/cheeseboard.py b/neuro_py/behavior/cheeseboard.py index faaa70f..9699872 100644 --- a/neuro_py/behavior/cheeseboard.py +++ b/neuro_py/behavior/cheeseboard.py @@ -1,14 +1,6 @@ import matplotlib.pyplot as plt import numpy as np -from lazy_loader import attach as _attach - -__all__ = ( - "plot_grid_with_circle_and_random_dots", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def plot_grid_with_circle_and_random_dots(): # Create a 15x15 grid of dots within the circle @@ -56,5 +48,6 @@ def plot_grid_with_circle_and_random_dots(): plt.axis("off") plt.show() + if __name__ == "__main__": plot_grid_with_circle_and_random_dots() diff --git a/neuro_py/behavior/get_trials.py b/neuro_py/behavior/get_trials.py index 3dbefdd..e9ca9da 100644 --- a/neuro_py/behavior/get_trials.py +++ b/neuro_py/behavior/get_trials.py @@ -5,23 +5,12 @@ import nelpy as nel import numpy as np import scipy.io as sio -from lazy_loader import attach as _attach from scipy.signal import medfilt from neuro_py.behavior import linear_positions, well_traversal_classification from neuro_py.io import loading from neuro_py.process.intervals import find_interval -__all__ = ( - "get_linear_maze_trials", - "get_t_maze_trials", - "get_w_maze_trials", - "get_cheeseboard_trials", - "get_openfield_trials", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - # linear track def get_linear_maze_trials(basepath, epoch_input=None): diff --git a/neuro_py/behavior/kinematics.py b/neuro_py/behavior/kinematics.py index 778c416..15938d7 100644 --- a/neuro_py/behavior/kinematics.py +++ b/neuro_py/behavior/kinematics.py @@ -2,22 +2,15 @@ from typing import Union -from lazy_loader import attach as _attach -__all__ = ( - "get_velocity", - "get_speed", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - - -def get_velocity(position:np.ndarray, time:Union[np.ndarray,None]=None) -> np.ndarray: +def get_velocity( + position: np.ndarray, time: Union[np.ndarray, None] = None +) -> np.ndarray: if time is None: time = np.arange(position.shape[0]) return np.gradient(position, time, axis=0) -def get_speed(position:np.ndarray, time:Union[np.ndarray,None]=None) -> np.ndarray: +def get_speed(position: np.ndarray, time: Union[np.ndarray, None] = None) -> np.ndarray: velocity = get_velocity(position, time=time) return np.sqrt(np.sum(velocity**2, axis=1)) diff --git a/neuro_py/behavior/linear_positions.py b/neuro_py/behavior/linear_positions.py index 47d0fba..787e1ec 100644 --- a/neuro_py/behavior/linear_positions.py +++ b/neuro_py/behavior/linear_positions.py @@ -3,20 +3,8 @@ import nelpy as nel import numpy as np import pandas as pd -from lazy_loader import attach as _attach from sklearn.decomposition import PCA -__all__ = ( - "linearize_position", - "find_laps", - "peakdetz", - "find_good_laps", - "get_linear_track_lap_epochs", - "find_good_lap_epochs", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def linearize_position(x, y): """ diff --git a/neuro_py/behavior/linearization_pipeline.py b/neuro_py/behavior/linearization_pipeline.py index fceb485..5985e8d 100644 --- a/neuro_py/behavior/linearization_pipeline.py +++ b/neuro_py/behavior/linearization_pipeline.py @@ -6,18 +6,9 @@ import matplotlib.pyplot as plt import numpy as np import pandas as pd -from lazy_loader import attach as _attach from scipy.io import loadmat, savemat from track_linearization import get_linearized_position, make_track_graph -__all__ = ( - "NodePicker", - "load_animal_behavior", - "load_epoch", - "run", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) - """ TODO: diff --git a/neuro_py/behavior/well_traversal_classification.py b/neuro_py/behavior/well_traversal_classification.py index 7756594..fe91dc5 100644 --- a/neuro_py/behavior/well_traversal_classification.py +++ b/neuro_py/behavior/well_traversal_classification.py @@ -2,24 +2,8 @@ import numpy as np import pandas as pd -from lazy_loader import attach as _attach from scipy.ndimage.measurements import label -__all__ = ( - "paired_distances", - "enter_exit_target", - "enter_exit_target_dio", - "shift_well_enters", - "segment_path", - "find_last_non_center_well", - "get_correct_inbound_outbound", - "score_inbound_outbound", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - -_WELL_NAMES = {1: "Center", 2: "Left", 3: "Right"} - def paired_distances(x, y): """Euclidean distance between x and y at each time point. @@ -88,9 +72,7 @@ def shift_well_enters(enter_exit): return shifted_enter_exit -def segment_path( - time, position, well_locations, max_distance_from_well=10 -): +def segment_path(time, position, well_locations, max_distance_from_well=10): """Label traversals between each well location. Parameters @@ -206,7 +188,9 @@ def get_correct_inbound_outbound(segments_df): def score_inbound_outbound( - segments_df, min_distance_traveled=50, well_names=_WELL_NAMES + segments_df, + min_distance_traveled=50, + well_names={1: "Center", 2: "Left", 3: "Right"}, ): """In the alternating arm task, determines whether the trial should be inbound (running to the center arm) or outbound (running to the opposite diff --git a/neuro_py/ensemble/__init__.py b/neuro_py/ensemble/__init__.py index 9d3175d..e21bb75 100644 --- a/neuro_py/ensemble/__init__.py +++ b/neuro_py/ensemble/__init__.py @@ -1,13 +1,3 @@ -from . import assembly_reactivation -from . import assembly -from . import explained_variance -from . import similarity_index -from . import similaritymat +import lazy_loader as lazy -__all__ = [ - "assembly_reactivation", - "assembly", - "explained_variance", - "similarity_index", - "similaritymat", -] +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/ensemble/__init__.pyi b/neuro_py/ensemble/__init__.pyi new file mode 100644 index 0000000..37e712b --- /dev/null +++ b/neuro_py/ensemble/__init__.pyi @@ -0,0 +1,31 @@ +__all__ = [ + "toyExample", + "marcenkopastur", + "getlambdacontrol", + "binshuffling", + "circshuffling", + "runSignificance", + "extractPatterns", + "runPatterns", + "computeAssemblyActivity", + "AssemblyReact", + "ExplainedVariance", + "similarity_index", + "similaritymat", +] + +from .assembly import ( + binshuffling, + circshuffling, + computeAssemblyActivity, + extractPatterns, + getlambdacontrol, + marcenkopastur, + runPatterns, + runSignificance, + toyExample, +) +from .assembly_reactivation import AssemblyReact +from .explained_variance import ExplainedVariance +from .similarity_index import similarity_index +from .similaritymat import similaritymat diff --git a/neuro_py/ensemble/assembly.py b/neuro_py/ensemble/assembly.py index fd60ad4..4e7fc3f 100644 --- a/neuro_py/ensemble/assembly.py +++ b/neuro_py/ensemble/assembly.py @@ -9,24 +9,9 @@ from typing import Tuple, Union import numpy as np -from lazy_loader import attach as _attach from scipy import stats from sklearn.decomposition import PCA, FastICA -__all__ = ( - "toyExample", - "ToyAssemblies", - "marcenkopastur", - "getlambdacontrol", - "binshuffling", - "circshuffling", - "runSignificance", - "extractPatterns", - "runPatterns", - "computeAssemblyActivity", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach __author__ = "VĂ­tor Lopes dos Santos" __version__ = "2019.1" diff --git a/neuro_py/ensemble/assembly_reactivation.py b/neuro_py/ensemble/assembly_reactivation.py index d80d60d..13c94fb 100644 --- a/neuro_py/ensemble/assembly_reactivation.py +++ b/neuro_py/ensemble/assembly_reactivation.py @@ -6,16 +6,12 @@ import nelpy as nel import numpy as np import seaborn as sns -from lazy_loader import attach as _attach from scipy import stats from neuro_py.ensemble import assembly from neuro_py.io import loading from neuro_py.session.locate_epochs import compress_repeated_epochs, find_pre_task_post -__all__ = ("AssemblyReact",) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach logging.getLogger().setLevel(logging.ERROR) @@ -451,91 +447,3 @@ def Otsu(vector: np.ndarray) -> Tuple[np.ndarray, float, float]: self.valid_assembly = np.array(keep_assembly) return self.assembly_members - - -# def get_peak_activity(assembly_act, epochs): -# """ -# Gets the peak activity of the assembly activity -# """ -# strengths = [] -# assembly_id = [] -# centers = [] -# for assembly_act, ep in zip(assembly_act[epochs], epochs): -# strengths.append(assembly_act.max()) -# assembly_id.append(np.arange(assembly_act.n_signals)) -# centers.append(np.tile(ep.centers, assembly_act.n_signals)) - -# return np.hstack(assembly_id), np.hstack(strengths), np.hstack(centers) - - -# def get_pre_post_assembly_strengths(basepath): -# """ -# Gets the pre and post assembly strengths -# """ -# # initialize session -# m1 = AssemblyReact(basepath, weight_dt=0.025) -# # load data -# m1.load_data() -# # check if no cells were found -# if m1.cell_metrics.shape[0] == 0: -# return None -# # restrict to pre/task/post epochs -# m1.restrict_epochs_to_pre_task_post() -# # get weights for task outside ripples -# # % (TODO: use more robust method to locate epochs than index) -# m1.get_weights(m1.epochs[1][~m1.ripples]) - -# # get assembly activity -# assembly_act_pre = m1.get_assembly_act(epoch=m1.ripples[m1.epochs[0]]) -# assembly_act_task = m1.get_assembly_act(epoch=m1.ripples[m1.epochs[1]]) -# assembly_act_post = m1.get_assembly_act(epoch=m1.ripples[m1.epochs[2]]) -# results = { -# "assembly_act_pre": assembly_act_pre, -# "assembly_act_task": assembly_act_task, -# "assembly_act_post": assembly_act_post, -# "react": m1, -# } - -# return results - - -# def session_loop(basepath, save_path): -# save_file = os.path.join( -# save_path, basepath.replace(os.sep, "_").replace(":", "_") + ".pkl" -# ) -# if os.path.exists(save_file): -# return -# results = get_pre_post_assembly_strengths(basepath) -# # save file -# with open(save_file, "wb") as f: -# pickle.dump(results, f) - - -# def run(df, save_path, parallel=True): -# # find sessions to run -# basepaths = pd.unique(df.basepath) - -# if not os.path.exists(save_path): -# os.mkdir(save_path) - -# if parallel: -# num_cores = multiprocessing.cpu_count() -# processed_list = Parallel(n_jobs=num_cores)( -# delayed(session_loop)(basepath, save_path) for basepath in basepaths -# ) -# else: -# for basepath in basepaths: -# print(basepath) -# session_loop(basepath, save_path) - - -# def load_results(save_path): -# sessions = glob.glob(save_path + os.sep + "*.pkl") -# all_results = {} -# for session in sessions: -# with open(session, "rb") as f: -# results = pickle.load(f) -# if results is None: -# continue -# all_results[results["react"].basepath] = results -# return all_results diff --git a/neuro_py/ensemble/explained_variance.py b/neuro_py/ensemble/explained_variance.py index c0268df..64dad2d 100644 --- a/neuro_py/ensemble/explained_variance.py +++ b/neuro_py/ensemble/explained_variance.py @@ -2,17 +2,11 @@ import numpy as np -from lazy_loader import attach as _attach from nelpy.core._eventarray import SpikeTrainArray from nelpy.core._intervalarray import EpochArray from nelpy.core._analogsignalarray import AnalogSignalArray from numba import jit -__all__ = ( - "ExplainedVariance", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach warnings.simplefilter(action="ignore", category=FutureWarning) warnings.simplefilter(action="ignore", category=RuntimeWarning) @@ -326,7 +320,7 @@ def ev_signal(self): data=self.ev, timestamps=self.matching_time, fs=1 / np.diff(self.matching_time)[0], - support=EpochArray(data=[self.matching.start, self.matching.stop]) + support=EpochArray(data=[self.matching.start, self.matching.stop]), ) @property @@ -336,7 +330,7 @@ def rev_signal(self): data=self.rev, timestamps=self.matching_time, fs=1 / np.diff(self.matching_time)[0], - support=EpochArray(data=[self.matching.start, self.matching.stop]) + support=EpochArray(data=[self.matching.start, self.matching.stop]), ) def pvalue(self, n_shuffles=1000): diff --git a/neuro_py/ensemble/similarity_index.py b/neuro_py/ensemble/similarity_index.py index d9f5ef7..7aa38fb 100644 --- a/neuro_py/ensemble/similarity_index.py +++ b/neuro_py/ensemble/similarity_index.py @@ -2,19 +2,10 @@ import multiprocessing import numpy as np - from joblib import Parallel, delayed -from lazy_loader import attach as _attach - from neuro_py.stats.stats import get_significant_events -__all__ = ( - "similarity_index", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def similarity_index(patterns, n_shuffles=1000, parallel=True): """ @@ -50,7 +41,7 @@ def shuffle_patterns(patterns): return np.random.permutation(patterns.flatten()).reshape(patterns.shape) # calculate absolute inner product between patterns - def get_si(patterns,return_combo=False): + def get_si(patterns, return_combo=False): x = np.arange(0, patterns.shape[0]) # use itertools to get all combinations of patterns combos = np.array(list(itertools.combinations(x, 2))) @@ -64,7 +55,7 @@ def get_si(patterns,return_combo=False): return np.array(si) # calculate observed si - si, combos = get_si(patterns,return_combo=True) + si, combos = get_si(patterns, return_combo=True) # shuffle patterns and calculate si if parallel: diff --git a/neuro_py/ensemble/similaritymat.py b/neuro_py/ensemble/similaritymat.py index 38eee83..5853119 100644 --- a/neuro_py/ensemble/similaritymat.py +++ b/neuro_py/ensemble/similaritymat.py @@ -1,17 +1,8 @@ import numpy as np - -from lazy_loader import attach as _attach from sklearn.metrics.pairwise import cosine_similarity as getsim -__all__ = ( - "similaritymat", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def similaritymat(patternsX, patternsY=None, method="cosine", findpairs=False): - """ INPUTS diff --git a/neuro_py/io/__init__.py b/neuro_py/io/__init__.py index 7220a97..e21bb75 100644 --- a/neuro_py/io/__init__.py +++ b/neuro_py/io/__init__.py @@ -1,4 +1,3 @@ -from . import loading -from . import saving +import lazy_loader as lazy -__all__ = ["loading", "saving"] +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/io/__init__.pyi b/neuro_py/io/__init__.pyi new file mode 100644 index 0000000..22edc02 --- /dev/null +++ b/neuro_py/io/__init__.pyi @@ -0,0 +1,71 @@ +__all__ = ( + "loadXML", + "loadLFP", + "LFPLoader", + "load_position", + "writeNeuroscopeEvents", + "load_all_cell_metrics", + "load_cell_metrics", + "load_SWRunitMetrics", + "add_manual_events", + "load_ripples_events", + "load_theta_cycles", + "load_barrage_events", + "load_ied_events", + "load_dentate_spikes", + "load_theta_rem_shift", + "load_SleepState_states", + "load_animal_behavior", + "load_epoch", + "load_trials", + "load_brain_regions", + "get_animal_id", + "add_animal_id", + "load_basic_data", + "load_spikes", + "load_deepSuperficialfromRipple", + "load_mua_events", + "load_manipulation", + "load_channel_tags", + "load_extracellular_metadata", + "load_probe_layout", + "load_emg", + "load_events", + "epoch_to_mat", +) + +from .loading import ( + LFPLoader, + add_animal_id, + add_manual_events, + get_animal_id, + load_all_cell_metrics, + load_animal_behavior, + load_barrage_events, + load_basic_data, + load_brain_regions, + load_cell_metrics, + load_channel_tags, + load_deepSuperficialfromRipple, + load_dentate_spikes, + load_emg, + load_epoch, + load_events, + load_extracellular_metadata, + load_ied_events, + load_manipulation, + load_mua_events, + load_position, + load_probe_layout, + load_ripples_events, + load_SleepState_states, + load_spikes, + load_SWRunitMetrics, + load_theta_cycles, + load_theta_rem_shift, + load_trials, + loadLFP, + loadXML, + writeNeuroscopeEvents, +) +from .saving import epoch_to_mat diff --git a/neuro_py/io/loading.py b/neuro_py/io/loading.py index 98f96e1..5ef6ab1 100644 --- a/neuro_py/io/loading.py +++ b/neuro_py/io/loading.py @@ -14,50 +14,12 @@ import pandas as pd import scipy.io as sio from joblib import Parallel, delayed -from lazy_loader import attach as _attach from scipy import signal from neuro_py.behavior.kinematics import get_speed from neuro_py.process.intervals import find_interval, in_intervals from neuro_py.process.peri_event import get_participation -__all__ = ( - "loadXML", - "loadLFP", - "LFPLoader", - "load_position", - "writeNeuroscopeEvents", - "load_all_cell_metrics", - "load_cell_metrics", - "load_SWRunitMetrics", - "add_manual_events", - "load_ripples_events", - "load_theta_cycles", - "load_barrage_events", - "load_ied_events", - "load_dentate_spikes", - "load_theta_rem_shift", - "load_SleepState_states", - "load_animal_behavior", - "load_epoch", - "load_trials", - "load_brain_regions", - "get_animal_id", - "add_animal_id", - "load_basic_data", - "load_spikes", - "load_deepSuperficialfromRipple", - "load_mua_events", - "load_manipulation", - "load_channel_tags", - "load_extracellular_metadata", - "load_probe_layout", - "load_emg", - "load_events", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - simplefilter(action="ignore", category=pd.errors.PerformanceWarning) diff --git a/neuro_py/io/saving.py b/neuro_py/io/saving.py index fa72fea..ac12bf0 100644 --- a/neuro_py/io/saving.py +++ b/neuro_py/io/saving.py @@ -1,20 +1,12 @@ """ Loading functions for cell explorer format""" + import os +from typing import Union import nelpy as nel import numpy as np - -from typing import Union - -from lazy_loader import attach as _attach from scipy.io import savemat -__all__ = ( - "epoch_to_mat", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def epoch_to_mat( epoch: nel.EpochArray, @@ -49,7 +41,7 @@ def epoch_to_mat( data[epoch_name]["peaks"] = np.median(epoch.data, axis=0) else: data[epoch_name]["peaks"] = np.median(epoch.data, axis=1) - + data[epoch_name]["amplitudes"] = [] data[epoch_name]["amplitudeUnits"] = [] data[epoch_name]["eventID"] = [] @@ -62,7 +54,7 @@ def epoch_to_mat( else: data[epoch_name]["duration"] = epoch.durations - data[epoch_name]["center"] = data[epoch_name]["peaks"] + data[epoch_name]["center"] = data[epoch_name]["peaks"] data[epoch_name]["detectorinfo"] = {} if detection_name is None: data[epoch_name]["detectorinfo"]["detectorname"] = [] diff --git a/neuro_py/lfp/CSD.py b/neuro_py/lfp/CSD.py index 68cebf3..ac30322 100644 --- a/neuro_py/lfp/CSD.py +++ b/neuro_py/lfp/CSD.py @@ -2,18 +2,10 @@ import neo import numpy as np import quantities as pq - -from lazy_loader import attach as _attach from elephant.current_source_density import estimate_csd from neuro_py.io import loading -__all__ = ( - "get_coords", - "get_csd", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) - def get_coords(basepath, shank=0): """ @@ -51,10 +43,13 @@ def get_coords(basepath, shank=0): return rescaled_coords -def get_csd(basepath, data, shank, fs = 1250, diam = 0.015, method = 'DeltaiCSD', channel_offset = 0.046 ): + +def get_csd( + basepath, data, shank, fs=1250, diam=0.015, method="DeltaiCSD", channel_offset=0.046 +): """ - compute the CSD for a given basepath and data using elephant estimate_csd. - + compute the CSD for a given basepath and data using elephant estimate_csd. + Klas H. Pettersen, Anna Devor, Istvan Ulbert, Anders M. Dale, Gaute T. Einevoll, Current-source density estimation based on inversion of electrostatic forward solution: Effects of finite extent of neuronal activity and conductivity @@ -97,10 +92,10 @@ def get_csd(basepath, data, shank, fs = 1250, diam = 0.015, method = 'DeltaiCSD' dtype=float, ) - if method == 'DeltaiCSD': + if method == "DeltaiCSD": csd = estimate_csd(signal, coordinates=coords, diam=diam * pq.mm, method=method) - elif method == 'StandardCSD': + elif method == "StandardCSD": # create coordinates for the CSD coords = np.zeros(data.shape[1]) @@ -108,28 +103,28 @@ def get_csd(basepath, data, shank, fs = 1250, diam = 0.015, method = 'DeltaiCSD' if idx == 0: coords[idx] = 0 else: - coords[idx] = coords[idx-1] + channel_offset + coords[idx] = coords[idx - 1] + channel_offset coords = coords * pq.mm # add dimension to coords to make it (64,1) - coords = coords[:,np.newaxis] + coords = coords[:, np.newaxis] csd = estimate_csd(signal, coordinates=coords, method=method) - - elif method == 'KD1CSD': + + elif method == "KD1CSD": # create coordinates for the CSD coords = np.zeros(data.shape[1]) for idx, i in enumerate(coords): if idx == 0: coords[idx] = 0 else: - coords[idx] = coords[idx-1] + channel_offset + coords[idx] = coords[idx - 1] + channel_offset coords = coords * pq.mm # add dimension to coords to make it (64,1) - coords = coords[:,np.newaxis] - csd = estimate_csd(signal, coordinates=coords, method=method) + coords = coords[:, np.newaxis] + csd = estimate_csd(signal, coordinates=coords, method=method) return csd diff --git a/neuro_py/lfp/__init__.py b/neuro_py/lfp/__init__.py index 0c9abbb..e21bb75 100644 --- a/neuro_py/lfp/__init__.py +++ b/neuro_py/lfp/__init__.py @@ -1,6 +1,3 @@ -from . import preprocessing -from . import CSD -from . import spectral -from . import theta_cycles +import lazy_loader as lazy -__all__ = ["preprocessing", "CSD", "spectral", "theta_cycles"] +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/lfp/__init__.pyi b/neuro_py/lfp/__init__.pyi new file mode 100644 index 0000000..60d8812 --- /dev/null +++ b/neuro_py/lfp/__init__.pyi @@ -0,0 +1,21 @@ +__all__ = ( + "get_coords", + "get_csd", + "clean_lfp", + "whiten_lfp", + "event_triggered_wavelet", + "get_theta_channel", + "process_lfp", + "save_theta_cycles", + "get_theta_cycles", +) + +from .CSD import get_coords, get_csd +from .preprocessing import clean_lfp +from .spectral import event_triggered_wavelet, whiten_lfp +from .theta_cycles import ( + get_theta_channel, + get_theta_cycles, + process_lfp, + save_theta_cycles, +) diff --git a/neuro_py/lfp/preprocessing.py b/neuro_py/lfp/preprocessing.py index 856fc5c..5418c9a 100644 --- a/neuro_py/lfp/preprocessing.py +++ b/neuro_py/lfp/preprocessing.py @@ -1,16 +1,8 @@ import nelpy as nel import numpy as np -from lazy_loader import attach as _attach - from neuro_py.process import intervals -__all__ = ( - "clean_lfp", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def clean_lfp(lfp, thresholds=(5, 10), artifact_time_expand=(0.25, 0.1)): """ diff --git a/neuro_py/lfp/spectral.py b/neuro_py/lfp/spectral.py index c531837..6632abe 100644 --- a/neuro_py/lfp/spectral.py +++ b/neuro_py/lfp/spectral.py @@ -2,18 +2,10 @@ import numpy as np import pandas as pd -from lazy_loader import attach as _attach from neurodsp.timefrequency.wavelets import compute_wavelet_transform from scipy import signal from statsmodels.regression import yule_walker -__all__ = ( - "whiten_lfp", - "event_triggered_wavelet", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def whiten_lfp(lfp, order=2): """ diff --git a/neuro_py/lfp/theta_cycles.py b/neuro_py/lfp/theta_cycles.py index c76a788..59e35a4 100644 --- a/neuro_py/lfp/theta_cycles.py +++ b/neuro_py/lfp/theta_cycles.py @@ -1,27 +1,16 @@ import os import sys -from typing import Union, Tuple +from typing import Tuple, Union import nelpy as nel import numpy as np import pandas as pd -from lazy_loader import attach as _attach from neurodsp.filt import filter_signal from scipy.io import savemat from neuro_py.io import loading from neuro_py.process.intervals import find_interval -__all__ = ( - "get_theta_channel", - "process_lfp", - "get_ep_from_df", - "save_theta_cycles", - "get_theta_cycles", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def get_theta_channel(basepath: str, tag: str = "CA1so") -> int: brain_region = loading.load_brain_regions(basepath) diff --git a/neuro_py/plotting/__init__.py b/neuro_py/plotting/__init__.py index e6a15b4..e21bb75 100644 --- a/neuro_py/plotting/__init__.py +++ b/neuro_py/plotting/__init__.py @@ -1,4 +1,3 @@ -from . import events -from . import figure_helpers +import lazy_loader as lazy -__all__ = ["events", "figure_helpers"] \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/plotting/__init__.pyi b/neuro_py/plotting/__init__.pyi new file mode 100644 index 0000000..48a93f2 --- /dev/null +++ b/neuro_py/plotting/__init__.pyi @@ -0,0 +1,23 @@ +__all__ = ( + "plot_events", + "plot_peth", + "plot_peth_fast", + "set_plotting_defaults", + "set_size", + "lighten_color", + "set_equal_axis_range", + "restore_natural_scale", + "adjust_box_widths", + "plot_joint_peth", +) + +from .events import plot_events, plot_peth, plot_peth_fast +from .figure_helpers import ( + adjust_box_widths, + lighten_color, + plot_joint_peth, + restore_natural_scale, + set_equal_axis_range, + set_plotting_defaults, + set_size, +) diff --git a/neuro_py/plotting/events.py b/neuro_py/plotting/events.py index e527e8a..b0a41e7 100644 --- a/neuro_py/plotting/events.py +++ b/neuro_py/plotting/events.py @@ -1,4 +1,5 @@ import warnings +from typing import Union import matplotlib import matplotlib.pyplot as plt @@ -6,20 +7,8 @@ import pandas as pd import seaborn as sns -from typing import Union - -from lazy_loader import attach as _attach from neuro_py.stats.stats import confidence_intervals -__all__ = ( - "plot_events", - "plot_peth", - "plot_peth_fast", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - - def plot_events(events, labels, cmap="tab20", gridlines=True, alpha=0.75, ax=None): """ events: nested list of nelpy EpochArrays diff --git a/neuro_py/plotting/figure_helpers.py b/neuro_py/plotting/figure_helpers.py index 25f96c6..eecefc5 100644 --- a/neuro_py/plotting/figure_helpers.py +++ b/neuro_py/plotting/figure_helpers.py @@ -1,21 +1,8 @@ import matplotlib.pyplot as plt import numpy as np import seaborn as sns -from lazy_loader import attach as _attach from matplotlib.patches import PathPatch -__all__ = ( - "set_plotting_defaults", - "set_size", - "lighten_color", - "set_equal_axis_range", - "restore_natural_scale", - "adjust_box_widths", - "plot_joint_peth", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def set_plotting_defaults(): tex_fonts = { diff --git a/neuro_py/process/__init__.py b/neuro_py/process/__init__.py index f3b0fab..e21bb75 100644 --- a/neuro_py/process/__init__.py +++ b/neuro_py/process/__init__.py @@ -1,17 +1,3 @@ -from . import batch_analysis -from . import correlations -from . import intervals -from . import peri_event -from . import precession_utils -from . import pychronux -from . import utils +import lazy_loader as lazy -__all__ = [ - "batch_analysis", - "correlations", - "intervals", - "peri_event", - "precession_utils", - "pychronux", - "utils", -] +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/process/__init__.pyi b/neuro_py/process/__init__.pyi new file mode 100644 index 0000000..5e04ac4 --- /dev/null +++ b/neuro_py/process/__init__.pyi @@ -0,0 +1,115 @@ +__all__ = ( + "batch_analysis", + "encode_file_path", + "decode_file_path", + "load_results", + "compute_AutoCorrs", + "pairwise_corr", + "pairwise_cross_corr", + "pairwise_spatial_corr", + "compute_cross_correlogram", + "randomize_epochs", + "split_epoch_equal_parts", + "overlap_intersect", + "find_intersecting_intervals", + "find_interval", + "in_intervals", + "in_intervals_interval", + "truncate_epoch", + "shift_epoch_array", + "crossCorr", + "compute_psth", + "joint_peth", + "deconvolve_peth", + "peth_matrix", + "get_raster_points", + "event_triggered_average_irregular_sample", + "event_triggered_average", + "event_triggered_average_fast", + "count_in_interval", + "get_rank_order", + "count_events", + "relative_times", + "nearest_event_delay", + "event_spiking_threshold", + "corrcc", + "corrcc_uniform", + "spatial_phase_precession", + "fast_acf", + "acf_power", + "nonspatial_phase_precession", + "getfgrid", + "dpsschk", + "get_tapers", + "mtfftpt", + "mtspectrumpt", + "mtfftc", + "mtspectrumc", + "point_spectra", + "circular_shift", + "avgerage_diagonal", + "remove_inactive_cells", + "remove_inactive_cells_pre_task_post", +) + +from . import batch_analysis +from .batch_analysis import decode_file_path, encode_file_path, load_results +from .correlations import ( + compute_AutoCorrs, + compute_cross_correlogram, + pairwise_corr, + pairwise_cross_corr, + pairwise_spatial_corr, +) +from .intervals import ( + find_intersecting_intervals, + find_interval, + in_intervals, + in_intervals_interval, + overlap_intersect, + randomize_epochs, + shift_epoch_array, + split_epoch_equal_parts, + truncate_epoch, +) +from .peri_event import ( + compute_psth, + count_events, + count_in_interval, + crossCorr, + deconvolve_peth, + event_spiking_threshold, + event_triggered_average, + event_triggered_average_fast, + event_triggered_average_irregular_sample, + get_rank_order, + get_raster_points, + joint_peth, + nearest_event_delay, + peth_matrix, + relative_times, +) +from .precession_utils import ( + acf_power, + corrcc, + corrcc_uniform, + fast_acf, + nonspatial_phase_precession, + spatial_phase_precession, +) +from .pychronux import ( + dpsschk, + get_tapers, + getfgrid, + mtfftc, + mtfftpt, + mtspectrumc, + mtspectrumpt, + point_spectra, +) +from .utils import ( + avgerage_diagonal, + circular_shift, + remove_inactive_cells, + remove_inactive_cells_pre_task_post, +) diff --git a/neuro_py/process/batch_analysis.py b/neuro_py/process/batch_analysis.py index 18ddf7b..3cad7fe 100644 --- a/neuro_py/process/batch_analysis.py +++ b/neuro_py/process/batch_analysis.py @@ -7,19 +7,8 @@ import pandas as pd from joblib import Parallel, delayed -from lazy_loader import attach as _attach from tqdm import tqdm -__all__ = ( - "encode_file_path", - "decode_file_path", - "main_loop", - "run", - "load_results", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def encode_file_path(basepath: str, save_path: str) -> str: """ diff --git a/neuro_py/process/correlations.py b/neuro_py/process/correlations.py index 577aa88..74dbe79 100644 --- a/neuro_py/process/correlations.py +++ b/neuro_py/process/correlations.py @@ -2,23 +2,11 @@ import numpy as np import pandas as pd -from lazy_loader import attach as _attach from scipy import signal, stats from scipy.stats import poisson from neuro_py.process.peri_event import crossCorr, deconvolve_peth -__all__ = ( - "compute_AutoCorrs", - "pairwise_corr", - "pairwise_cross_corr", - "pairwise_spatial_corr", - "compute_cross_correlogram", - -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def compute_AutoCorrs(spks, binsize=0.001, nbins=100): # First let's prepare a pandas dataframe to receive the data diff --git a/neuro_py/process/intervals.py b/neuro_py/process/intervals.py index 09f4691..02c705c 100644 --- a/neuro_py/process/intervals.py +++ b/neuro_py/process/intervals.py @@ -4,24 +4,9 @@ import nelpy as nel import numba import numpy as np -from lazy_loader import attach as _attach from nelpy import core from numba import jit -__all__ = ( - "randomize_epochs", - "split_epoch_equal_parts", - "overlap_intersect", - "find_intersecting_intervals", - "find_interval", - "in_intervals", - "in_intervals_interval", - "truncate_epoch", - "shift_epoch_array", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def randomize_epochs(epoch, randomize_each=True, start_stop=None): """Randomly shifts the epochs of a EpochArray object and wraps them around the original time boundaries. diff --git a/neuro_py/process/peri_event.py b/neuro_py/process/peri_event.py index 2ec0c2c..773fa9f 100644 --- a/neuro_py/process/peri_event.py +++ b/neuro_py/process/peri_event.py @@ -3,33 +3,11 @@ import numpy as np import pandas as pd -from lazy_loader import attach as _attach from nelpy.core._eventarray import SpikeTrainArray from numba import jit, prange from scipy import stats from scipy.linalg import toeplitz -__all__ = ( - "crossCorr", - "compute_psth", - "joint_peth", - "deconvolve_peth", - "peth_matrix", - "get_raster_points", - "event_triggered_average_irregular_sample", - "event_triggered_average", - "event_triggered_average_fast", - "count_in_interval", - "get_participation", - "get_rank_order", - "count_events", - "relative_times", - "nearest_event_delay", - "event_spiking_threshold", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - @jit(nopython=True) def crossCorr( diff --git a/neuro_py/process/precession_utils.py b/neuro_py/process/precession_utils.py index 580e023..64b040b 100644 --- a/neuro_py/process/precession_utils.py +++ b/neuro_py/process/precession_utils.py @@ -4,24 +4,11 @@ import numpy as np import pyfftw import scipy as sp -from lazy_loader import attach as _attach from scipy.ndimage import gaussian_filter1d from scipy.signal import find_peaks import neuro_py.stats.circ_stats as pcs -__all__ = ( - "corrcc", - "corrcc_uniform", - "spatial_phase_precession", - "fast_acf", - "acf_power", - "nonspatial_phase_precession", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - - # These are the core functions used to identify both spatial and non-spatial phase precession # https://github.com/seqasim/human_precession/blob/main/Precession_utils.py # https://doi.org/10.1016/j.cell.2021.04.017 diff --git a/neuro_py/process/pychronux.py b/neuro_py/process/pychronux.py index ab1d202..efa185d 100644 --- a/neuro_py/process/pychronux.py +++ b/neuro_py/process/pychronux.py @@ -2,22 +2,8 @@ import numpy as np import pandas as pd -from lazy_loader import attach as _attach from scipy.signal.windows import dpss -__all__ = ( - "getfgrid", - "dpsschk", - "get_tapers", - "mtfftpt", - "mtspectrumpt", - "mtfftc", - "mtspectrumc", - "point_spectra", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def getfgrid(Fs: int, nfft: int, fpass: list): """ diff --git a/neuro_py/process/utils.py b/neuro_py/process/utils.py index 0d12631..dfbae0d 100644 --- a/neuro_py/process/utils.py +++ b/neuro_py/process/utils.py @@ -1,24 +1,12 @@ -import numpy as np -import nelpy as nel -import pandas as pd - from typing import List, Union -from lazy_loader import attach as _attach +import nelpy as nel +import numpy as np +import pandas as pd from neuro_py.process.intervals import truncate_epoch -__all__ = ( - "circular_shift", - "avgerage_diagonal", - "remove_inactive_cells", - "remove_inactive_cells_pre_task_post", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - - def circular_shift(m: np.ndarray, s: np.ndarray): """ CircularShift - Shift matrix rows or columns circularly. @@ -270,7 +258,7 @@ def return_results(st, cell_metrics): def remove_inactive_cells_pre_task_post( st: nel.core._eventarray.SpikeTrainArray, - cell_metrics: Union[pd.core.frame.DataFrame,None] = None, + cell_metrics: Union[pd.core.frame.DataFrame, None] = None, beh_epochs: nel.core._intervalarray.EpochArray = None, nrem_epochs: nel.core._intervalarray.EpochArray = None, theta_epochs: nel.core._intervalarray.EpochArray = None, diff --git a/neuro_py/session/__init__.py b/neuro_py/session/__init__.py index 45ba964..f84944a 100644 --- a/neuro_py/session/__init__.py +++ b/neuro_py/session/__init__.py @@ -1,3 +1,3 @@ -from . import locate_epochs +import lazy_loader as lazy -__all__ = ["locate_epochs"] +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) diff --git a/neuro_py/session/__init__.pyi b/neuro_py/session/__init__.pyi new file mode 100644 index 0000000..c890de9 --- /dev/null +++ b/neuro_py/session/__init__.pyi @@ -0,0 +1,19 @@ +__all__ = [ + "find_pre_task_post", + "compress_repeated_epochs", + "find_multitask_pre_post", + "find_epoch_pattern", + "find_env_paradigm_pre_task_post", + "find_pre_task_post_optimize_novel", + "get_experience_level", +] + +from .locate_epochs import ( + compress_repeated_epochs, + find_env_paradigm_pre_task_post, + find_epoch_pattern, + find_multitask_pre_post, + find_pre_task_post, + find_pre_task_post_optimize_novel, + get_experience_level, +) diff --git a/neuro_py/session/locate_epochs.py b/neuro_py/session/locate_epochs.py index 65a45c8..be9ed8c 100644 --- a/neuro_py/session/locate_epochs.py +++ b/neuro_py/session/locate_epochs.py @@ -4,19 +4,6 @@ import numpy as np import pandas as pd -from lazy_loader import attach as _attach - -__all__ = ( - "find_pre_task_post", - "compress_repeated_epochs", - "find_multitask_pre_post", - "find_epoch_pattern", - "find_env_paradigm_pre_task_post", - "find_pre_task_post_optimize_novel", - "get_experience_level", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach def find_pre_task_post(env, pre_post_label="sleep"): @@ -267,8 +254,8 @@ def find_env_paradigm_pre_task_post(epoch_df, env="sleep", paradigm="memory"): def find_pre_task_post_optimize_novel( - epoch_df: pd.DataFrame(), novel_indicators: list = [1, "novel", "1"] -) -> pd.DataFrame(): + epoch_df: pd.DataFrame, novel_indicators: list = [1, "novel", "1"] +) -> pd.DataFrame: """ find_pre_task_post_optimize_novel: find pre task post epochs in epoch_df diff --git a/neuro_py/spikes/__init__.py b/neuro_py/spikes/__init__.py index d2b1927..e21bb75 100644 --- a/neuro_py/spikes/__init__.py +++ b/neuro_py/spikes/__init__.py @@ -1,3 +1,3 @@ -from . import spike_tools +import lazy_loader as lazy -__all__ = ["spike_tools"] \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/spikes/__init__.pyi b/neuro_py/spikes/__init__.pyi new file mode 100644 index 0000000..a549e81 --- /dev/null +++ b/neuro_py/spikes/__init__.pyi @@ -0,0 +1,13 @@ +__all__ = [ + "get_spindices", + "spindices_to_ndarray", + "BurstIndex_Royer_2012", + "select_burst_spikes", +] + +from .spike_tools import ( + BurstIndex_Royer_2012, + get_spindices, + select_burst_spikes, + spindices_to_ndarray, +) \ No newline at end of file diff --git a/neuro_py/spikes/spike_tools.py b/neuro_py/spikes/spike_tools.py index f1b822e..41bb8b6 100644 --- a/neuro_py/spikes/spike_tools.py +++ b/neuro_py/spikes/spike_tools.py @@ -1,27 +1,11 @@ -__all__ = [ - "get_spindices", - "spindices_to_ndarray", - "BurstIndex_Royer_2012", - "select_burst_spikes" -] -import numpy as np -import pandas as pd - -from lazy_loader import attach as _attach from typing import Union -__all__ = ( - "get_spindices", - "spindices_to_ndarray", - "BurstIndex_Royer_2012", - "select_burst_spikes", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach +import numpy as np +import pandas as pd -def get_spindices(data: np.ndarray) -> pd.DataFrame(): +def get_spindices(data: np.ndarray) -> pd.DataFrame: """ Get spike timestamps and spike id for each spike train in a sorted dataframe of spike trains diff --git a/neuro_py/stats/__init__.py b/neuro_py/stats/__init__.py index 01e0f8a..e21bb75 100644 --- a/neuro_py/stats/__init__.py +++ b/neuro_py/stats/__init__.py @@ -1,5 +1,3 @@ -from . import regression -from . import stats -from . import system_identifier +import lazy_loader as lazy -__all__ = ['regression', 'stats', 'system_identifier'] +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/stats/__init__.pyi b/neuro_py/stats/__init__.pyi new file mode 100644 index 0000000..46aa225 --- /dev/null +++ b/neuro_py/stats/__init__.pyi @@ -0,0 +1,34 @@ +__all__ = [ + "percentile", + "resultant_vector_length", + "mean_ci_limits", + "center", + "get_var", + "rayleigh", + "ideal_data", + "ReducedRankRegressor", + "MultivariateRegressor", + "kernelReducedRankRegressor", + "get_significant_events", + "confidence_intervals", + "reindex_df", + "regress_out", + "SystemIdentifier", +] + +from .circ_stats import ( + center, + get_var, + mean_ci_limits, + percentile, + rayleigh, + resultant_vector_length, +) +from .regression import ( + MultivariateRegressor, + ReducedRankRegressor, + ideal_data, + kernelReducedRankRegressor, +) +from .stats import confidence_intervals, get_significant_events, regress_out, reindex_df +from .system_identifier import SystemIdentifier diff --git a/neuro_py/stats/regression.py b/neuro_py/stats/regression.py index 34dbca8..5a54262 100644 --- a/neuro_py/stats/regression.py +++ b/neuro_py/stats/regression.py @@ -1,19 +1,9 @@ import numpy as np import scipy -from lazy_loader import attach as _attach from scipy import sparse from sklearn.base import BaseEstimator from sklearn.metrics import r2_score -__all__ = ( - "ideal_data", - "ReducedRankRegressor", - "MultivariateRegressor", - "ReducedRankRegressor", - "kernelReducedRankRegressor", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach def ideal_data(num, dimX, dimY, rrank, noise=1): diff --git a/neuro_py/stats/stats.py b/neuro_py/stats/stats.py index c2ac6f1..8cca4ca 100644 --- a/neuro_py/stats/stats.py +++ b/neuro_py/stats/stats.py @@ -1,24 +1,8 @@ -__all__ = [ - "get_significant_events", - "confidence_intervals", - "reindex_df", - "regress_out", -] -import numpy as np -import scipy.stats as stats -import pandas as pd import warnings -from lazy_loader import attach as _attach - -__all__ = ( - "get_significant_events", - "confidence_intervals", - "reindex_df", - "regress_out", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach +import numpy as np +import pandas as pd +import scipy.stats as stats def get_significant_events(scores, shuffled_scores, q=95, tail="both"): @@ -103,7 +87,7 @@ def confidence_intervals(X: np.ndarray, conf: float = 0.95): # split into lower and upper lower = interval[:, 0] upper = interval[:, 1] - + return lower, upper diff --git a/neuro_py/stats/system_identifier.py b/neuro_py/stats/system_identifier.py index 96ac583..96fb8d7 100644 --- a/neuro_py/stats/system_identifier.py +++ b/neuro_py/stats/system_identifier.py @@ -14,20 +14,12 @@ x_(i+1) = dot(A, x_i) + dot(B, u_i) This is a linear dynamical system. """ + import numpy as np import scipy as sp - -from lazy_loader import attach as _attach from scipy import sparse from scipy.sparse import linalg as sparse_linalg -__all__ = ( - "ideal_data", - "SystemIdentifier", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def ideal_data(num, dimU, dimY, dimX, noise=1): """Linear system data""" @@ -42,7 +34,7 @@ def ideal_data(num, dimU, dimY, dimX, noise=1): A = np.dot(U, np.dot(np.lib.diag(S / max(S)), V)) U, S, V = np.linalg.svd(B) S2 = np.zeros((np.size(U, 1), np.size(V, 0))) - S2[:, :np.size(U, 1)] = np.lib.diag(S / max(S)) + S2[:, : np.size(U, 1)] = np.lib.diag(S / max(S)) B = np.dot(U, np.dot(S2, V)) # random input @@ -55,15 +47,12 @@ def ideal_data(num, dimU, dimY, dimX, noise=1): Y = np.reshape(np.dot(C, X[-1]) + np.dot(D, U[0]), (1, -1)) # generate next state - X = np.concatenate( - (X, np.reshape(np.dot(A, X[-1]) + np.dot(B, U[0]), (1, -1)))) + X = np.concatenate((X, np.reshape(np.dot(A, X[-1]) + np.dot(B, U[0]), (1, -1)))) # and so forth for u in U[1:]: - Y = np.concatenate( - (Y, np.reshape(np.dot(C, X[-1]) + np.dot(D, u), (1, -1)))) - X = np.concatenate( - (X, np.reshape(np.dot(A, X[-1]) + np.dot(B, u), (1, -1)))) + Y = np.concatenate((Y, np.reshape(np.dot(C, X[-1]) + np.dot(D, u), (1, -1)))) + X = np.concatenate((X, np.reshape(np.dot(A, X[-1]) + np.dot(B, u), (1, -1)))) return U, Y + np.random.randn(num, dimY) * noise @@ -76,6 +65,7 @@ class SystemIdentifier(object): - statedim is the dimension of the internal state variable. - reg is a regularization parameter (optional). """ + def __init__(self, U, Y, statedim, reg=None): if np.size(np.shape(U)) == 1: U = np.reshape(U, (-1, 1)) @@ -95,10 +85,10 @@ def __init__(self, U, Y, statedim, reg=None): K = np.size(U, 0) - 2 * width + 1 # build hankel matrices containing pasts and futures - U_p = np.array([np.ravel(U[t:t + width]) for t in range(K)]).T - U_f = np.array([np.ravel(U[t + width:t + 2 * width]) for t in range(K)]).T - Y_p = np.array([np.ravel(Y[t:t + width]) for t in range(K)]).T - Y_f = np.array([np.ravel(Y[t + width:t + 2 * width]) for t in range(K)]).T + U_p = np.array([np.ravel(U[t : t + width]) for t in range(K)]).T + U_f = np.array([np.ravel(U[t + width : t + 2 * width]) for t in range(K)]).T + Y_p = np.array([np.ravel(Y[t : t + width]) for t in range(K)]).T + Y_f = np.array([np.ravel(Y[t + width : t + 2 * width]) for t in range(K)]).T # solve the eigenvalue problem YfUfT = np.dot(Y_f, U_f.T) @@ -107,26 +97,30 @@ def __init__(self, U, Y, statedim, reg=None): UfUpT = np.dot(U_f, U_p.T) UfYpT = np.dot(U_f, Y_p.T) UpYpT = np.dot(U_p, Y_p.T) - F = sparse.bmat([ - [None, YfUfT, YfUpT, YfYpT], - [YfUfT.T, None, UfUpT, UfYpT], - [YfUpT.T, UfUpT.T, None, UpYpT], - [YfYpT.T, UfYpT.T, UpYpT.T, None], - ]) - Ginv = sparse.bmat([ - [np.linalg.pinv(np.dot(Y_f, Y_f.T)), None, None, None], - [None, np.linalg.pinv(np.dot(U_f, U_f.T)), None, None], - [None, None, np.linalg.pinv(np.dot(U_p, U_p.T)), None], - [None, None, None, np.linalg.pinv(np.dot(Y_p, Y_p.T))], - ]) + F = sparse.bmat( + [ + [None, YfUfT, YfUpT, YfYpT], + [YfUfT.T, None, UfUpT, UfYpT], + [YfUpT.T, UfUpT.T, None, UpYpT], + [YfYpT.T, UfYpT.T, UpYpT.T, None], + ] + ) + Ginv = sparse.bmat( + [ + [np.linalg.pinv(np.dot(Y_f, Y_f.T)), None, None, None], + [None, np.linalg.pinv(np.dot(U_f, U_f.T)), None, None], + [None, None, np.linalg.pinv(np.dot(U_p, U_p.T)), None], + [None, None, None, np.linalg.pinv(np.dot(Y_p, Y_p.T))], + ] + ) F = F - sparse.eye(sp.size(F, 0)) * reg # Take smallest eigenvalues - _, W = sparse_linalg.eigs(Ginv.dot(F), k=statedim, which='SR') + _, W = sparse_linalg.eigs(Ginv.dot(F), k=statedim, which="SR") # State sequence is a weighted combination of the past - W_U_p = W[width * (yDim + uDim):width * (yDim + uDim + uDim), :] - W_Y_p = W[width * (yDim + uDim + uDim):, :] + W_U_p = W[width * (yDim + uDim) : width * (yDim + uDim + uDim), :] + W_Y_p = W[width * (yDim + uDim + uDim) :, :] X_hist = np.dot(W_U_p.T, U_p) + np.dot(W_Y_p.T, Y_p) # Regress; trim inputs to match the states we retrieved @@ -155,11 +149,17 @@ def predict(self, U): Y = np.reshape(np.dot(self.C, X[-1]) + np.dot(self.D, U[0]), (1, -1)) # generate next state - X = np.concatenate((X, np.reshape(np.dot(self.A, X[-1]) + np.dot(self.B, U[0]), (1, -1)))) + X = np.concatenate( + (X, np.reshape(np.dot(self.A, X[-1]) + np.dot(self.B, U[0]), (1, -1))) + ) # and so forth for u in U[1:]: - Y = np.concatenate((Y, np.reshape(np.dot(self.C, X[-1]) + np.dot(self.D, u), (1, -1)))) - X = np.concatenate((X, np.reshape(np.dot(self.A, X[-1]) + np.dot(self.B, u), (1, -1)))) - - return Y \ No newline at end of file + Y = np.concatenate( + (Y, np.reshape(np.dot(self.C, X[-1]) + np.dot(self.D, u), (1, -1))) + ) + X = np.concatenate( + (X, np.reshape(np.dot(self.A, X[-1]) + np.dot(self.B, u), (1, -1))) + ) + + return Y diff --git a/neuro_py/tuning/__init__.py b/neuro_py/tuning/__init__.py index 93403dd..e21bb75 100644 --- a/neuro_py/tuning/__init__.py +++ b/neuro_py/tuning/__init__.py @@ -1,4 +1,3 @@ -from . import fields -from . import maps +import lazy_loader as lazy -__all__ = ['fields', 'maps'] \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file diff --git a/neuro_py/tuning/__init__.pyi b/neuro_py/tuning/__init__.pyi new file mode 100644 index 0000000..f022cea --- /dev/null +++ b/neuro_py/tuning/__init__.pyi @@ -0,0 +1,45 @@ +__all__ = ( + "detect_firing_fields", + "find_peaks", + "sort_fields_by_rate", + "remove_fields_by_area", + "separate_fields_by_laplace", + "separate_fields_by_dilation", + "separate_fields_by_laplace_of_gaussian", + "calculate_field_centers", + "which_field", + "compute_crossings", + "distance_to_edge_function", + "map_pass_to_unit_circle", + "consecutive", + "find_fields_1d", + "compute_linear_place_fields", + "compute_2d_place_fields", + "find_field", + "find_field2", + "map_stats2", + "SpatialMap", +) + +from .fields import ( + calculate_field_centers, + compute_2d_place_fields, + compute_crossings, + compute_linear_place_fields, + consecutive, + detect_firing_fields, + distance_to_edge_function, + find_field, + find_field2, + find_fields_1d, + find_peaks, + map_pass_to_unit_circle, + map_stats2, + remove_fields_by_area, + separate_fields_by_dilation, + separate_fields_by_laplace, + separate_fields_by_laplace_of_gaussian, + sort_fields_by_rate, + which_field, +) +from .maps import SpatialMap diff --git a/neuro_py/tuning/fields.py b/neuro_py/tuning/fields.py index aca58f0..72fac08 100644 --- a/neuro_py/tuning/fields.py +++ b/neuro_py/tuning/fields.py @@ -4,35 +4,10 @@ import numpy as np import scipy.ndimage as ndimage import scipy.ndimage.filters as filters -from lazy_loader import attach as _attach from scipy.interpolate import interp1d from scipy.ndimage import gaussian_filter1d, label from scipy.ndimage.filters import gaussian_filter, maximum_filter -__all__ = ( - "detect_firing_fields", - "find_peaks", - "sort_fields_by_rate", - "remove_fields_by_area", - "separate_fields_by_laplace", - "separate_fields_by_dilation", - "separate_fields_by_laplace_of_gaussian", - "calculate_field_centers", - "which_field", - "compute_crossings", - "distance_to_edge_function", - "map_pass_to_unit_circle", - "consecutive", - "find_fields_1d", - "compute_linear_place_fields", - "compute_2d_place_fields", - "find_field", - "find_field2", - "map_stats2", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - def detect_firing_fields( image_gray, diff --git a/neuro_py/tuning/maps.py b/neuro_py/tuning/maps.py index 4baf250..67b7f4e 100644 --- a/neuro_py/tuning/maps.py +++ b/neuro_py/tuning/maps.py @@ -7,20 +7,12 @@ import nelpy as nel import numpy as np from joblib import Parallel, delayed -from lazy_loader import attach as _attach from scipy.io import savemat from scipy.spatial.distance import pdist from neuro_py.stats.stats import get_significant_events from neuro_py.tuning import fields -__all__ = ( - "SpatialMap", -) -__getattr__, __dir__, __all__ = _attach(f"{__name__}", submodules=__all__) -del _attach - -# logging.getLogger().setLevel(logging.ERROR) np.seterr(divide="ignore", invalid="ignore") From 9fbce62b1cc36f9c38c55f299b7050871d5c2105 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Fri, 13 Sep 2024 17:46:26 -0400 Subject: [PATCH 2/4] del lazy --- neuro_py/__init__.py | 3 ++- neuro_py/behavior/__init__.py | 3 ++- neuro_py/ensemble/__init__.py | 3 ++- neuro_py/io/__init__.py | 3 ++- neuro_py/lfp/__init__.py | 3 ++- neuro_py/plotting/__init__.py | 3 ++- neuro_py/process/__init__.py | 3 ++- neuro_py/session/__init__.py | 1 + neuro_py/spikes/__init__.py | 3 ++- neuro_py/stats/__init__.py | 3 ++- neuro_py/tuning/__init__.py | 3 ++- 11 files changed, 21 insertions(+), 10 deletions(-) diff --git a/neuro_py/__init__.py b/neuro_py/__init__.py index e21bb75..2a559be 100644 --- a/neuro_py/__init__.py +++ b/neuro_py/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy \ No newline at end of file diff --git a/neuro_py/behavior/__init__.py b/neuro_py/behavior/__init__.py index e21bb75..9ff4bc3 100644 --- a/neuro_py/behavior/__init__.py +++ b/neuro_py/behavior/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy diff --git a/neuro_py/ensemble/__init__.py b/neuro_py/ensemble/__init__.py index e21bb75..9ff4bc3 100644 --- a/neuro_py/ensemble/__init__.py +++ b/neuro_py/ensemble/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy diff --git a/neuro_py/io/__init__.py b/neuro_py/io/__init__.py index e21bb75..9ff4bc3 100644 --- a/neuro_py/io/__init__.py +++ b/neuro_py/io/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy diff --git a/neuro_py/lfp/__init__.py b/neuro_py/lfp/__init__.py index e21bb75..9ff4bc3 100644 --- a/neuro_py/lfp/__init__.py +++ b/neuro_py/lfp/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy diff --git a/neuro_py/plotting/__init__.py b/neuro_py/plotting/__init__.py index e21bb75..9ff4bc3 100644 --- a/neuro_py/plotting/__init__.py +++ b/neuro_py/plotting/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy diff --git a/neuro_py/process/__init__.py b/neuro_py/process/__init__.py index e21bb75..9ff4bc3 100644 --- a/neuro_py/process/__init__.py +++ b/neuro_py/process/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy diff --git a/neuro_py/session/__init__.py b/neuro_py/session/__init__.py index f84944a..9ff4bc3 100644 --- a/neuro_py/session/__init__.py +++ b/neuro_py/session/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy (__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy diff --git a/neuro_py/spikes/__init__.py b/neuro_py/spikes/__init__.py index e21bb75..9ff4bc3 100644 --- a/neuro_py/spikes/__init__.py +++ b/neuro_py/spikes/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy diff --git a/neuro_py/stats/__init__.py b/neuro_py/stats/__init__.py index e21bb75..9ff4bc3 100644 --- a/neuro_py/stats/__init__.py +++ b/neuro_py/stats/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy diff --git a/neuro_py/tuning/__init__.py b/neuro_py/tuning/__init__.py index e21bb75..9ff4bc3 100644 --- a/neuro_py/tuning/__init__.py +++ b/neuro_py/tuning/__init__.py @@ -1,3 +1,4 @@ import lazy_loader as lazy -(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) \ No newline at end of file +(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__) +del lazy From 43b4d11369946d551679f03db66db6c084ecbc64 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Fri, 13 Sep 2024 17:47:05 -0400 Subject: [PATCH 3/4] ref correct level for function, should fix name in future --- tests/test_similarity_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_similarity_index.py b/tests/test_similarity_index.py index 2d172b2..5130f27 100644 --- a/tests/test_similarity_index.py +++ b/tests/test_similarity_index.py @@ -4,7 +4,7 @@ def test_similarityindex(): patterns = [np.random.normal(0, .1, 100) for _ in range(10)] - si, combos, pvalues = similarity_index.similarity_index(patterns) + si, combos, pvalues = similarity_index(patterns) assert all(i <= 1 for i in si) assert combos[0,0] == 0 assert all(i <= 1 for i in pvalues) From 8e934dd75551efedf5ec50c594a91a489689a061 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Fri, 13 Sep 2024 17:56:41 -0400 Subject: [PATCH 4/4] fix: is False to ~ caused by previous linting --- neuro_py/io/loading.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neuro_py/io/loading.py b/neuro_py/io/loading.py index 5ef6ab1..a906df6 100644 --- a/neuro_py/io/loading.py +++ b/neuro_py/io/loading.py @@ -1483,7 +1483,7 @@ def load_spikes( if remove_bad_unit: # bad units will be tagged true, so only keep false values - restrict_idx = cell_metrics.bad_unit.values is False + restrict_idx = ~cell_metrics.bad_unit.values cell_metrics = cell_metrics[restrict_idx] st = st[restrict_idx]