Skip to content

Commit

Permalink
run_sample_simulation: make simulator backend, visibility format conf…
Browse files Browse the repository at this point in the history
…igurable, return all relevant objects. Visibility: verify path in constructor. Added test for simulation-format-imager combos. 🍥
  • Loading branch information
mpluess committed Sep 30, 2024
1 parent ddbe84f commit 2abf83e
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 113 deletions.
130 changes: 65 additions & 65 deletions karabo/examples/source_detection.ipynb

Large diffs are not rendered by default.

50 changes: 32 additions & 18 deletions karabo/simulation/sample_simulation.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
from datetime import datetime
from typing import Union
from typing import Tuple

from karabo.simulation.interferometer import InterferometerSimulation
from karabo.simulation.observation import Observation
from karabo.simulation.sky_model import SkyModel
from karabo.simulation.telescope import Telescope
from karabo.simulation.visibility import Visibility
from karabo.simulation.visibility import Visibility, VisibilityFormat
from karabo.simulator_backend import SimulatorBackend
from karabo.util._types import IntFloatList


def run_sample_simulation(
phase_center: Union[list[float], None] = None, *, verbose: bool = False
) -> tuple[Visibility, SkyModel]:
*,
simulator_backend: SimulatorBackend = SimulatorBackend.OSKAR,
visibility_format: VisibilityFormat = "MS",
verbose: bool = False,
) -> Tuple[
Visibility, IntFloatList, SkyModel, Telescope, Observation, InterferometerSimulation
]:
"""
TODO update
Creates example visibilities for use in tests, experiments and examples.
Args:
Expand All @@ -24,29 +31,32 @@ def run_sample_simulation(
Visibility: visibilities created by the simulation
SkyModel: Sky model used for the simulation
"""
if simulator_backend == SimulatorBackend.RASCIL:
raise NotImplementedError(
"RASCIL simulations are currently not supported in this sample"
)

if phase_center is None:
phase_center = [250, -80]
phase_center = [250, -80]

if verbose:
print("Getting Sky Survey")
# Get GLEAM Survey Sky
gleam_sky = SkyModel.get_GLEAM_Sky(min_freq=72e6, max_freq=80e6)
sky = SkyModel.get_GLEAM_Sky(min_freq=72e6, max_freq=80e6)

if verbose:
print("Filtering Sky Model")
sky = gleam_sky.filter_by_radius(0, 0.55, phase_center[0], phase_center[1])
sky = sky.filter_by_radius(0, 0.55, phase_center[0], phase_center[1])
sky.setup_default_wcs(phase_center=phase_center)

if verbose:
print("Setting Up Telescope")
askap_tel = Telescope.constructor(
"ASKAP", version=None, backend=SimulatorBackend.OSKAR
)
telescope = Telescope.constructor(
"ASKAP", version=None, backend=simulator_backend
) # type: ignore[call-overload]

