@@ -95,7 +95,6 @@ def predict_ignore_none(vis, model, g):
9595 g = gcfcf [ivis ]
9696 else :
9797 g = gcfcf [0 ]
98- # Create the graph to divide an image into facets. This is by reference.
9998 # Create the graph to divide the visibility into slices. This is by copy.
10099 sub_vis_lists = arlexecute .execute (visibility_scatter , nout = vis_slices )(subvis ,
101100 vis_iter , vis_slices )
@@ -271,29 +270,62 @@ def residual_list_arlexecute_workflow(vis, model_imagelist, context='2d', gcfcf=
271270 return arlexecute .optimize (result )
272271
273272
274- def restore_list_arlexecute_workflow (model_imagelist , psf_imagelist , residual_imagelist = None , ** kwargs ):
273+ def restore_list_arlexecute_workflow (model_imagelist , psf_imagelist , residual_imagelist = None , restore_facets = 1 ,
274+ restore_overlap = 0 , restore_taper = 'tukey' , ** kwargs ):
275275 """ Create a graph to calculate the restored image
276276
277277 :param model_imagelist: Model list
278278 :param psf_imagelist: PSF list
279279 :param residual_imagelist: Residual list
280280 :param kwargs: Parameters for functions in components
281+ :param restore_facets: Number of facets used per axis (used to distribute)
282+ :param restore_overlap: Overlap in pixels (0 is best)
283+ :param restore_taper: Type of taper.
281284 :return:
282285 """
283- if residual_imagelist is None :
284- residual_imagelist = []
286+ assert len (model_imagelist ) == len (psf_imagelist )
287+ if residual_imagelist is not None :
288+ assert len (model_imagelist ) == len (residual_imagelist )
289+
290+ if restore_facets % 2 == 0 or restore_facets == 1 :
291+ actual_number_facets = restore_facets
292+ else :
293+ actual_number_facets = max (1 , (restore_facets - 1 ))
285294
286295 psf_list = arlexecute .execute (remove_sumwt , nout = len (psf_imagelist ))(psf_imagelist )
287- if len (residual_imagelist ) > 0 :
296+
297+ # Scatter each list element into a list. We will then run restore_cube on each
298+ facet_model_list = [arlexecute .execute (image_scatter_facets , nout = actual_number_facets * actual_number_facets )
299+ (model , facets = restore_facets , overlap = restore_overlap , taper = restore_taper )
300+ for model in model_imagelist ]
301+ facet_psf_list = [arlexecute .execute (image_scatter_facets , nout = actual_number_facets * actual_number_facets )
302+ (psf , facets = restore_facets , overlap = restore_overlap , taper = restore_taper )
303+ for psf in psf_list ]
304+
305+ if residual_imagelist is not None :
288306 residual_list = arlexecute .execute (remove_sumwt , nout = len (residual_imagelist ))(residual_imagelist )
289- result = [arlexecute .execute (restore_cube )(model_imagelist [i ], psf_list [i ],
290- residual_list [i ], ** kwargs )
291- for i , _ in enumerate (model_imagelist )]
307+ facet_residual_list = [
308+ arlexecute .execute (image_scatter_facets , nout = actual_number_facets * actual_number_facets )
309+ (residual , facets = restore_facets , overlap = restore_overlap , taper = restore_taper )
310+ for residual in residual_list ]
311+ facet_restored_list = [[arlexecute .execute (restore_cube , nout = actual_number_facets * actual_number_facets )
312+ (model = facet_model_list [i ][im ], psf = facet_psf_list [i ][im ],
313+ residual = facet_residual_list [i ][im ],
314+ ** kwargs )
315+ for im , _ in enumerate (facet_model_list [i ])] for i , _ in enumerate (model_imagelist )]
292316 else :
293- result = [arlexecute .execute (restore_cube )(model_imagelist [i ], psf_list [i ], ** kwargs )
317+ facet_restored_list = [[arlexecute .execute (restore_cube , nout = actual_number_facets * actual_number_facets )
318+ (model = facet_model_list [i ][im ], psf = facet_psf_list [i ][im ],
319+ ** kwargs )
320+ for im , _ in enumerate (facet_model_list [i ])] for i , _ in enumerate (model_imagelist )]
321+
322+ # Now we run restore_cube on each and gather the results across all facets
323+ restored_imagelist = [arlexecute .execute (image_gather_facets )
324+ (facet_restored_list [i ], model_imagelist [i ], facets = restore_facets ,
325+ overlap = restore_overlap , taper = restore_taper )
294326 for i , _ in enumerate (model_imagelist )]
295327
296- return arlexecute .optimize (result )
328+ return arlexecute .optimize (restored_imagelist )
297329
298330
299331def deconvolve_list_arlexecute_workflow (dirty_list , psf_list , model_imagelist , prefix = '' , mask = None , ** kwargs ):
@@ -347,30 +379,51 @@ def deconvolve(dirty, psf, model, facet, gthreshold, msk=None):
347379 else :
348380 deconvolve_number_facets = deconvolve_facets ** 2
349381
350- deconvolve_model_imagelist = arlexecute .execute (image_gather_channels , nout = 1 )(model_imagelist )
382+ scattered_channels_facets_model_list = \
383+ [arlexecute .execute (image_scatter_facets , nout = deconvolve_number_facets )(m , facets = deconvolve_facets ,
384+ overlap = deconvolve_overlap ,
385+ taper = deconvolve_taper )
386+ for m in model_imagelist ]
387+ scattered_facets_model_list = [
388+ arlexecute .execute (image_gather_channels , nout = 1 )([scattered_channels_facets_model_list [chan ][facet ]
389+ for chan in range (nchan )])
390+ for facet in range (deconvolve_number_facets )]
351391
352392 # Scatter the separate channel images into deconvolve facets and then gather channels for each facet.
353393 # This avoids constructing the entire spectral cube.
394+ # i.e. SCATTER BY FACET then SCATTER BY CHANNEL
354395 dirty_list_trimmed = arlexecute .execute (remove_sumwt , nout = nchan )(dirty_list )
355396 scattered_channels_facets_dirty_list = \
356397 [arlexecute .execute (image_scatter_facets , nout = deconvolve_number_facets )(d , facets = deconvolve_facets ,
357398 overlap = deconvolve_overlap ,
358399 taper = deconvolve_taper )
359400 for d in dirty_list_trimmed ]
360-
361- # Now we do a transpose and gather
362- scattered_facets_list = [
401+ scattered_facets_dirty_list = [
363402 arlexecute .execute (image_gather_channels , nout = 1 )([scattered_channels_facets_dirty_list [chan ][facet ]
364403 for chan in range (nchan )])
365404 for facet in range (deconvolve_number_facets )]
366405
367406 psf_list_trimmed = arlexecute .execute (remove_sumwt , nout = nchan )(psf_list )
368- psf_list_trimmed = arlexecute .execute (image_gather_channels , nout = 1 )(psf_list_trimmed )
369407
370- scattered_model_imagelist = \
371- arlexecute .execute (image_scatter_facets , nout = deconvolve_number_facets )(deconvolve_model_imagelist ,
372- facets = deconvolve_facets ,
373- overlap = deconvolve_overlap )
408+ def extract_psf (psf , facets ):
409+ spsf = create_empty_image_like (psf )
410+ cx = spsf .shape [3 ] // 2
411+ cy = spsf .shape [2 ] // 2
412+ wx = spsf .shape [3 ] // facets
413+ wy = spsf .shape [2 ] // facets
414+ xbeg = cx - wx // 2
415+ xend = cx + wx // 2
416+ ybeg = cy - wy // 2
417+ yend = cy + wy // 2
418+ spsf .data = psf .data [..., ybeg :yend , xbeg :xend ]
419+ spsf .wcs .wcs .crpix [0 ] -= xbeg
420+ spsf .wcs .wcs .crpix [1 ] -= ybeg
421+ return spsf
422+
423+ psf_list_trimmed = [arlexecute .execute (extract_psf )(p , deconvolve_facets ) for p in psf_list_trimmed ]
424+ psf_centre = arlexecute .execute (image_gather_channels , nout = 1 )([psf_list_trimmed [chan ]
425+ for chan in range (nchan )])
426+
374427 # Work out the threshold. Need to find global peak over all dirty_list images
375428 threshold = get_parameter (kwargs , "threshold" , 0.0 )
376429 fractional_threshold = get_parameter (kwargs , "fractional_threshold" , 0.1 )
@@ -379,32 +432,47 @@ def deconvolve(dirty, psf, model, facet, gthreshold, msk=None):
379432
380433 # Find the global threshold. This uses the peak in the average on the frequency axis since we
381434 # want to use it in a stopping criterion in a moment clean
382- global_threshold = arlexecute .execute (threshold_list , nout = 1 )(scattered_facets_list , threshold ,
435+ global_threshold = arlexecute .execute (threshold_list , nout = 1 )(scattered_facets_dirty_list , threshold ,
383436 fractional_threshold ,
384437 use_moment0 = use_moment0 , prefix = prefix )
385438
386439 facet_list = numpy .arange (deconvolve_number_facets ).astype ('int' )
387440 if mask is None :
388441 scattered_results_list = [
389- arlexecute .execute (deconvolve , nout = 1 )(d , psf_list_trimmed , m , facet , global_threshold )
390- for d , m , facet in zip (scattered_facets_list , scattered_model_imagelist , facet_list )]
442+ arlexecute .execute (deconvolve , nout = 1 )(d , psf_centre , m , facet ,
443+ global_threshold )
444+ for d , m , facet in zip (scattered_facets_dirty_list , scattered_facets_model_list , facet_list )]
391445 else :
392446 mask_list = \
393447 arlexecute .execute (image_scatter_facets , nout = deconvolve_number_facets )(mask ,
394448 facets = deconvolve_facets ,
395449 overlap = deconvolve_overlap )
396450 scattered_results_list = [
397- arlexecute .execute (deconvolve , nout = 1 )(d , psf_list_trimmed , m , facet , global_threshold , msk )
398- for d , m , facet , msk in zip (scattered_facets_list , scattered_model_imagelist , facet_list , mask_list )]
451+ arlexecute .execute (deconvolve , nout = 1 )(d , psf_centre , m , facet ,
452+ global_threshold , msk )
453+ for d , m , facet , msk in
454+ zip (scattered_facets_dirty_list , scattered_facets_model_list , facet_list , mask_list )]
399455
456+ # We want to avoid constructing the entire cube so we do the inverse of how we got here:
457+ # i.e. SCATTER BY CHANNEL then GATHER BY FACET
400458 # Gather the results back into one image, correcting for overlaps as necessary. The taper function is is used to
401459 # feather the facets together
402- gathered_results_list = arlexecute .execute (image_gather_facets , nout = 1 )(scattered_results_list ,
403- deconvolve_model_imagelist ,
404- facets = deconvolve_facets ,
405- overlap = deconvolve_overlap ,
406- taper = deconvolve_taper )
407- result_list = arlexecute .execute (image_scatter_channels , nout = nchan )(gathered_results_list , subimages = nchan )
460+ # gathered_results_list = arlexecute.execute(image_gather_facets, nout=1)(scattered_results_list,
461+ # deconvolve_model_imagelist,
462+ # facets=deconvolve_facets,
463+ # overlap=deconvolve_overlap,
464+ # taper=deconvolve_taper)
465+ # result_list = arlexecute.execute(image_scatter_channels, nout=nchan)(gathered_results_list, subimages=nchan)
466+
467+ scattered_channel_results_list = [arlexecute .execute (image_scatter_channels , nout = nchan )(scat , subimages = nchan )
468+ for scat in scattered_results_list ]
469+
470+ # The structure is now [[channels] for facets]. We do the reverse transpose to the one above.
471+ result_list = [arlexecute .execute (image_gather_facets , nout = 1 )([scattered_channel_results_list [facet ][chan ]
472+ for facet in range (deconvolve_number_facets )],
473+ model_imagelist [chan ], facets = deconvolve_facets ,
474+ overlap = deconvolve_overlap )
475+ for chan in range (nchan )]
408476
409477 return arlexecute .optimize (result_list )
410478
0 commit comments