From 09b446a15958bc912446289c0f4097b68bd1e309 Mon Sep 17 00:00:00 2001 From: olivier Date: Thu, 30 May 2024 14:49:35 +0100 Subject: [PATCH 1/9] Create spike interface GUI controller --- src/viewephys/spike_interface.ui | 153 +++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/viewephys/spike_interface.ui diff --git a/src/viewephys/spike_interface.ui b/src/viewephys/spike_interface.ui new file mode 100644 index 0000000..74e13e0 --- /dev/null +++ b/src/viewephys/spike_interface.ui @@ -0,0 +1,153 @@ + + + MainWindow + + + true + + + + 0 + 0 + 785 + 295 + + + + Spike Interface Viewer + + + + + + + false + + + Qt::Horizontal + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Dataset Info + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 160 + 0 + + + + + + + + + + + + 16777215 + 40 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + smin + + + + + + + sval + + + Qt::AlignCenter + + + + + + + smax + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + 0 + 0 + 785 + 22 + + + + + File + + + + + + + + open + + + + + open live recording + + + + + + From 9146a0a4a3e6ee1871c57f48e8e914123c1a3398 Mon Sep 17 00:00:00 2001 From: Gaelle Date: Thu, 30 May 2024 16:49:22 +0100 Subject: [PATCH 2/9] todos --- src/viewephys/gui.py | 82 +++++++++++++++++++++++++++++-- src/viewephys/raster.py | 9 ++-- src/viewephys/tests/test_model.py | 1 - 3 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/viewephys/gui.py b/src/viewephys/gui.py index a21dd2f..7944aea 100644 --- a/src/viewephys/gui.py +++ b/src/viewephys/gui.py @@ -111,8 +111,10 @@ def on_horizontalSliderReleased(self): if not self.cbs[k].isChecked(): continue if k == 'destripe': - data = fcn_destripe(x=data, fs=self.sr.fs, channel_labels=True, h=self.sr.geometry, neuropixel_version=self.sr.major_version) - self.viewers[k] = viewephys(data, self.sr.fs, channels=self.sr.geometry, title=k, t0=t0 * T_SCALAR, t_scalar=T_SCALAR, a_scalar=A_SCALAR) + data = fcn_destripe(x=data, fs=self.sr.fs, channel_labels=True, h=self.sr.geometry, + neuropixel_version=self.sr.major_version) + self.viewers[k] = viewephys(data, self.sr.fs, channels=self.sr.geometry, title=k, + t0=t0 * T_SCALAR, t_scalar=T_SCALAR, a_scalar=A_SCALAR) def closeEvent(self, event): for k in self.viewers: @@ -121,6 +123,75 @@ def closeEvent(self, event): ev.close() self.close() +# =------ + +class SpikeInterfaceViewer(QtWidgets.QMainWindow): + def __init__(self, recording, *args, **kwargs): + """ + :param parent: + :param sr: ibllib.io.spikeglx.Reader instance + """ + super(SpikeInterfaceViewer, self).__init__(*args, *kwargs) + self.settings = QtCore.QSettings('int-brain-lab', 'SpikeInterfaceViewer') + uic.loadUi(Path(__file__).parent.joinpath('nav_file.ui'), self) + self.setWindowIcon(QtGui.QIcon(str(Path(__file__).parent.joinpath('viewephys.svg')))) + self.horizontalSlider.setMinimum(0) + self.horizontalSlider.setSingleStep(1) + self.horizontalSlider.setTickInterval(10) + self.horizontalSlider.sliderReleased.connect(self.on_horizontalSliderReleased) + self.horizontalSlider.valueChanged.connect(self.on_horizontalSliderValueChanged) + self.label_smin.setText('0') + self.show() + self.viewers = {'recording': None} + # self.cbs = {'butterworth': self.cb_butterworth_ap, 'destripe': self.cb_destripe_ap} + self.recording = recording + self.set_recording() + + def set_recording(self, *args, **kwargs): + # enable and set slider + num_samples = self.recording.get_num_samples() + fs = self.recording.sampling_frequency + total_duration = self.recording.get_total_duration() + num_channel = self.recording.get_num_channels() + self.horizontalSlider.setMaximum(int(np.floor(num_samples / NSAMP_CHUNK))) + tmax = np.floor(num_samples / NSAMP_CHUNK) * NSAMP_CHUNK / fs + + self.label_smax.setText(f"{tmax:0.2f}s") + tlabel = f'{total_duration} seconds long \n' \ + f'{fs} Hz Sampling Frequency \n' \ + f'{num_channel} Channels' + self.label.setText(tlabel) + self.horizontalSlider.setValue(0) + self.horizontalSlider.setEnabled(True) + self.on_horizontalSliderReleased() + + def on_horizontalSliderValueChanged(self): + tcur = self.horizontalSlider.value() * NSAMP_CHUNK / self.recording.sampling_frequency + self.label_sval.setText(f"{tcur:0.2f}s") + + def on_horizontalSliderReleased(self): + first = int(float(self.horizontalSlider.value()) * NSAMP_CHUNK) + last = first + int(NSAMP_CHUNK) + data = self.recording.get_traces(start_frame=first, end_frame=last).T + + t0 = first / self.recording.sampling_frequency * 0 + # TODO if t0 is not zero the sliders bugs and does not lead to display change (empty) + print(f'{first}, {last} - data: {data.shape} - {data[0, 0:10]}') + + for k in self.viewers: + self.viewers[k] = viewephys(data, self.recording.sampling_frequency, + channels=None, title=k, + t0=t0 * T_SCALAR, t_scalar=T_SCALAR, a_scalar=A_SCALAR) + # TODO send first in viewers + def closeEvent(self, event): + for k in self.viewers: + ev = self.viewers[k] + if ev is not None: + ev.close() + self.close() + +#----- + class PickSpikes(): @@ -184,7 +255,6 @@ def remove_spike(self, indx_remove): df_updated = df_updated.reset_index(drop=True) self.update_pick(df_updated) - def indx_select(self, sample, trace, s_range=0.5 * 30000, tr_range=3): iclose = np.where(np.logical_and( np.abs(self.picks['sample'] - sample) <= (s_range + 1), @@ -192,6 +262,12 @@ def indx_select(self, sample, trace, s_range=0.5 * 30000, tr_range=3): ))[0] return iclose + def save_picks(self, save_path): + self.picks.to_parquet(save_path.joinpath('picks.pqt')) + # TODO need to check that when changing the slide bar, the picks remain in memory + # TODO need to add column T0 (in sample from start), so as to get absolute samples + + class EphysViewer(EasyQC): keyPressed = QtCore.pyqtSignal(int) diff --git a/src/viewephys/raster.py b/src/viewephys/raster.py index 399fd63..9b5498d 100644 --- a/src/viewephys/raster.py +++ b/src/viewephys/raster.py @@ -15,7 +15,7 @@ import one.alf.io as alfio from one.alf.files import get_session_path import spikeglx -from ibldsp import voltage, utils +from ibldsp import voltage from iblatlas.atlas import BrainRegions from viewephys.gui import viewephys, SNS_PALETTE @@ -181,9 +181,10 @@ def show_ephys(self, t0, tlen=.4): sos = scipy.signal.butter(**butter_kwargs, output='sos') butt = scipy.signal.sosfiltfilt(sos, raw) destripe = voltage.destripe(raw, fs=self.data.sr.fs, channel_labels=True) - self.eqc_raw = viewephys(butt, self.data.sr.fs, channels=self.data.channels, br=self.data.br, title='butt', t0=t0, t_scalar=1) - self.eqc_des = viewephys(destripe, self.data.sr.fs, channels=self.data.channels, br=self.data.br, title='destripe', t0=t0, t_scalar=1) - stripes_noise = 20 * np.log10(np.median(utils.rms(butt - destripe))) + self.eqc_raw = viewephys(butt, self.data.sr.fs, channels=self.data.channels, + br=self.data.br, title='butt', t0=t0, t_scalar=1) + self.eqc_des = viewephys(destripe, self.data.sr.fs, channels=self.data.channels, + br=self.data.br, title='destripe', t0=t0, t_scalar=1) eqc_xrange = [t0 + tlen / 2 - 0.01, t0 + tlen / 2 + 0.01] self.eqc_des.viewBox_seismic.setXRange(*eqc_xrange) self.eqc_raw.viewBox_seismic.setXRange(*eqc_xrange) diff --git a/src/viewephys/tests/test_model.py b/src/viewephys/tests/test_model.py index 5d6aa0d..92d2492 100644 --- a/src/viewephys/tests/test_model.py +++ b/src/viewephys/tests/test_model.py @@ -14,4 +14,3 @@ def test_model_dataclass(): ProbeData(spikes=spikes, clusters=clusters, channels=channels) ProbeData(spikes=pd.DataFrame(spikes), clusters=pd.DataFrame(clusters), channels=pd.DataFrame(channels)) - From 469f2058caf2a891f836a9664e5e2e5936d2627c Mon Sep 17 00:00:00 2001 From: Gaelle Date: Fri, 31 May 2024 09:26:41 +0100 Subject: [PATCH 3/9] t0 add --- src/viewephys/gui.py | 4 +++- src/viewephys/tests/test_pick.py | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/viewephys/gui.py b/src/viewephys/gui.py index 7944aea..34e5158 100644 --- a/src/viewephys/gui.py +++ b/src/viewephys/gui.py @@ -205,6 +205,7 @@ def init_df(self, nrow=0): 'trace': np.zeros(nrow, dtype=np.int32) * -1, 'amp': np.zeros(nrow, dtype=np.int32), 'group': np.zeros(nrow, dtype=np.int32), + 't0': np.zeros(nrow, dtype=np.int32) }) return init_df @@ -229,12 +230,13 @@ def load_df(self, df): else: raise ValueError('df input is not pd.DataFrame') - def new_row_frompick(self, sample=None, trace=None, amp=None, group=None): + def new_row_frompick(self, sample=None, trace=None, amp=None, group=None, t0=None): new_row = self.init_df(nrow=1) new_row['sample'] = sample new_row['trace'] = trace new_row['amp'] = amp new_row['group'] = group + new_row['t0'] = t0 return new_row def add_spike(self, new_row): diff --git a/src/viewephys/tests/test_pick.py b/src/viewephys/tests/test_pick.py index 62be664..cc80b84 100644 --- a/src/viewephys/tests/test_pick.py +++ b/src/viewephys/tests/test_pick.py @@ -3,7 +3,7 @@ import pandas as pd ps = PickSpikes() -DEFAULT_DF_COLUMNS = ['sample', 'trace', 'amp', 'group'] +DEFAULT_DF_COLUMNS = ['sample', 'trace', 'amp', 'group', 't0'] def test_init_df(): @@ -16,7 +16,7 @@ def test_init_df(): def test_new_row_frompick(): - new_row = ps.new_row_frompick(sample=1, trace=2, amp=3, group=4) + new_row = ps.new_row_frompick(sample=1, trace=2, amp=3, group=4, t0=0) # Check size np.testing.assert_(new_row.shape[0] == 1) # Check column names @@ -41,8 +41,8 @@ def test_update_pick(): # ---- # Create filled df (2 rows) - df1 = ps.new_row_frompick(sample=1, trace=2, amp=3, group=4) - df2 = ps.new_row_frompick(sample=3, trace=2, amp=3, group=5) + df1 = ps.new_row_frompick(sample=1, trace=2, amp=3, group=4, t0=0) + df2 = ps.new_row_frompick(sample=3, trace=2, amp=3, group=5, t0=0) df = pd.concat([df1, df2]) # Update ps.update_pick(df) @@ -53,8 +53,8 @@ def test_update_pick(): def test_add_spike(): - df1 = ps.new_row_frompick(sample=1, trace=2, amp=3, group=4) - df2 = ps.new_row_frompick(sample=3, trace=2, amp=3, group=5) + df1 = ps.new_row_frompick(sample=1, trace=2, amp=3, group=4, t0=0) + df2 = ps.new_row_frompick(sample=3, trace=2, amp=3, group=5, t0=0) df = pd.concat([df1, df2]) df = df.reset_index(drop=True) ps.update_pick(df1) @@ -68,10 +68,10 @@ def test_add_spike(): def test_remove_spike(): - df1 = ps.new_row_frompick(sample=1, trace=2, amp=3, group=4) - df2 = ps.new_row_frompick(sample=3, trace=2, amp=3, group=5) - df3 = ps.new_row_frompick(sample=6, trace=6, amp=3, group=5) - df4 = ps.new_row_frompick(sample=7, trace=6, amp=3, group=5) + df1 = ps.new_row_frompick(sample=1, trace=2, amp=3, group=4, t0=0) + df2 = ps.new_row_frompick(sample=3, trace=2, amp=3, group=5, t0=0) + df3 = ps.new_row_frompick(sample=6, trace=6, amp=3, group=5, t0=0) + df4 = ps.new_row_frompick(sample=7, trace=6, amp=3, group=5, t0=0) df = pd.concat([df1, df2, df3, df4]) df = df.reset_index(drop=True) # Update From fa56348dddd9d2d2ec033bd94698bb1050ed2368 Mon Sep 17 00:00:00 2001 From: Gaelle Date: Fri, 31 May 2024 09:32:55 +0100 Subject: [PATCH 4/9] rename to sample0 --- .DS_Store | Bin 0 -> 6148 bytes src/viewephys/gui.py | 6 +++--- src/viewephys/tests/test_pick.py | 20 ++++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7e645ca602f2b745481ec505f4f48485145502fc GIT binary patch literal 6148 zcmeHK%}T>S5Z<+|O({YS3Oz1(Em&g_#Y>3w1&ruHr6#0kFlI}W*h4AgtS{t~_&m<+ zZlJ~BQN+%`?l(I>yO|HNKa4T%711GMHe<|!hR9K=5j5AjwoEW0S93(+Je!7z3~Q$O znIJ%ND2`fDa zuj9#lZ10}SG!No*GE)h0G=Y%2n>dZ++>=EbWh&R#4y$8z#&&P97&<3?;W$UjzF3?( zgT5FZ50}f1wYPt8b~%1dUQ+p{iR8ezk{yE;yo0h*(W^g86PZ4OwaTa>35fw>fEXYK zHj@E!9$4MYET5_-28e+l7{L8OKtps5mKxR80UchS(ceTw0Uh5Gh{B+2u+#`15Ux`J zbt*Sc46f6`E=-(ju+*s28CNUAJZ9zU@xs;WU>7Q!aaSYt!~ij{&Ok#CZ9M-k;Fqa= z Date: Fri, 31 May 2024 09:47:46 +0100 Subject: [PATCH 5/9] update scatter upon sliding bar change --- src/viewephys/gui.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/viewephys/gui.py b/src/viewephys/gui.py index e5c7c31..40ab713 100644 --- a/src/viewephys/gui.py +++ b/src/viewephys/gui.py @@ -182,7 +182,9 @@ def on_horizontalSliderReleased(self): self.viewers[k] = viewephys(data, self.recording.sampling_frequency, channels=None, title=k, t0=t0 * T_SCALAR, t_scalar=T_SCALAR, a_scalar=A_SCALAR) + self.viewers[k].update_pick_scatter() # TODO send first in viewers + def closeEvent(self, event): for k in self.viewers: ev = self.viewers[k] @@ -357,6 +359,12 @@ def on_key_picking_mode(self, key): case QtCore.Qt.Key.Key_Space: self.ctrl.model.pick_group += 1 + def update_pick_scatter(self): + # updates scatter plot + self.ctrl.add_scatter(self.ctrl.model.pickspikes.picks['sample'] * self.ctrl.model.si, + self.ctrl.model.pickspikes.picks['trace'], + label='_picks', rgb=PICK_COLOR) + def mouseClickPickingEvent(self, event): """ When the pick action is enabled this is triggered on mouse click @@ -413,9 +421,7 @@ def mouseClickPickingEvent(self, event): self.ctrl.model.pickspikes.add_spike(new_row=new_row) # updates scatter plot - self.ctrl.add_scatter(self.ctrl.model.pickspikes.picks['sample'] * self.ctrl.model.si, - self.ctrl.model.pickspikes.picks['trace'], - label='_picks', rgb=PICK_COLOR) + self.update_pick_scatter() def save_current_plot(self, filename): """ From 450da583206770261e831ce7a0171c9cfbad0ce1 Mon Sep 17 00:00:00 2001 From: Gaelle Date: Fri, 31 May 2024 10:22:30 +0100 Subject: [PATCH 6/9] update sample0 and plot --- src/viewephys/gui.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/viewephys/gui.py b/src/viewephys/gui.py index 40ab713..6457fd7 100644 --- a/src/viewephys/gui.py +++ b/src/viewephys/gui.py @@ -182,8 +182,8 @@ def on_horizontalSliderReleased(self): self.viewers[k] = viewephys(data, self.recording.sampling_frequency, channels=None, title=k, t0=t0 * T_SCALAR, t_scalar=T_SCALAR, a_scalar=A_SCALAR) + self.viewers[k].current_sample0 = first self.viewers[k].update_pick_scatter() - # TODO send first in viewers def closeEvent(self, event): for k in self.viewers: @@ -282,6 +282,7 @@ def __init__(self, *args, **kwargs): self.menufile.setEnabled(True) self.settings = QtCore.QSettings('int-brain-lab', 'EphysViewer') self.header_curves = {} + self.current_sample0 = 0 # menus handling # menu pick self.menupick = self.menuBar().addMenu('&Pick') @@ -360,9 +361,18 @@ def on_key_picking_mode(self, key): self.ctrl.model.pick_group += 1 def update_pick_scatter(self): - # updates scatter plot - self.ctrl.add_scatter(self.ctrl.model.pickspikes.picks['sample'] * self.ctrl.model.si, - self.ctrl.model.pickspikes.picks['trace'], + + print(f"TEST: {self.current_sample0}") + + # updates scatter plot with only picks from T0 + df = self.ctrl.model.pickspikes.picks + df_local_picks = df.loc[df["sample0"] == self.current_sample0] + print(df) + print('-------') + print(df_local_picks) + + self.ctrl.add_scatter(df_local_picks['sample'] * self.ctrl.model.si, + df_local_picks['trace'], label='_picks', rgb=PICK_COLOR) def mouseClickPickingEvent(self, event): @@ -417,7 +427,7 @@ def mouseClickPickingEvent(self, event): group = 0 # TODO group # Create new row new_row = self.ctrl.model.pickspikes.new_row_frompick( - sample=tmax, trace=xmax, amp=amp, group=group) + sample=tmax, trace=xmax, amp=amp, group=group, sample0=self.current_sample0) self.ctrl.model.pickspikes.add_spike(new_row=new_row) # updates scatter plot From 5974662c032964b2ebc38e501b657e4f023121c0 Mon Sep 17 00:00:00 2001 From: Gaelle Date: Fri, 31 May 2024 11:02:03 +0100 Subject: [PATCH 7/9] save picks upon S press --- src/viewephys/gui.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/viewephys/gui.py b/src/viewephys/gui.py index 6457fd7..f4fec89 100644 --- a/src/viewephys/gui.py +++ b/src/viewephys/gui.py @@ -126,7 +126,7 @@ def closeEvent(self, event): # =------ class SpikeInterfaceViewer(QtWidgets.QMainWindow): - def __init__(self, recording, *args, **kwargs): + def __init__(self, recording, save_path_picks=None, *args, **kwargs): """ :param parent: :param sr: ibllib.io.spikeglx.Reader instance @@ -145,6 +145,12 @@ def __init__(self, recording, *args, **kwargs): self.viewers = {'recording': None} # self.cbs = {'butterworth': self.cb_butterworth_ap, 'destripe': self.cb_destripe_ap} self.recording = recording + # Set save path for picks + if save_path_picks is None: + save_path_picks = Path(__file__).parent.joinpath('picks.csv') # This will save into the viewephys folder + elif save_path_picks.suffix != '.csv': + raise ValueError('Extension of save file must be .csv') + self.save_path_picks = save_path_picks self.set_recording() def set_recording(self, *args, **kwargs): @@ -176,7 +182,6 @@ def on_horizontalSliderReleased(self): t0 = first / self.recording.sampling_frequency * 0 # TODO if t0 is not zero the sliders bugs and does not lead to display change (empty) - print(f'{first}, {last} - data: {data.shape} - {data[0, 0:10]}') for k in self.viewers: self.viewers[k] = viewephys(data, self.recording.sampling_frequency, @@ -184,6 +189,9 @@ def on_horizontalSliderReleased(self): t0=t0 * T_SCALAR, t_scalar=T_SCALAR, a_scalar=A_SCALAR) self.viewers[k].current_sample0 = first self.viewers[k].update_pick_scatter() + # Propagate save path to each view + self.viewers[k].save_path_picks = self.save_path_picks + def closeEvent(self, event): for k in self.viewers: @@ -267,9 +275,8 @@ def indx_select(self, sample, trace, s_range=0.5 * 30000, tr_range=3): return iclose def save_picks(self, save_path): - self.picks.to_parquet(save_path.joinpath('picks.pqt')) - # TODO need to check that when changing the slide bar, the picks remain in memory - # TODO need to add column T0 (in sample from start), so as to get absolute samples + self.picks.to_csv(save_path) + # chose format CSV output class EphysViewer(EasyQC): @@ -283,6 +290,7 @@ def __init__(self, *args, **kwargs): self.settings = QtCore.QSettings('int-brain-lab', 'EphysViewer') self.header_curves = {} self.current_sample0 = 0 + self.save_path_picks = None # menus handling # menu pick self.menupick = self.menuBar().addMenu('&Pick') @@ -359,17 +367,14 @@ def on_key_picking_mode(self, key): match key: case QtCore.Qt.Key.Key_Space: self.ctrl.model.pick_group += 1 + case QtCore.Qt.Key.Key_S: + print(f"Saved picks to: {self.save_path_picks}") + self.ctrl.model.pickspikes.save_picks(self.save_path_picks) def update_pick_scatter(self): - - print(f"TEST: {self.current_sample0}") - # updates scatter plot with only picks from T0 df = self.ctrl.model.pickspikes.picks df_local_picks = df.loc[df["sample0"] == self.current_sample0] - print(df) - print('-------') - print(df_local_picks) self.ctrl.add_scatter(df_local_picks['sample'] * self.ctrl.model.si, df_local_picks['trace'], From 4cfcca29dd6a6c2d25907ba1a921f97ea8f307d1 Mon Sep 17 00:00:00 2001 From: Gaelle Date: Fri, 31 May 2024 12:03:03 +0100 Subject: [PATCH 8/9] auto load picks upon start --- src/viewephys/gui.py | 22 +++++++++++++++++----- src/viewephys/tests/test_pick.py | 5 +++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/viewephys/gui.py b/src/viewephys/gui.py index f4fec89..c9c0465 100644 --- a/src/viewephys/gui.py +++ b/src/viewephys/gui.py @@ -167,10 +167,23 @@ def set_recording(self, *args, **kwargs): f'{fs} Hz Sampling Frequency \n' \ f'{num_channel} Channels' self.label.setText(tlabel) - self.horizontalSlider.setValue(0) + first = 0 # first sample + self.horizontalSlider.setValue(first) self.horizontalSlider.setEnabled(True) self.on_horizontalSliderReleased() + for k in self.viewers: + # Propagate save path to each view + self.viewers[k].save_path_picks = self.save_path_picks + self.viewers[k].current_sample0 = first + # TODO make sure picks df remain across views + # Load if exists + if self.save_path_picks.exists(): + df = pd.read_csv(self.save_path_picks) + self.viewers[k].ctrl.model.pickspikes.load_df(df) + self.viewers[k].update_pick_scatter() + + def on_horizontalSliderValueChanged(self): tcur = self.horizontalSlider.value() * NSAMP_CHUNK / self.recording.sampling_frequency self.label_sval.setText(f"{tcur:0.2f}s") @@ -189,8 +202,6 @@ def on_horizontalSliderReleased(self): t0=t0 * T_SCALAR, t_scalar=T_SCALAR, a_scalar=A_SCALAR) self.viewers[k].current_sample0 = first self.viewers[k].update_pick_scatter() - # Propagate save path to each view - self.viewers[k].save_path_picks = self.save_path_picks def closeEvent(self, event): @@ -233,7 +244,7 @@ def load_df(self, df): if isinstance(df, pd.DataFrame): # check all keys are in - indxmissing = np.where(~df.columns.isin(default_df.columns))[0] + indxmissing = np.where(~default_df.columns.isin(df.columns))[0] if len(indxmissing) > 0: raise ValueError(f'df does not contain column {default_df.columns[indxmissing]}') self.update_pick(df) @@ -275,7 +286,7 @@ def indx_select(self, sample, trace, s_range=0.5 * 30000, tr_range=3): return iclose def save_picks(self, save_path): - self.picks.to_csv(save_path) + self.picks.to_csv(save_path, index=False) # chose format CSV output @@ -395,6 +406,7 @@ def mouseClickPickingEvent(self, event): return TR_RANGE = 3 S_RANGE = int(0.5 / self.ctrl.model.si) + print(f"HERE todo s_range {S_RANGE}") qxy = self.imageItem_seismic.mapFromScene(event.scenePos()) s, tr = (qxy.x(), qxy.y()) # if event.buttons() == QtCore.Qt.MiddleButton: diff --git a/src/viewephys/tests/test_pick.py b/src/viewephys/tests/test_pick.py index 2e94538..7c5204d 100644 --- a/src/viewephys/tests/test_pick.py +++ b/src/viewephys/tests/test_pick.py @@ -84,3 +84,8 @@ def test_remove_spike(): ps.remove_spike(indx_remove=indx_remove) pd.testing.assert_frame_equal(ps.picks, df_test) + + +def test_load_df(): + df1 = ps.new_row_frompick() + ps.load_df(df1) # check no raise From 40d5e0fa43bd36556b7894c961085290aba85747 Mon Sep 17 00:00:00 2001 From: Gaelle Date: Fri, 31 May 2024 15:40:26 +0100 Subject: [PATCH 9/9] picks final --- src/viewephys/.DS_Store | Bin 0 -> 6148 bytes src/viewephys/gui.py | 3 ++- src/viewephys/picks.csv | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 src/viewephys/.DS_Store create mode 100644 src/viewephys/picks.csv diff --git a/src/viewephys/.DS_Store b/src/viewephys/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0