frb_sifter.protoΒΆ
/**
This is the gRPC protocol definition for the CHORD FRB Grouper-to-Sifter.
Its canonical source is
https://github.com/dstndstn/chord-frb-sifter/blob/main/chord_frb_grpc/frb_sifter.proto
*/
syntax = "proto3";
service FrbSifter {
// First call - report my configuration.
// Returns true if good, false otherwise.
rpc CheckConfiguration (ConfigMessage) returns (ConfigReply) {}
// Report events from a given time chunk.
rpc FrbEvents (FrbEventsMessage) returns (FrbEventsReply) {}
}
// Wire-protocol version. This is the single source of truth for the protocol
// version on both the client (grouper) and server (sifter) sides -- both
// reference PROTOCOL_VERSION_CURRENT from the generated stubs, rather than each
// hardcoding their own constant.
//
// proto3 requires every enum to have a zero value; PROTOCOL_VERSION_UNSPECIFIED
// is that placeholder (a ConfigMessage.protocol_version of 0 is therefore
// invalid -- e.g. an old client that never set the field). Bump
// PROTOCOL_VERSION_CURRENT on any incompatible wire-format change.
enum ProtocolVersion {
PROTOCOL_VERSION_UNSPECIFIED = 0;
PROTOCOL_VERSION_CURRENT = 3;
}
message ConfigMessage {
// Wire-protocol version: the client sets this to PROTOCOL_VERSION_CURRENT (see
// the ProtocolVersion enum above), and the sifter REJECTS the config if it
// does not match its own PROTOCOL_VERSION_CURRENT. Kept as a uint32 rather
// than the enum type so an out-of-range value from a newer client round-trips
// as a plain integer the sifter can report, instead of decoding to the proto3
// "unknown enum" sentinel.
uint32 protocol_version = 1;
// Currently, we initialize all 5 of these fields in the main search, but when
// we send simulated events with 'pirate_frb run_fake_xengine -f -s ...', fields
// other than 'xengine_yaml' are empty strings (-> yaml null).
string pirate_yaml = 2;
string xengine_yaml = 3;
string dedispersion_plan_yaml = 4;
string grouper_yaml = 5;
string search_ip_addr = 6; // for rpc callbacks sifter -> pirate
}
message ConfigReply {
bool ok = 1;
}
// If there are early triggers, then the event timestamp can be outside
// the EventsMessage range [chunk_fpga_start:chunk_fpga_end]! In this scenario,
// the sifter may receive multiple events (in different chunks) for the same
// FRB, as the pulse crosses different early-trigger frequencies.
message FrbEvent {
int32 beam_id = 1;
int64 fpga_timestamp = 2; // can be outside the chunk, see above!
float dm = 3;
float snr = 4;
float rfi_prob = 5;
// Currently, these members are set to placeholder values in the main search, but when
// we send simulated events with 'pirate_frb run_fake_xengine -f -s ...', we do set
// meaningful values.
float width_ms = 6;
float subband_freq_lo_MHz = 7;
float subband_freq_hi_MHz = 8;
}
// When events are sent from the search pipeline, we set from_simulator=false.
// When the fake X-engine simulates pulses "upstream", it sends a parallel sequence
// of events with from_simulator=true. Thus, the sifter can use this flag to
// compare the actual outcome of the search (from_simulator=false) to the
// ideal outcome (from simulator=true).
message FrbEventsMessage {
bool from_simulator = 1;
int32 beam_set_id = 2;
int64 chunk_fpga_start = 3;
int64 chunk_fpga_end = 4;
repeated FrbEvent events = 5;
// Coarse-grained triggers
// A small array of SNRs, the same length as the beams being handled by this beam_set_id.
repeated float coarsegrain_snr = 6;
}
message FrbEventsReply {
bool ok = 1;
string message = 2;
}