Custom map simulations

In this tutorial we will build a simulation from scratch.

We start by defining a Band that will determine our array’s sensitivity to different spectra. We then generate an array by specifying a field of view, which will be populated by evenly-spaced beams of the given band.

[1]:
import maria
from maria.instrument import Band

f090 = Band(
    center=90,  # in GHz
    width=20,
    sensitivity=3e-5,  # in K sqrt(s)
    knee=1e0,
    gain_error=5e-2,
)

f150 = Band(center=150, width=30, sensitivity=5e-5, knee=1e0, gain_error=5e-2)
[2]:
array = {"field_of_view": 0.1, "primary_size": 100, "bands": [f090, f150]}

instrument = maria.get_instrument(array=array)

instrument.plot()
../_images/tutorials_custom-map-simulations_3_0.png

As something to observe, we can download a map and construct a map. We also define a plan to do a daisy scan centered on the center of the map.

[3]:
from maria.io import fetch

map_filename = fetch("maps/big_cluster.fits")

input_map = maria.map.read_fits(
    filename=map_filename,
    nu=150,
    index=1,
    width=0.25,
    center=(150, 10),
    units="Jy/pixel",
)

input_map.data *= 4
input_map.to("mK_RJ").plot()
Downloading https://github.com/thomaswmorris/maria-data/raw/master/maps/big_cluster.fits: 100%|██████████| 4.20M/4.20M [00:00<00:00, 102MB/s]
../_images/tutorials_custom-map-simulations_5_1.png
[4]:
plan = maria.Plan(
    scan_pattern="daisy",
    scan_options={"radius": 0.1, "speed": 0.02},  # in degrees
    duration=600,  # in seconds
    sample_rate=50,  # in Hz
    scan_center=(150, 10),
    frame="ra_dec",
)

plan.plot()
../_images/tutorials_custom-map-simulations_6_0.png
[5]:
sim = maria.Simulation(
    instrument,
    plan=plan,
    site="llano_de_chajnantor",
    map=input_map,
    atmosphere="2d",
)
Downloading https://github.com/thomaswmorris/maria-data/raw/master/atmosphere/spectra/am/chajnantor.h5: 100%|██████████| 11.4M/11.4M [00:00<00:00, 152MB/s]
Downloading https://github.com/thomaswmorris/maria-data/raw/master/atmosphere/weather/era5/chajnantor.h5: 100%|██████████| 4.05M/4.05M [00:00<00:00, 92.9MB/s]
Constructing atmosphere: 100%|██████████| 6/6 [00:16<00:00,  2.70s/it]
[6]:
tod = sim.run()
Generating turbulence: 100%|██████████| 6/6 [00:00<00:00, 182.82it/s]
Sampling turbulence: 100%|██████████| 6/6 [00:07<00:00,  1.20s/it]
Computing atmospheric emission: 100%|██████████| 2/2 [00:12<00:00,  6.36s/it, band=f150]
Sampling map: 100%|██████████| 2/2 [00:40<00:00, 20.17s/it, band=f150]
Generating noise: 100%|██████████| 2/2 [00:04<00:00,  2.31s/it, band=f150]
[7]:
tod.plot()
../_images/tutorials_custom-map-simulations_9_0.png
[8]:
from maria.mappers import BinMapper

mapper = BinMapper(
    center=(150, 10),
    frame="ra_dec",
    width=0.25,
    height=0.25,
    resolution=0.25 / 200,
    tod_preprocessing={
        "window": {"name": "tukey", "kwargs": {"alpha": 0.1}},
        "remove_spline": {"knot_spacing": 10},
        "remove_modes": {"modes_to_remove": [0]},
    },
    map_postprocessing={
        "gaussian_filter": {"sigma": 1},
        "median_filter": {"size": 1},
    },
    units="mK_RJ",
)

mapper.add_tods(tod)

output_map = mapper.run()
2025-01-29 15:56:05.387 INFO: Ran mapper for band f090 in 31.4 s.
2025-01-29 15:56:36.673 INFO: Ran mapper for band f150 in 31.3 s.
[9]:
output_map.plot()
../_images/tutorials_custom-map-simulations_11_0.png