casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
task_listsdm.py
Go to the documentation of this file.
00001 ########################################################################
00002 # Task to retrieve observing information from SDM XML files
00003 #
00004 # v1.0: 2010.12.07, M. Krauss
00005 # v1.1: 2011.02.23, M. Krauss: added functionality for ALMA data
00006 #
00007 # Original code based on readscans.py, courtesy S. Meyers
00008 
00009 import numpy as np
00010 from taskinit import *
00011 try:
00012     from xml.dom import minidom
00013 except ImportError, e:
00014     print "failed to load xml.dom.minidom:\n", e
00015     exit(1)
00016 
00017 def listsdm(sdm=None):
00018 
00019     # read Scan.xml
00020     xmlscans = minidom.parse(sdm+'/Scan.xml')
00021     scandict = {}
00022     startTimeShort = []
00023     endTimeShort = []
00024     rowlist = xmlscans.getElementsByTagName("row")
00025     for rownode in rowlist:
00026         rowfid = rownode.getElementsByTagName("scanNumber")
00027         fid = int(rowfid[0].childNodes[0].nodeValue)
00028         scandict[fid] = {}
00029         
00030         # number of subscans
00031         rowsubs = rownode.getElementsByTagName("numSubscan")
00032         if len(rowsubs) == 0:
00033             # EVLA and old ALMA data
00034             rowsubs = rownode.getElementsByTagName("numSubScan")
00035         nsubs = int(rowsubs[0].childNodes[0].nodeValue)
00036         
00037         # intents
00038         rownint = rownode.getElementsByTagName("numIntent")
00039         nint = int(rownint[0].childNodes[0].nodeValue)
00040         
00041         rowintents = rownode.getElementsByTagName("scanIntent")
00042         sint = str(rowintents[0].childNodes[0].nodeValue)
00043         sints = sint.split()
00044         rint = ''
00045         for r in range(nint):
00046             intent = sints[2+r]
00047             if rint=='':
00048                 rint = intent
00049             else:
00050                 rint += ' '+intent
00051         
00052         # start and end times in mjd ns
00053         rowstart = rownode.getElementsByTagName("startTime")
00054         start = int(rowstart[0].childNodes[0].nodeValue)
00055         startmjd = float(start)*1.0E-9/86400.0
00056         t = qa.quantity(startmjd,'d')
00057         starttime = qa.time(t,form="ymd",prec=8)[0]
00058         startTimeShort.append(qa.time(t,prec=8)[0])
00059         rowend = rownode.getElementsByTagName("endTime")
00060         end = int(rowend[0].childNodes[0].nodeValue)
00061         endmjd = float(end)*1.0E-9/86400.0
00062         t = qa.quantity(endmjd,'d')
00063         endtime = qa.time(t,form="ymd",prec=8)[0]
00064         endTimeShort.append(qa.time(t,prec=8)[0])
00065         
00066         # source name
00067         rowsrc = rownode.getElementsByTagName("sourceName")
00068         src = str(rowsrc[0].childNodes[0].nodeValue)
00069         
00070         scandict[fid]['start'] = starttime
00071         scandict[fid]['end'] = endtime
00072         timestr = starttime+'~'+endtime
00073         scandict[fid]['timerange'] = timestr
00074         scandict[fid]['source'] = src
00075         scandict[fid]['intent'] = rint
00076         scandict[fid]['nsubs'] = nsubs
00077 
00078     # read Main.xml
00079     xmlmain = minidom.parse(sdm+'/Main.xml')
00080     rowlist = xmlmain.getElementsByTagName("row")
00081     mainScanList = []
00082     mainConfigList = []
00083     fieldIdList = []
00084     for rownode in rowlist:
00085         
00086         # get the scan numbers
00087         rowfid = rownode.getElementsByTagName("scanNumber")
00088         fid = int(rowfid[0].childNodes[0].nodeValue)
00089         mainScanList.append(fid)
00090         
00091         # get the configuration description
00092         rowconfig = rownode.getElementsByTagName("configDescriptionId")
00093         config = str(rowconfig[0].childNodes[0].nodeValue)
00094         mainConfigList.append(config)
00095         
00096         # get the field ID
00097         rowfieldid = rownode.getElementsByTagName("fieldId")
00098         fieldid = string.split(str(rowfieldid[0].childNodes[0].nodeValue), '_')[1]
00099         fieldIdList.append(fieldid)
00100 
00101     # read ConfigDescription.xml to relate the configuration
00102     # description to a (set) of data description IDs
00103     xmlconfig = minidom.parse(sdm+'/ConfigDescription.xml')
00104     rowlist = xmlconfig.getElementsByTagName("row")
00105     configDescList = []
00106     dataDescList = []
00107     for rownode in rowlist:
00108         
00109         # get the configuration description
00110         rowConfigDesc = rownode.getElementsByTagName("configDescriptionId")
00111         configDesc = str(rowConfigDesc[0].childNodes[0].nodeValue)
00112         configDescList.append(configDesc)
00113         
00114         # make a list of the data description IDs:
00115         rowNumDataDesc = rownode.getElementsByTagName("numDataDescription")
00116         numDataDesc = int(rowNumDataDesc[0].childNodes[0].nodeValue)
00117         
00118         rowDataDesc = rownode.getElementsByTagName("dataDescriptionId")
00119         dataDescStr = str(rowDataDesc[0].childNodes[0].nodeValue)
00120         dataDescSplit = dataDescStr.split()
00121         dataDesc = []
00122         for i in range(numDataDesc):
00123             dataDesc.append(dataDescSplit[i+2])
00124         dataDescList.append(dataDesc)
00125 
00126     # read DataDescription.xml to relate the data description IDs to
00127     # spectral window IDs
00128     xmlDataDesc = minidom.parse(sdm+'/DataDescription.xml')
00129     rowlist = xmlDataDesc.getElementsByTagName("row")
00130     dataDescElList = []
00131     spwIdDataDescList = []
00132     for rownode in rowlist:
00133         
00134         # get the data description ID, make another list:
00135         rowDataDescEl = rownode.getElementsByTagName("dataDescriptionId")
00136         dataDescEl = str(rowDataDescEl[0].childNodes[0].nodeValue)
00137         dataDescElList.append(dataDescEl)
00138         
00139         # get the related spectral window ID:
00140         rowSpwIdDataDesc = rownode.getElementsByTagName("spectralWindowId")
00141         spwIdDataDesc = str(rowSpwIdDataDesc[0].childNodes[0].nodeValue)
00142         spwIdDataDescList.append(spwIdDataDesc)
00143 
00144     # read SpectralWindow.xml, get information about number of
00145     # channels, reference frequency, baseband name, channel width.
00146     # Interesting that there seem to be multiple fields that give the
00147     # same information: chanFreqStart=reFreq,
00148     # chanFreqStep=chanWidth=resolution.  Why? (Note: all units are Hz)
00149     # Note: this is where the script breaks for ALMA data, since there
00150     # are different tags in SpectraWindow.xml (for varying channel widths).
00151     xmlSpecWin = minidom.parse(sdm+'/SpectralWindow.xml')
00152     rowlist = xmlSpecWin.getElementsByTagName("row")
00153     spwIdList = []
00154     nChanList = []
00155     refFreqList = []
00156     chanWidthList = []
00157     basebandList = []
00158     for rownode in rowlist:
00159         
00160         # get the various row values:
00161         rowSpwId = rownode.getElementsByTagName("spectralWindowId")
00162         rowNChan = rownode.getElementsByTagName("numChan")
00163         rowRefFreq = rownode.getElementsByTagName("refFreq")
00164         # For EVLA
00165         rowChanWidth = rownode.getElementsByTagName("chanWidth")
00166         # For ALMA
00167         rowChanWidthArr = rownode.getElementsByTagName("chanWidthArray")
00168         rowBaseband = rownode.getElementsByTagName("basebandName")
00169         
00170         # convert to values or strings and append to the relevant lists:
00171         spwId = str(rowSpwId[0].childNodes[0].nodeValue)
00172         spwIdList.append(spwId)
00173         nChan = int(rowNChan[0].childNodes[0].nodeValue)
00174         nChanList.append(nChan)
00175         refFreq = float(rowRefFreq[0].childNodes[0].nodeValue)
00176         refFreqList.append(refFreq)
00177         if rowChanWidth:
00178             chanWidth = float(rowChanWidth[0].childNodes[0].nodeValue)
00179             chanWidthList.append(chanWidth)
00180         if rowChanWidthArr:
00181             tmpArr = str(rowChanWidthArr[0].childNodes[0].nodeValue).split(' ')
00182             tmpWidth = []
00183             for cw in range(2, len(tmpArr)):
00184                 thisWidth = float(tmpArr[cw])
00185                 tmpWidth.append(thisWidth)
00186             chanWidthList.append(tmpWidth)
00187         baseband = str(rowBaseband[0].childNodes[0].nodeValue)
00188         basebandList.append(baseband)
00189 
00190     # read Field.xml
00191     xmlField = minidom.parse(sdm+'/Field.xml')
00192     rowlist = xmlField.getElementsByTagName("row")
00193     fieldList = []
00194     fieldNameList = []
00195     fieldCodeList = []
00196     fieldRAList = []
00197     fieldDecList = []
00198     fieldSrcIDList = []
00199     for rownode in rowlist:
00200         rowField = rownode.getElementsByTagName("fieldId")
00201         rowName = rownode.getElementsByTagName("fieldName")
00202         rowCode = rownode.getElementsByTagName("code")
00203         rowCoords = rownode.getElementsByTagName("referenceDir")
00204         rowSrcId = rownode.getElementsByTagName("sourceId")
00205         
00206         # convert to values or strings and append to relevent lists:
00207         fieldList.append(int(string.split(str(rowField[0].childNodes[0].nodeValue),'_')[1]))
00208         fieldNameList.append(str(rowName[0].childNodes[0].nodeValue))
00209         fieldCodeList.append(str(rowCode[0].childNodes[0].nodeValue))
00210         coordInfo = rowCoords[0].childNodes[0].nodeValue.split()
00211         RADeg = float(coordInfo[3])*(180.0/np.pi)
00212         DecDeg = float(coordInfo[4])*(180.0/np.pi)
00213         RAInp = {'unit': 'deg', 'value': RADeg}
00214         DecInp = {'unit': 'deg', 'value': DecDeg}
00215         RAHMS = qa.formxxx(RAInp, format='hms')
00216         DecDMS = qa.formxxx(DecInp, format='dms')
00217         fieldRAList.append(RAHMS)
00218         fieldDecList.append(DecDMS)
00219         fieldSrcIDList.append(int(rowSrcId[0].childNodes[0].nodeValue))    
00220 
00221     # read Antenna.xml
00222     xmlAnt = minidom.parse(sdm+'/Antenna.xml')
00223     rowlist = xmlAnt.getElementsByTagName("row")
00224     antList = []
00225     antNameList = []
00226     dishDiamList = []
00227     stationList = []
00228     for rownode in rowlist:
00229         rowAnt = rownode.getElementsByTagName("antennaId")
00230         rowAntName = rownode.getElementsByTagName("name")
00231         rowDishDiam = rownode.getElementsByTagName("dishDiameter")
00232         rowStation = rownode.getElementsByTagName("stationId")
00233         
00234         # convert and append
00235         antList.append(int(string.split(str(rowAnt[0].childNodes[0].nodeValue), '_')[1]))
00236         antNameList.append(str(rowAntName[0].childNodes[0].nodeValue))
00237         dishDiamList.append(float(rowDishDiam[0].childNodes[0].nodeValue))
00238         stationList.append(str(rowStation[0].childNodes[0].nodeValue))
00239 
00240     # read Station.xml
00241     xmlStation = minidom.parse(sdm+'/Station.xml')
00242     rowlist = xmlStation.getElementsByTagName("row")
00243     statIdList = []
00244     statNameList = []
00245     statLatList = []
00246     statLonList = []
00247     for rownode in rowlist:
00248         rowStatId = rownode.getElementsByTagName("stationId")
00249         rowStatName = rownode.getElementsByTagName("name")
00250         rowStatPos = rownode.getElementsByTagName("position")
00251         
00252         # convert and append
00253         statIdList.append(str(rowStatId[0].childNodes[0].nodeValue))
00254         statNameList.append(str(rowStatName[0].childNodes[0].nodeValue))
00255         posInfo = string.split(str(rowStatPos[0].childNodes[0].nodeValue))
00256         x = qa.quantity([float(posInfo[2])], 'm')
00257         y = qa.quantity([float(posInfo[3])], 'm')
00258         z = qa.quantity([float(posInfo[4])], 'm')
00259         pos = me.position('ITRF', x, y, z)
00260         qLon = pos['m0']
00261         qLat = pos['m1']
00262         statLatList.append(qa.formxxx(qLat, 'dms', prec=0))
00263         statLonList.append(qa.formxxx(qLon, 'dms', prec=0))
00264     
00265     # associate antennas with stations:
00266     assocStatList = []
00267     for station in stationList:
00268         i = np.where(np.array(statIdList) == station)[0]
00269         assocStatList.append(statNameList[i])
00270 
00271     # read ExecBlock.xml
00272     xmlExecBlock = minidom.parse(sdm+'/ExecBlock.xml')
00273     rowlist = xmlExecBlock.getElementsByTagName("row")
00274     sTime = float(rowlist[0].getElementsByTagName("startTime")[0].childNodes[0].nodeValue)*1.0E-9
00275     eTime = float(rowlist[0].getElementsByTagName("endTime")[0].childNodes[0].nodeValue)*1.0E-9
00276     # integration time in seconds, start and end times:
00277     intTime = eTime - sTime
00278     t = qa.quantity(sTime/86400.0, 'd')
00279     obsStart = qa.time(t, form="ymd", prec=8)[0]
00280     t = qa.quantity(eTime/86400.0, 'd')
00281     obsEnd = qa.time(t, form="ymd", prec=8)[0]
00282     # observer name and obs. info:
00283     observerName = str(rowlist[0].getElementsByTagName("observerName")[0].childNodes[0].nodeValue)
00284     configName = str(rowlist[0].getElementsByTagName("configName")[0].childNodes[0].nodeValue)
00285     telescopeName = str(rowlist[0].getElementsByTagName("telescopeName")[0].childNodes[0].nodeValue)
00286     numAntenna = int(rowlist[0].getElementsByTagName("numAntenna")[0].childNodes[0].nodeValue)
00287 
00288     # make lists like the dataDescList for spectral windows & related info:
00289     spwOrd = []
00290     nChanOrd = []
00291     rFreqOrd = []
00292     cWidthOrd = []
00293     bbandOrd = []
00294     for i in range(0, len(configDescList)):
00295         spwTempList = []
00296         nChanTempList = []
00297         rFreqTempList = []
00298         cWidthTempList = []
00299         bbandTempList = []
00300         
00301         for dDesc in dataDescList[i]:
00302             el = np.where(np.array(dataDescElList) == dDesc)[0]
00303             spwIdN = spwIdDataDescList[el]
00304             spwEl = np.where(np.array(spwIdList) == spwIdN)[0]
00305             spwTempList.append(int(string.split(spwIdList[spwEl], '_')[1]))
00306             nChanTempList.append(nChanList[spwEl])
00307             rFreqTempList.append(refFreqList[spwEl])
00308             cWidthTempList.append(chanWidthList[spwEl])
00309             bbandTempList.append(basebandList[spwEl])
00310         spwOrd.append(spwTempList)
00311         nChanOrd.append(nChanTempList)
00312         rFreqOrd.append(rFreqTempList)
00313         cWidthOrd.append(cWidthTempList)
00314         bbandOrd.append(bbandTempList)
00315     
00316     # add this info to the scan dictionary:
00317     for scanNum in scandict:
00318         spwOrdList = []
00319         nChanOrdList = []
00320         rFreqOrdList = []
00321         cWidthOrdList = []
00322         bbandOrdList = []
00323         # scanEl could have multiple elements if subscans are present,
00324         # or for ALMA data:
00325         scanEl = np.where(np.array(mainScanList) == scanNum)[0]
00326         for thisEl in scanEl:
00327             configEl = mainConfigList[thisEl]
00328             listEl = np.where(np.array(configDescList) == configEl)[0]
00329             spwOrdList.append(spwOrd[listEl])
00330             nChanOrdList.append(nChanOrd[listEl])
00331             rFreqOrdList.append(rFreqOrd[listEl])
00332             cWidthOrdList.append(cWidthOrd[listEl])
00333             bbandOrdList.append(bbandOrd[listEl])
00334         scandict[scanNum]['field'] = int(fieldIdList[scanEl[0]])
00335         scandict[scanNum]['spws'] = spwOrdList
00336         scandict[scanNum]['nchan'] = nChanOrdList
00337         scandict[scanNum]['reffreq'] = rFreqOrdList
00338         scandict[scanNum]['chanwidth'] = cWidthOrdList
00339         scandict[scanNum]['baseband'] = bbandOrdList
00340             
00341     # report informatio to the logger
00342     casalog.origin('listsdm')
00343     casalog.post("================================================================================")
00344     casalog.post("   SDM File: %s" % sdm)
00345     casalog.post("================================================================================")
00346     casalog.post("   Observer: %s" % observerName)
00347     casalog.post("   Facility: %s, %s-configuration" % (telescopeName, configName))
00348     casalog.post("      Observed from %s to %s (UTC)" % (obsStart, obsEnd))
00349     casalog.post("      Total integration time = %.2f seconds (%.2f hours)" % (intTime, intTime/3600))
00350     casalog.post(" ")
00351     casalog.post("Scan listing:")
00352     casalog.post("  Timerange (UTC)           Scan FldID  FieldName       SpwIDs         Intent(s)")
00353 
00354     i = 0
00355     #SPWs = []
00356     for scan in scandict:
00357         SPWs = []
00358         for spw in scandict[scan]['spws']:
00359             SPWs += spw
00360         #printSPWs = sorted(SPWs)
00361         printSPWs = list(set(SPWs))
00362         casalog.post("  %s - %s %s %s  %s %s  %s" % (startTimeShort[i], endTimeShort[i], str(scandict.keys()[i]).rjust(4), str(scandict[scan]['field']).rjust(5), scandict[scan]['source'].ljust(15), str(printSPWs), scandict[scan]['intent']))
00363         i = i + 1
00364 
00365     casalog.post(" ")
00366     casalog.post("Spectral window information:")
00367     casalog.post("  SpwID  #Chans  Ch0(MHz)  ChWidth(kHz) TotBW(MHz)  Baseband")
00368 
00369     for i in range(0, len(spwIdList)):
00370         casalog.post("  %s   %s    %s  %s     %s    %s" % (string.split(spwIdList[i], '_')[1].ljust(4), str(nChanList[i]).ljust(4), str(refFreqList[i]/1e6).ljust(8), str(np.array(chanWidthList[i])/1e3).ljust(8), str(np.array(chanWidthList[i])*nChanList[i]/1e6).ljust(8), basebandList[i].ljust(8)))
00371     
00372     casalog.post(" ")
00373     casalog.post("Field information:")
00374     casalog.post("  FldID  Code   Name             RA            Dec             SrcID")
00375 
00376     for i in range(0, len(fieldList)):
00377         casalog.post("  %s  %s %s  %s %s %s" % (str(fieldList[i]).ljust(5), fieldCodeList[i].ljust(6), fieldNameList[i].ljust(15), fieldRAList[i].ljust(13), fieldDecList[i].ljust(15), str(fieldSrcIDList[i]).ljust(5)))    
00378     
00379     casalog.post(" ")
00380     casalog.post("Antennas (%i):" % len(antList))
00381     casalog.post("  ID    Name   Station   Diam.(m)  Lat.          Long.")
00382 
00383     for i in range(0, len(antList)):
00384         casalog.post("  %s %s %s     %s     %s  %s " % (str(antList[i]).ljust(5), antNameList[i].ljust(6), assocStatList[i].ljust(5), str(dishDiamList[i]).ljust(5), statLatList[i].ljust(12), statLonList[i].ljust(12)))
00385     
00386     # return the scan dictionary
00387     return scandict
00388