Skip to content

Commit

Permalink
flexible detector configs
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Morris committed Feb 21, 2024
1 parent 2b316a0 commit b333cba
Show file tree
Hide file tree
Showing 23 changed files with 350 additions and 165 deletions.
21 changes: 0 additions & 21 deletions docs/source/arrays.rst

This file was deleted.

9 changes: 0 additions & 9 deletions docs/source/customizing.rst

This file was deleted.

1 change: 0 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ a-flyin’ <https://youtu.be/qKxgfnoz2pk>`_
:maxdepth: 2

installation.rst
sites.rst
usage.rst
tutorials.rst
papers.rst
57 changes: 57 additions & 0 deletions docs/source/instruments.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
===========
Instruments
===========

The observing instrument is instantiated as an ``Instrument``.
The simplest way to get an instrument is to grab a pre-defined one, e.g.::

# The Atacama Cosmology Telescope
act = maria.get_instrument('ACT')

# The Atacama Large Millimeter Array
alma = maria.get_instrument('ALMA')

# MUSTANG-2
m2 = maria.get_instrument('MUSTANG-2')


+++++++++++++++++++++++
Customizing Instruments
+++++++++++++++++++++++

One way to customize instruments is to load a pre-defined instrument and pass extra parameters.
For example, we can give ACT twice the resolution with

.. code-block:: python
act = maria.get_instrument('ACT', primary_size=12)
Custom arrays of detectors are a bit more complicated. For example:

.. code-block:: python
f090 = {"center": 90, "width": 30}
f150 = {"center": 150, "width": 30}
dets = {"n": 500,
"field_of_view": 2
"array_shape": "hex",
"bands": [f090, f150]}
my_custom_array = maria.get_instrument(dets=dets)
Actually, there are several valid ways to define an array of detectors.
These are all valid:

.. code-block:: python
f090 = {"center": 90, "width": 30}
f150 = {"center": 150, "width": 30}
dets = {"n": 500,
"field_of_view": 2
"array_shape": "hex",
"bands": [f090, f150]}
my_custom_array = maria.get_instrument(dets=dets)
7 changes: 4 additions & 3 deletions docs/source/simulations.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
###########
Simulations
+++++++++++
###########

We simulate observations by defining a ``Simulation`` object and running it to produce a ``TOD`` object::

Expand All @@ -16,7 +17,7 @@ The same simulation can produce any number of ``TOD`` objects, continuing from w

yet_another_tod = sim.run()


+++++++++++++++++++++++
Customizing simulations
+++++++++++++++++++++++

Expand Down Expand Up @@ -47,7 +48,7 @@ We can also pass other arguments to the ``Simulation``, which will overwrite the
}
field_of_view=0.8
baseline=0
geometry=0
shape=0
primary_size=6
start_time=2022-02-10T06:00:00
integration_time=60 # in seconds
Expand Down
8 changes: 4 additions & 4 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Usage
:maxdepth: 2

simulations.rst
.. maps.rst
.. arrays.rst
.. sites.rst
.. pointings.rst
instruments.rst
pointings.rst
sites.rst
maps.rst
4 changes: 2 additions & 2 deletions maria/atmosphere/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def _simulate_atmospheric_emission(self, units="K_RJ"):
)

for band in bands:
band_index = self.instrument.dets(band=band.name).index
band_index = self.instrument.dets.subset(band=band.name).index

if self.verbose:
bands.set_description(f"Computing atm. emission ({band.name})")
Expand Down Expand Up @@ -167,7 +167,7 @@ def _simulate_atmospheric_emission(self, units="K_RJ"):
)

for band in bands:
band_index = self.instrument.dets(band=band.name).index
band_index = self.instrument.dets.subset(band=band.name).index

if self.verbose:
bands.set_description(f"Computing atm. transmission ({band.name})")
Expand Down
2 changes: 1 addition & 1 deletion maria/atmosphere/turbulent_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def sample(self):
for band in self.instrument.bands:
# we assume the atmosphere looks the same for every nu in the band

