################################################ # single dish + interfermeter join image reconstruction task # # ################################################ from __future__ import absolute_import import os import shutil import numpy import copy import time # get is_CASA6 and is_python3 from casatasks.private.casa_transition import * if is_CASA6: from casatasks import casalog from casatasks.private.imagerhelpers.imager_base import PySynthesisImager from casatasks.private.imagerhelpers.imager_parallel_continuum import PyParallelContSynthesisImager from casatasks.private.imagerhelpers.imager_parallel_cube import PyParallelCubeSynthesisImager from casatasks.private.imagerhelpers.input_parameters import ImagerParameters #from casatasks import imregrid from .cleanhelper import write_tclean_history, get_func_params from .sdint_helper import * from casatools import table from casatools import synthesisimager,synthesisutils else: from taskinit import * from tasks import * from imagerhelpers.imager_base import PySynthesisImager from imagerhelpers.imager_parallel_continuum import PyParallelContSynthesisImager from imagerhelpers.imager_parallel_cube import PyParallelCubeSynthesisImager from imagerhelpers.input_parameters import ImagerParameters from cleanhelper import write_tclean_history, get_func_params from sdint_helper import * table=casac.table synthesisimager=casac.synthesisimager synthesisutils=casac.synthesisutils try: if is_CASA6: from casampi.MPIEnvironment import MPIEnvironment from casampi import MPIInterface else: from mpi4casa.MPIEnvironment import MPIEnvironment from mpi4casa import MPIInterface mpi_available = True except ImportError: mpi_available = False sdintlib = SDINT_helper() synu = synthesisutils() # setup functions def setup_imagerObj(paramList=None): """ setup imaging parameters """ defaultconstructor = False if paramList!=None: if not isinstance(paramList, ImagerParameters): raise RuntimeError("Internal Error: invalid paramList") else: defaultconstructor = True if defaultconstructor: return PySynthesisImager else: return PySynthesisImager(params=paramList) def setup_imager(imagename, specmode,calcres,calpsf,inparams): """ Setup cube imaging for major cycles. - Do initialization - and run a major cycle """ # create a local copy of input params dict so that it can be # modified locparams = copy.deepcopy(inparams) # cube imaging setup locparams['imagename']=imagename locparams['specmode']='cube' locparams['niter']=0 locparams['deconvolver']='hogbom' #casalog.post("local inparams(msname) in setup_imager==",locparams['msname']) params = ImagerParameters(**locparams) #params = ImagerParameters(msname=self.vis, field=self.field,spw=self.spw, # imagename=imagename, # imsize=self.imsize, cell=self.cell, phasecenter=self.phasecenter, # weighting=self.weighting, # gridder=self.gridder, pblimit=self.pblimit,wprojplanes=self.wprojplanes, # specmode='cube',nchan=self.nchan, # reffreq=self.reffreq, width=self.width, start=self.start, interpolation=self.interpolation, # interactive=self.interactive, # deconvolver='hogbom', niter=0, # wbawp=True) ## Major cycle is either PySynthesisImager or PyParallelCubeSynthesisImager imagertool = setup_imagerObj(params) #self.imagertool = PySynthesisImager(params=params) imagertool.initializeImagers() imagertool.initializeNormalizers() imagertool.setWeighting() if 'psfphasecenter' in locparams: psfphasecenter = locparams['psfphasecenter'] else: psfphasecenter = '' ## Extra one for psfphasecenter... imagerInst=None if((psfphasecenter != '') and (gridder=='mosaic')): imagerInst = setup_imagerObj() gridder = locparams['gridder'] if calpsf == True: imagertool.makePSF() imagertool.makePB() if((psfphasecenter != '') and (gridder=='mosaic')): casalog.post("doing with different phasecenter psf", "INFO") imagertool.unlockimages(0) psfParameters=paramList.getAllPars() psfParameters['phasecenter']=psfphasecenter psfParamList=ImagerParameters(**psfParameters) psfimager=imagerInst(params=psfParamList) psfimager.initializeImagers() psfimager.setWeighting() psfimager.makeImage('psf', psfParameters['imagename']+'.psf') # can take out this since niter is fixed to 0 if locparams['niter'] >=0 : ## Make dirty image if calcres == True: t0=time.time(); imagertool.runMajorCycle() t1=time.time(); casalog.post("***Time for major cycle (calcres=T): "+"%.2f"%(t1-t0)+" sec", "INFO3", "task_tclean"); ## In case of no deconvolution iterations.... #if locparams['niter']==0 and calcres==False: # if savemodel != "none": # imagertool.predictModel() sdintlib.copy_restoringbeam(fromthis=imagename+'.psf', tothis=imagename+'.residual') return imagertool def setup_deconvolver(imagename,specmode,inparams): """ Cube or MFS minor cycles. """ #params = ImagerParameters(msname=self.vis, field=self.field,spw=self.spw, # imagename=imagename, # imsize=self.imsize, cell=self.cell, phasecenter=self.phasecenter, # weighting=self.weighting, # gridder=self.gridder, pblimit=self.pblimit,wprojplanes=self.wprojplanes, # specmode=self.specmode,nchan=self.nchan, # reffreq=self.reffreq, width=self.width, start=self.start, interpolation=self.interpolation, # interactive=self.interactive, # deconvolver=self.deconvolver, scales=self.scales,nterms=self.nterms, # niter=self.niter,cycleniter=self.cycleniter, threshold=self.threshold, # mask=self.mask) inparams['imagename']=imagename params = ImagerParameters(**inparams) deconvolvertool = setup_imagerObj(params) ## Why are we initializing these ? deconvolvertool.initializeImagers() deconvolvertool.initializeNormalizers() deconvolvertool.setWeighting() ### These three should be unncessary. Need a 'makeimage' method for csys generation. deconvolvertool.makePSF() ## Make this to get a coordinate system #deconvolvertool.makeImage('psf', imagename+'.psf') deconvolvertool.makePB() ## Make this to turn .weight into .pb maps ## Initialize deconvolvers. ( Order is important. This cleans up a leftover tablecache image.... FIX!) deconvolvertool.initializeDeconvolvers() deconvolvertool.initializeIterationControl() # This needs to be run before runMajorCycle deconvolvertool.runMajorCycle() ## Make this to make template residual images. return deconvolvertool def setup_sdimaging(template='',output='', inparms=None, sdparms=None): """ Make the SD cube Image and PSF Option 1 : Use/Regrid cubes for the observed image and PSF Option 2 : Make the SD image and PSF cubes using 'tsdimager's usage of the SD gridder option. Currently, only Option 1 is supported. """ sdintlib = SDINT_helper() if 'sdpsf' in sdparms: sdpsf = sdparms['sdpsf'] else: raise RuntimeError("Internal Error: missing sdpsf parameter") if 'sdimage' in sdparms: sdimage = sdparms['sdimage'] else: raise RuntimeError("Internal Error: missing sdimage parameter") if 'pblimit' in inparms: pblimit = inparms['pblimit'] if sdpsf !="": ## check the coordinates of psf with int psf sdintlib.checkpsf(sdpsf, template+'.psf') ## Regrid the input SD image and PSF cubes to the target coordinate system. #imregrid(imagename=sdimage, template=template+'.residual', # output=output+'.residual',overwrite=True,axes=[0,1]) sdintlib.regridimage(imagename=sdimage, template=template+'.residual', outfile=output+'.residual') #imregrid(imagename=sdimage, template=template+'.residual', # output=output+'.image',overwrite=True,axes=[0,1]) sdintlib.regridimage(imagename=sdimage, template=template+'.residual', outfile=output+'.image') if sdpsf !="": #imregrid(imagename=sdpsf, template=template+'.psf', # output=output+'.psf',overwrite=True,axes=[0,1]) sdintlib.regridimage(imagename=sdpsf, template=template+'.psf', outfile=output+'.psf') else: ## Make an internal sdpsf image if the user has not supplied one. casalog.post("Constructing a SD PSF cube by evaluating Gaussians based on the restoring beam information in the regridded SD Image Cube") sdintlib.create_sd_psf(sdimage=output+'.residual', sdpsfname=output+'.psf') ## Apply the pbmask from the INT image cube, to the SD cubes. #TTB: Create *.mask cube sdintlib.addmask(inpimage=output+'.residual', pbimage=template+'.pb', pblimit=pblimit) sdintlib.addmask(inpimage=output+'.image', pbimage=template+'.pb', pblimit=pblimit) def feather_residual(int_cube, sd_cube, joint_cube, applypb, inparm): if applypb==True: ## Take initial INT_dirty image to flat-sky. sdintlib.modify_with_pb(inpcube=int_cube+'.residual', pbcube=int_cube+'.pb', cubewt=int_cube+'.sumwt', chanwt=inparm['chanwt'], action='div', pblimit=inparm['pblimit'], freqdep=True) ## Feather flat-sky INT dirty image with SD image sdintlib.feather_int_sd(sdcube=sd_cube+'.residual', intcube=int_cube+'.residual', jointcube=joint_cube+'.residual', ## output sdgain=inparm['sdgain'], dishdia=inparm['dishdia'], usedata=inparm['usedata'], chanwt = inparm['chanwt']) if applypb==True: if inparm['specmode'].count('cube')>0: ## Multiply the new JOINT dirty image by the frequency-dependent PB. fdep_pb = True else: ## Multiply new JOINT dirty image by a common PB to get the effect of conjbeams. fdep_pb = False sdintlib.modify_with_pb(inpcube=joint_cube+'.residual', pbcube=int_cube+'.pb', cubewt=int_cube+'.sumwt', chanwt=inparm['chanwt'], action='mult', pblimit=inparm['pblimit'], freqdep=fdep_pb) def deleteTmpFiles(): if os.path.exists('tmp_intplane'): os.system('rm -rf tmp_intplane') if os.path.exists('tmp_sdplane'): os.system('rm -rf tmp_sdplane') if os.path.exists('tmp_jointplane'): os.system('rm -rf tmp_jointplane') def sdintimaging( usedata, ####### Single dish input data sdimage, sdpsf, sdgain, dishdia, ####### Interfermeter Data Selection vis,#='', selectdata, field,#='', spw,#='', timerange,#='', uvrange,#='', antenna,#='', scan,#='', observation,#='', intent,#='', datacolumn,#='corrected', ####### Image definition imagename,#='', imsize,#=[100,100], cell,#=['1.0arcsec','1.0arcsec'], phasecenter,#='J2000 19:59:28.500 +40.44.01.50', stokes,#='I', projection,#='SIN', startmodel,#='', ## Spectral parameters specmode,#='mfs', reffreq,#='', nchan,#=1, start,#='', width,#='', outframe,#='LSRK', veltype,#='', restfreq,#=[''], # sysvel,#='', # sysvelframe,#='', interpolation,#='', # chanchunks,#=1, perchanweightdensity, #='' ## ####### Gridding parameters gridder,#='ft', facets,#=1, psfphasecenter,#='', wprojplanes,#=1, ### PB vptable, mosweight, #=True aterm,#=True, psterm,#=True, wbawp ,#= True, # conjbeams ,#= True, cfcache ,#= "", usepointing, #=false computepastep ,#=360.0, rotatepastep ,#=360.0, pointingoffsetsigdev ,#=0.0, pblimit,#=0.01, # normtype,#='flatnoise', ####### Deconvolution parameters deconvolver,#='hogbom', scales,#=[], nterms,#=1, smallscalebias,#=0.0 ### restoration options restoration, restoringbeam,#=[], pbcor, ##### Outliers # outlierfile,#='', ### RESTRICTION : No support for outlier fields for joint SD-INT imaging. ##### Weighting weighting,#='natural', robust,#=0.5, noise,#0.0Jy npixels,#=0, # uvtaper,#=False, uvtaper,#=[], ##### Iteration control niter,#=0, gain,#=0.1, threshold,#=0.0, nsigma,#=0.0 cycleniter,#=0, cyclefactor,#=1.0, minpsffraction,#=0.1, maxpsffraction,#=0.8, interactive,#=False, ##### (new) Mask parameters usemask,#='user', mask,#='', pbmask,#='', # maskthreshold,#='', # maskresolution,#='', # nmask,#=0, ##### automask by multithresh sidelobethreshold,#=5.0, noisethreshold,#=3.0, lownoisethreshold,#=3.0, negativethreshold,#=0.0, smoothfactor,#=1.0, minbeamfrac,#=0.3, cutthreshold,#=0.01, growiterations,#=100 dogrowprune,#=True minpercentchange,#=0.0 verbose, #=False fastnoise, #=False ## Misc restart,#=True, #savemodel,#="none", # makeimages,#="auto" calcres,#=True, calcpsf):#=True, ####### State parameters #parallel):#=False): ################################################## # copied from SDINT.do_reconstruct ################################################# int_cube = imagename+'.int.cube' sd_cube = imagename+'.sd.cube' joint_cube = imagename+'.joint.cube' joint_multiterm = imagename+'.joint.multiterm' if specmode=='mfs': decname = joint_multiterm else: decname = joint_cube ##################################################### #### Sanity checks and controls ##################################################### ### Move these checks elsewhere ? inpparams=locals().copy() ###now deal with parameters which are not the same name #casalog.post("current inpparams=",inpparams) #casalog.post("inpparams.keys()=",inpparams.keys()) locvis=inpparams.pop('vis') #casalog.post("LOCVIS====",locvis) if type(locvis)==list: llocvis = [v.lstrip() for v in locvis] else: llocvis = locvis.lstrip() inpparams['msname']=llocvis inpparams['timestr']= inpparams.pop('timerange') inpparams['uvdist']= inpparams.pop('uvrange') inpparams['obs']= inpparams.pop('observation') inpparams['state']= inpparams.pop('intent') inpparams['loopgain']=inpparams.pop('gain') inpparams['scalebias']=inpparams.pop('smallscalebias') sdparms={} sdparms['sdimage']=inpparams['sdimage'] sdparms['sdpsf']=inpparams['sdpsf'] sdparms['sdgain']=inpparams['sdgain'] if specmode=='cont': specmode='mfs' inpparams['specmode']='mfs' # from sdint # automatically decide if pb need to be applied if gridder=='mosaic' or gridder=='awproject': applypb = True else: applypb = False if (deconvolver=="mtmfs") and (specmode!='mfs') and (specmode!='cube' or nterms!=1) and (specmode!='cubedata' or nterms!=1): casalog.post( "The MSMFS algorithm (deconvolver='mtmfs') applies only to specmode='mfs' or specmode='cube' with nterms=1 or specmode='cubedata' with nterms=1.", "WARN", "task_sdintimaging" ) return if(deconvolver=="mtmfs" and (specmode=='cube' or specmode=='cubedata') and nterms==1 ): casalog.post( "The MSMFS algorithm (deconvolver='mtmfs') with specmode='cube', nterms=1 is currently not supported. Please use deconvolver='multiscale' instead for cubes.", "WARN", "task_sdintimaging" ) return if(specmode=='mfs' and deconvolver!='mtmfs'): casalog.post("Currently, only the multi-term MFS algorithm is supported for specmode=mfs. To make a single plane MFS image (while retaining the frequency dependence for the cube major cycle stage), please pick nterms=1 along with deconvolver=mtmfs. The scales parameter is still usable for multi-scale multi-term deconvolution","WARN","task_sdintimaging") return; if(usedata=='sd'): casalog.post("The Single-Dish-Only mode of sdintimaging is better supported via the deconvolve task which supports spectral cube, mfs and multi-term mfs deconvolution in the image domain alone. The deconvolve task is the more appropriate version to use for stand-alone image-domain deconvolution, and will not have the bookkeeping overheads currently present in the sdintimaging task's sd-only mode. Please note that the 'sd' option of the sdintimaging task will be removed in a subsequent release. Please refer to the task deconvolve documentation for instructions on how to prepare image and psf cubes for the deconvolve task for all these modes.","WARN","task_sdintimaging"); # if parallel==True: # casalog.post("Cube parallelization (all major cycles) is currently not supported via task_sdintimaging. This will be enabled after a cube parallelization rework.") # return; ##################################################### #### Construct ImagerParameters object ##################################################### imager = None paramList = None deconvolvertool = None # Put all parameters into dictionaries and check them. ##make a dictionary of parameters that ImagerParameters take if is_python3: defparm=dict(list(zip(ImagerParameters.__init__.__code__.co_varnames[1:], ImagerParameters.__init__.__defaults__))) else: defparm=dict(zip(ImagerParameters.__init__.__func__.__code__.co_varnames[1:], ImagerParameters.__init__.func_defaults)) ###assign values to the ones passed to tclean and if not defined yet in tclean... ###assign them the default value of the constructor bparm={k: inpparams[k] if k in inpparams else defparm[k] for k in defparm.keys()} ###default mosweight=True is tripping other gridders as they are not ###expecting it to be true if(bparm['mosweight']==True and bparm['gridder'].find("mosaic") == -1): bparm['mosweight']=False ## Two options have been removed from the interface. Hard-code them here. bparm['normtype'] = 'flatnoise' ## Hard-code this since the pbcor steps assume it. bparm['conjbeams']=False #paramList=ImagerParameters(**bparm) #paramList.printParameters() if len(pointingoffsetsigdev)>0 and pointingoffsetsigdev[0]!=0.0 and usepointing==True and gridder.count('awproj')>1: casalog.post("pointingoffsetsigdev will be used for pointing corrections with AWProjection", "WARN") #========================================================= ####set the children to load c++ libraries and applicator ### make workers ready for c++ based mpicommands cppparallel=False if mpi_available and MPIEnvironment.is_mpi_enabled: mint=MPIInterface.MPIInterface() cl=mint.getCluster() if(is_CASA6): cl._cluster.pgc("from casatools import synthesisimager", False) cl._cluster.pgc("si=synthesisimager()", False) else: cl._cluster.pgc("from casac import casac", False) cl._cluster.pgc("si=casac.synthesisimager()", False) cl._cluster.pgc("si.initmpi()", False) cppparallel=True ###ignore chanchunk bparm['chanchunks']=1 retrec={} try: sdintlib = SDINT_helper() ## Init major cycle elements ### debug (remove it later) casalog.post("INT cube setup ....") t0=time.time(); imager=setup_imager(int_cube, specmode, calcres, calcpsf, bparm) ##imager.initializeImagers() ##imager.initializeNormalizers() ##imager.setWeighting() t1=time.time(); casalog.post("***Time for initializing imager (INT cube) : "+"%.2f"%(t1-t0)+" sec", "INFO3", "task_sdintimaging"); ## Init minor cycle elements if niter>0 or restoration==True: ### debug (remove it later) casalog.post("Combined image setup ....") t0=time.time(); deconvolvertool=setup_deconvolver(decname, specmode, bparm ) #imager.initializeDeconvolvers() t1=time.time(); #casalog.post("***Time for initializing deconvolver(s): "+"%.2f"%(t1-t0)+" sec", "INFO3", "task_tclean"); casalog.post("***Time for seting up deconvolver(s): "+"%.2f"%(t1-t0)+" sec", "INFO3", "task_sdintimaging"); if usedata!='int': ### debug (remove it later) casalog.post("SD cube setup ....") setup_sdimaging(template=int_cube, output=sd_cube, inparms=bparm, sdparms=sdparms ) ####now is the time to check estimated memory # need to move to somewhere below??? imager.estimatememory() ## Do sanity checks on INT and SD cubes ### Frequency range of cube, data selection range. mtmfs reffreq. ### nchan too small or too large ### sumwt : flagged channels in int cubes ### sd cube empty channels ? Weight image ? validity, inpparams = sdintlib.check_coords(intres=int_cube+'.residual', intpsf=int_cube+'.psf', intwt = int_cube+'.sumwt', sdres=sd_cube+'.residual', sdpsf=sd_cube+'.psf', sdwt = '', pars=inpparams) if validity==False: casalog.post('Exiting from the sdintimaging task due to inconsistencies found between the interferometer-only and singledish-only image and psf cubes. Please modify inputs as needed','WARN') if imager != None: imager.deleteTools() if deconvolvertool != None: deconvolvertool.deleteTools() deleteTmpFiles() return #### inpparams now has a new parameter "chanwt" with ones and zeros to indicate chans #### that have data from both INT and SD cubes (they are the 'ones'). This is to be used in #### feathering and in the cube-to-taylor sum and modify_with_pb. #### END MOVE THIS SECTION to setup_imager ....for sdint #### SDINT specific feathering.... ## Feather INT and SD residual images (feather in flat-sky. output has common PB) casalog.post("Feathering INT and SD residual images...") feather_residual(int_cube, sd_cube, joint_cube, applypb, inpparams) sdintlib.feather_int_sd(sdcube=sd_cube+'.psf', intcube=int_cube+'.psf', jointcube=joint_cube+'.psf', sdgain=sdgain, dishdia=dishdia, usedata=usedata, chanwt = inpparams['chanwt']) #print("Fitting for cube") synu.fitPsfBeam(joint_cube) ############### ##### Placeholder code for PSF renormalization if needed ##### Note : If this is enabled, we'll need to restrict the use of 'faceting' as .sumwt shape changes. #sdintlib.calc_renorm(intname=int_cube, jointname=joint_cube) #sdintlib.apply_renorm(imname=joint_cube+'.psf', sumwtname=joint_cube+'.sumwt') #sdintlib.apply_renorm(imname=joint_cube+'.residual', sumwtname=joint_cube+'.sumwt') ############### #casalog.post("feather_int_sd DONE") if specmode=='mfs': ## Calculate Spectral PSFs and Taylor Residuals casalog.post("Calculate spectral PSFs and Taylor Residuals...") sdintlib.cube_to_taylor_sum(cubename=joint_cube+'.psf', cubewt=int_cube+'.sumwt', chanwt=inpparams['chanwt'], mtname=joint_multiterm+'.psf', nterms=nterms, reffreq=inpparams['reffreq'], dopsf=True) sdintlib.cube_to_taylor_sum(cubename=joint_cube+'.residual', cubewt=int_cube+'.sumwt', chanwt=inpparams['chanwt'], mtname=joint_multiterm+'.residual', nterms=nterms, reffreq=inpparams['reffreq'], dopsf=False) #print("Fit for multiterm") synu.fitPsfBeam(joint_multiterm,nterms=nterms) if niter>0 : isit = deconvolvertool.hasConverged() deconvolvertool.updateMask() while ( not deconvolvertool.hasConverged() ): t0=time.time(); #### Print out the peak of the residual image here to check !!! # if specmode=='mfs': # print('Max of joint residual before initminorcycle' + str(imstat(joint_multiterm+'.residual.tt0',verbose=False)['max'][0])) # else: # print('Max of joint residual before initminorcycle' + str(imstat(joint_cube+'.residual',verbose=False)['max'][0])) deconvolvertool.runMinorCycle() # if specmode=='mfs': # print('Max of joint residual after minorcycle' + str(imstat(joint_multiterm+'.residual.tt0',verbose=False)['max'][0])) # else: # print('Max of joint residual after minorcycle' + str(imstat(joint_cube+'.residual',verbose=False)['max'][0])) t1=time.time(); casalog.post("***Time for minor cycle: "+"%.2f"%(t1-t0)+" sec", "INFO3", "task_sdintimaging"); ### sdint specific feathering steps HERE ## Prepare the joint model cube for INT and SD major cycles if specmode=='mfs': ## Convert Taylor model coefficients into a model cube : int_cube.model sdintlib.taylor_model_to_cube(cubename=int_cube, ## output mtname=joint_multiterm, ## input nterms=nterms, reffreq=inpparams['reffreq']) else: ## Copy the joint_model cube to the int_cube.model shutil.rmtree(int_cube+'.model',ignore_errors=True) shutil.copytree(joint_cube+'.model', int_cube+'.model') hasfile=os.path.exists(joint_cube+'.model') #casalog.post("DEBUG: has joint cube .image===",hasfile) if applypb==True: ## Take the int_cube.model to flat sky. if specmode=='cube': ## Divide the model by the frequency-dependent PB to get to flat-sky fdep_pb = True else: ## Divide the model by the common PB to get to get to flat-sky fdep_pb = False sdintlib.modify_with_pb(inpcube=int_cube+'.model', pbcube=int_cube+'.pb', cubewt=int_cube+'.sumwt', chanwt=inpparams['chanwt'], action='div', pblimit=pblimit,freqdep=fdep_pb) if usedata!="int": ## copy the int_cube.model to the sd_cube.model shutil.rmtree(sd_cube+'.model',ignore_errors=True) shutil.copytree(int_cube+'.model', sd_cube+'.model') if applypb==True: ## Multiply flat-sky model with freq-dep PB sdintlib.modify_with_pb(inpcube=int_cube+'.model', pbcube=int_cube+'.pb', cubewt=int_cube+'.sumwt', chanwt=inpparams['chanwt'], action='mult', pblimit=pblimit, freqdep=True) ## Major cycle for interferometer data t0=time.time(); # print('Max of int residual before major cycle' + str(imstat(int_cube+'.residual',verbose=False)['max'][0])) # print('Max of int model before major cycle' + str(imstat(int_cube+'.model',verbose=False)['max'][0])) if usedata != "sd": imager.runMajorCycle() # print('Max of int residual after major cycle' + str(imstat(int_cube+'.residual',verbose=False)['max'][0])) t1=time.time(); casalog.post("***Time for major cycle: "+"%.2f"%(t1-t0)+" sec", "INFO3", "task_tclean"); if usedata!="int": ## Major cycle for Single Dish data (uses the flat sky cube model in sd_cube.model ) sdintlib.calc_sd_residual(origcube=sd_cube+'.image', modelcube=sd_cube+'.model', residualcube=sd_cube+'.residual', ## output psfcube=sd_cube+'.psf') ## Feather the residuals feather_residual(int_cube, sd_cube, joint_cube, applypb, inpparams ) ############### ##### Placeholder code for PSF renormalization if needed #sdintlib.apply_renorm(imname=joint_cube+'.residual', sumwtname=joint_cube+'.sumwt') ############### if specmode=='mfs': ## Calculate Spectral Taylor Residuals sdintlib.cube_to_taylor_sum(cubename=joint_cube+'.residual', cubewt=int_cube+'.sumwt', chanwt=inpparams['chanwt'], mtname=joint_multiterm+'.residual', nterms=nterms, reffreq=inpparams['reffreq'], dopsf=False) # if specmode=='mfs': # print('Max of residual after feather step ' + str(imstat(joint_multiterm+'.residual.tt0',verbose=False)['max'][0])) # else: # print('Max of residual after feather step ' + str(imstat(joint_cube+'.residual',verbose=False)['max'][0])) deconvolvertool.updateMask() ## Get summary from iterbot if type(interactive) != bool: #retrec=imager.getSummary(); retrec=deconvolvertool.getSummary(); ## Restore images. if restoration==True: t0=time.time(); deconvolvertool.restoreImages() t1=time.time(); casalog.post("***Time for restoring images: "+"%.2f"%(t1-t0)+" sec", "INFO3", "task_tclean"); if pbcor==True: #if applypb==True: t0=time.time(); if specmode=='mfs': sdintlib.pbcor(imagename=decname+'.image.tt0' , pbimage=decname+'.pb.tt0' , cutoff=pblimit,outfile=decname+'.image.tt0.pbcor') else: sdintlib.pbcor(imagename=joint_cube+'.image' , pbimage=int_cube+'.pb' , cutoff=pblimit,outfile=joint_cube+'.image.pbcor') #imager.pbcorImages() t1=time.time(); casalog.post("***Time for pb-correcting images: "+"%.2f"%(t1-t0)+" sec", "INFO3", "task_tclean"); ##close tools # needs to deletools before concat or lock waits for ever imager.deleteTools() deconvolvertool.deleteTools() if parallel==True and not (specmode =='mfs' or specmode=='cont'): casalog.post("Running virtualconcat (type=%s) of sub-cubes" % concattype,"INFO2", "task_tclean") #imager.concatImages(type=concattype) deconvolver.concatImages(type=concattype) finally: if imager != None: imager.deleteTools() if(cppparallel): ###release workers back to python mpi control si=synthesisimager() si.releasempi() #clean up tmp files deleteTmpFiles() # Write history at the end, when hopefully all temp files are gone from disk, # so they won't be picked up. They need time to disappear on NFS or slow hw. # Copied from tclean. try: params = get_func_params(sdintimaging, locals()) write_tclean_history(imagename, 'sdintimaging', params, casalog) except Exception as exc: casalog.post("Error updating history (logtable): {} ".format(exc),'WARN') return retrec ##################################################