Coverage for /wheeldirectory/casa-6.7.0-12-py3.10.el8/lib/py/lib/python3.10/site-packages/casatasks/private/task_listsdm.py: 97%

294 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-01 07:19 +0000

1######################################################################## 

2# Task to retrieve observing information from SDM XML files 

3# 

4# v1.0: 2010.12.07, M. Krauss 

5# v1.1: 2011.02.23, M. Krauss: added functionality for ALMA data 

6# 

7# Original code based on readscans.py, courtesy S. Meyers 

8 

9import numpy as np 

10 

11try: 

12 from xml.dom import minidom 

13except ImportError as exc: 

14 raise ImportError("task listsdm requires minidom but there was an import error: {}". 

15 format(exc)) 

16 

17from casatools import quanta, measures 

18from casatasks import casalog 

19 

20_qa = quanta( ) 

21_me = measures( ) 

22str_split = str.split 

23 

24def listsdm(sdm=None): 

25 # read Scan.xml 

26 xmlscans = minidom.parse(sdm+'/Scan.xml') 

27 scandict = {} 

28 startTimeShort = [] 

29 endTimeShort = [] 

30 rowlist = xmlscans.getElementsByTagName("row") 

31 for rownode in rowlist: 

32 rowfid = rownode.getElementsByTagName("scanNumber") 

33 fid = int(rowfid[0].childNodes[0].nodeValue) 

34 scandict[fid] = {} 

35 

36 # number of subscans 

37 rowsubs = rownode.getElementsByTagName("numSubscan") 

38 if len(rowsubs) == 0: 

39 # EVLA and old ALMA data 

40 rowsubs = rownode.getElementsByTagName("numSubScan") 

41 nsubs = int(rowsubs[0].childNodes[0].nodeValue) 

42 

43 # intents 

44 rownint = rownode.getElementsByTagName("numIntent") 

45 nint = int(rownint[0].childNodes[0].nodeValue) 

46 

47 rowintents = rownode.getElementsByTagName("scanIntent") 

48 sint = str(rowintents[0].childNodes[0].nodeValue) 

49 sints = sint.split() 

50 rint = '' 

51 for r in range(nint): 

52 intent = sints[2+r] 

53 if rint=='': 

54 rint = intent 

55 else: 

56 rint += ' '+intent 

57 

58 # start and end times in mjd ns 

59 rowstart = rownode.getElementsByTagName("startTime") 

60 start = int(rowstart[0].childNodes[0].nodeValue) 

61 startmjd = float(start)*1.0E-9/86400.0 

62 t = _qa.quantity(startmjd,'d') 

63 starttime = _qa.time(t,form="ymd",prec=8)[0] 

64 startTimeShort.append(_qa.time(t,prec=8)[0]) 

65 rowend = rownode.getElementsByTagName("endTime") 

66 end = int(rowend[0].childNodes[0].nodeValue) 

67 endmjd = float(end)*1.0E-9/86400.0 

68 t = _qa.quantity(endmjd,'d') 

69 endtime = _qa.time(t,form="ymd",prec=8)[0] 

70 endTimeShort.append(_qa.time(t,prec=8)[0]) 

71 

72 # source name 

73 rowsrc = rownode.getElementsByTagName("sourceName") 

74 src = str(rowsrc[0].childNodes[0].nodeValue) 

75 

76 scandict[fid]['start'] = starttime 

77 scandict[fid]['end'] = endtime 

78 timestr = starttime+'~'+endtime 

79 scandict[fid]['timerange'] = timestr 

80 scandict[fid]['source'] = src 

81 scandict[fid]['intent'] = rint 

82 scandict[fid]['nsubs'] = nsubs 

83 

84 # read Main.xml 

85 xmlmain = minidom.parse(sdm+'/Main.xml') 

86 rowlist = xmlmain.getElementsByTagName("row") 

87 mainScanList = [] 

88 mainConfigList = [] 

89 fieldIdList = [] 

90 for rownode in rowlist: 

91 

92 # get the scan numbers 

93 rowfid = rownode.getElementsByTagName("scanNumber") 

94 fid = int(rowfid[0].childNodes[0].nodeValue) 

95 mainScanList.append(fid) 

96 

97 # get the configuration description 

98 rowconfig = rownode.getElementsByTagName("configDescriptionId") 

99 config = str(rowconfig[0].childNodes[0].nodeValue) 

100 mainConfigList.append(config) 

101 

102 # get the field ID 

103 rowfieldid = rownode.getElementsByTagName("fieldId") 

104 fieldid = str_split(str(rowfieldid[0].childNodes[0].nodeValue), '_')[1] 

105 fieldIdList.append(fieldid) 

106 

107 # read ConfigDescription.xml to relate the configuration 

108 # description to a (set) of data description IDs 

109 xmlconfig = minidom.parse(sdm+'/ConfigDescription.xml') 

110 rowlist = xmlconfig.getElementsByTagName("row") 

111 configDescList = [] 

112 dataDescList = [] 

113 for rownode in rowlist: 

114 

115 # get the configuration description 

116 rowConfigDesc = rownode.getElementsByTagName("configDescriptionId") 

117 configDesc = str(rowConfigDesc[0].childNodes[0].nodeValue) 

118 configDescList.append(configDesc) 

119 

120 # make a list of the data description IDs: 

121 rowNumDataDesc = rownode.getElementsByTagName("numDataDescription") 

122 numDataDesc = int(rowNumDataDesc[0].childNodes[0].nodeValue) 

123 

124 rowDataDesc = rownode.getElementsByTagName("dataDescriptionId") 

125 dataDescStr = str(rowDataDesc[0].childNodes[0].nodeValue) 

126 dataDescSplit = dataDescStr.split() 

127 dataDesc = [] 

128 for i in range(numDataDesc): 

129 dataDesc.append(dataDescSplit[i+2]) 

130 dataDescList.append(dataDesc) 

131 

132 # read DataDescription.xml to relate the data description IDs to 

133 # spectral window IDs 

134 xmlDataDesc = minidom.parse(sdm+'/DataDescription.xml') 

135 rowlist = xmlDataDesc.getElementsByTagName("row") 

136 dataDescElList = [] 

137 spwIdDataDescList = [] 

138 for rownode in rowlist: 

139 

140 # get the data description ID, make another list: 

141 rowDataDescEl = rownode.getElementsByTagName("dataDescriptionId") 

142 dataDescEl = str(rowDataDescEl[0].childNodes[0].nodeValue) 

143 dataDescElList.append(dataDescEl) 

144 

145 # get the related spectral window ID: 

146 rowSpwIdDataDesc = rownode.getElementsByTagName("spectralWindowId") 

147 spwIdDataDesc = str(rowSpwIdDataDesc[0].childNodes[0].nodeValue) 

148 spwIdDataDescList.append(spwIdDataDesc) 

149 

150 # read SpectralWindow.xml, get information about number of 

151 # channels, reference frequency, baseband name, channel width. 

152 # Interesting that there seem to be multiple fields that give the 

153 # same information: chanFreqStart=reFreq, 

154 # chanFreqStep=chanWidth=resolution. Why? (Note: all units are Hz) 

155 # Note: this is where the script breaks for ALMA data, since there 

156 # are different tags in SpectraWindow.xml (for varying channel widths). 

157 xmlSpecWin = minidom.parse(sdm+'/SpectralWindow.xml') 

158 rowlist = xmlSpecWin.getElementsByTagName("row") 

159 spwIdList = [] 

160 nChanList = [] 

161 refFreqList = [] 

162 chanWidthList = [] 

163 basebandList = [] 

164 for rownode in rowlist: 

165 

166 # get the various row values: 

167 rowSpwId = rownode.getElementsByTagName("spectralWindowId") 

168 rowNChan = rownode.getElementsByTagName("numChan") 

169 rowRefFreq = rownode.getElementsByTagName("refFreq") 

170 # For EVLA 

171 rowChanWidth = rownode.getElementsByTagName("chanWidth") 

172 # For ALMA 

173 rowChanWidthArr = rownode.getElementsByTagName("chanWidthArray") 

174 rowBaseband = rownode.getElementsByTagName("basebandName") 

175 

176 # convert to values or strings and append to the relevant lists: 

177 spwId = str(rowSpwId[0].childNodes[0].nodeValue) 

178 spwIdList.append(spwId) 

179 nChan = int(rowNChan[0].childNodes[0].nodeValue) 

180 nChanList.append(nChan) 

181 refFreq = float(rowRefFreq[0].childNodes[0].nodeValue) 

182 refFreqList.append(refFreq) 

183 if rowChanWidth: 

184 chanWidth = float(rowChanWidth[0].childNodes[0].nodeValue) 

185 chanWidthList.append(chanWidth) 

186 if rowChanWidthArr: 

187 tmpArr = str(rowChanWidthArr[0].childNodes[0].nodeValue).split(' ') 

188 tmpWidth = [] 

189 for cw in range(2, len(tmpArr)): 

190 thisWidth = float(tmpArr[cw]) 

191 tmpWidth.append(thisWidth) 

192 chanWidthList.append(tmpWidth) 

193 baseband = str(rowBaseband[0].childNodes[0].nodeValue) 

194 basebandList.append(baseband) 

195 

196 # read Field.xml 

197 xmlField = minidom.parse(sdm+'/Field.xml') 

198 rowlist = xmlField.getElementsByTagName("row") 

199 fieldList = [] 

200 fieldNameList = [] 

201 fieldCodeList = [] 

202 fieldRAList = [] 

203 fieldDecList = [] 

204 fieldSrcIDList = [] 

205 for rownode in rowlist: 

206 rowField = rownode.getElementsByTagName("fieldId") 

207 rowName = rownode.getElementsByTagName("fieldName") 

208 rowCode = rownode.getElementsByTagName("code") 

209 rowCoords = rownode.getElementsByTagName("referenceDir") 

210 rowSrcId = rownode.getElementsByTagName("sourceId") 

211 

212 # convert to values or strings and append to relevent lists: 

213 fieldList.append(int(str_split(str(rowField[0].childNodes[0].nodeValue),'_')[1])) 

214 fieldNameList.append(str(rowName[0].childNodes[0].nodeValue)) 

215 fieldCodeList.append(str(rowCode[0].childNodes[0].nodeValue)) 

216 coordInfo = rowCoords[0].childNodes[0].nodeValue.split() 

217 RADeg = float(coordInfo[3])*(180.0/np.pi) 

218 DecDeg = float(coordInfo[4])*(180.0/np.pi) 

219 RAInp = {'unit': 'deg', 'value': RADeg} 

220 DecInp = {'unit': 'deg', 'value': DecDeg} 

221 RAHMS = _qa.formxxx(RAInp, format='hms') 

222 DecDMS = _qa.formxxx(DecInp, format='dms') 

223 fieldRAList.append(RAHMS) 

224 fieldDecList.append(DecDMS) 

225 fieldSrcIDList.append(int(rowSrcId[0].childNodes[0].nodeValue)) 

226 

227 # read Antenna.xml 

228 xmlAnt = minidom.parse(sdm+'/Antenna.xml') 

229 rowlist = xmlAnt.getElementsByTagName("row") 

230 antList = [] 

231 antNameList = [] 

232 dishDiamList = [] 

233 stationList = [] 

234 for rownode in rowlist: 

235 rowAnt = rownode.getElementsByTagName("antennaId") 

236 rowAntName = rownode.getElementsByTagName("name") 

237 rowDishDiam = rownode.getElementsByTagName("dishDiameter") 

238 rowStation = rownode.getElementsByTagName("stationId") 

239 

240 # convert and append 

241 antList.append(int(str_split(str(rowAnt[0].childNodes[0].nodeValue), '_')[1])) 

242 antNameList.append(str(rowAntName[0].childNodes[0].nodeValue)) 

243 dishDiamList.append(float(rowDishDiam[0].childNodes[0].nodeValue)) 

244 stationList.append(str(rowStation[0].childNodes[0].nodeValue)) 

245 

246 # read Station.xml 

247 xmlStation = minidom.parse(sdm+'/Station.xml') 

248 rowlist = xmlStation.getElementsByTagName("row") 

249 statIdList = [] 

250 statNameList = [] 

251 statLatList = [] 

252 statLonList = [] 

253 for rownode in rowlist: 

254 rowStatId = rownode.getElementsByTagName("stationId") 

255 rowStatName = rownode.getElementsByTagName("name") 

256 rowStatPos = rownode.getElementsByTagName("position") 

257 

258 # convert and append 

259 statIdList.append(str(rowStatId[0].childNodes[0].nodeValue)) 

260 statNameList.append(str(rowStatName[0].childNodes[0].nodeValue)) 

261 posInfo = str_split(str(rowStatPos[0].childNodes[0].nodeValue)) 

262 x = _qa.quantity([float(posInfo[2])], 'm') 

263 y = _qa.quantity([float(posInfo[3])], 'm') 

264 z = _qa.quantity([float(posInfo[4])], 'm') 

265 pos = _me.position('ITRF', x, y, z) 

266 qLon = pos['m0'] 

267 qLat = pos['m1'] 

268 statLatList.append(_qa.formxxx(qLat, 'dms', prec=0)) 

269 statLonList.append(_qa.formxxx(qLon, 'dms', prec=0)) 

270 

271 # associate antennas with stations: 

272 assocStatList = [] 

273 for station in stationList: 

274 i = np.where(np.array(statIdList) == station)[0][0] 

275 assocStatList.append(statNameList[i]) 

276 

277 # read ExecBlock.xml 

278 xmlExecBlock = minidom.parse(sdm+'/ExecBlock.xml') 

279 rowlist = xmlExecBlock.getElementsByTagName("row") 

280 sTime = float(rowlist[0].getElementsByTagName("startTime")[0].childNodes[0].nodeValue)*1.0E-9 

281 eTime = float(rowlist[0].getElementsByTagName("endTime")[0].childNodes[0].nodeValue)*1.0E-9 

282 # integration time in seconds, start and end times: 

283 intTime = eTime - sTime 

284 t = _qa.quantity(sTime/86400.0, 'd') 

285 obsStart = _qa.time(t, form="ymd", prec=8)[0] 

286 t = _qa.quantity(eTime/86400.0, 'd') 

287 obsEnd = _qa.time(t, form="ymd", prec=8)[0] 

288 # observer name and obs. info: 

289 observerName = str(rowlist[0].getElementsByTagName("observerName")[0].childNodes[0].nodeValue) 

290 configName = str(rowlist[0].getElementsByTagName("configName")[0].childNodes[0].nodeValue) 

291 telescopeName = str(rowlist[0].getElementsByTagName("telescopeName")[0].childNodes[0].nodeValue) 

292 numAntenna = int(rowlist[0].getElementsByTagName("numAntenna")[0].childNodes[0].nodeValue) 

293 

294 # make lists like the dataDescList for spectral windows & related info: 

295 spwOrd = [] 

296 nChanOrd = [] 

297 rFreqOrd = [] 

298 cWidthOrd = [] 

299 bbandOrd = [] 

300 for i in range(0, len(configDescList)): 

301 spwTempList = [] 

302 nChanTempList = [] 

303 rFreqTempList = [] 

304 cWidthTempList = [] 

305 bbandTempList = [] 

306 

307 for dDesc in dataDescList[i]: 

308 el = np.where(np.array(dataDescElList) == dDesc)[0][0] 

309 spwIdN = spwIdDataDescList[el] 

310 spwEl = np.where(np.array(spwIdList) == spwIdN)[0][0] 

311 spwTempList.append(int(str_split(spwIdList[spwEl], '_')[1])) 

312 nChanTempList.append(nChanList[spwEl]) 

313 rFreqTempList.append(refFreqList[spwEl]) 

314 cWidthTempList.append(chanWidthList[spwEl]) 

315 bbandTempList.append(basebandList[spwEl]) 

316 spwOrd.append(spwTempList) 

317 nChanOrd.append(nChanTempList) 

318 rFreqOrd.append(rFreqTempList) 

319 cWidthOrd.append(cWidthTempList) 

320 bbandOrd.append(bbandTempList) 

321 

322 # add this info to the scan dictionary: 

323 for scanNum in scandict: 

324 spwOrdList = [] 

325 nChanOrdList = [] 

326 rFreqOrdList = [] 

327 cWidthOrdList = [] 

328 bbandOrdList = [] 

329 # scanEl could have multiple elements if subscans are present, 

330 # or for ALMA data: 

331 scanEl = np.where(np.array(mainScanList) == scanNum)[0] 

332 for thisEl in scanEl: 

333 configEl = mainConfigList[thisEl] 

334 listEl = np.where(np.array(configDescList) == configEl)[0][0] 

335 spwOrdList.append(spwOrd[listEl]) 

336 nChanOrdList.append(nChanOrd[listEl]) 

337 rFreqOrdList.append(rFreqOrd[listEl]) 

338 cWidthOrdList.append(cWidthOrd[listEl]) 

339 bbandOrdList.append(bbandOrd[listEl]) 

340 if len(scanEl) > 0: 

341 scandict[scanNum]['field'] = int(fieldIdList[scanEl[0]]) 

342 else: 

343 scandict[scanNum]['field'] = -1 

344 scandict[scanNum]['spws'] = spwOrdList 

345 scandict[scanNum]['nchan'] = nChanOrdList 

346 scandict[scanNum]['reffreq'] = rFreqOrdList 

347 scandict[scanNum]['chanwidth'] = cWidthOrdList 

348 scandict[scanNum]['baseband'] = bbandOrdList 

349 

350 # report informatio to the logger 

351 casalog.origin('listsdm') 

352 casalog.post("================================================================================") 

353 casalog.post(" SDM File: %s" % sdm) 

354 casalog.post("================================================================================") 

355 casalog.post(" Observer: %s" % observerName) 

356 casalog.post(" Facility: %s, %s-configuration" % (telescopeName, configName)) 

357 casalog.post(" Observed from %s to %s (UTC)" % (obsStart, obsEnd)) 

358 casalog.post(" Total integration time = %.2f seconds (%.2f hours)" % (intTime, intTime/3600)) 

359 casalog.post(" ") 

360 casalog.post("Scan listing:") 

361 casalog.post(" Timerange (UTC) Scan FldID FieldName SpwIDs Intent(s)") 

362 

363 i = 0 

364 #SPWs = [] 

365 for scan in scandict: 

366 SPWs = [] 

367 for spw in scandict[scan]['spws']: 

368 SPWs += spw 

369 #printSPWs = sorted(SPWs) 

370 printSPWs = list(set(SPWs)) 

371 casalog.post(" %s - %s %s %s %s %s %s" % (startTimeShort[i], endTimeShort[i], str(list(scandict.keys())[i]).rjust(4), str(scandict[scan]['field']).rjust(5), scandict[scan]['source'].ljust(15), str(printSPWs), scandict[scan]['intent'])) 

372 i = i + 1 

373 

374 casalog.post(" ") 

375 casalog.post("Spectral window information:") 

376 casalog.post(" SpwID #Chans Ch0(MHz) ChWidth(kHz) TotBW(MHz) Baseband") 

377 

378 for i in range(0, len(spwIdList)): 

379 casalog.post(" %s %s %s %s %s %s" % (str_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))) 

380 

381 casalog.post(" ") 

382 casalog.post("Field information:") 

383 casalog.post(" FldID Code Name RA Dec SrcID") 

384 

385 for i in range(0, len(fieldList)): 

386 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))) 

387 

388 casalog.post(" ") 

389 casalog.post("Antennas (%i):" % len(antList)) 

390 casalog.post(" ID Name Station Diam.(m) Lat. Long.") 

391 

392 for i in range(0, len(antList)): 

393 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))) 

394 

395 # return the scan dictionary 

396 return scandict