band_index = self.instrument.dets(band=band.name).index
band_index = self.instrument.dets.subset(band=band.name).index
band_angular_fwhm = self.instrument.angular_fwhm(z=self.depth)[
band_index
].mean()
Expand Down
18 changes: 12 additions & 6 deletions maria/instrument/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,10 @@ class Instrument:
"""

description: str = ""
primary_size: float = 5 # in meters
field_of_view: float = 1 # in deg
geometry: str = "hex"
baseline: float = 0
bath_temp: float = 0
primary_size: float = None # in meters
field_of_view: float = None # in deg
baseline: float = None
bath_temp: float = None
bands: BandList = None
dets: pd.DataFrame = None # dets, it's complicated
documentation: str = ""
Expand All @@ -85,6 +84,13 @@ def from_config(cls, config):

return cls(bands=dets.bands, dets=dets, **config)

# def __post_init__(self):

# if self.baseline is None:
# unique_baselines = sorted(np.unique(self.dets.baseline))

# ...

def __repr__(self):
nodef_f_vals = (
(f.name, attrgetter(f.name)(self)) for f in fields(self) if f.name != "dets"
Expand All @@ -93,7 +99,7 @@ def __repr__(self):
nodef_f_repr = []
for name, value in nodef_f_vals:
if name == "bands":
nodef_f_repr.append(f"{name}={value.__short_repr__()}")
nodef_f_repr.append(f"bands=[{', '.join(value.names)}]")
else:
nodef_f_repr.append(f"{name}={value}")

Expand Down
28 changes: 16 additions & 12 deletions maria/instrument/bands.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
BAND_FIELD_TYPES = {
"center": "float",
"width": "float",
"passband_shape": "str",
"shape": "str",
"tau": "float",
"white_noise": "float",
"pink_noise": "float",
"efficiency": "float",
}

here, this_filename = os.path.split(__file__)
Expand Down Expand Up @@ -97,7 +101,7 @@ class Band:
tau: float = 0.0
white_noise: float = 0.0
pink_noise: float = 0.0
passband_shape: str = "gaussian"
shape: str = "gaussian"
efficiency: float = 1.0

@classmethod
Expand All @@ -107,7 +111,7 @@ def from_passband(cls, name, nu, pb, pb_err=None):
nu[pb > pb.max() / np.e**2].ptp(), 3
) # width is the two-sigma interval

band = cls(name=name, center=center, width=width, passband_shape="custom")
band = cls(name=name, center=center, width=width, shape="custom")

band._nu = nu
band._pb = pb
Expand All @@ -116,20 +120,20 @@ def from_passband(cls, name, nu, pb, pb_err=None):

@property
def nu_min(self) -> float:
if self.passband_shape == "flat":
if self.shape == "flat":
return self.center - 0.5 * self.width
if self.passband_shape == "gaussian":
if self.shape == "gaussian":
return self.center - self.width
if self.passband_shape == "custom":
if self.shape == "custom":
return self._nu[self._pb > 1e-2 * self._pb.max()].min()

@property
def nu_max(self) -> float:
if self.passband_shape == "flat":
if self.shape == "flat":
return self.center + 0.5 * self.width
if self.passband_shape == "gaussian":
if self.shape == "gaussian":
return self.center + self.width
if self.passband_shape == "custom":
if self.shape == "custom":
return self._nu[self._pb > 1e-2 * self._pb.max()].max()

def passband(self, nu):
Expand All @@ -139,13 +143,13 @@ def passband(self, nu):

_nu = np.atleast_1d(nu)

if self.passband_shape == "gaussian":
if self.shape == "gaussian":
band_sigma = self.width / 4

return np.exp(-0.5 * np.square((_nu - self.center) / band_sigma))

if self.passband_shape == "flat":
if self.shape == "flat":
return np.where((_nu > self.nu_min) & (_nu < self.nu_max), 1.0, 0.0)

elif self.passband_shape == "custom":
elif self.shape == "custom":
return np.interp(_nu, self._nu, self._pb)
Empty file removed maria/instrument/bands.yml
Empty file.
14 changes: 7 additions & 7 deletions maria/instrument/bands/act.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ pa4:
f150:
center: 150
width: 30
passband_shape: gaussian
shape: gaussian
tau: 0
white_noise: 266.e-6
pink_noise: 1.e-1
efficiency: 0.5
f220:
center: 220
width: 30
passband_shape: gaussian
shape: gaussian
tau: 0
white_noise: 266.e-6
pink_noise: 1.e-1
Expand All @@ -19,15 +19,15 @@ pa5:
f090:
center: 90
width: 30
passband_shape: gaussian
shape: gaussian
tau: 0
white_noise: 266.e-6
pink_noise: 1.e-1
efficiency: 0.5
f150:
center: 150
width: 30
passband_shape: gaussian
shape: gaussian
tau: 0
white_noise: 266.e-6
pink_noise: 1.e-1
Expand All @@ -36,15 +36,15 @@ pa6:
f090:
center: 90
width: 30
passband_shape: gaussian
shape: gaussian
tau: 0
white_noise: 266.e-6
pink_noise: 1.e-1
efficiency: 0.5
f150:
center: 150
width: 30
passband_shape: gaussian
shape: gaussian
tau: 0
white_noise: 266.e-6
pink_noise: 1.e-1
Expand All @@ -53,7 +53,7 @@ pa6:
f093:
n_dets: 217
field_of_view: 0.07
detector_geometry: hex
array_shape: hex

bands: [mustang2/f093]

Expand Down
Loading

0 comments on commit b333cba

Please sign in to comment.