casa
$Rev:20696$
|
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