-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bridging between ByCycle and NeuroDSP functionalities #148
Comments
Hi @davidglitvin, sorry for the delayed response. Lets start with some simulated data to answer your questions: import numpy as np
from bycycle import BycycleGroup
from neurodsp.sim import sim_powerlaw
from neurodsp.plts import plot_bursts
# Simulate
n_seconds = 10
fs = 1000
osc = np.zeros(int(n_seconds * fs))
osc[4000:6000] = np.sin(2*np.pi*10*np.arange(0, 2000)/fs + np.pi)
n_rows = 2
sigs = np.zeros((n_rows, int(n_seconds * fs)))
for i in range(n_rows):
sigs[i] = sim_powerlaw(n_seconds, fs) + osc
# Fit Bycyle
bg = BycycleGroup(thresholds={})
bg.fit(sigs, fs, (5, 15))
bg.recompute_edges()
# Plot
sig = sigs[0]
df_features = bg[0].df_features
times = np.arange(0, len(sig)/fs, 1/fs)
# Determine which samples are defined as bursting
is_osc = np.zeros(len(sig), dtype=bool)
df_osc = df_features.loc[df_features['is_burst']]
start = 0
for cyc in df_osc.to_dict('records'):
samp_start_burst = int(cyc['sample_last_trough']) - int(fs * start)
samp_end_burst = int(cyc['sample_next_trough'] + 1) - int(fs * start)
is_osc[samp_start_burst:samp_end_burst] = True
plot_bursts(times, sig, is_osc, labels=['Signal', 'Bursts']) Alternatively, you could use this since it's built in, but it doesn't produce the same plots as plot_bursts: bg[0].plot(plot_only_results=True)
# Determine these using the `is_burst` column
i_cyc_start = ... # the first row is non-burst in the segment
i_cyc_end = ... # last row that is non-burst in the same segment
# Where non-burst segment starts and ends
sig_ind = 0
i_start = bg[sig_ind].df_features.iloc[i_cyc_start].sample_last_trough
i_end = bg[sig_ind].df_features.iloc[i_cyc_end].sample_next_trough
# Slice
sig_non_burst = sigs[sig_ind, i_start:i_end] I would then chunk, e.g. reshape, sig_non_burst above based on the length of desired lagged coherence window. You'll probably need to slice off a few samples so it's evenly divisible by the desired window length. The code above is for one non-burst segment. The length of each chunk should be constant, so the end result will be a loop of the above and a single 2d array of non-burst chunks. Then continue from this line. |
Ok, thanks for the help! I had another question that is somewhat related, and probably doesn't warrant opening a new issue for this github repository. For the FOOOFGroup array containing information about the cycles that are (or are not) parts of bursts, there are a number of features that describe each cycles' shape (i.e. amp_fraction, amp_consistency, period_consistency, monotonicity, period, time_peak, time_trough, time_decay, time_rise, time_rdsym, time_ptsym, etc). I am noticing that in my data the bursts have several classes of cycle groups with common values for the attributes. Have you tried using something like ICA, or machine learning to classify discrete clusters of cycles within bursts? |
You're welcome! I've used kmeans in the past to cluster cycles. I did this by resampling cycles to have the same number of samples per cycle. Then passed the resampled cycles into kmeans. Resampling is probably not ideal unless each cycle has a sufficient number of samples and there is little variation in the number of samples per cycle. Using bycycle features + a clustering method sounds like a good idea and would be a nice use case! Let me know how it works out. If the data is open source or simulate-able, then it may be a nice addition to the examples page. |
Dear ByCycle team,
I am writing to inquire about how to bridge/transition between ByCycle and NeuroDSP. More specifically, I have an array with multiple sub-arrays corresponding to different experimental subjects that I pass through the cycle-by-cycle algorithm, which I store in the "BycycleGroup" object. As a quick background -
The text was updated successfully, but these errors were encountered: