Simulating observations with MUSTANG-2

MUSTANG-2 is a bolometric array on the Green Bank Telescope. In this notebook we simulate an observation of the Crab Nebula (M1).

[1]:
import maria

input_map = maria.map.get("maps/m1.h5")

input_map.plot(nu_index=[0, 1, 2])
print(input_map)
2026-05-13 12:08:58.104 INFO: Fetching https://github.com/thomaswmorris/maria-data/raw/master/maps/m1.h5
Downloading: 100%|██████████| 4.54M/4.54M [00:00<00:00, 132MB/s]
ProjectionMap:
  data(1, 3, 805, 787):
    min: -2.429e-02
    max: 3.824e-01
    units: K_RJ
    quantity: rayleigh_jeans_temperature
  stokes(1):
    components: I
  nu(3):
    values: [149.8962 214.1375 272.5386] GHz
  y(805):
    height: 13.42’
    res: 1”
  x(787):
    width: 13.12’
    res: 1”
  frame: ra/dec
  center:
    ra: 05ʰ34ᵐ31.95ˢ
    dec: 22°00’52.16”
  beam(maj, min, psi): (0 rad, 0 rad, 0 rad)
  memory: 15.2 MB
../_images/tutorials_mustang-nebula_1_2.png
[2]:
from maria import Planner

planner = Planner(target=input_map, site="green_bank", constraints={"el": (60, 90)})
plans = planner.generate_plans(total_duration=900, sample_rate=100)

plans[0].plot()
print(plans)
PlanList(1 plans, 900 s):
                           start_time duration    target(ra,dec)     center(az,el)
chunk
0      2026-05-13 17:33:24.182 +00:00    900 s  (83.63°, 22.01°)  (117.3°, 61.56°)
../_images/tutorials_mustang-nebula_2_1.png
[3]:
instrument = maria.get_instrument("MUSTANG-2")

print(instrument)
instrument.plot()
Instrument(1 array)
├ arrays:
│            n   FOV baseline      bands polarized
│  array1  217  4.2’      0 m  [m2/f093]     False
│
└ bands:
         name     center      width    η      NEP         NET_RJ         NET_CMB    FWHM
   0  m2/f093  86.21 GHz  20.98 GHz  0.1  15 aW√s  571.1 uK_RJ√s  690.5 uK_CMB√s  9.133”
../_images/tutorials_mustang-nebula_3_1.png
[4]:
sim = maria.Simulation(
    instrument,
    plans=plans,
    site="green_bank",
    map=input_map,
    atmosphere="2d",
)

print(sim)
2026-05-13 12:09:10.481 INFO: Fetching https://github.com/thomaswmorris/maria-data/raw/master/atmosphere/spectra/am/v3/green_bank.h5
Downloading: 100%|██████████| 22.0M/22.0M [00:00<00:00, 184MB/s]
2026-05-13 12:09:11.316 INFO: Fetching https://github.com/thomaswmorris/maria-data/raw/master/atmosphere/weather/era5/green_bank.h5
Downloading: 100%|██████████| 12.0M/12.0M [00:00<00:00, 155MB/s]
Simulation
├ Instrument(1 array)
│ ├ arrays:
│ │            n   FOV baseline      bands polarized
│ │  array1  217  4.2’      0 m  [m2/f093]     False
│ │
│ └ bands:
│          name     center      width    η      NEP         NET_RJ         NET_CMB    FWHM
│    0  m2/f093  86.21 GHz  20.98 GHz  0.1  15 aW√s  571.1 uK_RJ√s  690.5 uK_CMB√s  9.133”
├ Site:
│   region: green_bank
│   timezone: America/New_York
│   location:
│     longitude: 79°50’23.28” W
│     latitude:  38°25’59.16” N
│     altitude: 825 m
│   seasonal: True
│   diurnal: True
├ PlanList(1 plans, 900 s):
│                            start_time duration    target(ra,dec)     center(az,el)
│ chunk
│ 0      2026-05-13 17:33:24.182 +00:00    900 s  (83.63°, 22.01°)  (117.3°, 61.56°)
├ '2d'
└ ProjectionMap:
    data(1, 3, 1, 805, 787):
      min: -2.429e-02
      max: 3.824e-01
      units: K_RJ
      quantity: rayleigh_jeans_temperature
    stokes(1):
      components: I
    nu(3):
      values: [149.8962 214.1375 272.5386] GHz
    t(1):
      values: [1.77867414e+09] s
    y(805):
      height: 13.42’
      res: 1”
    x(787):
      width: 13.12’
      res: 1”
    frame: ra/dec
    center:
      ra: 05ʰ34ᵐ31.95ˢ
      dec: 22°00’52.16”
    beam(maj, min, psi): (0 rad, 0 rad, 0 rad)
    memory: 15.2 MB
[5]:
tods = sim.run()
tods[0].plot()
2026-05-13 12:09:12.086 INFO: Simulating observation 1 of 1
Constructing atmosphere: 100%|██████████| 8/8 [00:00<00:00,  8.50it/s]
Generating turbulence: 100%|██████████| 8/8 [00:00<00:00, 28.73it/s]
Sampling turbulence: 100%|██████████| 8/8 [00:03<00:00,  2.07it/s]
Computing atmospheric emission: 100%|██████████| 1/1 [00:00<00:00,  1.20it/s, band=m2/f093]
Sampling map: 100%|██████████| 1/1 [00:09<00:00,  9.81s/it, band=m2/f093, channel=(0 Hz, 182 GHz)]
Generating noise: 100%|██████████| 1/1 [00:00<00:00,  1.13it/s, band=m2/f093]
2026-05-13 12:09:41.265 INFO: Simulated observation 1 of 1 in 29.16 s
../_images/tutorials_mustang-nebula_5_1.png
[6]:
from maria.mappers import BinMapper

mapper = BinMapper(
    tod_preprocessing={
        # "remove_modes": {"modes_to_remove": 1},
        "remove_spline": {"knot_spacing": 30, "remove_el_gradient": True},
    },
    units="uK_RJ",
    tods=tods,
    resolution=2 * input_map.resolution,
)

output_map = mapper.run()
2026-05-13 12:09:48.513 INFO: Inferring center {'ra': '05ʰ34ᵐ31.97ˢ', 'dec': '22°00’52.23”'} for mapper.
2026-05-13 12:09:48.527 INFO: Inferring mapper width 16.95’ for mapper from observation patch.
2026-05-13 12:09:48.528 INFO: Inferring mapper height 16.95’ to match supplied width.
2026-05-13 12:09:48.532 INFO: Inferring mapper stokes parameters 'I' for mapper.
Preprocessing TODs: 100%|██████████| 1/1 [00:07<00:00,  7.31s/it]
Mapping: 100%|██████████| 1/1 [00:01<00:00,  1.71s/it, tod=1/1]
[7]:
output_map.plot()
../_images/tutorials_mustang-nebula_7_0.png