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
« 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>
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>
68import os
69import numpy
71from casatools import table, ms, agentflagger, quanta
72from casatasks import casalog, importuvfits
73from .mstools import write_history
75_qa = quanta( )
77def importgmrt( fitsfile, flagfile, vis ):
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'
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.')
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=[]
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)
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 )
127 mytb = table( )
128 myms = ms( )
129 aflocal = agentflagger( )
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]
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')
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' )
160 # If we don't have a flagfile then we are done!
161 # Yippee awe eh!
162 if ( len( flagfile ) < 1 ):
163 return
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()
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]
180 except Exception as instance:
181 msg = 'Unable to find obaservation start/en times: {}'.format(instance)
182 raise RuntimeError(msg)
184 days=[]
185 startYY = startObs.split('/')[0]
186 startMM = startObs.split('/')[1]
187 startDD = startObs.split('/')[2]
189 endYY = endObs.split('/')[0]
190 endMM =endObs.split('/')[1]
191 endDD =endObs.split('/')[2]
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')
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' )
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()
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 = []
224 while ( len( line ) > 0 ):
225 casalog.post( 'Read from flag file: '+str(line), 'DEBUG1' )
227 # Default antenna list and time range
228 antennas = []
229 baselines = []
230 timerange = []
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
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
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
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('=')
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' )
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')
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')
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]
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
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( ' ' )
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)
365 line = FLAG_FILE.readline()
367 FLAG_FILE.close()
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()