FrbSifterClient¶
- class pirate_frb.rpc.FrbSifterClient(server_address: str = 'localhost:50051', timeout=1, raise_exception_on_timeout=True)¶
The FrbSifterClient manages grouper-sifter communication (from the grouper side).
The grouper sends two types of messages to the sifter: a ConfigMessage (sent once), and FrbEventsMessages (sent once per FPGA window, typically one per time chunk).
If FrbSifterClient is used as a context manager, then close() is automatically called.
Attributes (read-only):
server_address(str) – the sifter’sip:portaddress.timeout(float) – per-send RPC deadline, in seconds. If > 0 (default 1), send_events() is fire-and-forget and an event is dropped if it isn’t delivered within this many seconds. 0 means synchronous: send_events() blocks until the sifter replies.raise_exception_on_timeout(bool, default True) – what happens when an async send (timeout > 0) expires: if True the timeout is re-raised from the next send_events() (or printed by close() if there is no next send); if False the event is dropped and a message is printed to stdout (so a sifter that is offline or not responding is visible).
Usage:
with FrbSifterClient("localhost:7100") as sifter: sifter.send_configuration(pirate_yaml, xengine_yaml, dedispersion_plan_yaml, grouper_yaml, search_ip_addr) sifter.send_events(beam_set_id, events, coarsegrain_snr)
where ‘events’ is a FrbSifterEvents.
- close(drain_timeout=2.0)¶
Wait (briefly) for in-flight async sends, then close the gRPC channel.
send_events() dispatches its RPCs asynchronously; close() waits up to ‘drain_timeout’ seconds (total) for the pending ones to finish – so a clean shutdown doesn’t cancel the last events – then closes the channel (which cancels anything still in flight). A leftover deferred timeout (raise_exception_on_timeout=True) that no subsequent send_events() will report is printed here rather than raised, so close() can’t mask an exception that is unwinding through __exit__.
Automatically called if the FrbSifterClient is used as a context manager.
- send_configuration(pirate_yaml, xengine_yaml, dedispersion_plan_yaml, grouper_yaml, search_ip_addr)¶
Send the initial ConfigMessage (CheckConfiguration RPC).
Sent once, before any events. Unlike send_events(), this send is always synchronous: it blocks until the sifter replies and raises on failure (the client’s
timeoutgoverns only send_events()). Each yaml argument may be either a str (sent unmodified) or any yaml-serializable object (yaml.dump()’d to a string before sending).- Parameters:
pirate_yaml (str or object) – Pirate dedispersion-configuration yaml.
dedispersion_plan_yaml (str or object) – Dedispersion-plan yaml.
grouper_yaml (str or object) – Grouper-specific configuration yaml.
search_ip_addr (str) – The producer FrbServer’s FrbSearch RPC endpoint (an
ip:portstring, typicallygrouper.search_ip_addr), so the sifter can call back to pirate. Sent as-is (not yaml-serialized).
- Return type:
None
- Raises:
RuntimeError – On failure: a yaml-serialization error, a gRPC transport error, or a not-ok reply from the sifter.
- send_events(beam_set_id, events, coarsegrain_snr, from_simulator=False)¶
Send an FrbEventsMessage (FrbEvents RPC).
Sent once per FPGA window, after send_configuration().
The request is built and validated synchronously (so the caller’s arrays are snapshotted before returning). Delivery then depends on the client’s
timeout. Iftimeout > 0(the default) this is fire-and-forget: the RPC is dispatched on a grpc background thread with atimeout-second deadline and this method returns immediately; an event not delivered withintimeoutseconds expires (handled perraise_exception_on_timeout– see the class docstring). Iftimeout == 0the send is synchronous: it blocks until the sifter replies and raises on any transport error or not-ok reply. (In the async case those are instead handled by the background callback: a not-ok reply is logged, and a failed/expired send followsraise_exception_on_timeout.) close() waits briefly for in-flight sends to finish.- Parameters:
beam_set_id (int) – X-engine beam-set id.
events (
FrbSifterEvents) – The per-event triggers (one FrbEvent per array element) AND the FPGA window[chunk_fpga_start, chunk_fpga_end]this message covers – the window is taken from this object. For a coarse-grain-only message, pass an FrbSifterEvents with empty per-event arrays but a valid window.coarsegrain_snr (array_like) – Per-beam coarse-grained max SNR over the same FPGA window, as a 1-d numpy or cupy array (or any 1-d iterable). A cupy array is copied to the host in a single shot via
.get()(cupy raises on implicitnp.asarray()), then cast to float32.from_simulator (bool, optional) – False (default) for events produced by the real search pipeline; True for the parallel “ideal” events the fake X-engine emits when simulating pulses upstream (so the sifter can tell the two apart).
- Return type:
None
- Raises:
RuntimeError – Synchronously, for malformed input (a bad ‘events’ type, or a coarsegrain_snr that can’t be converted to a 1-d float32 array); with timeout=0, also on a transport error or not-ok reply. With raise_exception_on_timeout=True, a previous async send that timed out is re-raised here (deferred from its background callback thread).