Example simulations (example
)
generate_random_ptsrc_catalogue(Nptsrc, ra_bounds, dec_bounds, logflux_bounds=(-1.0, 2.0))
Generate a catalogue of point sources with random positions and log(flux) values.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
Nptsrc
|
int
|
Number of point sources in catalogue. |
required |
ra_bounds
|
tuple of float
|
Tuple with the lower and upper bounds of the RA range, in radians. Sources will be placed according to a uniform random distribution within the specified interval. |
required |
dec_bounds
|
tuple of float
|
Same as above, but for the declination range. |
required |
logflux_bounds
|
tuple of float
|
The lower and upper bounds of log10(flux) at some reference frequency. The reference frequency is not specified here, so these values can be treated purely as amplitude/scaling factors. Sources will be randomly assigned fluxes/amplitudes in this interval in log10(flux). |
(-1.0, 2.0)
|
Returns:
Name | Type | Description |
---|---|---|
ra |
array_like
|
RA values for the sources, in radians. |
dec |
array_like
|
Dec values for the sources, in radians. |
ptsrc_amps |
array_like
|
Amplitude or flux values at an unspecified reference frequency. |
Source code in hydra/example.py
def generate_random_ptsrc_catalogue(
Nptsrc, ra_bounds, dec_bounds, logflux_bounds=(-1.0, 2.0)
):
"""
Generate a catalogue of point sources with random positions and log(flux)
values.
Parameters:
Nptsrc (int):
Number of point sources in catalogue.
ra_bounds (tuple of float):
Tuple with the lower and upper bounds of the RA range, in radians.
Sources will be placed according to a uniform random distribution
within the specified interval.
dec_bounds (tuple of float):
Same as above, but for the declination range.
logflux_bounds (tuple of float):
The lower and upper bounds of log10(flux) at some reference
frequency. The reference frequency is not specified here, so these
values can be treated purely as amplitude/scaling factors. Sources
will be randomly assigned fluxes/amplitudes in this interval in
log10(flux).
Returns:
ra (array_like):
RA values for the sources, in radians.
dec (array_like):
Dec values for the sources, in radians.
ptsrc_amps (array_like):
Amplitude or flux values at an unspecified reference frequency.
"""
# Get coordinate bounds
ra_low, ra_high = (min(ra_bounds), max(ra_bounds))
dec_low, dec_high = (min(dec_bounds), max(dec_bounds))
logflux_low, logflux_high = (min(logflux_bounds), max(logflux_bounds))
# Generate random point source locations
# RA goes from [0, 2 pi] and Dec from [-pi / 2, +pi / 2].
ra = np.random.uniform(low=ra_low, high=ra_high, size=Nptsrc)
# Inversion sample to get them uniform on the sphere, in case wide bounds are used
U = np.random.uniform(low=0, high=1, size=Nptsrc)
dsin = np.sin(dec_high) - np.sin(dec_low)
dec = np.arcsin(
U * dsin + np.sin(dec_low)
) # np.arcsin returns on [-pi / 2, +pi / 2]
# Generate fluxes
ptsrc_amps = 10.0 ** np.random.uniform(
low=logflux_low, high=logflux_high, size=Nptsrc
)
return ra, dec, ptsrc_amps
run_example_simulation(times, freqs, output_dir, ra, dec, ptsrc_amps, array_latitude, beam_type='gaussian', hex_array=(3, 4))
Run an example visibility simulation for testing purposes, using semi-realistic beams, randomly placed point sources, and a hexagonal array layout.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
times
|
array_like
|
Time array, i.e. local sidereal time (LST), in radians. |
required |
freqs
|
array_like
|
Frequency array, in MHz. |
required |
output_dir
|
str
|
Unused. |
required |
ra
|
array_like
|
RA values for the sources, in radians. |
required |
dec
|
array_like
|
Dec values for the sources, in radians. |
required |
ptsrc_amps
|
array_like
|
Amplitude or flux values at an unspecified reference frequency. |
required |
array_latitude
|
float
|
Array latitude in radians. |
required |
hex_array
|
tuple
|
Tuple of length 2 specifying the number of antennas in the first and central rows of a regular symmetric hexagonal array. |
(3, 4)
|
beam_type
|
str
|
The type of beam model to use for the simulations. Can be 'polybeam' or 'gaussian'. |
'gaussian'
|
Returns:
Name | Type | Description |
---|---|---|
model0 |
array_like
|
Model visibility computed by the simulator. The shape is given
by |
fluxes |
array_like
|
Point source fluxes, per source and per frequency. |
beams |
list
|
List of |
ant_info |
tuple
|
Tuple of arrays and dictionaries containing antenna information,
in the order: |
Source code in hydra/example.py
def run_example_simulation(
times, freqs, output_dir, ra, dec, ptsrc_amps, array_latitude,
beam_type='gaussian', hex_array=(3,4),
):
"""
Run an example visibility simulation for testing purposes, using
semi-realistic beams, randomly placed point sources, and a hexagonal
array layout.
Parameters:
times (array_like):
Time array, i.e. local sidereal time (LST), in radians.
freqs (array_like):
Frequency array, in MHz.
output_dir (str):
Unused.
ra (array_like):
RA values for the sources, in radians.
dec (array_like):
Dec values for the sources, in radians.
ptsrc_amps (array_like):
Amplitude or flux values at an unspecified reference frequency.
array_latitude (float):
Array latitude in radians.
hex_array (tuple):
Tuple of length 2 specifying the number of antennas in the first
and central rows of a regular symmetric hexagonal array.
beam_type (str):
The type of beam model to use for the simulations. Can be
'polybeam' or 'gaussian'.
Returns:
model0 (array_like):
Model visibility computed by the simulator. The shape is given
by `extract_vis_from_sim()`.
fluxes (array_like):
Point source fluxes, per source and per frequency.
beams (list):
List of `UVBeam` or `AnalyticBeam`-compatible beam objects.
ant_info (tuple):
Tuple of arrays and dictionaries containing antenna information,
in the order: `(ants, ant_pos, antpairs, ants1, ants2)`.
"""
# Dimensions of simulation
hex_array = tuple(hex_array)
assert len(hex_array) == 2, "hex-array argument must have length 2."
# Set up array and data properties
ant_pos = build_hex_array(hex_spec=hex_array, d=14.6)
ants = np.array(list(ant_pos.keys()))
Nants = len(ants)
# Set up baselines
antpairs = []
for i in range(len(ants)):
for j in range(i, len(ants)):
if i != j:
# Exclude autos
antpairs.append((i, j))
ants1, ants2 = list(zip(*antpairs))
beta_ptsrc = -2.7
fluxes = get_flux_from_ptsrc_amp(ptsrc_amps, freqs, beta_ptsrc)
##np.save(os.path.join(output_dir, "ptsrc_amps0"), ptsrc_amps)
##np.save(os.path.join(output_dir, "ptsrc_coords0"), np.column_stack((ra, dec)).T)
# Beams
if "polybeam" in beam_type.lower():
# PolyBeam fitted to HERA Fagnoni beam
beam_coeffs = [
0.29778665,
-0.44821433,
0.27338272,
-0.10030698,
-0.01195859,
0.06063853,
-0.04593295,
0.0107879,
0.01390283,
-0.01881641,
-0.00177106,
0.01265177,
-0.00568299,
-0.00333975,
0.00452368,
0.00151808,
-0.00593812,
0.00351559,
]
beams = [
PolyBeam(beam_coeffs, spectral_index=-0.6975, ref_freq=1.0e8)
for ant in ants
]
else:
beams = [
pyuvsim.analyticbeam.AnalyticBeam("gaussian", diameter=14.0) for ant in ants
]
# Run a simulation
t0 = time.time()
_sim_vis = simulate_vis(
ants=ant_pos,
fluxes=fluxes,
ra=ra,
dec=dec,
freqs=freqs * 1e6, # MHz -> Hz
lsts=times,
beams=beams,
polarized=False,
precision=2,
latitude=array_latitude,
use_feed="x",
)
# timing_info(ftime, 0, "(0) Simulation", time.time() - t0)
# print("(0) Simulation", time.time() - t0)
# Allocate computed visibilities to only the requested baselines (saves memory)
model0 = extract_vis_from_sim(ants, antpairs, _sim_vis)
del _sim_vis # save some memory
# Return
ant_info = (ants, ant_pos, antpairs, ants1, ants2)
return model0, fluxes, beams, ant_info