From 445a8d0aa6e7e68db81491d1c16a5305263a63c2 Mon Sep 17 00:00:00 2001 From: David Rafferty <rafferty@strw.leidenuniv.nl> Date: Mon, 15 Oct 2012 08:06:13 +0000 Subject: [PATCH] Task #3403: Added option to include empty islands in output source-list catalogs. --- CEP/PyBDSM/doc/source/conf.py | 2 +- CEP/PyBDSM/doc/source/process_image.rst | 2 +- CEP/PyBDSM/doc/source/whats_new.rst | 8 +++ CEP/PyBDSM/doc/source/write_catalog.rst | 5 ++ CEP/PyBDSM/src/python/_version.py | 9 +++- CEP/PyBDSM/src/python/functions.py | 63 ++++++++++++----------- CEP/PyBDSM/src/python/gaul2srl.py | 37 +++++++++----- CEP/PyBDSM/src/python/gausfit.py | 27 ++++++---- CEP/PyBDSM/src/python/image.py | 3 ++ CEP/PyBDSM/src/python/interface.py | 3 +- CEP/PyBDSM/src/python/make_residimage.py | 65 +++++++++++++++--------- CEP/PyBDSM/src/python/opts.py | 5 +- CEP/PyBDSM/src/python/output.py | 16 +++++- CEP/PyBDSM/src/python/plotresults.py | 4 +- CEP/PyBDSM/src/python/pybdsm.py | 2 +- CEP/PyBDSM/src/python/readimage.py | 1 - CEP/PyBDSM/src/python/wavelet_atrous.py | 2 +- 17 files changed, 163 insertions(+), 91 deletions(-) diff --git a/CEP/PyBDSM/doc/source/conf.py b/CEP/PyBDSM/doc/source/conf.py index beb46f3e1f0..457c7341fe3 100644 --- a/CEP/PyBDSM/doc/source/conf.py +++ b/CEP/PyBDSM/doc/source/conf.py @@ -50,7 +50,7 @@ copyright = u'2012, David Rafferty and Niruj Mohan' # The short X.Y version. version = '1.4' # The full version, including alpha/beta/rc tags. -release = '1.4.4' +release = '1.4.5' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/CEP/PyBDSM/doc/source/process_image.rst b/CEP/PyBDSM/doc/source/process_image.rst index d7c365b9151..67594324bbb 100644 --- a/CEP/PyBDSM/doc/source/process_image.rst +++ b/CEP/PyBDSM/doc/source/process_image.rst @@ -909,7 +909,7 @@ The options for this module are as follows: This parameter is an integer (default is 2). When constructing a set of 'unresolved' sources for psf estimation, this parameter controls the factor of nyquist sample for binning bmaj, etc. vs SNR. psf_smooth - This parameter is a float (default is ``None``) that sets the smoothing scale used to smooth the interpolated images. Generally, artifacts due to noise and the interpolation can be significantly reduced if the smoothing scale is similar to the typical source separation scale. + This parameter is a float (default is ``None``) that sets the smoothing scale (in arcsec) used to smooth the interpolated images. Generally, artifacts due to noise and the interpolation can be significantly reduced if the smoothing scale is similar to the typical source separation scale. psf_snrcut This parameter is a float (default is 10.0). Only Gaussians with SNR greater than this are considered for processing. diff --git a/CEP/PyBDSM/doc/source/whats_new.rst b/CEP/PyBDSM/doc/source/whats_new.rst index 405eeb5c442..b62ae3fffb3 100644 --- a/CEP/PyBDSM/doc/source/whats_new.rst +++ b/CEP/PyBDSM/doc/source/whats_new.rst @@ -4,6 +4,14 @@ What's New ********** +Version 1.4.5 (2012/10/12): + + * Added option (``incl_empty``) to include empty islands (that have no un-flagged Gaussians) in output catalogs. Any such empty islands are given negative source IDs and have positions given by the location of the peak of the island. + + * Fixed a bug in Gaussian fitting that could cause a crash when fitting fails. + + * Fixed a bug in parallelization that could cause a crash due to improper concatenation of result lists. + Version 1.4.4 (2012/10/09): * Fixed a bug related to the parallelization of Gaussian fitting that could cause a crash due to improper mapping of island lists to processes. diff --git a/CEP/PyBDSM/doc/source/write_catalog.rst b/CEP/PyBDSM/doc/source/write_catalog.rst index aeee14b249a..e5fc7d128aa 100644 --- a/CEP/PyBDSM/doc/source/write_catalog.rst +++ b/CEP/PyBDSM/doc/source/write_catalog.rst @@ -32,6 +32,8 @@ The task parameters are as follows: :term:`format` ................ 'bbs': Format of output Gaussian list: 'bbs', 'ds9', 'fits', 'star', 'kvis', or 'ascii' :term:`incl_chan` ............ False : Include fluxes from each channel (if any)? + :term:`incl_empty` ........... False : Include islands without any valid Gaussians + (source list only)? :term:`srcroot` ............... None : Root name for entries in the output catalog. None => use image file name @@ -86,6 +88,9 @@ Each of the parameters is described in detail below. incl_chan This parameter is a Boolean (default is ``False``) that determines whether the total flux densities of each source measured in each channel by the spectral index module are included in the output. + incl_empty + This parameter is a Boolean (default is ``False``) that determines whether islands without any valid Gaussians are included in the output catalog. This option is only available for source lists. If True, islands for which Gaussian fitting failed will be included in the output catalog. In these cases, the source IDs are negative. + srcroot This parameter is a string (default is ``None``) that sets the root for source names in the output catalog. diff --git a/CEP/PyBDSM/src/python/_version.py b/CEP/PyBDSM/src/python/_version.py index 33b931ce61a..002422b03ae 100644 --- a/CEP/PyBDSM/src/python/_version.py +++ b/CEP/PyBDSM/src/python/_version.py @@ -9,7 +9,7 @@ adding to the changelog will naturally do this. """ # Version number -__version__ = '1.4.4' +__version__ = '1.4.5' # Store svn Revision number. For this to work, one also needs to do: # @@ -27,6 +27,13 @@ def changelog(): PyBDSM Changelog. ----------------------------------------------------------------------- + 2012/10/09 - Version 1.4.5 + + 2012/10/12 - Added option ("incl_empty") to include empty islands (that + have no un-flagged Gaussians) in output catalogs. Any such empty + islands are given negative source IDs and positions given by the + location of the peak of the island. + 2012/10/10 - Fixed a bug in Gaussian fitting that could cause a crash when fitting fails. Fixed a bug in parallelization that could cause a crash due to improper concatenation of result lists. diff --git a/CEP/PyBDSM/src/python/functions.py b/CEP/PyBDSM/src/python/functions.py index c31481ac9c3..2a116e72e91 100755 --- a/CEP/PyBDSM/src/python/functions.py +++ b/CEP/PyBDSM/src/python/functions.py @@ -734,38 +734,41 @@ def get_errors(img, p, stdav, bm_pix=None): errors = [] for i in range(ngaus): pp = p[i*7:i*7+7] - ### Now do error analysis as in Condon (and fBDSM) + ### Now do error analysis as in Condon (and fBDSM) size = pp[3:6] size = corrected_size(size) # angle is now degrees CCW from +y-axis - sq2 = sqrt(2.0) - if bm_pix == None: - bm_pix = N.array([img.pixel_beam[0]*fwsig, img.pixel_beam[1]*fwsig, img.pixel_beam[2]]) - dumr = sqrt(abs(size[0]*size[1]/(4.0*bm_pix[0]*bm_pix[1]))) - dumrr1 = 1.0+bm_pix[0]*bm_pix[1]/(size[0]*size[0]) - dumrr2 = 1.0+bm_pix[0]*bm_pix[1]/(size[1]*size[1]) - dumrr3 = dumr*pp[0]/stdav - d1 = sqrt(8.0*log(2.0)) - d2 = (size[0]*size[0]-size[1]*size[1])/(size[0]*size[0]) - try: - e_peak = pp[0]*sq2/(dumrr3*pow(dumrr1,0.75)*pow(dumrr2,0.75)) - e_maj=size[0]*sq2/(dumrr3*pow(dumrr1,1.25)*pow(dumrr2,0.25)) - e_min=size[1]*sq2/(dumrr3*pow(dumrr1,0.25)*pow(dumrr2,1.25)) # in fw - pa_rad = size[2]*pi/180.0 - e_x0 = sqrt( (e_maj*N.sin(pa_rad))**2 + (e_min*N.cos(pa_rad))**2 ) / d1 - e_y0 = sqrt( (e_maj*N.cos(pa_rad))**2 + (e_min*N.sin(pa_rad))**2 ) / d1 - e_pa=2.0/(d2*dumrr3*pow(dumrr1,0.25)*pow(dumrr2,1.25)) - e_pa=e_pa*180.0/pi - e_tot=pp[0]*sqrt(e_peak*e_peak/(pp[0]*pp[0])+(0.25/dumr/dumr)*(e_maj*e_maj/(size[0]*size[0])+e_min*e_min/(size[1]*size[1]))) - except: - e_peak = 0.0 - e_x0 = 0.0 - e_y0 = 0.0 - e_maj = 0.0 - e_min = 0.0 - e_pa = 0.0 - e_tot = 0.0 - if abs(e_pa) > 180.0: e_pa=180.0 # dont know why i did this - errors = errors + [e_peak, e_x0, e_y0, e_maj, e_min, e_pa, e_tot] + if size[0] == 0.0 or size[1] == 0.0: + errors = errors + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] + else: + sq2 = sqrt(2.0) + if bm_pix == None: + bm_pix = N.array([img.pixel_beam[0]*fwsig, img.pixel_beam[1]*fwsig, img.pixel_beam[2]]) + dumr = sqrt(abs(size[0]*size[1]/(4.0*bm_pix[0]*bm_pix[1]))) + dumrr1 = 1.0+bm_pix[0]*bm_pix[1]/(size[0]*size[0]) + dumrr2 = 1.0+bm_pix[0]*bm_pix[1]/(size[1]*size[1]) + dumrr3 = dumr*pp[0]/stdav + d1 = sqrt(8.0*log(2.0)) + d2 = (size[0]*size[0]-size[1]*size[1])/(size[0]*size[0]) + try: + e_peak = pp[0]*sq2/(dumrr3*pow(dumrr1,0.75)*pow(dumrr2,0.75)) + e_maj=size[0]*sq2/(dumrr3*pow(dumrr1,1.25)*pow(dumrr2,0.25)) + e_min=size[1]*sq2/(dumrr3*pow(dumrr1,0.25)*pow(dumrr2,1.25)) # in fw + pa_rad = size[2]*pi/180.0 + e_x0 = sqrt( (e_maj*N.sin(pa_rad))**2 + (e_min*N.cos(pa_rad))**2 ) / d1 + e_y0 = sqrt( (e_maj*N.cos(pa_rad))**2 + (e_min*N.sin(pa_rad))**2 ) / d1 + e_pa=2.0/(d2*dumrr3*pow(dumrr1,0.25)*pow(dumrr2,1.25)) + e_pa=e_pa*180.0/pi + e_tot=pp[0]*sqrt(e_peak*e_peak/(pp[0]*pp[0])+(0.25/dumr/dumr)*(e_maj*e_maj/(size[0]*size[0])+e_min*e_min/(size[1]*size[1]))) + except: + e_peak = 0.0 + e_x0 = 0.0 + e_y0 = 0.0 + e_maj = 0.0 + e_min = 0.0 + e_pa = 0.0 + e_tot = 0.0 + if abs(e_pa) > 180.0: e_pa=180.0 # dont know why i did this + errors = errors + [e_peak, e_x0, e_y0, e_maj, e_min, e_pa, e_tot] return errors diff --git a/CEP/PyBDSM/src/python/gaul2srl.py b/CEP/PyBDSM/src/python/gaul2srl.py index 87e1b2914fc..317b6b35fd8 100644 --- a/CEP/PyBDSM/src/python/gaul2srl.py +++ b/CEP/PyBDSM/src/python/gaul2srl.py @@ -43,11 +43,13 @@ class Op_gaul2srl(Op): img.aperture = None src_index = -1 - src_index_dum = 0 + dsrc_index = 0 sources = [] + dsources = [] no_gaus_islands = [] for iisl, isl in enumerate(img.islands): isl_sources = [] + isl_dsources = [] g_list = [] for g in isl.gaul: if g.flag == 0: @@ -64,21 +66,23 @@ class Op_gaul2srl(Op): isl_sources.extend(source) else: if not img.waveletimage: - no_gaus_islands.append((isl.island_id, isl.origin[0], isl.origin[1])) - # Put in the dummy Gaussian as the source and use negative IDs - #g_list = isl.gaul - #src_index_dum, source = self.process_single_gaussian(img, g_list, src_index_dum, code = 'S') - #sources.append(source) - #isl_sources.append(source) + dg = isl.dgaul[0] + no_gaus_islands.append((isl.island_id, dg.centre_pix[0], dg.centre_pix[1])) + # Put in the dummy Source as the source and use negative IDs + g_list = isl.dgaul + dsrc_index, dsource = self.process_single_gaussian(img, g_list, dsrc_index, code = 'S') + dsources.append(dsource) + isl_dsources.append(dsource) isl.sources = isl_sources - + isl.dsources = isl_dsources img.sources = sources + img.dsources = dsources img.nsrc = src_index + 1 mylogger.userinfo(mylog, "Number of sources formed from Gaussians", str(img.nsrc)) - if not img.waveletimage and len(no_gaus_islands) > 0 and not img.opts.quiet: - message = 'Gaussian fitting failed for the following island' + if not img.waveletimage and not img._pi and len(no_gaus_islands) > 0 and not img.opts.quiet: + message = 'All Gaussians were flagged for the following island' if len(no_gaus_islands) == 1: message += ':\n' else: @@ -90,10 +94,12 @@ class Op_gaul2srl(Op): else: message += 'Please check these islands. If they are valid islands and\n' if img.opts.atrous_do: - message += 'should be fit, try adjusting the flagging options.' + message += 'should be fit, try adjusting the flagging options (use\n'\ + 'show_fit with "ch0_flagged=True" to see the flagged Gaussians).' else: - message += 'should be fit, try adjusting the flagging options or \n'\ - 'enabling the wavelet module (with "atrous_do=True").' + message += 'should be fit, try adjusting the flagging options (use\n'\ + 'show_fit with "ch0_flagged=True" to see the flagged Gaussians)\n'\ + 'or enabling the wavelet module (with "atrous_do=True").' mylog.warning(message) img.completed_Ops.append('gaul2srl') @@ -114,7 +120,10 @@ class Op_gaul2srl(Op): bbox = img.islands[g.island_id].bbox ngaus = 1 island_id = g.island_id - gaussians = list([g]) + if g.gaus_num < 0: + gaussians = [] + else: + gaussians = list([g]) aper_flux = func.ch0_aperture_flux(img, g.centre_pix, img.aperture) source_prop = list([code, total_flux, peak_flux_centroid, peak_flux_max, aper_flux, posn_sky_centroid, \ diff --git a/CEP/PyBDSM/src/python/gausfit.py b/CEP/PyBDSM/src/python/gausfit.py index 996c7e14223..0b27e19dd01 100644 --- a/CEP/PyBDSM/src/python/gausfit.py +++ b/CEP/PyBDSM/src/python/gausfit.py @@ -100,22 +100,27 @@ class Op_gausfit(Op): idx = isl.island_id gaul = gaus_list[idx][0] fgaul = gaus_list[idx][1] + dgaul = [] gaul = [Gaussian(img, par, idx, gidx) for (gidx, par) in enumerate(gaul)] if len(gaul) == 0: - # No good Gaussians were fit. In this case, use the flagged - # Gaussian (estimated using moment analysis) as a dummy so + # No good Gaussians were fit. In this case, make a dummy + # Gaussian located at the island center so # that the source may still be included in output catalogs. - # These dummy Gaussians all have an ID of -1. -# gaul= [Gaussian(img, par, idx, -1, flag) -# for (gidx2, (flag, par)) in enumerate(fgaul)] + # These dummy Gaussians all have an ID of -1. They do not + # appear in any of the source or island Gaussian lists except + # the island dgaul list. + posn = N.unravel_index(N.argmax(isl.image*~isl.mask_active), isl.shape) + N.array(isl.origin) + par = [isl.max_value, posn[0], posn[1], 0.0, 0.0, 0.0] + dgaul = [Gaussian(img, par, idx, -1)] gidx = 0 fgaul= [Gaussian(img, par, idx, gidx + gidx2 + 1, flag) for (gidx2, (flag, par)) in enumerate(fgaul)] isl.gaul = gaul isl.fgaul= fgaul + isl.dgaul = dgaul gaussian_list = [g for isl in img.islands for g in isl.gaul] img.gaussians = gaussian_list @@ -133,13 +138,13 @@ class Op_gausfit(Op): for isl in img.islands: m = 0 for g in isl.gaul: - if g.gaussian_idx == -1: - nn -= 1; m = 0 - g.gaus_num = nn - else: - n += 1; m += 1 - g.gaus_num = n - 1 + n += 1; m += 1 + g.gaus_num = n - 1 tot_flux += g.total_flux + for dg in isl.dgaul: + nn -= 1 + dg.gaus_num = nn + isl.ngaus = m img.ngaus = n img.total_flux_gaus = tot_flux diff --git a/CEP/PyBDSM/src/python/image.py b/CEP/PyBDSM/src/python/image.py index 88da33456d3..48d4cb48bf4 100644 --- a/CEP/PyBDSM/src/python/image.py +++ b/CEP/PyBDSM/src/python/image.py @@ -41,6 +41,9 @@ class Image(object): basedir = String('DUMMY', doc="Base directory for output files") completed_Ops = List(String(), doc="List of completed operations") _is_interactive_shell = Bool(False, doc="PyBDSM is being used in the interactive shell") + waveletimage = Bool(False, doc="Image is a wavelet transform image") + _pi = Bool(False, doc="Image is a polarized intensity image") + def __init__(self, opts): diff --git a/CEP/PyBDSM/src/python/interface.py b/CEP/PyBDSM/src/python/interface.py index adf26bf8804..861287cb351 100644 --- a/CEP/PyBDSM/src/python/interface.py +++ b/CEP/PyBDSM/src/python/interface.py @@ -24,6 +24,7 @@ def process(img, **kwargs): # First, reset img to initial state (in case img is being reprocessed) if hasattr(img, 'use_io'): del img.use_io if hasattr(img, 'sources'): del img.sources + if hasattr(img, 'dsources'): del img.dsources if hasattr(img, 'gaussians'): del img.gaussians if hasattr(img, 'atrous_gaussians'): del img.atrous_gaussians if hasattr(img, 'islands'): del img.islands @@ -703,7 +704,7 @@ def write_catalog(img, outfile=None, format='bbs', srcroot=None, catalog_type='g patch "source" - sources are grouped by source into patches incl_chan - Include fluxes for each channel? - incl_empty - Include islands without any valid Gaussians (if any)? + incl_empty - Include islands without any valid Gaussians (source list only)? sort_by - Property to sort output list by: "flux" - sort by total integrated flux, largest first "indx" - sort by Gaussian and island or source index, smallest first diff --git a/CEP/PyBDSM/src/python/make_residimage.py b/CEP/PyBDSM/src/python/make_residimage.py index e13296df712..93a32683869 100644 --- a/CEP/PyBDSM/src/python/make_residimage.py +++ b/CEP/PyBDSM/src/python/make_residimage.py @@ -85,18 +85,7 @@ class Op_make_residimage(Op): ### residual rms and mean per island for isl in img.islands: resid = img.resid_gaus[isl.bbox] - n, m = resid.shape - - ind = N.where(~isl.mask_active) - resid = resid[ind] - isl.gresid_rms = N.std(resid) - isl.gresid_mean = N.mean(resid) - for src in isl.sources: - src.gresid_rms = N.std(resid) - src.gresid_mean = N.mean(resid) - for g in src.gaussians: - g.gresid_rms = N.std(resid) - g.gresid_mean = N.mean(resid) + self.calc_resid_mean_rms(isl, resid, type='gaus') # Calculate some statistics for the Gaussian residual image non_masked = N.where(~N.isnan(img.ch0)) @@ -145,17 +134,7 @@ class Op_make_residimage(Op): ### shapelet residual rms and mean per island for isl in img.islands: resid = img.resid_shap[isl.bbox] - n, m = resid.shape - ind = N.where(~isl.mask_active) - resid = resid[ind] - isl.sresid_rms = N.std(resid) - isl.sresid_mean = N.mean(resid) - for src in isl.sources: - src.sresid_rms = N.std(resid) - src.sresid_mean = N.mean(resid) - for g in src.gaussians: - g.sresid_rms = N.std(resid) - g.sresid_mean = N.mean(resid) + self.calc_resid_mean_rms(isl, resid, type='shap') # Calculate some statistics for the Shapelet residual image non_masked = N.where(~N.isnan(img.ch0)) @@ -193,4 +172,44 @@ class Op_make_residimage(Op): return ceil(S*1.5) return ceil(S*sqrt(-2*log(thresh/A))) + def calc_resid_mean_rms(self, isl, resid, type): + """Inserts mean and rms of residual image into isl, src, and gaussians + + type - specifies 'gaus' or 'shap' + """ + if len(isl.gaul) == 0: + resid = N.zeros(isl.shape) + + ind = N.where(~isl.mask_active) + resid = resid[ind] + if type == 'gaus': + isl.gresid_rms = N.std(resid) + isl.gresid_mean = N.mean(resid) + else: + isl.sresid_rms = N.std(resid) + isl.sresid_mean = N.mean(resid) + if hasattr(isl, 'sources'): + for src in isl.sources: + if type == 'gaus': + src.gresid_rms = N.std(resid) + src.gresid_mean = N.mean(resid) + else: + src.sresid_rms = N.std(resid) + src.sresid_mean = N.mean(resid) + for g in src.gaussians: + if type == 'gaus': + g.gresid_rms = N.std(resid) + g.gresid_mean = N.mean(resid) + else: + g.sresid_rms = N.std(resid) + g.sresid_mean = N.mean(resid) + if hasattr(isl, 'dsources'): + for dsrc in isl.dsources: # Handle dummy sources (if any) + if type == 'gaus': + dsrc.gresid_rms = N.std(resid) + dsrc.gresid_mean = N.mean(resid) + else: + dsrc.sresid_rms = N.std(resid) + dsrc.sresid_mean = N.mean(resid) + diff --git a/CEP/PyBDSM/src/python/opts.py b/CEP/PyBDSM/src/python/opts.py index b7631e66154..1c8091b724b 100644 --- a/CEP/PyBDSM/src/python/opts.py +++ b/CEP/PyBDSM/src/python/opts.py @@ -1087,11 +1087,10 @@ class Opts(object): group = 'hidden') incl_empty = Bool(False, doc = "Include islands without any valid Gaussians "\ - "(if any)?\n"\ + "(source list only)?\n"\ "If True, islands for which Gaussian fitting "\ "failed will be included in the output catalog. "\ - "In these cases, the source properties are "\ - "estimated using moment analysis, and the source IDs "\ + "In these cases, the source IDs "\ "are negative.", group = 'hidden') catalog_type = Enum('gaul', 'shap', 'srl', diff --git a/CEP/PyBDSM/src/python/output.py b/CEP/PyBDSM/src/python/output.py index 491c58c1560..ffdc104793b 100644 --- a/CEP/PyBDSM/src/python/output.py +++ b/CEP/PyBDSM/src/python/output.py @@ -266,7 +266,7 @@ def write_lsm_gaul(img, filename=None, srcroot=None, patch=None, def write_ds9_list(img, filename=None, srcroot=None, deconvolve=False, - clobber=False, objtype='gaul'): + clobber=False, incl_empty=False, objtype='gaul'): """Writes Gaussian list to a ds9 region file""" import numpy as N from const import fwsig @@ -279,10 +279,18 @@ def write_ds9_list(img, filename=None, srcroot=None, deconvolve=False, elif objtype == 'srl': root = img.parentname outl = [img.sources] + if incl_empty: + # Append the dummy sources for islands without any unflagged Gaussians + outl[0] += img.dsources outn = [] for src in img.sources: outn.append(root + '_i' + str(src.island_id) + '_s' + str(src.source_id)) + if incl_empty: + # Append the dummy sources for islands without any unflagged Gaussians + for dsrc in img.dsources: + outn.append(root + '_i' + str(dsrc.island_id) + '_s' + + str(dsrc.source_id)) outn = [outn] outstr_list = make_ds9_str(img, outl, outn, deconvolve=deconvolve) if filename == None: @@ -308,6 +316,9 @@ def write_ascii_list(img, filename=None, sort_by='indx', outl, outn, patl = list_and_sort_gaussians(img, patch=None, sort_by=sort_by) elif objtype == 'srl': outl = [img.sources] + if incl_empty: + # Append the dummy sources for islands without any unflagged Gaussians + outl[0] += img.dsources outstr_list = make_ascii_str(img, outl, objtype=objtype) if filename == None: if objtype == 'gaul': @@ -359,6 +370,9 @@ def write_fits_list(img, filename=None, sort_by='index', objtype='gaul', outl, outn, patl = list_and_sort_gaussians(img, patch=None, sort_by=sort_by) elif objtype == 'srl': outl = [img.sources] + if incl_empty: + # Append the dummy sources for islands without any unflagged Gaussians + outl[0] += img.dsources elif objtype == 'shap': outl = [img.islands] diff --git a/CEP/PyBDSM/src/python/plotresults.py b/CEP/PyBDSM/src/python/plotresults.py index cf9db04e387..f2956b98f75 100644 --- a/CEP/PyBDSM/src/python/plotresults.py +++ b/CEP/PyBDSM/src/python/plotresults.py @@ -300,7 +300,7 @@ def plotresults(img, ch0_image=True, rms_image=True, mean_image=True, valid = g.valid else: valid = True - if g.jlevel == 0 and valid: + if g.jlevel == 0 and valid and g.gaus_num >= 0: gidx = g.gaus_num e = Ellipse(xy=g.centre_pix, width=g.size_pix[0], height=g.size_pix[1], angle=g.size_pix[2]+90.0) @@ -324,7 +324,7 @@ def plotresults(img, ch0_image=True, rms_image=True, mean_image=True, if hasattr(img, 'gaussians'): for atrg in img.gaussians: - if atrg.jlevel > 0: + if atrg.jlevel > 0 and atrg.gaus_num >= 0: col = 'r' style = '-' gidx = atrg.gaus_num diff --git a/CEP/PyBDSM/src/python/pybdsm.py b/CEP/PyBDSM/src/python/pybdsm.py index 13504874593..a2ca8f2f22c 100644 --- a/CEP/PyBDSM/src/python/pybdsm.py +++ b/CEP/PyBDSM/src/python/pybdsm.py @@ -452,7 +452,7 @@ def write_catalog(**kwargs): print "\n\033[31;1mAborted\033[0m" write_catalog.arg_list = ['bbs_patches', 'format', 'outfile', 'srcroot', - 'incl_chan', 'clobber', 'catalog_type']#, 'incl_empty'] + 'incl_chan', 'clobber', 'catalog_type', 'incl_empty'] write_catalog.use_groups = False diff --git a/CEP/PyBDSM/src/python/readimage.py b/CEP/PyBDSM/src/python/readimage.py index 5155d2e2235..50f17569e00 100644 --- a/CEP/PyBDSM/src/python/readimage.py +++ b/CEP/PyBDSM/src/python/readimage.py @@ -112,7 +112,6 @@ class Op_readimage(Op): img.filename = img.opts.filename img.parentname = fname img.imagename = fname + '.pybdsm' - img.waveletimage = False if img.opts.output_all: # Set up directory to write output to basedir = './' + fname + '_pybdsm' diff --git a/CEP/PyBDSM/src/python/wavelet_atrous.py b/CEP/PyBDSM/src/python/wavelet_atrous.py index 7f260b3915f..ccf22d5d181 100644 --- a/CEP/PyBDSM/src/python/wavelet_atrous.py +++ b/CEP/PyBDSM/src/python/wavelet_atrous.py @@ -269,7 +269,7 @@ class Op_wavelet_atrous(Op): #self.morphfilter_pyramid(img, pdir) img.ngaus += ntot_wvgaus img.total_flux_gaus += total_flux - mylogger.userinfo(mylog, "Total flux density in model over all scales" , '%.3f Jy' % img.total_flux_gaus) + mylogger.userinfo(mylog, "Total flux density in model on all scales" , '%.3f Jy' % img.total_flux_gaus) if img.opts.output_all: func.write_image_to_file(img.use_io, img.imagename + '.atrous.cJ.fits', im_new, img, bdir) -- GitLab