Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(tracker): add rotation calculations #232

Draft
wants to merge 52 commits into
base: main
Choose a base branch
from

Conversation

hollandjg
Copy link
Collaborator

@hollandjg hollandjg commented Mar 12, 2025

Add support for calculating rotations based on tracked floes.

Input format:

Example: floes.tracked.satellite.csv
Columns required:

  • floe ID
  • satellite name
  • mask – the binary mask
  • overpass time in ISO8601 format (with trailing Z or +00:00), e.g. 2022-09-11T09:21:00+00:00
  • date in YYYY-MM-DD format

Output format:

Example: floes.tracked.satellite.rotation.csv
One row per floe comparison. Measurements i: i=1 is the earlier, i=2 is the later.

Columns returned:

  • ID of the floe
  • Angle measures:
    • theta_deg – angle between floe image in degrees
    • theta_rad – angle between floe image in radians
  • Time measurements:
    • dt_sec – number of seconds between overpass in the two measurements
    • omega_<deg,rad>_per_<sec,hour,day> – mean angular velocity of rotation in degrees or radians per second hour or day.
  • Metadata
    • satellite<i> – which satellite measurement i was from
    • date<i> – which date measurement i was taken
    • datetime<i> – which UTC time measurement i's overpass occurred
  • Original data
    • mask<i> – the binary mask used for the measurement

Example:

"ID","theta_deg","theta_rad","dt_sec","omega_deg_per_sec","omega_deg_per_hour","omega_deg_per_day","omega_rad_per_sec","omega_rad_per_hour","omega_rad_per_day","satellite1","satellite2","date1","date2","datetime1","datetime2","mask1","mask2"
1,1.072809162243001,0.0187240521267024,83080.0,1.2912965361615322e-5,0.046486675301815154,1.1156802072435636,2.2537376175616754e-7,0.0008113455423222031,0.019472293015732875,"aqua","aqua",2022-09-11,2022-09-12,2022-09-11T09:21:00+00:00,2022-09-12T08:25:40+00:00,Bool[0 0 0 0 0 0 0 0 0...
1,1.0223826030170984,0.01784394263775848,88954.0,1.1493385379152128e-5,0.041376187364947664,0.9930284967587438,2.0059741706678146e-7,0.0007221507014404133,0.017331616834569918,"aqua","aqua",2022-09-12,2022-09-13,2022-09-12T08:25:40+00:00,2022-09-13T09:08:14+00:00,Bool[0 0 0 0 0 0 0 0...
2,21.98895362526594,0.383779639829234,88971.0,0.00024714742584961325,0.8897307330586076,21.353537593406582,4.313536318904295e-6,0.01552873074805546,0.37268953795333104,"terra","terra",2022-09-10,2022-09-11,2022-09-10T11:49:22+00:00,2022-09-11T12:32:13+00:00,Bool[0 0 0 0 0 0 0 0 0 0 0...
3,1.4746356413379618,0.025737247208605634,88968.0,1.6574899304670914e-5,0.05966963749681528,1.432071299923567,2.8928656605302617e-7,0.0010414316377908943,0.024994359306981462,"terra","terra",2022-09-11,2022-09-12,2022-09-11T12:32:13+00:00,2022-09-12T13:15:01+00:00,Bool[0 0 0 1 1 1 0...
4,43.85519582087611,0.7654175611811456,88954.0,0.0004930098232892969,1.7748353638414687,42.59604873219525,8.604644661073651e-6,0.030976720779865144,0.7434412987167635,"aqua","aqua",2022-09-12,2022-09-13,2022-09-12T08:25:40+00:00,2022-09-13T09:08:14+00:00,Bool[0 0 0 0 0 0 0 0 0 0 0 0...
4,26.595714399934263,0.46418278319892087,100468.0,0.00026471826253069894,0.9529857451105163,22.87165788265239,4.6202052713194335e-6,0.016632738976749963,0.3991857354419991,"aqua","terra",2022-09-13,2022-09-14,2022-09-13T09:08:14+00:00,2022-09-14T13:02:42+00:00,Bool[0 0 0 0 0 0 0 0 0...
5,0.15628109569439388,0.002727619678491507,83080.0,1.8810916670004079e-6,0.0067719300012014675,0.16252632002883524,3.2831243120985884e-8,0.00011819247523554916,0.00283661940565318,"aqua","aqua",2022-09-11,2022-09-12,2022-09-11T09:21:00+00:00,2022-09-12T08:25:40+00:00,Bool[0 0 0 0 0 0...

Limitations

Testing of the rotation detection function (shown in test-rotation.jl) shows that the rotation measurements aren't very stable, and often aren't very good.

Even when given the same "floe" with an unambiguous orientation, the qd_rigid will often calculate a best fit rotation which is π radians.

Copy link
Member

@cpaniaguam cpaniaguam left a comment

Choose a reason for hiding this comment

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

Couple suggestions.

Copy link
Collaborator Author

@hollandjg hollandjg left a comment

Choose a reason for hiding this comment

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

Some feedback...

@hollandjg hollandjg requested a review from cpaniaguam March 13, 2025 19:06
@hollandjg
Copy link
Collaborator Author

@danielmwatkins @cpaniaguam I think the function RegisterQD.qd_rigid is causing us too serious problems to merge this PR. It'll need someone to take a look at the parameters and decide what to do.

In the tracker it's restricted to allow rotations only up to ±π/4 rad (±45º), but as we talked about last week, you might want to have rotations which are beyond that in some cases.

I added some testcases with rotations of rectangles and a couple of variations on a "hammer" shape all around the circle. These require that we allow full rotations ±π rad (±180º) so I loosened the maximum rotation in the version used in the IFTPipeline.jl package.

This works a lot of the time, but it's pretty unstable and will often return a rotation π away from the true value, even in cases like the hammer where the orientation of the object is completely unambiguous and where rotating by π makes the fit substantially worse. Increasing the image size doesn't make this problem go away.

The orientation and angular velocity measures will likely be impacted by this issue.

- `floe` ID
- `satellite` name
- `mask` – the binary mask (choose a column using argument `mask_column`)
- `passtime` in ISO8601 format (with trailing Z or +00:00), e.g. 2022-09-11T09:21:00+00:00 (choose a column using argument `time_column`)
Copy link
Collaborator

Choose a reason for hiding this comment

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

How does it handle it if the pass time doesn't have the Z? Perhaps assuming UTC and raising a warning would be appropriate.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If the pass time doesn't have the Z or an explicit time zone, right now it should throw an error.

I think assuming UTC would be sensible, but right now the mechanism it's using to parse the values doesn't have an easy way to add that as a fallback. Could we add that as an issue and tackle it later?

@danielmwatkins
Copy link
Collaborator

danielmwatkins commented Mar 18, 2025 via email

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.

3 participants