Skip to content

Add reference frames (OPT, NNR, TPW, PMAG) to un-optimised rotation files#3

Open
jcannon-gplates wants to merge 7 commits into
masterfrom
add-ref-frames-to-unoptimised
Open

Add reference frames (OPT, NNR, TPW, PMAG) to un-optimised rotation files#3
jcannon-gplates wants to merge 7 commits into
masterfrom
add-ref-frames-to-unoptimised

Conversation

@jcannon-gplates

@jcannon-gplates jcannon-gplates commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds add_ref_frames_to_unoptimised.py, a post-processing step that assembles a
single comprehensive rotation model containing all available absolute reference frames
as distinct (high-numbered) plate IDs:

Plate ID Reference frame
014 paleomag (the model's native frame)
015 optimised mantle (best run)
016 optimised mantle, maximum net rotation (nr_max run)
017 no-net rotation
018 approx true polar wander (TPW = pmag − optimised)

Anchoring to any of 014–018 in GPlates/pyGPlates reconstructs the model in that
reference frame; anchoring 000 uses whichever frame default_reference_frame_plate_id
is set to (paleomag by default). Reference-frame features are bundled into the first
output rotation file so plate 000 is always defined.

Key implementation details:

  • All input/output paths are derived automatically from Optimised_config.py — the
    script needs no manual editing for a standard run.
  • An unoptimised_input_is_in_pmag_frame guard aborts rather than silently
    mislabelling reference frames if the input is not in its paleomagnetic frame.
  • Rotation sequences stored as R(000→frame) (fixed 000, moving frame) so GPlates
    does not see conflicting sequences with 000 as the moving plate.
  • Adds config support for Merdith_etal_plate_model_1Ga-present_rev6-2 and fixes
    Zahirovic_etal_2022_GDJ (PMAG seeding via Africa 701701 / GAPWAP, corrected file
    paths).
  • README rewritten to reflect current capabilities (laptop runtime, GPlately PMM,
    5 reference frames, updated installation and run instructions).

🤖 Generated with Claude Code

@jcannon-gplates jcannon-gplates self-assigned this Jun 25, 2026
@jcannon-gplates jcannon-gplates force-pushed the add-ref-frames-to-unoptimised branch from a92a6c0 to 4e86bf4 Compare June 26, 2026 14:03
jcannon-gplates and others added 7 commits June 29, 2026 12:46
This adds an extra file containing the reference frames, including
optimised mantle (6), no-net rotation (7) and an approximation to true
polar wander (8) which is paleomag minus optimised mantle reference
frames. Plate ID 0 gives the original un-optimised reference frame.
- Changed plate IDs of OPT, NNR and TPW from 6, 7, 8 to 15, 16, 17 to
  reduce potential conflict with existing IDs (eg, hotspots).
- Added plate ID  014 for PMAG.
- Output rotation files match input files except 000 is changed to 014.
- We still keep reference frames (14, 15, 16, 17) in extra file.
- Can specify default 000 to be equivalent to any reference frame.
Because paleomag includes a mantle reference frame and true polar
wander (PMAG=OPT+TPW). We were using the old 005-000 which is OPT-PMAG.
You can’t have 000-015, 000-016, 000-017 rotation sequences
(ie, with 000 as a shared moving plate) since they’ll overlap in time
(which GPlates complains about). This was causing issues when anchoring
to 015 and 016 (but 017 was fine).
Instead of in a separate 'reference_frames<suffix>.rot' file.
Otherwise users might have thought they could exclude it if they didn't
want the reference frames because only using 000 (but 000 is part of
the reference frames and so always needed inclusion).
No longer really need a supplementary directory.
…to_unoptimised.py, and add optimised_max_NNR frame (016).

- Optimised_config.py: add Merdith_etal_plate_model_1Ga-present_rev6-2
  (rotation file, topologies, continental polygons, diagnostics) and fix
  Zahirovic_etal_2022_GDJ continental polygons path and reference params
  (seeds from paleomagnetic pole via Africa 701701 / GAPWAP).

- add_ref_frames_to_unoptimised.py: refactor to read all input/output paths
  from Optimised_config.py automatically (no manual editing required); add
  optimised_max_NNR reference frame (plate ID 016, from the nr_max run),
  shifting NNR to 017 and TPW to 018; add unoptimised_input_is_in_pmag_frame
  guard that aborts rather than silently mislabelling frames; extract helper
  functions for the frame calculations; add a module docstring.

- README.md: rewrite to reflect current capabilities (laptop runtime,
  GPlately PMM, 5 reference frames, updated installation and running
  instructions).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jcannon-gplates jcannon-gplates force-pushed the add-ref-frames-to-unoptimised branch from 4e86bf4 to 50c8b0b Compare June 29, 2026 02:46
@jcannon-gplates jcannon-gplates marked this pull request as ready for review June 29, 2026 02:53
@jcannon-gplates

Copy link
Copy Markdown
Contributor Author

Gosh, Dietmar's Claude modifications re-arranged my add_ref_frames_to_unoptimised.py script so much (including re-arranging the reference frame math) that I genuinely got confused. But I'm reasonably sure the math is still correct (eg, TPW). Not 100% sure though.

How does it re-arrange so much and still get it right! Claude probably did this in a few minutes, but it's taken me many hours to convince myself it's correct (partly because I had to reload all the work I'd done a year ago back into my mind in order to check this).

The new code is actually cleaner and better. It's just hard to compare and verify. In situations like this (and probably for any optAPM modifications) I think we need to tell Claude not to restructure source code and rotation math so much. I googled and found this:

CRITICAL: MATHEMATICAL & STRUCTURAL LAYOUT PINNING
1. PRESERVE MATH LOGIC VERBATIM: Do not alter, re-factor, or re-arrange any mathematical equations, formula sequences, or rotation logic (e.g., matrix/quaternion/trig operations). Keep the operators, variable assignments, and sequence of steps exactly as written.
2. NO CODE RE-STRUCTURING: Do not collapse, expand, or split existing blocks of logic. Treat the current script structure as immutable.
3. LINE-MATCHING EDITS ONLY: Only modify the specific lines of code required for the new feature. Do not touch adjacent structural logic "for cleanup."
4. NO INLINING: Do not inline local variables or expand existing multi-line calculations into single lines.

...probably easiest to just add directly to the chat prompt (a more permanent solution depends on whether using Claude Code or Claude Projects; eg, CLAUDE.md or custom instructions).

Also, Dietmar has been trying this out on some plate models, so would probably notice when anchoring different reference frames looks weird. So I'll go ahead and merge this. If something looks suspect in the future we can come back and revisit this.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant