quicknxs.presenters package

QuickNXS presenters, responsible for communication between the model and view layers.

Submodules

quicknxs.presenters.configuration_handler module

class quicknxs.presenters.configuration_handler.ConfigurationHandler(main_window)[source]

Bases: object

Handles events upon changes in the configuration.

Configuration state that is global to all runs is stored as class variables in the class Configuration. This class handles updating the configuration state upon changes in the UI configuration elements, as well as triggering any recalculation and replotting needed as a consequence of the changed configuration.

config_setter_factory(qwidget: QWidget, config_name: str)[source]

Factory function to create configuration setters.

Generates anonymous functions to serve as callback when any of the global configurations (Configuration class variables) are updated in the UI.

Each callback will be associated to one configuration parameter. Upon invoked, the Configuration class variable value will be updated.

Parameters:
  • qwidget (QWidget) – UI widget

  • config_name (str) – Name of the Configuration variable to update

connect_config_events()[source]

Connect configuration widget events.

global_reflectivity_updater()[source]

Recalculate and replot reflectivity upon change in global reflectivity configuration.

quicknxs.presenters.data_manager module

Data presenter. Holds information about the current data location and manages the data cache.

class quicknxs.presenters.data_manager.DataManager(current_directory: str)[source]

Bases: object

Holds information about the current data location and manages the data cache.

current_directory

Current directory

_nexus_data

Current data set

active_cross_section

Currently active CrossSectionData

_cache

Cache of loaded data

active_reduction_list_index

Index of current data (ROI) tab

peak_reduction_lists

Dictionary of reduction lists key: reduction list index, corresponds to the reduction table tab in the UI

direct_beam_list

List of direct beam data sets

reduction_states

List of cross-sections common to all reduced data sets

final_merged_reflectivity

Merged reflectivity data

cached_offspec

Cached off-specular data

cached_gisans

Cached GISANS data

MAIN_REDUCTION_LIST_INDEX = 1
MAX_CACHE = 50
add_active_to_direct_beam_list()[source]

Add active data set to the direct beam list.

This method allows adding any run to the direct beam list, even if it wasn’t originally acquired as a direct beam (i.e., when the PV data_type != 1). This is useful for calibration and other runs started with “Start RUN” command in EPICS, which don’t add the “Direct Beam” PV-tag.

Returns:

Result of the add operation, including success or reason for failure.

Return type:

AddToDirectBeamResult

add_active_to_reduction(peak_index=1) AddToReductionResult[source]

Add active data set to reduction list.

New data sets are always added to the main reduction list. Data sets are added to secondary reduction lists by initializing from the main reduction list (button to add new data tab) or by propagating individual data sets to other tabs (right-click menu).

Parameters:

peak_index (int) – The index of the peak in peak_reduction_lists

Returns:

Result of the add operation, including success or reason for failure.

Return type:

AddToReductionResult

add_additional_reduction_list(tab_index: int)[source]

Add reduction list for an additional ROI/peak.

Parameters:

tab_index (int) – Index of the peak in self.peak_reduction_lists

asymmetry()[source]

Determine which cross-section to use to compute asymmetry, and compute it.

calculate_gisans(nexus_data=None, progress=None)[source]

Compute GISANS for a single data set.

calculate_reflectivity(configuration=None, active_only=False, nexus_data=None, specular=True)[source]

Calculate reflectivity using the current configuration.

clear_cache()[source]
clear_cached_unused_data()[source]

Delete cached files that are not in the reduction list or direct beam list.

clear_direct_beam_list()[source]

Remove all items from the direct beam list.

clear_reduction_lists()[source]

Resets to one empty reduction list.

copy_nexus_data_to_reduction(nexus_data_to_copy: NexusData, peak_index: int)[source]

Add data set to the reduction list specified by peak_index.

Parameters:
  • nexus_data_to_copy – Data set to copy

  • peak_index – reduction list to copy data set to

Returns:

True if the data set was added successfully, otherwise False

Return type:

bool

property current_event_files: list[str]

Sorted list of event files in the current directory.

Return only file names with pattern ‘event.nxs’ or ‘.nxs.h5’

property current_file
property current_file_name
property data_sets

Dict of reduced cross sections.

Type:

dict

determine_asymmetry_states()[source]

Determine which cross-section to use to compute asymmetry.

extract_metadata(file_path=None)[source]

Return the current q-value at the center of the wavelength range of the current data set.

If a file path is provided, the mid q-value will be extracted from that data file.

find_active_data_id() int | None[source]

Look for the active data in the reduction list.

Returns:

The index within the reduction list or none.

Return type:

int | None

find_active_direct_beam_id() int | None[source]

Look for the active data in the direct beam list.

Returns:

The index within the direct beam list or none.

Return type:

int | None

find_best_direct_beam()[source]

Find the best direct beam in the direct beam list for the active data.

Returns:

True if we have updated the data with a new normalization run.

Return type:

bool

find_data_in_direct_beam_list(nexus_data: NexusData | None) int | None[source]

Return the index of the given data in the direct beam list, or None if not found.

Returns:

The index within the direct beam list, or none.

Return type:

int | None

find_data_in_reduction_list(nexus_data: NexusData | None) int | None[source]

Return the index of the given data in the active reduction list, or None if not found.

Returns:

The index within the reduction list, or none.

Return type:

int | None

find_direct_beam_by_name(direct_beam_name: str) NexusData | None[source]

Find a direct beam data set by its name.

Parameters:

direct_beam_name (str) – Name of the direct beam run to find.

Returns:

The direct beam data set if found, otherwise None.

Return type:

NexusData or None

find_run_number_in_direct_beam_list(nexus_data: NexusData | None) int | None[source]

Look for data with the same run number in the direct beam list.

This method compares by run number rather than object identity, which is useful for detecting duplicates when deepcopied objects are involved.

Parameters:

nexus_data (NexusData | None) – The data to search for by run number.

Returns:

The index within the direct beam list, or None if not found.

Return type:

int | None

find_run_number_in_reduction_list(nexus_data: NexusData | None, reduction_list: list[NexusData] | None = None) int | None[source]

Look for the given run number in a reduction list, or the active reduction list if None.

Returns:

The index in the reduction list or None

Return type:

int | None

get_active_direct_beam()[source]

Return the direct beam data object for the active data.

get_cachesize()[source]
get_trim_values() list[int] | None[source]

Cut the start and end of the active data set to 5% of its maximum intensity.

is_active(data_set: NexusData)[source]

Check if the given data set is the active data set.

is_direct_beam_for_run(nexus_data: NexusData, direct_beam_run: str | int) bool[source]

Check if the direct beam is the configured direct beam for the given run.

Parameters:
  • nexus_data (NexusData) – NexusData run object

  • direct_beam (str | int) – Direct beam run number

is_gisans_available(active_only=True)[source]

Verify that all data sets and all cross-sections have calculated GISANS data available.

is_nexus_data_compatible(nexus_data: NexusData, reduction_list: list[NexusData]) bool[source]

Determine if the data set is compatible with the data sets in the reduction list.

A data set is compatible if the polarization cross-section states matches those of the first run in the reduction list, both the same number of states and the same states.

Parameters:
  • nexus_data (NexusData) – The data set to check if compatible with reduction list

  • reduction_list (list[NexusData]) – The reduction list

Returns:

True if the data set is compatible with the reduction list, False otherwise.

Return type:

bool

is_offspec_available()[source]

Verify that all data sets and all cross-sections have calculated off-specular data available.

is_same_run(run_number_a: str | int, run_number_b: str | int) bool[source]

Returns True if two run numbers are considered the same.

Tries to compare the run numbers as integers if possible; falls back to comparing them as-is (e.g., strings).

Parameters:
  • run_number_a (str or int) – The first run number.

  • run_number_b (str or int) – The second run number.

Returns:

True if the run numbers are equal (after normalization), False otherwise.

Return type:

bool

load(file_path: str, configuration: Configuration, force: bool = False, update_parameters: bool = True, progress: Callable | None = None) bool[source]

Load one or more Nexus data files.

Parameters:
  • file_path – absolute path to one or more files. If more than one, files are concatenated with the merge symbol ‘+’.

  • configuration – Configuration to use to load the data

  • force – if True, existing data in the cache will be replaced by reading from file.

  • update_parameters – if True, we will find peak ranges

  • progress – aggregator to estimate percent of time allotted to this function

Returns:

True if the data is retrieved from the cache of past loading events

Return type:

bool

load_data_from_reduced_file(file_path: str, configuration: Configuration | None = None, progress: ProgressReporter | None = None)[source]

Load the information from a reduced file, the load the data.

Ask the main event handler to update the UI once we are done.

load_direct_beam_and_data_files(db_files: list[tuple], data_files: list[tuple], additional_peaks: list | None = None, configuration: Configuration | None = None, progress: ProgressReporter | None = None, force: bool = False, t_0: float | None = None)[source]

Load direct beam and data files and add them to the direct beam list and reduction list, respectively.

Parameters:
  • db_files (list) – List of (run_number, run_file, conf, slice_value) for direct beam files

  • data_files (list) – List of (run_number, run_file, conf, slice_value) for data files

  • additional_peaks (list | None) – List of (peak_index, run_number, run_file, conf, slice_value) for data files for additional peaks

  • configuration (Configuration) – Configuration to base the loaded data on

  • progress (ProgressReporter) – Progress reporter

  • force (bool) – If True, ignore cache and force reloading from file

  • t_0 (float) – Start time for logging data loading time

property main_reduction_list: list[NexusData]

Reduction list for the first (mandatory) data tab.

merge_data_sets(asymmetry=True)[source]
rebin_gisans(pol_state, wl_min=0, wl_max=100, qy_npts=50, qz_npts=50, use_pf=False)[source]

Merge all the off-specular reflectivity data and rebin.

reduce_gisans(progress=None)[source]

Calculate GISANS for all datasets in the reduction list.

Since the specular reflectivity is prominently displayed, it is updated as soon as parameters change. This is not the case for GISANS, which is computed on-demand.

reduce_offspec(progress=None)[source]

Calculate off-specular reflectivity for all datasets in all reduction list.

Since the specular reflectivity is prominently displayed, it is updated as soon as parameters change. This is not the case for the off-specular, which is computed on-demand.

reduce_spec(direct_beam: str | int | None = None)[source]

Calculate reflectivity for all runs in all reduction lists.

If a direct beam is given, only calculate reflectivity for the runs using the given direct beam.

Parameters:

direct_beam (str | int | None) – Direct beam run number

property reduction_list: list[NexusData]

Reduction list for the active data tab.

Type:

list[NexusData]

reload_files(configuration: Configuration | None = None, progress=None)[source]

Force reload of files in the reduction lists and direct beam list.

remove_active_from_direct_beam_list()[source]

Remove the active data set from the direct beam list.

Uses run number comparison to find the entry.

remove_additional_reduction_list(tab_index: int)[source]

Remove reduction list for additional ROI/peak.

Parameters:

tab_index (int) – Index of the peak in self.peak_reduction_lists

remove_from_active_reduction_list(index: int)[source]

Remove item from the active reduction list.

Parameters:

index (int) – Index of the item to remove

set_active_cross_section(index: int) bool[source]

Set the current cross section to the specified index, or zero if it doesn’t exist.

set_active_data_from_direct_beam_list(index: int)[source]

Set a data set in the direct beam list as the active data set according to its index.

Parameters:

index – index in the direct beam list

set_active_data_from_reduction_list(index)[source]

Set a data set in the reduction list as the active data set according to its index.

Parameters:

index (int) – index in the reduction list

set_active_reduction_list_index(tab_index: int)[source]

Set the active reduction list index.

Parameters:

tab_index (int) – Index of the peak in self.peak_reduction_lists

stitch_data_sets(normalize_to_unity: bool = True, q_cutoff: float = 0.01, global_stitching: bool = False, poly_degree: int | None = None, poly_points: int = 3)[source]

Determine scaling factors for each data set.

Parameters:
  • normalize_to_unity – If True, the reflectivity plateau will be normalized to 1.

  • q_cutoff – critical q-value below which we expect R=1

  • global_stitching – If True, use data from all cross-sections to calculate scaling factors

  • poly_degree – if not None, find the scaling factor by simultaneously fitting a polynomial and scaling factor to the curves

  • poly_points – number of additional points on each end of the overlap region to include in the fit

strip_overlap()[source]

Remove overlapping points in the reflectivity, cutting always from the lower Qz measurements.

update_active_direct_beam()[source]

Updates the active direct beam when switching to the direct beam tab.

Tries to maintain the previously selected direct beam row index if available, otherwise defaults to the first direct beam.

update_active_reduction_list(tab_index: int)[source]

Updates the active reduction list and run.

Parameters:

tab_index (int) – Index of the peak in self.peak_reduction_lists

update_configuration(configuration, active_only: bool = False, nexus_data: NexusData | None = None)[source]

Update configuration.

update_direct_pixel_from_direct_beam() float | None[source]

Set direct_pixel_overwrite based on the matched direct beam peak position.

quicknxs.presenters.main_handler module

Manage file-related and UI events.

class quicknxs.presenters.main_handler.MainHandler(main_window)[source]

Bases: object

Event handler for the main application window.

DIRECT_BEAM_TAB_INDEX = 0
MAIN_DATA_TAB_INDEX = 1
active_cross_section_changed()[source]

Update UI metadata and plots after the active cross section is changed.

active_data_changed()[source]

Actions to be taken once the active data set has changed.

Updates the UI to highlight the active data set in the reduction and direct beam tables, and updates the radio button states.

Also syncs the highlighted file in the file list.

add_direct_beam(silent=False)[source]

Add dataset to the direct beam table.

add_reflectivity(silent=False)[source]

Collect information about the current extraction settings and store them in the list of reduction items.

Returns:

True if everything is ok, false otherwise.

Return type:

bool

ask_question(message: str) bool[source]

Display a popup dialog with a message and choices “Ok” and “Cancel”.

automated_file_selection()[source]

Automatically select files in the current directory based on incident angle.

Go through the files in the current in order of run numbers, and load files until the incident angle is no longer increasing.

change_log_level(level: str)[source]

Update all handlers + root logger to new level.

check_region_values_changed()[source]

Return true if any of the parameters tied to a particular slot has changed.

Some parameters are tied to the changeRegionValues() slot. There are time-consuming actions that we only want to take if those values actually changed, as opposed to the use simply clicking outside the box.

Some parameters don’t require a recalculation but simply a refreshing of the plots. Those are parameters such as scaling factors or the number of points clipped.

Returns:

-1 = no valid change,

0 = replot needed, 1 = recalculation needed

Return type:

int

clear_direct_beams()[source]

Remove all items from the direct beam list.

clear_reflectivity()[source]

Remove all items from the reduction lists.

compute_gisans_on_change(force=False, active_only=True)[source]

Compute GISANS as needed.

compute_offspec_on_change(force=False)[source]

Compute off-specular as needed.

property direct_beam_table: QTableWidget

Returns the direct beam table widget.

direct_beam_table_changed(item: QTableWidgetItem)[source]

Perform action upon change in direct beam list.

empty_cache()[source]

Empty the data cache.

file_loaded()[source]

Update UI after a file is loaded.

file_open_dialog()[source]

GUI callback for backend MainHandler._file_open_dialog.

file_open_sum_dialog()[source]

GUI callback for backend MainHandler._file_open_sum_dialog.

