From a85d447911f3737831a3e0acb5cf36bb04ee13ff Mon Sep 17 00:00:00 2001 From: Danny Price Date: Fri, 3 May 2024 09:40:08 +0800 Subject: [PATCH 1/3] Issue #1433: RDATE and DATE-OBS in UVFITS writer --- pyuvdata/uvdata/uvfits.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/pyuvdata/uvdata/uvfits.py b/pyuvdata/uvdata/uvfits.py index b6fefff558..73ce72ede5 100644 --- a/pyuvdata/uvdata/uvfits.py +++ b/pyuvdata/uvdata/uvfits.py @@ -1158,8 +1158,12 @@ def write_uvfits( hdu.header["PSCAL" + str(i + 1) + " "] = pscal_dict[key] hdu.header["PZERO" + str(i + 1) + " "] = pzero_dict[key] - # ISO string of first time in self.time_array - hdu.header["DATE-OBS"] = Time(self.time_array[0], scale="utc", format="jd").isot + # Create an astropy.time.Time object from first timestamp. + # This is used to generate DATE-OBS and RDATE keywords + obs_date0 = Time(self.time_array[0], format="jd", scale="utc", location=self.location) + + # Per AIPS memo 117, DATE-OBS is the YYYY-MM-DD string + hdu.header["DATE-OBS"] = obs_date0.strftime("%Y-%m-%d") hdu.header["CTYPE2 "] = "COMPLEX " hdu.header["CRVAL2 "] = 1.0 @@ -1338,26 +1342,21 @@ def write_uvfits( else: ant_hdu.header["FREQ"] = self.freq_array[0, 0] + # RDATE: Reference date when obs started, YYYY-MM-DD if (self.rdate is None) or (self.rdate == ""): - rdate_obj = Time(np.floor(self.time_array[0]), format="jd", scale="utc") - else: - try: - rdate_obj = Time(self.rdate, scale="utc") - except ValueError: - rdate_obj = Time(np.floor(self.time_array[0]), format="jd", scale="utc") - - if self.rdate is None: - ant_hdu.header["RDATE"] = rdate_obj.strftime("%Y-%m-%d") + ant_hdu.header["RDATE"] = obs_date0.strftime("%Y-%m-%d") else: ant_hdu.header["RDATE"] = self.rdate + # GSTIA0: Greenwich sidereal time in degrees at zero hours on RDATE if self.gst0 is None: - ant_hdu.header["GSTIA0"] = rdate_obj.sidereal_time("apparent", "tio").deg + ant_hdu.header["GSTIA0"] = obs_date0.sidereal_time("apparent", "tio").deg else: ant_hdu.header["GSTIA0"] = self.gst0 + # UT1UTC: the difference between UT1 and UTC in seconds on RDATE if self.dut1 is None: - ant_hdu.header["UT1UTC"] = float(rdate_obj.delta_ut1_utc) + ant_hdu.header["UT1UTC"] = float(obs_date0.delta_ut1_utc) else: ant_hdu.header["UT1UTC"] = self.dut1 From 316a5cfef8bdada9eebd38757423918bd36714ad Mon Sep 17 00:00:00 2001 From: Danny Price Date: Fri, 3 May 2024 09:58:10 +0800 Subject: [PATCH 2/3] Adding EarthLocation to obs_date0 Time --- pyuvdata/uvdata/uvfits.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pyuvdata/uvdata/uvfits.py b/pyuvdata/uvdata/uvfits.py index 73ce72ede5..7acac55b18 100644 --- a/pyuvdata/uvdata/uvfits.py +++ b/pyuvdata/uvdata/uvfits.py @@ -11,6 +11,7 @@ from astropy import constants as const from astropy.io import fits from astropy.time import Time +from astropy.coordinates import EarthLocation from docstring_parser import DocstringStyle from .. import utils as uvutils @@ -1160,7 +1161,12 @@ def write_uvfits( # Create an astropy.time.Time object from first timestamp. # This is used to generate DATE-OBS and RDATE keywords - obs_date0 = Time(self.time_array[0], format="jd", scale="utc", location=self.location) + eloc = EarthLocation(self.telescope_location[0], + self.telescope_location[1], + self.telescope_location[2], + unit='m' + ) + obs_date0 = Time(self.time_array[0], format="jd", scale="utc", location=eloc) # Per AIPS memo 117, DATE-OBS is the YYYY-MM-DD string hdu.header["DATE-OBS"] = obs_date0.strftime("%Y-%m-%d") From 1f80f9cc5cfc383ee4ff8140e88fdce48e943790 Mon Sep 17 00:00:00 2001 From: Danny Price Date: Fri, 3 May 2024 09:59:29 +0800 Subject: [PATCH 3/3] Appeasing linter gods --- pyuvdata/uvdata/uvfits.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/pyuvdata/uvdata/uvfits.py b/pyuvdata/uvdata/uvfits.py index 7acac55b18..ea20ef9f88 100644 --- a/pyuvdata/uvdata/uvfits.py +++ b/pyuvdata/uvdata/uvfits.py @@ -60,9 +60,11 @@ def _get_parameter_data( # angles in uvfits files are stored in degrees, so convert to radians self.lst_array = np.deg2rad(vis_hdu.data.par("lst")) if run_check_acceptability: - (latitude, longitude, altitude) = ( - self.telescope_location_lat_lon_alt_degrees - ) + ( + latitude, + longitude, + altitude, + ) = self.telescope_location_lat_lon_alt_degrees uvutils.check_lsts_against_times( jd_array=self.time_array, lst_array=self.lst_array, @@ -1161,11 +1163,12 @@ def write_uvfits( # Create an astropy.time.Time object from first timestamp. # This is used to generate DATE-OBS and RDATE keywords - eloc = EarthLocation(self.telescope_location[0], - self.telescope_location[1], - self.telescope_location[2], - unit='m' - ) + eloc = EarthLocation( + self.telescope_location[0], + self.telescope_location[1], + self.telescope_location[2], + unit="m", + ) obs_date0 = Time(self.time_array[0], format="jd", scale="utc", location=eloc) # Per AIPS memo 117, DATE-OBS is the YYYY-MM-DD string