RadioAstronomySoftwareGroup / pyuvsim

A ultra-high precision package for simulating radio interferometers in python on compute clusters.
https://pyuvsim.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
43 stars 7 forks source link

uvw errors for non-terrestrial telescopes? #408

Closed jpober closed 4 months ago

jpober commented 2 years ago

In our telecon the other day, we looked at the calculation of uvw's (which eventually go into the visibility calculation) for telescopes on the moon. When initializing from a parameter file, the UVData method set_uvws_from_antenna_positions gets called, which I thought we decided calls code from utils.pyx (i.e. cython code) where gps parameters about the Earth curvature and such are hardcoded. Taking another look, neither @aelanman nor I couldn't find where that method called the cython code. @mkolopanis Can you remember where the issue was? Am I misremembering which method called the cython with hardcoded earth parameters?

mkolopanis commented 2 years ago

functions which depend on the hardcoded GPS constants are the _lla_to/from_xyz conversions https://github.com/RadioAstronomySoftwareGroup/pyuvdata/blob/119315929ed698ac735bacd868612c082be61a23/pyuvdata/utils.pyx#L213

so anything in pyuvdata that needs LatLonAlt_from_XYZ or XYZ_from_LatLonAlt depends on them. which includes things like get_enu_antpos and the ECEF -> ENU conversion functions

jpober commented 2 years ago

Ok, so maybe I was wrong that it was the set_uvws_from_antenna_positions method in particular. But it looks like parse_telescope_params on line 1220 of simsetup.py runs: tele_params['telescope_location'] = uvutils.XYZ_from_LatLonAlt(*telescope_location) So that is likely an issue. Not sure if it's the only one...

aelanman commented 2 years ago

Oh, that's subtle... pyuvsim.simsetup sets the XYZ assuming the Lat/Lon/Alt are on Earth, and then SkyModel uses the XYZ position as selenocentric coordinates.

A quick way to check if that's what's happening is to look at the telescope_location in the output file and see if the position vector is roughly an Earth radius vs. a Moon radius.

jpober commented 2 years ago

I can't say for certain, but my guess is the output location is an Earth radius like location. I say that because I believe pyuvdata has a check that the radius is "sensible" and we don't fail that check. But we can look to be sure.

jpober commented 2 years ago

After an initial conversation with @aelanman this morning, we decided there are two issues, one easier to fix than the other:

(1) line 1220 in simsetup sets the telescope location (that will be attached to the UVData object) as ECEF even when presented with a lunar lat/lon/height. To fix, we should check the world and if it's the Moon, call the MoonLocation.from_selenocentric method to set the XYZ coordinates on the UVData object. (Whether we want to call the method from the object or turn the last couple lines of code in that method into a standalone function in LunarSky is debatable.) This fix will also likely trigger a check in pyuvdata about the distance from the center of the earth to fail.

(2) line 1258 in simsetup calculates the antenna positions in ECEF. It then subtracts off the telescope location, which may offset this error. However, once issue (1) is fixed, this will definitely be an error. To fix, we need to calculate the telescope locations used the LunarTopo transform lunartopo_to_mcmf. As written, LunarTopo objects are initialized in an alt/az like coordinate system, but in principle can be represented in an ENU coordinate system. @aelanman may need to make some changes to LunarSky to enable this transformation to proceed as we need it to.

aelanman commented 2 years ago

I've started working to address this (see branch fixing_lunar_pos). Making the replacement to correct (1) did cause errors in the pyuvdata acceptability checks. I've disabled the check for now. I made a change to fix (2) as well, but that's causing a failure in pyuvdata because it's using ENU_from_ECEF to reverse the transformation I'm doing here (and so not liking that the vectors aren't Earth-radius in scale). It may be possible to fix that using utils.py:calc_uvws directly.

Overall, it seems like these issues can be resolved quickly with some patches to pyuvsim, but long-term it would make more sense to properly incorporate support for MCMF and LunarTopo frames in pyuvdata directly using the telescope_frame parameter (as I think was the idea in the pyuvdata slack).