{
  "id": "grand-isle-wind-2025-v1",
  "version": "1.0.0",
  "selected_lag_hours": 12,
  "scope": "Grand Isle station 8761724, 2025; held-out observed-weather residual estimation; no causal or catch inference",
  "source_records": {
    "wind": 8760,
    "pressure": 8760,
    "observed": 8760,
    "predicted": 8760
  },
  "expected_hours": 8760,
  "common_hours": 8693,
  "excluded_hours": 67,
  "valid_weather_hours": {
    "wind": 8752,
    "pressure": 8755
  },
  "exclusion_reason_counts_overlapping": {
    "wind_unavailable_lag_3": 11,
    "wind_unavailable_lag_6": 14,
    "wind_unavailable_lag_12": 20,
    "wind_unavailable_lag_24": 32,
    "previous_target_unavailable": 3,
    "pressure_missing_or_flagged": 5,
    "wind_unavailable_lag_0": 8,
    "target_missing_or_flagged": 2
  },
  "splits": {
    "train": {
      "expected_hours": 4272,
      "admitted_hours": 4232
    },
    "validation": {
      "expected_hours": 2136,
      "admitted_hours": 2110
    },
    "test": {
      "expected_hours": 2208,
      "admitted_hours": 2208
    }
  },
  "boundary_gap_common_hours": 143,
  "candidate_validation_scores": [
    {
      "lag_hours": 0,
      "hours": 2110,
      "mae_ft": 0.32337006671245955,
      "rmse_ft": 0.38523542763809704,
      "bias_ft": 0.30255146504313307
    },
    {
      "lag_hours": 3,
      "hours": 2110,
      "mae_ft": 0.3113595880522423,
      "rmse_ft": 0.37169950939976254,
      "bias_ft": 0.28871901302742675
    },
    {
      "lag_hours": 6,
      "hours": 2110,
      "mae_ft": 0.302278015848975,
      "rmse_ft": 0.3603691185248362,
      "bias_ft": 0.27842355420538534
    },
    {
      "lag_hours": 12,
      "hours": 2110,
      "mae_ft": 0.2880638530034371,
      "rmse_ft": 0.34468976977224874,
      "bias_ft": 0.2665732108019115
    },
    {
      "lag_hours": 24,
      "hours": 2110,
      "mae_ft": 0.2922200960937415,
      "rmse_ft": 0.3469553654434575,
      "bias_ft": 0.2734887867069333
    }
  ],
  "scores": {
    "train": {
      "tide_only": {
        "hours": 4232,
        "mae_ft": 0.31204914933837424,
        "rmse_ft": 0.36907817267149934,
        "bias_ft": -0.22384546313799622
      },
      "training_mean": {
        "hours": 4232,
        "mae_ft": 0.2270333640352915,
        "rmse_ft": 0.29344830238914155,
        "bias_ft": 0.0
      },
      "season": {
        "hours": 4232,
        "mae_ft": 0.22374012447636252,
        "rmse_ft": 0.2900889223622632,
        "bias_ft": -9.842998082215471e-17
      },
      "season_pressure": {
        "hours": 4232,
        "mae_ft": 0.17169346264259097,
        "rmse_ft": 0.2185306547412406,
        "bias_ft": 1.4397221075479345e-16
      },
      "season_wind": {
        "hours": 4232,
        "mae_ft": 0.19080849991919335,
        "rmse_ft": 0.24498904496080376,
        "bias_ft": 3.3159780319617154e-17
      },
      "season_pressure_wind": {
        "hours": 4232,
        "mae_ft": 0.14321856049773235,
        "rmse_ft": 0.1825752169203703,
        "bias_ft": 7.009725713134259e-17
      },
      "persistence_1h": {
        "hours": 4232,
        "mae_ft": 0.040019848771266534,
        "rmse_ft": 0.0663267638515899,
        "bias_ft": -9.87712665406425e-05
      }
    },
    "validation": {
      "tide_only": {
        "hours": 2110,
        "mae_ft": 0.28666350710900473,
        "rmse_ft": 0.34258959183842547,
        "bias_ft": -0.27992417061611374
      },
      "training_mean": {
        "hours": 2110,
        "mae_ft": 0.163277818740537,
        "rmse_ft": 0.20531660569305168,
        "bias_ft": -0.05607870747811752
      },
      "season": {
        "hours": 2110,
        "mae_ft": 0.16868824777003494,
        "rmse_ft": 0.20428039158461778,
        "bias_ft": 0.05965685263565107
      },
      "season_pressure": {
        "hours": 2110,
        "mae_ft": 0.3233891033766552,
        "rmse_ft": 0.3818577138781185,
        "bias_ft": 0.30762696392097943
      },
      "season_wind": {
        "hours": 2110,
        "mae_ft": 0.1635975649679238,
        "rmse_ft": 0.19609041207162387,
        "bias_ft": 0.036079855365226496
      },
      "season_pressure_wind": {
        "hours": 2110,
        "mae_ft": 0.2880638530034371,
        "rmse_ft": 0.34468976977224874,
        "bias_ft": 0.2665732108019115
      },
      "persistence_1h": {
        "hours": 2110,
        "mae_ft": 0.03237535545023696,
        "rmse_ft": 0.04842588513089771,
        "bias_ft": 0.00046919431279620835
      }
    },
    "test": {
      "tide_only": {
        "hours": 2208,
        "mae_ft": 0.28656340579710143,
        "rmse_ft": 0.38673257809049616,
        "bias_ft": -0.13956249999999998
      },
      "training_mean": {
        "hours": 2208,
        "mae_ft": 0.2871038648769897,
        "rmse_ft": 0.3703890028410571,
        "bias_ft": 0.08428296313799623
      },
      "season": {
        "hours": 2208,
        "mae_ft": 0.28815518803979884,
        "rmse_ft": 0.36896442036733584,
        "bias_ft": 0.12349500370751798
      },
      "season_pressure": {
        "hours": 2208,
        "mae_ft": 0.45203162718407325,
        "rmse_ft": 0.5172605453017832,
        "bias_ft": 0.4356009140714744
      },
      "season_wind": {
        "hours": 2208,
        "mae_ft": 0.290277515454439,
        "rmse_ft": 0.35587095360844695,
        "bias_ft": 0.17183525804060656
      },
      "season_pressure_wind": {
        "hours": 2208,
        "mae_ft": 0.4345543416738768,
        "rmse_ft": 0.49240621496283205,
        "bias_ft": 0.42529493557441117
      },
      "persistence_1h": {
        "hours": 2208,
        "mae_ft": 0.03351086956521739,
        "rmse_ft": 0.056118267647603984,
        "bias_ft": 0.00016938405797101453
      }
    }
  },
  "coefficients": {
    "season": [
      0.2636311923797058,
      -0.05854037649530931,
      -0.06025260628219611
    ],
    "season_pressure": [
      0.6047513929174566,
      -0.2639503313666099,
      0.061954778648015435,
      -0.42037026242882886
    ],
    "season_wind": [
      0.2503693440298078,
      -0.09205562680750619,
      -0.014429129059034212,
      -0.016101981994969185,
      0.016748465257473328
    ],
    "season_pressure_wind": [
      0.5504559063281974,
      -0.24566651003849604,
      0.04715667814931957,
      -0.4038116304386493,
      -0.01886725970950633,
      0.002685027013562943
    ]
  },
  "wind_increment_mae_reduction_ft": 0.017477285510196408,
  "wind_increment_mae_reduction_percent": 3.8663855489650123,
  "paired_block_interval_ft": {
    "72": [
      -0.0015812974273549667,
      0.03810953623572338
    ],
    "24": [
      0.0023126126562203623,
      0.033012081945245374
    ]
  },
  "episodes": [
    {
      "selection": "highest_daily_test_residual",
      "date": "2025-10-05",
      "hours": 24,
      "mean_residual_ft": 1.1081666666666667,
      "mean_wind_eastward_knots": -10.993984275414272,
      "mean_wind_northward_knots": 0.03207703945805562,
      "mean_wind_speed_knots": 11.663333333333332,
      "mean_pressure_mb": 1011.6416666666668
    },
    {
      "selection": "lowest_daily_test_residual",
      "date": "2025-11-11",
      "hours": 24,
      "mean_residual_ft": -0.7739583333333333,
      "mean_wind_eastward_knots": -4.182644496751188,
      "mean_wind_northward_knots": -7.480868953687718,
      "mean_wind_speed_knots": 10.424166666666666,
      "mean_pressure_mb": 1030.8458333333333
    }
  ],
  "monthly": [
    {
      "month": "2025-01",
      "expected_hours": 744,
      "common_hours": 720,
      "split": "train",
      "mae_ft": {
        "tide_only": 0.28986666666666666,
        "training_mean": 0.2811635620142827,
        "season": 0.27547785755745474,
        "season_pressure": 0.1837614137127431,
        "season_wind": 0.21385390870042542,
        "season_pressure_wind": 0.15275036961576174,
        "persistence_1h": 0.04707916666666667
      }
    },
    {
      "month": "2025-02",
      "expected_hours": 672,
      "common_hours": 672,
      "split": "train",
      "mae_ft": {
        "tide_only": 0.3153705357142857,
        "training_mean": 0.2062222662930957,
        "season": 0.2152017936835422,
        "season_pressure": 0.14456455225795137,
        "season_wind": 0.19868011710158942,
        "season_pressure_wind": 0.15328656356360654,
        "persistence_1h": 0.03891369047619048
      }
    },
    {
      "month": "2025-03",
      "expected_hours": 744,
      "common_hours": 744,
      "split": "train",
      "mae_ft": {
        "tide_only": 0.32571774193548386,
        "training_mean": 0.3137341898388113,
        "season": 0.3108307285759645,
        "season_pressure": 0.2194342443907365,
        "season_wind": 0.24257107485462798,
        "season_pressure_wind": 0.1739390229777537,
        "persistence_1h": 0.04509408602150537
      }
    },
    {
      "month": "2025-04",
      "expected_hours": 720,
      "common_hours": 720,
      "split": "train",
      "mae_ft": {
        "tide_only": 0.3157777777777778,
        "training_mean": 0.26834742438563325,
        "season": 0.2678430317340911,
        "season_pressure": 0.2345251087566234,
        "season_wind": 0.1961089366889495,
        "season_pressure_wind": 0.16105563876627071,
        "persistence_1h": 0.030637500000000005
      }
    },
    {
      "month": "2025-05",
      "expected_hours": 744,
      "common_hours": 733,
      "split": "train",
      "mae_ft": {
        "tide_only": 0.3032673942701228,
        "training_mean": 0.1453836636089097,
        "season": 0.14560399075784944,
        "season_pressure": 0.1291928735620481,
        "season_wind": 0.16836989899033933,
        "season_pressure_wind": 0.12539392056890133,
        "persistence_1h": 0.043126875852660305
      }
    },
    {
      "month": "2025-06",
      "expected_hours": 720,
      "common_hours": 714,
      "split": "boundary_gap + train",
      "mae_ft": {
        "tide_only": 0.34478011204481795,
        "training_mean": 0.15252301525525142,
        "season": 0.12395734630249862,
        "season_pressure": 0.12134161375572099,
        "season_wind": 0.1259323106880288,
        "season_pressure_wind": 0.10105043935861754,
        "persistence_1h": 0.034515406162464984
      }
    },
    {
      "month": "2025-07",
      "expected_hours": 744,
      "common_hours": 742,
      "split": "validation",
      "mae_ft": {
        "tide_only": 0.2261199460916442,
        "training_mean": 0.13055462042505056,
        "season": 0.17093647018396105,
        "season_pressure": 0.22541650447158806,
        "season_wind": 0.15394983773935694,
        "season_pressure_wind": 0.16900108110026352,
        "persistence_1h": 0.03765902964959568
      }
    },
    {
      "month": "2025-08",
      "expected_hours": 744,
      "common_hours": 739,
      "split": "validation",
      "mae_ft": {
        "tide_only": 0.34961569688768607,
        "training_mean": 0.20372487024564434,
        "season": 0.1693153098476808,
        "season_pressure": 0.30241242904402915,
        "season_wind": 0.16044241324942768,
        "season_pressure_wind": 0.2610654672747946,
        "persistence_1h": 0.034422192151556154
      }
    },
    {
      "month": "2025-09",
      "expected_hours": 720,
      "common_hours": 701,
      "split": "boundary_gap + validation",
      "mae_ft": {
        "tide_only": 0.26242510699001426,
        "training_mean": 0.16228225880392308,
        "season": 0.18243439851906249,
        "season_pressure": 0.5000197412991101,
        "season_wind": 0.19544065575336578,
        "season_pressure_wind": 0.49477758052463283,
        "persistence_1h": 0.023410841654778886
      }
    },
    {
      "month": "2025-10",
      "expected_hours": 744,
      "common_hours": 744,
      "split": "test",
      "mae_ft": {
        "tide_only": 0.4639650537634409,
        "training_mean": 0.32916734760249605,
        "season": 0.2998804450661474,
        "season_pressure": 0.385781551543597,
        "season_wind": 0.2361126469249157,
        "season_pressure_wind": 0.36142371197874185,
        "persistence_1h": 0.032022849462365596
      }
    },
    {
      "month": "2025-11",
      "expected_hours": 720,
      "common_hours": 720,
      "split": "test",
      "mae_ft": {
        "tide_only": 0.21330555555555558,
        "training_mean": 0.32755644691241337,
        "season": 0.3643209204368526,
        "season_pressure": 0.6222173734435809,
        "season_wind": 0.4140649192095427,
        "season_pressure_wind": 0.6047989623179324,
        "persistence_1h": 0.027162500000000003
      }
    },
    {
      "month": "2025-12",
      "expected_hours": 744,
      "common_hours": 744,
      "split": "test",
      "mae_ft": {
        "tide_only": 0.1800564516129032,
        "training_mean": 0.20589272211720228,
        "season": 0.2027211577259789,
        "season_pressure": 0.3535858193476067,
        "season_wind": 0.2246481222854746,
        "season_pressure_wind": 0.3429321126812162,
        "persistence_1h": 0.04114247311827957
      }
    }
  ],
  "source_provenance": {
    "protocol": "grand-isle-wind-2025-v1",
    "sources": [
      {
        "file": "wind.json",
        "url": "https://api.tidesandcurrents.noaa.gov/api/prod/datagetter?station=8761724&begin_date=20250101&end_date=20251231&units=english&time_zone=gmt&format=json&interval=h&application=LouisianaDeepSeaFishingResearch&product=wind",
        "retrievedAt": "2026-10-21T20:39:37.664Z",
        "sha256": "b0747ec0a848670b009fe768717eca42ac45efb3ffe05c3a65b9b8848451a942",
        "bytes": 738962
      },
      {
        "file": "air_pressure.json",
        "url": "https://api.tidesandcurrents.noaa.gov/api/prod/datagetter?station=8761724&begin_date=20250101&end_date=20251231&units=english&time_zone=gmt&format=json&interval=h&application=LouisianaDeepSeaFishingResearch&product=air_pressure",
        "retrievedAt": "2026-10-21T20:39:38.896Z",
        "sha256": "a20314b621eb2defa23eeaa2ecc4be5150fb2f4eabccc40309bb684973bfb21d",
        "bytes": 455580
      },
      {
        "file": "sensors.json",
        "url": "https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi/stations/8761724/sensors.json",
        "retrievedAt": "2026-10-21T20:39:39.004Z",
        "sha256": "06a35eb3abf220008007a5df19afd0ee5d62a5b1b2cce4cbb7cfbfa9fba4194f",
        "bytes": 1383
      },
      {
        "file": "station.json",
        "url": "https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi/stations/8761724.json",
        "retrievedAt": "2026-10-21T20:39:39.079Z",
        "sha256": "99438003fe4d52ce34db0aabf10087cb379e33fef8af493cf803e8bbcdd3e10d",
        "bytes": 2634
      },
      {
        "file": "observations.json",
        "url": "https://api.tidesandcurrents.noaa.gov/api/prod/datagetter?station=8761724&begin_date=20250101&end_date=20251231&datum=MLLW&units=english&time_zone=gmt&format=json&application=LouisianaDeepSeaFishingResearch&product=hourly_height",
        "retrievedAt": "2026-10-21T20:22:38.957Z",
        "sha256": "be3c69d2df3280d2f54d2942c1b7d3614434e1111ac2cfa9810502bd9271d6c3",
        "bytes": 540569,
        "reuse": "Unchanged retained full-year study input"
      },
      {
        "file": "predictions.json",
        "url": "https://api.tidesandcurrents.noaa.gov/api/prod/datagetter?station=8761724&begin_date=20250101&end_date=20251231&datum=MLLW&units=english&time_zone=gmt&format=json&application=LouisianaDeepSeaFishingResearch&product=predictions&interval=h",
        "retrievedAt": "2026-10-21T20:22:39.232Z",
        "sha256": "07fc621fc0e0356127083c73338a775358e75b9c15e4750af28c34b3e49819b1",
        "bytes": 333478,
        "reuse": "Unchanged retained full-year study input"
      }
    ],
    "attribution": "Source weather observations and station metadata: NOAA CO-OPS. Analysis: Louisiana Deep Sea Fishing. No NOAA endorsement.",
    "rights": "https://tidesandcurrents.noaa.gov/disclaimers.html",
    "reuseNote": "NOAA CO-OPS public-domain source material, with attribution; no third-party restriction noted in these API responses. Our calculations are separately identified."
  },
  "protocol": {
    "id": "grand-isle-wind-2025-v1",
    "version": "1.0.0",
    "fixedBeforeFitting": "2026-10-21",
    "station": "8761724",
    "period": "2025-01-01T00:00:00Z/2025-12-31T23:00:00Z",
    "target": "Retained annual quality-screened observed minus predicted height, ft MLLW, exact UTC hour",
    "weather": "NOAA CO-OPS wind and air_pressure, interval=h, units=english, time_zone=gmt. On-the-hour six-minute weather observations, not hourly averages. Wind knots; pressure millibars (hPa).",
    "quality": "Exact hour; finite numeric values; wind s>=0 and 0<=d<=360 with f=0,0; pressure v>0 with f=0,0,0. No interpolation. Duplicate/off-grid/out-of-period timestamps and wrong station fail. Calm speed zero permits missing direction with valid flags; components zero.",
    "lagsHours": [
      0,
      3,
      6,
      12,
      24
    ],
    "commonSample": "Target eligible; current pressure; wind at every candidate lag; previous-hour target for persistence benchmark. All models compared on identical hours. Report exclusion reasons on all 8760 hours.",
    "split": {
      "trainStart": "2025-01-01",
      "trainEndExclusive": "2025-06-28",
      "validationStart": "2025-07-01",
      "validationEndExclusive": "2025-09-28",
      "testStart": "2025-10-01",
      "testEndExclusive": "2026-01-01",
      "boundaryGapHours": 72
    },
    "models": "OLS with intercept. Season: annual sine/cosine with 8760-hour period. Pressure: current (mb-1013.25)/10. Wind: eastward=-s*sin(d), northward=-s*cos(d), one candidate lag. Compare zero correction (tide alone), training mean, season, season+pressure, season+wind, season+pressure+wind and previous-hour residual persistence. No test-period fit or refit.",
    "selection": "Choose one lag by validation MAE of season+pressure+wind; ties use first listed lag. Keep training-only coefficients fixed; report all candidate validation errors and final test comparisons at selected lag. No selection by test results.",
    "primaryComparison": "Test MAE reduction adding wind to season+pressure, in feet and percent; report RMSE and signed mean error (estimate minus observation) too. Same-hour residual estimation with observed weather, not future-weather forecasting or causality.",
    "uncertainty": "Paired circular moving-block bootstrap of test per-hour absolute-error improvement on full test grid; retain missing rows; 72-hour blocks, 2000 draws, seed 8761724; 24-hour sensitivity. Percentile 2.5/97.5 bounds are within-this-period descriptive resampling, not population/climate confidence.",
    "episodes": "Illustrate highest and lowest test-period daily mean residual among UTC days with at least 20 eligible common-sample hours. Show +/-48h context and explain selection on target extrema, not typicality or model fit.",
    "limits": "Single station and year; observational, autocorrelated; simple annual harmonic trained on half-year is an imperfect seasonal control, so also report mean and pressure controls. No river, offshore wind field, sensor-height adjustment or historical maintenance control. No catch, current, access-depth or safety conclusion. Independent scientific review pending."
  },
  "software": {
    "python": "3.11+",
    "numpy": "2.5.4"
  },
  "review_status": "Local review; independent scientific review not performed"
}