get_configuration_from_ui() Configuration[source]

Gather the reduction options.

Retrieve the reduction options either from the active cross section, or from the current settings in the graphical interface.

Note that some options are global (static members of Configuration class), while others are per-cross-section (members of Configuration instance). This is because some options are applied to all cross-sections (e.g. whether to use a ROI or not), while others are specific to each cross-section (e.g. the peak position and width).

get_log_level()[source]

Return current root logger level as a string for GUI dropdown.

get_reduction_table_by_index(tab_index: int) QTableWidget[source]

Return the QTableWidget for the data tab with the given index.

get_tab_index_for_reduction_table(table_widget: QTableWidget) int[source]

Return the tab index that owns the given reduction table widget.

hide_data_table()[source]
hide_run_data()[source]
hide_sidebar()[source]
initialize_additional_reduction_table(tab_index: int)[source]

Initialize new reduction table from the main reduction table.

Parameters:

tab_index (int) – Index of the additional tab/peak

new_progress_reporter()[source]

Return a progress reporter.

open_file(file_path: str, force: bool = False, silent: bool = False) None[source]

Read one or more data files. If more than one, merge their data.

Parameters:
  • file_path – Absolute path to data files. If more than one file, paths are joined with the plus symbol ‘+’

  • force – if true, the file will be reloaded even if it was loaded previously

  • silent – if true, the plots currently shown in the interface will NOT be updated

open_reduced_file_dialog()[source]

Open a reduced file and all the data files needed to reproduce it.

open_run_number(number: list[int] | list[str] | int | str | None = None)[source]

Open a data file by typing a run number or a composite run number for merging data sets.

Example

“120:123+125+127:132” opens files with run numbers from 120 to 132 except 124 and 126

populate_from_configuration(configuration=None)[source]

Set reduction options in UI, usually after loading a reduced data set.

propagate_binning_options_to_run_config()[source]

Enable the selected binning type with the given Q-step for all runs in the active data tab.

Note: This function updates the UI and internal configuration state while blocking all signals. The caller is responsible for triggering recalculation and replotting.

property reduction_table: QTableWidget

Returns the active reduction table widget if one of the data tabs is active, else the first one.

reduction_table_binning_type_changed(combobox_index: int, row: int)[source]

Perform action upon change in binning type column in the UI reduction table.

Parameters:
  • combobox_index (int) – The selected index in the combobox

  • row (int) – The row in the reduction table to update.

reduction_table_cell_changed(refl: NexusData, recalculate: bool = True)[source]

Perform action upon change in UI reduction table.

Updates the internal configuration state and recalculates the reflectivity.

Parameters:
  • refl (NexusData) – The data set to update.

  • recalculate (bool, optional) – Whether to recalculate the reflectivity, by default True

reduction_table_changed(item: QTableWidgetItem)[source]

Perform action upon change in data reduction list.

Parameters:

item (QTableWidgetItem) – The changed table item

reduction_table_right_click(pos: QPoint, is_reduction_table: bool = True)[source]

Handle right-click on the reduction table.

Parameters:
  • pos – Mouse position

  • is_reduction_table – True if the reduction table is active, False if the direct beam table is active

reload_all_files()[source]

Reload all files upon change in loading configuration.

To speed up reloading, the file cache is first cleared of files that are not used in the reduction list or direct beam list.

remove_direct_beam()[source]

Remove one item from the direct beam list.

remove_reflectivity()[source]

Remove one item from the reduction list.

report_message(message: str, informative_message: str | None = None, detailed_message: str | None = None, pop_up: bool = False, is_error: bool = False)[source]

Report a message or error to the status bar at the bottom of the window.

If is_error is True, the message is also logged on the error channel.

save_run_data(nexus_data: NexusData)[source]

Save run data to file.

show_results()[source]

Pop up the result viewer.

stitch_reflectivity()[source]

Stitch the reflectivity parts and normalize to 1.

strip_overlap()[source]

