casa
$Rev:20696$
|
00001 import os 00002 import shutil 00003 import string 00004 import copy 00005 import math 00006 from taskinit import * 00007 from parallel.parallel_task_helper import ParallelTaskHelper 00008 import partitionhelper as ph 00009 import flaghelper as fh 00010 import simple_cluster 00011 00012 class PartitionHelper(ParallelTaskHelper): 00013 def __init__(self, args = {}): 00014 ParallelTaskHelper.__init__(self,'partition', args) 00015 self._calScanList = None 00016 self._selectionScanList = None 00017 self._msTool = None 00018 self._tbTool = None 00019 00020 def initialize(self): 00021 ''' 00022 This method will prepare the system for working, in particular: 00023 * Open the input MS as a msTool 00024 * Create the Output Directory and the Data subdirectory 00025 * Populate the global data selection filter (if necessary) 00026 ''' 00027 ParallelTaskHelper.initialize(self) 00028 00029 for (arg,value) in self._arg.items(): 00030 if value == None: 00031 self._arg[arg] = '' 00032 00033 00034 # Since we are here we know that the outputvis should not be '' 00035 if self._arg['outputvis'] == '': 00036 raise ValueError, "An output vis was required." 00037 if os.path.exists(self._arg['outputvis']): 00038 raise ValueError, \ 00039 "Vis directory for output (%s) already exists" %\ 00040 self._arg['outputvis'] 00041 00042 # Find the absolute path to the outputvis 00043 self._arg['outputvis'] = os.path.abspath(self._arg['outputvis']) 00044 outputPath, self.outputBase = os.path.split(self._arg['outputvis']) 00045 try: 00046 self.outputBase = self.outputBase[:self.outputBase.rindex('.')] 00047 except ValueError: 00048 # outputBase must not have a trailing . 00049 pass 00050 00051 self.dataDir = outputPath + '/' + self.outputBase+'.data' 00052 if self._arg['createmms']: 00053 if os.path.exists(self.dataDir): 00054 shutil.rmtree(self.dataDir) 00055 00056 os.mkdir(self.dataDir) 00057 00058 ## handle the POINTING and SYSCAL tables ## 00059 self.ptab = self._arg['vis']+'/POINTING' 00060 self.stab = self._arg['vis']+'/SYSCAL' 00061 00062 mytb = tbtool() 00063 00064 # test their properties 00065 self.pointingisempty = True 00066 self.makepointinglinks = False 00067 self.pwriteaccess = True 00068 00069 mytb.open(self.ptab) 00070 self.pointingisempty = (mytb.nrows()==0) 00071 mytb.close() 00072 self.makepointinglinks = not self.pointingisempty 00073 self.pwriteaccess = True 00074 00075 self.syscalisempty = True 00076 self.makesyscallinks = False 00077 self.swriteaccess = True 00078 if(os.path.exists(self.stab)): # syscal is optional 00079 mytb.open(self.stab) 00080 self.syscalisempty = (mytb.nrows()==0) 00081 mytb.close() 00082 self.makesyscallinks = not self.syscalisempty 00083 00084 if not self.pointingisempty: 00085 if os.access(os.path.dirname(self.ptab), os.W_OK) \ 00086 and not os.path.islink(self.ptab): 00087 # move to datadir 00088 os.system('mv '+self.ptab+' '+self.dataDir) 00089 # create empty copy in original place so partition does not need to deal with it 00090 mytb.open(self.dataDir+'/POINTING') 00091 tmpp = mytb.copy(newtablename=self.ptab, norows=True) 00092 tmpp.close() 00093 mytb.close() 00094 else: 00095 self.pwriteaccess = False 00096 00097 00098 if not self.syscalisempty: 00099 if os.access(os.path.dirname(self.stab), os.W_OK) \ 00100 and not os.path.islink(self.stab): 00101 # move to datadir 00102 os.system('mv '+self.stab+' '+self.dataDir) 00103 # create empty copy in original place so partition does not need to deal with it 00104 mytb.open(self.dataDir+'/SYSCAL') 00105 tmpp = mytb.copy(newtablename=self.stab, norows=True) 00106 tmpp.close() 00107 mytb.close() 00108 else: 00109 self.swriteaccess = False 00110 00111 00112 def generateJobs(self): 00113 ''' 00114 This method overrides the method in the TaskHelper baseclass 00115 ''' 00116 if self._arg['calmsselection'] in ['auto','manual']: 00117 casalog.post("Analyzing MS for Calibration MS Creation") 00118 self._createCalMSCommand() 00119 00120 if self._arg['outputvis'] != '': 00121 casalog.post("Analyzing MS for partitioning") 00122 self._createPrimarySplitCommand() 00123 00124 return True 00125 00126 def _createCalMSCommand(self): 00127 ''' 00128 Create a command which will generate a MS with only those subMSs 00129 in the selected calibration 00130 ''' 00131 self._selectMS(True) 00132 self._calScanList = self._getScanList() 00133 00134 00135 # Now create the command dict. for this 00136 calCmd = copy.copy(self._arg) 00137 calCmd['createmms'] = False 00138 calCmd['calmsselection'] = 'none' 00139 calCmd['scan'] = ParallelTaskHelper.listToCasaString(self._calScanList) 00140 if self._arg['createmms']: 00141 calCmd['outputvis'] = self.dataDir + '/%s.cal.ms' % self.outputBase 00142 else: 00143 calCmd['outputvis'] = self._arg['calmsname'] 00144 self._executionList.append( 00145 simple_cluster.JobData(self._taskName, calCmd)) 00146 00147 def _createPrimarySplitCommand(self): 00148 if self._arg['createmms']: 00149 if self._arg['separationaxis'].lower() == 'scan': 00150 self._createScanSeparationCommands() 00151 elif self._arg['separationaxis'].lower() == 'spw': 00152 self._createSPWSeparationCommands() 00153 elif self._arg['separationaxis'].lower() == 'both': 00154 self._createDefaultSeparationCommands() 00155 else: 00156 # Single mms case 00157 singleCmd = copy.copy(self._arg) 00158 singleCmd['calmsselection'] = 'none' 00159 if scanList is not None: 00160 singleCmd['scan'] = ParallelTaskHelper.\ 00161 listToCasaString(scanList) 00162 self._executionList.append( 00163 simple_cluster.JobData(self._taskName, singleCmd)) 00164 00165 def _createScanSeparationCommands(self): 00166 scanList = self._selectionScanList 00167 if scanList is None: 00168 self._selectMS() 00169 scanList = self._getScanList() 00170 00171 # Make sure we have enough scans to create the needed number of 00172 # subMSs. If not change the total expected. 00173 numSubMS = self._arg['numsubms'] 00174 numSubMS = min(len(scanList),numSubMS) 00175 00176 partitionedScans = self.__partition(scanList, numSubMS) 00177 for output in xrange(numSubMS): 00178 mmsCmd = copy.copy(self._arg) 00179 mmsCmd['createmms'] = False 00180 mmsCmd['calmsselection'] = 'none' 00181 mmsCmd['scan']= ParallelTaskHelper.\ 00182 listToCasaString(partitionedScans[output]) 00183 mmsCmd['outputvis'] = self.dataDir+'/%s.%04d.ms' \ 00184 % (self.outputBase, output) 00185 self._executionList.append( 00186 simple_cluster.JobData(self._taskName, mmsCmd)) 00187 00188 def _createSPWSeparationCommands(self): 00189 # This method is to generate a list of commands to partition 00190 # the data based on SPW. 00191 self._selectMS() 00192 spwList = self._getSPWList() 00193 numSubMS = self._arg['numsubms'] 00194 numSubMS = min(len(spwList),numSubMS) 00195 00196 partitionedSPWs = self.__partition(spwList,numSubMS) 00197 for output in xrange(numSubMS): 00198 mmsCmd = copy.copy(self._arg) 00199 mmsCmd['createmms'] = False 00200 mmsCmd['calmsselection'] = 'none' 00201 if self._selectionScanList is not None: 00202 mmsCmd['scan'] = ParallelTaskHelper.\ 00203 listToCasaString(self._selectionScanList) 00204 mmsCmd['spw'] = ParallelTaskHelper.\ 00205 listToCasaString(partitionedSPWs[output]) 00206 mmsCmd['outputvis'] = self.dataDir+'/%s.%04d.ms' \ 00207 % (self.outputBase, output) 00208 self._executionList.append( 00209 simple_cluster.JobData(self._taskName, mmsCmd)) 00210 00211 def _createDefaultSeparationCommands(self): 00212 # This method is similar to the SPW Separation mode above, except 00213 # that if there are not enough SPW to satisfy the numSubMS it uses 00214 # 00215 self._selectMS() 00216 00217 # Get the list of spectral windows 00218 spwList = self._getSPWList() 00219 00220 # Check if we can just divide on SPW or if we need to do SPW and 00221 # scan 00222 numSubMS = self._arg['numsubms'] 00223 numSpwPartitions = min(len(spwList),numSubMS) 00224 numScanPartitions = int(math.ceil(numSubMS/float(numSpwPartitions))) 00225 00226 if numScanPartitions > 1: 00227 # Check that the scanlist is not null 00228 scanList = self._selectionScanList 00229 if scanList is None: 00230 scanList = self._getScanList() 00231 00232 # Check that the number of scans is enough for the partitions 00233 if len(scanList) < numScanPartitions: 00234 numScanPartitions = len(scanList) 00235 else: 00236 scanList = None 00237 00238 partitionedSpws = self.__partition(spwList,numSpwPartitions) 00239 partitionedScans = self.__partition(scanList,numScanPartitions) 00240 00241 for output in xrange(numSpwPartitions*numScanPartitions): 00242 mmsCmd = copy.copy(self._arg) 00243 mmsCmd['createmms'] = False 00244 mmsCmd['calmsselection'] = 'none' 00245 00246 00247 mmsCmd['scan'] = ParallelTaskHelper.listToCasaString \ 00248 (partitionedScans[output%numScanPartitions]) 00249 mmsCmd['spw'] = ParallelTaskHelper.listToCasaString\ 00250 (partitionedSpws[output/numScanPartitions]) 00251 mmsCmd['outputvis'] = self.dataDir+'/%s.%04d.ms' \ 00252 % (self.outputBase, output) 00253 self._executionList.append( 00254 simple_cluster.JobData(self._taskName, mmsCmd)) 00255 00256 def _selectMS(self, doCalibrationSelection = False): 00257 ''' 00258 This method will open the MS and ensure whatever selection critera 00259 have been requested are honored. 00260 00261 If doCalibrationSelection is true then the MS is selected to the 00262 calibration criteria. If scanList is not None then it used as the 00263 scan selectior criteria. 00264 ''' 00265 print "Start of Select MS" 00266 if self._msTool is None: 00267 # Open up the msTool 00268 self._msTool = mstool() 00269 self._msTool.open(self._arg['vis']) 00270 else: 00271 self._msTool.reset() 00272 print "MS Tool Initialized" 00273 00274 print "Getting Selection Filter" 00275 selectionFilter = self._getSelectionFilter() 00276 print "Selection Filter Complete" 00277 00278 if not doCalibrationSelection and self._calScanList is not None: 00279 print "Augmenting Cal Selection" 00280 # We need to augment the selection to remove cal scans 00281 if self._selectionScanList is None: 00282 # Generate the selection scan list if needed 00283 if selectionFilter is not None: 00284 self._msTool.msselect(selectionFilter) 00285 print "Getting Scan List" 00286 self._selectionScanList = self._getScanList() 00287 print "Scan List Complete" 00288 00289 for scan in self._calScanList: 00290 self._selectionScanList.remove(scan) 00291 00292 # Augment the selection 00293 if selectionFilter is None: 00294 selectionFilter = {} 00295 selectionFilter['scan'] = ParallelTaskHelper.listToCasaString\ 00296 (self._selectionScanList) 00297 00298 print "Doing Primary Selection" 00299 if selectionFilter is not None: 00300 print selectionFilter 00301 self._msTool.msselect(selectionFilter) 00302 print "Primary Selection Complete" 00303 00304 if doCalibrationSelection: 00305 print "Doing Calibration Selection" 00306 calFilter = self._getCalibrationFilter() 00307 self._msTool.msselect(calFilter) 00308 print "Calibration Selection Complete" 00309 00310 00311 def _getSPWList(self): 00312 ''' 00313 This method returns the spectral window list from the current 00314 ms. Be careful about having selection already done when you call this. 00315 ''' 00316 if self._msTool is None: 00317 self._selectMS() 00318 00319 # Now get the list of SPWs in the selected ms 00320 ddInfo = self._msTool.getspectralwindowinfo() 00321 spwList = [info['SpectralWindowId'] for info in ddInfo.values()] 00322 00323 # Return a unique sorted list: 00324 return list(set(spwList)) 00325 00326 def _getScanList(self): 00327 ''' 00328 This method returns the scan list from the current ms. Be careful 00329 about having selection already done when you call this. 00330 ''' 00331 if self._msTool is None: 00332 self._selectMS() 00333 00334 scanSummary = self._msTool.getscansummary() 00335 scanList = [int(scan) for scan in scanSummary] 00336 00337 if len(scanList) == 0: 00338 raise ValueError, "No Scans present in the created MS." 00339 00340 return scanList 00341 00342 00343 def postExecution(self): 00344 ''' 00345 This overrides the post execution portion of the task helper 00346 in this case we probably need to generate the output reference 00347 ms. 00348 ''' 00349 00350 if self._arg['createmms']: 00351 casalog.post("Finalizing MMS structure") 00352 00353 # restore POINTING and SYSCAL 00354 if self.pwriteaccess and not self.pointingisempty: 00355 print "restoring POINTING" 00356 os.system('rm -rf '+self.ptab) # remove empty copy 00357 os.system('mv '+self.dataDir+'/POINTING '+self.ptab) 00358 if self.swriteaccess and not self.syscalisempty: 00359 print "restoring SYSCAL" 00360 os.system('rm -rf '+self.stab) # remove empty copy 00361 os.system('mv '+self.dataDir+'/SYSCAL '+self.stab) 00362 00363 # jagonzal (CAS-4287): Add a cluster-less mode to by-pass parallel processing for MMSs as requested 00364 if (ParallelTaskHelper.getBypassParallelProcessing()==1): 00365 outputList = self._sequential_return_list 00366 self._sequential_return_list = {} 00367 else: 00368 outputList = self._jobQueue.getOutputJobs() 00369 # We created a data directory and many SubMSs, 00370 # now build the reference MS 00371 if self._arg['calmsselection'] in ['auto','manual']: 00372 # A Cal MS was created in the data directory, see if it was 00373 # successful, if so build a multi-MS 00374 if os.path.exists(self._arg['calmsname']): 00375 raise ValueError, "Output MS already exists" 00376 self._msTool.createmultims(self._arg['calmsname'], 00377 [self.dataDir +'/%s.cal.ms'%self.outputBase]) 00378 00379 subMSList = [] 00380 if (ParallelTaskHelper.getBypassParallelProcessing()==1): 00381 for subMS in outputList: 00382 subMSList.append(subMS) 00383 else: 00384 for job in outputList: 00385 if job.status == 'done': 00386 subMSList.append(job.getCommandArguments()['outputvis']) 00387 subMSList.sort() 00388 00389 if len(subMSList) == 0: 00390 casalog.post("Error: no subMSs were created.", 'WARN') 00391 return False 00392 00393 mastersubms = subMSList[0] 00394 00395 subtabs_to_omit = [] 00396 00397 # deal with POINTING table 00398 if not self.pointingisempty: 00399 shutil.rmtree(mastersubms+'/POINTING', ignore_errors=True) 00400 shutil.copytree(self.ptab, mastersubms+'/POINTING') # master subms gets a full copy of the original 00401 if self.makepointinglinks: 00402 for i in xrange(1,len(subMSList)): 00403 theptab = subMSList[i]+'/POINTING' 00404 shutil.rmtree(theptab, ignore_errors=True) 00405 os.symlink('../'+os.path.basename(mastersubms)+'/POINTING', theptab) 00406 # (link in target will be created my makeMMS) 00407 subtabs_to_omit.append('POINTING') 00408 00409 # deal with SYSCAL table 00410 if not self.syscalisempty: 00411 shutil.rmtree(mastersubms+'/SYSCAL', ignore_errors=True) 00412 shutil.copytree(self.stab, mastersubms+'/SYSCAL') # master subms gets a full copy of the original 00413 if self.makesyscallinks: 00414 for i in xrange(1,len(subMSList)): 00415 thestab = subMSList[i]+'/SYSCAL' 00416 shutil.rmtree(thestab, ignore_errors=True) 00417 os.symlink('../'+os.path.basename(mastersubms)+'/SYSCAL', thestab) 00418 # (link in target will be created my makeMMS) 00419 subtabs_to_omit.append('SYSCAL') 00420 00421 ph.makeMMS(self._arg['outputvis'], subMSList, 00422 True, # copy subtables 00423 subtabs_to_omit # omitting these 00424 ) 00425 00426 thesubmscontainingdir = os.path.dirname(subMSList[0].rstrip('/')) 00427 00428 os.rmdir(thesubmscontainingdir) 00429 00430 return True 00431 00432 00433 def _getSelectionFilter(self): 00434 # This method takes the list of specified selection criteria and 00435 # puts them into a dictionary. There is a bit of name managling 00436 # necessary. 00437 # The pairs are: (msselection syntax, split task syntanc) 00438 selectionPairs = [] 00439 selectionPairs.append(('field','field')) 00440 selectionPairs.append(('spw','spw')) 00441 selectionPairs.append(('baseline','antenna')) 00442 selectionPairs.append(('time','timerange')) 00443 selectionPairs.append(('scan','scan')) 00444 selectionPairs.append(('uvdist','uvrange')) 00445 selectionPairs.append(('scanintent','scanintent')) 00446 selectionPairs.append(('observation','observation')) 00447 return self.__generateFilter(selectionPairs) 00448 00449 def _getCalibrationFilter(self): 00450 # Now get the calibrationSelectionFilter 00451 if self._arg['calmsselection'].lower() == 'auto': 00452 return {'scanintent':'CALIBRATE_*'} 00453 else: 00454 selectionPairs = [] 00455 selectionPairs.append(('field','calfield')) 00456 selectionPairs.append(('scan','calscan')) 00457 selectionPairs.append(('scanintent','calintent')) 00458 return self.__generateFilter(selectionPairs) 00459 00460 def __generateFilter(self, selectionPairs): 00461 filter = None 00462 for (selSyntax, argSyntax) in selectionPairs: 00463 if self._arg[argSyntax] != '': 00464 if filter is None: 00465 filter = {} 00466 filter[selSyntax] = self._arg[argSyntax] 00467 return filter 00468 00469 def __partition(self, lst, n): 00470 ''' 00471 This method will split the list lst into "n" almost equal parts 00472 if lst is none, then we assume an empty list 00473 ''' 00474 if lst is None: 00475 lst = [] 00476 00477 division = len(lst)/float(n) 00478 return [ lst[int(round(division * i)): 00479 int(round(division * (i+1)))] for i in xrange(int(n))] 00480 00481 00482 def partition(vis, 00483 outputvis, 00484 createmms, 00485 separationaxis, 00486 numsubms, 00487 datacolumn, 00488 calmsselection, 00489 calmsname, 00490 calfield, 00491 calscan, 00492 calintent, 00493 field, 00494 spw, 00495 antenna, 00496 timebin, 00497 combine, 00498 timerange, 00499 scan, 00500 scanintent, 00501 array, 00502 uvrange, 00503 observation 00504 ): 00505 """Create a multi visibility set from an existing visibility set: 00506 00507 Keyword arguments: 00508 vis -- Name of input visibility file (MS) 00509 default: none; example: vis='ngc5921.ms' 00510 outputvis -- Name of output visibility file (MS) 00511 default: none; example: outputvis='ngc5921_src.ms' 00512 createmms -- Boolean flag if we're creating Multi MS 00513 default: True 00514 separationaxis -- what axis do we intend to split on. 00515 default = 'scan' 00516 Options: 'scan','spw','both' 00517 numsubms -- Number of sub-MSs to create. 00518 default: 64 00519 datacolumn -- Which data column to split out 00520 default='corrected'; example: datacolumn='data' 00521 Options: 'data', 'corrected', 'model', 'all', 00522 'float_data', 'lag_data', 'float_data,data', and 00523 'lag_data,data'. 00524 note: 'all' = whichever of the above that are present. 00525 calmsselection -- Method by which to create a separate Calibration ms 00526 default = 'none' 00527 options: 'none','auto','manual' 00528 calmsname -- Name of output calibration visibility file (MS) 00529 default: none; example: outputvis='ngc5921_CAL.ms' 00530 calfield -- Field selection for calibration MS. 00531 default: '' 00532 calscans -- Scan selection for calibration MS. 00533 default: '' 00534 calintent -- Scan intent selection for calibration MS. 00535 default: '' 00536 field -- Field name 00537 default: field = '' means use all sources 00538 field = 1 # will get field_id=1 (if you give it an 00539 integer, it will retrieve the source with that index) 00540 field = '1328+307' specifies source '1328+307'. 00541 Minimum match can be used, egs field = '13*' will 00542 retrieve '1328+307' if it is unique or exists. 00543 Source names with imbedded blanks cannot be included. 00544 spw -- Spectral window index identifier 00545 default=-1 (all); example: spw=1 00546 antenna -- antenna names 00547 default '' (all), 00548 antenna = '3 & 7' gives one baseline with antennaid = 3,7. 00549 timebin -- Interval width for time averaging. 00550 default: '0s' or '-1s' (no averaging) 00551 example: timebin='30s' 00552 combine -- Data descriptors that time averaging can ignore: 00553 scan, and/or state 00554 Default '' (none) 00555 timerange -- Time range 00556 default='' means all times. examples: 00557 timerange = 'YYYY/MM/DD/hh:mm:ss~YYYY/MM/DD/hh:mm:ss' 00558 timerange='< YYYY/MM/DD/HH:MM:SS.sss' 00559 timerange='> YYYY/MM/DD/HH:MM:SS.sss' 00560 timerange='< ddd/HH:MM:SS.sss' 00561 timerange='> ddd/HH:MM:SS.sss' 00562 scan -- Scan numbers to select. 00563 default '' (all). 00564 scanintent -- Select based on the scan intent. 00565 default '' (all) 00566 array -- (Sub)array IDs to select. 00567 default '' (all). 00568 uvrange -- uv distance range to select. 00569 default '' (all). 00570 observation -- observation ID(s) to select. 00571 default '' (all). 00572 """ 00573 #retval = True 00574 casalog.origin('partition') 00575 00576 # Start by going through and checking all the parameters 00577 if not isinstance(vis, str) or not os.path.exists(vis): 00578 raise ValueError, \ 00579 'Visibility data set (%s) not found - please verify the name' % \ 00580 vis 00581 00582 # SMC: The outputvis must be given 00583 # NOTE: added print statement because the exception msgs are 00584 # not being printed at this moment. 00585 if not outputvis or outputvis.isspace(): 00586 print 'Please specify outputvis' 00587 raise ValueError, 'Please specify outputvis' 00588 00589 outputvis = outputvis.rstrip('/') 00590 00591 if outputvis != '' and os.path.exists(outputvis): 00592 print 'Output MS %s already exists - will not overwrite.'%outputvis 00593 raise ValueError, "Output MS %s already exists - will not overwrite."%\ 00594 outputvis 00595 if isinstance(antenna,list): 00596 antenna = ', '.join([str(ant) for ant in antenna]) 00597 if isinstance(spw, list): 00598 spw = ','.join([str(s) for s in spw]) 00599 elif isinstance(spw,int): 00600 spw = str(spw) 00601 00602 # Accept digits without units ...assume seconds 00603 timebin = qa.convert(qa.quantity(timebin), 's')['value'] 00604 timebin = str(timebin) + 's' 00605 if timebin == '0s': 00606 timebin= '-1s' 00607 00608 if hasattr(combine, '_iter_'): 00609 combine = ', '.join(combine) 00610 00611 if calmsselection in ['auto','manual']: 00612 if os.path.exists(calmsname): 00613 raise ValueError, ("Output calibration MS %s already exists "+\ 00614 "will not overwrite." ) % calmsname 00615 00616 if createmms or not \ 00617 ((calmsselection in ['auto','manual']) ^ (outputvis != '')): 00618 00619 # This means we are creating more than a single MS do it in parallel 00620 ph = PartitionHelper(locals()) 00621 ph.go() 00622 00623 # Create a backup of the flags that are in the MMS 00624 casalog.origin('partition') 00625 casalog.post('Create a backup of the flags that are in the MMS') 00626 fh.backupFlags(aflocal=None, msfile=outputvis, prename='partition') 00627 00628 return 00629 00630 # Create the msTool 00631 try: 00632 msTool = mstool() 00633 msTool.open(vis) 00634 msTool.partition(outputms=outputvis, 00635 field=field, 00636 spw=spw, 00637 baseline=antenna, 00638 subarray=array, 00639 timebin=timebin, 00640 time=timerange, 00641 whichcol=datacolumn, 00642 scan=scan, 00643 uvrange=uvrange, 00644 combine=combine, 00645 intent=scanintent, 00646 obs=str(observation)) 00647 msTool.close() 00648 except Exception, instance: 00649 casalog.post("*** Error \'%s\' captured in partition" % (instance),'WARN') 00650 msTool.close() 00651 00652 # Write history to output MS, not the input ms. 00653 try: 00654 param_names = partition.func_code.co_varnames[:partition.func_code.co_argcount] 00655 param_vals = [eval(p) for p in param_names] 00656 write_history(msTool, outputvis, 'partition', param_names, 00657 param_vals, casalog) 00658 except Exception, instance: 00659 casalog.post("*** Error \'%s\' updating HISTORY" % (instance), 00660 'WARN') 00661 00662 return True