from __future__ import absolute_import import os from casatasks.private.casa_transition import is_CASA6 if is_CASA6: from casatasks import casalog from casatools import sdm, table, quanta, ms _ms = ms() _tb = table() _qa = quanta() else: from taskinit import * _ms = casac.ms() _tb = casac.table() _qa = qa # not really local, but it has no state as used here def exportasdm(vis=None, asdm=None, datacolumn=None, archiveid=None, rangeid=None, subscanduration=None, sbduration=None, apcorrected=None, verbose=None): """ Convert a CASA visibility file (MS) into an ALMA or EVLA Science Data Model. Keyword arguments: vis -- MS name, default: none asdm -- Name of output ASDM file (directory), default: none; example: asdm='ExecBlock3' datacolumn -- specifies which of the MS data columns (DATA, CORRECTED_DATA, or MODEL_DATA) should be used as the visibilities in the ASDM, default: DATA archiveid -- the X0 in uid://X0/X1/X<running> default: "S0" rangeid -- the X1 in uid://X0/X1/X<running> default: "X1" subscanduration -- maximum duration of a subscan in the output ASDM default: "24h" sbduration -- maximum duration of a scheduling block in the output ASDM default: "2700s" apcorrected -- If true, the data in column datacolumn should be regarded as having atmospheric phase correction, default: False verbose -- produce log output, default: True """ #Python script casalog.origin('exportasdm') parsummary = 'vis=\"'+str(vis)+'\", asdm=\"'+str(asdm)+'\", datacolumn=\"'+str(datacolumn)+'\",' casalog.post(parsummary) parsummary = 'archiveid=\"'+str(archiveid)+'\", rangeid=\"'+str(rangeid)+'\", subscanduration=\"'+str(subscanduration)+'\",' casalog.post(parsummary) parsummary = 'sbduration=\"'+str(sbduration)+'\", apcorrected='+str(apcorrected)+', verbose='+str(verbose)+',' casalog.post(parsummary) if not (type(vis)==str) or not (os.path.exists(vis)): raise ValueError('Visibility data set not found - please verify the name') if (asdm == ""): raise ValueError("Must provide output data set name in parameter asdm.") if os.path.exists(asdm): raise ValueError("Output ASDM %s already exists - will not overwrite." % asdm) # determine sb and subscan duration ssdur_secs = 24.*3600 # default is one day, i.e. there will be only one subscan per scan if not(subscanduration==""): if (_qa.canonical(subscanduration)['unit'].find('s') < 0): raise TypeError("subscanduration is not a valid time quantity: %s" % subscanduration) else: ssdur_secs = _qa.canonical(subscanduration)['value'] sbdur_secs = 2700. # default is 45 minutes if not(sbduration==""): if (_qa.canonical(sbduration)['unit'].find('s') < 0): raise TypeError("sbduration is not a valid time quantity: %s" % sbduration) else: sbdur_secs = _qa.canonical(sbduration)['value'] # create timesorted copy of the input ms tsortvis = vis+'-tsorted' os.system('rm -rf '+tsortvis) _ms.open(vis) _ms.timesort(tsortvis) _ms.close() # Prepare for actual exportasdm casalog.post("Checking timesorted MS for potential problems ... ") _tb.open(tsortvis) a = _tb.getcol('PROCESSOR_ID') a0 = a[0] candoit = True for i in range(0,len(a)-1): if(a[i]!=a[i+1]): candoit = False break _tb.close() if candoit: casalog.post(" Checking if PROCESSOR and MAIN need modifications ...") _tb.open(tsortvis+'/PROCESSOR') nprocrows = _tb.nrows() _tb.close() if ((nprocrows>0) and (a0>-1)): _tb.open(tsortvis+'/PROCESSOR') therow = _tb.nrows()-1 mode0 = _tb.getcell('MODE_ID',a0) _tb.close() offset = 1 if nprocrows>1: casalog.post(" Modifying PROCESSOR subtable ...") while (nprocrows>1 and therow>0): _tb.open(tsortvis+'/PROCESSOR', nomodify=False) therow = _tb.nrows()-offset if(_tb.getcell('MODE_ID',therow)!=mode0): _tb.removerows([therow]) else: offset += 1 nprocrows = _tb.nrows() casalog.post("... done.") casalog.post(" Modifying processor ids in main table ...") a = a - a # set all precessor ids to zero _tb.open(tsortvis, nomodify=False) _tb.putcol('PROCESSOR_ID', a) _tb.close() casalog.post(" ... done.") else: casalog.post(" No modifications to proc id in PROCESSOR and MAIN necessary.") casalog.post(" Checking if SYSCAL needs modifications ...") if(os.path.exists(tsortvis+'/SYSCAL')): for cname in ['TANT_SPECTRUM', 'TSYS_SPECTRUM', 'TANT_TSYS_SPECTRUM', 'TCAL_SPECTRUM', 'TRX_SPECTRUM', 'TSKY_SPECTRUM', 'PHASE_DIFF_SPECTRUM']: _tb.open(tsortvis+'/SYSCAL', nomodify=False) if(cname in _tb.colnames()): cdesc = _tb.getcoldesc(cname) if 'ndim' in cdesc and (cdesc['ndim']==-1): _tb.removecols([cname]) casalog.post(' Removed empty array column '+cname+' from table SYSCAL.') _tb.close() casalog.post(" Checking if OBSERVATION needs modifications ...") _tb.open(tsortvis+'/OBSERVATION') nobsrows = _tb.nrows() _tb.close() if(nobsrows>0): _tb.open(tsortvis+'/OBSERVATION', nomodify=False) cdesc = _tb.getcoldesc('LOG') if 'ndim' in cdesc and (cdesc['ndim']>0): b = _tb.getvarcol('LOG') if not (type(b['r1'])==bool): kys = b.keys() modified = False b2 = [] for i in range(0,len(kys)): k = 'r'+str(i+1) if (b[k][0] == [''])[0]: b[k][0] = ["-"] modified = True b2.append([b[k][0][0]]) if modified: _tb.putcol('LOG',b2) casalog.post(" Modified log column in OBSERVATION table.") _tb.close() casalog.post("Done.") else: raise RuntimeError("More than one processor id in use in the main table. Cannot proceed.") if is_CASA6: # sdm tool _sdm = sdm(asdm) rval = _sdm.fromms(tsortvis, datacolumn, archiveid, rangeid, ssdur_secs, sbdur_secs, apcorrected, verbose) # this line is independent of CASA version, but is here so that the CASA5 version can do additional error reporting after cleaning up this temporary MS os.system('rm -rf '+tsortvis) if not rval: raise RuntimeError('The sdm tool method fromms failed') else: # use MS2asdm executable execute_string= '--datacolumn \"' + datacolumn execute_string+= '\" --archiveid \"' + archiveid + '\" --rangeid \"' + rangeid execute_string+= '\" --subscanduration \"' + str(ssdur_secs) execute_string+= '\" --schedblockduration \"' + str(sbdur_secs) execute_string+= '\" --logfile \"' + casalog.logfile() +'\"' if(not apcorrected): execute_string+= ' --apuncorrected' if(verbose): execute_string+= ' --verbose' theexecutable = 'MS2asdm' execute_string += ' ' + tsortvis + ' ' + asdm execute_string = theexecutable+' '+execute_string if(verbose): casalog.post('Running '+theexecutable+' standalone invoked as:') casalog.post(execute_string) rval = os.system(execute_string) os.system('rm -rf '+tsortvis) if(rval != 0): raise RuntimeError(theexecutable + ' terminated with exit ' 'code ' + str(rval),'WARN')