2424from astropy .visualization import (
2525 SqrtStretch ,
2626 ImageNormalize ,
27- MinMaxInterval ,
2827)
2928from fitscube import combine_fits
3029from fixms .fix_ms_corrs import fix_ms_corrs
5251 workdir_arg_parser ,
5352)
5453
54+ from arrakis .utils .exceptions import DivergenceError
55+
5556matplotlib .use ("Agg" )
5657
5758TQDM_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 )
284309def 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 )
0 commit comments