Interactive model-pressure showcase and architecture-only Trackformer 1.2 paper
Browse files- .gitattributes +3 -0
- README.md +12 -0
- RELEASE_NOTES_TRACKFORMER_1_2.md +2 -0
- docs/trackformer_1_2_evaluation.md +8 -0
- docs/trackformer_1_2_pressure.html +0 -0
- paper/release_data/pressure_showcase.json +28 -0
- paper/release_data/pressure_showcase.npz +3 -0
- paper/release_data/pressure_showcase_coastlines.json +1 -0
- paper/trackformer.pdf +3 -0
- paper/trackformer.tex +270 -0
- paper/trackformer_1_1_legacy.tex +224 -0
- paper/trackformer_1_2_interactive_pressure_preview.png +3 -0
- release_tools/build_pressure_showcase.py +112 -0
- release_tools/pressure_showcase_template.html +42 -0
.gitattributes
CHANGED
|
@@ -9,3 +9,6 @@ paper/release_data/surigae_pressure.npz filter=lfs diff=lfs merge=lfs -text
|
|
| 9 |
paper/trackformer_1_2_surigae_isobars.png filter=lfs diff=lfs merge=lfs -text
|
| 10 |
paper/trackformer_1_2_vs_1_1_270_bars.png filter=lfs diff=lfs merge=lfs -text
|
| 11 |
paper/trackformer_1_2_vs_1_1_route_examples.png filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
paper/trackformer_1_2_surigae_isobars.png filter=lfs diff=lfs merge=lfs -text
|
| 10 |
paper/trackformer_1_2_vs_1_1_270_bars.png filter=lfs diff=lfs merge=lfs -text
|
| 11 |
paper/trackformer_1_2_vs_1_1_route_examples.png filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
paper/release_data/pressure_showcase.npz filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
paper/trackformer.pdf filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
paper/trackformer_1_2_interactive_pressure_preview.png filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
|
@@ -65,6 +65,18 @@ The 1.2 mean has better aggregate direction, shape and position scores on this p
|
|
| 65 |
|
| 66 |
A new **1,473-case / 270-storm** benchmark is in progress; it is not the completed 270-case result above. Each storm contributes at most one forecast per UTC day, through +120 h. Daily errors are averaged within each storm, then the 270 storm scores receive equal weight. Selection was frozen before new inference, without filtering on forecast quality. See the [protocol](docs/daily_storm_benchmark.md) and [frozen cohort](paper/release_data/daily_storm_cohort.json). Results are pending; no improvement is claimed from the partial run.
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
## Recent pressure forecast with isobars
|
| 69 |
|
| 70 |
The archived **Surigae forecast issued 27 September 2026 at 12:00 UTC** shows the model's regional pressure field at +6, +24 and +36 h. Thin lines are isobars every **4 hPa**, with selected labels every 12 hPa; magenta shows the forecast track and centre. Coastlines provide geographic context. These panels use the actual saved model values.
|
|
|
|
| 65 |
|
| 66 |
A new **1,473-case / 270-storm** benchmark is in progress; it is not the completed 270-case result above. Each storm contributes at most one forecast per UTC day, through +120 h. Daily errors are averaged within each storm, then the 270 storm scores receive equal weight. Selection was frozen before new inference, without filtering on forecast quality. See the [protocol](docs/daily_storm_benchmark.md) and [frozen cohort](paper/release_data/daily_storm_cohort.json). Results are pending; no improvement is claimed from the partial run.
|
| 67 |
|
| 68 |
+
## Interactive forecast pressure and observed route
|
| 69 |
+
|
| 70 |
+
**[Open the interactive 1.2 pressure map](https://yu314-coder.github.io/typhoon-predict/trackformer_1_2_pressure.html)** — play or scrub from +6 to +120 h, toggle forecast/observed routes, and hover or tap to inspect pressure and position. Click the preview below to open it. GitHub and Hugging Face Markdown cannot execute the interactive controls inside the README itself.
|
| 71 |
+
|
| 72 |
+
[](https://yu314-coder.github.io/typhoon-predict/trackformer_1_2_pressure.html)
|
| 73 |
+
|
| 74 |
+
This **PRAPIROON forecast issued 19 July 2024 at 00 UTC** uses the actual saved **50-member mean physical pressure field**, member-mean route and central pressure. The observed route uses exact six-hour best-track coordinates from the verification archive. It is the lowest-track-error case among the declared full-map-coverage and pressure-quality candidates: 133.2 km saved-benchmark mean track error and 2.91 hPa central-pressure MAE. This is a deliberately selected showcase, not typical performance or an unbiased evaluation. The [data and selection manifest](paper/release_data/pressure_showcase.json) explains the choice. The mean map has not been moved to match the observed track.
|
| 75 |
+
|
| 76 |
+
### Architecture-only paper
|
| 77 |
+
|
| 78 |
+
The revised **[Trackformer 1.2 technical paper (PDF)](paper/trackformer.pdf)** describes only the detailed architecture and how forecasts work: input tensors, multiscale attention, recurrent basin transport, moving pressure core, centre association, physical pressure reconstruction, objectives and 50-member means. [Editable LaTeX source](paper/trackformer.tex). Benchmark results remain separate in the evaluation notes; the previous 1.1 paper source is preserved as [a legacy document](paper/trackformer_1_1_legacy.tex).
|
| 79 |
+
|
| 80 |
## Recent pressure forecast with isobars
|
| 81 |
|
| 82 |
The archived **Surigae forecast issued 27 September 2026 at 12:00 UTC** shows the model's regional pressure field at +6, +24 and +36 h. Thin lines are isobars every **4 hPa**, with selected labels every 12 hPa; magenta shows the forecast track and centre. Coastlines provide geographic context. These panels use the actual saved model values.
|
RELEASE_NOTES_TRACKFORMER_1_2.md
CHANGED
|
@@ -8,6 +8,8 @@ On the 270-case development cohort, 1.1 versus 1.2 mean-of-50 scores are: direct
|
|
| 8 |
|
| 9 |
The route gallery now shows six explicitly selected best-performing examples from distinct storms, with the selection rule and all case scores supplied. It is not representative evidence; the aggregate bars retain all 270 cases. A separate larger benchmark has frozen **270 distinct storms / 1,473 daily issues**, with daily scores averaged per storm and storms weighted equally. Its forecasts are being computed; results are pending.
|
| 10 |
|
|
|
|
|
|
|
| 11 |
The Surigae illustration is a single forecast issued 2026-09-27 12 UTC, with 4 hPa isobars at +6/+24/+36 h. It is separate from the 50-member historical benchmark. Reproduction data and metric definitions are included. The model weights are unchanged in this documentation revision.
|
| 12 |
|
| 13 |
This is not an operational warning service. Do not use for safety-critical decisions. A genuinely untouched storm-level holdout is still required before generalization claims.
|
|
|
|
| 8 |
|
| 9 |
The route gallery now shows six explicitly selected best-performing examples from distinct storms, with the selection rule and all case scores supplied. It is not representative evidence; the aggregate bars retain all 270 cases. A separate larger benchmark has frozen **270 distinct storms / 1,473 daily issues**, with daily scores averaged per storm and storms weighted equally. Its forecasts are being computed; results are pending.
|
| 10 |
|
| 11 |
+
The README preview now links to an interactive PRAPIROON pressure/route showcase with playback, lead selection, hover details and observed-track overlays. It uses actual saved 50-member mean pressure fields and a disclosed selected-best rule. The main paper has been replaced with an architecture-only Trackformer 1.2 description; the 1.1 source is preserved separately.
|
| 12 |
+
|
| 13 |
The Surigae illustration is a single forecast issued 2026-09-27 12 UTC, with 4 hPa isobars at +6/+24/+36 h. It is separate from the 50-member historical benchmark. Reproduction data and metric definitions are included. The model weights are unchanged in this documentation revision.
|
| 14 |
|
| 15 |
This is not an operational warning service. Do not use for safety-critical decisions. A genuinely untouched storm-level holdout is still required before generalization claims.
|
docs/trackformer_1_2_evaluation.md
CHANGED
|
@@ -31,6 +31,14 @@ No same-270 1.1 central-pressure prediction array was verified in the route arti
|
|
| 31 |
|
| 32 |
## Recent pressure-line example
|
| 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
The Surigae archive issued **2026-09-27 12 UTC** supplies real model regional MSLP fields at +6, +24 and +36 h. Isobars are drawn every 4 hPa, with selected labels every 12 hPa and one common colour scale. The magenta curve is the saved model route. Fields are neither relocated nor altered to force the map minimum onto the route. The regional map is a resampled composite and can differ slightly from central pressure sampled in the moving core.
|
| 35 |
|
| 36 |
This example is one deterministic member from the released checkpoint. Inputs contain nine GFS analyses ending at 06 UTC (six hours before issue), issue-time JMA centre/central pressure, and static geography. Issue-time wind, prior motion and native regional history were unavailable and masked/zeroed. The stored +0 field is an input analysis; it is excluded from these forecast panels. The GFS transfer and input lag remain limitations. The selected leads keep the centre within the fixed 114–144°E, 11–41°N map. Names, times, member count and checkpoint/source hashes are in `paper/release_data/surigae_provenance.json`.
|
|
|
|
| 31 |
|
| 32 |
## Recent pressure-line example
|
| 33 |
|
| 34 |
+
### Interactive selected-best example
|
| 35 |
+
|
| 36 |
+
The [interactive PRAPIROON map](https://yu314-coder.github.io/typhoon-predict/trackformer_1_2_pressure.html) uses the unchanged saved 50-member fields for case 151, issued 2024-07-19 00 UTC. It is selected by the lowest track error among four cases meeting the disclosed route-shape, heading, central-pressure and complete-map-coverage criteria. Its 133.2 km score is the existing benchmark local-coordinate mean; the UI's individual-lead position error is a great-circle distance to exact observed coordinates and is therefore a separately calculated diagnostic. The pressure MAE is 2.91 hPa. These are showcase results, not typical or new holdout performance.
|
| 37 |
+
|
| 38 |
+
The page plays all twenty forecast leads, shows model and observed paths independently, and inspects physical mean pressure on the saved fixed grid. The observed path is taken directly from the storm's six-hour verification coordinates, not reconstructed from cumulative local displacements. Full-path observation overlays are retrospective verification and are never fed into inference. Data, hashes and the selection rule are in `paper/release_data/pressure_showcase.json` and the numerical data are in `pressure_showcase.npz`. Rebuild the standalone page and preview with `python release_tools/build_pressure_showcase.py`; no inference or GPU allocation is required to render saved outputs.
|
| 39 |
+
|
| 40 |
+
### Recent single-member example
|
| 41 |
+
|
| 42 |
The Surigae archive issued **2026-09-27 12 UTC** supplies real model regional MSLP fields at +6, +24 and +36 h. Isobars are drawn every 4 hPa, with selected labels every 12 hPa and one common colour scale. The magenta curve is the saved model route. Fields are neither relocated nor altered to force the map minimum onto the route. The regional map is a resampled composite and can differ slightly from central pressure sampled in the moving core.
|
| 43 |
|
| 44 |
This example is one deterministic member from the released checkpoint. Inputs contain nine GFS analyses ending at 06 UTC (six hours before issue), issue-time JMA centre/central pressure, and static geography. Issue-time wind, prior motion and native regional history were unavailable and masked/zeroed. The stored +0 field is an input analysis; it is excluded from these forecast panels. The GFS transfer and input lag remain limitations. The selected leads keep the centre within the fixed 114–144°E, 11–41°N map. Names, times, member count and checkpoint/source hashes are in `paper/release_data/surigae_provenance.json`.
|
docs/trackformer_1_2_pressure.html
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
paper/release_data/pressure_showcase.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"public_model": "Trackformer 1.2",
|
| 3 |
+
"storm_name": "PRAPIROON",
|
| 4 |
+
"storm_id": "2024198N08130",
|
| 5 |
+
"issue_time_utc": "2024-07-19T00:00:00Z",
|
| 6 |
+
"case_index": 151,
|
| 7 |
+
"source_row": 186973,
|
| 8 |
+
"members": 50,
|
| 9 |
+
"member_policy": "50 smooth historical-input perturbations, not latent samples",
|
| 10 |
+
"selection_rule": "Among the saved 270 cases, require both routes within the fixed regional patch with 1-degree margin and valid basin coverage, shape >=0.90, heading error <=30 degrees, >=18 pressure labels and central-pressure MAE <=15 hPa; choose lowest mean track error. No field values altered.",
|
| 11 |
+
"eligible_cases": 4,
|
| 12 |
+
"selected_best_not_representative": true,
|
| 13 |
+
"metrics": {
|
| 14 |
+
"mean_track_error_km": 133.2238587752683,
|
| 15 |
+
"track_error_120h_km": 305.1292398492091,
|
| 16 |
+
"shape_similarity": 0.9809541562706234,
|
| 17 |
+
"direction_error_deg": 29.459619452579773,
|
| 18 |
+
"direction_valid_steps": 20
|
| 19 |
+
},
|
| 20 |
+
"central_pressure_mae_hpa": 2.908013343811035,
|
| 21 |
+
"native_history_available": false,
|
| 22 |
+
"checkpoint_sha256": "f194a23d3f91ea76ad776dfad942fabd669eeae8b3fd665815463095367e9ee0",
|
| 23 |
+
"archive_sha256": "4afc595af1c02096d2cb38563069a9b2fc37c8cff2b439b77eac2ed96e34223e",
|
| 24 |
+
"data_sha256": "2e271cf728daf219662f3f2f2c519dccb9d63695cd97d2b5e5f2484f3d822648",
|
| 25 |
+
"observed_route_source": "Exact six-hour issue-centre coordinates from the same storm in track_windows_v13, not a reconstruction from cumulative local steps. Retrospective best-track verification only.",
|
| 26 |
+
"field_source": "Unmodified saved ensemble50_native_mslp_hpa: model basin-plus-moving-core reconstruction on the fixed issue-anchored geographic grid. 0.25-degree output sampling is not native forecast resolution.",
|
| 27 |
+
"note": "Mean route and mean central pressure need not equal the minimum of the mean field."
|
| 28 |
+
}
|
paper/release_data/pressure_showcase.npz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2e271cf728daf219662f3f2f2c519dccb9d63695cd97d2b5e5f2484f3d822648
|
| 3 |
+
size 738620
|
paper/release_data/pressure_showcase_coastlines.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
[[[117.882035,4.137551],[117.313232,3.234428],[118.04833,2.28769],[117.875627,1.827641],[118.996747,0.902219],[117.811858,0.784242],[117.478339,0.102475],[117.521644,-0.803723],[116.560048,-1.487661],[116.533797,-2.483517],[116.148084,-4.012726],[116.000858,-3.657037],[114.864803,-4.106984],[114.468652,-3.495704],[113.755672,-3.43917],[113.256994,-3.118776],[112.068126,-3.478392],[111.703291,-2.994442],[111.04824,-3.049426],[110.223846,-2.934032],[110.070936,-1.592874],[109.571948,-1.314907],[109.091874,-0.459507],[108.952658,0.415375],[109.069136,1.341934],[109.66326,2.006467],[109.830227,1.338136],[110.514061,0.773131],[111.159138,0.976478],[111.797548,0.904441],[112.380252,1.410121],[112.859809,1.49779],[113.80585,1.217549],[114.621355,1.430688],[115.134037,2.821482],[115.519078,3.169238],[115.865517,4.306559],[117.015214,4.306094],[117.882035,4.137551]],[[127.932378,2.174596],[128.004156,1.628531],[128.594559,1.540811],[128.688249,1.132386],[128.635952,0.258486],[128.12017,0.356413],[127.968034,-0.252077],[128.379999,-0.780004],[128.100016,-0.899996],[127.696475,-0.266598],[127.39949,1.011722],[127.600512,1.810691],[127.932378,2.174596]],[[122.927567,0.875192],[124.077522,0.917102],[125.065989,1.643259],[125.240501,1.419836],[124.437035,0.427881],[123.685505,0.235593],[122.723083,0.431137],[121.056725,0.381217],[120.183083,0.237247],[120.04087,-0.519658],[120.935905,-1.408906],[121.475821,-0.955962],[123.340565,-0.615673],[123.258399,-1.076213],[122.822715,-0.930951],[122.38853,-1.516858],[121.508274,-1.904483],[122.454572,-3.186058],[122.271896,-3.5295],[123.170963,-4.683693],[123.162333,-5.340604],[122.628515,-5.634591],[122.236394,-5.282933],[122.719569,-4.464172],[121.738234,-4.851331],[121.489463,-4.574553],[121.619171,-4.188478],[120.898182,-3.602105],[120.972389,-2.627643],[120.305453,-2.931604],[120.390047,-4.097579],[120.430717,-5.528241],[119.796543,-5.6734],[119.366906,-5.379878],[119.653606,-4.459417],[119.498835,-3.494412],[119.078344,-3.487022],[118.767769,-2.801999],[119.180974,-2.147104],[119.323394,-1.353147],[119.825999,0.154254],[120.035702,0.566477],[120.885779,1.309223],[121.666817,1.013944],[122.927567,0.875192]],[[102.584932,12.186595],[102.348099,13.394247],[102.988422,14.225721],[104.281418,14.416743],[105.218777,14.273212],[106.043946,13.881091],[106.496373,14.570584],[107.382727,14.202441],[107.614548,13.535531],[107.491403,12.337206],[105.810524,11.567615],[106.24967,10.961812],[105.199915,10.88931],[104.334335,10.486544],[103.49728,10.632555],[103.09069,11.153661],[102.584932,12.186595]],[[105.218777,14.273212],[104.281418,14.416743],[102.988422,14.225721],[102.348099,13.394247],[102.584932,12.186595],[101.687158,12.64574],[100.83181,12.627085],[100.978467,13.412722],[100.097797,13.406856],[100.018733,12.307001],[99.478921,10.846367],[99.153772,9.963061],[99.222399,9.239255],[99.873832,9.207862],[100.279647,8.295153],[100.459274,7.429573],[101.017328,6.856869],[101.623079,6.740622],[102.141187,6.221636],[101.814282,5.810808],[101.154219,5.691384],[101.075516,6.204867],[100.259596,6.642825],[100.085757,6.464489],[99.690691,6.848213],[99.519642,7.343454],[98.988253,7.907993],[98.503786,8.382305],[98.339662,7.794512],[98.150009,8.350007],[98.25915,8.973923],[98.553551,9.93296],[99.038121,10.960546],[99.587286,11.892763],[99.196354,12.804748],[99.212012,13.269294],[99.097755,13.827503],[98.430819,14.622028],[98.192074,15.123703],[98.537376,15.308497],[98.903348,16.177824],[98.493761,16.837836],[97.859123,17.567946],[97.375896,18.445438],[97.797783,18.62708],[98.253724,19.708203],[98.959676,19.752981],[99.543309,20.186598],[100.115988,20.41785],[100.548881,20.109238],[100.606294,19.508344],[101.282015,19.462585],[101.035931,18.408928],[101.059548,17.512497],[102.113592,18.109102],[102.413005,17.932782],[102.998706,17.961695],[103.200192,18.309632],[103.956477,18.240954],[104.716947,17.428859],[104.779321,16.441865],[105.589039,15.570316],[105.544338,14.723934],[105.218777,14.273212]],[[107.382727,14.202441],[106.496373,14.570584],[106.043946,13.881091],[105.218777,14.273212],[105.544338,14.723934],[105.589039,15.570316],[104.779321,16.441865],[104.716947,17.428859],[103.956477,18.240954],[103.200192,18.309632],[102.998706,17.961695],[102.413005,17.932782],[102.113592,18.109102],[101.059548,17.512497],[101.035931,18.408928],[101.282015,19.462585],[100.606294,19.508344],[100.548881,20.109238],[100.115988,20.41785],[100.329101,20.786122],[101.180005,21.436573],[101.270026,21.201652],[101.80312,21.174367],[101.652018,22.318199],[102.170436,22.464753],[102.754896,21.675137],[103.203861,20.766562],[104.435,20.758733],[104.822574,19.886642],[104.183388,19.624668],[103.896532,19.265181],[105.094598,18.666975],[105.925762,17.485315],[106.556008,16.604284],[107.312706,15.908538],[107.564525,15.202173],[107.382727,14.202441]],[[104.334335,10.486544],[105.199915,10.88931],[106.24967,10.961812],[105.810524,11.567615],[107.491403,12.337206],[107.614548,13.535531],[107.382727,14.202441],[107.564525,15.202173],[107.312706,15.908538],[106.556008,16.604284],[105.925762,17.485315],[105.094598,18.666975],[103.896532,19.265181],[104.183388,19.624668],[104.822574,19.886642],[104.435,20.758733],[103.203861,20.766562],[102.754896,21.675137],[102.170436,22.464753],[102.706992,22.708795],[103.504515,22.703757],[104.476858,22.81915],[105.329209,23.352063],[105.811247,22.976892],[106.725403,22.794268],[106.567273,22.218205],[107.04342,21.811899],[108.05018,21.55238],[106.715068,20.696851],[105.881682,19.75205],[105.662006,19.058165],[106.426817,18.004121],[107.361954,16.697457],[108.269495,16.079742],[108.877107,15.276691],[109.33527,13.426028],[109.200136,11.666859],[108.36613,11.008321],[107.220929,10.364484],[106.405113,9.53084],[105.158264,8.59976],[104.795185,9.241038],[105.076202,9.918491],[104.334335,10.486544]],[[109.47521,18.197701],[108.655208,18.507682],[108.626217,19.367888],[109.119056,19.821039],[110.211599,20.101254],[110.786551,20.077534],[111.010051,19.69593],[110.570647,19.255879],[110.339188,18.678395],[109.47521,18.197701]],[[80.25999,42.349999],[80.18015,42.920068],[80.866206,43.180362],[79.966106,44.917517],[81.947071,45.317027],[82.458926,45.53965],[83.180484,47.330031],[85.16429,47.000956],[85.720484,47.452969],[85.768233,48.455751],[86.598776,48.549182],[87.35997,49.214981],[87.751264,49.297198],[88.013832,48.599463],[88.854298,48.069082],[90.280826,47.693549],[90.970809,46.888146],[90.585768,45.719716],[90.94554,45.286073],[92.133891,45.115076],[93.480734,44.975472],[94.688929,44.352332],[95.306875,44.241331],[95.762455,43.319449],[96.349396,42.725635],[97.451757,42.74889],[99.515817,42.524691],[100.845866,42.663804],[101.83304,42.514873],[103.312278,41.907468],[104.522282,41.908347],[104.964994,41.59741],[106.129316,42.134328],[107.744773,42.481516],[109.243596,42.519446],[110.412103,42.871234],[111.129682,43.406834],[111.829588,43.743118],[111.667737,44.073176],[111.348377,44.457442],[111.873306,45.102079],[112.436062,45.011646],[113.463907,44.808893],[114.460332,45.339817],[115.985096,45.727235],[116.717868,46.388202],[117.421701,46.672733],[118.874326,46.805412],[119.66327,46.69268],[119.772824,47.048059],[118.866574,47.74706],[118.064143,48.06673],[117.295507,47.697709],[116.308953,47.85341],[115.742837,47.726545],[115.485282,48.135383],[116.191802,49.134598],[116.678801,49.888531],[117.879244,49.510983],[119.288461,50.142883],[119.27939,50.58292],[120.18208,51.64355],[120.7382,51.96411],[120.725789,52.516226],[120.177089,52.753886],[121.003085,53.251401],[122.245748,53.431726],[123.57147,53.4588],[125.068211,53.161045],[125.946349,52.792799],[126.564399,51.784255],[126.939157,51.353894],[127.287456,50.739797],[127.6574,49.76027],[129.397818,49.4406],[130.582293,48.729687],[130.98726,47.79013],[132.50669,47.78896],[133.373596,48.183442],[135.026311,48.47823],[134.50081,47.57845],[134.11235,47.21248],[133.769644,46.116927],[133.09712,45.14409],[131.883454,45.321162],[131.02519,44.96796],[131.288555,44.11152],[131.144688,42.92999],[130.633866,42.903015],[130.64,42.395024],[129.994267,42.985387],[129.596669,42.424982],[128.052215,41.994285],[128.208433,41.466772],[127.343783,41.503152],[126.869083,41.816569],[126.182045,41.107336],[125.079942,40.569824],[124.265625,39.928493],[122.86757,39.637788],[122.131388,39.170452],[121.054554,38.897471],[121.585995,39.360854],[121.376757,39.750261],[122.168595,40.422443],[121.640359,40.94639],[120.768629,40.593388],[119.639602,39.898056],[119.023464,39.252333],[118.042749,39.204274],[117.532702,38.737636],[118.059699,38.061476],[118.87815,37.897325],[118.911636,37.448464],[119.702802,37.156389],[120.823457,37.870428],[121.711259,37.481123],[122.357937,37.454484],[122.519995,36.930614],[121.104164,36.651329],[120.637009,36.11144],[119.664562,35.609791],[119.151208,34.909859],[120.227525,34.360332],[120.620369,33.376723],[121.229014,32.460319],[121.908146,31.692174],[121.891919,30.949352],[121.264257,30.676267],[121.503519,30.142915],[122.092114,29.83252],[121.938428,29.018022],[121.684439,28.225513],[121.125661,28.135673],[120.395473,27.053207],[119.585497,25.740781],[118.656871,24.547391],[117.281606,23.624501],[115.890735,22.782873],[114.763827,22.668074],[114.152547,22.22376],[113.80678,22.54834],[113.241078,22.051367],[111.843592,21.550494],[110.785466,21.397144],[110.444039,20.341033],[109.889861,20.282457],[109.627655,21.008227],[109.864488,21.395051],[108.522813,21.715212],[108.05018,21.55238],[107.04342,21.811899],[106.567273,22.218205],[106.725403,22.794268],[105.811247,22.976892],[105.329209,23.352063],[104.476858,22.81915],[103.504515,22.703757],[102.706992,22.708795],[102.170436,22.464753],[101.652018,22.318199],[101.80312,21.174367],[101.270026,21.201652],[101.180005,21.436573],[101.150033,21.849984],[100.416538,21.558839],[99.983489,21.742937],[99.240899,22.118314],[99.531992,22.949039],[98.898749,23.142722],[98.660262,24.063286],[97.60472,23.897405],[97.724609,25.083637],[98.671838,25.918703],[98.712094,26.743536],[98.68269,27.508812],[98.246231,27.747221],[97.911988,28.335945],[97.327114,28.261583],[96.248833,28.411031],[96.586591,28.83098],[96.117679,29.452802],[95.404802,29.031717],[94.56599,29.277438],[93.413348,28.640629],[92.503119,27.896876],[91.696657,27.771742],[91.258854,28.040614],[90.730514,28.064954],[90.015829,28.296439],[89.47581,28.042759],[88.814248,27.299316],[88.730326,28.086865],[88.120441,27.876542],[86.954517,27.974262],[85.82332,28.203576],[85.011638,28.642774],[84.23458,28.839894],[83.898993,29.320226],[83.337115,29.463732],[82.327513,30.115268],[81.525804,30.422717],[81.111256,30.183481],[79.721367,30.882715],[78.738894,31.515906],[78.458446,32.618164],[79.176129,32.48378],[79.208892,32.994395],[78.811086,33.506198],[78.912269,34.321936],[77.837451,35.49401],[76.192848,35.898403],[75.896897,36.666806],[75.158028,37.133031],[74.980002,37.41999],[74.829986,37.990007],[74.864816,38.378846],[74.257514,38.606507],[73.928852,38.505815],[73.675379,39.431237],[73.960013,39.660008],[73.822244,39.893973],[74.776862,40.366425],[75.467828,40.562072],[76.526368,40.427946],[76.904484,41.066486],[78.187197,41.185316],[78.543661,41.582243],[80.11943,42.123941],[80.25999,42.349999]],[[121.777818,24.394274],[121.175632,22.790857],[120.74708,21.970571],[120.220083,22.814861],[120.106189,23.556263],[120.69468,24.538451],[121.495044,25.295459],[121.951244,24.997596],[121.777818,24.394274]],[[120.833896,12.704496],[120.323436,13.466413],[121.180128,13.429697],[121.527394,13.06959],[121.26219,12.20556],[120.833896,12.704496]],[[122.586089,9.981045],[122.837081,10.261157],[122.947411,10.881868],[123.49885,10.940624],[123.337774,10.267384],[124.077936,11.232726],[123.982438,10.278779],[123.623183,9.950091],[123.309921,9.318269],[122.995883,9.022189],[122.380055,9.713361],[122.586089,9.981045]],[[126.376814,8.414706],[126.478513,7.750354],[126.537424,7.189381],[126.196773,6.274294],[125.831421,7.293715],[125.363852,6.786485],[125.683161,6.049657],[125.396512,5.581003],[124.219788,6.161355],[123.93872,6.885136],[124.243662,7.36061],[123.610212,7.833527],[123.296071,7.418876],[122.825506,7.457375],[122.085499,6.899424],[121.919928,7.192119],[122.312359,8.034962],[122.942398,8.316237],[123.487688,8.69301],[123.841154,8.240324],[124.60147,8.514158],[124.764612,8.960409],[125.471391,8.986997],[125.412118,9.760335],[126.222714,9.286074],[126.306637,8.782487],[126.376814,8.414706]],[[118.504581,9.316383],[117.174275,8.3675],[117.664477,9.066889],[118.386914,9.6845],[118.987342,10.376292],[119.511496,11.369668],[119.689677,10.554291],[119.029458,10.003653],[118.504581,9.316383]],[[122.336957,18.224883],[122.174279,17.810283],[122.515654,17.093505],[122.252311,16.262444],[121.662786,15.931018],[121.50507,15.124814],[121.728829,14.328376],[122.258925,14.218202],[122.701276,14.336541],[123.950295,13.782131],[123.855107,13.237771],[124.181289,12.997527],[124.077419,12.536677],[123.298035,13.027526],[122.928652,13.55292],[122.671355,13.185836],[122.03465,13.784482],[121.126385,13.636687],[120.628637,13.857656],[120.679384,14.271016],[120.991819,14.525393],[120.693336,14.756671],[120.564145,14.396279],[120.070429,14.970869],[119.920929,15.406347],[119.883773,16.363704],[120.286488,16.034629],[120.390047,17.599081],[120.715867,18.505227],[121.321308,18.504065],[121.937601,18.218552],[122.246006,18.47895],[122.336957,18.224883]],[[122.03837,11.415841],[121.883548,11.891755],[122.483821,11.582187],[123.120217,11.58366],[123.100838,11.165934],[122.637714,10.741308],[122.00261,10.441017],[121.967367,10.905691],[122.03837,11.415841]],[[125.502552,12.162695],[125.783465,11.046122],[125.011884,11.311455],[125.032761,10.975816],[125.277449,10.358722],[124.801819,10.134679],[124.760168,10.837995],[124.459101,10.88993],[124.302522,11.495371],[124.891013,11.415583],[124.87799,11.79419],[124.266762,12.557761],[125.227116,12.535721],[125.502552,12.162695]],[[100.085757,6.464489],[100.259596,6.642825],[101.075516,6.204867],[101.154219,5.691384],[101.814282,5.810808],[102.141187,6.221636],[102.371147,6.128205],[102.961705,5.524495],[103.381215,4.855001],[103.438575,4.181606],[103.332122,3.726698],[103.429429,3.382869],[103.502448,2.791019],[103.854674,2.515454],[104.247932,1.631141],[104.228811,1.293048],[103.519707,1.226334],[102.573615,1.967115],[101.390638,2.760814],[101.27354,3.270292],[100.695435,3.93914],[100.557408,4.76728],[100.196706,5.312493],[100.30626,6.040562],[100.085757,6.464489]],[[117.882035,4.137551],[117.015214,4.306094],[115.865517,4.306559],[115.519078,3.169238],[115.134037,2.821482],[114.621355,1.430688],[113.80585,1.217549],[112.859809,1.49779],[112.380252,1.410121],[111.797548,0.904441],[111.159138,0.976478],[110.514061,0.773131],[109.830227,1.338136],[109.66326,2.006467],[110.396135,1.663775],[111.168853,1.850637],[111.370081,2.697303],[111.796928,2.885897],[112.995615,3.102395],[113.712935,3.893509],[114.204017,4.525874],[114.659596,4.007637],[114.869557,4.348314],[115.347461,4.316636],[115.4057,4.955228],[115.45071,5.44773],[116.220741,6.143191],[116.725103,6.924771],[117.129626,6.928053],[117.643393,6.422166],[117.689075,5.98749],[118.347691,5.708696],[119.181904,5.407836],[119.110694,5.016128],[118.439727,4.966519],[118.618321,4.478202],[117.882035,4.137551]],[[115.45071,5.44773],[115.4057,4.955228],[115.347461,4.316636],[114.869557,4.348314],[114.659596,4.007637],[114.204017,4.525874],[114.599961,4.900011],[115.45071,5.44773]]]
|
paper/trackformer.pdf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bdfca35340399aab010bc11e2a0af82eedf3a5ee618324626e5aedc0ece5bdff
|
| 3 |
+
size 178019
|
paper/trackformer.tex
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\documentclass[11pt]{article}
|
| 2 |
+
\usepackage[margin=0.9in]{geometry}
|
| 3 |
+
\usepackage{amsmath,amssymb,booktabs,array,microtype,xcolor}
|
| 4 |
+
\usepackage[colorlinks=true,linkcolor=teal,urlcolor=teal]{hyperref}
|
| 5 |
+
\setlength{\parskip}{4pt}
|
| 6 |
+
\setlength{\parindent}{0pt}
|
| 7 |
+
\newcommand{\sample}{\mathcal{S}}
|
| 8 |
+
\title{\textbf{Trackformer 1.2}\\[4pt]\large Architecture and Forecast-State Evolution}
|
| 9 |
+
\author{Yu Yao-Hsing\\\small\url{https://github.com/yu314-coder/typhoon-predict}}
|
| 10 |
+
\date{Implementation description --- 29 September 2026}
|
| 11 |
+
\begin{document}
|
| 12 |
+
\maketitle
|
| 13 |
+
\begin{abstract}
|
| 14 |
+
Trackformer 1.2 advances an atmospheric basin state and a translating pressure
|
| 15 |
+
core to forecast tropical-cyclone motion and central pressure. Recurrent
|
| 16 |
+
convolutional networks evolve the fields; multiscale attention supplies
|
| 17 |
+
environmental context. The reported centre is associated with a depression in
|
| 18 |
+
the predicted core, and central pressure is sampled from that same field.
|
| 19 |
+
Twenty six-hour transitions produce a five-day forecast. This paper describes
|
| 20 |
+
only the released architecture, input contract, update equations, objectives
|
| 21 |
+
and ensemble mechanism. It contains no benchmark comparisons or skill claims.
|
| 22 |
+
\end{abstract}
|
| 23 |
+
|
| 24 |
+
\section{Design and forecast state}
|
| 25 |
+
The system is not a route predictor followed by an independently drawn pressure
|
| 26 |
+
image. It evolves pressure and atmospheric states, proposes a translation of a
|
| 27 |
+
storm-following frame, then associates a centre with the predicted pressure
|
| 28 |
+
within that frame. Translation is learned and steering-conditioned: this is
|
| 29 |
+
neither a pressure-only tracker nor a complete atmospheric numerical solver.
|
| 30 |
+
|
| 31 |
+
At step $k$, the recurrent state is
|
| 32 |
+
\[
|
| 33 |
+
s_k=(g_k,h^g_k,c_k,h^c_k,a_k,o_k,z_k,m_k,v_k;G,R,I,M).
|
| 34 |
+
\]
|
| 35 |
+
Here $g$ is the normalized eight-channel basin field; $h^g$ its memory;
|
| 36 |
+
$c$ the core pressure; $h^c$ core memory; $a$ its anomaly relative to the basin;
|
| 37 |
+
$o$ the core-grid origin; $z$ the associated storm centre; $m$ displacement per
|
| 38 |
+
six hours; and $v$ auxiliary maximum wind. Static geography $G$, regional
|
| 39 |
+
coordinates $R$, issue intensity $I$ and masks $M$ stay fixed.
|
| 40 |
+
|
| 41 |
+
\begin{center}\small
|
| 42 |
+
\begin{tabular}{p{0.25\linewidth}p{0.63\linewidth}}
|
| 43 |
+
\toprule
|
| 44 |
+
Stage & Function\\\midrule
|
| 45 |
+
Initialization & Past analyses and issue observations initialize fields and memories.\\
|
| 46 |
+
Attention & Multiscale environmental tokens condition basin memory.\\
|
| 47 |
+
Basin transition & Steering, backward transport and learned tendencies evolve eight fields.\\
|
| 48 |
+
Core transition & A translated frame carries a recurrent pressure anomaly.\\
|
| 49 |
+
Readout & Field-based association yields route and central pressure; pressure is reconstructed geographically.\\
|
| 50 |
+
\bottomrule
|
| 51 |
+
\end{tabular}\end{center}
|
| 52 |
+
|
| 53 |
+
\section{Inputs, geometry and outputs}
|
| 54 |
+
Nine past analyses at $-48,-42,\ldots,0$ h form a tensor of shape
|
| 55 |
+
$B\times9\times8\times25\times33$. The basin spans $60$ to $0^\circ$N and
|
| 56 |
+
$100$ to $180^\circ$E at $2.5^\circ$ spacing. Channels are
|
| 57 |
+
\[
|
| 58 |
+
[\mathrm{MSLP},Z_{500},u_{850},v_{850},u_{500},v_{500},u_{200},v_{200}],
|
| 59 |
+
\]
|
| 60 |
+
in hPa, metres and metres per second. Channel normalization is
|
| 61 |
+
$\widetilde x_j=(x_j-\mu_j)/\sigma_j$, with the released training-only constants.
|
| 62 |
+
Statistics are not refitted for each forecast.
|
| 63 |
+
|
| 64 |
+
Optional regional pressure history has shape $B\times9\times1\times121\times121$
|
| 65 |
+
on an issue-anchored patch sampled every $0.25^\circ$, with offsets of
|
| 66 |
+
$\pm15^\circ$. A detail-availability flag chooses native regional history or
|
| 67 |
+
coarse basin pressure during initialization. The regional coordinate grid is
|
| 68 |
+
still supplied when native observations are unavailable.
|
| 69 |
+
|
| 70 |
+
Four static channels encode latitude/$90$, longitude/$180-1$, land fraction
|
| 71 |
+
and elevation/$8000$ m. The issue state supplies latitude/longitude, east/north
|
| 72 |
+
motion in km per six hours, maximum wind in knots, central pressure in hPa and
|
| 73 |
+
two intensity-availability masks. Only observations and analyses at or before
|
| 74 |
+
issue time may enter inference; retrospective data availability is a separate
|
| 75 |
+
operational question.
|
| 76 |
+
|
| 77 |
+
The internal core is a $65\times65$ grid at 20-km sampling over $\pm640$ km.
|
| 78 |
+
Its field is a learned reconstruction, not native 20-km observations.
|
| 79 |
+
For each of twenty leads ($6,12,\ldots,120$ h), outputs include basin fields,
|
| 80 |
+
regional pressure, core pressure/coordinates, storm centre, central pressure,
|
| 81 |
+
domain masks and auxiliary maximum wind. This implementation does not output
|
| 82 |
+
quadrant wind radii or a resolved surface-wind map.
|
| 83 |
+
|
| 84 |
+
\section{Neural modules}
|
| 85 |
+
The released non-tiny architecture has 21,452,595 trainable parameters.
|
| 86 |
+
\subsection{Multiresolution evolution networks}
|
| 87 |
+
The basin network receives 44 channels: eight fields, 32 memory features and
|
| 88 |
+
four static channels. Encoder widths are $72,144,288,432$; residual-block depths
|
| 89 |
+
are $2,2,4,4$. A $3\times3$ stem and stride-two convolutions produce four
|
| 90 |
+
scales. The decoder uses $1\times1$ projections, bilinear upsampling, additive
|
| 91 |
+
skip connections and one residual block at each reconstructed scale.
|
| 92 |
+
Output heads emit ten transition channels and 32 recurrent features. Eight
|
| 93 |
+
transition channels are field tendencies and two are flow corrections.
|
| 94 |
+
|
| 95 |
+
Each residual block comprises a depthwise $5\times5$ convolution, eight-group
|
| 96 |
+
normalization, $1\times1$ expansion by four, GELU and $1\times1$ contraction.
|
| 97 |
+
A learned residual multiplier starts at 0.01. Transition heads start at zero.
|
| 98 |
+
The core network uses widths $64,128,256,384$ and the same depths. Its 45 inputs
|
| 99 |
+
are core pressure, eight environmental fields, 32 core-memory channels and four
|
| 100 |
+
geographic channels. Three outputs represent one anomaly tendency and two
|
| 101 |
+
local-flow corrections.
|
| 102 |
+
|
| 103 |
+
\subsection{Convolutional recurrent memory}
|
| 104 |
+
Basin and core memories each have 32 channels. History encoders receive 72
|
| 105 |
+
flattened basin channels or nine pressure-history channels, respectively.
|
| 106 |
+
Given advected memory $h$ and new evolution features $f$,
|
| 107 |
+
\begin{align*}
|
| 108 |
+
(r,u)&=\operatorname{sigmoid}(W_g*[h,f]),\\
|
| 109 |
+
q&=\tanh(W_q*[r\odot h,f]),\\
|
| 110 |
+
h'&=(1-u)\odot h+u\odot q.
|
| 111 |
+
\end{align*}
|
| 112 |
+
The gate convolution emits 64 channels split into reset and update gates;
|
| 113 |
+
the candidate convolution emits 32. Forecast leads share these recurrent
|
| 114 |
+
modules rather than using twenty independent predictors.
|
| 115 |
+
|
| 116 |
+
\subsection{Environmental attention}
|
| 117 |
+
A $1\times1$ convolution projects $[g,h^g,G]$ from 44 to 64 channels.
|
| 118 |
+
Average pooling at sizes/strides three and five with ceiling mode yields
|
| 119 |
+
$9\times11+5\times7=134$ environmental tokens. Two pre-normalization
|
| 120 |
+
Transformer layers use width 64, four heads, feed-forward width 128,
|
| 121 |
+
ReLU activation and zero dropout. Each of the 825 basin cells supplies a
|
| 122 |
+
query projected from its memory to width 64. Four-head cross-attention
|
| 123 |
+
retrieves context; a zero-initialized $64\to32$ projection adds it to basin
|
| 124 |
+
memory before the transition. No separate positional embedding is added:
|
| 125 |
+
geographic coordinates are already among the token inputs.
|
| 126 |
+
|
| 127 |
+
\section{Observation-conditioned initialization}
|
| 128 |
+
Write $\sample(F,\xi)$ for bilinear field sampling. Sampling uses FP32 geometry,
|
| 129 |
+
aligned corners and border padding for the basin; transported core anomalies
|
| 130 |
+
use zero padding. All nine pressure histories are sampled onto the core grid
|
| 131 |
+
centred at the issue observation. A detail mask chooses native pressure or
|
| 132 |
+
coarse pressure. The latest map initializes $c_0$, while all nine maps initialize
|
| 133 |
+
the core memory.
|
| 134 |
+
|
| 135 |
+
If issue central pressure is valid, the initial core is corrected by
|
| 136 |
+
\[
|
| 137 |
+
c_0(x,y)\leftarrow c_0(x,y)+
|
| 138 |
+
(\widetilde p_{\rm issue}-c_0(0,0))
|
| 139 |
+
e^{-(x^2+y^2)/(2\,100^2)}T(x,y),
|
| 140 |
+
\]
|
| 141 |
+
where $x,y$ are kilometres and
|
| 142 |
+
$T=\operatorname{clip}((640-\sqrt{x^2+y^2})/160,0,1)$.
|
| 143 |
+
The anomaly is $a_0=c_0-\sample(g_{0,\mathrm{MSLP}},\xi_0)$.
|
| 144 |
+
This compact prior is applied only at initialization. Future scalar pressure
|
| 145 |
+
is not repeatedly inserted into the field.
|
| 146 |
+
|
| 147 |
+
\section{One six-hour transition}
|
| 148 |
+
\subsection{Basin transport}
|
| 149 |
+
Learned softmax weights blend physical winds at 850, 500 and 200 hPa.
|
| 150 |
+
Their initialization is $(0.4,0.4,0.2)$, not a fixed inference constraint.
|
| 151 |
+
For network output $d$,
|
| 152 |
+
\[
|
| 153 |
+
U_k=\sum_\ell\alpha_\ell(u_\ell,v_\ell)_k+15\tanh(d_{8:10})
|
| 154 |
+
\quad\mathrm{m\,s^{-1}}.
|
| 155 |
+
\]
|
| 156 |
+
Backtracing constructs departure coordinates $D(U_k)$ and
|
| 157 |
+
\[
|
| 158 |
+
g_{k+1}=\sample(g_k,D(U_k))+0.2\tanh(d_{0:8}).
|
| 159 |
+
\]
|
| 160 |
+
Six hours convert 1 m/s to 21.6 km. Coordinate conversion uses 111.2 km per
|
| 161 |
+
latitude degree and $111.2\max(\cos\phi,0.2)$ km per longitude degree.
|
| 162 |
+
The attention-conditioned memory is advected by the same departure grid and
|
| 163 |
+
updated with new features. Tendencies are in normalized channel units.
|
| 164 |
+
This semi-Lagrangian-style update is not a complete or exactly conservative
|
| 165 |
+
atmospheric equation solver.
|
| 166 |
+
|
| 167 |
+
\subsection{Moving-frame proposal}
|
| 168 |
+
A $44\to64\to3$ GELU MLP reads sampled 32-channel memory, eight basin fields,
|
| 169 |
+
previous motion divided by 100, and two issue-intensity masks. For output $b$,
|
| 170 |
+
\[
|
| 171 |
+
m_{k+1}=0.7(21.6)U_k(z_k)+0.3m_k+100\tanh(b_{0:2}).
|
| 172 |
+
\]
|
| 173 |
+
This displacement, in km per six hours, defines a new origin relative to
|
| 174 |
+
$z_k$. It proposes where the pressure core moves, but is not the final reported
|
| 175 |
+
centre. The third output updates auxiliary wind:
|
| 176 |
+
$v_{k+1}=\max(0,v_k+5b_2)$.
|
| 177 |
+
|
| 178 |
+
\subsection{Relative core transport}
|
| 179 |
+
The core network reads the previous pressure core, its old sampled environment,
|
| 180 |
+
core memory and geography at the proposed origin. Local velocity is
|
| 181 |
+
$U^{\rm local}=\sample(U_k)+5\tanh(d^c_{1:3})$.
|
| 182 |
+
Subtracting $m_{k+1}/21.6$ removes bulk frame translation. Backward coordinates
|
| 183 |
+
also account for the offset between the previous associated centre and its
|
| 184 |
+
previous grid origin. On this relative departure grid $D_c$,
|
| 185 |
+
\begin{align*}
|
| 186 |
+
a_{k+1}&=\sample(a_k,D_c)+0.1d^c_0,\\
|
| 187 |
+
c_{k+1}&=\sample(g_{k+1,\mathrm{MSLP}},\xi_{k+1})+Ta_{k+1}.
|
| 188 |
+
\end{align*}
|
| 189 |
+
Unlike the basin tendency, $d^c_0$ is not bounded by $\tanh$.
|
| 190 |
+
Core memory uses the same relative sampling followed by its gated update.
|
| 191 |
+
|
| 192 |
+
\subsection{Centre association and central pressure}
|
| 193 |
+
Convert core pressure to hPa: $P=\sigma_p c_{k+1}+\mu_p$.
|
| 194 |
+
For cells within 300 km of the proposed origin,
|
| 195 |
+
\[
|
| 196 |
+
w_i=\operatorname{softmax}_i\left(-P_i/2-r_i^2/(2\,180^2)\right).
|
| 197 |
+
\]
|
| 198 |
+
Cells beyond 300 km are excluded. The weighted mean of cell latitude/longitude
|
| 199 |
+
is $z_{k+1}$. Central pressure is the bilinear sample $\sample(P,z_{k+1})$,
|
| 200 |
+
not necessarily the grid minimum. The spatial prior associates the forecast
|
| 201 |
+
with this storm rather than an unrelated remote depression.
|
| 202 |
+
|
| 203 |
+
\subsection{Geographic pressure output}
|
| 204 |
+
The issue-anchored regional output is
|
| 205 |
+
\[
|
| 206 |
+
\widehat p_R=\sample(g_{k+1,\mathrm{MSLP}},R)
|
| 207 |
+
+\sample(Ta_{k+1},R;\mathrm{zero\ padding}),
|
| 208 |
+
\]
|
| 209 |
+
then de-normalized to hPa. This basin-plus-core reconstruction is generated by
|
| 210 |
+
the model itself; future observed fields and display-only vortices are not
|
| 211 |
+
substituted. Its $0.25^\circ$ sampling is not proof of native resolution.
|
| 212 |
+
Masks indicate valid basin coverage. Resampling and localized association mean
|
| 213 |
+
the reported centre, central pressure and regional map minimum need not coincide
|
| 214 |
+
exactly. A display must preserve those distinctions rather than relocate fields.
|
| 215 |
+
|
| 216 |
+
\section{Autoregression and learning objectives}
|
| 217 |
+
Inference initializes once and repeats the transition twenty times, using only
|
| 218 |
+
fixed issue context and its own predicted future state. The implemented
|
| 219 |
+
single-step loss is
|
| 220 |
+
\begin{align*}
|
| 221 |
+
L={}&L_{\rm env}+L_{\rm regional}+0.2L_{\rm route}
|
| 222 |
+
+0.5L_{\rm pressure}+0.05L_{\rm wind}\\
|
| 223 |
+
&+0.25L_{\Delta p}+0.1L_{\Delta z}.
|
| 224 |
+
\end{align*}
|
| 225 |
+
The final terms require valid preceding-target labels. Environment loss is
|
| 226 |
+
cosine-latitude-weighted Smooth L1 in normalized units. Regional loss includes
|
| 227 |
+
Smooth L1 and $0.2$ times adjacent-grid gradient errors on each axis. Absolute
|
| 228 |
+
regional-field supervision excludes the inner 150 km around the target centre,
|
| 229 |
+
because reanalysis can underresolve observed central pressure. This is a
|
| 230 |
+
supervision choice, not proof of correct inner-core structure.
|
| 231 |
+
|
| 232 |
+
Route residuals use a 100-km scale; pressure and wind use 20 hPa and 30 kt.
|
| 233 |
+
Pressure-change error uses 10 hPa and displacement-change error uses 100 km.
|
| 234 |
+
All objectives use explicit masks. They train field evolution and readout
|
| 235 |
+
together, without adding an independent central-pressure output head.
|
| 236 |
+
Training-only normalization, storm-level split boundaries and causal input
|
| 237 |
+
selection remain essential implementation constraints.
|
| 238 |
+
|
| 239 |
+
\section{Single forecasts and 50-member means}
|
| 240 |
+
Evaluation-mode inference is deterministic for fixed inputs and weights.
|
| 241 |
+
The documented ensemble perturbs only normalized historical weather: independent
|
| 242 |
+
Gaussian fields are spatially smoothed with kernels five (basin) and nine
|
| 243 |
+
(regional), centred, unit-scaled per map and multiplied by amplitudes 0.025 and
|
| 244 |
+
0.015. Issue centre, motion, intensity, masks and geography remain fixed.
|
| 245 |
+
Each member performs a complete recurrent rollout.
|
| 246 |
+
|
| 247 |
+
With $M=50$, routes and central pressures are averaged separately:
|
| 248 |
+
$\overline z=M^{-1}\sum_m z^{(m)}$ and $\overline p=M^{-1}\sum_m p^{(m)}$.
|
| 249 |
+
Physical pressure fields are averaged on common geographic grids, not by
|
| 250 |
+
averaging unaligned moving-core array indices. In general,
|
| 251 |
+
\[
|
| 252 |
+
\overline z\ne\arg\min_x\overline P(x),\qquad
|
| 253 |
+
\overline p\ne\min_x\overline P(x).
|
| 254 |
+
\]
|
| 255 |
+
These are perturbed-input realizations of one model, not 50 trained networks or
|
| 256 |
+
learned latent samples. Spread is not automatically calibrated uncertainty.
|
| 257 |
+
Member counts, perturbation settings and seed policy must accompany the outputs.
|
| 258 |
+
|
| 259 |
+
\section{Source identity and use boundary}
|
| 260 |
+
The public name is \textbf{Trackformer 1.2}. Its manifest retains the internal
|
| 261 |
+
checkpoint identity, 1.2.73 epoch 4, and exact weight/source hashes.
|
| 262 |
+
\texttt{model.py} implements environmental attention and added temporal losses;
|
| 263 |
+
\texttt{baseline\_model.py} implements moving-core evolution and readout;
|
| 264 |
+
\texttt{v165\_base.py} supplies sampling, evolution blocks and memories.
|
| 265 |
+
All are in \texttt{models/trackformer\_1\_2\_field/}.
|
| 266 |
+
|
| 267 |
+
This paper describes mechanisms only. Learned reconstructions, limited domain,
|
| 268 |
+
input-source differences and retrospective availability constrain interpretation.
|
| 269 |
+
The model remains a research artifact, not an operational warning system.
|
| 270 |
+
\end{document}
|
paper/trackformer_1_1_legacy.tex
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
\documentclass[11pt]{article}
|
| 2 |
+
\usepackage[margin=1in]{geometry}
|
| 3 |
+
\usepackage{amsmath,amssymb}
|
| 4 |
+
\usepackage{booktabs}
|
| 5 |
+
\usepackage{graphicx}
|
| 6 |
+
\usepackage{xcolor}
|
| 7 |
+
\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
|
| 8 |
+
\usepackage{array}
|
| 9 |
+
\usepackage{microtype}
|
| 10 |
+
|
| 11 |
+
\title{\textbf{Trackformer 1.1}\\
|
| 12 |
+
\large Causal Western-Pacific Tropical-Cyclone Forecasting}
|
| 13 |
+
\author{Yu Yao-Hsing\\
|
| 14 |
+
\small \href{https://github.com/yu314-coder/typhoon-predict}{github.com/yu314-coder/typhoon-predict}}
|
| 15 |
+
\date{Model card and training description\\2026-08-20}
|
| 16 |
+
|
| 17 |
+
\begin{document}
|
| 18 |
+
\maketitle
|
| 19 |
+
|
| 20 |
+
\begin{abstract}
|
| 21 |
+
Trackformer 1.1 is a research model for forecasting tropical-cyclone motion,
|
| 22 |
+
maximum sustained wind, central pressure, radius of maximum wind (RMW), and
|
| 23 |
+
four-quadrant 34/50/64-kt wind radii over the western Pacific. It combines a
|
| 24 |
+
causal regional analysis-state route with spatial and temporal structure
|
| 25 |
+
experts. The model reads observed storm history and analysis information
|
| 26 |
+
available at the issue time or earlier. It does not consume official
|
| 27 |
+
agency forecast tracks, positive-lead weather fields, or future observations
|
| 28 |
+
as inputs. This document describes the released model, its data contract,
|
| 29 |
+
training procedure, source boundary, and held-out diagnostic comparison with
|
| 30 |
+
the internal Trackformer 1.2.26 causal baseline.
|
| 31 |
+
\end{abstract}
|
| 32 |
+
|
| 33 |
+
\section{Scope and intended use}
|
| 34 |
+
|
| 35 |
+
The release is an experimental research artifact for reproducible tropical
|
| 36 |
+
cyclone forecasting and hindcast evaluation. It is not an operational
|
| 37 |
+
warning system and must not be used for evacuation, aviation, maritime,
|
| 38 |
+
emergency-management, or other safety-critical decisions. Official
|
| 39 |
+
meteorological agencies remain the authority for real-world warnings.
|
| 40 |
+
|
| 41 |
+
\section{Forecast contract}
|
| 42 |
+
|
| 43 |
+
The model produces twenty future states at six-hour intervals:
|
| 44 |
+
\[
|
| 45 |
+
\{6,12,18,\ldots,120\}\ {\rm hours}.
|
| 46 |
+
\]
|
| 47 |
+
Each state contains latitude and longitude, maximum sustained wind, central
|
| 48 |
+
pressure, RMW, and twelve quadrant radii:
|
| 49 |
+
\[
|
| 50 |
+
[v_{\max},p_{\rm c},r_{\rm mw},R34_{NE},R34_{SE},R34_{SW},R34_{NW},
|
| 51 |
+
R50_{NE},\ldots,R64_{NW}].
|
| 52 |
+
\]
|
| 53 |
+
Wind is exposed as a one-minute estimate in knots. Pressure is in hPa.
|
| 54 |
+
Distances are exposed in kilometres, although the historical training
|
| 55 |
+
structure labels and the native checkpoint tensors use nautical miles. The
|
| 56 |
+
public conversion is
|
| 57 |
+
\[
|
| 58 |
+
1\ {\rm nautical\ mile}=1.852\ {\rm km}.
|
| 59 |
+
\]
|
| 60 |
+
The output projection keeps radii non-negative and enforces
|
| 61 |
+
\[
|
| 62 |
+
R34_q \geq R50_q \geq R64_q
|
| 63 |
+
\]
|
| 64 |
+
for every quadrant \(q\).
|
| 65 |
+
|
| 66 |
+
\section{Architecture}
|
| 67 |
+
|
| 68 |
+
\subsection{Causal regional route}
|
| 69 |
+
|
| 70 |
+
The route module operates on a western-Pacific analysis domain covering the
|
| 71 |
+
nearby ocean and the land regions that affect recurvature and decay. It
|
| 72 |
+
constructs steering views from 850-hPa, 500-hPa, and 200-hPa winds together
|
| 73 |
+
with 500-hPa height. Inner-flow, deep-layer, ridge, trough, and jet-level
|
| 74 |
+
views are integrated into a weighted route ensemble. The route sees only
|
| 75 |
+
analysis states at or before the issue time.
|
| 76 |
+
|
| 77 |
+
\subsection{Intensity and structure experts}
|
| 78 |
+
|
| 79 |
+
The intensity input contract is a nine-step observed storm window with shape
|
| 80 |
+
\(9\times54\), together with a current four-channel storm-centred analysis
|
| 81 |
+
patch of shape \(4\times17\times17\). The spatial experts use a transformer
|
| 82 |
+
encoder for the observed track/environment sequence and a convolutional
|
| 83 |
+
field encoder for the current patch. Lead queries decode a twenty-step
|
| 84 |
+
curve for maximum wind and central pressure.
|
| 85 |
+
|
| 86 |
+
Three structure experts use the same causal history and field representation
|
| 87 |
+
to estimate RMW and the twelve quadrant radii. The structure decoder is
|
| 88 |
+
shared across leads but has lead embeddings and a temporal decoder. Expert
|
| 89 |
+
outputs are averaged and blended using validation-only weights.
|
| 90 |
+
|
| 91 |
+
\subsection{Temporal expert}
|
| 92 |
+
|
| 93 |
+
An additional group of three temporal experts reads the current field and
|
| 94 |
+
older analysis fields with shape \(8\times17\times17\). It provides a
|
| 95 |
+
validation-gated residual adjustment to the primary intensity path. The
|
| 96 |
+
residual branch is disabled when its required causal history is unavailable.
|
| 97 |
+
It cannot access positive-lead fields.
|
| 98 |
+
|
| 99 |
+
\section{Data and training}
|
| 100 |
+
|
| 101 |
+
\subsection{Sources}
|
| 102 |
+
|
| 103 |
+
\begin{itemize}
|
| 104 |
+
\item \textbf{IBTrACS best track:} observed storm position, intensity,
|
| 105 |
+
RMW, and wind-radius history and future labels for training targets and
|
| 106 |
+
later verification.
|
| 107 |
+
\item \textbf{Atmospheric analysis/reanalysis:} current, \(t-12\) h, and
|
| 108 |
+
\(t-24\) h pressure, height, and multi-level wind summaries.
|
| 109 |
+
\item \textbf{SST summaries:} current and past sea-surface-temperature
|
| 110 |
+
context with availability flags.
|
| 111 |
+
\item \textbf{Static geography:} land/sea state, terrain, land cover,
|
| 112 |
+
coastline proximity, and geographic location features.
|
| 113 |
+
\end{itemize}
|
| 114 |
+
|
| 115 |
+
The input policy excludes JMA, JTWC, ECMWF, GFS, GEFS, and other official
|
| 116 |
+
forecast products. It also excludes positive-lead weather fields and
|
| 117 |
+
observations that were not available at issue time. Future best-track labels
|
| 118 |
+
are targets for supervised training or chronological scoring only.
|
| 119 |
+
|
| 120 |
+
\subsection{Chronological storm-disjoint split}
|
| 121 |
+
|
| 122 |
+
The split is determined by each storm's first year:
|
| 123 |
+
\begin{center}
|
| 124 |
+
\begin{tabular}{ll}
|
| 125 |
+
\toprule
|
| 126 |
+
\textbf{Split} & \textbf{Storm first year}\\
|
| 127 |
+
\midrule
|
| 128 |
+
Training & through 2015\\
|
| 129 |
+
Validation & 2016--2019\\
|
| 130 |
+
Test & 2020 onward\\
|
| 131 |
+
\bottomrule
|
| 132 |
+
\end{tabular}
|
| 133 |
+
\end{center}
|
| 134 |
+
|
| 135 |
+
All normalization statistics, checkpoint selection, and calibration fits are
|
| 136 |
+
limited to the training and validation periods. The test period is held out
|
| 137 |
+
until final scoring. Storm identity is kept intact across the split so
|
| 138 |
+
overlapping windows from one storm cannot cross from training into
|
| 139 |
+
validation or test.
|
| 140 |
+
|
| 141 |
+
\subsection{Objectives and regularization}
|
| 142 |
+
|
| 143 |
+
The training loss is a masked, lead-weighted Huber/Smooth L1 objective. A
|
| 144 |
+
temporal curve term penalizes implausible lead-to-lead jumps. Structure
|
| 145 |
+
channels use explicit availability masks, so an absent historical radius is
|
| 146 |
+
not interpreted as a zero-radius label. Radius ordering is penalized in the
|
| 147 |
+
loss and enforced again at the output boundary. Separate kinematic and
|
| 148 |
+
thermodynamic paths reduce task interference between track and intensity.
|
| 149 |
+
Three seeds are trained for each expert group and the ensemble/calibration
|
| 150 |
+
weights are selected on the validation split.
|
| 151 |
+
|
| 152 |
+
\section{Held-out diagnostic comparison}
|
| 153 |
+
|
| 154 |
+
Table~\ref{tab:metrics} reports the final \(+120\) h mean absolute errors. The
|
| 155 |
+
Trackformer 1.1 values are the released calibrated public path. The
|
| 156 |
+
Trackformer 1.2.26 values are the causal physics-v4 comparison baseline on
|
| 157 |
+
9,994 untouched test windows from storms whose first year is 2020 or later.
|
| 158 |
+
Lower error is better. The comparison is diagnostic; the 1.2.26 model is not
|
| 159 |
+
part of this release.
|
| 160 |
+
|
| 161 |
+
\begin{table}[ht]
|
| 162 |
+
\centering
|
| 163 |
+
\caption{Reported held-out \(+120\) h errors.}
|
| 164 |
+
\label{tab:metrics}
|
| 165 |
+
\small
|
| 166 |
+
\begin{tabular}{lrrr}
|
| 167 |
+
\toprule
|
| 168 |
+
\textbf{Metric} & \textbf{Trackformer 1.1} & \textbf{Trackformer 1.2.26} & \textbf{Unit}\\
|
| 169 |
+
\midrule
|
| 170 |
+
Maximum wind MAE & 20.36 & 19.88 & kt\\
|
| 171 |
+
Central pressure MAE & 14.44 & 13.63 & hPa\\
|
| 172 |
+
RMW MAE & 25.22 & 18.53 & km\\
|
| 173 |
+
R34 MAE & 61.92 & 46.67 & km\\
|
| 174 |
+
R50 MAE & 34.24 & 25.42 & km\\
|
| 175 |
+
R64 MAE & 20.49 & 14.77 & km\\
|
| 176 |
+
\bottomrule
|
| 177 |
+
\end{tabular}
|
| 178 |
+
\end{table}
|
| 179 |
+
|
| 180 |
+
\begin{figure}[ht]
|
| 181 |
+
\centering
|
| 182 |
+
\includegraphics[width=\linewidth]{trackformer_1_1_vs_1_2_26_test120h_mae.png}
|
| 183 |
+
\caption{The same comparison as Table~\ref{tab:metrics}. The four-quadrant
|
| 184 |
+
structure values for Trackformer 1.1 were converted from native nautical
|
| 185 |
+
miles using 1.852 km per nautical mile.}
|
| 186 |
+
\label{fig:comparison}
|
| 187 |
+
\end{figure}
|
| 188 |
+
|
| 189 |
+
\section{Release contents and reproducibility}
|
| 190 |
+
|
| 191 |
+
The GitHub Release archive contains:
|
| 192 |
+
\begin{itemize}
|
| 193 |
+
\item three primary intensity checkpoints;
|
| 194 |
+
\item three structure checkpoints;
|
| 195 |
+
\item three temporal checkpoints;
|
| 196 |
+
\item normalization statistics;
|
| 197 |
+
\item calibration state and the model manifest.
|
| 198 |
+
\end{itemize}
|
| 199 |
+
|
| 200 |
+
The main repository contains the public source modules:
|
| 201 |
+
\begin{itemize}
|
| 202 |
+
\item \texttt{trackformer\_1\_1.py} for the public loader;
|
| 203 |
+
\item \texttt{trackformer\_1\_1\_route.py} for the causal route;
|
| 204 |
+
\item \texttt{trackformer\_1\_1\_intensity.py} for intensity and structure;
|
| 205 |
+
\item \texttt{trackformer\_1\_1\_temporal.py} for the temporal expert.
|
| 206 |
+
\end{itemize}
|
| 207 |
+
The supported checkpoint format is native PyTorch. GGUF is not an
|
| 208 |
+
appropriate interchange format for this CNN/Transformer weather model.
|
| 209 |
+
|
| 210 |
+
\section{Limitations}
|
| 211 |
+
|
| 212 |
+
Performance varies with storm structure, basin, analysis source, land
|
| 213 |
+
interaction, and missing observations. A held-out aggregate metric does not
|
| 214 |
+
guarantee skill on every individual storm. The release provides no
|
| 215 |
+
operational warning confidence and must be interpreted with the limitations
|
| 216 |
+
of the data and causal hindcast design.
|
| 217 |
+
|
| 218 |
+
\section*{License}
|
| 219 |
+
|
| 220 |
+
Code and compact artifacts are released under the repository MIT license.
|
| 221 |
+
Upstream datasets remain subject to their own terms and attribution
|
| 222 |
+
requirements.
|
| 223 |
+
|
| 224 |
+
\end{document}
|
paper/trackformer_1_2_interactive_pressure_preview.png
ADDED
|
Git LFS Details
|
release_tools/build_pressure_showcase.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Build an offline interactive map from saved physical 50-member fields.
|
| 2 |
+
|
| 3 |
+
--source-root prepares the public data subset; otherwise use published subset.
|
| 4 |
+
No model inference, GPU allocation, training, or weather retrieval is performed.
|
| 5 |
+
"""
|
| 6 |
+
import argparse, base64, csv, hashlib, io, json
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
import numpy as np
|
| 9 |
+
import matplotlib
|
| 10 |
+
matplotlib.use('Agg')
|
| 11 |
+
import matplotlib.pyplot as plt
|
| 12 |
+
|
| 13 |
+
REPO=Path(__file__).resolve().parents[1]
|
| 14 |
+
DATA=REPO/'paper/release_data'
|
| 15 |
+
|
| 16 |
+
def sha(path):
|
| 17 |
+
h=hashlib.sha256()
|
| 18 |
+
with Path(path).open('rb') as f:
|
| 19 |
+
for b in iter(lambda:f.read(8*1024**2),b''):h.update(b)
|
| 20 |
+
return h.hexdigest()
|
| 21 |
+
|
| 22 |
+
def absolute(local,lat,lon):
|
| 23 |
+
return np.stack([lat+local[...,1]/111.2,lon+local[...,0]/(111.2*max(np.cos(np.deg2rad(lat)),.2))],-1)
|
| 24 |
+
|
| 25 |
+
def prepare(root):
|
| 26 |
+
archive=root/'benchmark_ensemble50/v173_e4/v173_e4_causal_ensemble50.npz'
|
| 27 |
+
cases=json.loads((REPO/'paper/trackformer_1_2_showcase_selection.json').read_text())['all_case_metrics']
|
| 28 |
+
patches={r['track_archive_row']:r for r in json.loads((root/'data/v164_reuse/plan.json').read_text())['rows']}
|
| 29 |
+
with np.load(root/'track_build/track_windows_v13.npz') as w:
|
| 30 |
+
target,mask=w['target'],w['target_mask']
|
| 31 |
+
times,ids=w['base_time'],w['storm_id'].astype(str)
|
| 32 |
+
lats,lons=w['base_lat'],w['base_lon']%360
|
| 33 |
+
with np.load(archive) as z:
|
| 34 |
+
routes=z['ensemble50_local'];truth=z['truth_local'];pressure=z['ensemble50_pressure_hpa']
|
| 35 |
+
eligible=[]
|
| 36 |
+
for c in cases:
|
| 37 |
+
i=c['case_index'];r=c['source_row'];lat,lon=c['base_lat'],c['base_lon']
|
| 38 |
+
patch=patches.get(r)
|
| 39 |
+
anchor=np.array([patch['center_lat'],patch['center_lon']]) if patch else np.round(np.array([lat,lon])*4)/4
|
| 40 |
+
p,t=absolute(routes[i],lat,lon),absolute(truth[i],lat,lon)
|
| 41 |
+
points=np.vstack([[lat,lon],p,t])
|
| 42 |
+
fits=(np.abs(points-anchor)<14).all() and (points[:,0]>0).all() and (points[:,0]<60).all() and (points[:,1]>100).all() and (points[:,1]<180).all()
|
| 43 |
+
pm=mask[r,:20,3].astype(bool)&np.isfinite(target[r,:20,3])&(target[r,:20,3]>800)&(target[r,:20,3]<1100)
|
| 44 |
+
pe=float(np.abs(pressure[i]-target[r,:20,3])[pm].mean()) if pm.any() else None
|
| 45 |
+
m=c['models']['1.2']
|
| 46 |
+
if fits and pm.sum()>=18 and pe<=15 and m['shape_similarity']>=.9 and m['direction_error_deg'] is not None and m['direction_error_deg']<=30:
|
| 47 |
+
eligible.append((m['mean_track_error_km'],i,anchor,pe))
|
| 48 |
+
_,i,anchor,pe=min(eligible,key=lambda x:(x[0],x[1]));c=cases[i];r=c['source_row']
|
| 49 |
+
lookup={int(times[j]):int(j) for j in np.flatnonzero(ids==c['storm_id'])}
|
| 50 |
+
issue=int(times[r]);future=[lookup[issue+k*6*3600*10**9] for k in range(21)]
|
| 51 |
+
observed=np.stack([lats[future],lons[future]],-1)
|
| 52 |
+
forecast=np.vstack([[c['base_lat'],c['base_lon']],absolute(routes[i],c['base_lat'],c['base_lon'])])
|
| 53 |
+
assert (np.abs(np.vstack([observed,forecast])-anchor)<15).all()
|
| 54 |
+
field=z['ensemble50_native_mslp_hpa'][i].copy()
|
| 55 |
+
assert field.shape==(20,121,121) and np.isfinite(field).all()
|
| 56 |
+
pm=mask[r,:20,3].astype(bool)&(target[r,:20,3]>800)&(target[r,:20,3]<1100)
|
| 57 |
+
np.savez_compressed(DATA/'pressure_showcase.npz',pressure_hpa=field,latitude=anchor[0]+np.linspace(15,-15,121),longitude=anchor[1]+np.linspace(-15,15,121),forecast_lat_lon=forecast,observed_lat_lon=observed,central_pressure_hpa=pressure[i],observed_pressure_hpa=target[r,:20,3],pressure_mask=pm)
|
| 58 |
+
names={}
|
| 59 |
+
with (root/'data/ibtracs/ibtracs.WP.list.v04r01.csv').open() as f:
|
| 60 |
+
for row in csv.DictReader(f):names[row['SID']]=row['NAME']
|
| 61 |
+
rule='Among the saved 270 cases, require both routes within the fixed regional patch with 1-degree margin and valid basin coverage, shape >=0.90, heading error <=30 degrees, >=18 pressure labels and central-pressure MAE <=15 hPa; choose lowest mean track error. No field values altered.'
|
| 62 |
+
meta={'public_model':'Trackformer 1.2','storm_name':names[c['storm_id']],'storm_id':c['storm_id'],'issue_time_utc':c['issue_time_utc'],'case_index':i,'source_row':r,'members':50,'member_policy':'50 smooth historical-input perturbations, not latent samples','selection_rule':rule,'eligible_cases':len(eligible),'selected_best_not_representative':True,'metrics':c['models']['1.2'],'central_pressure_mae_hpa':pe,'native_history_available':r in patches,'checkpoint_sha256':'f194a23d3f91ea76ad776dfad942fabd669eeae8b3fd665815463095367e9ee0','archive_sha256':sha(archive),'data_sha256':sha(DATA/'pressure_showcase.npz'),'observed_route_source':'Exact six-hour issue-centre coordinates from the same storm in track_windows_v13, not a reconstruction from cumulative local steps. Retrospective best-track verification only.','field_source':'Unmodified saved ensemble50_native_mslp_hpa: model basin-plus-moving-core reconstruction on the fixed issue-anchored geographic grid. 0.25-degree output sampling is not native forecast resolution.','note':'Mean route and mean central pressure need not equal the minimum of the mean field.'}
|
| 63 |
+
rings=json.loads((root/'trackformer-weatherlab-site/public/data/history/coastlines.json').read_text())
|
| 64 |
+
rings=[ring for ring in rings if any(anchor[1]-15<=x<=anchor[1]+15 and max(0,anchor[0]-15)<=y<=anchor[0]+15 for x,y in ring)]
|
| 65 |
+
(DATA/'pressure_showcase_coastlines.json').write_text(json.dumps(rings,separators=(',',':'))+'\n')
|
| 66 |
+
(DATA/'pressure_showcase.json').write_text(json.dumps(meta,indent=2)+'\n')
|
| 67 |
+
print('Selected',meta['storm_name'],meta['issue_time_utc'],'case',i,'track',meta['metrics']['mean_track_error_km'],'pressure',pe)
|
| 68 |
+
|
| 69 |
+
def build():
|
| 70 |
+
meta=json.loads((DATA/'pressure_showcase.json').read_text())
|
| 71 |
+
rings=json.loads((DATA/'pressure_showcase_coastlines.json').read_text())
|
| 72 |
+
with np.load(DATA/'pressure_showcase.npz') as z: a={k:z[k] for k in z.files}
|
| 73 |
+
assert sha(DATA/'pressure_showcase.npz')==meta['data_sha256']
|
| 74 |
+
lat,lon=a['latitude'],a['longitude'];tracks=np.concatenate([a['forecast_lat_lon'],a['observed_lat_lon']])
|
| 75 |
+
bounds=[max(100,float(lon.min()),float(tracks[:,1].min()-3)),min(180,float(lon.max()),float(tracks[:,1].max()+3)),max(0,float(lat.min()),float(tracks[:,0].min()-3)),min(60,float(lat.max()),float(tracks[:,0].max()+3))]
|
| 76 |
+
ratio=(bounds[3]-bounds[2])/((bounds[1]-bounds[0])*np.cos(np.deg2rad((bounds[2]+bounds[3])/2)))
|
| 77 |
+
fields=a['pressure_hpa'];valid=(lat[:,None]>=0)&(lat[:,None]<=60)&(lon[None,:]>=100)&(lon[None,:]<=180)
|
| 78 |
+
lo=int(np.floor(fields[:,valid].min()/4)*4);hi=int(np.ceil(fields[:,valid].max()/4)*4)
|
| 79 |
+
levels=np.arange(lo,hi+2,2);frames=[]
|
| 80 |
+
for field in fields:
|
| 81 |
+
fig=plt.figure(figsize=(9,9*ratio));ax=fig.add_axes([0,0,1,1])
|
| 82 |
+
f=np.ma.masked_where(~valid,field)
|
| 83 |
+
ax.contourf(lon,lat,f,levels=levels,cmap='RdYlBu_r',extend='both')
|
| 84 |
+
contour=ax.contour(lon,lat,f,levels=np.arange(lo,hi+4,4),colors='#314656',linewidths=.65)
|
| 85 |
+
ax.clabel(contour,levels=np.arange(lo,hi+4,8),fontsize=8,fmt='%d',inline_spacing=5)
|
| 86 |
+
for ring in rings:
|
| 87 |
+
xy=np.asarray(ring);ax.plot(xy[:,0],xy[:,1],c='#4f6164',lw=.8)
|
| 88 |
+
ax.set(xlim=bounds[:2],ylim=bounds[2:]);ax.set_axis_off()
|
| 89 |
+
buf=io.BytesIO();fig.savefig(buf,format='png',dpi=115);plt.close(fig)
|
| 90 |
+
frames.append('data:image/png;base64,'+base64.b64encode(buf.getvalue()).decode())
|
| 91 |
+
packet={'meta':meta,'bounds':bounds,'ratio':ratio,'range':[lo,hi],'frames':frames,'fields':fields.round(2).tolist(),'latitude':lat.tolist(),'longitude':lon.tolist(),'forecast':a['forecast_lat_lon'].tolist(),'observed':a['observed_lat_lon'].tolist(),'pressure':a['central_pressure_hpa'].tolist(),'observedPressure':[float(v) if ok else None for v,ok in zip(a['observed_pressure_hpa'],a['pressure_mask'])]}
|
| 92 |
+
template=(REPO/'release_tools/pressure_showcase_template.html').read_text()
|
| 93 |
+
html=template.replace('/*__DATA__*/',json.dumps(packet,separators=(',',':'),allow_nan=False))
|
| 94 |
+
(REPO/'docs/trackformer_1_2_pressure.html').write_text(html)
|
| 95 |
+
# A real, clickable README preview; it is not a fabricated map.
|
| 96 |
+
fig,ax=plt.subplots(figsize=(10,8),layout='constrained');k=11
|
| 97 |
+
im=ax.contourf(lon,lat,np.ma.masked_where(~valid,fields[k]),levels=levels,cmap='RdYlBu_r')
|
| 98 |
+
cs=ax.contour(lon,lat,np.ma.masked_where(~valid,fields[k]),levels=np.arange(lo,hi+4,4),colors='#314656',linewidths=.6);ax.clabel(cs,levels=np.arange(lo,hi+4,8),fmt='%d',fontsize=8)
|
| 99 |
+
for ring in rings:
|
| 100 |
+
xy=np.asarray(ring);ax.plot(xy[:,0],xy[:,1],c='#4f6164',lw=.8)
|
| 101 |
+
for key,color,label,style in [('observed_lat_lon','#162437','Observed route','--'),('forecast_lat_lon','#b01467','1.2 mean of 50','-')]:
|
| 102 |
+
p=a[key];ax.plot(p[:,1],p[:,0],style,c=color,lw=2.3,label=label);ax.scatter(p[k+1,1],p[k+1,0],c=color,s=50,edgecolors='white',zorder=6)
|
| 103 |
+
ax.set(xlim=bounds[:2],ylim=bounds[2:],xlabel='Longitude °E',ylabel='Latitude °N',title='Trackformer 1.2 · PRAPIROON · +72 h\nModel pressure + forecast and observed routes')
|
| 104 |
+
ax.set_aspect(1/np.cos(np.deg2rad((bounds[2]+bounds[3])/2)));ax.legend();fig.colorbar(im,ax=ax,label='Model mean sea-level pressure (hPa)',shrink=.75)
|
| 105 |
+
fig.text(.5,-.015,'Click to explore +6 to +120 h · Selected best-performing example, not typical skill',ha='center',fontsize=10)
|
| 106 |
+
fig.savefig(REPO/'paper/trackformer_1_2_interactive_pressure_preview.png',dpi=150,bbox_inches='tight');plt.close(fig)
|
| 107 |
+
print('Built offline interactive map and README preview:',len(html),'bytes')
|
| 108 |
+
|
| 109 |
+
if __name__=='__main__':
|
| 110 |
+
p=argparse.ArgumentParser();p.add_argument('--source-root',type=Path);args=p.parse_args()
|
| 111 |
+
if args.source_root:prepare(args.source_root)
|
| 112 |
+
build()
|
release_tools/pressure_showcase_template.html
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html>
|
| 2 |
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Trackformer 1.2 · Interactive pressure forecast</title>
|
| 3 |
+
<style>
|
| 4 |
+
:root{color-scheme:light;--ink:#182f3b;--muted:#526c75;--line:#d4e1e5;--accent:#0c6870;--pink:#ac145f}*{box-sizing:border-box}body{margin:0;background:#f3f7f8;color:var(--ink);font:16px/1.5 system-ui,sans-serif}main{max-width:1200px;margin:auto;padding:30px 24px}header{display:flex;justify-content:space-between;align-items:start;gap:25px}h1{font-size:32px;line-height:1.15;margin:6px 0 14px;letter-spacing:-1px}p{margin:8px 0}.eyebrow{font-size:12px;letter-spacing:2px;text-transform:uppercase;color:var(--accent);font-weight:700}.sub{color:var(--muted);max-width:780px;font-size:14px}a{color:var(--accent)}.tag{border:1px solid var(--line);padding:5px 10px;border-radius:5px;white-space:nowrap;font-size:13px}.controls{display:flex;align-items:center;flex-wrap:wrap;gap:12px;margin:22px 0 14px;padding:16px;background:white;border:1px solid var(--line);border-radius:10px}button,select{font:inherit;color:var(--ink);border:1px solid #b6ced4;background:white;border-radius:6px;padding:8px 14px;cursor:pointer}button:focus-visible,input:focus-visible{outline:3px solid #158790;outline-offset:3px}#play{background:var(--accent);color:white;border-color:var(--accent);min-width:84px}input[type=range]{flex:1;min-width:140px;accent-color:var(--accent)}.date{min-width:195px;font-size:14px;font-variant-numeric:tabular-nums}.layout{display:grid;grid-template-columns:minmax(0,1fr) 265px;gap:20px}.mapcard,.aside{background:white;border:1px solid var(--line);border-radius:10px;overflow:hidden}#map{display:block;width:100%;height:auto;touch-action:pan-y}.legend{display:flex;gap:16px;flex-wrap:wrap;padding:12px 16px;border-bottom:1px solid var(--line);font-size:14px}.legend label{display:flex;align-items:center;gap:6px}.legend input{accent-color:var(--accent)}.key{display:inline-block;width:22px;border-top:3px solid var(--pink)}.key.obs{border-color:#162437;border-top-style:dashed}.bar{height:12px;background:linear-gradient(90deg,#313695,#74add1,#e0f3f8,#ffffbf,#fdae61,#d73027,#a50026)}.scale{padding:10px 16px 14px;font-size:12px;display:grid;gap:5px}.ticks{display:flex;justify-content:space-between}#hover{margin:0;padding:10px 16px;background:#f7fafb;color:#355762;font-size:13px;min-height:45px}.aside{padding:18px;height:max-content}h2{font-size:16px;margin:0 0 12px}.stat{padding:12px 0;border-bottom:1px solid #e8eff1;font-size:13px}.stat strong{display:block;font-size:23px;font-variant-numeric:tabular-nums;line-height:1.3}.stat span{color:var(--muted)}#curve{width:100%;margin:15px 0}details{margin-top:24px;font-size:14px}summary{cursor:pointer;font-weight:600}.note{background:#eaf2f4;border-left:3px solid #779daa;padding:12px 16px;margin:20px 0;font-size:13px;color:#35545c}footer{font-size:12px;color:var(--muted);margin:22px 0}.maptext{font-size:12px;fill:#294650}.touch{font-size:12px;color:var(--muted)}@media(max-width:800px){.layout{grid-template-columns:1fr}.aside{display:grid;grid-template-columns:1fr 1fr;gap:12px}.aside h2,.aside .touch,#curve{grid-column:1/-1}.stat{padding:3px 0}h1{font-size:25px}main{padding:20px 12px}header{display:block}.tag{display:inline-block;margin-top:10px}.date{min-width:0;width:100%}}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto}}
|
| 5 |
+
</style></head><body><main>
|
| 6 |
+
<header><div><div class="eyebrow">Trackformer 1.2 / field forecast</div><h1 id="title">Pressure, motion and the observed route</h1><p class="sub" id="subtitle"></p></div><span class="tag">50-member mean · selected showcase</span></header>
|
| 7 |
+
<div class="controls"><button id="back" aria-label="Previous six-hour forecast">−6 h</button><button id="play" aria-pressed="false">Play</button><button id="next" aria-label="Next six-hour forecast">+6 h</button><label for="lead" class="sr" style="font-size:13px">Lead</label><input id="lead" type="range" min="0" max="19" value="3" aria-label="Forecast lead time"><div class="date"><strong id="leadLabel"></strong><br><span id="valid"></span></div><label style="font-size:13px">Speed <select id="speed"><option value="1000">1×</option><option value="500">2×</option><option value="250">4×</option></select></label></div>
|
| 8 |
+
<div class="layout"><section class="mapcard" aria-label="Interactive model pressure and routes"><div class="legend"><label><input id="showForecast" type="checkbox" checked><span class="key"></span>1.2 forecast</label><label><input id="showObserved" type="checkbox" checked><span class="key obs"></span>Observed route</label><label><input id="full" type="checkbox" checked>Full 120 h paths</label></div><svg id="map" role="img" aria-label="Forecast sea-level pressure with forecast and observed storm paths"></svg><p id="hover" role="status">Hover or tap the map to inspect model pressure, position and valid time.</p><div class="scale"><div>Model mean sea-level pressure · hPa · isobars every 4 hPa</div><div class="bar"></div><div class="ticks"><span id="low"></span><span id="mid"></span><span id="high"></span></div></div></section>
|
| 9 |
+
<aside class="aside"><h2>At the selected lead</h2><div class="stat"><span>Forecast central pressure</span><strong id="pressure"></strong></div><div class="stat"><span>Observed central pressure</span><strong id="truthPressure"></strong></div><div class="stat"><span>Position error · great-circle</span><strong id="error"></strong></div><svg id="curve" viewBox="0 0 240 155" role="img" aria-label="Forecast and observed central pressure from 6 to 120 hours"></svg><p class="touch">Map markers and the chart cursor share the same valid time. Central pressure is the mean of member core samples, not the minimum of the mean map.</p></aside></div>
|
| 10 |
+
<p class="note" id="selection"></p><details><summary>Data, selection rule and model-field provenance</summary><p id="rule"></p><p id="fieldNote"></p><p id="routeNote"></p><p id="sourceHash" style="overflow-wrap:anywhere"></p><p>Observed routes and pressures are retrospective verification labels. They are not inputs to future forecast steps. This is a selected development example, not an untouched test or an operational warning.</p></details>
|
| 11 |
+
<footer>Research only. The colours and contours represent saved model-generated physical pressure; the field has not been moved to fit observations. <a href="https://github.com/yu314-coder/typhoon-predict">Source and paper</a> · <a href="https://huggingface.co/euler314/typhoon-predict">Model weights</a></footer>
|
| 12 |
+
</main><script>
|
| 13 |
+
const D=/*__DATA__*/;
|
| 14 |
+
const $=id=>document.getElementById(id),NS='http://www.w3.org/2000/svg';let k=3,timer=null;
|
| 15 |
+
function el(tag,attrs,parent){const e=document.createElementNS(NS,tag);for(const [a,v]of Object.entries(attrs))e.setAttribute(a,v);if(parent)parent.appendChild(e);return e}
|
| 16 |
+
const W=900,L=54,T=24,PW=820,PH=PW*D.ratio,H=PH+72;const map=$('map');map.setAttribute('viewBox',`0 0 ${W} ${H}`);
|
| 17 |
+
const [west,east,south,north]=D.bounds,x=lon=>L+(lon-west)/(east-west)*PW,y=lat=>T+(north-lat)/(north-south)*PH;
|
| 18 |
+
const image=el('image',{x:L,y:T,width:PW,height:PH,preserveAspectRatio:'none'},map);
|
| 19 |
+
const defs=el('defs',{},map),clip=el('clipPath',{id:'area'},defs);el('rect',{x:L,y:T,width:PW,height:PH},clip);
|
| 20 |
+
const grid=el('g',{},map);for(let lon=Math.ceil(west/5)*5;lon<=east;lon+=5){el('line',{x1:x(lon),x2:x(lon),y1:T,y2:T+PH,stroke:'#456878','stroke-opacity':.16},grid);el('text',{x:x(lon),y:T+PH+23,'text-anchor':'middle',class:'maptext'},grid).textContent=lon+'°E'}
|
| 21 |
+
for(let lat=Math.ceil(south/5)*5;lat<=north;lat+=5){el('line',{x1:L,x2:L+PW,y1:y(lat),y2:y(lat),stroke:'#456878','stroke-opacity':.16},grid);el('text',{x:L-9,y:y(lat)+4,'text-anchor':'end',class:'maptext'},grid).textContent=lat+'°N'}
|
| 22 |
+
el('rect',{x:L,y:T,width:PW,height:PH,fill:'none',stroke:'#a7bec4'},map);
|
| 23 |
+
const group=el('g',{'clip-path':'url(#area)'},map);
|
| 24 |
+
function route(color,dash){const halo=el('path',{fill:'none',stroke:'white','stroke-width':6,'stroke-opacity':.85},group),p=el('path',{fill:'none',stroke:color,'stroke-width':3,'stroke-dasharray':dash},group),marker=el('circle',{r:7,fill:color,stroke:'white','stroke-width':2},group);return {halo,p,marker}}
|
| 25 |
+
const truth=route('#162437','8 5'),pred=route('#ac145f','');
|
| 26 |
+
const hit=el('rect',{x:L,y:T,width:PW,height:PH,fill:'transparent','pointer-events':'all'},map);
|
| 27 |
+
const path=p=>p.map((v,i)=>(i?'L':'M')+x(v[1]).toFixed(2)+','+y(v[0]).toFixed(2)).join(' ');
|
| 28 |
+
function date(n){return new Date(Date.parse(D.meta.issue_time_utc)+n*3600000).toISOString().slice(0,16).replace('T',' ')+' UTC'}
|
| 29 |
+
function hav(a,b){const r=Math.PI/180,p=(b[0]-a[0])*r,q=(b[1]-a[1])*r,z=Math.sin(p/2)**2+Math.cos(a[0]*r)*Math.cos(b[0]*r)*Math.sin(q/2)**2;return 6371*2*Math.asin(Math.sqrt(Math.min(1,z)))}
|
| 30 |
+
function drawCurve(){const svg=$('curve');svg.replaceChildren();const vals=[...D.pressure,...D.observedPressure.filter(v=>v!==null)],min=Math.floor(Math.min(...vals)/5)*5-5,max=Math.ceil(Math.max(...vals)/5)*5+5;const cx=i=>35+i/19*192,cy=v=>115-(v-min)/(max-min)*90;
|
| 31 |
+
for(let v=min;v<=max;v+=10){el('line',{x1:35,x2:227,y1:cy(v),y2:cy(v),stroke:'#dde7ea'},svg);el('text',{x:31,y:cy(v)+3,'text-anchor':'end',fill:'#506873','font-size':10},svg).textContent=v}
|
| 32 |
+
for(const [values,color,dash]of [[D.pressure,'#ac145f',''],[D.observedPressure,'#162437','4 3']]){let p='',gap=true;values.forEach((v,i)=>{if(v===null){gap=true;return}p+=(gap?'M':'L')+cx(i)+','+cy(v);gap=false});el('path',{d:p,fill:'none',stroke:color,'stroke-width':2,'stroke-dasharray':dash},svg)}
|
| 33 |
+
el('line',{x1:cx(k),x2:cx(k),y1:20,y2:120,stroke:'#377782','stroke-width':1.5},svg);for(const i of [0,9,19])el('text',{x:cx(i),y:137,'text-anchor':'middle',fill:'#506873','font-size':11},svg).textContent='+'+(i+1)*6+'h';el('text',{x:35,y:12,fill:'#506873','font-size':11},svg).textContent='Central pressure · hPa'}
|
| 34 |
+
function render(){const lead=(k+1)*6;image.setAttribute('href',D.frames[k]);$('lead').value=k;$('leadLabel').textContent='+'+lead+' hours';$('valid').textContent=date(lead);$('pressure').textContent=D.pressure[k].toFixed(1)+' hPa';$('truthPressure').textContent=D.observedPressure[k]===null?'Not available':D.observedPressure[k].toFixed(0)+' hPa';$('error').textContent=hav(D.forecast[k+1],D.observed[k+1]).toFixed(1)+' km';
|
| 35 |
+
for(const [obj,coords,id]of [[pred,D.forecast,'showForecast'],[truth,D.observed,'showObserved']]){let d=path($('full').checked?coords:coords.slice(0,k+2));obj.p.setAttribute('d',d);obj.halo.setAttribute('d',d);obj.marker.setAttribute('cx',x(coords[k+1][1]));obj.marker.setAttribute('cy',y(coords[k+1][0]));for(const e of Object.values(obj))e.style.display=$(id).checked?'':'none'}drawCurve();$('back').disabled=k===0;$('next').disabled=k===19;$('hover').textContent='Hover or tap: model pressure on the fixed grid · '+date(lead)}
|
| 36 |
+
function stop(){if(timer)clearInterval(timer);timer=null;$('play').textContent='Play';$('play').setAttribute('aria-pressed','false')}
|
| 37 |
+
function play(){if(k===19)k=0;render();$('play').textContent='Pause';$('play').setAttribute('aria-pressed','true');timer=setInterval(()=>{if(k===19){stop();return}k++;render()},Number($('speed').value))}
|
| 38 |
+
$('play').onclick=()=>timer?stop():play();$('speed').onchange=()=>{if(timer){stop();play()}};$('back').onclick=()=>{stop();k=Math.max(0,k-1);render()};$('next').onclick=()=>{stop();k=Math.min(19,k+1);render()};$('lead').oninput=e=>{stop();k=+e.target.value;render()};for(const id of ['showForecast','showObserved','full'])$(id).onchange=render;document.addEventListener('visibilitychange',()=>{if(document.hidden)stop()});
|
| 39 |
+
function inspect(event){const pt=map.createSVGPoint();pt.x=event.clientX;pt.y=event.clientY;const p=pt.matrixTransform(map.getScreenCTM().inverse());const lon=west+(p.x-L)/PW*(east-west),lat=north-(p.y-T)/PH*(north-south);const ix=Math.max(0,Math.min(120,Math.round((lon-D.longitude[0])/.25))),iy=Math.max(0,Math.min(120,Math.round((D.latitude[0]-lat)/.25)));let text=lat.toFixed(2)+'°N, '+lon.toFixed(2)+'°E · model mean '+D.fields[k][iy][ix].toFixed(1)+' hPa';for(const [coords,label,id]of [[D.forecast,'1.2 forecast','showForecast'],[D.observed,'Observed route','showObserved']])if($(id).checked){const end=$('full').checked?21:k+2;for(let i=0;i<end;i++)if(Math.hypot(x(coords[i][1])-p.x,y(coords[i][0])-p.y)<14){text=label+' · +'+i*6+' h · '+coords[i][0].toFixed(2)+'°N, '+coords[i][1].toFixed(2)+'°E · '+date(i*6);break}}$('hover').textContent=text}
|
| 40 |
+
hit.addEventListener('pointermove',inspect);hit.addEventListener('pointerdown',inspect);
|
| 41 |
+
$('title').textContent='PRAPIROON · pressure and route';$('subtitle').textContent='Issue '+date(0)+' · Actual model pressure fields against the observed best-track route.';$('low').textContent=D.range[0];$('mid').textContent=(D.range[0]+D.range[1])/2;$('high').textContent=D.range[1];$('selection').textContent='Selected best-performing example from the saved 270-case development benchmark: '+D.meta.metrics.mean_track_error_km.toFixed(1)+' km mean local-coordinate track error and '+D.meta.central_pressure_mae_hpa.toFixed(2)+' hPa central-pressure MAE. This selection is not typical performance.';$('rule').textContent=D.meta.selection_rule;$('fieldNote').textContent=D.meta.field_source+' Native regional history available: '+D.meta.native_history_available+'.';$('routeNote').textContent=D.meta.observed_route_source;$('sourceHash').textContent='Checkpoint SHA-256: '+D.meta.checkpoint_sha256;render();
|
| 42 |
+
</script></body></html>
|