ProteinController¶
class ProteinController(available_subclasses: Optional[Mapping[str, List[str]]] = None, **kwargs)
Bases: MetaSubsetTabController
Subclass of MetaSubsetTabController for managing protein view-model logic.
Relays queries, event data, and filter/column metadata between the database backend and ProteinView.
Public Methods¶
- ProteinController.build_ensemble_histogram(loader: str, sql_filter: str, experiments_and_channels: Dict[str, List[int | None]] | None, plot_type: str, bins: Any, sizes: bool, dataset_label: str, dataset_key: Tuple[Any, ...], d: float, L: float, N: int) None¶
Fetch one event subset and average it into a single histogram to draw.
A request slot. The aggregation happens with the fetch rather than in the widget: handing the widget a generator to walk means whole events, and the DataFrame built from them, live above the Model for no one’s benefit.
The drawing context arrives and departs unchanged; this slot marshals and does not interpret it. Nothing is handed back at all if the subset has no usable event, which is what leaves the previous figure in place.
- Parameters:
loader (str) – the database loader plugin’s key
sql_filter (str) – the subset filter’s WHERE-clause body, empty for all rows
experiments_and_channels (Optional[Dict[str, List[Optional[int]]]]) – the experiment and channel scope, or None
plot_type (str) – ‘Raw Histogram’ or ‘Filtered Histogram’
bins (Any) – a bin count, or a bin width when sizes is True, or None
sizes (bool) – does bins refer to a bin width (True) or a count (False)
dataset_label (str) – the label the histogram is drawn under
dataset_key (Tuple[Any, ...]) – the plotted-datasets key, handed back unchanged
d (float) – the diameter of the pore in nanometers
L (float) – the length of the pore in nanometers
N (int) – target number of samples to draw for each ensemble
- Returns:
None
- Return type:
None
- ProteinController.check_for_existing_fit_columns(loader: str) None¶
Ask whether this database already holds fit columns, and tell the View.
Phase one of a two-phase commit.
_commit_fitsinterleaved a plugin call with a modal question for the user, which no single intent can express: the answer to “does this already exist?” decides whether the user is asked at all.RawDataController._start_eventfinderhas the same shape for the same reason.The table name is the answer and the flag -
Nonemeans no such column, so nothing needs overwriting.- Parameters:
loader (str) – the database loader plugin’s key
- Returns:
None
- Return type:
None
- ProteinController.commit_fits(loader: str, fit_data: DataFrame, units: List[str | None], overwrite_table: str | None) None¶
Drop any fit columns being replaced, then write the new ones.
Phase two, reached either straight away when the database holds no fit data or once the user has approved the overwrite. The user’s decision travels as
overwrite_tablerather than being held on the View between the two halves, which is what_start_eventfinder’s filter key does.The DROP and DELETE statements are built here rather than in the widget, for the same reason as every other piece of SQL: writing it is not a widget’s job.
- Parameters:
- Returns:
None
- Return type:
None
- ProteinController.filter_xyerr_scatterplot(columns: Sequence[ndarray[tuple[int, ...], dtype[float64]]], log_flags: Sequence[bool], ax: Axes, axis_labels: Sequence[str], dataset_label: str) None¶
Filter an error-bar scatterplot’s columns, and hand them back to draw.
Separate from the shared
MetaSubsetTabController.filter_scatterplotbecause only this tab draws error bars. The four arrays go down together so one mask covers them all: a row dropped from the values has to be dropped from their error bars, or the bars no longer describe the points they sit on.- Parameters:
columns (Sequence[npt.NDArray[np.float64]]) – the raw x, y, x error and y error values
log_flags (Sequence[bool]) – log-scale each column? the two error columns never are
ax (Axes) – the axis object the View will draw on
axis_labels (Sequence[str]) – the axis labels, already formatted
dataset_label (str) – string to label the dataset
- Returns:
None
- Return type:
None
- ProteinController.fit_distribution_events(event_data: Sequence[Dict[str, Any]], plot_type: str, bins: Any, sizes: bool, d: float, L: float, N: int) None¶
Bin and fit every event on the individual distribution path, and hand back.
A request slot, the same shape as
fit_event_histograms. The events and the pore geometry pass straight through; this slot marshals and does not interpret them.- Parameters:
event_data (Sequence[Dict[str, Any]]) – the events being plotted, passed back to the View unchanged
plot_type (str) – ‘Raw Histogram’ or ‘Filtered Histogram’
bins (Any) – a bin count, or a bin width when sizes is True, or None
sizes (bool) – does bins refer to a bin width (True) or a count (False)
d (float) – the diameter of the pore in nanometers
L (float) – the length of the pore in nanometers
N (int) – target number of samples to draw for each ensemble
- Returns:
None
- Return type:
None
- ProteinController.fit_ensemble_geometry(bins: ndarray[tuple[int, ...], dtype[float64]], amplitude: ndarray[tuple[int, ...], dtype[float64]], plot_data: DataFrame, plot_type: str, d: float, L: float, N: int) None¶
Fit the ensemble histogram, and hand the result back to the View to draw.
A request slot, the same shape as
ClusteringController.cluster: the View asks, this calls the Model, and the answer goes back through a setter.The context arrives and departs unchanged rather than being held here or on the View between the halves. A fit that fails its sanity checks is not an error -
(None, None)is a legitimate answer the View reports to the user - so only an unexpected failure is caught, and it is reported rather than raised, because Qt invoked this from a signal and nothing above it could handle it.- Parameters:
bins (npt.NDArray[np.float64]) – the histogram’s bin centers
amplitude (npt.NDArray[np.float64]) – the amplitude in each bin
plot_data (pd.DataFrame) – the frame the View will draw the fit into
plot_type (str) – the plot type label to reuse when plotting the fit
d (float) – the diameter of the pore in nanometers
L (float) – the length of the pore in nanometers
N (int) – target number of samples to draw for each ensemble
- Returns:
None
- Return type:
None
- ProteinController.fit_event_histograms(event_data: Sequence[Dict[str, Any]], plot_type: str, bins: Any, sizes: bool) None¶
Bin and fit every event in one call, and hand the results back to draw.
A request slot. One call rather than one per event keeps each answer off the widget; see
ProteinModel.fit_histograms. The binning happens ahead of the fitting in the same call, so the two describe the same bins and the widget is handed the histograms rather than building them.The events pass straight through: this slot marshals, it does not interpret them. A failure is reported on the status panel rather than raised, because Qt invoked this from a signal and nothing above it could handle it - and an unusable bin request is now reported once here rather than logged once per event and drawn as a grid of empty subplots.
- Parameters:
- Returns:
None
- Return type:
None
- ProteinController.load_event_distribution_data(loader: str, sql_filter: str, experiments_and_channels: Dict[str, List[int | None]] | None) None¶
Build the query for one subset, load its events, and hand both to the View.
Both distribution modes - individual and ensemble - run this same chain, so there is one slot rather than one per mode.
The ``_raw`` branch this replaced could never work, which is why it is gone rather than converted. It handed a complete
SELECTtoload_event_dataas itsconditionsargument, and that argument is a WHERE-clause body: the loader spliced it in afterWHERE, SQLite rejected the result as a syntax error,construct_event_data_queryreturned("", debug)and the generator yielded nothing. Measured against a real loader - the same filter as an ordinary WHERE body yields every event, and as a rawSELECTyields none. Raw filters are refused before a plot is attempted now; seeMetaSubsetTabView._refuse_raw_filters.