diff --git a/Controller.py b/Controller.py index 0a4d9ba..7bd91b4 100644 --- a/Controller.py +++ b/Controller.py @@ -36,11 +36,11 @@ class Controller: self.stim_values = {} self.recording_times = {} - def save_parameters(self): + def save_parameters(self, folder_path): header = "trial_index,threshold,min_window,step_size\n" for repro in self.thresholds.keys(): # TODO change '.' to self.data_path after testing: - with open("." + "/{}_thresholds.csv".format(repro), "w") as threshold_file: + with open(folder_path + "/{}_thresholds.csv".format(repro), "w") as threshold_file: threshold_file.write(header) for i in range(len(self.sorting[repro])): if len(self.thresholds[repro][i]) == 0: @@ -53,7 +53,14 @@ class Controller: step = self.thresholds[repro][i][2] threshold_file.write("{},{},{},{}\n".format(i, thresh, min_window, step)) print("Thresholds saved!") + + def save_redetected_spikes(self, folder_path): # TODO save redetected spikes: + header = "trial_index,threshold,min_window,step_size\n" + for repro in self.thresholds.keys(): + # TODO change '.' to self.data_path after testing: + with open(folder_path + "/{}_thresholds.csv".format(repro), "w") as threshold_file: + threshold_file.write(header) def get_repros(self): return self.parser.get_measured_repros() diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..cdc758d --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,15 @@ +# Spike redetector + +###redetection parameters: + +- **Threshold**: number of standard deviations between a maximum and a minimum to count as a spike. +- **Min window size**: The minimum size of a window (as number of indices) in which spikes are detected. The voltage trace is split into parts + if the maximum or minimum of the next part are too different from the current part. + This makes the estimation of the STD a lot more stable between trials where the absolute voltage might wander. +- **step size**: The number of indices that are used in each step while trying to increase the size of the window. + +### plot controls: + +- Drag and drop with LMB + +- zoom control with RMB -> press and hold; up down is zoom on y-axis while left right is zoom on x-axis \ No newline at end of file diff --git a/SpikeRedetectGui.py b/SpikeRedetectGui.py index 4152943..7555702 100644 --- a/SpikeRedetectGui.py +++ b/SpikeRedetectGui.py @@ -106,7 +106,6 @@ class SpikeRedetectGui(QWidget): self.grouping_checkbox.setText("Group by Stimulus Value:") panel_layout.addWidget(self.grouping_checkbox) - trial_label = QLabel("Trial:") panel_layout.addWidget(trial_label) self.trial_spinbox = QSpinBox(self) @@ -156,6 +155,11 @@ class SpikeRedetectGui(QWidget): button.clicked.connect(self.save_threshold_parameters) panel_layout.addWidget(button) + button = QPushButton('Save redetected spikes!', self) + button.setToolTip('Save redetected spikes with the accepted thresholds.') + button.clicked.connect(self.save_redetected_spikes) + panel_layout.addWidget(button) + panel.setLayout(panel_layout) middle.addWidget(panel) @@ -202,18 +206,31 @@ class SpikeRedetectGui(QWidget): for val in self.controller.get_stim_values(repro): self.stim_val_box.addItem(str(val)) - - @pyqtSlot() def accept_redetection(self): params = (self.threshold_spinbox.value(), self.window_spinbox.value(), self.step_spinbox.value()) - self.controller.set_redetection_params(self.repro_box.currentText(), self.trial_idx, params) - - self.trial_change(self.trial_idx + 1) + if not self.grouping_checkbox.isChecked(): + self.controller.set_redetection_params(self.repro_box.currentText(), self.trial_idx, params) + self.trial_change(self.trial_idx + 1) + else: + # TODO set params for all trials of the current stim value + # also choose next trial idx that has no accepted params yet and update stim_val_box + pass @pyqtSlot() def save_threshold_parameters(self): - self.controller.save_parameters() + # TODO add question for save_path + data_path = QFileDialog.getExistingDirectory(self, directory=self.controller.data_path, caption='Select a folder to save the parameters:') + if data_path is None: + return + self.controller.save_parameters(data_path) + + @pyqtSlot() + def save_redetected_spikes(self): + data_path = QFileDialog.getExistingDirectory(self, directory=self.controller.data_path, caption='Select a folder to save the redetected spikes:') + if data_path is None: + return + self.controller.save_redetected_spikes(data_path) class PlotCanvas(FigureCanvas): @@ -329,7 +346,8 @@ class PlotCanvas(FigureCanvas): ax.eventplot(spiketimes, lineoffsets=max(trace) + 2, colors="black") redetect = detect_spiketimes(time, trace, redetection_vars[0], redetection_vars[1], redetection_vars[2]) ax.eventplot(redetect, lineoffsets=max(trace) + 1, colors="red") - ax.set_title('Trial XYZ') + ax.plot(redetect, trace[np.round(np.array((redetect + recording_times[0]) / sampling_interval)).astype(int)], 'o', color='red') + ax.set_title('Trial') if self.current_repro == repro: ax.set_xlim(xlim) diff --git a/main.py b/main.py index 164da56..223d393 100644 --- a/main.py +++ b/main.py @@ -14,7 +14,7 @@ sam_file = "../neuronModel/data/final_sam/2011-10-25-ad-invivo-1" def main(): app = QApplication(sys.argv) - ex = SpikeRedetectGui(sam_file) + ex = SpikeRedetectGui(test_file) sys.exit(app.exec_())