EventAnalysisController¶
class EventAnalysisController(available_subclasses: Optional[Mapping[str, List[str]]] = None, **kwargs)
Bases: MetaEventTabController
Subclass of MetaEventTabController for for managing event analysis view-model logic.
Connects the EventAnalysisModel and EventAnalysisView.
Public Methods¶
- EventAnalysisController.load_event_plot(loader: str, eventfitter: str, channel: int, events: List[int], data_filter: str, raw: bool) None¶
Load the selected events, their raw traces and their fits, ready to plot.
Eight calls and the assembly that turns their answers into plot arguments, all on this side: it is pure data marshalling - no Qt and no matplotlib - so none of it belongs in the widget.
_update_event_plotstays in the View.The alignment this builds is the load-bearing part.
event_dataandlabelstake one to three entries per event - the data, then optionally the raw trace, then optionally the fit - while the six feature lists take exactly one placeholder per event, and an event’s features are written to its own placeholder. Soevent_datais routinely longer thanvertical_lines, andnum_eventscounts events rather than traces. Getting that wrong attaches a fit’s features to another event’s subplot, which no gate would notice.Three different unpacking rules, which the bus used to apply implicitly from each callee’s declared return type.
load_eventreturns a dict whosedatakey is the samples;get_fitted_eventreturns a bare array and must not be unwrapped;get_plot_featuresreturns a six-tuple in the order (vertical, horizontal, points, vlabels, hlabels, plabels). All three are explicit here.One call hoisted.
get_eventfitting_statustakes only the channel, so the View asking it once per event asked the same question N times. It is asked once per request now, as the samplerate was on RawData’s trace path.- Parameters:
loader (str) – the event loader plugin’s key
eventfitter (str) – the event fitter plugin’s key, or “No Event Fitter”
channel (int) – the single channel whose events are being plotted
events (List[int]) – the event indices the user selected
data_filter (str) – the filter plugin’s key, or “” for no filtering
raw (bool) – whether to overlay each event’s unfiltered trace
- Returns:
None
- Return type:
None
- EventAnalysisController.request_fitting_statuses(eventfitter: str, channels: List[int], data_filter: str) None¶
Ask the fitter which channels it has already fitted, for the View to confirm.
The first half of the fitting launch, and the analogue of
RawDataController.request_eventfinding_statuses: every channel’s status is resolved here, in one call. Asking per channel and reading each answer back off the widget is how the “start over?” prompt gets shown, or skipped, for the wrong channel - a look-up that fails leaves the previous channel’s fitted-ness in place.
- EventAnalysisController.request_loader_channels(loader: str) None¶
Fetch an event loader’s channel list and hand it to the View.
The direct analogue of
RawDataController.request_reader_channels, againstMetaEventLoaderrather thanMetaReader. A loader that cannot be read leaves the channel combobox alone rather than clearing it - an empty combobox reads as “this loader has no channels”, which is a different and more alarming thing than “this loader could not be read”.- Parameters:
loader (str) – the event loader plugin’s key
- Returns:
None
- Return type:
None
- EventAnalysisController.start_fitting(eventfitter: str, channels: List[int], data_filter: str) None¶
Fit the approved channels and run the resulting generators.
silentandindicesare passed explicitly as False and None because the View always did, even though both match their defaults: stating them means this call does not change meaning if a default ever does.A channel that cannot be launched is reported and skipped, and the ones that did register still run, for the same reason as
write_events.
- EventAnalysisController.write_events(writer: str, channels: List[int]) None¶
Hand each channel’s fitted events to a database writer and run the generators.
The analogue of
RawDataController.commit_events, againstMetaDatabaseWriter.write_events. Like that one it was never an emit-then-read: the plugin returns a generator and the bus passed it straight intoset_generatoras an argument, so there was no attribute to park it on and no stale value to inherit.The same deliberate behaviour change applies. The View wrapped the whole loop in
except (IndexError, ValueError)and skippedrun_generatorsentirely if it fired - a guard that could not catch a plugin failure, because the bus swallowed those first. Now thatcall()raises, a channel that cannot be written is reported and skipped and the rest still run, rather than an arbitrary writer exception escaping a Qt slot.
Private Methods¶
- EventAnalysisController._init() None¶
Build this tab’s View and Model, and do any other setup the tab needs.
Assigning both
self.viewandself.modelis required rather than conventional: the constructor calls this and then immediately connects the two to each other, so leaving either unset raisesAttributeErrorbefore the tab exists. kwargs given to the base constructor are available as attributes by the time this runs.