if verbose:
print("Setting Up Observation")
observation_settings = Observation(
observation = Observation(
start_frequency_hz=100e6,
start_date_and_time=datetime(2024, 3, 15, 10, 46, 0),
phase_centre_ra_deg=phase_center[0],
Expand All @@ -59,12 +69,16 @@ def run_sample_simulation(
print("Generating Visibilities")

interferometer_sim = InterferometerSimulation(channel_bandwidth_hz=1e6)
visibility_askap = interferometer_sim.run_simulation(
askap_tel, sky, observation_settings, backend=SimulatorBackend.OSKAR
)
visibility = interferometer_sim.run_simulation(
telescope,
sky,
observation,
backend=simulator_backend,
visibility_format=visibility_format,
) # type: ignore[call-overload]

# In case run_simulation returns a list of vis (allowed by type hint)
if isinstance(visibility_askap, list):
visibility_askap = visibility_askap[0]
if isinstance(visibility, list):
visibility = visibility[0]

return visibility_askap, sky
return visibility, phase_center, sky, telescope, observation, interferometer_sim
2 changes: 2 additions & 0 deletions karabo/simulation/visibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ def is_valid_path_for_format(path: FilePathType, format: VisibilityFormat) -> bo

class Visibility:
def __init__(self, path: FilePathType) -> None:
if not os.path.exists(path):
raise ValueError(f"Path {path} does not exist")
self.path = path

self.format: VisibilityFormat
Expand Down
88 changes: 88 additions & 0 deletions karabo/test/test_sim_format_imager_combos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# TODO files abräumen
import os

import pytest

from karabo.imaging.imager_base import DirtyImagerConfig
from karabo.imaging.imager_oskar import OskarDirtyImager, OskarDirtyImagerConfig
from karabo.imaging.imager_rascil import RascilDirtyImager, RascilDirtyImagerConfig
from karabo.imaging.imager_wsclean import WscleanDirtyImager
from karabo.simulation.sample_simulation import run_sample_simulation
from karabo.simulation.visibility import VisibilityFormat
from karabo.simulator_backend import SimulatorBackend

IMAGING_NPIXEL = 2048
IMAGING_CELLSIZE = 3.878509448876288e-05


@pytest.mark.parametrize(
"simulator_backend,visibility_format",
[
(SimulatorBackend.OSKAR, "MS"),
(SimulatorBackend.OSKAR, "OSKAR_VIS"),
# (SimulatorBackend.RASCIL, "MS"),
],
)
def test_oskar_imager(
simulator_backend: SimulatorBackend, visibility_format: VisibilityFormat
) -> None:
visibility, _, _, _, _, _ = run_sample_simulation(
simulator_backend=simulator_backend,
visibility_format=visibility_format,
)
assert os.path.exists(visibility.path)
dirty_image = OskarDirtyImager(
OskarDirtyImagerConfig(
imaging_npixel=IMAGING_NPIXEL,
imaging_cellsize=IMAGING_CELLSIZE,
)
).create_dirty_image(visibility)
assert os.path.isfile(dirty_image.path)


@pytest.mark.parametrize(
"simulator_backend,visibility_format",
[
(SimulatorBackend.OSKAR, "MS"),
# (SimulatorBackend.RASCIL, "MS"),
],
)
def test_rascil_imager(
simulator_backend: SimulatorBackend, visibility_format: VisibilityFormat
) -> None:
visibility, _, _, _, _, _ = run_sample_simulation(
simulator_backend=simulator_backend,
visibility_format=visibility_format,
)
assert os.path.exists(visibility.path)
dirty_image = RascilDirtyImager(
RascilDirtyImagerConfig(
imaging_npixel=IMAGING_NPIXEL,
imaging_cellsize=IMAGING_CELLSIZE,
)
).create_dirty_image(visibility)
assert os.path.isfile(dirty_image.path)


@pytest.mark.parametrize(
"simulator_backend,visibility_format",
[
(SimulatorBackend.OSKAR, "MS"),
# (SimulatorBackend.RASCIL, "MS"),
],
)
def test_wsclean_imager(
simulator_backend: SimulatorBackend, visibility_format: VisibilityFormat
) -> None:
visibility, _, _, _, _, _ = run_sample_simulation(
simulator_backend=simulator_backend,
visibility_format=visibility_format,
)
assert os.path.exists(visibility.path)
dirty_image = WscleanDirtyImager(
DirtyImagerConfig(
imaging_npixel=IMAGING_NPIXEL,
imaging_cellsize=IMAGING_CELLSIZE,
)
).create_dirty_image(visibility)
assert os.path.isfile(dirty_image.path)
49 changes: 19 additions & 30 deletions karabo/test/test_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from karabo.simulation.sample_simulation import run_sample_simulation
from karabo.simulation.sky_model import SkyModel
from karabo.simulation.telescope import Telescope
from karabo.simulation.visibility import Visibility
from karabo.simulator_backend import SimulatorBackend


Expand Down Expand Up @@ -320,48 +319,38 @@ def test_parallelization_by_observation() -> None:
assert dirty.header["CDELT4"] == CHANNEL_BANDWIDTHS_HZ[i]


def test_run_sample_simulation(
verbose: bool = True, phase_center: list = [250, -80]
) -> None:
def test_run_sample_simulation() -> None:
"""
Executes the ASKAP sample simulation, captures verbose output,
validates the output files, and checks the sky model filtering.
Args:
verbose: Boolean flag to capture verbose output from the simulation.
phase_center: List containing the RA and DEC of the phase center
for the simulation.
"""

# run simulation and capture output
old_stdout = sys.stdout
sys.stdout = StringIO()

visibilities, sky = run_sample_simulation(
verbose=verbose, phase_center=phase_center
)
(
visibility,
phase_center,
sky,
telescope,
observation,
interferometer_sim,
) = run_sample_simulation(verbose=True)

output = sys.stdout.getvalue()
sys.stdout = old_stdout

# returns non-None values of the correct type
assert visibilities is not None
assert sky is not None
assert isinstance(visibilities, Visibility)
assert isinstance(sky, SkyModel)

# verbose output content
if verbose:
expected_messages = [
"Getting Sky Survey",
"Filtering Sky Model",
"Setting Up Telescope",
"Setting Up Observation",
"Generating Visibilities",
]
for message in expected_messages:
assert message in output
expected_messages = [
"Getting Sky Survey",
"Filtering Sky Model",
"Setting Up Telescope",
"Setting Up Observation",
"Generating Visibilities",
]
for message in expected_messages:
assert message in output

# Ensure the visibilities file path is valid
vis_path = visibilities.vis_path
assert os.path.exists(vis_path)
assert os.path.exists(visibility.path)

0 comments on commit 2abf83e

Please sign in to comment.