Skip to content
Snippets Groups Projects

Mosaicing

Closed Philipp Arras requested to merge parras/resolve:mosaicing into master
Compare and
10 files
+ 614
66
Compare changes
  • Side-by-side
  • Inline
Files
10
demo/mosaicing.py 0 → 100644
+ 125
0
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright(C) 2019-2020 Max-Planck-Society
# Author: Philipp Arras
import numpy as np
import matplotlib.pyplot as plt
import nifty7 as ift
import resolve as rve
@rve.onlymaster
def imsave(fname, field):
plt.imsave(fname, field.val.T, origin="lower")
plt.close()
def main():
rve.set_nthreads(2)
rve.set_wgridding(False)
diffusefluxlevel = 20
interobs_extended = {
f"extended{ii}": rve.Observation.load(f"/data/mosaicing/extended_field{ii}.npz")
for ii in range(5, 135)
# for ii in [50, 58, 59, 68, 69, 70, 88]
# for ii in [68, 69, 70]
}
interobs_compact = {
f"compact{ii}": rve.Observation.load(f"/data/mosaicing/compact_field{ii}.npz")
for ii in range(5, 153)
}
interobs = {**interobs_compact, **interobs_extended}
sdobs = {"sd0": rve.SingleDishObservation.load("/data/mosaicing/totalpower.npz")}
rve.set_epsilon(1 / 10 / max(o.max_snr() for o in interobs.values()))
xs, ys = [], []
for vv in interobs.values():
xs.append(vv.direction.phase_center[0])
ys.append(vv.direction.phase_center[1])
for vv in sdobs.values():
foo, bar = vv.pointings.phase_centers.T
xs.extend(foo)
ys.extend(bar)
xs, ys = np.array(xs), np.array(ys)
# Convention: The phase center is the coordinate of the [nx/2, ny/2] pixel
global_phase_center_casa = -2.7180339078174175, -0.5210930907116116
global_phase_center = (max(xs) + min(xs)) / 2, (max(ys) + min(ys)) / 2
margin = 1 * rve.ARCMIN2RAD
xfov = 2 * max(abs(xs - global_phase_center[0])) + 2 * margin
yfov = 2 * max(abs(ys - global_phase_center[1])) + 2 * margin
print(f"Field of view: {xfov/rve.ARCMIN2RAD:.2f}' x {yfov/rve.ARCMIN2RAD:.2f}'")
xs, ys = [], []
for vv in interobs.values():
xs.append(vv.direction.phase_center[0])
ys.append(vv.direction.phase_center[1])
xs, ys = np.array(xs), np.array(ys)
plt.scatter(xs, ys, label="Interferometer")
for kk, vv in sdobs.items():
plt.scatter(
*vv.pointings.phase_centers.T, label="Single dish " + kk, alpha=0.2, s=1
)
plt.scatter(*global_phase_center_casa, label="Phase center CASA")
plt.scatter(*global_phase_center, label="Phase center resolve")
plt.xlim([global_phase_center[0] - xfov / 2, global_phase_center[0] + xfov / 2])
plt.ylim([global_phase_center[1] - yfov / 2, global_phase_center[1] + yfov / 2])
plt.gca().invert_xaxis()
plt.gca().set_aspect("equal")
plt.legend()
if rve.mpi.master:
plt.savefig("pointings.png")
plt.close()
beam_directions = {}
for kk, obs in interobs.items():
extended_blockage = np.array([10.7, 0.75]) # m
extended_blockage *= np.mean(obs.freq) / rve.SPEEDOFLIGHT
beam_directions[kk] = rve.BeamDirection(
obs.direction.phase_center[0] - global_phase_center[0],
obs.direction.phase_center[1] - global_phase_center[1],
lambda x: rve.alma_beam_func(*extended_blockage, x),
0.1,
)
npix = np.array([1800, 1800])
fov = np.array([xfov, yfov])
dom = ift.RGSpace(npix, fov / npix)
logsky = ift.SimpleCorrelatedField(
dom, diffusefluxlevel, (1, 0.1), (1.5, 1), (1.2, 0.4), (0.2, 0.2), (-1.5, 0.5)
)
skyslicer = rve.SkySlicer(logsky.target, beam_directions)
ift.extra.check_linear_operator(skyslicer)
lh = rve.ImagingLikelihood(interobs, skyslicer @ logsky.exp())
R = rve.StokesIResponse(interobs, skyslicer.target) @ skyslicer
vis = ift.MultiField.from_dict({kk: o.vis for kk, o in interobs.items()})
weight = ift.MultiField.from_dict({kk: o.weight for kk, o in interobs.items()})
imsave("total_dirty.png", R.adjoint(vis * weight))
imsave("skyslicer_adjoint.png", skyslicer.adjoint(ift.full(skyslicer.target, 1.0)))
plotter = rve.Plotter("png", "plots")
plotter.add("logsky", logsky)
plotter.add("sky", logsky.exp(), cmap="inferno_r")
plotter.add("power spectrum logsky", logsky.power_spectrum)
# plotter.add_histogram(
# "normalized residuals (original weights)", lh.normalized_residual
# )
ham = ift.StandardHamiltonian(lh, ift.AbsDeltaEnergyController(0.5, 3, 300, name="Sampling"))
fld = 0.1 * ift.from_random(lh.domain)
state = rve.MinimizationState(fld, [])
mini = ift.NewtonCG(ift.GradientNormController(name="newton", iteration_limit=5))
# TODO Add minisanity to resolve
# TODO Fix histogram plots
for ii in range(20):
state = rve.simple_minimize(ham, state.mean, 3, mini)
plotter.plot(f"iter{ii}", state)
state.save(f"iter{ii}")
if __name__ == "__main__":
main()
Loading