diff --git a/changelog.md b/changelog.md index 53705eb..28ffc70 100644 --- a/changelog.md +++ b/changelog.md @@ -16,13 +16,18 @@ - Currently tracking is only supported on loaded files, parameters on the right side of the screen, and when processing has completed. Per-file metadata or processing stages are not currently implemented - Clicking close on the Main Window will now properly close all sub windows when closing the application and closing the application with unsaved changes will now prompt to save a project or discard changes. Fixes [Issue 87](https://git.research.dezeeuw.ca/tyler/flares/issues/87) - The Save button under the File menu no longer asks for a destination if a saved project was already loaded. Fixes [Issue 72](https://git.research.dezeeuw.ca/tyler/flares/issues/72) +- Added an icon to the 'Toggle Status Bar' view option +- Status bar visibility and window layout sizes are now stored between application sessions. Fixes [Issue 88](https://git.research.dezeeuw.ca/tyler/flares/issues/88) - The popup that appeared when a project was saved has now been moved to a message displayed from the status bar - Moved all loading of files, loading of folders, loading of projects, and saving of projects to a new file for easier future development - Changed the working of some messages on the status bar to better reflect what has occurred +- Added a new terminal command 'assoc' to associate .flare files to the application. This is undergoing testing and may not function correctly. +- Removed the debug flag from the application package, which may speed up the application. Fixes [Issue 11](https://git.research.dezeeuw.ca/tyler/flares/issues/11) - Fixed an issue where the two Group Stats Viewer windows would crash the application once attempted to be opened if JSON_LOCATION was not set - Fixed an issue where participants could be skipped when processing multiple participants at once which could prevent overall processing from completing - Fixed an issue where when loading a save file some list dropdowns could go blue and bold even if the value was default - Fixed an issue where the Analysis button would not be clickable if the user had previously pushed Clear. Fixes [Issue 83](https://git.research.dezeeuw.ca/tyler/flares/issues/83) +- Fixed an issue where removing all files via their right click feature would cause the Process button to still be visible. Fixes [Issue 91](https://git.research.dezeeuw.ca/tyler/flares/issues/91) - Fixed an issue where some popup windows would not properly display the application name when they would open - Fixed an issue where the welcome dialog image would not display correctly on macOS - Fixed an issue where the Linux version would fail at 0 seconds when attempting to process files diff --git a/changelog_major.md b/changelog_major.md index af465b9..9180aad 100644 --- a/changelog_major.md +++ b/changelog_major.md @@ -1,87 +1,35 @@ -# Version 1.5.2 +# Version 1.6.0 -- Opening both a file or a folder now contains support for reading some metadata from the BIDS structure. Both options will still function if this metadata is not present -- Currently only the AGE metadata is grabbed and is auto populated into the participants AGE field and displayed on their bubble -- If the participants have metadata, a popup will be displayed asking if the user wants to group the participants by their metadata -- If the user wants to create groups, a dialog box is presented allowing them to do so. Once completed, the GROUP value will be automatically applied to all applicable participants -- A new options menu item has been added: Regroup Files from Metadata. This will allow the dialog to be opened at a later time with a popup appearing if there is no metadata present -- Added two new options to the Export to CSV Viewer: Export Configuration to CSV and Paragraph of Configuration -- Export Configuration to CSV will export the parameters utilized for each file into a CSV formatted file to provide additional validation of what parameters were used -- Paragraph of Configuration will generate a ready-to-go paragraph explaining in a more friendly and easy to follow manner of what parameters were used -- Chunked the loading of folders to provide more feedback to the user instead of hanging the application waiting for all files to load -- New parameters have been added to the right side of the screen! This allows for more flexibility and customizability when processing -- A new Preference Menu option has been added: Show Advanced Parameters. This keeps some of the parameters hidden when not checked. Since this is a preference, it will be saved when reopening the application -- Advanced parameters should only be changed if you know what you are doing, and will have a yellow warning symbol next to them to avoid potential confusion on what parameters are advanced -- Optimized some of the calculations in Scalp Coupling Index to speed up Step 6 by up to ~25% on a per-file basis -- Removed duplicate/redundant calculations in Peak Spectral Power to speed up Step 8 by up to ~50% on a per-file basis -- Changed how the figures are generated when processing to speed up Step 28 by up to ~85% on a per-file basis -- Removed unused methods inside the processing file to slightly speed up application load time -- Fixed an issue with the build script not properly updating the version string causing the application to falsely think that an update was always available -- Fixed an issue where parameters that were dependent on SHORT_CHANNELS were not properly being updated -- Fixed an issue where files that failed processing were not having their progress bar turn red at the step that failed -- Fixed an issue where progress bars were not updating when MAX_WORKERS was set to a value higher than default -- Fixed an issue where a high value of MAX_WORKERS was never hit the targeted value due to not being able to spawn the workers fast enough -- Fixed an issue causing numerous 'Invalid File' popups to appear upon closing the application while files were still having their initial metadata being grabbed -- Fixed an issue where both 'Update events in snirf file...' windows could not be open at the same time -- Fixed an issue where externally updating a participant's metadata when they were selected would cause the application to crash -- Fixed an issue where there was a redundant checking of dependencies when the parameters on the right side of the screen were being calculated -- Fixed an issue in which clicking menu options too fast would cause the application to hard crash -- Added a time elapsed message to the status bar denoting how long processing has been going on for. When processing is complete, it will change to be the time elapsed -- Added a speedup multiplier to show how much time was saved by having MAX_WORKERS not set to 1. This multiplier is calculated using a naive approach and may not be accurate -- Removed redundant font styling when parameters were changed from their default values - - -# Version 1.5.1 - -- Opening a folder is now minimally BIDS compatible. It will recursively go through all folders, but not load external metadata -- Renamed options in the Viewer Launcher window to better denote what actions they can perform -- 2 new analysis options have been added in the viewer launcher window: Inter-Group Stats and Cross-Group Stats -- Each of these analysis options have lots of text explaining what they do when their respective windows are opened -- The parameter input dialog in the analysis windows will now be able to scroll down when lots of parameters are required -- When a project is saved, it automatically will populate into the Recent Projects menu. Fixes [Issue 86](https://git.research.dezeeuw.ca/tyler/flares/issues/86) -- The description when clicking "Why are these useful?" underneath the per-file parameters is no longer placeholder text. Fixes [Issue 85](https://git.research.dezeeuw.ca/tyler/flares/issues/85) -- Added a new parameter section "Region of Interest". It has one parameter of "JSON_LOCATION", a json file containing Region of Interest data -- Temporarily removed the parameter REMOVE_EVENTS due to its functionality being removed because of a memory leak -- Fixed participant metadata remaining in the background when the participant was removed. Fixes [Issue 82](https://git.research.dezeeuw.ca/tyler/flares/issues/82) -- Fixed processing remaining active hidden in the background when the "Clear" button was pushed. Fixes [Issue 81](https://git.research.dezeeuw.ca/tyler/flares/issues/81) -- Now when "Clear" is pushed while data is processing, a popup will appear ensuring that the user understands that pushing "Clear" will stop processing -- Reset to Default Configuration will now properly reset all of the parameters to their default values. Fixes [Issue 90](https://git.research.dezeeuw.ca/tyler/flares/issues/90) -- A confirmation popup will now display once the application has been reset to default in addition to the status bar message -- Changed the improper display text of "Cross Validation" to now properly read as "Coefficient of Variation" -- Changed the parameters "CV" and "CV_THRESHOLD" to now be "COEFF_VAR and COEFF_VAR_THRESHOLD" -- Changed the improper display text of "Mean Absolute Deviation" to now properly read as "Median Absolute Deviation" -- Changed the parameters "SHORT_CHANNEL", "SHORT_CHANNEL_THRESH", and "LONG_CHANNEL_THRESH" to now be "SHORT_CHANNELS", "SHORT_CHANNELS_THRESHOLD", and "LONG_CHANNELS_THRESHOLD" -- Changed the parameter section "Channel Variance" to now be "Sensor Dropout" to better reflect the action it performs, not the method employed to calculate it -- Changed the parameters "CHANNEL_VAR" and "CHANNEL_THRESH" to now be "SENSOR_DROPOUT" and "SENSOR_DROPOUT_VARIANCE_THRESHOLD" -- Changed the messaged displayed when the application crashes to better reflect what occurred -- Changed the processing stages 25-27 and updates their messages to better reflect their actions that they now perform -- Changed stage 25 from "Generate Channel Significance" to "Generate Channel Results" -- Changed stage 26 from "Generate Channel, Region of Interest, and Contrast Results" to "Generate Region of Interest Results" -- Changed stage 27 from "Compute Contrast Results" to "Generate Contrast Results" -- Changed backend code to only load required methods and not load all methods every time -- Fixed string parameters not going blue and bold when their value was different than default -- Fixed all parameters not going blue and bold when a save file is loaded containing values that differ from default -- Fixed a crucial bug where short channels were not being processed and filtered the same way as long channels before being used as regressors -- Fixed a crucial bug where short channels were being presented to the design matrix as normal long channels -- Fixed a crucial bug where long channels could be interpolated from short channels. Short channels are still potentially interpolated from long channels. See [this link](https://git.research.dezeeuw.ca/tyler/flares/issues/80) for more information regarding this issue. -- Decreased unnecessary processing time when fOLDing channels by an order of magnitude. Fixes [Issue 84](https://git.research.dezeeuw.ca/tyler/flares/issues/84) -- Added a welcome message when the terminal is opened, resized the terminal, and added more commands - - -# Version 1.5.0 - -- This release introduces a new configuration file that may break existing installs. If your application does not update correctly, please download fresh from [this link.](https://git.research.dezeeuw.ca/tyler/flares/releases/) -- This release features an almost complete rewrite of backend files. If you encounter any problems, please raise an issue at [this link.](https://git.research.dezeeuw.ca/tyler/flares/issues/new) -- New configuration file has been added! Now your choices of preferences will be saved when the application is closed and re-opened. If the configuration file is missing, a new one will be generated -- Recent files and recent projects are now saved and appear under the File menu for quick resuming -- The new option "Reset to Default Configuration" under the Options menu will reset the configuration file back to its default values and remove any recent files -- A welcome dialog will now display the changelog on first startup and after every update. This popup will only appear once but can be reopened under the Options menu through the button "Show Update Changelog" -- Changed the hotkey for "Update optodes in snirf file..." to be F9 instead of F6 -- Revamped the fOLD channels window. Images containing the pie charts are now interactable! Click whitespace to expand the whole image and click a chart to expand it. -- fOLD progress bar when processing now updates the percentages live. Fixes [Issue 76](https://git.research.dezeeuw.ca/tyler/flares/issues/76) -- Overall pie charts on an individual and global basis are now generated. Fixes [Issue 78](https://git.research.dezeeuw.ca/tyler/flares/issues/78) -- Brodmann images are now available when examining a pie chart to understand which area is being reported. Fixes [Issue 77](https://git.research.dezeeuw.ca/tyler/flares/issues/77) -- Added a new option 'Folding Bypass' to the Preferences Menu. This skips most processing steps and the only analysis option available will be to fold. Parameters on the right will be ignored. Fixes [Issue 75](https://git.research.dezeeuw.ca/tyler/flares/issues/75) -- Fixed an issue where the fOLD analysis progress window would go unresponsive before processing participants. Fixes [Issue 45](https://git.research.dezeeuw.ca/tyler/flares/issues/45), Fixes [Issue 34](https://git.research.dezeeuw.ca/tyler/flares/issues/34) -- Added a feature to hover over the 28-stage progress bar and see which state the progress bar is at. Fixes [Issue 74](https://git.research.dezeeuw.ca/tyler/flares/issues/74) -- Loading a broken snirf file no longer hangs its processing and can now be removed from the list. Fixes [Issue 73](https://git.research.dezeeuw.ca/tyler/flares/issues/73) \ No newline at end of file +- This is potentially a save-changing release due to adding more data into the save file, renaming existing data, and changing what part of the code saves data. Please update your project files to ensure compatibility +- It is still possible to load older saves by enabling 'Incompatible Save Bypass' from the Preferences menu, but your mileage may vary +- Optimized calculations being performed when calculating the Heart Rate to speed up step 5 by up to ~35% on a per-file basis +- Optimized calculations being performed when running the General Linear Model to speed up step 5 by up to ~35% on a per-file basis +- The Group Stats Viewer windows will now properly load the Right/Left or Front/Back fallback ROIs if JSON_LOCATION is not set +- Changed the warning message for lots of short channels and changed when it shows to be percentage based (35%) instead of numerical based (6) +- Renames GENDER to SEX to better represent the values that the field expects and to be more BIDS compliant +- Changed the Assign Groups by AGE window to now be the Assign Groups by Metadata window and added support for grouping by other metadata values +- Added a new metadata value of HAND to allow for grouping participants based on their handiness +- Updated the layout of the participant metadata area to better accommodate current and future metadata values +- Updated the message displayed when "Why are these useful?" is clicked to better represent what the values are used for and to accommodate the new metadata values +- Changed the application title to now show what project you are working on. If you are not working on a project, it will display 'Untitled' +- Tracking of current save states is now present and an asterisk will now appear in the title bar when a project has not been saved +- Currently tracking is only supported on loaded files, parameters on the right side of the screen, and when processing has completed. Per-file metadata or processing stages are not currently implemented +- Clicking close on the Main Window will now properly close all sub windows when closing the application and closing the application with unsaved changes will now prompt to save a project or discard changes. Fixes [Issue 87](https://git.research.dezeeuw.ca/tyler/flares/issues/87) +- The Save button under the File menu no longer asks for a destination if a saved project was already loaded. Fixes [Issue 72](https://git.research.dezeeuw.ca/tyler/flares/issues/72) +- Added an icon to the 'Toggle Status Bar' view option +- Status bar visibility and window layout sizes are now stored between application sessions. Fixes [Issue 88](https://git.research.dezeeuw.ca/tyler/flares/issues/88) +- The popup that appeared when a project was saved has now been moved to a message displayed from the status bar +- Moved all loading of files, loading of folders, loading of projects, and saving of projects to a new file for easier future development +- Changed the working of some messages on the status bar to better reflect what has occurred +- Added a new terminal command 'assoc' to associate .flare files to the application. This is undergoing testing and may not function correctly. +- Removed the debug flag from the application package, which may speed up the application. Fixes [Issue 11](https://git.research.dezeeuw.ca/tyler/flares/issues/11) +- Fixed an issue where the two Group Stats Viewer windows would crash the application once attempted to be opened if JSON_LOCATION was not set +- Fixed an issue where participants could be skipped when processing multiple participants at once which could prevent overall processing from completing +- Fixed an issue where when loading a save file some list dropdowns could go blue and bold even if the value was default +- Fixed an issue where the Analysis button would not be clickable if the user had previously pushed Clear. Fixes [Issue 83](https://git.research.dezeeuw.ca/tyler/flares/issues/83) +- Fixed an issue where removing all files via their right click feature would cause the Process button to still be visible. Fixes [Issue 91](https://git.research.dezeeuw.ca/tyler/flares/issues/91) +- Fixed an issue where some popup windows would not properly display the application name when they would open +- Fixed an issue where the welcome dialog image would not display correctly on macOS +- Fixed an issue where the Linux version would fail at 0 seconds when attempting to process files +- Fixed an issue where fOLDing channels could cause the same channels to be repeated misaligning the labels +- Fixed all instances of the word MacOS to now read macOS to match Apple branding \ No newline at end of file diff --git a/icons/short_text_24dp_1F1F1F.svg b/icons/short_text_24dp_1F1F1F.svg new file mode 100644 index 0000000..f73fa49 --- /dev/null +++ b/icons/short_text_24dp_1F1F1F.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/main.py b/main.py index f187b3d..0e2905d 100644 --- a/main.py +++ b/main.py @@ -56,9 +56,8 @@ recent_projects = [View] status_bar = true -left_top = 0 -left_bottom = 0 -right = 0 +main_h_ratio = 0.5778 +left_v_ratio = 0.30 [Options] show_welcome_dialog = false @@ -520,6 +519,7 @@ class MainApplication(QMainWindow): self.folder_paths = [] self.section_widget = None self.first_run = True + self.show_status_bar = False self.is_2d_bypass = False self.incompatible_save_bypass = False self.missing_events_bypass = False @@ -710,6 +710,9 @@ class MainApplication(QMainWindow): self.main_h_splitter.setSizes([600, 400]) self.left_v_splitter.setSizes([300, 700]) + self.main_h_splitter.splitterMoved.connect(self.save_splitter_ratios) + self.left_v_splitter.splitterMoved.connect(self.save_splitter_ratios) + self.progress_update_signal.connect(self.update_file_progress) self.update_window_title() self.update_sections(0) @@ -781,11 +784,13 @@ class MainApplication(QMainWindow): edit_menu.addAction(make_action(name, shortcut, slot, icon=icon)) # View menu - # TODO: Pretty this like the rest of the menus? + + self.view_actions = {} + view_menu = menu_bar.addMenu("View") - toggle_statusbar_action = make_action("Toggle Status Bar", checkable=True, checked=True, slot=None) + toggle_statusbar_action = make_action("Toggle Status Bar", "", self.toggle_statusbar, True, True, resource_path("icons/short_text_24dp_1F1F1F.svg")) view_menu.addAction(toggle_statusbar_action) - toggle_statusbar_action.toggled.connect(self.statusbar.setVisible) + self.view_actions["statusbar"] = toggle_statusbar_action # Reset Layout Action view_menu.addSeparator() @@ -1083,20 +1088,19 @@ class MainApplication(QMainWindow): self.is_saved = not (files_dirty or params_dirty or meta_dirty) self.update_window_title() + def reset_window_layout(self): """ Snaps all draggable splitters back to their default proportional positions. """ - total_width = self.main_h_splitter.width() - left_w = int(total_width * 26 / 45) - right_w = total_width - left_w - self.main_h_splitter.setSizes([left_w, right_w]) + self.main_h_ratio = 26 / 45 + self.left_v_ratio = 0.30 - total_height = self.left_v_splitter.height() - top_h = int(total_height * 0.30) - bottom_h = total_height - top_h - self.left_v_splitter.setSizes([top_h, bottom_h]) + self.apply_splitter_ratios() + + self._update_config_setting("View", "main_h_ratio", round(self.main_h_ratio, 4)) + self._update_config_setting("View", "left_v_ratio", round(self.left_v_ratio, 4)) self.statusBar().showMessage("Window layout has been reset to default.", 3000) @@ -1133,39 +1137,44 @@ class MainApplication(QMainWindow): self.top_left_widget.paste() # Trigger paste self.statusbar.showMessage("Pasted from clipboard") # Show status message - def _update_config_setting(self, key, value): + def _update_config_setting(self, group, key, value): """Helper to update memory configuration and save to disk.""" # configparser expects string values - file_cfg.set("Preferences", key, str(value).lower()) + file_cfg.set(group, key, str(value).lower()) try: with open(cfg_path, "w") as f: file_cfg.write(f) except Exception as e: print(f"Warning: Could not save setting '{key}' to disk: {e}") + def toggle_statusbar(self, checked): + self.show_status_bar = checked + self._update_config_setting("View", "status_bar", checked) + self.statusbar.setVisible(checked) + def is_2d_bypass_func(self, checked): self.is_2d_bypass = checked - self._update_config_setting("2d_data_bypass", checked) + self._update_config_setting("Preferences", "2d_data_bypass", checked) def incompatable_save_bypass_func(self, checked): self.incompatible_save_bypass = checked - self._update_config_setting("incompatible_save_bypass", checked) + self._update_config_setting("Preferences", "incompatible_save_bypass", checked) def missing_events_bypass_func(self, checked): self.missing_events_bypass = checked - self._update_config_setting("missing_events_bypass", checked) + self._update_config_setting("Preferences", "missing_events_bypass", checked) def analysis_clearing_bypass_func(self, checked): self.analysis_clearing_bypass = checked - self._update_config_setting("analysis_clearing_bypass", checked) + self._update_config_setting("Preferences", "analysis_clearing_bypass", checked) def folding_bypass_func(self, checked): self.folding_bypass = checked - self._update_config_setting("folding_bypass", checked) + self._update_config_setting("Preferences", "folding_bypass", checked) def advanced_parameters_func(self, checked): self.advanced_parameters = checked - self._update_config_setting("advanced_parameters", checked) + self._update_config_setting("Preferences", "advanced_parameters", checked) self.update_sections(0) def about_window(self): @@ -1275,6 +1284,10 @@ class MainApplication(QMainWindow): self.folding_bypass = file_cfg.getboolean("Preferences", "folding_bypass", fallback=False) self.advanced_parameters = file_cfg.getboolean("Preferences", "advanced_parameters", fallback=False) + self.show_status_bar = file_cfg.getboolean("View", "status_bar", fallback=False) + self.main_h_ratio = file_cfg.getfloat("View", "main_h_ratio", fallback=26 / 45) + self.left_v_ratio = file_cfg.getfloat("View", "left_v_ratio", fallback=0.30) + # 2. Sync the UI Menu checkmarks visually if hasattr(self, 'pref_actions'): self.pref_actions["2d_data_bypass"].setChecked(self.is_2d_bypass) @@ -1284,6 +1297,9 @@ class MainApplication(QMainWindow): self.pref_actions["folding_bypass"].setChecked(self.folding_bypass) self.pref_actions["advanced_parameters"].setChecked(self.advanced_parameters) + if hasattr(self, 'view_actions'): + self.view_actions["statusbar"].setChecked(self.show_status_bar) + if self.advanced_parameters: self.update_sections(0) @@ -1293,7 +1309,45 @@ class MainApplication(QMainWindow): if hasattr(self, 'recent_projects_menu'): self.project_manager.update_recent_projects_menu() - + QTimer.singleShot(0, self.apply_splitter_ratios) + + + def save_splitter_ratios(self): + """Calculates current splitter ratios and saves them via _update_config_setting.""" + # Calculate main horizontal splitter ratio + if hasattr(self, 'main_h_splitter'): + h_sizes = self.main_h_splitter.sizes() + h_total = sum(h_sizes) + if h_total > 0: + self.main_h_ratio = round(h_sizes[0] / h_total, 4) + self._update_config_setting("View", "main_h_ratio", self.main_h_ratio) + + # Calculate left vertical splitter ratio + if hasattr(self, 'left_v_splitter'): + v_sizes = self.left_v_splitter.sizes() + v_total = sum(v_sizes) + if v_total > 0: + self.left_v_ratio = round(v_sizes[0] / v_total, 4) + self._update_config_setting("View", "left_v_ratio", self.left_v_ratio) + + + def apply_splitter_ratios(self): + """Applies saved ratio positions to main_h_splitter and left_v_splitter.""" + if hasattr(self, 'main_h_splitter'): + print("Splitter actual width:", self.main_h_splitter.width()) + total_width = self.main_h_splitter.width() + if total_width > 0: + left_w = int(total_width * self.main_h_ratio) + right_w = total_width - left_w + self.main_h_splitter.setSizes([left_w, right_w]) + + if hasattr(self, 'left_v_splitter'): + total_height = self.left_v_splitter.height() + if total_height > 0: + top_h = int(total_height * self.left_v_ratio) + bottom_h = total_height - top_h + self.left_v_splitter.setSizes([top_h, bottom_h]) + def restore_sections_from_config(self, config): """ @@ -1639,6 +1693,9 @@ class MainApplication(QMainWindow): if key_to_delete: del self.bubble_widgets[key_to_delete] + if hasattr(self, 'button1') and not self.bubble_widgets: + self.button1.setVisible(False) + # Remove from selected_paths if hasattr(self, 'selected_paths'): try: