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

144 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-10-31 17:39 +0000

1########################################################################3 

2# task_importgmrt.py 

3# 

4# 

5# Copyright (C) 2009 

6# Associated Universities, Inc. Washington DC, USA. 

7# 

8# This script is free software; you can redistribute it and/or modify it 

9# under the terms of the GNU Library General Public License as published by 

10# the Free Software Foundation; either version 2 of the License, or (at your 

11# option) any later version. 

12# 

13# This library is distributed in the hope that it will be useful, but WITHOUT 

14# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 

15# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 

16# License for more details. 

17# 

18# You should have received a copy of the GNU Library General Public License 

19# along with this library; if not, write to the Free Software Foundation, 

20# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 

21# 

22# Correspondence concerning AIPS++ should be adressed as follows: 

23# Internet email: casa-feedback@nrao.edu. 

24# Postal address: AIPS++ Project Office 

25# National Radio Astronomy Observatory 

26# 520 Edgemont Road 

27# Charlottesville, VA 22903-2475 USA 

28# 

29# <author> 

30# Shannon Jaeger (University of Calgary) 

31# </author> 

32# 

33# <summary> 

34# </summary> 

35# 

36# <reviewed reviwer="" date="" tests="" demos=""> 

37# </reviewed 

38# 

39# <etymology> 

40# importgmrt stands for import GMRT UV FITS data. 

41# </etymology> 

42# 

43# <synopsis> 

44# task_importgmrt.py is a Python script providing an easy to use task 

45# for importing GMRT FITS data files into the CASA system. A measurement 

46# set is produced from the GMRT FITS file. 

47# 

48# The given flag files are read and data is flagged according to 

49# the information found in these files. It is expected that the 

50# FLAG files are in the old AIPS TVFLAG file format. 

51# 

52# </synopsis>  

53# 

54# <example> 

55# <srcblock> 

56 

57# </srblock> 

58# </example> 

59# 

60# <motivation> 

61# To provide a user-friendly method for importing GMRT FITS files. 

62# </motivation> 

63# 

64# <todo> 

65# </todo> 

66 

67 

68import os 

69import numpy 

70 

71from casatools import table, ms, agentflagger, quanta 

72from casatasks import casalog, importuvfits 

73from .mstools import write_history 

74 

75_qa = quanta( ) 

76 

77def importgmrt( fitsfile, flagfile, vis ): 

78 

79 # First check if the output file exists. If it 

80 # does then we abort. CASA policy prevents files 

81 # from being over-written. 

82 # 

83 # Also if the vis name given is the empty string 

84 # we use the default name, input fitsfile with 

85 # "fits" removed 

86 if ( len( vis ) < 1 ): 

87 vis = '' 

88 fits_list=fitsfile.split( '.' ) 

89 last = len(fits_list) 

90 if ( fits_list[last-1].lower() == 'fits' or \ 

91 fits_list[last-1].lower() == 'fit' ): 

92 last = last -1 

93 for i in range( last ): 

94 if ( len ( vis ) < 1 ): 

95 vis = fits_list[i] 

96 else: 

97 vis = vis + '.'+fits_list[i] 

98 vis=vis+'.MS' 

99 

100 casalog.post( "The vis paramter is empty, consequently the" \ 

101 +" the default visibilty file\nname will be used, "\ 

102 + vis, 'WARN' ) 

103 if ( len( vis ) > 0 and os.path.exists( vis ) ): 

104 raise RuntimeError( 'Visibility file, '+vis+\ 

105 ' exists. import GMRT can not proceed, please\n'+\ 

106 'remove it or set vis to a different value.') 

107 

108 # Loop through the list of flag files and make sure each one 

109 # of them exists 

110 if isinstance( flagfile, str ): 

111 if ( len( flagfile ) > 0 ): 

112 flagfile=[flagfile] 

113 else: 

114 flagfile=[] 

115 

116 for i in range( len( flagfile ) ): 

117 if ( not os.path.exists( flagfile[i] ) ): 

118 msg = 'Unable to locate FLAG file '+ flagfile[i] 

119 raise RuntimeError(msg) 

120 

121 

122 # Ok, we've done our preliminary checks, now let's get 

123 # down to business and import our fitsfile. 

124 casalog.post( 'Starting import ...', 'NORMAL' ) 

125 importuvfits( fitsfile, vis ) 

126 

127 mytb = table( ) 

128 myms = ms( ) 

129 aflocal = agentflagger( ) 

130 

131 # Write history 

132 try: 

133 param_names = importgmrt.__code__.co_varnames[:importgmrt.__code__.co_argcount] 

134 vars = locals( ) 

135 param_vals = [vars[p] for p in param_names] 

136 

137 ok &= write_history(myms, vis, 'importgmrt', param_names, 

138 param_vals, casalog) 

139 except Exception as instance: 

140 casalog.post("*** Error \'%s\' updating HISTORY" % (instance), 'WARN') 

141 

142 # CASA's importuvfits doesn't understand the GMRT antenna 

143 # names very well and/or the FITS files tend to put the 

144 # antenna names in a place that CASA doesn't look for them. 

145 # Luckily the information seems to be in the "station" 

146 # information. So let's fix up the Name column. 

147 casalog.post( 'Correcting GMRT Antenna names.', 'NORMAL1' ) 

148 try: 

149 mytb.open( vis+'/ANTENNA', nomodify=False ) 

150 stations = mytb.getcol('STATION') 

151 names = [] 

152 for idx in range( 0, len( stations ) ): 

153 names.append( stations[idx].split(':')[0] ) 

154 mytb.putcol( 'NAME', numpy.array( names ) ) 

155 mytb.done() 

156 except Exception as instance: 

157 casalog.post( 'Unable to properly name the antennas, but continuing') 

158 casalog.post( str(instance), 'WARN' ) 

159 

160 # If we don't have a flagfile then we are done! 

161 # Yippee awe eh! 

162 if ( len( flagfile ) < 1 ): 

163 return 

164 

165 # We've imported let's find out the observation start 

166 # and end times, this will be needed for flagging. 

167 # We use it to find the different days the observation 

168 # was done on. 

169 startObs = '' 

170 endObs = '' 

171 try: 

172 myms.open( vis ) 

173 trange=myms.range( 'time' )['time'] 

174 myms.done() 

175 

176 # Now have the observation time range in a numpy array. 

177 startObs = _qa.time( str( trange[0] )+'s', prec=8, form='ymd' )[0] 

178 endObs = _qa.time( str( trange[1] )+'s', prec=8, form='ymd' )[0] 

179 

180 except Exception as instance: 

181 msg = 'Unable to find obaservation start/en times: {}'.format(instance) 

182 raise RuntimeError(msg) 

183 

184 days=[] 

185 startYY = startObs.split('/')[0] 

186 startMM = startObs.split('/')[1] 

187 startDD = startObs.split('/')[2] 

188 

189 endYY = endObs.split('/')[0] 

190 endMM =endObs.split('/')[1] 

191 endDD =endObs.split('/')[2] 

192 

193 for year in range( int( startYY ), int( endYY ) + 1 ): 

194 for month in range( int( startMM ), int( endMM ) + 1 ): 

195 for day in range( int( startDD ), int( endDD ) + 1 ): 

196 days.append( str(year) + '/' + str(month) + '/' + str(day) + '/' ) 

197 casalog.post( "DAYS: "+str(days), 'DEBUG1') 

198 

199 

200 # Read through the flag file(s) and assemble it into 

201 # a data structure. The hope is to minimize the 

202 # number of calls to "flagdata" to make the flagging 

203 # fast! 

204 # 

205 # The expected file format is what is the flag file 

206 # format used by TVFLAG/UVFLAG in AIPS, which is as follows: 

207 # 1. If a line starts with '!' it's a comment 

208 # 2.  

209 # 

210 casalog.post( 'Starting the flagging ...', 'NORMAL' ) 

211 

212 # First lets save the flag information as we got it from the 

213 # flag file. 

214 aflocal.open( vis ) 

215 aflocal.saveflagversion( 'none', 'No flagging performed yet' ) 

216 aflocal.done() 

217 

218 for file in flagfile: 

219 casalog.post( 'Reading flag file '+file, 'NORMAL2' ) 

220 FLAG_FILE = open( file, 'r' ) 

221 line = FLAG_FILE.readline() 

222 ant_names = [] 

223 

224 while ( len( line ) > 0 ): 

225 casalog.post( 'Read from flag file: '+str(line), 'DEBUG1' ) 

226 

227 # Default antenna list and time range 

228 antennas = [] 

229 baselines = [] 

230 timerange = [] 

231 

232 # Skip comment lines, and the end of file. 

233 if ( len(line) < 1 or ( line[0] == '!' and line[2:6] != 'PANT' ) ): 

234 line = FLAG_FILE.readline() 

235 continue 

236 

237 # Store the antenna name list 

238 if ( line[0:6] == '! PANT' ): 

239 ant_names= line.split(':')[1].lstrip(' ').split(' ') 

240 line = FLAG_FILE.readline() 

241 continue 

242 

243 # First divide lines up on spaces 

244 casalog.post( 'LINE READ: '+line, 'DEBUG1' ) 

245 step1=line.split(' ') 

246 if ( len( step1 ) < 2 ): 

247 # We want a line with something on it. 

248 line = FLAG_FILE.readline() 

249 continue 

250 

251 # Parse each bit of the string looking for the 

252 # antenna and timrange information. 

253 for i in range( len( step1 ) ): 

254 step2=step1[i].split('=') 

255 

256 if ( len( step2 ) != 2 ): 

257 # We want something with an equals sign in it! 

258 continue 

259 casalog.post( 'keyword/value: '+str(step2), 'DEBUG1' ) 

260 

261 

262 if ( step2[0].upper().startswith( 'ANT' ) ): 

263 # Should be a comma separated list which 

264 # is acceptable to flag data 

265 #antennas=list(step2[1].split(',') 

266 antennas=step2[1] 

267 casalog.post( "antennas: "+antennas, 'DEBUG1') 

268 

269 

270 if ( step2[0].upper().startswith( 'BASEL' ) ): 

271 # Should be a comma separated list which 

272 # is acceptable to flag data 

273 baselines=step2[1] 

274 casalog.post( "baselines: "+baselines, 'DEBUG1') 

275 

276 if ( step2[0].upper() == 'TIMERANGE' ): 

277 # Time in the FLAG file is in the format 

278 # start-day,start-hour,start-min,star-sec,\ 

279 # end-day,end-hour,end-min,end-sec 

280 # 

281 # CASA expects data to be of the form 

282 # YYYY/MM/DD/HH:MM:SS~YYYY/MM/DD/HH:MM:SS 

283 # http://casa.nrao.edu/Memos/msselection/node8.html 

284 # 

285 # We use the day # to index into our days list and 

286 # append the time on the end. But day # starts at 

287 # 1 and indexing starts at 0 so we need to adjust. 

288 times = step2[1].split(',') 

289 casalog.post( "time: "+str(times), 'DEBUG1') 

290 if ( int(times[0]) < 1 and int(times[4]) > len(days) ): 

291 # All data for this antenna 

292 timerange = '' 

293 elif ( int(times[0]) < 1 ): 

294 # We want all time before the end time 

295 timerange = '<' + days[int(times[4])-1] \ 

296 + times[5] + ':' + times[6] + ':' +times[7] 

297 elif ( int(times[4]) > len(days) ): 

298 # We want all times after the start time 

299 timerange = '>' + days[int(times[0])-1] \ 

300 + times[1]+':'+times[2]+':'+times[3] 

301 else: 

302 # We ahve a fully specified time range 

303 timerange = days[int(times[0])-1] \ 

304 + times[1]+':'+times[2]+':'+times[3]\ 

305 +'~'\ 

306 +days[int(times[4])-1] \ 

307 +times[5]+':'+times[6]+':'+times[7] 

308 

309 # Construct the antenna query string 

310 # 

311 # Verify the syntax of the ANTENNA & BASELINE keywords,  

312 # if ANTENNA will always have only one. I suspect we 

313 # with to loop through the baselines only here. 

314 # 

315 # OLD CODE FOR creating ANT SELECTION STRING 

316 # 

317 #antStr='' 

318 #selectAntStr='' 

319 #if ( len( antennas ) > 0 and len( baselines ) > 0 ): 

320 # # We are selecting baselines. 

321 # for ant1 in antennas: 

322 # for ant2 in baselines: 

323 # if ( len( antStr ) < 1 ): 

324 # antStr=str(int(ant1)-1)+'&'+str(int(ant2)-1) 

325 # selectAntStr=antStr 

326 #elif ( len( antennas ) > 0 ): 

327 # antStr=str(int(antennas)-1) 

328 # # A hack to make sure we always have some unflagged data. 

329 # # CASA seg faults if the myfg.setdata() results in no data. 

330 # selectAntStr+=antStr+','+antennas 

331 

332 

333 antStr='' 

334 #if ( len( antennas ) > 0 and len( baselines ) > 0 ): 

335 # # We are selecting baselines. 

336 # for ant1 in antennas: 

337 # for ant2 in baselines: 

338 # if ( len( antStr ) < 1 ): 

339 # antStr=str(int(ant1)-1)+'&'+str(int(ant2)-1) 

340 # selectAntStr=antStr 

341 #elif ( len( antennas ) > 0 ): 

342 if ( len( antennas ) > 0 ): 

343 antStr = ant_names[ int(antennas)-1 ].strip( ' ' ) 

344 

345 try: 

346# casalog.post( "flagdata( "+vis+", mode='manualflag', antenna='" 

347# +antStr+"', timerange='"+timerange+"' )", 'NORMAL') 

348 casalog.post( "flagdata( "+vis+", mode='manual', antenna='" 

349 +antStr+"', timerange='"+timerange+"' )", 'NORMAL') 

350 #flagdata( vis, mode='manual', selectdata=True, \ 

351 # antenna=antStr, timerange=timerange, \ 

352 # flagbackup=False ) 

353 aflocal.open(vis) 

354 aflocal.selectdata(timerange=timerange) 

355 aflocal.parsemanualparameters(antenna=antStr, timerange=timerange) 

356 aflocal.init() 

357 aflocal.run(True, True) 

358 aflocal.done() 

359 except Exception as instance: 

360 msg = 'Unable to flag data from flag file '+file\ 

361 +'.\nAntennas='+antennas+' and timerange='\ 

362 +timerange 

363 raise RuntimeError(msg) 

364 

365 line = FLAG_FILE.readline() 

366 

367 FLAG_FILE.close() 

368 

369 # Save a Flag version so we can revert back to it if we wish 

370 aflocal.open( vis ) 

371 aflocal.saveflagversion( 'import', 'Flagged the data from the GMRT flag file' ) 

372 aflocal.done()