diff --git a/changelog.md b/changelog.md index e5819f9..b454d52 100644 --- a/changelog.md +++ b/changelog.md @@ -8,6 +8,10 @@ - Bad channels can now be dealt with by taking no action, removing them completely, or interpolating them based on their neighbours. Interpolation remains the default option - Fixed an underlying deprecation warning - Fixed an issue causing some overlay elements to not render on the brain for certain devices +- Fixed a crash when rendering some Inter-Group images with only one participant in a group +- Fixed a crash when attempting to fOLD channels without the fOLD dataset installed +- Lowered the number of rectangles in the progress bar to 24 after combining some actions +- Fixed the User Guide window to properly display information about the 24 stages and added a link to the Git wiki page # Version 1.1.7 diff --git a/flares.py b/flares.py index c2b97c8..c5ed443 100644 --- a/flares.py +++ b/flares.py @@ -2578,7 +2578,10 @@ def plot_fir_model_results(df, raw_haemo, dm, selected_event, l_bound, u_bound): dm_cols_activity = np.where([f"{selected_event}" in c for c in dm.columns])[0] dm = dm[[dm.columns[i] for i in dm_cols_activity]] - lme = smf.mixedlm("theta ~ -1 + delay:TidyCond:Chroma", df, groups=df["ID"]).fit() + try: + lme = smf.mixedlm("theta ~ -1 + delay:TidyCond:Chroma", df, groups=df["ID"]).fit() + except: + lme = smf.ols("theta ~ -1 + delay:TidyCond:Chroma", df, groups=df["ID"]).fit() # type: ignore df_sum = statsmodels_to_results(lme) df_sum["delay"] = [int(n) for n in df_sum["delay"]] @@ -3516,21 +3519,21 @@ def process_participant(file_path, progress_callback=None): if progress_callback: progress_callback(19) logger.info("19") - # Step 16: Plot GLM results + # Step 20: Generate GLM Results fig_glm_result = plot_glm_results(file_path, raw_haemo, glm_est, design_matrix) for name, fig in fig_glm_result: fig_individual[f"GLM {name}"] = fig - if progress_callback: progress_callback(21) - logger.info("21") + if progress_callback: progress_callback(20) + logger.info("20") - # Step 17: Plot channel significance + # Step 21: Generate Channel Significance fig_significance = individual_significance(raw_haemo, glm_est) for name, fig in fig_significance: fig_individual[f"Significance {name}"] = fig - if progress_callback: progress_callback(22) - logger.info("22") + if progress_callback: progress_callback(21) + logger.info("21") - # Step 18: cha, con, roi + # Step 22: Generate Channel, Region of Interest, and Contrast Results cha = glm_est.to_dataframe() # HACK: Comment out line 588 (self._renderer.show()) in _brain.py from MNE @@ -3583,10 +3586,10 @@ def process_participant(file_path, progress_callback=None): contrast_dict[condition] = contrast_vector - if progress_callback: progress_callback(23) - logger.info("23") + if progress_callback: progress_callback(22) + logger.info("22") - # Compute contrast results + # Step 23: Compute Contrast Results contrast_results = {} for cond, contrast_vector in contrast_dict.items(): @@ -3597,10 +3600,10 @@ def process_participant(file_path, progress_callback=None): cha["ID"] = file_path - if progress_callback: progress_callback(24) - logger.info("24") + if progress_callback: progress_callback(23) + logger.info("23") - + # Step 24: Finishing Up fig_bytes = convert_fig_dict_to_png_bytes(fig_individual) sanitize_paths_for_pickle(raw_haemo, epochs) diff --git a/main.py b/main.py index 1a6c8ac..d675642 100644 --- a/main.py +++ b/main.py @@ -498,29 +498,38 @@ class UserGuideWindow(QWidget): layout = QVBoxLayout() label = QLabel("Progress Bar Stages:", self) - label2 = QLabel("Stage 1: Load the snirf file\n" - "Stage 2: Check the optode positions\n" - "Stage 12: Get Short/Long Channels\n" - "Stage 3: Scalp Coupling Index\n" - "Stage 4: Signal to Noise Ratio\n" - "Stage 5: Peak Spectral Power\n" - "Stage 6: Identify bad channels\n" - "Stage 7: Interpolate bad channels\n" - "Stage 8: Optical Density\n" - "Stage 9: Temporal Derivative Distribution Repair\n" - "Stage 10: Beer Lambert Law\n" - "Stage 11: Heart Rate Filtering\n" - "Stage 13: Calculate Events from Annotations\n" - "Stage 14: Epoch Calculations\n" - "Stage 15: Design Matrix\n" - "Stage 16: General Linear Model\n" - "Stage 17: Generate Plots from the GLM\n" - "Stage 18: Individual Significance\n" - "Stage 19: Channel, Region of Interest, and Contrast Results\n" - "Stage 20: Image Conversion\n", self) + label2 = QLabel("Stage 1: Preprocessing\n" + "Stage 2: Trimming\n" + "Stage 3: Verify Optode Placement\n" + "Stage 4: Short/Long Cannels\n" + "Stage 5: Heart Rate\n" + "Stage 6: Scalp Coupling Index\n" + "Stage 7: Signal to Noise Ratio\n" + "Stage 8: Peak Spectral Power\n" + "Stage 9: Bad Channels Handling\n" + "Stage 10: Optical Density\n" + "Stage 11: Temporal Derivative Distribution Repair Filtering\n" + "Stage 12: Wavelet Filtering\n" + "Stage 13: Haemoglobin Concentration\n" + "Stage 14: Enhance Negative Correlation\n" + "Stage 15: Filter\n" + "Stage 16: Extracting Events\n" + "Stage 17: Epoch Calculations\n" + "Stage 18: Design Matrix\n" + "Stage 19: General Linear Model\n" + "Stage 20: Generate GLM Results\n" + "Stage 21: Generate Channel Significance\n" + "Stage 22: Generate Channel, Region of Interest, and Contrast Results\n" + "Stage 23: Compute Contrast Results\n" + "Stage 24: Finishing Up\n", self) + label3 = QLabel("For more information, visit the Git wiki page here.", self) + label3.setTextFormat(Qt.TextFormat.RichText) + label3.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction) + label3.setOpenExternalLinks(True) layout.addWidget(label) layout.addWidget(label2) + layout.addWidget(label3) self.setLayout(layout) @@ -1244,7 +1253,7 @@ class ProgressBubble(QWidget): self.progress_layout = QHBoxLayout() self.rects = [] - for _ in range(25): + for _ in range(24): rect = QFrame() rect.setFixedSize(10, 18) rect.setStyleSheet("background-color: white; border: 1px solid gray;") @@ -2445,9 +2454,23 @@ class ParticipantFoldChannelsWidget(QWidget): for idx in selected_indexes: if idx == 0: - - flares.fold_channels(haemo_obj) - + try: + flares.fold_channels(haemo_obj) + except: + msg_box = QMessageBox() + msg_box.setIcon(QMessageBox.Icon.Critical) + msg_box.setWindowTitle("Something went wrong!") + message = ( + "Unable to locate the fOLD files!

" + f"Please download the 'Supplementary' folder from here. " + "Once the folder is downloaded, place it in C:/Users/your username/mne_data/fOLD/fOLD-public-master/Supplementary.

" + "If you are not using Windows, please go to the FLARES Git page for more information." + ) + msg_box.setTextFormat(Qt.TextFormat.RichText) + msg_box.setText(message) + msg_box.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction) + msg_box.setStandardButtons(QMessageBox.StandardButton.Ok) + msg_box.exec() else: print(f"No method defined for index {idx}")