Remove overlapping points in the reflectivity, cutting always from the lower Qz measurements.

trim_data_to_normalization()[source]

Cut the start and end of the active data set to 5% of its maximum intensity.

update_calculated_data()[source]

Update the calculated entries in the overview tab.

We should call this after the peak ranges change, or after a change is made that will affect the displayed results.

update_cross_section_info()[source]

Update cross section metadata shown in the overview tab.

update_daslog()[source]

Write parameters from all file daslogs to the table in the daslog tab.

update_direct_beam_table(idx: int, data: CrossSectionData) None[source]

Update a direct beam table entry with cross-section data.

Parameters:
  • idx – Row to update

  • data – Cross-section data

update_file_list(query_path: str | None = None) None[source]

Update the list of data files.

Parameters:

query_path – Full path of a directory, a Nexus file, or a list of Nexus files. If a list of files, their paths are joined by the plus symbol ‘+’.

update_overview_run_info_from_active_run()[source]

Update metadata shown in the overview tab.

update_reduction_table(table_widget: QTableWidget, idx: int, data: CrossSectionData)[source]

Update the reduction table.

Parameters:
  • table_widget – Table widget of the table to update

  • idx – Row to update

  • data – Cross-section data

update_reduction_table_from_direct_beam(direct_beam: NexusData)[source]

Update all reflectivity runs that use the given direct beam.

Parameters:

direct_beam – Direct beam data

update_tables()[source]

Update a data set that may be in the reduction table or the direct beam table.

quicknxs.presenters.plot_presenter module

Event handlers for the main application window.

Most of those come straight from QuickNXS.

class quicknxs.presenters.plot_presenter.PlotPresenter(main_window)[source]

Bases: object

Class to handle plotting events.

change_color_scale(*args, **kws)[source]

Wrap a function to slow it down.

change_offspec_colorscale()[source]

Modify color scale.

change_region_values()[source]

Called when the reflectivity extraction region has been changed.

Sets up a trigger to replot the reflectivity with a delay so a subsequent change can occur without several replots.

clip_offspec_colorscale()[source]

Modify color scale.

connect_plot_events()[source]

Connect matplotlib mouse events.

control_down = False
last_event = None
plot_mouse_event(event: MouseEvent)[source]

Show the mouse position of any plot in the main window status bar.

The single plot status indicator is only visible for larger plot toolbars.

plot_pick_x(*args, **kws)[source]

Wrap a function to slow it down.

plot_pick_xtof(event: MouseEvent)[source]

Plot for xtof-map has been clicked.

plot_pick_xy(event)[source]

Plot for xy-map has been clicked.

plot_pick_y(event: MouseEvent)[source]

Plot for y-projection has been clicked.

plot_release(event)[source]

Release the mouse button on a plot.

refl = None
quicknxs.presenters.plot_presenter.slow_down_events(fn)[source]

Decorator to slow down UI events.

Seems to be necessary since PyQt5 seems to be overactive with the UI events.

quicknxs.presenters.progress_reporter module

Class used to report on progress.

It allows for sub-tasks and computes a meaningful progress status accordingly.

class quicknxs.presenters.progress_reporter.ProgressReporter(max_value: int = 100, call_back: Callable | None = None, status_bar: StatusBar | None = None, progress_bar: QProgressBar | None = None)[source]

Bases: object

Progress reporter class that allows for sub-tasks.

Initialize the progress reporter.

create_sub_task(max_value: int) ProgressReporter[source]

Create a sub-task, with max_value being its portion of the complete task.

Parameters:

max_value – The maximum value for the sub-task, representing its portion of the total task.

Returns:

A new ProgressReporter instance representing the sub-task, to be called by the worker to update the progress.

Return type:

ProgressReporter

reset()[source]

Reset the progress bar to show no progress

set_value(value: int, message: str = '', out_of: int | None = None)[source]

Set the value of a progress indicator.

update(message: str = '')[source]

Updates the progress status according to sub-tasks.