Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
0c5e8ee
deleted temp markdowns
pauladkisson Jan 26, 2026
de0d373
Move folder_selection to Kinter pop-up up to a dedicated module.
pauladkisson Jan 26, 2026
f030da5
Progress bar to a dedicated module.
pauladkisson Jan 26, 2026
d14abc2
Progress bar to a dedicated module.
pauladkisson Jan 26, 2026
2c2fc04
Refactored inputParameters into a class pt 1
pauladkisson Jan 26, 2026
ef2cf95
added Sidebar class
pauladkisson Jan 27, 2026
0b204a2
Organized input_parameters GUI class into methods.
pauladkisson Jan 30, 2026
d59626e
Renamed InputParameters GUI to ParameterForm.
pauladkisson Jan 30, 2026
c048d27
Renamed SavingInputParameters
pauladkisson Jan 30, 2026
711b412
Refactored step one code to a dedicated module.
pauladkisson Jan 30, 2026
9a20a25
Refactored npm_gui_prompts into a dedicated module.
pauladkisson Jan 30, 2026
c37d5ff
Added NpmChannelSelector
pauladkisson Jan 31, 2026
89abe93
Added StorenamesSelector
pauladkisson Jan 31, 2026
e5b43a8
Refactored fetchValues
pauladkisson Jan 31, 2026
436c800
Refined StorenamesSelector
pauladkisson Feb 2, 2026
daddc9f
Refactored NpmChannelSelector into StorenamesInstructionsNPM by takin…
pauladkisson Feb 2, 2026
1d8796a
renamed widgets
pauladkisson Feb 2, 2026
7d33944
Refactored configuration into a dedicated class.
pauladkisson Feb 2, 2026
39f8407
Refactored configuration init
pauladkisson Feb 2, 2026
a3db0c7
Refactored configuration dropdown helper
pauladkisson Feb 2, 2026
05399f7
Composed config with the selector.
pauladkisson Feb 2, 2026
d7daeac
refactored pure function _save out of save_button
pauladkisson Feb 2, 2026
9e952d4
refactored channel_selector out of pure _save fn
pauladkisson Feb 2, 2026
ee22ba0
refactored storenames
pauladkisson Feb 2, 2026
a21d92f
Merge branch 'analysis' into frontend
pauladkisson Feb 3, 2026
c341c09
Deduplicated writeToFile
pauladkisson Feb 3, 2026
8a2bc59
Deduplicated takeOnlyDirs
pauladkisson Feb 3, 2026
66b23b4
I moved read_raw_data to orchestration layer.
pauladkisson Feb 3, 2026
fa68e65
Fixed bug with step six: GUI.
pauladkisson Feb 3, 2026
bdb4562
Refactored DFF and z-score visualization to dedicated pre-visualize.p…
pauladkisson Feb 3, 2026
9c31299
refactored visualize into preprocessing.py
pauladkisson Feb 3, 2026
78ea92b
Added ArtifactRemovalWidget.
pauladkisson Feb 4, 2026
ea0489e
Refactored ArtifactRemovalWidget
pauladkisson Feb 4, 2026
a289d1f
Refactored ArtifactRemovalWidget
pauladkisson Feb 4, 2026
2924a2c
Refactor to visualize z-score into its own function.
pauladkisson Feb 4, 2026
86762ea
Refactored artifact removal plots to a dedicated function
pauladkisson Feb 5, 2026
bb83a2f
Moved preprocessing.py into the orchestration layer.
pauladkisson Feb 5, 2026
e41c810
Renamed the step 4 button 'pre-process and remove artifacts' to bette…
pauladkisson Feb 5, 2026
08e13e8
Refactored into a dedicated module.
pauladkisson Feb 5, 2026
1f960ca
Refactored visualization into dedicated execute fn
pauladkisson Feb 5, 2026
4440f6a
Refactored visualization into dedicated execute fn
pauladkisson Feb 5, 2026
83641a8
Moved step 5 modules to orchestration
pauladkisson Feb 5, 2026
8163cbc
Moved get_all_stores_for_combining_data to utils.utils
pauladkisson Feb 5, 2026
0e98e37
Moved scanPortsAndFind to frontend_utils
pauladkisson Feb 5, 2026
655712f
Merge branch 'analysis' into frontend
pauladkisson Feb 5, 2026
810d7da
Merge branch 'analysis' into frontend
pauladkisson Feb 5, 2026
cb37395
Moved read_Df to utils.utils
pauladkisson Feb 5, 2026
561e074
removed comment
pauladkisson Feb 5, 2026
6e693f9
Refactored Viewer class into a dedicated module.
pauladkisson Feb 6, 2026
2b4ecca
Refactored Viewer class into a dedicated module.
pauladkisson Feb 6, 2026
521dba2
Fixed bug with objects initialization.
pauladkisson Feb 6, 2026
4b07e1c
Refactored visualization front-end code into dedicated dashboard module.
pauladkisson Feb 6, 2026
039b36e
Refactored visualization front-end code into dedicated dashboard module.
pauladkisson Feb 6, 2026
46f148e
Renamed some classes
pauladkisson Feb 6, 2026
7d6db84
Renamed some classes
pauladkisson Feb 6, 2026
2733c54
Move to visualization, step 6, to orchestration layer.
pauladkisson Feb 6, 2026
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
38 changes: 2 additions & 36 deletions src/guppy/analysis/io_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,10 @@

