diff --git a/lsmtool/operations_lib.py b/lsmtool/operations_lib.py index 1c83b89402c6af5bea6685c060a5309b105a8648..2f9d1d912f907f7c9ccd77adc1ca76ae2687dc65 100644 --- a/lsmtool/operations_lib.py +++ b/lsmtool/operations_lib.py @@ -19,6 +19,45 @@ import logging +def radec_to_xyz(ra, dec, time): + """ + Convert RA and Dec coordinates to ITRS coordinates for LOFAR observations. + + Note: the location adopted for LOFAR is that of the core, so the returned + ITRS coordinates will be less accurate for stations outside of the core. + + Parameters + ---------- + ra : astropy.coordinates.Angle + Right ascension + dec: astropy.coordinates.Angle + Declination + time: float + MJD time in seconds + + Returns + ------- + pointing_xyz: array + NumPy array containing the ITRS X, Y and Z coordinates + """ + from astropy.coordinates import SkyCoord, ITRS, EarthLocation, AltAz + from astropy.time import Time + import astropy.units as u + import numpy as np + + obstime = Time(time/3600/24, scale='utc', format='mjd') + + # Set the location to the LOFAR core + loc_LOFAR = EarthLocation(lon=0.11990128407256424, lat=0.9203091252660295, height=6364618.852935438*u.m) + + dir_pointing = SkyCoord(ra, dec) + dir_pointing_altaz = dir_pointing.transform_to(AltAz(obstime=obstime, location=loc_LOFAR)) + dir_pointing_xyz = dir_pointing_altaz.transform_to(ITRS) + + pointing_xyz = np.asarray([dir_pointing_xyz.x, dir_pointing_xyz.y, dir_pointing_xyz.z]) + return pointing_xyz + + def apply_beam_star(inputs): """ Simple multiprocessing helper function for apply_beam() @@ -74,17 +113,21 @@ def apply_beam(RA, Dec, spectralIndex, flux, referenceFrequency, beamMS, time, a except ImportError: import lofar.stationresponse as lsr import casacore.tables as pt + from astropy.coordinates import Angle + import astropy.units as u # Use ant1, times, and n channel to compute the beam, where n is determined by # the order of the spectral index polynomial if has_eb: sr = eb.load_telescope(beamMS) - source_xyz = eb.thetaphi2cart(RA*np.pi/180., Dec*np.pi/180.) + source_ra = Angle(RA, unit=u.deg) + source_dec = Angle(Dec, unit=u.deg) + source_xyz = radec_to_xyz(source_ra, source_dec, time) obs = pt.table(beamMS+'::FIELD', ack=False) - pointing_ra = float(obs.col('REFERENCE_DIR')[0][0][0]) # rad - pointing_dec = float(obs.col('REFERENCE_DIR')[0][0][1]) # rad + pointing_ra = Angle(float(obs.col('REFERENCE_DIR')[0][0][0]), unit=u.rad) + pointing_dec = Angle(float(obs.col('REFERENCE_DIR')[0][0][1]), unit=u.rad) obs.close() - pointing_xyz = eb.thetaphi2cart(pointing_ra, pointing_dec) + pointing_xyz = radec_to_xyz(pointing_ra, pointing_dec, time) freqs = np.arange(startfreq, startfreq+numchannels*channelwidth, channelwidth) else: sr = lsr.stationresponse(beamMS, inverse=invert, useElementResponse=False, @@ -130,6 +173,11 @@ def attenuate(beamMS, fluxes, RADeg, DecDeg, spectralIndex=None, referenceFreque """ Returns flux attenuated by primary beam. + Note: the attenuation is approximated using the array factor beam from the + first station in the beam MS only (and it is assumed that this station is at + LOFAR core). This approximation has been found to produce reasonable results + for a typical LOFAR observation but may not work well for atypical observations. + Parameters ---------- beamMS : str