--- orphan: true --- # xengine_metadata.yml ```yaml # The xengine_metadata file represents all FRB-related metadata from the X-engine. # It is sent from the X-engine to every FRB node, and is also one of three metadata # files sent from pirate to the grouper. # # The purpose of this git-controlled example file is to document the file format. version: 2 # Frequency channels. The observed frequency band is divided into "zones". # Within each zone, all frequency channels have the same width, but the # channel width may differ between zones. # zone_nfreq: number of frequency channels in each zone. # zone_freq_edges: frequency band edges in MHz. # For example: # zone_nfreq: [N] zone_freq_edges: [400,800] one zone, channel width (400/N) MHz # zone_nfreq: [2*N,N] zone_freq_edges: [400,600,800] width (100/N), (200/N) MHz in lower/upper band # # In this config, we have: # Total frequency channels: 28160 # Channel widths (MHz): [ 0.00610352, 0.012207, 0.0244141, 0.0976562, 0.195312 ] zone_nfreq: [8192, 8192, 6144, 2048, 3584] zone_freq_edges: [300, 350, 450, 600, 800, 1500] # Optional: which frequency channels are present? # A list of distinct integers 0 <= (channel_id) < (total frequency channels). # Only makes sense in "context 1" (see above), to indicate which frequency channels # are sent by a particular X-engine node. freq_channels: [ 0, 10000, 20000, 28159 ] # Data for each beam received by this node. # beamset: an integer identifier for this set of beams # beam_ids: length Nbeams; integer id # beam_positions_x: float, length Nbeams & # beam_positions_y: float, length Nbeams; # direction cosines in the grid frame. The grid frame is defined by x & y unit vectors # which are orthogonal and lie along (or close to) the axes of the telescope grid. Each # beam has a skywards-directed unit vector b. The grid_x and grid_y values are the x & y direction # cosines: b.x and b.y. beamset: 42 beam_ids: [ 100, 200, 300 ] beam_positions_x: [0.0, 0.1, 0.0 ] beam_positions_y: [0.0, 0.0, 0.1 ] ############# # Timekeeping ############# # The X-engine uses fpga sequence number (seq) to keep track of time. # To keep time in pirate, we need to know: # # - unix_ns_at_seq_0: the epoch (the UNIX time at seq = 0, in nanoseconds). # - dt_ns_per_seq: the rate at which seqs tick, number of nanoseconds per seq tick. # - seq_per_frb_time_sample: the number of seq ticks covered by an frb time sample. # # In Kotekan language: # - unix_ns_at_seq_0 = time0_ns # - dt_ns_per_seq = fengine_fft_length / ADC_sampling_rate_GHz # - seq_per_frb_time_sample = upchanelization factor * frb_downsampling_factor (not sure if this exists) # # The sifter will need Earth Orientation Parameters (EOP) (which change in time and Kotekan has) and # a precession/nutation model (which Kotekan does *not* have) to compute RA/DEC for the beams. # Since the sifter has to do this calculation anyways, I propose we *don't* sent UT1 or EOP data # from Kotekan to Pirate, and instead rely on the sifter to make the astropy calls itself. # # This means the sifter may infer a *slightly* different UT1 for the same seq number compared to # the X-engine (if it has more up-to-date EOP data). The difference will be sub-ms, which I think is # acceptable? # # unix_ns_at_seq_0 will change whenever the F-engine reboots, which will also require a reboot of # the X-engine. unix_ns_at_seq_0: 1772483060000000000 dt_ns_per_seq: 5120 # note long, not double seq_per_frb_time_sample: 256 ################################################## # Telescope alignment and localization parameters. ################################################## # Coordinate Systems # # Topocentric: origin at the given lat/lon. x-axis is directed exactly East (increasing Longitude), # y-axis is directed exactly North (increasing Latitude), z-axis is directed exactly "up" (increasing # altitude). orthogonal, Z = X x Y. # # Grid: origin at SW corner of Dish Array, aligned with Dish Array. x-axis directed "east-ish" # parallel to dish "e/w" separatation vector. y-axis directed "north-ish" parallel to "n/s" # separation vector. Z = X x Y points normal to grid plane. Dish grid lives in x-y plane at a # constant Z. Orthogonal. Rotated by O(1) degrees from "Topocentric" # # Dish Elevation Axis: The axis around which the dishes pivot. positive is in the east direction. # *Not* parallel to the dish grid "e/w" separation. "Coelevation" pointing measures an angle around # this axis. # # Dish Vertical Axis: Local "up/zenith" for the dishes. The direction which has coelevation = 0.0. # Orthogonal to the Dish Elevation axis. # Position on the Earth in degrees tel_origin_itrs_lat_deg: 49.32075144444 tel_origin_itrs_lon_deg: -119.62081125 # Unit vectors in the x & y grid directions, in topocentric coordinates. tel_grid_x_axis: [ 0.999974342398359362, -0.000037539331442772, -0.007163318767675494] tel_grid_y_axis: [0.000065403387739210, 0.999992433220348809, 0.003889630373557614] # Unit vectors for the dish frame, the elevation axis and vertical axis, in # topocentric coordinates. tel_dish_elev_axis: [0.99999999838132391, -0.000056897733584327, 0.0] tel_dish_vert_axis: [0.0, 0.0, 1.0] # The dish pointing angle, co-elevation in degrees: angle away from vertical, # north is positive tel_dish_coelev_deg: 0.0 # Values of dish separation in x and y directions in meters. tel_dish_separation_x_m: 6.300156854906823 tel_dish_separation_y_m: 8.500057809796308 ##################################################### # Temporary kludge: per-frequency-zone noise variance ##################################################### # For now, the FRB server assumes that the noise is mean-zero, uncorrelated # between samples, with variance known in advance! We assume that the noise # variance is constant in time, and depends only on frequency "zone" (see above). # (A per-frequency-channel variance was awkward to implement.) # # In a future revision, this will be generalized, and the 'noise_variance' # metadata will go away. # # noise_variance: an array of length nzones (=len(zone_nfreq)). If a scalar is # specified, then all frequency zones are assumed to have the same variance. noise_variance: 1.0 ############################################### # Sender-consistency rules ############################################### # When multiple X-engine nodes connect to a single FRB node, the FRB # receiver enforces that all senders agree on (almost all of) the # metadata above. The check is implemented in # XEngineMetadata::check_sender_consistency() (in # src_lib/XEngineMetadata.cpp). Every field above falls into one of # three groups: # # 1. NOT checked across senders: # freq_channels (each sender deliberately sends a different # subset of the frequency channels) # # 2. Required to be bit-identical across senders (compared with ==): # version # zone_nfreq # beamset # beam_ids # unix_ns_at_seq_0 # dt_ns_per_seq # seq_per_frb_time_sample # # 3. Required to match within an absolute tolerance |a - b| <= eps # (NOT bit-identical). All tolerances are hard-coded near the top # of src_lib/XEngineMetadata.cpp: # # zone_freq_edges eps = 1.0e-3 MHz # beam_positions_x eps = 1.0e-9 (direction cosine) # beam_positions_y eps = 1.0e-9 (direction cosine) # tel_origin_itrs_lat_deg eps = 1.0e-6 degrees # tel_origin_itrs_lon_deg eps = 1.0e-6 degrees # tel_grid_x_axis eps = 1.0e-9 (direction cosine) # tel_grid_y_axis eps = 1.0e-9 (direction cosine) # tel_dish_elev_axis eps = 1.0e-9 (direction cosine) # tel_dish_vert_axis eps = 1.0e-9 (direction cosine) # tel_dish_coelev_deg eps = 1.0e-6 degrees # tel_dish_separation_x_m eps = 1.0e-6 meters # tel_dish_separation_y_m eps = 1.0e-6 meters # noise_variance eps = 1.0e-12 ```