import h5py
import numpy as np
import pandas as pd

logger = logging.getLogger(__name__)

from ..utils.utils import takeOnlyDirs

def takeOnlyDirs(paths):
removePaths = []
for p in paths:
if os.path.isfile(p):
removePaths.append(p)
return list(set(paths) - set(removePaths))
logger = logging.getLogger(__name__)


# find files by ignoring the case sensitivity
Expand Down Expand Up @@ -143,20 +136,6 @@ def get_coords(filepath, name, tsNew, removeArtifacts): # TODO: Make less redun
return coords


def get_all_stores_for_combining_data(folderNames):
op = []
for i in range(100):
temp = []
match = r"[\s\S]*" + "_output_" + str(i)
for j in folderNames:
temp.append(re.findall(match, j))
temp = sorted(list(np.concatenate(temp).flatten()), key=str.casefold)
if len(temp) > 0:
op.append(temp)

return op


# for combining data, reading storeslist file from both data and create a new storeslist array
def check_storeslistfile(folderNames):
storesList = np.array([[], []])
Expand Down Expand Up @@ -197,19 +176,6 @@ def get_control_and_signal_channel_names(storesList):
return channels_arr


# function to read h5 file and make a dataframe from it
def read_Df(filepath, event, name):
event = event.replace("\\", "_")
event = event.replace("/", "_")
if name:
op = os.path.join(filepath, event + "_{}.h5".format(name))
else:
op = os.path.join(filepath, event + ".h5")
df = pd.read_hdf(op, key="df", mode="r")

return df


def make_dir_for_cross_correlation(filepath):
op = os.path.join(filepath, "cross_correlation_output")
if not os.path.exists(op):
Expand Down
2 changes: 1 addition & 1 deletion src/guppy/analysis/psth_average.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
from .io_utils import (
make_dir_for_cross_correlation,
makeAverageDir,
read_Df,
write_hdf5,
)
from .psth_utils import create_Df_for_psth, getCorrCombinations
from ..utils.utils import read_Df

logger = logging.getLogger(__name__)

Expand Down
15 changes: 15 additions & 0 deletions src/guppy/analysis/standard_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,18 @@ def read_freq_and_amp_from_hdf5(filepath, name):
df = pd.read_hdf(op, key="df", mode="r")

return df


