Skip to content

Wrap fitcircle - #1550

Open
willschlitzer wants to merge 40 commits into
mainfrom
wrap/fitcircle
Open

Wrap fitcircle#1550
willschlitzer wants to merge 40 commits into
mainfrom
wrap/fitcircle

Conversation

@willschlitzer

@willschlitzer willschlitzer commented Sep 29, 2021

Copy link
Copy Markdown
Contributor

This pull request wraps the module fitcircle.

Preview at https://pygmt-dev--1550.org.readthedocs.build/en/1550/api/generated/pygmt.fitcircle.html

Reminders

  • Run make format and make check to make sure the code follows the style guide.
  • Add tests for new features or tests that would have caught the bug that you're fixing.
  • Add new public functions/methods/classes to doc/api/index.rst.
  • Write detailed docstrings for all functions/methods.
  • If adding new functionality, add an example to docstrings or tutorials.

Slash Commands

You can write slash commands (/command) in the first line of a comment to perform
specific operations. Supported slash commands are:

  • /format: automatically format and lint the code
  • /test-gmt-dev: run full tests on the latest GMT development version

@willschlitzer willschlitzer added the feature Brand new feature label Sep 29, 2021
@willschlitzer willschlitzer added this to the 0.5.0 milestone Sep 29, 2021
@willschlitzer willschlitzer self-assigned this Sep 29, 2021
@willschlitzer willschlitzer modified the milestones: 0.5.0, 0.6.0 Oct 7, 2021
@willschlitzer
willschlitzer marked this pull request as ready for review January 14, 2022 00:40
@weiji14 weiji14 removed this from the 0.6.0 milestone Mar 13, 2022
@willschlitzer willschlitzer changed the title Wrap fitcircle WIP: Wrap fitcircle Dec 1, 2022
@seisman
seisman marked this pull request as draft December 2, 2022 00:46
@willschlitzer

Copy link
Copy Markdown
Contributor Author

I don't think I'm able to come up with a good way to format the output; I'm going to close this PR for the time being. If anyone has a solution please feel free to reopen it!

@seisman

seisman commented Dec 9, 2022

Copy link
Copy Markdown
Member

I'm reopening the issue so it's more visible to people who'd like to help.

@seisman seisman reopened this Dec 9, 2022
@seisman seisman modified the milestones: 0.8.0, 0.9.0 Dec 11, 2022
@willschlitzer willschlitzer removed their assignment Feb 2, 2023
@weiji14 weiji14 removed this from the 0.9.0 milestone Mar 6, 2023
@seisman seisman added this to the 0.12.0 milestone Dec 11, 2023
@seisman seisman removed this from the 0.12.0 milestone Feb 26, 2024
@willschlitzer willschlitzer changed the title WIP: Wrap fitcircle Wrap fitcircle Aug 2, 2026
@willschlitzer willschlitzer self-assigned this Aug 2, 2026
@willschlitzer willschlitzer added this to the 0.20.0 milestone Aug 2, 2026
@willschlitzer
willschlitzer marked this pull request as ready for review August 2, 2026 02:12
"""
Load the sample data from the @sat_03 remote file.
"""
fname = which("@sat_03.txt", download="c")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This @sat_03.txt file will need to be added to the cache list at https://github.com/GenericMappingTools/pygmt/blob/v0.19.0/pygmt/helpers/caching.py

