astropy / astropy/astropy

Interesting path from GCRS to Alt/Az

Open
#19,028 1 comment 0 reactions 0 assignees View on GitHub
coordinates Performance
Dominant language
Python
Stars
5.3k
Forks
2.2k
Avg merge
1d 20h
Merged PRs (30d)
81

Description

### Description

Hi, I'm new to contributing here, and may not have all the context, feel free to close if this is an ongoing topic of discussion that I missed.

I have a purpose for converting GCRS state vectors to Az/El, and was looking to see what exactly AstroPy would do in this situation. Looking at the frame transform graph yields the following

``` python
>>> from astropy.coordinates import frame_transform_graph
>>> from astropy.coordinates import GCRS, AltAz
>>> frame_transform_graph.find_shortest_path(GCRS, AltAz)
([, , ], 2.0)
```

As far as I can tell, there's no shorter path than 2 hops, so this would check out, if only a little suspect because I can't see there being a reason to transfer to a solar system barycentric system, and I suppose it's possible that this could exacerbate floating point precision errors. Upon a little bit more inspection though, this gets somewhat suspect:

* GCRS -> ICRS: Changes the barycenter to the solar system center (NOTE: unrelated and there may be a totally reasonable explanation for this, but this uses a CIRS -> ICRS erfa function (`aticq`) instead of a GCRS -> ICRS function)
* ICRS -> AltAz: Converts angles first to topocentric CIRS (`atciqz`), and then to observed frame (`atioq`).

What's implicit here (traceable, I think to https://github.com/astropy/astropy/issues/10887, which implements the ICRS -> AltAz) is that this is sneakily a 3 hop transform, because the ICRS -> AltAz converts to an intermediate CIRS.

### Expected behavior

I think it would make more sense if the shortest path algorithm instead resolved to `GCRS -> CIRS -> AltAz`. I can just do that manually, so it's not a huge problem for me, but it seems suboptimal in the default case

### How to Reproduce

```python
>>> from astropy.coordinates import frame_transform_graph
>>> from astropy.coordinates import GCRS, AltAz
>>> frame_transform_graph.find_shortest_path(GCRS, AltAz)
([, , ], 2.0)
```

### Versions

```python
import astropy
astropy.system_info()
```
```
platform
--------
platform.platform() = 'macOS-15.6.1-arm64-arm-64bit-Mach-O'
platform.version() = 'Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:40 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6041'
platform.python_version() = '3.13.7'

packages
--------
astropy 7.1.1
numpy 2.3.4
scipy 1.16.3
matplotlib 3.10.7
pandas 2.3.3
pyerfa 2.0.1.5
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the frame_transform_graph.find_shortest_path(GCRS, AltAz) result and trace the GCRS, ICRS, CIRS, and AltAz transformations, including the aticq, atciqz, and atioq calls mentioned. Review the transform introduced in issue #10887 and identify the relevant registration or implementation entry points. Done should include a tested shortest path that appropriately handles the GCRS-to-AltAz conversion.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.