def write_transients_to_hdf5(filepath, name, z_score, ts, peaksInd):
event = f"transient_outputs_{name}"
write_hdf5(z_score, event, filepath, "z_score")
write_hdf5(ts, event, filepath, "timestamps")
write_hdf5(peaksInd, event, filepath, "peaksInd")


def read_transients_from_hdf5(filepath, name):
event = f"transient_outputs_{name}"
z_score = read_hdf5(event, filepath, "z_score")
ts = read_hdf5(event, filepath, "timestamps")
peaksInd = read_hdf5(event, filepath, "peaksInd")
return z_score, ts, peaksInd
Empty file added src/guppy/frontend/__init__.py
Empty file.
75 changes: 75 additions & 0 deletions src/guppy/frontend/artifact_removal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import logging
import os

import matplotlib.pyplot as plt
import numpy as np

from ..visualization.preprocessing import visualize_control_signal_fit

logger = logging.getLogger(__name__)

# Only set matplotlib backend if not in CI environment
if not os.getenv("CI"):
plt.switch_backend("TKAgg")


class ArtifactRemovalWidget:

def __init__(self, filepath, x, y1, y2, y3, plot_name, removeArtifacts):
self.coords = [] # List to store selected coordinates
self.filepath = filepath
self.plot_name = plot_name

if (y1 == 0).all() == True:
y1 = np.zeros(x.shape[0])

coords_path = os.path.join(filepath, "coordsForPreProcessing_" + plot_name[0].split("_")[-1] + ".npy")
artifacts_have_been_removed = removeArtifacts and os.path.exists(coords_path)
name = os.path.basename(filepath)
self.fig, self.ax1, self.ax2, self.ax3 = visualize_control_signal_fit(
x, y1, y2, y3, plot_name, name, artifacts_have_been_removed
)

self.cid = self.fig.canvas.mpl_connect("key_press_event", self._on_key_press)
self.fig.canvas.mpl_connect("close_event", self._on_close)

def _on_key_press(self, event):
"""Handle key press events for artifact selection.

Pressing 'space' draws a vertical line at the cursor position to mark artifact boundaries.
Pressing 'd' removes the most recently added line.
"""
if event.key == " ":
ix, iy = event.xdata, event.ydata
logger.info(f"x = {ix}, y = {iy}")
self.ax1.axvline(ix, c="black", ls="--")
self.ax2.axvline(ix, c="black", ls="--")
self.ax3.axvline(ix, c="black", ls="--")

self.fig.canvas.draw()

self.coords.append((ix, iy))

return self.coords

elif event.key == "d":
if len(self.coords) > 0:
logger.info(f"x = {self.coords[-1][0]}, y = {self.coords[-1][1]}; deleted")
del self.coords[-1]
self.ax1.lines[-1].remove()
self.ax2.lines[-1].remove()
self.ax3.lines[-1].remove()
self.fig.canvas.draw()

return self.coords

def _on_close(self, _event):
"""Handle figure close event by saving coordinates and cleaning up."""
if self.coords and len(self.coords) > 0:
name_1 = self.plot_name[0].split("_")[-1]
np.save(os.path.join(self.filepath, "coordsForPreProcessing_" + name_1 + ".npy"), self.coords)
logger.info(
f"Coordinates file saved at {os.path.join(self.filepath, 'coordsForPreProcessing_'+name_1+'.npy')}"
)
self.fig.canvas.mpl_disconnect(self.cid)
self.coords = []
19 changes: 19 additions & 0 deletions src/guppy/frontend/frontend_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import logging
import socket
from random import randint

logger = logging.getLogger(__name__)


def scanPortsAndFind(start_port=5000, end_port=5200, host="127.0.0.1"):
while True:
port = randint(start_port, end_port)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0.001) # Set timeout to avoid long waiting on closed ports
result = sock.connect_ex((host, port))
if result == 0: # If the connection is successful, the port is open
continue
else:
break

return port
Loading
Loading