casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
task_partition.py
Go to the documentation of this file.
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