Skip to content

Commit e3e61ac

Browse files
authored
Divergence (#79)
* Add exception * Add divergence retry
1 parent 0966b7f commit e3e61ac

File tree

2 files changed

+61
-35
lines changed

2 files changed

+61
-35
lines changed

arrakis/imager.py

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from astropy.visualization import (
2525
SqrtStretch,
2626
ImageNormalize,
27-
MinMaxInterval,
2827
)
2928
from fitscube import combine_fits
3029
from fixms.fix_ms_corrs import fix_ms_corrs
@@ -52,6 +51,8 @@
5251
workdir_arg_parser,
5352
)
5453

54+
from arrakis.utils.exceptions import DivergenceError
55+
5556
matplotlib.use("Agg")
5657

5758
TQDM_OUT = TqdmToLogger(logger, level=logging.INFO)
@@ -147,20 +148,15 @@ def get_mfs_image(
147148
if pol == "I"
148149
else f"{prefix_str}-MFS-{pol}-image.fits"
149150
)
150-
mfs_model_name = (
151-
f"{prefix_str}-MFS-model.fits"
152-
if pol == "I"
153-
else f"{prefix_str}-MFS-{pol}-model.fits"
154-
)
155151
mfs_residual_name = (
156152
f"{prefix_str}-MFS-residual.fits"
157153
if pol == "I"
158154
else f"{prefix_str}-MFS-{pol}-residual.fits"
159155
)
160156

161157
big_image = fits.getdata(mfs_image_name).squeeze()
162-
big_model = fits.getdata(mfs_model_name).squeeze()
163158
big_residual = fits.getdata(mfs_residual_name).squeeze()
159+
big_model = big_image - big_residual
164160

165161
small_image = resize(big_image, small_size)
166162
small_model = resize(big_model, small_size)
@@ -181,14 +177,11 @@ def make_validation_plots(prefix: Path, pols: str) -> None:
181177
for stokes in pols:
182178
mfs_image = get_mfs_image(prefix_str, stokes)
183179
fig, axs = plt.subplots(1, 3, figsize=(15, 5))
184-
for ax, sub_image, title in zip(axs, mfs_image, ("Image", "Model", "Residual")):
180+
for ax, sub_image, title in zip(
181+
axs, mfs_image, ("Image", "Model (conv.)", "Residual")
182+
):
185183
sub_image = np.abs(sub_image)
186-
if title == "Model":
187-
norm = ImageNormalize(
188-
sub_image, interval=MinMaxInterval(), stretch=SqrtStretch()
189-
)
190-
else:
191-
norm = ImageNormalize(mfs_image.residual, vmin=0, stretch=SqrtStretch())
184+
norm = ImageNormalize(mfs_image.residual, vmin=0, stretch=SqrtStretch())
192185
_ = ax.imshow(sub_image, origin="lower", norm=norm, cmap="cubehelix")
193186
ax.set_title(title)
194187
ax.get_yaxis().set_visible(False)
@@ -280,6 +273,38 @@ def get_prefix(
280273
return out_dir / prefix
281274

282275

276+
def run_wsclean_singuarlity(
277+
command: str,
278+
simage: Path,
279+
out_dir: Path,
280+
root_dir: Path,
281+
) -> None:
282+
logger.info(f"Running wsclean with command: {command}")
283+
try:
284+
output = sclient.execute(
285+
image=simage.resolve(strict=True).as_posix(),
286+
command=command.split(),
287+
bind=f"{out_dir}:{out_dir}, {root_dir.resolve(strict=True).as_posix()}:{root_dir.resolve(strict=True).as_posix()}",
288+
return_result=True,
289+
quiet=False,
290+
stream=True,
291+
)
292+
for line in output:
293+
logger.info(line.rstrip())
294+
# Catch divergence - look for the string 'KJy' in the output
295+
if "KJy" in line:
296+
raise DivergenceError(
297+
f"Detected divergence in wsclean output: {line.rstrip()}"
298+
)
299+
300+
except CalledProcessError as e:
301+
logger.error(f"Failed to run wsclean with command: {command}")
302+
logger.error(f"Stdout: {e.stdout}")
303+
logger.error(f"Stderr: {e.stderr}")
304+
logger.error(f"{e=}")
305+
raise e
306+
307+
283308
@task(name="Image Beam", persist_result=True)
284309
def image_beam(
285310
ms: Path,
@@ -423,29 +448,26 @@ def image_beam(
423448
)
424449

425450
root_dir = ms.parent
426-
logger.info(f"Running wsclean with command: {command}")
427451
try:
428-
output = sclient.execute(
429-
image=simage.resolve(strict=True).as_posix(),
430-
command=command.split(),
431-
bind=f"{out_dir}:{out_dir}, {root_dir.resolve(strict=True).as_posix()}:{root_dir.resolve(strict=True).as_posix()}",
432-
return_result=True,
433-
quiet=False,
434-
stream=True,
452+
run_wsclean_singuarlity(
453+
command=command,
454+
simage=simage,
455+
out_dir=out_dir,
456+
root_dir=root_dir,
457+
)
458+
except DivergenceError as de:
459+
logger.error(f"Detected divergence in wsclean output: {de}")
460+
new_pix = npix + 1024
461+
new_command = command.replace(f"{npix} {npix}", f"{new_pix} {new_pix}")
462+
logger.critical(
463+
f"Rerunning wsclean with larger image size: {new_pix}x{new_pix}"
464+
)
465+
run_wsclean_singuarlity(
466+
command=new_command,
467+
simage=simage,
468+
out_dir=out_dir,
469+
root_dir=root_dir,
435470
)
436-
for line in output:
437-
logger.info(line.rstrip())
438-
# Catch divergence - look for the string 'KJy' in the output
439-
if "KJy" in line:
440-
raise ValueError(
441-
f"Detected divergence in wsclean output: {line.rstrip()}"
442-
)
443-
except CalledProcessError as e:
444-
logger.error(f"Failed to run wsclean with command: {command}")
445-
logger.error(f"Stdout: {e.stdout}")
446-
logger.error(f"Stderr: {e.stderr}")
447-
logger.error(f"{e=}")
448-
raise e
449471

450472
# Purge ms_temp
451473
shutil.rmtree(ms_temp)

arrakis/utils/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@ class ReadError(OSError):
3434
class RegistryError(Exception):
3535
"""Raised when a registry operation with the archiving
3636
and unpacking registeries fails"""
37+
38+
39+
class DivergenceError(Exception):
40+
"""Raised when a divergence is detected"""

0 commit comments

Comments
 (0)