def dispAstropy(imname='sim_onepoint_true.im'): exportfits(imagename=imname, fitsimage=imname + '.fits', overwrite=True) hdu = fits.open(imname + '.fits')[0] wcs = WCS(hdu.header, naxis=2) fig = pl.figure() fig.add_subplot(121, projection=wcs) pl.imshow(hdu.data[0, 0, :, :], origin='lower', cmap=pl.cm.viridis) pl.xlabel('RA') pl.ylabel('Dec')
data_path = '/home/roberto/ALMA_IMF/residuals_fix/continuum/' plots_path = '/home/roberto/ALMA_IMF/residuals_fix/plots/' max_npix_peak = 100 ################################### data_path = os.path.join(data_path) files = [ f for f in glob.glob(data_path + '*') if not os.path.basename(f).endswith('.fits') ] for file in files: if not os.path.exists(file + '.fits'): print('Running exportfits on file ' + file) exportfits(imagename=file, fitsimage=file + '.fits') else: print(file + '.fits' + ' already exists. Not running exportfits.') fits_files = glob.glob(data_path + '*.fits') for file in fits_files: hdu = fits.open(file) data = hdu[0].data header = hdu[0].header bmaj_npix = header['BMAJ'] / header['CDELT2'] bmin_npix = header['BMIN'] / header['CDELT2'] clean_beam_sum = (np.pi / (4 * np.log(2))) * bmaj_npix * bmin_npix hdu.close()
if cleanup_temps: os.system(f"rm -r {common_beam_outpath}/*") # Keep the weight file. Remove the rest. os.system(f"rm -r {outfile}.mask") os.system(f"rm -r {outfile}.sum") os.system(f"rm -r {outfile}.sum_noise") os.system(f"rm -r {outfile}.temp") os.system(f"rm -r {outfile}.temp_noise") # Export to FITS. outfile_fits = f'{outfile}.fits' exportfits(imagename=outfile, fitsimage=outfile_fits, velocity=True, optical=False, dropdeg=True, history=False) # Lastly, convert to K from Jy/beam. outfile_fits_K = f'{outfile}_K.fits' cube = SpectralCube.read(outfile_fits) cube.allow_huge_operations = True cube = cube.to(u.K) cube.write(outfile_fits_K) del cube # Remove the original Jy/beam fits file. # No need to gave a CASA image and fits file of the
def export_fitspng(src_dir, n_spw, epoch, ATCA_band, tar): for i in range(0, n_spw): spw = str(i) imagename = f"{src_dir}/casa_files/{tar}_{ATCA_band}_{spw}" exportfits( imagename=f"{src_dir}/casa_files/{imagename}_preself.image", fitsimage=f"{src_dir}/images/{imagename}_preself.fits", overwrite=True, ) exportfits( imagename=f"{src_dir}/casa_files/{imagename}_self1.image", fitsimage=f"{src_dir}/images/{imagename}_self1.fits", overwrite=True, ) exportfits( imagename=f"{src_dir}/casa_files/{imagename}_self2.image", fitsimage=f"{src_dir}/images/{imagename}_self2.fits", overwrite=True, ) exportfits( imagename=f"{src_dir}/casa_files/{imagename}_self3.image", fitsimage=f"{src_dir}/images/{imagename}_self3.fits", overwrite=True, ) exportfits( imagename=f"{src_dir}/casa_files/{imagename}_self3_pbcor", fitsimage=f"{src_dir}/images/{imagename}_self3_pbcor.fits", overwrite=True, ) extensions = ["preself", "self1", "self2", "self3"] for ext in extensions: imname = f"{src_dir}/casa_files/{imagename}_{ext}.image" plt.subplots(1, 1, figsize=(18, 12)) pix, w = buildImage(imname) ax = plt.subplot(1, 1, 1, projection=w) p1 = int(pix.shape[0] * 0.25) p2 = int(pix.shape[0] * 0.75) norm = simple_norm(pix[p1:p2, p1:p2].transpose(), "sqrt") im = ax.imshow( pix[p1:p2, p1:p2].transpose(), origin="lower", cmap=plt.cm.plasma, norm=norm, ) plt.colorbar(im, ax=ax) ax.set_xlabel("Right Ascension", fontsize=30) ax.set_ylabel("Declination", fontsize=30) plt.title(f"{imagename} {ext}", fontsize=30) plt.savefig(f"{src_dir}/images/{imagename}_{ext}.png") plt.close() mask_im = f"{src_dir}/casa_files/{tar}_{ATCA_band}_mfs.mask" plt.subplots(1, 1, figsize=(18, 12)) pix, w = buildImage(mask_im) ax = plt.subplot(1, 1, 1, projection=w) p1 = int(pix.shape[0] * 0.25) p2 = int(pix.shape[0] * 0.75) im = ax.imshow(pix[p1:p2, p1:p2].transpose(), origin="lower", cmap=plt.cm.plasma) plt.colorbar(im, ax=ax) ax.set_xlabel("Right Ascension", fontsize=30) ax.set_ylabel("Declination", fontsize=30) plt.title(f"{tar} {ATCA_band} mask", fontsize=30) plt.savefig(f"{src_dir}/images/{tar}_{ATCA_band}_mask.png") plt.close() return
import subprocess import casatasks as cts import parameters as prms #cts.exportfits(imagename='/mnt/work/work/HI_DATA/out_RGG5/RGG5_cube_14kmps/uvran_0.5~20klambda.image', fitsimage="../out_RGG5/RGG5_finalcube_20lkambda.fits", dropstokes = True, velocity = True) cts.exportfits(imagename='/Data/omkar/HI_DATA/quenched_hi/out_AGC722572/AGC722572_cube_14kmps/uvran_0.5~5klambda.image', fitsimage="/Data/omkar/HI_DATA/quenched_hi/out_AGC722572/AGC722572_cube_14kmps/AGC722572_finalcube_5lkambda.fits", dropstokes = True, velocity = True) #cts.exportfits(imagename='/mnt/work/work/HI_DATA/blcal_test/RGG5_cube_multiscale_14kmps/uvran_1~30klambda.image', fitsimage="../blcal_test/RGG5_finalcube_msclean_30lkambda.fits", dropstokes = True, velocity = True)
def exportfits(infile, outfile): if os.path.exists(outfile): os.remove(outfile) casatasks.exportfits(infile, outfile, dropdeg=True, dropstokes=True)
def quicklook_line_imaging( myvis, thisgal, linespw_dict, nchan_vel=5, # channel_width_kms=20., niter=0, nsigma=5., imsize_max=800, overwrite_imaging=False, export_fits=True): if not os.path.exists("quicklook_imaging"): os.mkdir("quicklook_imaging") this_vsys = target_vsys_kms[thisgal] # Pick our line range based on the HI for all lines. this_velrange = target_line_range_kms[thisgal]['HI'] # We have a MW foreground window on some targets. Skip this for the galaxy range. if isinstance(this_velrange[0], list): for this_range in this_velrange: if min(this_range) < this_vsys < max(this_range): this_velrange = this_range break # Check that the search for the right velocity range didn't fail if isinstance(this_velrange[0], list): raise ValueError( f"Unable to find range with target vsys ({this_vsys}) from {this_velrange}." f" Check the velocity ranges defined in target_setup.py for {thisgal}" ) # width_vel = channel_width_kms # width_vel_str = f"{width_vel}km/s" start_vel = f"{int(min(this_velrange))}km/s" # nchan_vel = int(abs(this_velrange[0] - this_velrange[1]) / width_vel) width_vel = int( round(abs(this_velrange[0] - this_velrange[1]) / float(nchan_vel))) width_vel_str = f"{width_vel}km/s" # Select only the non-continuum SPWs line_spws = [] for thisspw in linespw_dict: if "continuum" not in linespw_dict[thisspw]['label']: # Our 20A-346 tracks have a combined OH1665/1667 SPW. Split into separate cubes in this case line_labels = linespw_dict[thisspw]['label'].split("-") for line_label in line_labels: line_spws.append([str(thisspw), line_label]) # Select our target fields. We will loop through # to avoid the time + memory needed for mosaics. synthutil = synthesisutils() myms = ms() # if no fields are provided use observe_target intent # I saw once a calibrator also has this intent so check carefully # mymsmd.open(vis) myms.open(myvis) mymsmd = myms.metadata() target_fields = mymsmd.fieldsforintent("*TARGET*", True) mymsmd.close() myms.close() t0 = datetime.datetime.now() # Loop through targets and line SPWs for target_field in target_fields: casalog.post(f"Quick look imaging of field {target_field}") # Loop through the SPWs to identify the biggest image size needed. # For ease downstream, we will use the same imsize for all SPWs. # NOTE: for L-band, that's a factor of ~2 difference. It may be more pronounced in other # bands cell_size = {} imsizes = [] for thisspw_info in line_spws: thisspw, line_name = thisspw_info # Ask for cellsize this_im = imager() this_im.selectvis(vis=myvis, field=target_field, spw=str(thisspw)) image_settings = this_im.advise() this_im.close() # When all data is flagged, uvmax = 0 so cellsize = 0. # Check for that case to avoid tclean failures # if image_settings[2]['value'] == 0.: # casalog.post(f"All data flagged for {this_imagename}. Skipping") # continue # NOTE: Rounding will only be reasonable for arcsec units with our L-band setup. # Could easily fail on ~<0.1 arcsec cell sizes. cell_size[thisspw] = [ image_settings[2]['value'], image_settings[2]['unit'] ] # No point in estimating image size for an empty SPW. if image_settings[2]['value'] == 0.: continue # For the image size, we will do an approx scaling was # theta_PB = 45 / nu (arcmin) this_msmd = msmetadata() this_msmd.open(myvis) mean_freq = this_msmd.chanfreqs( int(thisspw)).mean() / 1.e9 # Hz to GHz this_msmd.close() approx_pbsize = 1.2 * (45. / mean_freq) * 60 # arcsec approx_imsize = synthutil.getOptimumSize( int(approx_pbsize / image_settings[2]['value'])) imsizes.append(approx_imsize) if len(imsizes) == 0: casalog.post(f"{target_field} is fully flagged. Skipping.") continue this_imsize = min(imsize_max, max(imsizes)) for thisspw_info in line_spws: thisspw, line_name = thisspw_info casalog.post( f"Quick look imaging of field {target_field} SPW {thisspw}") target_field_label = target_field.replace('-', '_') this_imagename = f"quicklook_imaging/quicklook-{target_field_label}-spw{thisspw}-{line_name}-{myvis}" if export_fits: check_exists = os.path.exists(f"{this_imagename}.image.fits") else: check_exists = os.path.exists(f"{this_imagename}.image") if check_exists: if overwrite_imaging: rmtables(f"{this_imagename}*") os.remove(f"{this_imagename}.image.fits") else: casalog.post(f"Found {this_imagename}. Skipping imaging.") continue if cell_size[thisspw][0] == 0: casalog.post( f"All data flagged for {this_imagename}. Skipping") continue this_cellsize = f"{round(cell_size[thisspw][0] * 0.8, 1)}{cell_size[thisspw][1]}" this_pblim = 0.5 this_nsigma = nsigma this_niter = niter # Clean up any possible imaging remnants first rmtables(f"{this_imagename}*") tclean(vis=myvis, field=target_field, spw=str(thisspw), cell=this_cellsize, imsize=this_imsize, specmode='cube', weighting='briggs', robust=0.0, start=start_vel, width=width_vel_str, nchan=nchan_vel, niter=this_niter, nsigma=this_nsigma, imagename=this_imagename, restfreq=f"{linerest_dict_GHz[line_name]}GHz", pblimit=this_pblim) if export_fits: exportfits(imagename=f"{this_imagename}.image", fitsimage=f"{this_imagename}.image.fits", history=False, overwrite=True) # Clean-up extra imaging products if they are not needed. cleanup_misc_quicklook(this_imagename, remove_psf=True, remove_residual=this_niter == 0, remove_image=True if export_fits else False) t1 = datetime.datetime.now() casalog.post(f"Quicklook line imaging took {t1 - t0}")
def quicklook_continuum_imaging(myvis, contspw_dict, niter=0, nsigma=5., imsize_max=800, overwrite_imaging=False, export_fits=True): ''' Per-SPW MFS, nterm=1, dirty images of the targets ''' if not os.path.exists("quicklook_imaging"): os.mkdir("quicklook_imaging") # Select only the continuum SPWs (in case there are any line SPWs). continuum_spws = [] for thisspw in contspw_dict: if "continuum" in contspw_dict[thisspw]['label']: continuum_spws.append(str(thisspw)) # Select our target fields. We will loop through # to avoid the time + memory needed for mosaics. synthutil = synthesisutils() myms = ms() # if no fields are provided use observe_target intent # I saw once a calibrator also has this intent so check carefully # mymsmd.open(vis) myms.open(myvis) mymsmd = myms.metadata() target_fields = mymsmd.fieldsforintent("*TARGET*", True) mymsmd.close() myms.close() t0 = datetime.datetime.now() # Loop through targets and line SPWs for target_field in target_fields: casalog.post(f"Quick look imaging of field {target_field}") cell_size = {} imsizes = [] for thisspw in continuum_spws: # Ask for cellsize this_im = imager() this_im.selectvis(vis=myvis, field=target_field, spw=str(thisspw)) image_settings = this_im.advise() this_im.close() # When all data is flagged, uvmax = 0 so cellsize = 0. # Check for that case to avoid tclean failures # if image_settings[2]['value'] == 0.: # casalog.post(f"All data flagged for {this_imagename}. Skipping") # continue # NOTE: Rounding will only be reasonable for arcsec units with our L-band setup. # Could easily fail on ~<0.1 arcsec cell sizes. cell_size[thisspw] = [ image_settings[2]['value'], image_settings[2]['unit'] ] # No point in estimating image size for an empty SPW. if image_settings[2]['value'] == 0.: continue # For the image size, we will do an approx scaling was # theta_PB = 45 / nu (arcmin) this_msmd = msmetadata() this_msmd.open(myvis) mean_freq = this_msmd.chanfreqs( int(thisspw)).mean() / 1.e9 # Hz to GHz this_msmd.close() approx_pbsize = 1.2 * (45. / mean_freq) * 60 # arcsec approx_imsize = synthutil.getOptimumSize( int(approx_pbsize / image_settings[2]['value'])) imsizes.append(approx_imsize) if len(imsizes) == 0: casalog.post(f"{target_field} is fully flagged. Skipping.") continue this_imsize = min(imsize_max, max(imsizes)) for thisspw in continuum_spws: casalog.post( f"Quick look imaging of field {target_field} SPW {thisspw}") target_field_label = target_field.replace('-', '_') this_imagename = f"quicklook_imaging/quicklook-{target_field_label}-spw{thisspw}-continuum-{myvis}" if export_fits: check_exists = os.path.exists(f"{this_imagename}.image.fits") else: check_exists = os.path.exists(f"{this_imagename}.image") if check_exists: if overwrite_imaging: rmtables(f"{this_imagename}*") os.remove(f"{this_imagename}.image.fits") else: casalog.post(f"Found {this_imagename}. Skipping imaging.") continue if cell_size[thisspw][0] == 0: casalog.post( f"All data flagged for {this_imagename}. Skipping") continue this_cellsize = f"{round(cell_size[thisspw][0] * 0.8, 1)}{cell_size[thisspw][1]}" this_pblim = 0.5 this_nsigma = nsigma this_niter = niter # Clean up any possible imaging remnants first rmtables(f"{this_imagename}*") tclean(vis=myvis, field=target_field, spw=str(thisspw), cell=this_cellsize, imsize=this_imsize, specmode='mfs', nterms=1, weighting='briggs', robust=0.0, niter=this_niter, nsigma=this_nsigma, fastnoise=True, imagename=this_imagename, pblimit=this_pblim) if export_fits: exportfits(imagename=f"{this_imagename}.image", fitsimage=f"{this_imagename}.image.fits", history=False, overwrite=True) # Clean-up extra imaging products if they are not needed. cleanup_misc_quicklook(this_imagename, remove_psf=True, remove_residual=this_niter == 0, remove_image=True if export_fits else False) t1 = datetime.datetime.now() casalog.post(f"Quicklook continuum imaging took {t1 - t0}")
def runtclean(vis, imname, startmodel='', spw='', field='', specmode='mfs', imsize=[], cell='', phasecenter='', start=0, width=1, nchan=-1, restfreq=None, threshold='', niter=0, usemask='auto-multithresh', sidelobethreshold=2.0, noisethreshold=4.25, lownoisethreshold=1.5, minbeamfrac=0.3, growiterations=75, negativethreshold=0.0, mask='', pbmask=0.4, interactive=True): """ runtclean (A. Plunkett, NRAO) a wrapper around the CASA task "TCLEAN," vis - the MS containing the interferometric data imname - the root name of the output images startmodel - start model for cleaning default: '' i.e. no start model, example: 'TP.scaled.image' spw - the standard selection parameter spw of tclean default: '' i.e. all SPWs field - the standard selection parameter field of tclean default: '' i.e. all fields specmode - the standard tclean specmode parameter: supported are msf or cube default: msf imsize - (optional) the standard tclean imsize parameter should correspond to the imagesize for the most extended interferometer config. default: determine from the input MS with aU.pickCellSize cell - (optional) the standard tclean cell parameter should correspond to the cell size for the most extended interferometer config, i.e. smallest beam / 5. default: determine from the input MS with aU.pickCellSize phasecenter - the standard tclean phasecenter parameter e.g. 'J2000 12:00:00 -35.00.00.0000' default: '' - determine from the input MS with aU.pickCellSize start - the standard tclean start parameter default: 0 width - the standard tclean width parameter default: 1 nchan - the standard tclean nchan parameter default: -1 restfreq - the restfrequency to write to the image for velocity calculations default: None, example: '115.271GHz' threshold - the threshold for cleaning default: None, example: '12mJy' niter - the standard tclean niter parameter default: 0, example: niter=1000000 usemask - the standard tclean mask parameter. If usemask='auto-multithresh', can specify: sidelobethreshold, noisethreshold, lownoisethreshold, minbeamfrac, growiterations - if usemask='user', must specify mask='maskname.mask' if usemask='pb', can specify pbmask=0.4, or some level. default: 'auto-multithresh' interactive - the standard tclean interactive option default: True Example: runtclean('gmc_120L.alma.all_int-weighted.ms', 'gmc_120L', phasecenter='J2000 12:00:00 -35.00.00.0000', spw='0', field='0~68', imsize=[1120,1120], cell='0.21arcsec', threshold='12mJy',niter=100000, usemask='auto-multithresh') """ if os.path.exists(vis): myvis = vis else: print(vis + ' does not exist') return False mymaskname = '' if usemask == 'auto-multithresh': mymask = usemask print('Run with {0} mask'.format(mymask)) elif usemask == 'pb': mymask = usemask pbmask = pbmask print('Run with {0} mask {1}'.format(mymask, pbmask)) elif usemask == 'user': if os.path.exists(maskname): mymask = usemask mymaskname = mask print('Run with {0} mask {1} '.format(mymask, maskname)) else: print('mask ' + maskname + ' does not exist, or not specified') return False else: print('check the mask options') return False os.system('rm -rf ' + imname + '.TCLEAN.*') tclean( vis=myvis, imagename=imname + '.TCLEAN', startmodel=startmodel, field=field, intent='OBSERVE_TARGET#ON_SOURCE', phasecenter=phasecenter, stokes='I', spw=spw, outframe='LSRK', specmode=specmode, nterms=1, imsize=imsize, cell=cell, deconvolver='hogbom', niter=niter, cycleniter=niter, cyclefactor=2.0, weighting='briggs', robust=0.5, gridder='mosaic', pbcor=True, threshold=threshold, interactive=interactive, # Masking Parameters below this line # --> Should be updated depending on dataset usemask=mymask, sidelobethreshold=sidelobethreshold, noisethreshold=noisethreshold, lownoisethreshold=lownoisethreshold, minbeamfrac=minbeamfrac, growiterations=growiterations, negativethreshold=negativethreshold, mask=mask, pbmask=pbmask, verbose=True) print('Exporting final pbcor image to FITS ...') exportfits(imname + '.TCLEAN.image.pbcor', imname + '.TCLEAN.pbcor.fits') return True
def runfeather(intimage, intpb, sdimage, featherim='featherim'): """ runtcleanFeather (A. Plunkett, NRAO) a wrapper around the CASA task "FEATHER," intimage - the interferometry image default: None, example: 'imagename.image' intpb - the interferometry primary beam default: None, example: 'imagename.pb' sdimage - the Single Dish image Note that in case you are creating a cube, this image must be a cube with the same spectral grid as the one you are trying to create. default: None, example: 'TPimage.image' featherim - the name of the output feather image default: 'featherim' Example: runfeather(intimage='',intpb='',sdimage='',featherim='') """ ## Call Feather module if os.path.exists(sdimage): mysdimage = sdimage else: print(sdimage + ' does not exist') return False if os.path.exists(intimage): myintimage = intimage else: print(intimage + ' does not exist') return False if os.path.exists(intpb): myintpb = intpb else: print(intpb + ' does not exist') return False # TO DO: Improve this bit, because it's messy # # ##################################### # # PROCESS DATA # # ##################################### # # Reorder the axes of the low to match high/pb # myfiles=[myintimage,mysdimage] # mykeys=['cdelt1','cdelt2','cdelt3','cdelt4'] # os.system('rm -rf lowres.* ') # im_axes={} # print('Making dictionary of axes information for high and lowres images') # for f in myfiles: # print(f) # print('------------') # axes = {} # i=0 # for key in mykeys: # q = imhead(f,mode='get',hdkey=key) # axes[i]=q # i=i+1 # print(str(key)+' : '+str(q)) # im_axes[f]=axes # print(' ') # order=[] # for i in range(4): # hi_ax = im_axes[myintimage][i]['unit'] # lo_ax = im_axes[myintimage][i]['unit'] # if hi_ax == lo_ax: # order.append(str(i)) # else: # lo_m1 = im_axes[mysdimage][i-1]['unit'] # if hi_ax == lo_m1: # order.append(str(i-1)) # else: # lo_p1 = im_axes[mysdimage][i+1]['unit'] # if hi_ax == lo_p1: # order.append(str(i+1)) # order = ''.join(order) # print('order is '+order) # if order=='0,1,2,3': # print('No reordering necessary') # else: # imtrans(imagename=mysdimage,outfile='lowres.ro',order=order) # lowres='lowres.ro' # print('Had to reorder!') # Regrid low res Image to match high res image print('Regridding lowres image...') imregrid(imagename=mysdimage, template=myintimage, axes=[0, 1, 2], output='lowres.regrid') # Multiply the lowres image with the highres primary beam response print('Multiplying lowres by the highres pb...') immath(imagename=['lowres.regrid', myintpb], expr='IM0*IM1', outfile='lowres.multiplied') # Feather together the low*pb and hi images print('Feathering...') feather(imagename=featherim + '.image', highres=myintimage, lowres='lowres.multiplied', lowpassfiltersd=True) os.system('rm -rf ' + featherim + '.image.pbcor') immath(imagename=[featherim + '.image', myintpb], expr='IM0/IM1', outfile=featherim + '.image.pbcor') print('Exporting final pbcor image to FITS ...') exportfits(featherim + '.image.pbcor', featherim + '.image.pbcor.fits') return True
def runsdintimg(vis, sdimage, jointname, spw='', field='', specmode='mfs', sdpsf='', threshold=None, sdgain=5, imsize=[], cell='', phasecenter='', dishdia=12.0, start=0, width=1, nchan=-1, restfreq=None, interactive=True): """ runsdintimg (D. Petry, ESO) a wrapper around the CASA task "sdintimaging" vis - the MS containing the interferometric data sdimage - the Single Dish image Note that in case you are creating a cube, this image must be a cube with the same spectral grid as the one you are trying to create. jointname - the imagename of the output images spw - the standard selection parameter spw of tclean default: '' i.e. all SPWs field - the standard selection parameter field of tclean default: '' i.e. all fields specmode - the standard tclean specmode parameter: supported are msf or cube default: msf sdpsf - (optional) the SD PSF, must have the same coords as sdimage if omitted or set to '' (empty string), a PSF will be derived from the beam information in sdimage threshold - the tclean threshold sdgain - the weight of the SD data relative to the interferometric data default: 5 'auto' - determine the scale automatically (experimental) imsize - the standard tclean imsize parameter should correspond to the imagesize for the most extended interferometer config. cell - the standard tclean cell parameter should correspond to the cell size for the most extended interferometer config, i.e. smallest beam / 5. phasecenter - the standard tclean phasecenter parameter e.g. 'J2000 12:00:00 -35.00.00.0000' default: '' - determine from the input MS with aU.pickCellSize dishdia - in metres, (optional) used if no sdpsf is provided default: 12.0 start - the standard tclean start parameter default: 0 width - the standard tclean width parameter default: 1 nchan - the standard tclean nchan parameter default: -1 restfreq - the restfrequency to write to the image for velocity calculations default: None, example: '115.271GHz' interactive - if True (default) use interactive cleaning with initial mask set using pbmask=0.4 if False use non-interactive clean with automasking (you will need to provide the threshold parameter) Examples: runsdintimg('gmc_120L.alma.all_int-weighted.ms','gmc_120L.sd.image', 'gmc_120L.joint-sdgain2.5', phasecenter='J2000 12:00:00 -35.00.00.0000', sdgain=2.5, spw='0', field='0~68', imsize=[1120,1120], cell='0.21arcsec') ... will do an interactive clean for an agg. bw. image. A pbmask at level 0.4 will be suggested as a start. runsdintimg('gmc_120L.alma.all_int-weighted.ms','gmc_120L.sd.reimported.image', 'deepclean-automask-sdgain1.25', phasecenter='J2000 12:00:00 -35.00.00.0000', sdgain=1.25, spw='0',field='0~68', imsize=[1120,1120], cell='0.21arcsec', threshold='0.012Jy', interactive=False) ... will run a non-interactive clean for an agg. bw. image using automasking. runsdintimg('ngc253.ms','ngc253-b6-tp-cube-200chan.image', 'ngc253-sdgain5', spw='0', specmode='cube', field='NGC_253', imsize=[500, 500], cell='1.2arcsec', phasecenter=3, nchan = 200, start=150, width=1, restfreq='230.538GHz') ... will run an interactive clean on a cube. """ if os.path.exists(vis): myvis = vis else: print(vis + ' does not exist') return False if os.path.exists(sdimage): mysdimage = sdimage else: print(sdimage + ' does not exist') return False mysdpsf = '' if sdpsf != '': if os.path.exists(sdpsf): mysdpsf = sdpsf else: print(sdpsf + ' does not exist') return False if specmode not in ['mfs', 'cube']: print('specmode \"' + specmode + '\" is not supported.') return False if not type(threshold) == str or 'Jy' not in threshold: if not interactive: print("You must provide a valid threshold, example '1mJy'") return False else: print( "You have not set a valid threshold. Please do so in the graphical user interface!" ) threshold = '1mJy' myia = iatool() myhead = imhead(mysdimage) myaxes = list(myhead['axisnames']) numchan = myhead['shape'][myaxes.index('Frequency')] print('Testing whether the sd image has per channel beams ...') myia.open(mysdimage) try: mybeam = myia.restoringbeam() except: myia.close() casalog.post('ERROR: sdimage does not contain beam information.', 'SEVERE', origin='runsdintimg') return False haspcb = False if 'beams' in mybeam.keys(): haspcb = True casalog.post("The sdimage has a per channel beam.", 'INFO', origin='runsdintimg') myia.close() if not haspcb: os.system('rm -rf copy_of_' + mysdimage) os.system('cp -R ' + mysdimage + ' copy_of_' + mysdimage) if numchan == 1: # image has only one channel; need workaround for per-channel-beam problem myia.open('copy_of_' + mysdimage) mycoords = myia.coordsys().torecord() mycoords['spectral2']['wcs']['crval'] += mycoords['spectral2'][ 'wcs']['cdelt'] myia.setcoordsys(mycoords) myia.close() tmpia = myia.imageconcat( outfile='mod_' + mysdimage, infiles=[mysdimage, 'copy_of_' + mysdimage], axis=3, overwrite=True) tmpia.close() mysdimage = 'mod_' + mysdimage numchan = 2 myia.open(mysdimage) myia.setrestoringbeam(remove=True) for i in range(numchan): myia.setrestoringbeam(beam=mybeam, log=True, channel=i, polarization=0) myia.close() casalog.post( 'Needed to give the sdimage a per-channel beam. Modifed image is in ' + mysdimage, 'WARN', origin='runsdintimg') # specmode and deconvolver if specmode == 'mfs': mydeconvolver = 'mtmfs' elif specmode == 'cube': mydeconvolver = 'hogbom' numchan = nchan scales = [0] mygridder = 'mosaic' # image and cell size npnt = 0 if imsize == [] or cell == '': casalog.post( 'You need to provide values for the parameters imsize and cell.', 'SEVERE', origin='runsdintimg') return False if phasecenter == '': phasecenter = npnt if restfreq == None: therf = [] else: therf = [restfreq] os.system('rm -rf ' + jointname + '.*') if interactive: sdintimaging( vis=myvis, sdimage=mysdimage, sdpsf=mysdpsf, dishdia=dishdia, sdgain=sdgain, usedata='sdint', imagename=jointname, imsize=imsize, cell=cell, phasecenter=phasecenter, weighting='briggs', robust=0.5, specmode=specmode, gridder=mygridder, pblimit=0.2, pbcor=True, interpolation='linear', wprojplanes=1, deconvolver=mydeconvolver, scales=scales, nterms=1, niter=10000000, spw=spw, start=start, width=width, nchan=numchan, field=field, cycleniter=100, threshold=threshold, restfreq=therf, perchanweightdensity=False, interactive=True, usemask='pb', pbmask=0.4, ) else: # non-interactive, use automasking sdintimaging(vis=myvis, sdimage=mysdimage, sdpsf=mysdpsf, dishdia=dishdia, sdgain=sdgain, usedata='sdint', imagename=jointname, imsize=imsize, cell=cell, phasecenter=phasecenter, weighting='briggs', robust=0.5, specmode=specmode, gridder=mygridder, pblimit=0.2, pbcor=True, interpolation='linear', wprojplanes=1, deconvolver=mydeconvolver, scales=scales, nterms=1, niter=10000000, spw=spw, start=start, width=width, nchan=numchan, field=field, threshold=threshold, restfreq=therf, perchanweightdensity=False, interactive=False, cycleniter=100000, cyclefactor=2.0, usemask='auto-multithresh', sidelobethreshold=2.0, noisethreshold=4.25, lownoisethreshold=1.5, minbeamfrac=0.3, growiterations=75, negativethreshold=0.0) print('Exporting final pbcor image to FITS ...') if mydeconvolver == 'mtmfs': exportfits(jointname + '.joint.multiterm.image.tt0.pbcor', jointname + '.joint.multiterm.image.tt0.pbcor.fits') elif mydeconvolver == 'hogbom': exportfits(jointname + '.joint.cube.image.pbcor', jointname + '.joint.cube.image.pbcor.fits') return True
image_name = f"{permosaic_path}/{line}/{prefix}_{line}_{spec}" if not os.path.exists(f"{image_name}.image.pbcor"): print(f"Did not find image for {prefix} {line} {spec}") continue fits_image = f"{image_name}.image.pbcor.fits" fits_image_K = f"{image_name}.image.pbcor_K.fits" need_export = not os.path.exists(fits_image_K) if need_export: exportfits(imagename=f"{image_name}.image.pbcor", fitsimage=fits_image, velocity=True, optical=False, dropdeg=True, history=False, overwrite=True) cube = SpectralCube.read(fits_image) cube.allow_huge_operations = True cube = cube.to(u.K) # Also convolve to a common beam. com_beam = cube.beams.common_beam( auto_increase_epsilon=True, max_epsilon=5e-3, max_iter=20) cube = cube.convolve_to(com_beam) cube.write(fits_image_K, overwrite=True)