casa
$Rev:20696$
|
00001 ################################################ 00002 # Refactored Clean task 00003 # 00004 # v1.0: 2012.10.05, U.R.V. 00005 # 00006 ################################################ 00007 00008 from taskinit import * 00009 00010 import os 00011 import shutil 00012 import numpy 00013 from taskinit import * 00014 import copy 00015 00016 def tclean(vis='', field='', spw='', 00017 imagename='',nchan=1, 00018 startmodel='', 00019 niter=0, threshold=0.0, loopgain=0.1, maxcycleniter=-1, cyclefactor=1, minpsffraction=0.05, maxpsffraction=0.8, 00020 usescratch=True, clusterdef=''): 00021 00022 #casalog.post('This is an empty task. It is meant only to build/test/maintain the interface for the refactored imaging code. When ready, it will be offered to users for testing.','WARN') 00023 00024 # Put all parameters into dictionaries 00025 params={} 00026 params['dataselection']={'vis':vis, 'field':field, 'spw':spw, 'usescratch':usescratch} 00027 params['imagedefinition']={'imagename':imagename, 'nchan':nchan} 00028 params['imaging']={'startmodel':startmodel} 00029 params['deconvolution']={} 00030 params['iteration']={'niter':niter, 'threshold':threshold, 'loopgain':loopgain, 'maxcycleniter':maxcycleniter, 'cyclefactor':cyclefactor , 'minpsffraction':minpsffraction, 'maxpsffraction':maxpsffraction} 00031 params['other']={'clusterdef':clusterdef} 00032 00033 # Instantiate the Imager class 00034 if len(clusterdef)==0: 00035 imager = PySynthesisImager(casalog,params) 00036 else: 00037 imager = ParallelPySynthesisImager(casalog,params) 00038 00039 # Check input parameters (types, etc..) 00040 if not imager.checkParameters(): 00041 return False 00042 00043 # All setup steps 00044 imager.initialize() 00045 00046 # Run major/minor cycle loops 00047 imager.runLoops() 00048 00049 # Restore and Clean up. 00050 imager.finalize() 00051 00052 # Save history - Params, Flux Cleaned, Peak Residual, Niter, TimeTaken, Image Names? 00053 return imager.returninfo() 00054 00055 00056 ################################################### 00057 ## Single-node imaging. 00058 ################################################### 00059 00060 class PySynthesisImager: 00061 """ Class to do imaging and deconvolution """ 00062 00063 def __init__(self,casalog,params): 00064 self.toolsi=None #gentools(['si'])[0] 00065 self.casalog = casalog 00066 self.params = params 00067 self.loopcontrols = {} 00068 self.listofimagedefinitions = [] 00069 self.casalog.origin('tclean') 00070 00071 00072 def checkParameters(self): 00073 self.casalog.origin('tclean.checkParameters') 00074 self.casalog.post('Verifying Input Parameters') 00075 # Init the error-string 00076 errs = "" 00077 00078 errs = errs + self.checkAndFixSelectionPars( self.params['dataselection'] ) 00079 00080 errs = errs + self.checkAndFixImageCoordPars( self.params['imagedefinition'] ) 00081 00082 ## If there are errors, print a message and exit. 00083 if len(errs) > 0: 00084 casalog.post('Parameter Errors : \n' + errs) 00085 return False 00086 return True 00087 00088 def initialize(self, toolsi=None): 00089 self.casalog.origin('tclean.initialize') 00090 if toolsi==None: 00091 #self.toolsi = gentools(['si'])[0] 00092 self.toolsi = casac.synthesisimager() ##gentools(['si'])[0] 00093 toolsi = self.toolsi 00094 toolsi.selectdata(selpars=self.params['dataselection']) 00095 00096 impars = copy.deepcopy( self.params['imagedefinition'] ) 00097 00098 ## Start a loop on 'multi-fields' here.... 00099 for eachimdef in self.listofimagedefinitions: 00100 # Fill in the individual parameters 00101 impars['imagename'] = eachimdef[ 'imagename' ] 00102 # Init a mapper for each individual field 00103 toolsi.defineimage(impars=impars) 00104 toolsi.setupimaging(gridpars=self.params['imaging']) 00105 toolsi.setupdeconvolution(decpars=self.params['deconvolution']) 00106 toolsi.initmapper() 00107 ## End loop on 'multi-fields' here.... 00108 00109 self.loopcontrols = toolsi.setupiteration(iterpars=self.params['iteration'] ) # From ParClean loopcontrols gets overwritten, but it is always with the same thing. Try to clean this up. 00110 00111 ##toolsi.initcycles() 00112 00113 00114 def runMajorCycle(self,toolsi=None): 00115 self.casalog.origin('tclean.runMajorCycle') 00116 if toolsi==None: 00117 toolsi = self.toolsi 00118 self.loopcontrols.update( toolsi.runmajorcycle( self.loopcontrols ) ) 00119 # In this prev statement, send in updated model to override default. 00120 00121 00122 def runMinorCycle(self, toolsi=None): 00123 self.casalog.origin('tclean.runMinorCycle') 00124 if toolsi==None: 00125 toolsi = self.toolsi 00126 self.loopcontrols.update( toolsi.runminorcycle( self.loopcontrols ) ) 00127 00128 def runLoops(self): 00129 self.casalog.origin('tclean.runLoops') 00130 self.runMajorCycle() 00131 while not self.loopcontrols['stop']: # Make the tool take loopcontrols as in/out ( not const ! ) 00132 self.runMinorCycle() 00133 self.runMajorCycle() 00134 00135 def finalize(self, toolsi=None): 00136 if toolsi==None: 00137 toolsi = self.toolsi 00138 toolsi.endloops( self.loopcontrols ) 00139 #toolsi.done() 00140 00141 def returninfo(self): 00142 return self.loopcontrols 00143 00144 00145 ###### Start : Parameter-checking functions ################## 00146 def checkAndFixSelectionPars(self, selpars={} ): 00147 errs="" 00148 # vis, field, spw, etc must all be equal-length lists of strings. 00149 if not selpars.has_key('vis'): 00150 errs = errs + 'MS name(s) not specified' 00151 else: 00152 if type(selpars['vis'])==str: 00153 selpars['vis']=[selpars['vis']] 00154 nvis = len(selpars['vis']) 00155 selkeys = ['field','spw'] 00156 for par in selkeys: 00157 if selpars.has_key(par): 00158 if selpars[par]=='': 00159 selpars[par] = [] 00160 for it in range(0,nvis): 00161 selpars[par].append('') 00162 if type(selpars[par])==str: 00163 selpars[par]=[selpars[par]] 00164 if len(selpars[par]) != nvis: 00165 errs = errs + "Selection for " + par + " must be a list of " + str(nvis) + " selection strings\n" 00166 else: 00167 errs = errs + "Selection for " + par + " is unspecified\n" 00168 00169 return errs 00170 00171 def checkAndFixImageCoordPars(self, impars={} ): 00172 errs="" 00173 00174 ### Get a list of image-coord pars from the multifield outlier file + main field... 00175 ### Go through this list, and do setup. : Fill in self.listofimagedefinitions with dicts of params 00176 00177 ## FOR NOW... this list is just a list of image names.... 00178 00179 ## One image only 00180 if type( impars['imagename'] ) == str: 00181 self.listofimagedefinitions.append( {'imagename':impars['imagename']} ) 00182 00183 ## If multiple images are specified....... 00184 if type( impars['imagename'] ) == list: 00185 for imname in impars['imagename']: 00186 self.listofimagedefinitions.append( {'imagename':imname} ) 00187 00188 return errs 00189 00190 ###### End : Parameter-checking functions ################## 00191 00192 00193 00194 ################################################### 00195 ## Parallel imaging. 00196 ################################################### 00197 00198 class ParallelPySynthesisImager(PySynthesisImager): 00199 """ Class to do imaging and deconvolution, with major cycles distributed across cluster nodes """ 00200 00201 def __init__(self,casalog,params): 00202 PySynthesisImager.__init__(self,casalog,params) 00203 # Read params['other']['clusterdef'] to decide chunking. 00204 self.nchunks = len(params['other']['clusterdef']) 00205 # Initialize a list of synthesisimager tools 00206 self.toollist = [] 00207 for ch in range(0,self.nchunks): 00208 #self.toollist.append( gentools(['si'])[0] ) 00209 self.toollist.append( casac.synthesisimager() ) ## gentools(['si'])[0] ) 00210 00211 00212 def initialize(self): 00213 selpars = copy.deepcopy( self.params['dataselection'] ) 00214 for ch in range(0,self.nchunks): 00215 casalog.origin('parallel.tclean.runMinorCycle') 00216 casalog.post('Initialize for chunk '+str(ch)) 00217 00218 for dat in range(0,len( selpars['spw'] )): 00219 self.params['dataselection']['spw'][dat] = selpars['spw'][dat] + ':'+str(ch) 00220 00221 PySynthesisImager.initialize(self, self.toollist[ch] ) 00222 self.params['dataselection'] = copy.deepcopy(selpars) 00223 00224 def runMajorCycle(self): 00225 lcontrols = copy.deepcopy( self.loopcontrols ) 00226 for ch in range(0,self.nchunks): 00227 self.loopcontrols = copy.deepcopy( lcontrols ) 00228 PySynthesisImager.runMajorCycle(self, self.toollist[ch] ) # Send in updated model as startmodel.. 00229 self.gatherImages() 00230 00231 def runMinorCycle(self): 00232 casalog.origin('parallel.tclean.runMinorCycle') 00233 casalog.post('Set combined images for the minor cycle') 00234 PySynthesisImager.runMinorCycle(self, self.toollist[0] ) # Use the full list for spectral-cube deconv. 00235 casalog.origin('parallel.tclean.runMinorCycle') 00236 casalog.post('Mark updated model as input to all major cycles') 00237 00238 def finalize(self): 00239 self.toollist[0].endloops( self.loopcontrols ) 00240 #for ch in range(0,self.nchunks): 00241 # self.toollist[ch].done() 00242 00243 def gatherImages(self): 00244 casalog.origin('parallel.tclean.gatherimages') 00245 casalog.post('Gather images from all chunks') 00246