Comment thread pygmt/src/fitcircle.py
return lib.virtualfile_to_dataset(
vfname=vouttbl,
output_type=output_type,
column_names=["longitude", "latitude", "method"],

@weiji14 weiji14 Aug 2, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These output columns might change depending on whether -L/norm=1/2 or -L/norm=3/True ? Could we do something like:

column_names=["longitude", "latitude", "method"] if kwargs.get("L") in {1, 2} else ["longitude_l1", "latitude_l1", "longitude_l2", "latitude_l2"],

or whatever column names make sense for norm=3.

Alternatively, we can just disable the ability to output to pandas format for norm=3/norm=True if it gets too complicated.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to disable the pandas format for norm=3/True, as that seemed more straightforward.

Comment thread pygmt/src/fitcircle.py Outdated
Comment thread pygmt/src/fitcircle.py Outdated
S="small_circle",
)
def fitcircle(
data: PathLike | TableLike,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should support parameters x/y, too.

Comment thread pygmt/src/fitcircle.py Outdated
$table_classes.
$output_type
$outfile
norm : int or bool

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1, 2, 3 are not readable arguments. GMT recommends absolutes/squares/both instead.

https://github.com/GenericMappingTools/gmt/blob/d52a1e5825b73c3ad6948efce1ac8eeff01c2c93/src/longopt/fitcircle_inc.h#L32-33

As for the parameter, GMT supports norm and solution, while GMT.jl uses norm (https://www.generic-mapping-tools.org/GMTjl_doc/documentation/modules/fitcircle.html).

@seisman seisman added the needs review This PR has higher priority and needs review. label Aug 4, 2026
@seisman

seisman commented Aug 6, 2026

Copy link
Copy Markdown
Member

@willschlitzer Could you please an issue for tracking this module, using the template at https://github.com/GenericMappingTools/pygmt/blob/main/.github/ISSUE_TEMPLATE/3-module_request.md

@willschlitzer

Copy link
Copy Markdown
Contributor Author

@willschlitzer Could you please an issue for tracking this module, using the template at https://github.com/GenericMappingTools/pygmt/blob/main/.github/ISSUE_TEMPLATE/3-module_request.md

@seisman Done in #4821

@seisman

seisman commented Aug 12, 2026

Copy link
Copy Markdown
Member

fitcircle has three important options:

  • -L: select the averaging method
  • -S: output small circle pole or not
  • -M: controls the output of columns

Their combinations can lead to quite different output formats, as shown below:

$ gmt fitcircle @sat_03.txt -L1
330.249933144   -18.4048179232  Points read: 703 Average Position (Flat Earth)
330.16910976    -18.4206421065  L1 Average Position (Fisher's Method)
52.7435567383   21.2080711967   L1 N Hemisphere Great Circle Pole (Cross-Averaged)
232.743556738   -21.2080711967  L1 S Hemisphere Great Circle Pole (Cross-Averaged)
$ gmt fitcircle @sat_03.txt -L2
330.249933144   -18.4048179232  Points read: 703 Average Position (Flat Earth)
330.169184777   -18.4206532702  L2 Average Position (Eigenval Method)
52.7451972868   21.2040074195   L2 N Hemisphere Great Circle Pole (Eigenval Method)
232.745197287   -21.2040074195  L2 S Hemisphere Great Circle Pole (Eigenval Method)
$ gmt fitcircle @sat_03.txt -L3
330.249933144   -18.4048179232  Points read: 703 Average Position (Flat Earth)
330.16910976    -18.4206421065  L1 Average Position (Fisher's Method)
52.7435567383   21.2080711967   L1 N Hemisphere Great Circle Pole (Cross-Averaged)
232.743556738   -21.2080711967  L1 S Hemisphere Great Circle Pole (Cross-Averaged)
330.169184777   -18.4206532702  L2 Average Position (Eigenval Method)
52.7451972868   21.2040074195   L2 N Hemisphere Great Circle Pole (Eigenval Method)
232.745197287   -21.2040074195  L2 S Hemisphere Great Circle Pole (Eigenval Method)
$ gmt fitcircle @sat_03.txt -L3 -S
330.249933144   -18.4048179232  Points read: 703 Average Position (Flat Earth)
330.16910976    -18.4206421065  L1 Average Position (Fisher's Method)
52.7435567383   21.2080711967   L1 N Hemisphere Great Circle Pole (Cross-Averaged)
232.743556738   -21.2080711967  L1 S Hemisphere Great Circle Pole (Cross-Averaged)
235.188595579   -22.0070525722  L1 Small Circle Pole. Distance from Pole to L1 Small Circle (degrees): 87.6019637313
330.169184777   -18.4206532702  L2 Average Position (Eigenval Method)
52.7451972868   21.2040074195   L2 N Hemisphere Great Circle Pole (Eigenval Method)
232.745197287   -21.2040074195  L2 S Hemisphere Great Circle Pole (Eigenval Method)
235.184676903   -22.0012240239  L2 Small Circle Pole.  Distance from Pole to L2 Small Circle (degrees): 87.6073161087
$ gmt fitcircle @sat_03.txt -L3 -F
330.249933144   -18.4048179232  330.16910976    -18.4206421065  52.7435567383   21.2080711967   232.743556738   -21.2080711967     330.169184777   -18.4206532702  52.7451972868   21.2040074195   232.745197287   -21.2040074195
$ gmt fitcircle @sat_03.txt -L3 -Ffmnsc -S
330.249933144   -18.4048179232  330.16910976    -18.4206421065  52.7435567383   21.2080711967   232.743556738   -21.2080711967     235.188595579   -22.0070525722  87.6019637313   330.169184777   -18.4206532702  52.7451972868   21.2040074195      232.745197287   -21.2040074195  235.184676903   -22.0012240239  87.6073161087
$ gmt fitcircle @sat_03.txt -L3 -Ff
330.249933144   -18.4048179232

The current implementation always returns a pandas.DataFrame object, which is not Pythonic, and also makes it difficult to implement the -F option later.

As mentioned in #1550 (comment), I propose

  1. return a dictionary of tuples instead. The dictionary will look like the following for -L1/-L2:
solution = fitcircle(data="@sat_03.txt", norm=1)
>>> print(solution)
{
    "flat_mean": (330.249933144, -18.4048179232),
    "mean": (330.16910976, -18.4206421065),
    "north_pole": (52.7435567383, 21.2080711967),
    "south_pole": (232.743556738, -21.2080711967),
}
  1. Anyone who wants both (i.e., -L3) should call pygmt.fitcircle twice.
  2. When -S is used, the output can be:
{
    "flat_mean": (330.249933144, -18.4048179232),
    "mean": (330.16910976, -18.4206421065),
    "north_pole": (52.7435567383, 21.2080711967),
    "south_pole": (232.743556738, -21.2080711967),
    "small_circle_pole": (235.188595579, -22.0070525722),
    "small_circle_distance": 87.6019637313,
}
  1. No need to implement the -F option, as the information is already in the dict. Anyone who wants the multi-column output can convert the dictionary manually.

Internally, we can just call fitcircle with -F and then extract the information to build the output dictionary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Brand new feature needs review This PR has higher priority and needs review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants