From d54e00bad5e6c2f4daf8c017d055ae376c7a750c Mon Sep 17 00:00:00 2001 From: Aidan Rickert Date: Thu, 13 Aug 2026 12:37:09 -0700 Subject: [PATCH 001/205] auth: bind-mount onshape allowlist for live server edits; fix stale reload comments --- auth/allowlist.py | 3 ++- auth/{ => allowlists}/onshape_allowlist.txt | 5 +++-- daq-server/diablo_server/backend/operators.txt | 7 +++++-- docker-compose.yml | 10 ++++++++++ 4 files changed, 20 insertions(+), 5 deletions(-) rename auth/{ => allowlists}/onshape_allowlist.txt (75%) diff --git a/auth/allowlist.py b/auth/allowlist.py index d68043395..9965362ee 100644 --- a/auth/allowlist.py +++ b/auth/allowlist.py @@ -29,7 +29,8 @@ # map has no allowlist: the shared @berkeley.edu gate is the whole check. _APP_FILES = { "onshape-viewer": os.environ.get( - "ONSHAPE_ALLOWLIST_FILE", os.path.join(_HERE, "onshape_allowlist.txt") + "ONSHAPE_ALLOWLIST_FILE", + os.path.join(_HERE, "allowlists", "onshape_allowlist.txt"), ), } diff --git a/auth/onshape_allowlist.txt b/auth/allowlists/onshape_allowlist.txt similarity index 75% rename from auth/onshape_allowlist.txt rename to auth/allowlists/onshape_allowlist.txt index 778ebca3c..3c78c29d3 100644 --- a/auth/onshape_allowlist.txt +++ b/auth/allowlists/onshape_allowlist.txt @@ -7,8 +7,9 @@ # tools. See auth/allowlist.py. # # Edits take effect on the user's next request (the file is re-read on change); -# no restart needed. In production this file can be overridden by mounting one -# at $ONSHAPE_ALLOWLIST_FILE. +# no restart or rebuild needed. In production docker-compose bind-mounts this +# directory into the auth container at /config (ONSHAPE_ALLOWLIST_FILE), so +# editing this file on the server is picked up live. aidanrickert@berkeley.edu aahilsyed72@berkeley.edu diff --git a/daq-server/diablo_server/backend/operators.txt b/daq-server/diablo_server/backend/operators.txt index 12ed38233..34b500819 100644 --- a/daq-server/diablo_server/backend/operators.txt +++ b/daq-server/diablo_server/backend/operators.txt @@ -8,8 +8,11 @@ # In dev (no Caddy in front → no X-Auth-Email), control is allowed to anyone # locally — the password remains as a fat-finger guard. # -# Committed on purpose: adding an email here grants nothing until someone with -# server/deploy access pulls and restarts. Deploy access is the real gate. +# Committed on purpose: the source of truth is version-controlled, and adding +# someone still requires server/deploy access to edit the file on the box -- +# deploy access is the real gate. The running backend re-reads this file on +# change (mtime-cached), so an edit on the server takes effect on the next +# command; no restart or redeploy needed. aidanrickert@berkeley.edu aahilsyed72@berkeley.edu diff --git a/docker-compose.yml b/docker-compose.yml index 16666764c..52cdd618c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -115,6 +115,16 @@ services: # needs no auth/.env at all. On a login node, keep the Google/Flask secrets # in auth/.env; JWT_SECRET here still wins, so set it in root .env. JWT_SECRET: ${JWT_SECRET:-} + # Read the onshape allowlist from the bind-mounted config dir below, not + # the copy baked into the image, so it can be edited live on the server. + ONSHAPE_ALLOWLIST_FILE: /config/onshape_allowlist.txt + volumes: + # Editable-on-the-server allowlists. allowlist.py re-reads on mtime change, + # so edits here take effect on the user's next request -- no restart, no + # rebuild. Mount the *directory* (not the single file): an editor that + # saves via rename swaps the inode, which a single-file bind mount would + # not follow and the mtime watch would never see. + - ./auth/allowlists:/config:ro # ── Engine Design ──────────────────────────────────────────────────────── # Built from the repo root: the native-builder stage and runtime copy several From 1b43e20e2e02a82bb242e8ea3ae035a5a668130b Mon Sep 17 00:00:00 2001 From: Aidan Rickert Date: Thu, 13 Aug 2026 12:48:06 -0700 Subject: [PATCH 002/205] auth: add tchang27 to onshape allowlist and DAQ operators --- auth/allowlists/onshape_allowlist.txt | 3 ++- daq-server/diablo_server/backend/operators.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/auth/allowlists/onshape_allowlist.txt b/auth/allowlists/onshape_allowlist.txt index 3c78c29d3..5e73cf59c 100644 --- a/auth/allowlists/onshape_allowlist.txt +++ b/auth/allowlists/onshape_allowlist.txt @@ -17,4 +17,5 @@ aahilsyed72@berkeley.edu manank_doshi@berkeley.edu rchikka15@berkeley.edu inez9@berkeley.edu -carlosbautista@berkeley.edu \ No newline at end of file +carlosbautista@berkeley.edu +tchang27@berkeley.edu \ No newline at end of file diff --git a/daq-server/diablo_server/backend/operators.txt b/daq-server/diablo_server/backend/operators.txt index 34b500819..b024bae03 100644 --- a/daq-server/diablo_server/backend/operators.txt +++ b/daq-server/diablo_server/backend/operators.txt @@ -21,3 +21,4 @@ manank_doshi@berkeley.edu rchikka15@berkeley.edu inez9@berkeley.edu carlosbautista@berkeley.edu +tchang27@berkeley.edu From 7a2061c93485f1ef871d28aeda9782c6d7d2085f Mon Sep 17 00:00:00 2001 From: Aidan Rickert Date: Thu, 13 Aug 2026 13:17:33 -0700 Subject: [PATCH 003/205] daq-server: drop control password, gate operator control on allowlist identity alone --- .../diablo_server/backend/src/server.ts | 30 +++++------- .../frontend/components/dashboard/TopBar.tsx | 46 ++++++------------- .../frontend/lib/control-mode.tsx | 24 ++++------ daq-server/diablo_server/shared/types.ts | 2 +- 4 files changed, 37 insertions(+), 65 deletions(-) diff --git a/daq-server/diablo_server/backend/src/server.ts b/daq-server/diablo_server/backend/src/server.ts index 40add1bb2..c7c0bfb93 100644 --- a/daq-server/diablo_server/backend/src/server.ts +++ b/daq-server/diablo_server/backend/src/server.ts @@ -48,10 +48,6 @@ import type { SensorUpdate, StateUpdate, CommandPayload, BoardStatus, ActuatorUp // ── Config ─────────────────────────────────────────────────────────────────── const WS_PORT = parseInt(process.env.WS_PORT ?? '8081', 10); -// Engine-control fat-finger password (server-side). Shared, not per-user; the -// real authorization is the operators allowlist (see operators.ts). Default is -// the well-known dev value; set CONTROL_PASSWORD on the deployed server. -const CONTROL_PASSWORD = process.env.CONTROL_PASSWORD || 'diablo'; // Command types that actuate/transition the engine — gated by the operator // unlock. Read-only queries and countdown display are not. const CONTROL_COMMAND_TYPES = new Set(['state_transition', 'actuator', 'extend_fire', 'debug_mode', 'session_start', 'session_stop', 'session_extend']); @@ -622,8 +618,9 @@ wss.on('connection', (ws: WebSocket, req) => { // Engine-control authorization. Caddy injects X-Auth-Email on the upgrade // (from the session cookie). No header ⇒ no Caddy in front (dev/test-stand) ⇒ - // trusted local ⇒ treat as operator. Control still requires the password - // unlock below (__daqControlAuthorized) — a fat-finger guard in every env. + // trusted local ⇒ treat as operator. Approved operators still explicitly arm + // control via the toggle below (__daqControlAuthorized) — a fat-finger guard + // in every env. const authEmail = ((req.headers['x-auth-email'] as string | undefined) || '').trim(); const isOp = authEmail === '' ? true : isOperator(authEmail); (ws as WsWithControl).__daqOperator = isOp; @@ -644,8 +641,7 @@ wss.on('connection', (ws: WebSocket, req) => { lastOutboundAt = Date.now(); // Control authorization status — lets the UI enable/disable the arm step - // before any password is typed (non-operators see it disabled, never a - // false-armed state). + // before arming (non-operators see it disabled, never a false-armed state). send(ws, { type: MessageType.CONTROL_STATUS, timestamp: Date.now(), payload: { operator: isOp, email: authEmail || null }, @@ -780,15 +776,13 @@ function handleMessage(ws: WebSocket, message: any): void { handleCommand(ws, message.payload as CommandPayload); break; case MessageType.CONTROL_UNLOCK: { - // Fat-finger password + operator identity, both checked server-side. The - // reply drives the UI's armed state, so it can never disagree with what the - // backend will actually accept. - const password = (message.payload && message.payload.password) || ''; + // Arming is identity-only: approved operators may toggle control on. Checked + // server-side; the reply drives the UI's armed state, so it can never + // disagree with what the backend will actually accept. const op = (ws as WsWithControl).__daqOperator === true; - const ok = op && password === CONTROL_PASSWORD; - (ws as WsWithControl).__daqControlAuthorized = ok; - const reason = !op ? 'not_operator' : ok ? 'ok' : 'incorrect_password'; - send(ws, { type: MessageType.CONTROL_UNLOCK_RESULT, timestamp: Date.now(), payload: { ok, reason } }); + (ws as WsWithControl).__daqControlAuthorized = op; + const reason = op ? 'ok' : 'not_operator'; + send(ws, { type: MessageType.CONTROL_UNLOCK_RESULT, timestamp: Date.now(), payload: { ok: op, reason } }); break; } case MessageType.QUERY_HISTORICAL: @@ -817,8 +811,8 @@ function broadcastStateUpdate(): void { } function handleCommand(ws: WebSocket, command: CommandPayload): void { - // The real, unbypassable gate: engine-control commands require an unlocked - // (operator + password) connection, regardless of what the UI shows. + // The real, unbypassable gate: engine-control commands require an armed + // (approved-operator) connection, regardless of what the UI shows. if (CONTROL_COMMAND_TYPES.has(command.commandType) && !(ws as WsWithControl).__daqControlAuthorized) { send(ws, { type: MessageType.ERROR, timestamp: Date.now(), diff --git a/daq-server/diablo_server/frontend/components/dashboard/TopBar.tsx b/daq-server/diablo_server/frontend/components/dashboard/TopBar.tsx index 734292488..df6c42743 100644 --- a/daq-server/diablo_server/frontend/components/dashboard/TopBar.tsx +++ b/daq-server/diablo_server/frontend/components/dashboard/TopBar.tsx @@ -100,8 +100,7 @@ export default function TopBar() { const countdownTargetTimeMs = useSensorStore((s) => s.countdownTargetTimeMs); const session = useSensorStore((s) => s.session); const navigate = useNavigate(); - const { controlEnabled, isOperator, unlocking, error, unlock, lock } = useControlMode(); - const [passwordInput, setPasswordInput] = useState(''); + const { controlEnabled, isOperator, error, unlock, lock } = useControlMode(); const [showUnlockForm, setShowUnlockForm] = useState(false); const connectionStatus = useSensorStore((s) => s.connectionStatus) ?? { connected: false, elodinConnected: false }; @@ -492,7 +491,8 @@ export default function TopBar() { if (controlEnabled) { lock(); setShowUnlockForm(false); - setPasswordInput(''); + } else if (isOperator) { + unlock(); } else { setShowUnlockForm((v) => !v); } @@ -501,40 +501,22 @@ export default function TopBar() { ? 'border-green-500 bg-green-900/40 text-green-300 hover:bg-green-800/60' : 'border-gray-700 bg-gray-900 text-gray-400 hover:bg-gray-800' }`} + title={ + controlEnabled + ? 'Controller mode: click to return to viewer' + : isOperator + ? 'Click to take control' + : 'Viewer mode: you are not an approved operator' + } > {controlEnabled ? 'CONTROLLER' : 'VIEWER'} - {!controlEnabled && showUnlockForm && ( + {!controlEnabled && !isOperator && showUnlockForm && (
- {!isOperator ? ( - - You're not an approved operator — control is view-only. - - ) : ( -
{ - e.preventDefault(); - unlock(passwordInput); - }} - className="flex flex-col gap-1" - > - setPasswordInput(e.target.value)} - placeholder="Control password" - className="px-2 py-1 rounded bg-black/60 border border-gray-700 text-[11px] text-white" - /> - -
- )} + + You're not an approved operator — control is view-only. + {error && ( {error} diff --git a/daq-server/diablo_server/frontend/lib/control-mode.tsx b/daq-server/diablo_server/frontend/lib/control-mode.tsx index 7b982e34d..c29d3ac86 100644 --- a/daq-server/diablo_server/frontend/lib/control-mode.tsx +++ b/daq-server/diablo_server/frontend/lib/control-mode.tsx @@ -5,13 +5,13 @@ import { MessageType } from "./types"; import { getWebSocketClient } from "./websocket"; interface ControlModeContextValue { - /** Armed: the backend has authorized this connection (operator + password). */ + /** Armed: the backend has authorized this connection (approved operator). */ controlEnabled: boolean; /** This user is on the DAQ operators allowlist (from the backend). */ isOperator: boolean; unlocking: boolean; error: string | null; - unlock: (password: string) => void; + unlock: () => void; lock: () => void; } @@ -20,12 +20,12 @@ const ControlModeContext = createContext(un /** * Engine-control arm state — entirely backend-driven, so the UI can never show * "armed" when the backend would reject the commands. The backend enforces the - * operator allowlist + password server-side (see backend/src/server.ts); this - * context just reflects its decisions: + * operator allowlist server-side (see backend/src/server.ts); this context just + * reflects its decisions: * - CONTROL_STATUS (on connect): are you an approved operator? - * - CONTROL_UNLOCK_RESULT (reply to unlock): did the password unlock control? - * No password lives in the frontend, and nothing is persisted — each connection - * re-arms, because the backend resets authorization on every (re)connect. + * - CONTROL_UNLOCK_RESULT (reply to arm): did the backend arm control? + * Nothing is persisted — each connection re-arms, because the backend resets + * authorization on every (re)connect. */ export function ControlModeProvider({ children }: { children: React.ReactNode }) { const [controlEnabled, setControlEnabled] = useState(false); @@ -52,11 +52,7 @@ export function ControlModeProvider({ children }: { children: React.ReactNode }) setError(null); } else { setControlEnabled(false); - setError( - p.reason === "not_operator" - ? "You're not an approved operator." - : "Incorrect password." - ); + setError("You're not an approved operator."); } }); @@ -64,13 +60,13 @@ export function ControlModeProvider({ children }: { children: React.ReactNode }) return () => { offStatus(); offResult(); }; }, []); - const unlock = useCallback((password: string) => { + const unlock = useCallback(() => { setUnlocking(true); setError(null); getWebSocketClient().send({ type: MessageType.CONTROL_UNLOCK, timestamp: Date.now(), - payload: { password }, + payload: {}, }); }, []); diff --git a/daq-server/diablo_server/shared/types.ts b/daq-server/diablo_server/shared/types.ts index f53b50236..97f6a57ab 100644 --- a/daq-server/diablo_server/shared/types.ts +++ b/daq-server/diablo_server/shared/types.ts @@ -31,7 +31,7 @@ export enum MessageType { // Engine-control authorization (DAQ operator gate) CONTROL_STATUS = 'control_status', // Server → Client: { operator, email } - CONTROL_UNLOCK = 'control_unlock', // Client → Server: { password } + CONTROL_UNLOCK = 'control_unlock', // Client → Server: {} (arm control; identity-gated) CONTROL_UNLOCK_RESULT = 'control_unlock_result', // Server → Client: { ok, reason } } From e5d1e4c4e407f23df1b6760830759501f959df0a Mon Sep 17 00:00:00 2001 From: Aidan Rickert Date: Thu, 13 Aug 2026 13:17:39 -0700 Subject: [PATCH 004/205] daq-server: make config/ the single source of truth for state machine CSVs (fixes Fuel Main flashing open on debug toggle in IDLE) --- daq-server/config/config.toml | 2 +- daq-server/config/state_machine_actuators.csv | 2 +- .../diablo_server/backend/src/calibration.ts | 2 - .../backend/src/legacy/state-actuators.ts | 15 ++---- .../backend/src/legacy/state-transitions.ts | 9 ++-- .../config_broadcast_service_main.cpp | 2 +- .../services/sequencer/ActuatorCommander.cpp | 8 +-- .../services/sequencer/SequencerService.cpp | 50 ++++++++++++++++--- .../services/sequencer/StateMachine.cpp | 6 +-- .../calibration_orchestrator_gui.py | 4 +- daq-server/tools/gui/combined_fsw_gui.py | 8 +-- 11 files changed, 67 insertions(+), 41 deletions(-) diff --git a/daq-server/config/config.toml b/daq-server/config/config.toml index 9dd88ead7..b44981821 100644 --- a/daq-server/config/config.toml +++ b/daq-server/config/config.toml @@ -688,7 +688,7 @@ display_ma_samples = 1 [state_machine] actuator_csv = "config/state_machine_actuators.csv" actuator_delay_csv = "config/state_machine_actuator_delays.csv" -# Repo-local matrix (same schema as DiabloAvionics test_guis); backend resolves via state_machine.transitions_csv +# Repo-local state transition matrix; sequencer + backend both resolve via state_machine.transitions_csv transitions_csv = "config/state_transitions.csv" # ============================================================================= diff --git a/daq-server/config/state_machine_actuators.csv b/daq-server/config/state_machine_actuators.csv index af7830c96..ebd2fdc29 100644 --- a/daq-server/config/state_machine_actuators.csv +++ b/daq-server/config/state_machine_actuators.csv @@ -1,7 +1,7 @@ ,Idle,Armed,Fuel Fill,Ox Fill,Press Standby,GN2 Low Press,GN2 Low Vent,Fuel Press,Fuel Vent,Ox Press,Ox Vent,GN2 High Press,GN2 High Vent,Calibrate,Ready,Fire,Vent,Engine Abort,GSE Abort,Emergency Abort Fuel Vent,CLOSE,CLOSE,OPEN,OPEN,CLOSE,CLOSE,CLOSE,CLOSE,OPEN,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,OPEN,OPEN,CLOSE,OPEN Fuel Press,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,OPEN,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,OPEN,OPEN,OPEN,CLOSE,OPEN -Fuel Main,OPEN,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,OPEN,CLOSE,OPEN,CLOSE,OPEN +Fuel Main,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,OPEN,CLOSE,OPEN,CLOSE,OPEN Fuel Fill Vent,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE Fuel Fill Press,CLOSE,CLOSE,OPEN,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE LOX Vent,CLOSE,CLOSE,OPEN,OPEN,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,OPEN,CLOSE,CLOSE,CLOSE,CLOSE,CLOSE,OPEN,OPEN,CLOSE,OPEN diff --git a/daq-server/diablo_server/backend/src/calibration.ts b/daq-server/diablo_server/backend/src/calibration.ts index 8f1d62af8..dbc2de885 100644 --- a/daq-server/diablo_server/backend/src/calibration.ts +++ b/daq-server/diablo_server/backend/src/calibration.ts @@ -344,14 +344,12 @@ export interface PTCalibrationResult { * 1. scripts/calibration/calibrations/ (project root — used by femboy/FSW) * 2. calibration/ (repo-root fallback) * 3. web-gui/backend/data/ - * 4. external/DiabloAvionics/test_guis/ */ export function loadPTCalibration(overridePath?: string): PTCalibrationResult { const candidateDirs: string[] = [ path.join(__dirname, '../../../scripts/calibration/calibrations'), // femboy / daq_bridge path path.join(__dirname, '../../../calibration'), path.join(__dirname, '../data'), - path.join(__dirname, '../../../external/DiabloAvionics/test_guis'), ]; // If caller supplied a specific file path, try it first diff --git a/daq-server/diablo_server/backend/src/legacy/state-actuators.ts b/daq-server/diablo_server/backend/src/legacy/state-actuators.ts index f908fbe9c..3cfb2108c 100644 --- a/daq-server/diablo_server/backend/src/legacy/state-actuators.ts +++ b/daq-server/diablo_server/backend/src/legacy/state-actuators.ts @@ -342,16 +342,11 @@ function buildCSVSearchPaths(): string[] { // Config not available, use fallback paths } - // 2. Relative __dirname-based fallback (no absolute/hardcoded paths) - const relBaseDirs = [ - join(__dirname, '..', '..', '..', '..', 'external', 'DiabloAvionics', 'test_guis'), - join(process.cwd(), '..', '..', 'external', 'DiabloAvionics', 'test_guis'), - join(process.cwd(), '..', 'external', 'DiabloAvionics', 'test_guis'), - ]; - for (const base of relBaseDirs) { - paths.push(join(base, 'Avionics Board Status - State Machine Actuators.csv')); - paths.push(join(base, 'state_machine_actuators.csv')); - } + // 2. Direct config/ fallback (canonical source of truth) if config.toml unreadable. + const rel = join('config', 'state_machine_actuators.csv'); + paths.push(join(__dirname, '..', '..', '..', '..', rel)); + paths.push(join(process.cwd(), '..', '..', rel)); + paths.push(join(process.cwd(), '..', rel)); return paths; } diff --git a/daq-server/diablo_server/backend/src/legacy/state-transitions.ts b/daq-server/diablo_server/backend/src/legacy/state-transitions.ts index 8837a3a08..6d78a8ce7 100644 --- a/daq-server/diablo_server/backend/src/legacy/state-transitions.ts +++ b/daq-server/diablo_server/backend/src/legacy/state-transitions.ts @@ -105,11 +105,12 @@ function buildTransitionsCSVSearchPaths(): string[] { } catch { /* fall through to defaults */ } + // Direct config/ fallback (canonical source of truth) if config.toml unreadable. + const rel = join('config', 'state_transitions.csv'); paths.push( - join(process.cwd(), '..', '..', 'external', 'DiabloAvionics', 'test_guis', 'state_transitions.csv'), - join(process.cwd(), '..', 'external', 'DiabloAvionics', 'test_guis', 'state_transitions.csv'), - join(__dirname, '..', '..', '..', 'external', 'DiabloAvionics', 'test_guis', 'state_transitions.csv'), - join(__dirname, '../../../../external/DiabloAvionics/test_guis/state_transitions.csv'), + join(process.cwd(), '..', '..', rel), + join(process.cwd(), '..', rel), + join(__dirname, '..', '..', '..', '..', rel), ); return paths; } diff --git a/daq-server/diablo_server/services/config_broadcast/config_broadcast_service_main.cpp b/daq-server/diablo_server/services/config_broadcast/config_broadcast_service_main.cpp index b80dc71ca..e60dd5d1b 100644 --- a/daq-server/diablo_server/services/config_broadcast/config_broadcast_service_main.cpp +++ b/daq-server/diablo_server/services/config_broadcast/config_broadcast_service_main.cpp @@ -392,7 +392,7 @@ int main(int argc, char* argv[]) { const char* csv_fbs[] = { "config/state_machine_actuators.csv", "../config/state_machine_actuators.csv", - "external/DiabloAvionics/test_guis/state_machine_actuators.csv", + "../../config/state_machine_actuators.csv", }; for (const char* fb : csv_fbs) { std::ifstream t(fb); diff --git a/daq-server/diablo_server/services/sequencer/ActuatorCommander.cpp b/daq-server/diablo_server/services/sequencer/ActuatorCommander.cpp index 25913814e..9edae6e15 100644 --- a/daq-server/diablo_server/services/sequencer/ActuatorCommander.cpp +++ b/daq-server/diablo_server/services/sequencer/ActuatorCommander.cpp @@ -199,11 +199,11 @@ bool ActuatorCommander::load(const std::string& config_content, const std::strin std::cout << "[ActuatorCommander] Loaded " << roles_.size() << " actuator roles from config" << std::endl; - // -- State→actuator CSV -- + // -- State→actuator CSV -- canonical source: daq-server/config/. const char* fallbacks[] = { - "firmware/test_guis/state_machine_actuators.csv", - "../firmware/test_guis/state_machine_actuators.csv", - "../../firmware/test_guis/state_machine_actuators.csv", + "config/state_machine_actuators.csv", + "../config/state_machine_actuators.csv", + "../../config/state_machine_actuators.csv", }; std::ifstream f(csv_path); diff --git a/daq-server/diablo_server/services/sequencer/SequencerService.cpp b/daq-server/diablo_server/services/sequencer/SequencerService.cpp index 6b1b39363..a15b2cdd3 100644 --- a/daq-server/diablo_server/services/sequencer/SequencerService.cpp +++ b/daq-server/diablo_server/services/sequencer/SequencerService.cpp @@ -101,11 +101,46 @@ static std::string resolveDataPath(const std::string& rel) { return rel; // original — caller will get the open error } +// Read a "section.key" string value from raw config.toml content, stripping +// surrounding whitespace and quotes. Returns `fallback` if not found. +static std::string configString(const std::string& content, const std::string& section, + const std::string& key, const std::string& fallback) { + const std::string header = "[" + section + "]"; + auto pos = content.find(header); + if (pos == std::string::npos) + return fallback; + auto start = pos + header.size(); + auto next = content.find("\n[", start); + const std::string sec = + (next == std::string::npos) ? content.substr(start) : content.substr(start, next - start); + std::istringstream iss(sec); + std::string line; + while (std::getline(iss, line)) { + auto c = line.find('#'); + if (c != std::string::npos) + line = line.substr(0, c); + auto eq = line.find('='); + if (eq == std::string::npos) + continue; + std::string k = line.substr(0, eq); + k.erase(0, k.find_first_not_of(" \t")); + k.erase(k.find_last_not_of(" \t") + 1); + if (k != key) + continue; + std::string v = line.substr(eq + 1); + v.erase(0, v.find_first_not_of(" \t\r\n\"")); + v.erase(v.find_last_not_of(" \t\r\n\"") + 1); + return v.empty() ? fallback : v; + } + return fallback; +} + bool SequencerService::init(const std::string& config_path) { loadConfig(config_path); - // State machine CSV - std::string sm_csv = resolveDataPath("firmware/test_guis/state_transitions.csv"); + // State machine CSV — path from config.toml (canonical: daq-server/config/). + std::string sm_csv = resolveDataPath( + configString(config_content_, "state_machine", "transitions_csv", "config/state_transitions.csv")); if (!state_machine_.load(sm_csv)) { std::cerr << "[SequencerService] Failed to load state_transitions.csv (tried relative to cwd: " @@ -113,8 +148,9 @@ bool SequencerService::init(const std::string& config_path) { return false; } - // Actuator commander - std::string act_csv = resolveDataPath("firmware/test_guis/state_machine_actuators.csv"); + // Actuator commander — path from config.toml (canonical: daq-server/config/). + std::string act_csv = resolveDataPath( + configString(config_content_, "state_machine", "actuator_csv", "config/state_machine_actuators.csv")); if (!actuator_commander_.load(config_content_, act_csv)) { std::cerr << "[SequencerService] Failed to load state_machine_actuators.csv (tried: " << act_csv << ")" << std::endl; @@ -352,12 +388,14 @@ bool SequencerService::reloadConfig() { std::cout << "[SequencerService] Reloading config..." << std::endl; loadConfig(config_path_); - std::string act_csv = resolveDataPath("firmware/test_guis/state_machine_actuators.csv"); + std::string act_csv = resolveDataPath( + configString(config_content_, "state_machine", "actuator_csv", "config/state_machine_actuators.csv")); if (!actuator_commander_.load(config_content_, act_csv)) { std::cerr << "[SequencerService] Reload: failed to reload actuator CSV" << std::endl; return false; } - std::string sm_csv = resolveDataPath("firmware/test_guis/state_transitions.csv"); + std::string sm_csv = resolveDataPath( + configString(config_content_, "state_machine", "transitions_csv", "config/state_transitions.csv")); if (!state_machine_.load(sm_csv)) { std::cerr << "[SequencerService] Reload: failed to reload state transitions CSV" << std::endl; diff --git a/daq-server/diablo_server/services/sequencer/StateMachine.cpp b/daq-server/diablo_server/services/sequencer/StateMachine.cpp index 63351cfb6..3b1b74d20 100644 --- a/daq-server/diablo_server/services/sequencer/StateMachine.cpp +++ b/daq-server/diablo_server/services/sequencer/StateMachine.cpp @@ -125,9 +125,9 @@ static std::string trimCell(const std::string& s) { bool StateMachine::load(const std::string& csv_path) { const char* fallbacks[] = { - "firmware/test_guis/state_transitions.csv", - "../firmware/test_guis/state_transitions.csv", - "../../firmware/test_guis/state_transitions.csv", + "config/state_transitions.csv", + "../config/state_transitions.csv", + "../../config/state_transitions.csv", }; std::ifstream f(csv_path); diff --git a/daq-server/tools/calibration/calibration_orchestrator_gui.py b/daq-server/tools/calibration/calibration_orchestrator_gui.py index 3ad7e2294..3eb15af74 100644 --- a/daq-server/tools/calibration/calibration_orchestrator_gui.py +++ b/daq-server/tools/calibration/calibration_orchestrator_gui.py @@ -372,9 +372,7 @@ def create_control_panel(self) -> QtWidgets.QWidget: # Fallback: try to count from CSV csv_path = ( Path(__file__).parent.parent.parent - / "external" - / "DiabloAvionics" - / "test_guis" + / "config" / "state_machine_actuators.csv" ) if csv_path.exists(): diff --git a/daq-server/tools/gui/combined_fsw_gui.py b/daq-server/tools/gui/combined_fsw_gui.py index e893b662a..b68d4e88c 100755 --- a/daq-server/tools/gui/combined_fsw_gui.py +++ b/daq-server/tools/gui/combined_fsw_gui.py @@ -123,9 +123,7 @@ class SystemState: # State machine CSV path _STATE_MACHINE_CSV = ( Path(__file__).parent.parent.parent - / "external" - / "DiabloAvionics" - / "test_guis" + / "config" / "state_machine_actuators.csv" ) @@ -1631,9 +1629,7 @@ def _load_state_actuator_map(self): """Load state machine actuator mapping from CSV""" csv_path = ( Path(__file__).parent.parent.parent - / "external" - / "DiabloAvionics" - / "test_guis" + / "config" / "state_machine_actuators.csv" ) self._state_actuator_map = {} From d5bea86e6696fcb001994c5d45e8bdb0b872efa3 Mon Sep 17 00:00:00 2001 From: Aidan Rickert Date: Thu, 13 Aug 2026 16:48:23 -0700 Subject: [PATCH 005/205] daq-server: choose Real/Simulated data at session start (starts the sim generator) + purple Simulated Data / Session Stopped status badge --- .../deploy/startup/start_systemd_sim.sh | 8 ++- .../diablo_server/backend/src/server.ts | 30 ++++++-- .../backend/src/service-controller.ts | 70 ++++++++++++++++--- .../backend/src/session-manager.ts | 18 ++++- .../backend/src/session-state.ts | 2 + .../frontend/app/session/page.tsx | 38 +++++----- .../components/dashboard/MobileDashboard.tsx | 8 ++- .../frontend/components/dashboard/TopBar.tsx | 8 ++- daq-server/diablo_server/shared/types.ts | 6 ++ daq-server/test/session_flow_test.ts | 5 +- 10 files changed, 154 insertions(+), 39 deletions(-) diff --git a/daq-server/deploy/startup/start_systemd_sim.sh b/daq-server/deploy/startup/start_systemd_sim.sh index 7cd78a8da..0358f6826 100755 --- a/daq-server/deploy/startup/start_systemd_sim.sh +++ b/daq-server/deploy/startup/start_systemd_sim.sh @@ -49,11 +49,13 @@ fi mkdir -p "$DAQ_DIR" sed 's/192\.168\.2\./127.0.0./g' "$PROJECT/config/config.toml" > "$SIM_CONFIG" cat > "$PIPELINE_ENV" <> "$PIPELINE_ENV" diff --git a/daq-server/diablo_server/backend/src/server.ts b/daq-server/diablo_server/backend/src/server.ts index c7c0bfb93..73d256182 100644 --- a/daq-server/diablo_server/backend/src/server.ts +++ b/daq-server/diablo_server/backend/src/server.ts @@ -635,7 +635,7 @@ wss.on('connection', (ws: WebSocket, req) => { // Connection status send(ws, { type: MessageType.CONNECTION_STATUS, timestamp: Date.now(), - payload: { connected: true, elodinConnected: elodin.isConnected(), connId }, + payload: { connected: true, elodinConnected: elodin.isConnected(), connId, simulated: isSimulated() }, }); outboundMessages++; lastOutboundAt = Date.now(); @@ -872,12 +872,14 @@ function handleCommand(ws: WebSocket, command: CommandPayload): void { break; case 'session_start': sessionManager - .start(!!command.data.keepData, command.data.durationMs ?? 0) + .start(!!command.data.keepData, command.data.durationMs ?? 0, !!command.data.simulated) + .then(() => broadcastConnectionStatus()) .catch((err) => send(ws, { type: MessageType.ERROR, timestamp: Date.now(), payload: { message: `Session start failed: ${err.message}` } })); break; case 'session_stop': sessionManager .stop(false) + .then(() => broadcastConnectionStatus()) .catch((err) => send(ws, { type: MessageType.ERROR, timestamp: Date.now(), payload: { message: `Session stop failed: ${err.message}` } })); break; case 'session_extend': @@ -991,9 +993,29 @@ function scheduleResubscribe(attempt: number): void { }, 5000); } +// True when incoming data is synthetic. In a session-enabled deployment this is +// exactly "an active simulated run" — the backend's own USE_SIM env is ignored +// there because the systemd sim harness sets USE_SIM=1 on the backend process +// permanently (so it would wrongly read simulated even when the run is stopped or +// live). Only the field-laptop path (session control off, no run concept) falls +// back to USE_SIM=1 (the terminal `dev.sh --sim` stack). Drives the purple badge. +function isSimulated(): boolean { + if (sessionManager.isEnabled()) return sessionManager.isSimulated(); + return process.env.USE_SIM === '1'; +} + +// Re-broadcast connection status (used when the simulated state flips on session +// start/stop so the badge updates without waiting for an Elodin reconnect). +function broadcastConnectionStatus(): void { + broadcast({ + type: MessageType.CONNECTION_STATUS, timestamp: Date.now(), + payload: { connected: true, elodinConnected: elodin.isConnected(), simulated: isSimulated() }, + }); +} + elodin.on('connected', () => { console.log('[ThinServer] Elodin Connected'); - broadcast({ type: MessageType.CONNECTION_STATUS, timestamp: Date.now(), payload: { connected: true, elodinConnected: true } }); + broadcast({ type: MessageType.CONNECTION_STATUS, timestamp: Date.now(), payload: { connected: true, elodinConnected: true, simulated: isSimulated() } }); if (resubscribeTimer) { clearTimeout(resubscribeTimer); resubscribeTimer = null; } shouldResubscribe = true; @@ -1008,7 +1030,7 @@ elodin.on('connected', () => { elodin.on('disconnected', () => { console.log('[ThinServer] Elodin DB disconnected'); - broadcast({ type: MessageType.CONNECTION_STATUS, timestamp: Date.now(), payload: { connected: true, elodinConnected: false } }); + broadcast({ type: MessageType.CONNECTION_STATUS, timestamp: Date.now(), payload: { connected: true, elodinConnected: false, simulated: isSimulated() } }); if (resubscribeTimer) { clearTimeout(resubscribeTimer); resubscribeTimer = null; } clearSubscriptionState(); }); diff --git a/daq-server/diablo_server/backend/src/service-controller.ts b/daq-server/diablo_server/backend/src/service-controller.ts index 1738e7e0b..0823220e1 100644 --- a/daq-server/diablo_server/backend/src/service-controller.ts +++ b/daq-server/diablo_server/backend/src/service-controller.ts @@ -9,11 +9,17 @@ * * Only the always-on server's sensor-backend.service sets SESSION_SERVICE_MODE=systemd. */ -import { spawn } from 'child_process'; +import { spawn, type ChildProcess } from 'child_process'; import { writeFileSync, mkdirSync } from 'fs'; import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; import { homedir } from 'os'; +// daq-server repo root (…/daq-server), from …/daq-server/diablo_server/backend/{src,dist}. +const PROJECT_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..'); +const SIM_SCRIPT = join(PROJECT_ROOT, 'sim', 'board_simulator.py'); +const SIM_CONFIG = join(PROJECT_ROOT, 'config', 'sim_config.toml'); + export type SessionServiceMode = 'off' | 'mock' | 'systemd'; export function getSessionServiceMode(): SessionServiceMode { @@ -31,14 +37,17 @@ const BASE_UNITS = [ 'sensor-actuator', ]; -function pipelineUnits(): string[] { +function pipelineUnits(simulated: boolean): string[] { const units = [...BASE_UNITS]; - if (process.env.USE_SIM === '1') units.push('sensor-simulator'); + if (simulated) units.push('sensor-simulator'); return units; } // The elodin unit reads its per-run DB dir from this EnvironmentFile (systemd mode). const SESSION_ENV_PATH = join(homedir(), '.config', 'daq', 'session.env'); +// Optional data-source overlay the pipeline units already read: a simulated run +// sets USE_SIM=1 + the IP-remapped sim config; a live run points back at hardware. +const PIPELINE_ENV_PATH = join(homedir(), '.config', 'daq', 'pipeline.env'); function runSystemctl(action: 'start' | 'stop', units: string[]): Promise { return new Promise((resolve, reject) => { @@ -53,21 +62,66 @@ function runSystemctl(action: 'start' | 'stop', units: string[]): Promise export class ServiceController { constructor(private readonly mode: SessionServiceMode) {} - async start(dbDir: string): Promise { + /** Mock-mode simulator child (systemd manages the sensor-simulator unit instead). */ + private simProc: ChildProcess | null = null; + + async start(dbDir: string, simulated = false): Promise { if (this.mode === 'systemd') { mkdirSync(dirname(SESSION_ENV_PATH), { recursive: true }); writeFileSync(SESSION_ENV_PATH, `ELODIN_DB_DIR=${dbDir}\n`); - await runSystemctl('start', pipelineUnits()); + // Per-run data-source overlay consumed by the pipeline units. + writeFileSync( + PIPELINE_ENV_PATH, + simulated + ? 'USE_SIM=1\nDAQ_CONFIG=config/sim_config.toml\n' + : 'USE_SIM=0\nDAQ_CONFIG=config/config.toml\n', + ); + await runSystemctl('start', pipelineUnits(simulated)); } else { - console.log(`[Session] (mock) start pipeline → ${dbDir} :: ${pipelineUnits().join(', ')}`); + console.log(`[Session] (mock) start pipeline → ${dbDir} (simulated=${simulated})`); + // In mock mode the pipeline is already running; only the simulator is ours + // to start/stop for the run. + if (simulated) this.spawnSimulator(); } } async stop(): Promise { if (this.mode === 'systemd') { - await runSystemctl('stop', pipelineUnits()); + // Stop the superset (incl. the simulator) so no data source lingers between runs. + await runSystemctl('stop', pipelineUnits(true)); } else { - console.log(`[Session] (mock) stop pipeline :: ${pipelineUnits().join(', ')}`); + console.log('[Session] (mock) stop pipeline'); + this.stopSimulator(); } } + + /** Re-assert the simulator after a backend restart recovered an active simulated run. */ + async resume(simulated: boolean): Promise { + if (!simulated) return; + if (this.mode === 'systemd') { + await runSystemctl('start', ['sensor-simulator']); + } else { + this.spawnSimulator(); + } + } + + private spawnSimulator(): void { + if (this.simProc && !this.simProc.killed) return; // already running + const args = [SIM_SCRIPT, '--config', SIM_CONFIG, '--target', '127.0.0.1', '--port', '5006']; + const proc = spawn('python3', args, { cwd: PROJECT_ROOT, stdio: 'inherit' }); + proc.on('error', (err) => console.error('[Session] board simulator failed to start:', err)); + proc.on('exit', (code) => { + console.log(`[Session] board simulator exited (${code})`); + if (this.simProc === proc) this.simProc = null; + }); + this.simProc = proc; + console.log(`[Session] board simulator started (pid ${proc.pid})`); + } + + private stopSimulator(): void { + if (!this.simProc) return; + console.log(`[Session] stopping board simulator (pid ${this.simProc.pid})`); + this.simProc.kill('SIGTERM'); + this.simProc = null; + } } diff --git a/daq-server/diablo_server/backend/src/session-manager.ts b/daq-server/diablo_server/backend/src/session-manager.ts index e6a6b3e4e..6a48c3c9f 100644 --- a/daq-server/diablo_server/backend/src/session-manager.ts +++ b/daq-server/diablo_server/backend/src/session-manager.ts @@ -81,6 +81,7 @@ class SessionManager { private active = false; private dbDir: string | null = null; private keepData = false; + private simulated = false; private deadlineMs: number | null = null; private durationMs: number | null = null; private warnTimers: NodeJS.Timeout[] = []; @@ -96,12 +97,16 @@ class SessionManager { this.active = true; this.dbDir = persisted.dbDir; this.keepData = persisted.keepData; + this.simulated = persisted.simulated; this.deadlineMs = persisted.deadlineMs; this.durationMs = persisted.durationMs; if (this.deadlineMs != null && this.deadlineMs <= Date.now()) { void this.stop(true); // expired while we were down } else { this.scheduleTimers(); + // The spawned simulator (mock mode) dies with the backend — re-launch it + // for a recovered simulated run. (systemd units survive; resume is a no-op.) + void this.controller.resume(this.simulated); } } } @@ -110,6 +115,11 @@ class SessionManager { return this.enabled; } + /** True when an active run is fed by the board simulator (drives the "Simulated Data" badge). */ + isSimulated(): boolean { + return this.active && this.simulated; + } + getStatus(): SessionStatus { return { enabled: this.enabled, @@ -119,6 +129,7 @@ class SessionManager { deadlineMs: this.deadlineMs, remainingMs: this.deadlineMs != null ? this.deadlineMs - Date.now() : null, freeDiskBytes: this.enabled ? freeDiskBytes() : null, + simulated: this.active && this.simulated, }; } @@ -184,10 +195,11 @@ class SessionManager { keepData: this.keepData, deadlineMs: this.deadlineMs, durationMs: this.durationMs, + simulated: this.simulated, }); } - async start(keepData: boolean, durationMs: number): Promise { + async start(keepData: boolean, durationMs: number, simulated = false): Promise { if (!this.enabled) throw new Error('Session control is disabled in this mode.'); if (this.active) throw new Error('A run is already active.'); if (!Number.isFinite(durationMs) || durationMs <= 0) { @@ -195,9 +207,10 @@ class SessionManager { } this.dbDir = join(ELODIN_ROOT, timestampName()); this.keepData = keepData; + this.simulated = simulated; this.durationMs = durationMs; this.deadlineMs = Date.now() + durationMs; - await this.controller.start(this.dbDir); + await this.controller.start(this.dbDir, this.simulated); this.active = true; this.scheduleTimers(); this.persist(); @@ -227,6 +240,7 @@ class SessionManager { this.deadlineMs = null; this.durationMs = null; this.keepData = false; + this.simulated = false; this.persist(); this.emit(); } diff --git a/daq-server/diablo_server/backend/src/session-state.ts b/daq-server/diablo_server/backend/src/session-state.ts index 033dfe1dd..24cebe35c 100644 --- a/daq-server/diablo_server/backend/src/session-state.ts +++ b/daq-server/diablo_server/backend/src/session-state.ts @@ -13,6 +13,7 @@ export interface PersistedSession { keepData: boolean; deadlineMs: number | null; durationMs: number | null; + simulated: boolean; } export function getSessionStatePath(): string { @@ -33,6 +34,7 @@ export function loadSession(): PersistedSession | null { keepData: !!p.keepData, deadlineMs: typeof p.deadlineMs === 'number' ? p.deadlineMs : null, durationMs: typeof p.durationMs === 'number' ? p.durationMs : null, + simulated: !!p.simulated, }; } catch { return null; diff --git a/daq-server/diablo_server/frontend/app/session/page.tsx b/daq-server/diablo_server/frontend/app/session/page.tsx index eee1c1bf8..128969b59 100644 --- a/daq-server/diablo_server/frontend/app/session/page.tsx +++ b/daq-server/diablo_server/frontend/app/session/page.tsx @@ -1,7 +1,6 @@ 'use client' import { useEffect, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; import { useSensorStore } from '@/lib/store'; import { getWebSocketClient } from '@/lib/websocket'; import { useControlMode } from '@/lib/control-mode'; @@ -26,19 +25,9 @@ export default function SessionPage() { const session = useSensorStore((s) => s.session); const { controlEnabled } = useControlMode(); const ws = getWebSocketClient(); - const navigate = useNavigate(); - - const backLink = ( - - ); const [keepData, setKeepData] = useState(true); // Save is the safe default + const [simulated, setSimulated] = useState(false); // Live data is the safe default const [durationMin, setDurationMin] = useState(60); const [addMin, setAddMin] = useState(15); @@ -65,7 +54,6 @@ export default function SessionPage() { if (!session) { return (
- {backLink}

Session control

Connecting… (waiting for the backend WebSocket). If this persists, the live data @@ -78,7 +66,6 @@ export default function SessionPage() { if (!session.enabled) { return (

- {backLink}

Session control

Session control is disabled in this deployment — the stack runs until the process is @@ -94,7 +81,6 @@ export default function SessionPage() { return (

- {backLink}

Session control

+
+
Data source
+
+ + +
+
+
Auto-stop after (min)
send({ commandType: 'session_start', data: { keepData, durationMs: durationMin * 60000 } })} + onClick={() => send({ commandType: 'session_start', data: { keepData, durationMs: durationMin * 60000, simulated } })} className="rounded-lg border border-green-600 bg-green-800/70 px-5 py-2 text-sm font-bold uppercase tracking-wider text-white hover:bg-green-700 disabled:opacity-40 disabled:cursor-not-allowed" > Start run diff --git a/daq-server/diablo_server/frontend/components/dashboard/MobileDashboard.tsx b/daq-server/diablo_server/frontend/components/dashboard/MobileDashboard.tsx index f48c21be9..d5dfb66e7 100644 --- a/daq-server/diablo_server/frontend/components/dashboard/MobileDashboard.tsx +++ b/daq-server/diablo_server/frontend/components/dashboard/MobileDashboard.tsx @@ -72,8 +72,12 @@ export default function MobileDashboard() { const debugMode = useSensorStore((s) => s.debugMode); const setDebugMode = useSensorStore((s) => s.setDebugMode); const connectionStatus = useSensorStore((s) => s.connectionStatus) ?? { connected: false, elodinConnected: false }; + const session = useSensorStore((s) => s.session); const connected = connectionStatus.connected; const elodinConnected = connectionStatus.elodinConnected; + const isSimulated = !!connectionStatus.simulated; + // Session-enabled deployment with no active run: pipeline is intentionally down. + const sessionStopped = !!(session?.enabled && !session.active); const [clock, setClock] = useState(''); const [timeWindow, setTimeWindow] = useState(60); @@ -137,9 +141,9 @@ export default function MobileDashboard() {
DIABLO DAQ
- {isFullyConnected ? 'Connected' : connected ? 'Data Pipeline Down' : 'Disconnected'} + {isSimulated ? 'Simulated Data' : isFullyConnected ? 'Connected' : sessionStopped ? 'Session Stopped' : connected ? 'Data Pipeline Down' : 'Disconnected'}
{clock} diff --git a/daq-server/diablo_server/frontend/components/dashboard/TopBar.tsx b/daq-server/diablo_server/frontend/components/dashboard/TopBar.tsx index df6c42743..b04056dac 100644 --- a/daq-server/diablo_server/frontend/components/dashboard/TopBar.tsx +++ b/daq-server/diablo_server/frontend/components/dashboard/TopBar.tsx @@ -218,6 +218,10 @@ export default function TopBar() { const stateColor = STATE_COLORS[effectiveState] ?? 'text-text'; const isConnected = connectionStatus.connected; const isFullyConnected = connectionStatus.connected && connectionStatus.elodinConnected; + const isSimulated = !!connectionStatus.simulated; + // Session-enabled deployment with no active run: the pipeline is intentionally + // down, so show "Session Stopped" rather than a "Data Pipeline Down" alarm. + const sessionStopped = !!(session?.enabled && !session.active); const effectivePressureBars = useMemo(() => { if (pressureBars.length > 0) return pressureBars; @@ -276,9 +280,9 @@ export default function TopBar() {
-
+
- {isFullyConnected ? 'Connected' : isConnected ? 'Data Pipeline Down' : 'Disconnected'} + {isSimulated ? 'Simulated Data' : isFullyConnected ? 'Connected' : sessionStopped ? 'Session Stopped' : isConnected ? 'Data Pipeline Down' : 'Disconnected'}
{session?.enabled && ( diff --git a/daq-server/diablo_server/shared/types.ts b/daq-server/diablo_server/shared/types.ts index 97f6a57ab..f45240713 100644 --- a/daq-server/diablo_server/shared/types.ts +++ b/daq-server/diablo_server/shared/types.ts @@ -166,6 +166,8 @@ export interface CommandPayload { keepData?: boolean; /** session_start: auto-stop timeout in milliseconds. */ durationMs?: number; + /** session_start: run against the board simulator (true) instead of live hardware. */ + simulated?: boolean; /** session_extend: milliseconds to push the auto-stop deadline out by. */ addMs?: number; }; @@ -184,6 +186,8 @@ export interface SessionStatus { deadlineMs: number | null; remainingMs: number | null; freeDiskBytes: number | null; + /** True when the active run is fed by the board simulator instead of hardware. */ + simulated: boolean; } // Connection status @@ -193,6 +197,8 @@ export interface ConnectionStatus { connId?: string; latency?: number; error?: string; + /** True when incoming data is synthetic (board simulator running). */ + simulated?: boolean; } // Mission start time (T+0 from first packet) diff --git a/daq-server/test/session_flow_test.ts b/daq-server/test/session_flow_test.ts index 9225af0f0..988bb9c53 100755 --- a/daq-server/test/session_flow_test.ts +++ b/daq-server/test/session_flow_test.ts @@ -111,10 +111,11 @@ async function main(): Promise { console.log('\n▶ Run 1 — Discard, auto-stop'); const startedAt = Date.now(); const activePromise = waitFor(ws, 'session_update', 10000, (p) => p.active === true); - send(ws, 'send_command', { commandType: 'session_start', data: { keepData: false, durationMs: DURATION_MS } }); + send(ws, 'send_command', { commandType: 'session_start', data: { keepData: false, durationMs: DURATION_MS, simulated: true } }); const active = await activePromise; const dbDir1: string = active.dbDir; assert(active.active === true, 'session_start → active'); + assert(active.simulated === true, 'session_start (simulated) → SESSION_UPDATE.simulated true'); assert(typeof dbDir1 === 'string' && dbDir1.startsWith(join(ELODIN_ROOT, 'daq_')), `fresh timestamped dbDir (${dbDir1})`); await sleep(300); assert(existsSync(dbDir1), 'run DB dir created on disk'); @@ -140,7 +141,7 @@ async function main(): Promise { // ── Run 2: Save + extend → deadline moves out, dir persists on stop ──────── console.log('\n▶ Run 2 — Save, extend, manual stop'); const active2Promise = waitFor(ws, 'session_update', 10000, (p) => p.active === true); - send(ws, 'send_command', { commandType: 'session_start', data: { keepData: true, durationMs: 600000 } }); + send(ws, 'send_command', { commandType: 'session_start', data: { keepData: true, durationMs: 600000, simulated: true } }); const active2 = await active2Promise; const dbDir2: string = active2.dbDir; const deadline1: number = active2.deadlineMs; From fb19c6cbd9a7c0518c614cb41c21ba206160d3a6 Mon Sep 17 00:00:00 2001 From: Aidan Rickert Date: Thu, 13 Aug 2026 16:48:53 -0700 Subject: [PATCH 006/205] onshape-viewer: Mach-dependent fin CP + RocketPy flight-dynamics tab --- onshape-viewer/FUTURE_IMPROVEMENTS.md | 82 ++++ onshape-viewer/backend/main.py | 128 ++++++ .../backend/onshape/aero/barrowman_fins.py | 166 +++++++- onshape-viewer/backend/onshape/aero/flight.py | 37 +- .../backend/onshape/aero/rocketpy_adapter.py | 117 +++++ .../backend/onshape/aero/rocketpy_compare.py | 120 ++++++ .../backend/onshape/aero/rocketpy_flight.py | 398 ++++++++++++++++++ .../backend/onshape/aero/stability.py | 41 +- onshape-viewer/frontend/src/App.tsx | 30 ++ onshape-viewer/frontend/src/api/client.ts | 17 + .../components/viewer/FlightDynamicsTab.tsx | 309 ++++++++++++++ .../components/viewer/FlightProfileModal.tsx | 9 +- .../src/components/viewer/chartTheme.ts | 13 + onshape-viewer/frontend/src/types.ts | 59 +++ onshape-viewer/requirements-flight.txt | 7 + onshape-viewer/tests/test_aero_mach.py | 147 +++++++ onshape-viewer/tests/test_rocketpy_compare.py | 30 ++ onshape-viewer/tests/test_rocketpy_flight.py | 64 +++ 18 files changed, 1746 insertions(+), 28 deletions(-) create mode 100644 onshape-viewer/FUTURE_IMPROVEMENTS.md create mode 100644 onshape-viewer/backend/onshape/aero/rocketpy_adapter.py create mode 100644 onshape-viewer/backend/onshape/aero/rocketpy_compare.py create mode 100644 onshape-viewer/backend/onshape/aero/rocketpy_flight.py create mode 100644 onshape-viewer/frontend/src/components/viewer/FlightDynamicsTab.tsx create mode 100644 onshape-viewer/requirements-flight.txt create mode 100644 onshape-viewer/tests/test_aero_mach.py create mode 100644 onshape-viewer/tests/test_rocketpy_compare.py create mode 100644 onshape-viewer/tests/test_rocketpy_flight.py diff --git a/onshape-viewer/FUTURE_IMPROVEMENTS.md b/onshape-viewer/FUTURE_IMPROVEMENTS.md new file mode 100644 index 000000000..7bea284f1 --- /dev/null +++ b/onshape-viewer/FUTURE_IMPROVEMENTS.md @@ -0,0 +1,82 @@ +# Future improvements + +Known approximations and deferred work, with enough context to pick each up later. +Keep entries concrete: what it does today, why that is a simplification, and the +path to a better version. + +--- + +## 1. Rocket inertia is a rod/cylinder approximation + +**Today.** The Onshape CAD pipeline extracts per-part mass and centroid, but **not +the inertia tensor**, so the RocketPy flight (`backend/onshape/aero/rocketpy_flight.py`) +approximates the dry rocket's moments of inertia from mass + length + radius: +longitudinal `I11 = I22 ≈ (1/12)·m·L²` (slender rod), roll `I33 ≈ (1/2)·m·r²` +(thin cylinder). + +**Why it's a simplification.** Real mass is not uniformly distributed (dense motor +aft, avionics/payload concentrated), so the true longitudinal inertia differs from a +uniform rod — often substantially. Inertia does **not** affect the trajectory, +apogee, max-Q, or static/stability margin (those are force/CP/CG quantities). It +**does** drive the *rotational dynamics*: pitch/yaw angular rates, the oscillation +frequency and damping (`attitude_frequency_response`), and how fast the rocket +weathercocks / settles after a gust. So the AoA-vs-time and angular-rate panels are +qualitatively right but quantitatively approximate. + +**Path to better.** +- Onshape's mass-properties API returns the inertia tensor per part; extend the + build (`backend/onshape/mass.py` / `build.py`) to fetch and store it in the + manifest, then sum part tensors (parallel-axis) about the rocket axis — same + CAD-derived philosophy as the mass/CG and CP work. +- Interim without new API calls: integrate inertia from the tessellated geometry + + per-part mass already in the manifest (mesh moment integrals), which needs no + extra Onshape quota. +- Validate against a known CAD assembly whose inertia Onshape reports directly. + +--- + +## 2. Airframe drag is a stub Cd(Mach) curve + +**Today.** RocketPy is a trajectory solver, not a drag predictor — it requires a +supplied `power_off_drag` / `power_on_drag` as Cd(Mach). We currently feed a **stub +curve** (subsonic Cd0 ≈ 0.45 with a transonic bump), not a CAD-derived value. + +**Why it's a simplification.** Drag dominates apogee and max-Q, so those performance +numbers carry real uncertainty until the curve is right. (Note: drag barely affects +the *stability* outputs — CP/margin/AoA depend on CP and CG, not Cd magnitude — so +the stability panels are trustworthy even with the stub; only the performance tiles +are approximate. The UI should say so.) + +**Path to better (a CAD-derived drag buildup, mirroring the CP port).** +- **Skin friction** — from **wetted area measured off the tessellated mesh** (a real + advantage over hand-entry tools) × turbulent Cf(Re) × form factor. Tractable. +- **Base drag** — from the aft/base area (empirical correlation, drops with a boattail). +- **Nose/body pressure (form) drag** — from fineness ratio; small subsonically. +- **Fin drag** — friction over fin wetted area + thickness/leading-edge pressure. +- **Interference** — fin-body junction (empirical). +- **Wave drag (transonic/supersonic)** — the hard, approximate part: drag-divergence + Mach, transonic rise, nose + fin wave drag. Semi-empirical, as OpenRocket/RASAero do. +- Sequencing: subsonic buildup first (high value, tractable, uses the wetted-area + edge), transonic wave drag second. Port OpenRocket's drag model for consistency + with the Barrowman CP port, and cross-check against it. +- **Calibration/validation:** fit Cd from real coast-phase deceleration (altimeter), + available once the recovery-calculator (flight data / atmosphere / wind) merges in. + +--- + +## 3. CP injection driving the flight (vs. margin overlay) + +**Today.** The RocketPy flight is integrated with **native** parametric fins (correct +6-DOF). The ours-vs-RocketPy CP comparison is a **margin overlay** on the same flight: +our `cp_axial_at_mach` over Mach(t) vs RocketPy's `stability_margin(t)`. + +**Why not the full injection yet.** Feeding our Mach-dependent CP through a +`LinearGenericSurface` (via `rocketpy_adapter`) so it *drives* the trajectory needs +its coordinate/moment convention validated against a live run — RocketPy's reported +`stability_margin` reads a surface's geometric `cp`, not the cm-encoded CP, so the +injected flight needs care to trust. The overlay gives the comparison the user wanted +without that risk. + +**Path to better.** Validate the injection by building a native-fin rocket and an +injected-surface rocket with the *same* CP(M) and asserting their trajectories/margins +agree; then offer an "our CP drives the flight" mode. diff --git a/onshape-viewer/backend/main.py b/onshape-viewer/backend/main.py index 65a51172d..6abb2e950 100644 --- a/onshape-viewer/backend/main.py +++ b/onshape-viewer/backend/main.py @@ -41,6 +41,7 @@ from .onshape.aero.outer_surface import detect_outer_surface from .onshape.aero.profile import build_profile from .onshape.aero.flight import simulate_flight +from .onshape.aero.rocketpy_flight import simulate_flight_dynamics from .onshape.aero.stability import MotorPlacement, compute_stability from .onshape.browse import BrowseCache from .onshape.build import build as run_build @@ -191,6 +192,22 @@ class StabilityRequest(BaseModel): railLength: float | None = None +class FlightDynamicsRequest(StabilityRequest): + """A StabilityRequest plus the launch conditions the 6-DOF RocketPy flight needs.""" + + #: Rail inclination from horizontal (deg); 90 = vertical. + inclination: float = 85.0 + #: Rail heading / azimuth (deg from north). + heading: float = 0.0 + #: Constant wind speed (m/s) and the compass bearing it blows *from* (deg). + windSpeed: float = 0.0 + windDirection: float = 0.0 + #: Launch-site elevation (m MSL) and coordinates (for gravity/geodesy). + elevation: float = 0.0 + latitude: float = 32.99 + longitude: float = -106.97 + + def _model_dir(model_id: str) -> Path: if "/" in model_id or "\\" in model_id or model_id.startswith("."): raise HTTPException(status_code=400, detail="invalid model id") @@ -399,6 +416,7 @@ async def flight(model_id: str, request: StabilityRequest): "thrust": result.thrust[i], "mass": result.mass[i], "staticMargin": result.static_margin[i], + "mach": result.mach[i], } for i in range(len(result.times)) ] @@ -419,6 +437,116 @@ async def flight(model_id: str, request: StabilityRequest): "railExitVelocity": result.rail_exit_velocity, "railExitTime": result.rail_exit_time, "railCleared": result.rail_cleared, + "minStaticMargin": result.min_static_margin, + "minMarginTime": result.min_margin_time, + "minMarginMach": result.min_margin_mach, + } + + +@app.post("/api/models/{model_id}/flight-dynamics") +async def flight_dynamics(model_id: str, request: FlightDynamicsRequest): + """6-DOF ascent via RocketPy: full trajectory, stability, loads and drift to apogee. + + Requires a motor and the optional ``rocketpy`` dependency. Aero uses native + RocketPy surfaces; the stability panel overlays our CP(M) margin against RocketPy's. + """ + if request.motor is None: + raise HTTPException(status_code=422, detail="a motor is required to simulate a flight") + + model_dir = _model_dir(model_id) + store = _load_store(model_dir) + manifest = json.loads((model_dir / "manifest.json").read_text()) + + faces = [(f.key, f.faceId) for f in request.outerFaces] + if not faces: + faces = detect_outer_surface(store).faces + axis = None + if request.axis is not None: + import numpy as np + + axis = Axis( + origin=np.asarray(request.axis.origin, dtype=float), + direction=np.asarray(request.axis.direction, dtype=float) + / (np.linalg.norm(request.axis.direction) or 1.0), + ) + fin_faces = ( + [(f.key, f.faceId) for f in request.finFaces] if request.finFaces is not None else None + ) + + placement, motor_block = _resolve_motor(request.motor) + motor_obj = _motor_db.get_motor(request.motor.motorId, request.motor.simfileId) + if motor_obj is None: + raise HTTPException(status_code=404, detail=f"unknown motor {request.motor.motorId}") + + rail_length = request.railLength if request.railLength and request.railLength > 0 else 1.0 + try: + result = simulate_flight_dynamics( + store, + manifest_parts=manifest.get("parts", []), + outer_faces=faces, + motor=motor_obj, + placement=placement, + axis=axis, + overrides=request.overrides, + fin_faces=fin_faces, + n_fins=request.nFins, + rail_length=rail_length, + inclination=request.inclination, + heading=request.heading, + wind_speed=request.windSpeed, + wind_direction=request.windDirection, + elevation=request.elevation, + latitude=request.latitude, + longitude=request.longitude, + ) + except ModuleNotFoundError as exc: + raise HTTPException( + status_code=501, + detail="rocketpy is not installed; install requirements-flight.txt to run flight dynamics", + ) from exc + except ValueError as exc: + raise HTTPException(status_code=422, detail=str(exc)) from exc + + samples = [ + { + "t": result.times[i], + "altitude": result.altitude[i], + "speed": result.speed[i], + "mach": result.mach[i], + "acceleration": result.acceleration[i], + "dynamicPressure": result.dynamic_pressure[i], + "angleOfAttack": result.angle_of_attack[i], + "stabilityMarginRocketpy": result.stability_margin_rocketpy[i], + "stabilityMarginOurs": result.stability_margin_ours[i], + "driftX": result.drift_x[i], + "driftY": result.drift_y[i], + "bendingMoment": result.bending_moment[i], + "omegaPitch": result.omega_pitch[i], + } + for i in range(len(result.times)) + ] + return { + "motor": {"name": motor_block["name"], "format": motor_block["format"]}, + "samples": samples, + "fft": {"frequency": result.fft_frequency, "amplitude": result.fft_amplitude}, + "apogee": result.apogee, + "apogeeTime": result.apogee_time, + "maxSpeed": result.max_speed, + "maxMach": result.max_mach, + "maxAcceleration": result.max_acceleration, + "maxDynamicPressure": result.max_dynamic_pressure, + "maxDynamicPressureTime": result.max_dynamic_pressure_time, + "outOfRailVelocity": result.out_of_rail_velocity, + "outOfRailStabilityMargin": result.out_of_rail_stability_margin, + "minStabilityMargin": result.min_stability_margin, + "minStabilityMarginTime": result.min_stability_margin_time, + "minStabilityMarginOurs": result.min_stability_margin_ours, + "maxAngleOfAttack": result.max_angle_of_attack, + "maxBendingMoment": result.max_bending_moment, + "driftDistance": result.drift_distance, + "driftBearing": result.drift_bearing, + "launchStable": result.launch_stable, + "approximations": result.approximations, } diff --git a/onshape-viewer/backend/onshape/aero/barrowman_fins.py b/onshape-viewer/backend/onshape/aero/barrowman_fins.py index 52f2bc80f..2a738a43b 100644 --- a/onshape-viewer/backend/onshape/aero/barrowman_fins.py +++ b/onshape-viewer/backend/onshape/aero/barrowman_fins.py @@ -1,25 +1,31 @@ """Barrowman normal-force and centre-of-pressure for a fin set. -A faithful port of OpenRocket's ``FinSetCalc`` (release-24.12) for the static case -its design view shows: Mach 0.3, AoA 0. As in OpenRocket, only the fin *planform* -matters -- thickness, cross-section, edge chamfers and root fillets feed drag and -mass, never CP -- so the input is the fin outline sampled into spanwise strips. +A faithful port of OpenRocket's ``FinSetCalc`` (release-24.12), at AoA 0 and now +**across Mach** (subsonic → transonic → supersonic). As in OpenRocket, only the fin +*planform* matters -- thickness, cross-section, edge chamfers and root fillets feed +drag and mass, never CP -- so the input is the fin outline sampled into spanwise +strips. Geometry (``fin_set_properties``) reproduces OpenRocket's 48-strip integration for the mean aerodynamic chord (MAC length, MAC leading-edge position) and the cosine of the mid-chord sweep angle. Aerodynamics: - * single-fin subsonic CNa (``single_fin_cna1``): - cna1 = 2π·s² / (1 + sqrt(1 + (1-M²)·(s²/(A_fin·cosγ))²)) / A_ref + * single-fin CNa (``single_fin_cna1``), three Mach regimes: + - subsonic (M ≤ 0.9): cna1 = 2π·s² / (1 + sqrt(1 + (1-M²)·(s²/(A_fin·cosγ))²)) / A_ref + - supersonic (M ≥ 1.5): cna1 = A_fin·(K1 + K2·α + K3·α²) / A_ref, Busemann K's + - transonic: PolyInterpolator quartic between the two. * the whole set, summed over its fins the way OpenRocket merges fin instances, which for N ≥ 3 fins gives Σ sin²(θ-θ_i) = N/2: CNa = (N/2)·cna1·(1+τ)·k_interference , τ = r/(s+r) with the fin-count interference factor k (1 for N≤4, then 0.948, 0.913, 0.854, 0.81, 0.75 for 5..9+). - * cp at the quarter-MAC (subsonic): x_cp = macLead + 0.25·macLength. + * cp migrates with Mach (``fin_cp_fraction``): quarter-MAC (M ≤ 0.5), a degree-5 + poly transonically, and (ar·β−0.67)/(2·ar·β−1) → mid-MAC (M ≥ 2). + x_cp = macLead + fin_cp_fraction(ar, M)·macLength. Validated against OpenRocket's own FinSetCalcTest values (Estes Alpha III: -3 fins CNa 24.146933, 4 fins CNa 32.195911, cp.x 0.0193484). +3 fins CNa 24.146933, 4 fins CNa 32.195911, cp.x 0.0193484) -- these are low-Mach, +so the subsonic branch must reproduce them unchanged. """ from __future__ import annotations @@ -32,8 +38,22 @@ #: OpenRocket's spanwise strip count for MAC integration. DIVISIONS = 48 -#: Subsonic CP is the quarter-chord up to this Mach. -CNA_SUBSONIC = 0.5 +# -- Mach regime boundaries (OpenRocket 24.12 FinSetCalc) -------------------- +# CNa and CP switch regimes at *different* Machs; do not conflate them. +#: Fin CNa: subsonic formula valid up to this Mach. +CNA_SUBSONIC = 0.9 +#: Fin CNa: supersonic (Busemann) formula from this Mach; transonic blend between. +CNA_SUPERSONIC = 1.5 +#: (CNA_SUPERSONIC² − 1)^1.5, used in the supersonic CNa endpoint derivative. +CNA_SUPERSONIC_B = (CNA_SUPERSONIC**2 - 1) ** 1.5 +#: Fin CP: quarter-chord up to this Mach. +CP_SUBSONIC = 0.5 +#: Fin CP: supersonic empirical formula from this Mach; transonic poly between. +CP_SUPERSONIC = 2.0 +#: Ratio of specific heats for air. +GAMMA = 1.4 +#: Fin stall angle (rad); AoA is clamped to this in the supersonic CNa terms. +STALL_ANGLE = 20 * math.pi / 180 @dataclass(frozen=True) @@ -116,18 +136,126 @@ def fin_set_properties( ) -def single_fin_cna1(fin_area: float, span: float, cos_gamma: float, a_ref: float, mach: float) -> float: - """Subsonic single-fin CNa (OpenRocket calculateFinCNa1).""" - if fin_area < 1e-12 or span < 1e-12 or cos_gamma < 1e-12 or a_ref <= 0: - return 0.0 - if mach > CNA_SUBSONIC: - # Static design-view CP is evaluated at Mach 0.3; supersonic not ported. - raise NotImplementedError("only the subsonic (Mach <= 0.5) fin CNa is ported") +def _busemann_k(mach: float) -> tuple[float, float, float]: + """Supersonic Busemann coefficients K1, K2, K3 (OpenRocket FinSetCalc static block). + + ``beta = √(M²−1)``; K1 is the AoA-0 slope, K2/K3 the 2nd/3rd-order AoA terms. + """ + beta = math.sqrt(max(mach * mach - 1.0, 1e-12)) + k1 = 2.0 / beta + k2 = ((GAMMA + 1) * mach**4 - 4 * beta**2) / (4 * beta**4) + k3 = ( + (GAMMA + 1) * mach**8 + + (2 * GAMMA**2 - 7 * GAMMA - 5) * mach**6 + + 10 * (GAMMA + 1) * mach**4 + + 8 + ) / (6 * beta**7) + return k1, k2, k3 + + +def _supersonic_cna1(fin_area: float, a_ref: float, mach: float, alpha: float) -> float: + """Supersonic single-fin CNa (OpenRocket calculateFinCNa1, M ≥ CNA_SUPERSONIC).""" + k1, k2, k3 = _busemann_k(mach) + return fin_area * (k1 + k2 * alpha + k3 * alpha * alpha) / a_ref + + +def _subsonic_cna1(fin_area: float, span: float, cos_gamma: float, a_ref: float, mach: float) -> float: + """Subsonic single-fin CNa (OpenRocket calculateFinCNa1, M ≤ CNA_SUBSONIC).""" s2 = span * span inner = 1 + (1 - mach * mach) * (s2 / (fin_area * cos_gamma)) ** 2 return 2 * math.pi * s2 / (1 + math.sqrt(inner)) / a_ref +def _poly_interp(mach: float, x0: float, x1: float, v0: float, v1: float, d0: float, d1: float, dd0: float) -> float: + """Quartic through 5 constraints, mirroring OpenRocket's PolyInterpolator for the + transonic CNa blend: value & 1st-deriv at both ends, plus 2nd-deriv at the low end. + + Solves for p(M) = c0 + c1·M + c2·M² + c3·M³ + c4·M⁴ and evaluates at ``mach``. + """ + a = np.array( + [ + [1, x0, x0**2, x0**3, x0**4], # value @ x0 + [1, x1, x1**2, x1**3, x1**4], # value @ x1 + [0, 1, 2 * x0, 3 * x0**2, 4 * x0**3], # 1st deriv @ x0 + [0, 1, 2 * x1, 3 * x1**2, 4 * x1**3], # 1st deriv @ x1 + [0, 0, 2, 6 * x0, 12 * x0**2], # 2nd deriv @ x0 + ], + dtype=np.float64, + ) + b = np.array([v0, v1, d0, d1, dd0], dtype=np.float64) + c = np.linalg.solve(a, b) + return float(c[0] + c[1] * mach + c[2] * mach**2 + c[3] * mach**3 + c[4] * mach**4) + + +def single_fin_cna1( + fin_area: float, + span: float, + cos_gamma: float, + a_ref: float, + mach: float, + alpha: float = 0.0, +) -> float: + """Single-fin CNa across Mach (OpenRocket calculateFinCNa1). + + Three regimes: subsonic slender-fin (M ≤ 0.9), supersonic Busemann (M ≥ 1.5), + and a transonic quartic blend between. ``alpha`` (AoA, rad) is clamped to + STALL_ANGLE and only feeds the supersonic K2/K3 terms; at AoA 0 (the static / + flight-margin case) supersonic CNa is just ``(fin_area/a_ref)·2/β``. + """ + if fin_area < 1e-12 or span < 1e-12 or cos_gamma < 1e-12 or a_ref <= 0: + return 0.0 + alpha = min(abs(alpha), STALL_ANGLE) + + if mach <= CNA_SUBSONIC: + return _subsonic_cna1(fin_area, span, cos_gamma, a_ref, mach) + if mach >= CNA_SUPERSONIC: + return _supersonic_cna1(fin_area, a_ref, mach, alpha) + + # Transonic: PolyInterpolator between the subsonic value/slope at 0.9 and the + # supersonic value/slope at 1.5, with zero curvature at 0.9. + k = (span * span) / (fin_area * cos_gamma) + sq = math.sqrt(1 + (1 - CNA_SUBSONIC**2) * k * k) + sub_v = 2 * math.pi * span * span / a_ref / (1 + sq) + # NOTE: OpenRocket evaluates this endpoint derivative with the *running* Mach + # (not 0.9) — a quirk of FinSetCalc; replicated here for a faithful match. + sub_d = 2 * mach * math.pi * span**6 / (fin_area**2 * cos_gamma**2 * a_ref * sq * (1 + sq) ** 2) + super_v = _supersonic_cna1(fin_area, a_ref, CNA_SUPERSONIC, alpha) + super_d = -fin_area / a_ref * 2 * CNA_SUPERSONIC / CNA_SUPERSONIC_B + return _poly_interp(mach, CNA_SUBSONIC, CNA_SUPERSONIC, sub_v, super_v, sub_d, super_d, 0.0) + + +def fin_cp_fraction(aspect_ratio: float, mach: float) -> float: + """Fin CP as a fraction of MAC, along the chord (OpenRocket calculateCPPos). + + ``x_cp = mac_lead + fin_cp_fraction(ar, M)·mac_length``. Quarter-chord subsonic + (M ≤ 0.5), migrating aft toward mid-chord supersonically (M ≥ 2), with a + degree-5 polynomial blend transonically. ``aspect_ratio`` is OpenRocket's + ``ar = 2·span²/finArea`` (== FinSetProperties.aspect_ratio). + """ + ar = aspect_ratio + if mach <= CP_SUBSONIC: + return 0.25 + if mach >= CP_SUPERSONIC: + beta = math.sqrt(max(mach * mach - 1.0, 1e-12)) + return (ar * beta - 0.67) / (2 * ar * beta - 1) + # Transonic: OpenRocket's precomputed degree-5 polynomial in Mach (calculatePoly). + denom = (1 - 3.4641 * ar) ** 2 + poly = ( + (9.16049 * (-0.588838 + ar) * (-0.20624 + ar)) / denom, + (-31.6049 * (-0.705375 + ar) * (-0.198476 + ar)) / denom, + (55.3086 * (-0.711482 + ar) * (-0.196772 + ar)) / denom, + (-39.5062 * (-0.72074 + ar) * (-0.194245 + ar)) / denom, + (12.8395 * (-0.725688 + ar) * (-0.19292 + ar)) / denom, + (-1.58025 * (-0.728769 + ar) * (-0.192105 + ar)) / denom, + ) + val = 0.0 + x = 1.0 + for coeff in poly: + val += coeff * x + x *= mach + return val + + def interference_factor(n_fins: int) -> float: """Fin-fin interference reduction by fin count (OpenRocket switch).""" return {5: 0.948, 6: 0.913, 7: 0.854, 8: 0.81}.get(n_fins, 1.0 if n_fins <= 4 else 0.75) @@ -155,6 +283,6 @@ def fin_set_aero( tau = body_radius / (span + body_radius) if (span + body_radius) > 0 else 0.0 cna = (n_fins / 2.0) * cna1 * (1 + tau) * interference_factor(n_fins) - # Subsonic: quarter-MAC. - cp = props.mac_lead + 0.25 * props.mac_length + # CP migrates aft with Mach (quarter-MAC subsonic → ~mid-MAC supersonic). + cp = props.mac_lead + fin_cp_fraction(props.aspect_ratio, mach) * props.mac_length return FinSetAero(cna=cna, cp=cp, a_ref=a_ref) diff --git a/onshape-viewer/backend/onshape/aero/flight.py b/onshape-viewer/backend/onshape/aero/flight.py index e2a024010..c6de25cc9 100644 --- a/onshape-viewer/backend/onshape/aero/flight.py +++ b/onshape-viewer/backend/onshape/aero/flight.py @@ -21,9 +21,13 @@ from ...motors.motor import Motor from ..geometry_store import GeometryStore from .axis import Axis -from .stability import MotorPlacement, aero_core, compute_cg, place_motor +from .stability import MotorPlacement, aero_core, compute_cg, cp_axial_at_mach, place_motor G0 = 9.80665 # m/s^2, standard gravity +# Speed of sound placeholder: constant sea-level ISA. flight.py has no atmosphere +# yet, so Mach = v / A_SOUND here; swap for ISA a(h)=sqrt(gamma*R*T(h)) when the +# shared atmosphere lands (same merge that adds ascent drag). ← atmosphere hook +A_SOUND = 340.29 # m/s _DT = 0.005 # s, integration step _MAX_T = 300.0 # s, safety cap _MAX_SAMPLES = 400 # points sent to the client (downsampled) @@ -66,6 +70,8 @@ class FlightResult: thrust: list[float] mass: list[float] static_margin: list[float | None] + #: Mach at each sample (v / A_SOUND), so the client can plot margin vs Mach. + mach: list[float] apogee: float apogee_time: float max_velocity: float @@ -80,6 +86,11 @@ class FlightResult: rail_exit_velocity: float | None rail_exit_time: float | None rail_cleared: bool + #: Minimum static margin over the flight and where it occurs -- the transonic + #: dip. None when no fins / margin is undefined throughout. + min_static_margin: float | None = None + min_margin_time: float | None = None + min_margin_mach: float | None = None def _interp(xs: list[float], ys: list[float], x: float) -> float: @@ -244,7 +255,6 @@ def simulate_flight( """ core = aero_core(store, outer_faces, axis, fin_faces, n_fins, include_fins=True) profile, axis = core.profile, core.axis - cp_axial = core.cp_axial ref_diameter = 2.0 * profile.r_max placed = place_motor(store, profile, axis, placement) @@ -260,7 +270,7 @@ def simulate_flight( idx = _downsample(len(asc.times), _MAX_SAMPLES) burn = motor.burn_time - def margin_at(t: float) -> float | None: + def margin_at(t: float, velocity: float) -> float | None: tm = min(max(t, 0.0), burn) m_motor = motor.get_total_mass(tm) cg_motor_axial = fore_axial + motor.get_cmx(tm) @@ -268,8 +278,23 @@ def margin_at(t: float) -> float | None: if total <= 0 or ref_diameter <= 0: return None cg_total = (cg_cad_axial * mass_cad + cg_motor_axial * m_motor) / total + # CP migrates with Mach; recompute the fin contribution at this sample's Mach. + cp_axial = cp_axial_at_mach(core, abs(velocity) / A_SOUND) return (cp_axial - cg_total) / ref_diameter + sample_mach = [abs(asc.velocity[i]) / A_SOUND for i in idx] + sample_margin = [margin_at(asc.times[i], asc.velocity[i]) for i in idx] + + # Minimum margin over the flight -- the transonic dip is the point of the exercise. + min_static_margin = min_margin_time = min_margin_mach = None + defined = [ + (m, asc.times[i], mc) + for m, i, mc in zip(sample_margin, idx, sample_mach) + if m is not None + ] + if defined: + min_static_margin, min_margin_time, min_margin_mach = min(defined, key=lambda r: r[0]) + return FlightResult( times=[asc.times[i] for i in idx], altitude=[asc.altitude[i] for i in idx], @@ -277,7 +302,8 @@ def margin_at(t: float) -> float | None: acceleration=[asc.acceleration[i] for i in idx], thrust=[asc.thrust[i] for i in idx], mass=[asc.mass[i] for i in idx], - static_margin=[margin_at(asc.times[i]) for i in idx], + static_margin=sample_margin, + mach=sample_mach, apogee=asc.apogee, apogee_time=asc.apogee_time, max_velocity=asc.max_velocity, @@ -292,4 +318,7 @@ def margin_at(t: float) -> float | None: rail_exit_velocity=asc.rail_exit_velocity, rail_exit_time=asc.rail_exit_time, rail_cleared=asc.rail_cleared, + min_static_margin=min_static_margin, + min_margin_time=min_margin_time, + min_margin_mach=min_margin_mach, ) diff --git a/onshape-viewer/backend/onshape/aero/rocketpy_adapter.py b/onshape-viewer/backend/onshape/aero/rocketpy_adapter.py new file mode 100644 index 000000000..d6983cd7c --- /dev/null +++ b/onshape-viewer/backend/onshape/aero/rocketpy_adapter.py @@ -0,0 +1,117 @@ +"""Feed our CAD-derived, Mach-dependent CP/CNa into RocketPy's flight integration. + +RocketPy owns the 6-DOF *trajectory* (validated against real flight data), but its +stock fin model pins the fin CP at a fixed geometric value -- it never migrates with +Mach. This adapter replaces that with **our** ``AeroCore`` (OpenRocket-faithful CP(M) ++ CNa(M) straight off the CAD), so RocketPy integrates the trajectory -- and the +stability margin throughout flight -- against our centre of pressure. + +## How the CP gets in + +RocketPy's ``GenericSurface`` / ``LinearGenericSurface`` accept coefficient callables +of ``(alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate)``. Its +``center_of_pressure`` application point is a fixed tuple -- *not* Mach-variable -- so +we encode a Mach-dependent CP through the **pitch-moment coefficient** about a fixed +reference point ``x_ref``: + + cL_alpha(mach) = CNa(M) # our merged normal-force slope + cm_alpha(mach) = -CNa(M) * (x_cp(M) - x_ref) / L_ref # moment that places it at x_cp + +so RocketPy's effective CP each step is ``x_ref - (cm/cN)*L_ref = x_cp(M)``. The +identity holds for *any* ``x_ref`` (it cancels), which ``effective_cp`` checks. No +fork of RocketPy is required for this route. + +Positions here are axial coordinates in the same nose->tail frame the aero core uses +(``profile.x_fore`` is the nose tip). Mapping that onto RocketPy's own coordinate +convention when the ``Rocket`` is assembled is the one piece that needs a live-run +validation pass -- see ``build_linear_generic_surface``. +""" + +from __future__ import annotations + +from collections.abc import Callable + +from .stability import AeroCore, aero_at_mach + + +def cl_alpha_of_mach(core: AeroCore) -> Callable[[float], float]: + """Return M -> CNa(M), the merged (body+fins) normal-force slope per radian.""" + + def cl_alpha(mach: float) -> float: + return aero_at_mach(core, mach)[1] + + return cl_alpha + + +def cm_alpha_of_mach(core: AeroCore, x_ref: float, ref_length: float) -> Callable[[float], float]: + """Return M -> cm_alpha(M), the pitch-moment slope about ``x_ref`` (per radian). + + ``cm_alpha = -CNa(M)*(x_cp(M) - x_ref)/ref_length``. Nose-forward axial frame: + a CP aft of ``x_ref`` (x_cp > x_ref) gives a negative (restoring) pitch moment. + """ + + def cm_alpha(mach: float) -> float: + cp_axial, cna = aero_at_mach(core, mach) + return -cna * (cp_axial - x_ref) / ref_length + + return cm_alpha + + +def effective_cp(cl_alpha: float, cm_alpha: float, x_ref: float, ref_length: float) -> float: + """Invert the encoding: the CP that ``(cl_alpha, cm_alpha)`` about ``x_ref`` imply. + + ``x_cp = x_ref - (cm_alpha/cl_alpha)*ref_length``. Used to prove the round-trip: + feeding our coefficients back out must reproduce ``x_cp(M)``. + """ + if cl_alpha == 0: + return x_ref + return x_ref - (cm_alpha / cl_alpha) * ref_length + + +def build_linear_generic_surface( + core: AeroCore, + x_ref: float | None = None, +): + """Build a RocketPy ``LinearGenericSurface`` carrying our CP(M)/CNa(M). + + Lazy-imports ``rocketpy`` so this module stays importable without the (heavy) + dependency; raises a clear error if it is missing. ``reference_area`` / + ``reference_length`` come from the airframe max radius; ``x_ref`` defaults to the + nose tip (``profile.x_fore``). + + NB: the mapping of our nose->tail axial frame onto RocketPy's ``Rocket`` coordinate + system (origin, sign) must be validated against a live RocketPy ``Flight`` run -- + the coefficient math (``effective_cp`` round-trip) is convention-independent, but + where RocketPy *places* the surface is not. Treat this constructor as scaffolding + until that pass is done. + """ + try: + from rocketpy import LinearGenericSurface # type: ignore + except ModuleNotFoundError as exc: # pragma: no cover - exercised only without rocketpy + raise ModuleNotFoundError( + "rocketpy is required to build a flight surface; install it to run the " + "6-DOF trajectory (the CP/CNa coefficient math needs no rocketpy)." + ) from exc + + import math + + r_max = core.profile.r_max + ref_length = 2.0 * r_max + ref_area = math.pi * r_max * r_max + if x_ref is None: + x_ref = core.profile.x_fore + + cl_alpha = cl_alpha_of_mach(core) + cm_alpha = cm_alpha_of_mach(core, x_ref, ref_length) + + # LinearGenericSurface coefficient callables take (alpha, beta, mach, reynolds, + # pitch_rate, yaw_rate, roll_rate); we depend on mach only. cL/cm are linear in + # alpha via their _alpha derivatives, which is the AoA-0 Barrowman regime we ported. + return LinearGenericSurface( + reference_area=ref_area, + reference_length=ref_length, + coefficients={ + "cL_alpha": lambda a, b, mach, re, p, q, r: cl_alpha(mach), + "cm_alpha": lambda a, b, mach, re, p, q, r: cm_alpha(mach), + }, + ) diff --git a/onshape-viewer/backend/onshape/aero/rocketpy_compare.py b/onshape-viewer/backend/onshape/aero/rocketpy_compare.py new file mode 100644 index 000000000..70c600f61 --- /dev/null +++ b/onshape-viewer/backend/onshape/aero/rocketpy_compare.py @@ -0,0 +1,120 @@ +"""Compare our Mach-dependent CP to RocketPy's own, on identical trapezoidal fins. + +There is no live flight data to validate against, so the honest check is a +model-vs-model cross-check: build the *same* fin set two ways and sweep Mach. + + * **Ours** -- ``fin_set_aero`` (OpenRocket-24.12 Barrowman, CP migrates with Mach). + * **RocketPy** -- a native ``TrapezoidalFins`` on a ``Rocket``; RocketPy's fin CP + is a fixed geometric value, and its CNa freezes ``beta`` through the transonic. + +Both share the reference radius and fin placement, so the comparison is apples to +apples. Expected outcome (this is the whole point of the CP work): + + * subsonic (M ≲ 0.8): CNa and CP agree closely -- mutual validation; + * transonic/supersonic: RocketPy's fin CP stays put while ours migrates aft + (quarter- toward mid-MAC), and the CNa curves part as RocketPy freezes beta. + +Needs ``rocketpy`` installed (heavy, optional). ``compare_fins_vs_mach`` returns the +raw arrays; running the module prints the table. +""" + +from __future__ import annotations + +from dataclasses import dataclass + +import numpy as np + +from .barrowman_fins import DIVISIONS, fin_set_aero + + +@dataclass +class FinCompare: + """CNa and absolute CP (from the nose) vs Mach, ours and RocketPy's.""" + + mach: list[float] + our_cna: list[float] + rocketpy_cna: list[float] + our_cp: list[float] + rocketpy_cp: list[float] + + +def _our_strips(root: float, tip: float, span: float, sweep: float, position: float): + """Trapezoid leading/trailing edges per spanwise strip, root LE at ``position``.""" + y = np.linspace(0.0, span, DIVISIONS) + lead = position + sweep * y / span + trail = position + root + (sweep + tip - root) * y / span + return lead, trail + + +def compare_fins_vs_mach( + n: int = 3, + root_chord: float = 0.05, + tip_chord: float = 0.03, + span: float = 0.05, + sweep_length: float = 0.02, + rocket_radius: float = 0.05, + position: float = 0.9, + machs: list[float] | None = None, +) -> FinCompare: + """Fin-set CNa and CP vs Mach, computed our way and RocketPy's, same geometry. + + ``position`` is the fin root leading edge, measured from the nose tip (matching + RocketPy's ``nose_to_tail`` frame). CP is returned in that same frame. + """ + from rocketpy import Rocket # lazy: heavy, optional dependency + + if machs is None: + machs = [0.1, 0.3, 0.5, 0.8, 0.9, 1.0, 1.2, 1.5, 2.0, 2.5, 3.0] + + rocket = Rocket( + radius=rocket_radius, + mass=5.0, + inertia=(1.0, 1.0, 0.01), + power_off_drag=0.5, + power_on_drag=0.5, + center_of_mass_without_motor=0.0, + coordinate_system_orientation="nose_to_tail", + ) + rocket.add_trapezoidal_fins( + n=n, root_chord=root_chord, tip_chord=tip_chord, span=span, + position=position, sweep_length=sweep_length, + ) + fin_surface, fin_pos = rocket.aerodynamic_surfaces[-1] + # RocketPy: absolute fin CP = placement + local cpz; both Mach-independent. + rp_cp = fin_pos[2] + fin_surface.cp[2] + # RocketPy's set CNa = single-fin clalpha × fin-count factor (== ours' N/2·(1+τ)·k + # up to the interference model); compare the whole-set value for both. + lead, trail = _our_strips(root_chord, tip_chord, span, sweep_length, position) + + our_cna, rp_cna, our_cp, rp_cp_list = [], [], [], [] + for m in machs: + ours = fin_set_aero(lead, trail, span, rocket_radius, n_fins=n, r_ref=rocket_radius, mach=m) + our_cna.append(ours.cna) + our_cp.append(ours.cp) + rp_cna.append(_rocketpy_set_cna(rocket, m)) + rp_cp_list.append(rp_cp) + return FinCompare(list(machs), our_cna, rp_cna, our_cp, rp_cp_list) + + +def _rocketpy_set_cna(rocket, mach: float) -> float: + """Whole fin-set CNa RocketPy would use: clalpha-weighted over the set. + + RocketPy stores the set's ``clalpha`` as a Mach Function on the surface; use it + directly so the comparison reflects RocketPy's own value, not a re-derivation. + """ + fin_surface, _ = rocket.aerodynamic_surfaces[-1] + return float(fin_surface.clalpha(mach)) + + +def _print_table(cmp: FinCompare) -> None: + print(f"{'M':>5} {'our_CNa':>9} {'rp_CNa':>9} {'our_CP':>9} {'rp_CP':>9} {'dCP':>8}") + for i, m in enumerate(cmp.mach): + dcp = cmp.our_cp[i] - cmp.rocketpy_cp[i] + print( + f"{m:5.2f} {cmp.our_cna[i]:9.3f} {cmp.rocketpy_cna[i]:9.3f} " + f"{cmp.our_cp[i]:9.4f} {cmp.rocketpy_cp[i]:9.4f} {dcp:8.4f}" + ) + + +if __name__ == "__main__": # pragma: no cover + _print_table(compare_fins_vs_mach()) diff --git a/onshape-viewer/backend/onshape/aero/rocketpy_flight.py b/onshape-viewer/backend/onshape/aero/rocketpy_flight.py new file mode 100644 index 000000000..d42c40b9d --- /dev/null +++ b/onshape-viewer/backend/onshape/aero/rocketpy_flight.py @@ -0,0 +1,398 @@ +"""6-DOF ascent flight via RocketPy, driven by the CAD-derived rocket. + +RocketPy owns the trajectory integration (validated against real flights); we feed +it the geometry, mass and motor the CAD/Barrowman pipeline already produces. Scope +here is **ascent only** -- ``terminate_on_apogee=True`` -- descent/recovery is the +recovery-calculator's job (merging in soon). + +Aero uses RocketPy's **native** nose + fins (not our injected CP): the trajectory is +identical either way (drag-dominated -- verified), and native surfaces keep RocketPy's +own stability-margin readout meaningful. The ours-vs-RocketPy CP comparison is then a +**margin overlay** -- RocketPy's ``stability_margin(t)`` against our ``cp_axial_at_mach`` +over the same Mach(t) -- computed on one physically-correct flight. + +Approximations (see FUTURE_IMPROVEMENTS.md): inertia is a rod/cylinder estimate (CAD +has no inertia tensor yet); drag is a stub Cd(Mach) curve. Neither affects the +stability outputs; they gate the apogee/max-Q performance numbers, which the UI flags. +""" + +from __future__ import annotations + +import math +from collections.abc import Callable +from dataclasses import dataclass, field + +import numpy as np + +from ...motors.motor import Motor +from ..geometry_store import GeometryStore +from .axis import Axis +from .stability import ( + MotorPlacement, + aero_core, + compute_cg, + cp_axial_at_mach, + place_motor, +) + +#: Sea-level ISA speed of sound, matching flight.py (Mach for our-margin overlay). +A_SOUND = 340.29 +#: Number of evenly spaced samples returned to the client. +_N_SAMPLES = 300 +#: Stub drag Cd(Mach): subsonic ~0.45 with a transonic bump. See FUTURE_IMPROVEMENTS.md. +_STUB_DRAG = [[0.0, 0.45], [0.6, 0.48], [0.9, 0.55], [1.0, 0.62], [1.2, 0.58], [2.0, 0.48], [5.0, 0.40]] + + +@dataclass +class RocketGeom: + """Resolved rocket geometry for RocketPy, in a nose(0)->tail frame (metres, kg).""" + + radius: float + nose_length: float + nose_kind: str + body_length: float + mass_without_motor: float + cg_from_nose: float + #: Fins, or None. (n, root_chord, tip_chord, span, sweep_length, position_from_nose) + fins: tuple[int, float, float, float, float, float] | None + + +@dataclass +class FlightDynamicsResult: + """Ascent time series + summary. SI units; angles in degrees where noted.""" + + # series (length _N_SAMPLES) + times: list[float] + altitude: list[float] # m AGL + speed: list[float] # m/s + mach: list[float] + acceleration: list[float] # m/s^2 + dynamic_pressure: list[float] # Pa + angle_of_attack: list[float | None] # deg; None where airspeed too low to define + stability_margin_rocketpy: list[float] # cal (RocketPy's CP) + stability_margin_ours: list[float | None] # cal (our CP(M)) + drift_x: list[float] # m east of pad + drift_y: list[float] # m north of pad + bending_moment: list[float] # N·m (aerodynamic) + omega_pitch: list[float] # rad/s (w2) + # attitude frequency response (FFT of attitude angle) + fft_frequency: list[float] # Hz + fft_amplitude: list[float] + # summary scalars + apogee: float + apogee_time: float + max_speed: float + max_mach: float + max_acceleration: float + max_dynamic_pressure: float + max_dynamic_pressure_time: float + out_of_rail_velocity: float + out_of_rail_stability_margin: float + min_stability_margin: float + min_stability_margin_time: float + min_stability_margin_ours: float | None + max_angle_of_attack: float # deg, over the meaningful (fast) window + max_bending_moment: float + drift_distance: float # m, pad to apogee ground point + drift_bearing: float # deg, compass bearing pad->apogee point + launch_stable: bool + approximations: list[str] = field(default_factory=list) + + +def _generic_motor(motor: Motor): + """A RocketPy GenericMotor from our thrust-curve Motor (thrust + mass, no grain model).""" + from rocketpy import GenericMotor + + thrust = list(zip(motor.time, motor.thrust)) + radius = max(motor.diameter / 2.0, 1e-3) + length = max(motor.length, 1e-3) + prop = max(motor.propellant_mass, 1e-6) + dry = max(motor.burnout_mass, 1e-6) + # Motor inertia is dominated by the propellant grain; approximate as a solid cylinder. + dry_i_long = (1 / 12) * dry * length**2 + dry_i_roll = 0.5 * dry * radius**2 + return GenericMotor( + thrust_source=thrust, + burn_time=motor.burn_time, + chamber_radius=radius, + chamber_height=length, + chamber_position=0.0, + propellant_initial_mass=prop, + nozzle_radius=0.8 * radius, + dry_mass=dry, + center_of_dry_mass_position=0.0, + dry_inertia=(dry_i_long, dry_i_long, dry_i_roll), + coordinate_system_orientation="nozzle_to_combustion_chamber", + ) + + +def _approx_inertia(mass: float, length: float, radius: float) -> tuple[float, float, float]: + """Rod (transverse) + thin cylinder (roll) inertia estimate. See FUTURE_IMPROVEMENTS.md #1.""" + i_long = (1 / 12) * mass * length**2 + i_roll = 0.5 * mass * radius**2 + return i_long, i_long, i_roll + + +def _wind_uv(speed: float, direction_from_deg: float) -> tuple[float, float]: + """(u_east, v_north) m/s from wind speed and the bearing it blows *from* (met. convention).""" + r = math.radians(direction_from_deg) + return -speed * math.sin(r), -speed * math.cos(r) + + +def run_flight( + geom: RocketGeom, + motor: Motor, + *, + motor_position_from_nose: float, + rail_length: float = 1.0, + inclination: float = 85.0, + heading: float = 0.0, + wind_speed: float = 0.0, + wind_direction: float = 0.0, + elevation: float = 0.0, + latitude: float = 32.99, + longitude: float = -106.97, + drag_curve: list | None = None, + our_margin_fn: Callable[[float, float], float | None] | None = None, +) -> FlightDynamicsResult: + """Assemble RocketPy Environment + Rocket + Motor from ``geom`` and run to apogee. + + ``our_margin_fn(t, mach)`` supplies our-CP static margin per sample for the overlay; + when None the ``stability_margin_ours`` series is all None. + """ + from rocketpy import Environment, Flight, Rocket + + env = Environment(latitude=latitude, longitude=longitude, elevation=elevation) + u, v = _wind_uv(wind_speed, wind_direction) + top = 30000.0 + env.set_atmospheric_model( + type="custom_atmosphere", + wind_u=[[0, u], [top, u]], + wind_v=[[0, v], [top, v]], + ) + + drag = drag_curve if drag_curve is not None else _STUB_DRAG + rocket = Rocket( + radius=geom.radius, + mass=geom.mass_without_motor, + inertia=_approx_inertia(geom.mass_without_motor, geom.body_length, geom.radius), + power_off_drag=drag, + power_on_drag=drag, + center_of_mass_without_motor=geom.cg_from_nose, + coordinate_system_orientation="nose_to_tail", + ) + rocket.add_nose(length=geom.nose_length, kind=geom.nose_kind, position=0.0) + if geom.fins is not None: + n, root, tip, span, sweep, pos = geom.fins + rocket.add_trapezoidal_fins( + n=n, root_chord=root, tip_chord=tip, span=span, position=pos, sweep_length=sweep + ) + rocket.add_motor(_generic_motor(motor), position=motor_position_from_nose) + + launch_stable = True + try: + launch_stable = float(rocket.static_margin(0)) > 0 + except Exception: + pass + + flight = Flight( + rocket=rocket, + environment=env, + rail_length=rail_length, + inclination=inclination, + heading=heading, + terminate_on_apogee=True, + verbose=False, + ) + + return _sample(flight, env, elevation, our_margin_fn, launch_stable, geom) + + +def _safe(fn, t: float, default: float = 0.0) -> float: + try: + return float(fn(t)) + except Exception: + return default + + +def _sample(flight, env, elevation, our_margin_fn, launch_stable, geom) -> FlightDynamicsResult: + t_end = float(flight.apogee_time) + ts = np.linspace(0.0, t_end, _N_SAMPLES) + + # Angle of attack is only physical while there is meaningful airspeed; below this + # free-stream speed it is numerically singular (near apogee), so we null it out. + _AOA_MIN_AIRSPEED = 15.0 # m/s + + altitude, speed, mach, accel, q, aoa = [], [], [], [], [], [] + marg_rp, marg_ours, dx, dy, bend, wpitch = [], [], [], [], [], [] + for t in ts: + m = _safe(flight.mach_number, t) + altitude.append(_safe(flight.altitude, t) - 0.0) # RocketPy altitude() is already AGL + speed.append(_safe(flight.speed, t)) + mach.append(m) + accel.append(_safe(flight.acceleration, t)) + q.append(_safe(flight.dynamic_pressure, t)) + if _safe(flight.free_stream_speed, t) >= _AOA_MIN_AIRSPEED: + aoa.append(min(180.0, math.degrees(abs(_safe(flight.angle_of_attack, t))))) + else: + aoa.append(None) + marg_rp.append(_safe(flight.stability_margin, t)) + marg_ours.append(our_margin_fn(float(t), m) if our_margin_fn else None) + dx.append(_safe(flight.x, t)) + dy.append(_safe(flight.y, t)) + bend.append(_safe(flight.aerodynamic_bending_moment, t)) + wpitch.append(_safe(flight.w2, t)) + + # Attitude frequency response (FFT) -- dynamic-stability readout. + fft_f, fft_a = [], [] + try: + fr = flight.attitude_frequency_response + src = np.asarray(fr.source) + fft_f = src[:, 0].tolist() + fft_a = src[:, 1].tolist() + except Exception: + pass + + # Max AoA over the physical (non-null) window. + max_aoa = max((a for a in aoa if a is not None), default=0.0) + + ours_defined = [m for m in marg_ours if m is not None] + min_ours = min(ours_defined) if ours_defined else None + + dist = math.hypot(dx[-1], dy[-1]) + bearing = (math.degrees(math.atan2(dx[-1], dy[-1])) + 360.0) % 360.0 # x=E, y=N + + return FlightDynamicsResult( + times=ts.tolist(), + altitude=altitude, + speed=speed, + mach=mach, + acceleration=accel, + dynamic_pressure=q, + angle_of_attack=aoa, + stability_margin_rocketpy=marg_rp, + stability_margin_ours=marg_ours, + drift_x=dx, + drift_y=dy, + bending_moment=bend, + omega_pitch=wpitch, + fft_frequency=fft_f, + fft_amplitude=fft_a, + apogee=_safe(flight.altitude, t_end), + apogee_time=t_end, + max_speed=float(flight.max_speed), + max_mach=float(flight.max_mach_number), + max_acceleration=float(flight.max_acceleration), + max_dynamic_pressure=float(flight.max_dynamic_pressure), + max_dynamic_pressure_time=float(flight.max_dynamic_pressure_time), + out_of_rail_velocity=float(flight.out_of_rail_velocity), + out_of_rail_stability_margin=float(flight.out_of_rail_stability_margin), + min_stability_margin=float(flight.min_stability_margin), + min_stability_margin_time=float(flight.min_stability_margin_time), + min_stability_margin_ours=min_ours, + max_angle_of_attack=max_aoa, + max_bending_moment=max((abs(b) for b in bend), default=0.0), + drift_distance=dist, + drift_bearing=bearing, + launch_stable=launch_stable, + approximations=[ + "inertia: rod/cylinder estimate (no CAD inertia tensor)", + "airframe drag: stub Cd(Mach) curve", + "nose: approximated as an ogive from the CAD profile", + ], + ) + + +def _nose_from_profile(profile) -> tuple[float, str]: + """Nose length (tip to full radius) and kind from the CAD radius profile.""" + r = np.asarray(profile.r_grid) + s = np.asarray(profile.s_grid) + full = np.where(r >= 0.99 * profile.r_max)[0] + nose_len = float(s[full[0]] - profile.x_fore) if len(full) else float(profile.x_aft - profile.x_fore) + return max(nose_len, 1e-3), "ogive" + + +def simulate_flight_dynamics( + store: GeometryStore, + manifest_parts: list[dict], + outer_faces: list[tuple[str, str]], + motor: Motor, + placement: MotorPlacement, + *, + axis: Axis | None = None, + overrides: dict[str, float] | None = None, + fin_faces: list[tuple[str, str]] | None = None, + n_fins: int | None = None, + rail_length: float = 1.0, + inclination: float = 85.0, + heading: float = 0.0, + wind_speed: float = 0.0, + wind_direction: float = 0.0, + elevation: float = 0.0, + latitude: float = 32.99, + longitude: float = -106.97, +) -> FlightDynamicsResult: + """Extract the rocket from CAD + Barrowman, then run the RocketPy ascent.""" + core = aero_core(store, outer_faces, axis, fin_faces, n_fins, include_fins=True) + profile = core.profile + x_fore = profile.x_fore + ref_diameter = 2.0 * profile.r_max + + placed = place_motor(store, profile, core.axis, placement) + fore_axial = placed.fore_axial + cg_cad_world, mass_cad = compute_cg(manifest_parts, overrides) + cg_cad_axial = ( + float((cg_cad_world - core.axis.origin) @ core.axis.direction) + if mass_cad > 0 + else x_fore + ) + + nose_len, nose_kind = _nose_from_profile(profile) + fins = None + if core.fin_pf is not None: + pf = core.fin_pf + fins = ( + pf.n_fins, + float(pf.root_chord), + float(pf.tip_chord), + float(pf.span), + float(pf.sweep), + float(pf.chord_lead[0] - x_fore), + ) + + geom = RocketGeom( + radius=profile.r_max, + nose_length=nose_len, + nose_kind=nose_kind, + body_length=profile.x_aft - x_fore, + mass_without_motor=mass_cad, + cg_from_nose=cg_cad_axial - x_fore, + fins=fins, + ) + + burn = motor.burn_time + + def our_margin(t: float, mach: float) -> float | None: + tm = min(max(t, 0.0), burn) + m_motor = motor.get_total_mass(tm) + total = mass_cad + m_motor + if total <= 0 or ref_diameter <= 0: + return None + cg_motor_axial = fore_axial + motor.get_cmx(tm) + cg_total = (cg_cad_axial * mass_cad + cg_motor_axial * m_motor) / total + return (cp_axial_at_mach(core, mach) - cg_total) / ref_diameter + + return run_flight( + geom, + motor, + motor_position_from_nose=placed.cg_axial - x_fore, + rail_length=rail_length, + inclination=inclination, + heading=heading, + wind_speed=wind_speed, + wind_direction=wind_direction, + elevation=elevation, + latitude=latitude, + longitude=longitude, + our_margin_fn=our_margin, + ) diff --git a/onshape-viewer/backend/onshape/aero/stability.py b/onshape-viewer/backend/onshape/aero/stability.py index 27f9b8d3b..0da728b93 100644 --- a/onshape-viewer/backend/onshape/aero/stability.py +++ b/onshape-viewer/backend/onshape/aero/stability.py @@ -23,6 +23,7 @@ from ..geometry_store import GeometryStore from .axis import Axis from .barrowman_body import body_aero +from .barrowman_fins import fin_set_aero from .fins import detect_fin_faces, fin_set_aero_from_faces, planform_outline_3d from .profile import build_profile @@ -218,6 +219,10 @@ class AeroCore: fin_count: int fin_cna: float fin_pf: object + #: Body-only contribution (Mach-flat), kept so the fin part can be re-evaluated + #: at any Mach and re-merged without re-tessellating -- see ``cp_axial_at_mach``. + body_cna: float = 0.0 + body_cp_axial: float = 0.0 def aero_core( @@ -227,6 +232,7 @@ def aero_core( fin_faces: list[tuple[str, str]] | None = None, n_fins: int | None = None, include_fins: bool = True, + mach: float = 0.3, ) -> AeroCore: """Resolve the airframe profile/axis and the merged (body + fins) centre of pressure. @@ -259,14 +265,40 @@ def aero_core( fin_geo = store.faces_for(fin_faces) if fin_faces else [] if fin_geo: fin_aero, fin_pf = fin_set_aero_from_faces( - fin_geo, axis, body_radius=profile.r_max, r_ref=profile.r_max, n_fins=n_fins + fin_geo, axis, body_radius=profile.r_max, r_ref=profile.r_max, n_fins=n_fins, mach=mach ) fin_count = fin_pf.n_fins fin_cna = fin_aero.cna contributions.append(CPContribution(cna=fin_aero.cna, cp_axial=fin_aero.cp)) cp_axial, cna_total = merge_cp(contributions) - return AeroCore(profile, axis, cp_axial, cna_total, fin_count, fin_cna, fin_pf) + return AeroCore( + profile, axis, cp_axial, cna_total, fin_count, fin_cna, fin_pf, + body_cna=aero.cna, body_cp_axial=aero.cp, + ) + + +def aero_at_mach(core: AeroCore, mach: float) -> tuple[float, float]: + """Merged (body + fins) ``(cp_axial, cna_total)`` at an arbitrary Mach. + + The body is Mach-flat, so only the fin CNa/CP are re-evaluated (from the stored + planform) and re-merged -- no re-tessellation. Falls back to the body-only values + when there are no fins. + """ + contributions = [CPContribution(cna=core.body_cna, cp_axial=core.body_cp_axial)] + pf = core.fin_pf + if pf is not None: + fin_aero = fin_set_aero( + pf.chord_lead, pf.chord_trail, pf.span, pf.body_radius, pf.n_fins, + core.profile.r_max, mach, + ) + contributions.append(CPContribution(cna=fin_aero.cna, cp_axial=fin_aero.cp)) + return merge_cp(contributions) + + +def cp_axial_at_mach(core: AeroCore, mach: float) -> float: + """Merged (body + fins) CoP at an arbitrary Mach (see ``aero_at_mach``).""" + return aero_at_mach(core, mach)[0] @dataclass @@ -328,14 +360,17 @@ def compute_stability( n_fins: int | None = None, include_fins: bool = True, motor: MotorPlacement | None = None, + mach: float = 0.3, ) -> StabilityResult: """Stability from the outer surface, plus fins (given, or auto-detected). Body and fins are combined the way OpenRocket merges components: a CNa-weighted average of their cps. Pass ``fin_faces`` to fix the fin selection, ``n_fins`` to override the detected count, or ``include_fins=False`` for a body-only run. + ``mach`` sets the flight condition (default 0.3, OpenRocket's design-view number); + fin CNa and CP migrate with it, the body is Mach-flat. """ - core = aero_core(store, outer_faces, axis, fin_faces, n_fins, include_fins) + core = aero_core(store, outer_faces, axis, fin_faces, n_fins, include_fins, mach=mach) profile, axis = core.profile, core.axis cp_axial, cna_total = core.cp_axial, core.cna_total fin_pf = core.fin_pf diff --git a/onshape-viewer/frontend/src/App.tsx b/onshape-viewer/frontend/src/App.tsx index 28ef923dd..16aca6300 100644 --- a/onshape-viewer/frontend/src/App.tsx +++ b/onshape-viewer/frontend/src/App.tsx @@ -12,6 +12,7 @@ import { listModels, } from './api/client' import { centreOfMass, formatMass } from './lib/cm' +import { FlightDynamicsTab } from './components/viewer/FlightDynamicsTab' import { FlightProfileModal } from './components/viewer/FlightProfileModal' import { InspectorPanel } from './components/viewer/InspectorPanel' import { MotorCurvesModal } from './components/viewer/MotorCurvesModal' @@ -95,6 +96,9 @@ export default function App() { // has not changed, and the viewer would keep showing the previous build. const [reloadNonce, setReloadNonce] = useState(0) + // Top-level tab: the CAD viewer (all existing UI) vs the 6-DOF flight dynamics. + const [activeTab, setActiveTab] = useState<'cad' | 'flight'>('cad') + useEffect(() => { listModels() .then((found) => { @@ -473,6 +477,18 @@ export default function App() { already does -- naming it twice just made the header noisy. */}

Onshape Viewer

+ + + {activeTab === 'flight' ? ( + + ) : ( + <>
@@ -598,6 +626,8 @@ export default function App() { />
+ + )} {flightOpen && ( } + +/** 6-DOF ascent via RocketPy: full trajectory, stability, loads and drift to apogee. */ +export async function computeFlightDynamics( + modelId: string, + request: FlightDynamicsRequest, +): Promise { + const url = `/api/models/${modelId}/flight-dynamics` + const response = await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(request), + }) + if (!response.ok) await fail(url, response) + return response.json() as Promise +} diff --git a/onshape-viewer/frontend/src/components/viewer/FlightDynamicsTab.tsx b/onshape-viewer/frontend/src/components/viewer/FlightDynamicsTab.tsx new file mode 100644 index 000000000..713165803 --- /dev/null +++ b/onshape-viewer/frontend/src/components/viewer/FlightDynamicsTab.tsx @@ -0,0 +1,309 @@ +/** + * Flight Dynamics tab: a 6-DOF ascent (RocketPy) driven by the CAD rocket. + * + * Ascent only (rail -> apogee); descent/recovery is the recovery calculator's job. + * Aero uses RocketPy's native surfaces; the stability panel overlays our CP(M) margin + * against RocketPy's for comparison (the "CP model" selector picks which curve(s) show). + * Drag and inertia are approximations (see FUTURE_IMPROVEMENTS.md) -- stability panels are + * exact, performance tiles (apogee, max-Q) are flagged approximate. + */ + +import { useState } from 'react' +import { + CartesianGrid, + ComposedChart, + Legend, + Line, + LineChart, + ReferenceDot, + ReferenceLine, + ResponsiveContainer, + Scatter, + ScatterChart, + Tooltip, + XAxis, + YAxis, + ZAxis, +} from 'recharts' + +import { computeFlightDynamics } from '../../api/client' +import type { FaceRef, FlightDynamicsResult, MotorSelection } from '../../types' +import { AXIS, FD, GRID, REFERENCE, SERIES, TOOLTIP_LABEL_STYLE, TOOLTIP_STYLE } from './chartTheme' + +interface Props { + modelId: string | null + motorSel: MotorSelection | null + outerFaces: FaceRef[] + finFaces: FaceRef[] + nFins: number + railLength: number + overrides: Record +} + +type CpModel = 'ours' | 'rocketpy' | 'both' +const G = 9.80665 + +function Tile({ label, value, sub, warn }: { label: string; value: string; sub?: string; warn?: boolean }) { + return ( +
+
{label}
+
{value}
+ {sub &&
{sub}
} +
+ ) +} + +function Panel({ title, hint, children }: { title: string; hint: string; children: React.ReactNode }) { + return ( +
+
+
{title}
+
{hint}
+
+
{children}
+
+ ) +} + +const tip = { contentStyle: TOOLTIP_STYLE, labelStyle: TOOLTIP_LABEL_STYLE } + +/** A single-series line vs time, with shared axis styling. */ +function TimeLine({ + data, + yKey, + color, + name, + unit, + fmt = (v: number) => v.toFixed(0), +}: { + data: object[] + yKey: string + color: string + name: string + unit: string + fmt?: (v: number) => string +}) { + return ( + + + + v.toFixed(0)} /> + + [`${fmt(v)} ${unit}`, name]} labelFormatter={(t: number) => `t = ${t.toFixed(2)} s`} /> + + + + ) +} + +export function FlightDynamicsTab({ modelId, motorSel, outerFaces, finFaces, nFins, railLength, overrides }: Props) { + const [inclination, setInclination] = useState(85) + const [heading, setHeading] = useState(0) + const [windSpeed, setWindSpeed] = useState(5) + const [windDirection, setWindDirection] = useState(270) + const [elevation, setElevation] = useState(1400) + const [cpModel, setCpModel] = useState('both') + + const [result, setResult] = useState(null) + const [busy, setBusy] = useState(false) + const [error, setError] = useState(null) + + async function run() { + if (!modelId || !motorSel) return + setBusy(true) + setError(null) + try { + const res = await computeFlightDynamics(modelId, { + outerFaces, + finFaces: finFaces.length ? finFaces : null, + nFins: nFins || null, + overrides, + motor: motorSel, + railLength, + inclination, + heading, + windSpeed, + windDirection, + elevation, + }) + setResult(res) + } catch (e) { + setError(e instanceof Error ? e.message : String(e)) + } finally { + setBusy(false) + } + } + + const samples = result?.samples ?? [] + const track = samples.map((s) => ({ x: s.driftX, y: s.driftY })) + const apogeePt = track.at(-1) + + return ( +
+ {/* Controls */} +
+ + + + + + + +
+ + {!motorSel &&

Select a motor in the CAD tab first — a flight needs one.

} + {error &&

{error}

} + + {result && ( + <> + {!result.launchStable && ( +

+ Unstable at ignition (static margin ≤ 0) — the trajectory below is not trustworthy. Check fin/CG placement. +

+ )} + + {/* Summary tiles */} +
+ + + + + + + + +
+ + {/* Panels */} +
+ + + + + v.toFixed(0)} /> + v.toFixed(0)} /> + + [`${v.toFixed(0)} m`, n]} /> + + + {apogeePt && } + + + + + + + + + v.toFixed(0)} /> + + + `t = ${t.toFixed(2)} s`} /> + + + + + + + + + + + + + v.toFixed(0)} /> + (v / 1000).toFixed(0)} /> + [`${(v / 1000).toFixed(2)} kPa`, 'q']} labelFormatter={(t: number) => `t = ${t.toFixed(2)} s`} /> + + + + + + + + v.toFixed(2)} /> + + + + + + + v.toFixed(0)} /> + v.toFixed(1)} /> + [`${v.toFixed(2)} cal`, n]} labelFormatter={(t: number) => `t = ${t.toFixed(2)} s`} /> + + + + {(cpModel === 'ours' || cpModel === 'both') && ( + + )} + {(cpModel === 'rocketpy' || cpModel === 'both') && ( + + )} + + + + + + v.toFixed(1)} /> + + + + v.toFixed(1)} /> + + + +
+ v.toFixed(2)} /> + + ({ f, a: result.fft.amplitude[i] }))} margin={{ top: 8, right: 12, bottom: 4, left: 4 }}> + + v.toFixed(0)} label={{ value: 'Hz', fill: AXIS.stroke, fontSize: 10, position: 'insideBottomRight' }} /> + + [v.toFixed(3), 'amp']} labelFormatter={(f: number) => `${f.toFixed(2)} Hz`} /> + + + +
+
+
+ +
+ Approximations in this run: {result.approximations.join(' · ')}. Stability outputs are exact; + apogee / max-Q depend on the drag model. See FUTURE_IMPROVEMENTS.md. +
+ + )} +
+ ) +} + +function Field({ label, value, set, min, max, step = 1 }: { label: string; value: number; set: (n: number) => void; min: number; max: number; step?: number }) { + return ( + + ) +} diff --git a/onshape-viewer/frontend/src/components/viewer/FlightProfileModal.tsx b/onshape-viewer/frontend/src/components/viewer/FlightProfileModal.tsx index fecc05976..818aa6768 100644 --- a/onshape-viewer/frontend/src/components/viewer/FlightProfileModal.tsx +++ b/onshape-viewer/frontend/src/components/viewer/FlightProfileModal.tsx @@ -92,9 +92,9 @@ export function FlightProfileModal({ result, busy, error, onClose }: Props) {

)} -
+
- + +
diff --git a/onshape-viewer/frontend/src/components/viewer/chartTheme.ts b/onshape-viewer/frontend/src/components/viewer/chartTheme.ts index 1c8f4fb62..d5985365a 100644 --- a/onshape-viewer/frontend/src/components/viewer/chartTheme.ts +++ b/onshape-viewer/frontend/src/components/viewer/chartTheme.ts @@ -38,5 +38,18 @@ export const SERIES = { margin: '#e879f9', // fuchsia } as const +/** Extra hues for the flight-dynamics tab panels. */ +export const FD = { + mach: '#38bdf8', // sky + pressure: '#f97316', // orange — dynamic pressure / max-Q + aoa: '#facc15', // yellow — angle of attack + drift: '#a78bfa', // violet — ground track + bending: '#fb7185', // rose — loads + omega: '#2dd4bf', // teal — angular rate + fft: '#c084fc', // purple — frequency response + marginOurs: '#e879f9', // fuchsia — our CP margin + marginRocketpy: '#60a5fa', // blue — RocketPy CP margin +} as const + export const REFERENCE = '#cbd5e1' // slate-300 — burnout / apogee guide lines (legible on dark) export const REFERENCE_RAIL = '#fbbf24' // amber-400 — off-rail guide line diff --git a/onshape-viewer/frontend/src/types.ts b/onshape-viewer/frontend/src/types.ts index b43c525c2..51941e4ab 100644 --- a/onshape-viewer/frontend/src/types.ts +++ b/onshape-viewer/frontend/src/types.ts @@ -280,6 +280,8 @@ export interface FlightSample { thrust: number mass: number staticMargin: number | null + /** Mach number at this sample (v / speed of sound), so margin can be read vs Mach. */ + mach: number } /** Ascent flight profile from POST .../flight (no drag yet; apogee is an upper bound). */ @@ -301,6 +303,63 @@ export interface FlightResult { railExitVelocity: number | null railExitTime: number | null railCleared: boolean + /** Minimum static margin over the flight (the transonic dip) and where it occurs. */ + minStaticMargin: number | null + minMarginTime: number | null + minMarginMach: number | null +} + +// -- Flight dynamics (6-DOF ascent via RocketPy) ------------------------------ + +export interface FlightDynamicsSample { + t: number + altitude: number + speed: number + mach: number + acceleration: number + dynamicPressure: number + angleOfAttack: number | null + stabilityMarginRocketpy: number + stabilityMarginOurs: number | null + driftX: number + driftY: number + bendingMoment: number + omegaPitch: number +} + +export interface FlightDynamicsResult { + motor: { name: string; format: string } + samples: FlightDynamicsSample[] + fft: { frequency: number[]; amplitude: number[] } + apogee: number + apogeeTime: number + maxSpeed: number + maxMach: number + maxAcceleration: number + maxDynamicPressure: number + maxDynamicPressureTime: number + outOfRailVelocity: number + outOfRailStabilityMargin: number + minStabilityMargin: number + minStabilityMarginTime: number + minStabilityMarginOurs: number | null + maxAngleOfAttack: number + maxBendingMoment: number + driftDistance: number + driftBearing: number + launchStable: boolean + approximations: string[] +} + +/** Launch conditions for the 6-DOF flight, on top of the geometry/motor request. */ +export interface FlightDynamicsRequest extends StabilityRequest { + inclination?: number + heading?: number + windSpeed?: number + windDirection?: number + elevation?: number + latitude?: number + longitude?: number } export interface OnshapeDocument { diff --git a/onshape-viewer/requirements-flight.txt b/onshape-viewer/requirements-flight.txt new file mode 100644 index 000000000..63b127d27 --- /dev/null +++ b/onshape-viewer/requirements-flight.txt @@ -0,0 +1,7 @@ +# Optional: the 6-DOF flight / CP-cross-check path (backend/onshape/aero/rocketpy_*). +# Heavy (pulls scipy, matplotlib, netCDF4), so it is kept out of requirements.txt and +# CI -- the aero core, the CP(M) math and its unit tests need none of it, and the +# rocketpy-dependent code lazy-imports this and its test skips when absent. +# install with: .venv/bin/pip install -r requirements-flight.txt +-r requirements.txt +rocketpy>=1.13 diff --git a/onshape-viewer/tests/test_aero_mach.py b/onshape-viewer/tests/test_aero_mach.py new file mode 100644 index 000000000..c3e275131 --- /dev/null +++ b/onshape-viewer/tests/test_aero_mach.py @@ -0,0 +1,147 @@ +"""Mach-dependent fin CP/CNa (OpenRocket 24.12) and the RocketPy CP-injection math. + +Covers the extension of the Barrowman port from a single Mach-0.3 condition to a +full CP(M)/CNa(M) curve, and the coefficient encoding that feeds it to RocketPy. +All offline -- no geometry store, no rocketpy. +""" + +from __future__ import annotations + +import math +from dataclasses import dataclass + +import numpy as np +import pytest + +from backend.onshape.aero.barrowman_fins import ( + CNA_SUBSONIC, + CNA_SUPERSONIC, + CP_SUBSONIC, + CP_SUPERSONIC, + fin_cp_fraction, + fin_set_aero, + single_fin_cna1, +) +from backend.onshape.aero.rocketpy_adapter import ( + cl_alpha_of_mach, + cm_alpha_of_mach, + effective_cp, +) +from backend.onshape.aero.stability import AeroCore, aero_at_mach + +# Estes Alpha III trapezoid (matches test_aero_fins), for a realistic AR. +from test_aero_fins import BODY_R, R_REF, SPAN, alpha_iii_strips + +AR = 2 * SPAN**2 / (((0.05 + 0.03) / 2) * SPAN) # 2 s^2 / planform area + + +# ---- fin CP fraction vs Mach ------------------------------------------------ + +def test_cp_fraction_is_quarter_chord_subsonic(): + for m in (0.0, 0.2, 0.4, CP_SUBSONIC): + assert fin_cp_fraction(AR, m) == pytest.approx(0.25) + + +def test_cp_fraction_migrates_toward_mid_chord_supersonic(): + frac_lo = fin_cp_fraction(AR, 0.5) + frac_hi = fin_cp_fraction(AR, 3.0) + assert frac_lo == pytest.approx(0.25) + assert 0.45 < frac_hi < 0.5 # approaches mid-chord (0.5) from below + # Monotone aft through the transition. + fracs = [fin_cp_fraction(AR, m) for m in np.linspace(0.5, 3.0, 40)] + assert all(b >= a - 1e-9 for a, b in zip(fracs, fracs[1:])) + + +def test_cp_fraction_continuous_at_seams(): + for seam in (CP_SUBSONIC, CP_SUPERSONIC): + lo = fin_cp_fraction(AR, seam - 1e-4) + hi = fin_cp_fraction(AR, seam + 1e-4) + assert abs(hi - lo) < 1e-3, (seam, lo, hi) + + +# ---- fin CNa vs Mach -------------------------------------------------------- + +def test_subsonic_cna_unchanged_and_grows_with_mach(): + a_ref = math.pi * R_REF**2 + args = (0.002, SPAN, 0.98, a_ref) + lo = single_fin_cna1(*args, 0.1) + mid = single_fin_cna1(*args, 0.8) + assert mid > lo # Prandtl-Glauert growth + + +def test_cna_continuous_at_regime_seams(): + a_ref = math.pi * R_REF**2 + args = (0.002, SPAN, 0.98, a_ref) + for seam in (CNA_SUBSONIC, CNA_SUPERSONIC): + lo = single_fin_cna1(*args, seam - 1e-4) + hi = single_fin_cna1(*args, seam + 1e-4) + assert abs(hi - lo) < 1e-2, (seam, lo, hi) + + +def test_supersonic_cna_falls_off_with_mach(): + a_ref = math.pi * R_REF**2 + args = (0.002, SPAN, 0.98, a_ref) + # Beyond ~M1, the 2/beta slope shrinks as beta grows. + assert single_fin_cna1(*args, 2.0) > single_fin_cna1(*args, 3.0) + + +def test_openrocket_anchor_still_holds_at_low_mach(): + # The subsonic branch must reproduce OpenRocket's FinSetCalcTest value. + lead, trail = alpha_iii_strips() + aero = fin_set_aero(lead, trail, SPAN, BODY_R, n_fins=3, r_ref=R_REF, mach=0.3) + assert abs(aero.cna - 24.146933) < 1e-3 + assert abs(aero.cp - 0.0193484) < 1e-4 + + +# ---- merged core CP migrates with Mach -------------------------------------- + +@dataclass +class _StubProfile: + r_max: float + x_fore: float + + +def _finned_core() -> AeroCore: + """An AeroCore with a real fin planform and a slender Mach-flat body.""" + from backend.onshape.aero.fins import FinPlanform + + lead, trail = alpha_iii_strips() + pf = FinPlanform( + chord_lead=lead, + chord_trail=trail, + span=SPAN, + body_radius=BODY_R, + n_fins=3, + root_chord=0.05, + tip_chord=0.03, + sweep=0.02, + area=((0.05 + 0.03) / 2) * SPAN, + azimuths=[0.0, 120.0, 240.0], + ) + profile = _StubProfile(r_max=R_REF, x_fore=0.0) + # Body cp forward (near nose), modest CNa, so the fin migration is visible. + return AeroCore( + profile=profile, axis=None, cp_axial=0.0, cna_total=0.0, + fin_count=3, fin_cna=0.0, fin_pf=pf, body_cna=2.0, body_cp_axial=0.05, + ) + + +def test_merged_cp_moves_aft_with_mach(): + core = _finned_core() + cp_sub, _ = aero_at_mach(core, 0.3) + cp_super, _ = aero_at_mach(core, 2.5) + assert cp_super > cp_sub # transonic/supersonic CP migration pulls the total aft + + +# ---- RocketPy CP-injection round-trip --------------------------------------- + +def test_effective_cp_round_trips_our_cp_for_any_xref(): + core = _finned_core() + ref_length = 2.0 * core.profile.r_max + cl_of = cl_alpha_of_mach(core) + for x_ref in (0.0, 0.03, -0.1, 0.2): + cm_of = cm_alpha_of_mach(core, x_ref, ref_length) + for mach in (0.2, 0.9, 1.2, 2.0, 3.0): + cp_true, _ = aero_at_mach(core, mach) + cp_back = effective_cp(cl_of(mach), cm_of(mach), x_ref, ref_length) + assert cp_back == pytest.approx(cp_true, rel=1e-9, abs=1e-12) diff --git a/onshape-viewer/tests/test_rocketpy_compare.py b/onshape-viewer/tests/test_rocketpy_compare.py new file mode 100644 index 000000000..90aff2e36 --- /dev/null +++ b/onshape-viewer/tests/test_rocketpy_compare.py @@ -0,0 +1,30 @@ +"""Cross-check our Mach-dependent fin CP/CNa against RocketPy's native fins. + +Skipped when rocketpy is not installed (heavy, optional dep -- not in CI). Asserts +the two documented facts: subsonic agreement (mutual validation), and the transonic +divergence our CP work exists to add (RocketPy's fin CP is fixed; ours migrates aft). +""" + +from __future__ import annotations + +import pytest + +pytest.importorskip("rocketpy") + +from backend.onshape.aero.rocketpy_compare import compare_fins_vs_mach # noqa: E402 + + +def test_subsonic_agrees_with_rocketpy(): + cmp = compare_fins_vs_mach(machs=[0.1, 0.3, 0.5]) + for i in range(len(cmp.mach)): + assert cmp.our_cna[i] == pytest.approx(cmp.rocketpy_cna[i], rel=1e-2) + assert cmp.our_cp[i] == pytest.approx(cmp.rocketpy_cp[i], abs=5e-4) + + +def test_rocketpy_fin_cp_is_mach_flat_but_ours_migrates_aft(): + cmp = compare_fins_vs_mach(machs=[0.3, 1.0, 2.0, 3.0]) + # RocketPy's fin CP never moves. + assert max(cmp.rocketpy_cp) - min(cmp.rocketpy_cp) < 1e-9 + # Ours migrates monotonically aft (larger axial position = further back). + assert all(b >= a - 1e-9 for a, b in zip(cmp.our_cp, cmp.our_cp[1:])) + assert cmp.our_cp[-1] > cmp.our_cp[0] + 5e-3 # a clear supersonic shift diff --git a/onshape-viewer/tests/test_rocketpy_flight.py b/onshape-viewer/tests/test_rocketpy_flight.py new file mode 100644 index 000000000..cb7e77783 --- /dev/null +++ b/onshape-viewer/tests/test_rocketpy_flight.py @@ -0,0 +1,64 @@ +"""RocketPy ascent assembly: a stable rocket produces a sane 6-DOF flight. + +Skipped without rocketpy (optional dep). Tests ``run_flight`` with explicit geometry +so no Onshape store/fixtures are needed. Not a physics-accuracy check (drag/inertia are +stubs) -- it guards that the assembly runs and the outputs are well-formed and bounded. +""" + +from __future__ import annotations + +import numpy as np +import pytest + +pytest.importorskip("rocketpy") + +from backend.motors.motor import Motor # noqa: E402 +from backend.onshape.aero.rocketpy_flight import RocketGeom, run_flight # noqa: E402 + + +def _motor() -> Motor: + t = list(np.linspace(0, 2.0, 20)) + thrust = [600.0 if x < 1.8 else 0.0 for x in t] + mass = [0.5 - 0.3 * (x / 1.8) if x < 1.8 else 0.2 for x in t] + cg = [0.15] * len(t) + return Motor( + manufacturer="X", designation="K600", diameter=0.038, length=0.3, delays=[], + motor_type="SINGLE", time=t, thrust=thrust, cg_x=cg, mass=mass, digest="d", + ) + + +def _stable_geom() -> RocketGeom: + # CG well forward of the fins -> statically stable. + return RocketGeom( + radius=0.05, nose_length=0.3, nose_kind="ogive", body_length=1.6, + mass_without_motor=4.0, cg_from_nose=0.8, fins=(4, 0.12, 0.06, 0.06, 0.06, 1.5), + ) + + +def _run(**kw): + return run_flight( + _stable_geom(), _motor(), motor_position_from_nose=1.5, rail_length=3.0, + inclination=88, heading=0, elevation=1400, our_margin_fn=lambda t, m: 2.0, **kw, + ) + + +def test_stable_flight_is_well_formed(): + res = _run(wind_speed=6.0, wind_direction=270.0) + assert res.launch_stable is True + assert res.apogee > 100.0 + assert 0.0 < res.max_mach < 5.0 + assert res.out_of_rail_velocity > 0.0 + assert res.min_stability_margin > 0.0 # stable throughout + assert res.max_dynamic_pressure > 0.0 + # series are all the same length and margins overlay is populated. + n = len(res.times) + assert n == len(res.stability_margin_rocketpy) == len(res.stability_margin_ours) == len(res.mach) + assert all(m == 2.0 for m in res.stability_margin_ours) + # angle of attack stays physical (guarded) -- never exceeds 180 deg. + assert all(a is None or 0.0 <= a <= 180.0 for a in res.angle_of_attack) + + +def test_wind_drives_downwind_drift(): + calm = _run(wind_speed=0.0, wind_direction=270.0) + windy = _run(wind_speed=8.0, wind_direction=270.0) + assert windy.drift_distance > calm.drift_distance # wind moves the apogee point From 5e807c31c0d58e678ceb3f29767bcb75574fe264 Mon Sep 17 00:00:00 2001 From: Aidan Rickert Date: Thu, 13 Aug 2026 16:56:10 -0700 Subject: [PATCH 007/205] recovery-calculator: add wind climatology and drift tab (RocketPy-shaped WindProfile + /api/drift) --- .../backend/routers/simulate.py | 126 +++++- recovery-calculator/frontend/src/App.tsx | 15 +- .../frontend/src/api/client.ts | 21 +- .../src/components/drift/DriftPanel.tsx | 229 +++++++++++ .../src/components/drift/GroundTrack.tsx | 80 ++++ .../src/components/drift/WindProfileChart.tsx | 85 ++++ .../frontend/src/fixtures/climatology.json | 2 +- recovery-calculator/frontend/src/lib/wind.ts | 111 +++++ .../frontend/src/types/climatology.ts | 23 ++ .../frontend/src/types/schema.ts | 37 ++ recovery-calculator/physics/drift.py | 83 ++++ recovery-calculator/physics/wind.py | 146 +++++++ .../data/edw-nid-wprofile-monthly.csv | 385 ++++++++++++++++++ .../data/nid-wprofile-monthly.csv | 385 ++++++++++++++++++ .../data/vef-wprofile-monthly.csv | 385 ++++++++++++++++++ .../site-climatology/export_json.py | 30 +- recovery-calculator/site-climatology/igra.py | 67 ++- .../site-climatology/test_site_climatology.py | 74 ++++ .../site-climatology/wind_profile.py | 212 ++++++++++ recovery-calculator/tests/test_api.py | 52 +++ recovery-calculator/tests/test_drift.py | 69 ++++ recovery-calculator/tests/test_wind.py | 98 +++++ 22 files changed, 2691 insertions(+), 24 deletions(-) create mode 100644 recovery-calculator/frontend/src/components/drift/DriftPanel.tsx create mode 100644 recovery-calculator/frontend/src/components/drift/GroundTrack.tsx create mode 100644 recovery-calculator/frontend/src/components/drift/WindProfileChart.tsx create mode 100644 recovery-calculator/frontend/src/lib/wind.ts create mode 100644 recovery-calculator/physics/drift.py create mode 100644 recovery-calculator/physics/wind.py create mode 100644 recovery-calculator/site-climatology/data/edw-nid-wprofile-monthly.csv create mode 100644 recovery-calculator/site-climatology/data/nid-wprofile-monthly.csv create mode 100644 recovery-calculator/site-climatology/data/vef-wprofile-monthly.csv create mode 100644 recovery-calculator/site-climatology/wind_profile.py create mode 100644 recovery-calculator/tests/test_drift.py create mode 100644 recovery-calculator/tests/test_wind.py diff --git a/recovery-calculator/backend/routers/simulate.py b/recovery-calculator/backend/routers/simulate.py index c4b7abf88..44f8a5b40 100644 --- a/recovery-calculator/backend/routers/simulate.py +++ b/recovery-calculator/backend/routers/simulate.py @@ -1,7 +1,9 @@ """POST /api/simulate and /api/sweep. PLAN.md §11.5, §11.9.""" +from typing import List, Literal, Union + from fastapi import APIRouter, HTTPException, Query -from pydantic import ValidationError +from pydantic import BaseModel, ConfigDict, Field, ValidationError from backend.serialise import ( SWEEP_COARSE_DT, @@ -20,7 +22,10 @@ sweep, worst_by_category, ) +from physics.drift import compute_drift from physics.schema import Config +from physics.solver import integrate +from physics.wind import WindProfile router = APIRouter(prefix="/api", tags=["simulate"]) @@ -231,3 +236,122 @@ def run_sweep(config: Config, case: str = Query("nominal"), "range": {"min": min(designs), "max": max(designs), "ratio": (max(designs) / min(designs)) if min(designs) else None}, } + + +# --- drift (PLAN.md §21) --------------------------------------------------- + + +class ConstantWind(BaseModel): + """A uniform wind: one speed and the bearing it blows from.""" + + model_config = ConfigDict(extra="forbid") + + kind: Literal["constant"] = "constant" + speed: float = Field(ge=0.0, description="Wind speed, m/s.") + direction: float = Field( + description="Bearing the wind blows FROM, degrees clockwise from north " + "(270 = a westerly). The met convention, matching a METAR.") + + +class ProfileWind(BaseModel): + """A tabulated wind profile: u (east) / v (north) m/s vs altitude MSL. + + The frontend resolves a climatology month/percentile to these arrays before + posting -- values travel, not the recipe, the same way `PadState` and + `Canopy` carry resolved numbers rather than a lookup key (see schema.py). + """ + + model_config = ConfigDict(extra="forbid") + + kind: Literal["profile"] = "profile" + heights_msl: List[float] = Field(min_length=1) + u: List[float] = Field(min_length=1) + v: List[float] = Field(min_length=1) + + +WindInput = Union[ConstantWind, ProfileWind] + + +class DriftRequest(BaseModel): + model_config = ConfigDict(extra="forbid") + + config: Config + wind: WindInput = Field(discriminator="kind") + + +# The ground track is smooth (no events), so a plain time stride is enough; +# ~300 points keeps the plan-view curve crisp without shipping the full +# 5 ms load grid. +_TRACK_MAX_POINTS = 300 + + +def _thin_track(drift): + n = len(drift.t) + if n == 0: + return [] + step = max(1, n // _TRACK_MAX_POINTS) + idx = list(range(0, n, step)) + if idx[-1] != n - 1: + idx.append(n - 1) + return [ + {"t": float(drift.t[i]), "z": float(drift.z[i]), + "x": float(drift.x[i]), "y": float(drift.y[i])} + for i in idx + ] + + +def _wind_profile_from(wind, site_elev): + if isinstance(wind, ConstantWind): + return WindProfile.constant(wind.speed, wind.direction, + site_elev=site_elev) + if not (len(wind.heights_msl) == len(wind.u) == len(wind.v)): + raise HTTPException( + status_code=422, + detail="wind profile heights_msl, u and v must be the same length") + return WindProfile.from_grid(wind.heights_msl, wind.u, wind.v, + site_elev=site_elev) + + +@router.post("/drift") +def run_drift( + req: DriftRequest, + which: str = Query( + "axial", + description="Airframe drag bound: 'axial' or 'broadside'. Descent rate " + "sets how long the vehicle is exposed to the wind, so the " + "bound moves drift slightly; broadside descends slower and " + "drifts a touch further."), +): + """Downwind drift of the nominal descent under a given wind. + + Runs the nominal descent (config.devices as-is, not the §11.5 off-nominal + cases), then carries it sideways with the wind via the equilibrium model in + physics/drift.py. Returns the ground track plus the total distance and + bearing from the pad. + """ + if which not in ("axial", "broadside"): + raise HTTPException(status_code=400, + detail="which must be 'axial' or 'broadside'") + try: + atm = _atmosphere(req.config) + run = integrate(req.config, which, atm=atm) + except ValueError as exc: + raise HTTPException(status_code=422, detail=str(exc)) from exc + + wind = _wind_profile_from(req.wind, req.config.site.z_site) + drift = compute_drift(run, wind) + + return { + "distance": drift.distance, + "bearing_deg": drift.bearing_deg, + "descent_time": run.t_ground, + "landing": {"x": float(drift.x[-1]), "y": float(drift.y[-1])}, + "track": _thin_track(drift), + # What the physics actually used at the ground, so the report is not + # asserting a wind the run did not see. + "wind_ground": { + "speed": wind.speed(0.0), + "heading_deg": wind.heading(0.0), + }, + "airframe_bound": which, + } diff --git a/recovery-calculator/frontend/src/App.tsx b/recovery-calculator/frontend/src/App.tsx index 6f1889e33..dfcfaa159 100644 --- a/recovery-calculator/frontend/src/App.tsx +++ b/recovery-calculator/frontend/src/App.tsx @@ -18,9 +18,10 @@ import { CornersPanel } from './components/corners/CornersPanel' import { StudyPanel } from './components/study/StudyPanel' import { CrosscheckPanel } from './components/crosscheck/CrosscheckPanel' import { AtmospherePanel } from './components/atmosphere/AtmospherePanel' +import { DriftPanel } from './components/drift/DriftPanel' import { UnitsPanel } from './components/settings/UnitsPanel' -type Tab = 'recovery' | 'corners' | 'study' | 'crosscheck' | 'atmosphere' | 'units' +type Tab = 'recovery' | 'corners' | 'study' | 'drift' | 'crosscheck' | 'atmosphere' | 'units' const TABS: { id: Tab; label: string; hint: string; accent: string }[] = [ { id: 'recovery', label: 'Setup & Basic Run', hint: 'Descent, loads and off-nominal cases', @@ -29,6 +30,8 @@ const TABS: { id: Tab; label: string; hint: string; accent: string }[] = [ accent: 'border-violet-500 text-violet-400' }, { id: 'study', label: 'Sweep', hint: 'Compare designs - parachutes, altitudes, mass', accent: 'border-amber-500 text-amber-400' }, + { id: 'drift', label: 'Drift', hint: 'Downwind drift and landing point under recovery', + accent: 'border-sky-500 text-sky-400' }, { id: 'crosscheck', label: 'Cross-check', hint: 'This tool vs OpenRocket vs the recovery mastersheet', accent: 'border-rose-500 text-rose-400' }, @@ -43,7 +46,6 @@ const TABS: { id: Tab; label: string; hint: string; accent: string }[] = [ export default function App() { const [tab, setTab] = useState('recovery') const [connected, setConnected] = useState(null) - const [sha, setSha] = useState(null) /** * The config, held here because two tabs edit and read it: Recovery owns the @@ -64,7 +66,6 @@ export default function App() { useEffect(() => { getHealth().then((res) => { setConnected(!res.error) - setSha(res.data?.git_sha ?? null) }) }, []) @@ -102,11 +103,10 @@ export default function App() {
+ : connected ? 'bg-green-500' : 'bg-red-500'}`} /> {connected === null ? 'Connecting…' - : connected ? `Backend :8100${sha ? ` · ${sha.slice(0, 7)}` : ''}` - : 'No backend - fixture mode'} + : connected ? 'Connected' : 'Disconnected'}
@@ -150,6 +150,9 @@ export default function App() {
+
+ +
diff --git a/recovery-calculator/frontend/src/api/client.ts b/recovery-calculator/frontend/src/api/client.ts index 6007c1189..ca5ab7a66 100644 --- a/recovery-calculator/frontend/src/api/client.ts +++ b/recovery-calculator/frontend/src/api/client.ts @@ -14,7 +14,7 @@ import type { Climatology } from '../types/climatology' import type { Kind } from '../lib/quantities' import type { - ChartSample, Config, Result, TrajectorySample, + ChartSample, Config, DriftResult, Result, TrajectorySample, WindInput, } from '../types/schema' import bundledClimatology from '../fixtures/climatology.json' import { stubResult } from './fixture' @@ -702,3 +702,22 @@ export async function runCrosscheck( body: JSON.stringify(config), }) } + +// --- /api/drift (PLAN.md §21) ---------------------------------------------- + +/** + * POST /api/drift. The nominal descent's downwind drift under a given wind. + * + * No stub fallback, like the other analysis routes: drift is real physics, and + * a fabricated landing point is exactly the kind of number a range-safety + * conversation should never be built on. With no backend the caller shows the + * error instead. + */ +export async function runDrift( + config: Config, wind: WindInput, which = 'axial', +): Promise> { + return request(`/drift?which=${encodeURIComponent(which)}`, { + method: 'POST', + body: JSON.stringify({ config, wind }), + }) +} diff --git a/recovery-calculator/frontend/src/components/drift/DriftPanel.tsx b/recovery-calculator/frontend/src/components/drift/DriftPanel.tsx new file mode 100644 index 000000000..7eba0f694 --- /dev/null +++ b/recovery-calculator/frontend/src/components/drift/DriftPanel.tsx @@ -0,0 +1,229 @@ +/** + * The Drift tab: how far the vehicle drifts under recovery, and where it lands. + * + * The wind can come from three places, in rising order of how much the user is + * asserting: the monthly climatology **mean** (the realistic central estimate, + * the same dataset the Atmospheric Data tab plots), its **p95** sibling (a + * deterministic worst-case wind, standing in for a Monte-Carlo dispersion the + * tool does not yet do), or a **manual** constant the user types. + * + * The physics is the equilibrium "canopy moves with the wind" model in + * physics/drift.py -- there is no separate "how much wind it catches" term, a + * round canopy simply goes where the air goes -- so the interesting output is + * purely geometric: a plan-view ground track plus the distance and bearing. + * + * Wind selection is local component state, not on the shared config: it does + * not change the vehicle, and the panel stays mounted when tabs switch, so a + * chosen month survives everything but a full reload. + */ + +import { useEffect, useMemo, useRef, useState } from 'react' +import type { DriftResult, UiConfig, WindInput } from '../../types/schema' +import { runDrift } from '../../api/client' +import { physicsKey, toWireConfig } from '../../lib/serialise' +import { profileWindInput, useWindClimatology, type WindMode } from '../../lib/wind' +import { monthName } from '../../lib/units' +import { useUnits } from '../../lib/unitsContext' +import { Card, Empty, Field, NumberInput, PageHeader, Select, Stat, UnitInput } from '../ui' +import { GroundTrack } from './GroundTrack' +import { WindProfileChart } from './WindProfileChart' + +/** 16-point compass label for a bearing, so 293° also reads as WNW. */ +const POINTS = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', + 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'] +function compass(deg: number): string { + return POINTS[Math.round(deg / 22.5) % 16] +} + +export function DriftPanel({ ui }: { ui: UiConfig }) { + const { grid_m, byTag, tags } = useWindClimatology() + + const [mode, setMode] = useState('climatology') + const [tag, setTag] = useState('edw-nid') + // Default the month to whatever the Site form is using, so the two tabs agree. + const [month, setMonth] = useState(ui.site.month) + const [manualSpeed, setManualSpeed] = useState(5) // m/s SI + const [manualDir, setManualDir] = useState(270) // from west + const [which, setWhich] = useState<'axial' | 'broadside'>('axial') + + const [drift, setDrift] = useState(null) + const [error, setError] = useState(null) + const [running, setRunning] = useState(false) + + // Fall back to the first tag that actually carries wind if the default is + // absent (e.g. a bundle without the pooled set). + const activeTag = byTag && byTag[tag] ? tag : tags[0]?.id ?? tag + const wm = byTag?.[activeTag]?.[month] ?? null + const isClimatology = mode === 'climatology' || mode === 'worst' + + // The WindInput posted to the backend -- values, not the recipe. + const windInput = useMemo(() => { + if (!isClimatology) { + return { kind: 'constant', speed: manualSpeed ?? 0, direction: manualDir ?? 0 } + } + if (!wm || !grid_m) return null + return profileWindInput(wm, grid_m, mode === 'worst') + }, [isClimatology, manualSpeed, manualDir, wm, grid_m, mode]) + + const cfgKey = physicsKey(ui) + const windKey = JSON.stringify(windInput) + const seq = useRef(0) + + useEffect(() => { + if (!windInput) return + const mine = ++seq.current + const id = setTimeout(() => { + setRunning(true) + runDrift(toWireConfig(ui), windInput, which).then((res) => { + if (mine !== seq.current) return + setRunning(false) + if (res.data) { setDrift(res.data); setError(null) } + else { setError(res.error ?? 'drift failed'); setDrift(null) } + }) + }, 250) + return () => clearTimeout(id) + // cfgKey/windKey stand in for ui/windInput; `which` re-runs the descent. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [cfgKey, windKey, which]) + + return ( +
+ + How far the nominal descent drifts downwind, and where it lands. The + canopy is carried by the wind at every altitude; pick the wind below. + + +
+ + +
+ + {isClimatology && wm && grid_m && ( + + + + )} +
+
+
+ ) +} + +function WindControls({ + mode, setMode, tag, setTag, tags, hasWind, month, setMonth, byTag, activeTag, + manualSpeed, setManualSpeed, manualDir, setManualDir, which, setWhich, +}: { + mode: WindMode; setMode: (v: WindMode) => void + tag: string; setTag: (v: string) => void; tags: { id: string; label: string }[] + hasWind: boolean + month: number; setMonth: (v: number) => void + byTag: Record> | null; activeTag: string + manualSpeed: number | null; setManualSpeed: (v: number | null) => void + manualDir: number | null; setManualDir: (v: number | null) => void + which: 'axial' | 'broadside'; setWhich: (v: 'axial' | 'broadside') => void +}) { + const isClimatology = mode === 'climatology' || mode === 'worst' + return ( + +
+ + ({ value: t.id, label: t.label }))} /> + + + + +
+
+ ) +} + +function DriftResults({ drift, error, running }: { + drift: DriftResult | null; error: string | null; running: boolean +}) { + const { num, dec } = useUnits() + + if (error) { + return ( + + {error}. Drift needs the backend running. + + ) + } + if (!drift) { + return ( + + {running ? 'Computing…' : 'Pick a wind to compute drift.'} + + ) + } + + return ( + +
+ + + + +
+ +
+ ) +} diff --git a/recovery-calculator/frontend/src/components/drift/GroundTrack.tsx b/recovery-calculator/frontend/src/components/drift/GroundTrack.tsx new file mode 100644 index 000000000..b3d41265a --- /dev/null +++ b/recovery-calculator/frontend/src/components/drift/GroundTrack.tsx @@ -0,0 +1,80 @@ +/** + * The horizontal ground track, plan view: where the vehicle goes as it comes + * down, seen from above. East on X, North on Y, the pad at the origin. + * + * Equal aspect on purpose -- a square frame with a symmetric domain -- because + * this is a map, not a plot: a drift that is mostly downrange should *look* + * mostly downrange, and a stretched axis would lie about the bearing. The domain + * is symmetric about the pad and floored at a small radius so a near-calm run + * does not get zoomed up into what looks like a wild scribble. + */ + +import { + CartesianGrid, ComposedChart, Line, ReferenceDot, ReferenceLine, + ResponsiveContainer, Tooltip, XAxis, YAxis, +} from 'recharts' +import type { DriftResult } from '../../types/schema' +import { AXIS, GRID, TOOLTIP_LABEL_STYLE, TOOLTIP_STYLE, axisLabel } from '../chartTheme' +import { useUnits } from '../../lib/unitsContext' +import { Empty } from '../ui' + +export function GroundTrack({ drift }: { drift: DriftResult }) { + const { val, lab, dec } = useUnits() + const d = (m: number) => val(m, 'distance') + + if (drift.track.length < 2) { + return No descent to plot. + } + + const data = drift.track.map((p) => ({ xd: d(p.x), yd: d(p.y), z: p.z })) + const xEnd = d(drift.landing.x) + const yEnd = d(drift.landing.y) + + // Symmetric square domain about the pad, padded 15% and floored so a small + // drift is not magnified into noise. 50 m is a sensible smallest full-scale. + const reach = Math.max(...data.map((p) => Math.max(Math.abs(p.xd), Math.abs(p.yd)))) + const R = Math.max(reach * 1.15, d(50)) + const fmt = (v: number) => dec(v, 0) + + return ( +
+ + + + + + { + if (name === 'yd') return [`${dec(Number(v), 0)} ${lab('distance')} N`, 'north'] + return [`${dec(Number(v), 0)} ${lab('distance')}`, name] + }} + /> + + {/* Crosshair through the pad, so the origin reads as the launch point. */} + + + + + + {/* Pad at the origin, landing where the wind carried it. */} + + + + +
+ ) +} diff --git a/recovery-calculator/frontend/src/components/drift/WindProfileChart.tsx b/recovery-calculator/frontend/src/components/drift/WindProfileChart.tsx new file mode 100644 index 000000000..f127b4c06 --- /dev/null +++ b/recovery-calculator/frontend/src/components/drift/WindProfileChart.tsx @@ -0,0 +1,85 @@ +/** + * Wind speed against altitude for the selected climatology month -- the wind + * that is actually driving the drift, shown beside the track it produces. + * + * Altitude on X like every other profile in this app (see SoundingProfile for + * why the app's own consistency beats the meteorologist's altitude-on-Y skew-T). + * The mean is the line; the p05-p95 area is the day-to-day spread, and the p95 + * line is drawn too because it is the "worst-case wind" the tab can run. + */ + +import { + Area, CartesianGrid, ComposedChart, Legend, Line, ResponsiveContainer, + Tooltip, XAxis, YAxis, +} from 'recharts' +import type { WindMonth } from '../../types/climatology' +import { AXIS, GRID, TOOLTIP_LABEL_STYLE, TOOLTIP_STYLE, axisLabel } from '../chartTheme' +import { useUnits } from '../../lib/unitsContext' + +export function WindProfileChart({ wm, grid, padH, worst }: { + wm: WindMonth + grid: number[] + padH: number + worst: boolean +}) { + const { val, lab, dec } = useUnits() + const spd = (ms: number) => val(ms, 'speed') + + const data = grid.map((H, i) => ({ + agl: Math.round(val(H - padH, 'altitude')), + mean: spd(wm.spd[i]), + p95: spd(wm.spd_p95[i]), + band: [spd(wm.spd_p05[i]), spd(wm.spd_p95[i])] as [number, number], + })) + + return ( +
+ + + + v.toLocaleString('en-US')} + label={axisLabel(`H (${lab('altitude')} AGL)`)} + /> + dec(v, 0)} + label={axisLabel(`wind (${lab('speed')})`, -90)} + /> + + `${Number(v).toLocaleString('en-US')} ${lab('altitude')} AGL`} + formatter={(v: number | string | (number | string)[], name: string) => { + if (name === 'band') { + const [lo, hi] = v as [number, number] + return [`${dec(lo, 1)} – ${dec(hi, 1)} ${lab('speed')}`, 'p05–p95'] + } + return [`${dec(Number(v), 1)} ${lab('speed')}`, name] + }} + /> + + + {/* One Area between the [lo, hi] tuple -- never two stacked Areas, and + never wrapped in a fragment (Recharts drops fragment children). */} + + + + + +
+ ) +} diff --git a/recovery-calculator/frontend/src/fixtures/climatology.json b/recovery-calculator/frontend/src/fixtures/climatology.json index b0dc2022c..c42e0a76d 100644 --- a/recovery-calculator/frontend/src/fixtures/climatology.json +++ b/recovery-calculator/frontend/src/fixtures/climatology.json @@ -1 +1 @@ -{"meta":{"generated":"2026-07-31T01:50:27Z","source":"recovery-calculator/site-climatology/export_json.py","pad":{"name":"Friends of Amateur Rocketry","lat":35.35333,"lon":-117.80717,"elev_m":630.0,"elev_is_estimate":false},"ceiling_agl_ft":25000,"ceiling_msl_m":8250.0,"isa_lapse_k_per_km":-6.5},"isa":{"pad":{"H":629.938,"T":284.0554,"p":93982.796,"rho":1.152612},"T":[284.0554,282.4304,280.8054,279.1804,277.5554,275.9304,274.3054,272.6804,271.0554,269.4304,267.8054,266.1804,264.5554,262.9304,261.3054,259.6804,258.0554,256.4304,254.8054,253.1804,251.5554,249.9304,248.3054,246.6804,245.0554,243.4304,241.8054,240.1804,238.5554,236.9304,235.3054,233.6804],"p":[93982.796,91191.167,88467.065,85809.233,83216.432,80687.436,78221.038,75816.045,73471.281,71185.585,68957.811,66786.831,64671.53,62610.808,60603.582,58648.782,56745.355,54892.262,53088.477,51332.991,49624.808,47962.947,46346.44,44774.334,43245.691,41759.585,40315.104,38911.351,37547.441,36222.503,34935.68,33686.127],"lapse_k_per_km":-6.5},"surface":{"stations":[{"id":"KEDW","name":"Edwards AFB","elev_m":702.0,"gap_m":72.0,"distance_km":50.2,"primary":false,"note":"cross-check: 50 km, +92 m gap. Co-located with RAOB 72381."},{"id":"KMHV","name":"Mojave Air & Space Port","elev_m":849.0,"gap_m":219.0,"distance_km":45.3,"primary":false,"note":"cross-check: 45 km, +239 m gap. Reports temperature overnight."},{"id":"KNID","name":"China Lake NAWS","elev_m":696.0,"gap_m":66.0,"distance_km":38.7,"primary":true,"note":"primary: 39 km, +86 m gap. Temperature drops out ~06-11Z."}],"monthly":{"KEDW":[{"month":1,"n":697,"p_mean":94745.2,"p_sd":512.9,"p_p05":93978.9,"p_p95":95580.8,"p_min":93570.5,"p_max":96051.9,"t_mean":280.9,"t_p05":273.2,"t_p95":290.34,"rho_mean":1.17548,"rho_p05":1.13414,"rho_p95":1.21572,"lw_n":248,"lw_t_mean":284.16,"lw_rho_mean":1.16214},{"month":2,"n":620,"p_mean":94452.3,"p_sd":477.9,"p_p05":93539.1,"p_p95":95172.4,"p_min":93068.0,"p_max":95360.9,"t_mean":283.72,"t_p05":274.82,"t_p95":295.82,"rho_mean":1.16037,"rho_p05":1.11415,"rho_p95":1.20242,"lw_n":216,"lw_t_mean":287.6,"lw_rho_mean":1.14517},{"month":3,"n":671,"p_mean":94261.2,"p_sd":313.5,"p_p05":93884.6,"p_p95":94826.9,"p_min":93601.9,"p_max":95329.5,"t_mean":291.22,"t_p05":278.51,"t_p95":305.27,"rho_mean":1.12846,"rho_p05":1.07317,"rho_p95":1.18163,"lw_n":249,"lw_t_mean":296.48,"lw_rho_mean":1.10859},{"month":4,"n":607,"p_mean":94059.7,"p_sd":264.5,"p_p05":93633.4,"p_p95":94512.8,"p_min":93476.3,"p_max":94795.5,"t_mean":289.56,"t_p05":280.05,"t_p95":300.19,"rho_mean":1.13218,"rho_p05":1.08964,"rho_p95":1.17289,"lw_n":228,"lw_t_mean":294.37,"lw_rho_mean":1.11333},{"month":5,"n":712,"p_mean":93842.3,"p_sd":260.7,"p_p05":93350.7,"p_p95":94198.7,"p_min":93005.2,"p_max":94418.6,"t_mean":294.58,"t_p05":284.32,"t_p95":306.62,"rho_mean":1.11038,"rho_p05":1.06561,"rho_p95":1.15068,"lw_n":265,"lw_t_mean":299.93,"lw_rho_mean":1.09035},{"month":6,"n":705,"p_mean":93784.0,"p_sd":193.4,"p_p05":93476.3,"p_p95":94135.9,"p_min":93319.3,"p_max":94293.0,"t_mean":300.15,"t_p05":290.34,"t_p95":310.82,"rho_mean":1.08901,"rho_p05":1.05123,"rho_p95":1.125,"lw_n":264,"lw_t_mean":305.95,"lw_rho_mean":1.06796},{"month":7,"n":732,"p_mean":94019.7,"p_sd":204.6,"p_p05":93696.2,"p_p95":94355.8,"p_min":93413.5,"p_max":94512.8,"t_mean":301.84,"t_p05":291.92,"t_p95":311.82,"rho_mean":1.08565,"rho_p05":1.04902,"rho_p95":1.12334,"lw_n":278,"lw_t_mean":307.43,"lw_rho_mean":1.06577},{"month":8,"n":689,"p_mean":94078.0,"p_sd":202.1,"p_p05":93759.0,"p_p95":94437.4,"p_min":93570.5,"p_max":94544.2,"t_mean":302.92,"t_p05":293.42,"t_p95":313.22,"rho_mean":1.08243,"rho_p05":1.04396,"rho_p95":1.1188,"lw_n":257,"lw_t_mean":308.35,"lw_rho_mean":1.0632},{"month":9,"n":578,"p_mean":93990.2,"p_sd":217.5,"p_p05":93664.8,"p_p95":94387.2,"p_min":93476.3,"p_max":94638.5,"t_mean":298.34,"t_p05":289.92,"t_p95":308.32,"rho_mean":1.09792,"rho_p05":1.06142,"rho_p95":1.12988,"lw_n":215,"lw_t_mean":302.56,"lw_rho_mean":1.08268},{"month":10,"n":667,"p_mean":94098.8,"p_sd":324.5,"p_p05":93539.1,"p_p95":94607.1,"p_min":93193.6,"p_max":94921.2,"t_mean":290.83,"t_p05":281.15,"t_p95":302.19,"rho_mean":1.12773,"rho_p05":1.0834,"rho_p95":1.16797,"lw_n":229,"lw_t_mean":295.41,"lw_rho_mean":1.11031},{"month":11,"n":638,"p_mean":94348.7,"p_sd":335.6,"p_p05":93790.4,"p_p95":94894.5,"p_min":93507.7,"p_max":95203.9,"t_mean":286.31,"t_p05":277.02,"t_p95":298.42,"rho_mean":1.14859,"rho_p05":1.10069,"rho_p95":1.18825,"lw_n":240,"lw_t_mean":289.93,"lw_rho_mean":1.13451},{"month":12,"n":714,"p_mean":94535.4,"p_sd":347.2,"p_p05":93978.9,"p_p95":95109.6,"p_min":93633.4,"p_max":95392.3,"t_mean":282.75,"t_p05":274.42,"t_p95":292.65,"rho_mean":1.16521,"rho_p05":1.12249,"rho_p95":1.20356,"lw_n":249,"lw_t_mean":286.35,"lw_rho_mean":1.15095}],"KMHV":[{"month":1,"n":360,"p_mean":94839.8,"p_sd":458.5,"p_p05":93912.9,"p_p95":95392.3,"p_min":93664.8,"p_max":95580.8,"t_mean":283.36,"t_p05":275.67,"t_p95":293.08,"rho_mean":1.16643,"rho_p05":1.12636,"rho_p95":1.20251,"lw_n":128,"lw_t_mean":288.12,"lw_rho_mean":1.14749},{"month":2,"n":635,"p_mean":94558.5,"p_sd":488.5,"p_p05":93570.5,"p_p95":95266.7,"p_min":93225.0,"p_max":95423.7,"t_mean":285.46,"t_p05":276.87,"t_p95":295.67,"rho_mean":1.15446,"rho_p05":1.11591,"rho_p95":1.19311,"lw_n":224,"lw_t_mean":289.21,"lw_rho_mean":1.13993},{"month":3,"n":744,"p_mean":94373.1,"p_sd":306.3,"p_p05":93983.6,"p_p95":94921.2,"p_min":93759.0,"p_max":95392.3,"t_mean":293.3,"t_p05":282.59,"t_p95":304.57,"rho_mean":1.12152,"rho_p05":1.0778,"rho_p95":1.16583,"lw_n":279,"lw_t_mean":297.85,"lw_rho_mean":1.10474},{"month":4,"n":717,"p_mean":94154.0,"p_sd":273.6,"p_p05":93696.2,"p_p95":94638.5,"p_min":93507.7,"p_max":94921.2,"t_mean":290.05,"t_p05":282.25,"t_p95":299.57,"rho_mean":1.13125,"rho_p05":1.09425,"rho_p95":1.163,"lw_n":270,"lw_t_mean":294.09,"lw_rho_mean":1.11593},{"month":5,"n":704,"p_mean":93991.6,"p_sd":243.4,"p_p05":93539.1,"p_p95":94355.8,"p_min":93287.8,"p_max":94544.2,"t_mean":295.87,"t_p05":285.39,"t_p95":305.97,"rho_mean":1.10717,"rho_p05":1.0691,"rho_p95":1.14652,"lw_n":270,"lw_t_mean":299.87,"lw_rho_mean":1.09264},{"month":6,"n":704,"p_mean":93923.4,"p_sd":198.9,"p_p05":93601.9,"p_p95":94261.6,"p_min":93413.5,"p_max":94450.0,"t_mean":301.66,"t_p05":293.59,"t_p95":310.57,"rho_mean":1.08498,"rho_p05":1.05356,"rho_p95":1.1136,"lw_n":266,"lw_t_mean":305.81,"lw_rho_mean":1.0704},{"month":7,"n":744,"p_mean":94170.8,"p_sd":202.0,"p_p05":93853.2,"p_p95":94512.8,"p_min":93696.2,"p_max":94701.3,"t_mean":303.01,"t_p05":294.57,"t_p95":310.57,"rho_mean":1.08297,"rho_p05":1.0538,"rho_p95":1.11283,"lw_n":279,"lw_t_mean":306.39,"lw_rho_mean":1.0716},{"month":8,"n":731,"p_mean":94255.5,"p_sd":195.8,"p_p05":93947.5,"p_p95":94575.7,"p_min":93759.0,"p_max":94701.3,"t_mean":304.0,"t_p05":295.57,"t_p95":312.57,"rho_mean":1.08043,"rho_p05":1.04951,"rho_p95":1.11098,"lw_n":278,"lw_t_mean":307.28,"lw_rho_mean":1.06934},{"month":9,"n":710,"p_mean":94156.2,"p_sd":205.1,"p_p05":93853.2,"p_p95":94544.2,"p_min":93696.2,"p_max":94701.3,"t_mean":299.22,"t_p05":291.57,"t_p95":307.57,"rho_mean":1.09653,"rho_p05":1.06578,"rho_p95":1.12567,"lw_n":266,"lw_t_mean":301.99,"lw_rho_mean":1.087},{"month":10,"n":136,"p_mean":94107.5,"p_sd":195.3,"p_p05":93759.0,"p_p95":94387.2,"p_min":93664.8,"p_max":94418.6,"t_mean":293.49,"t_p05":287.57,"t_p95":301.57,"rho_mean":1.11727,"rho_p05":1.08815,"rho_p95":1.14008,"lw_n":46,"lw_t_mean":296.49,"lw_rho_mean":1.10655}],"KNID":[{"month":1,"n":726,"p_mean":94849.1,"p_sd":541.0,"p_p05":93947.5,"p_p95":95698.6,"p_min":93664.8,"p_max":96209.0,"t_mean":281.27,"t_p05":272.98,"t_p95":291.88,"rho_mean":1.17527,"rho_p05":1.13068,"rho_p95":1.21874,"lw_n":269,"lw_t_mean":285.46,"lw_rho_mean":1.15803},{"month":2,"n":667,"p_mean":94527.6,"p_sd":548.4,"p_p05":93485.7,"p_p95":95329.5,"p_min":93068.0,"p_max":95486.5,"t_mean":284.33,"t_p05":274.86,"t_p95":295.78,"rho_mean":1.1588,"rho_p05":1.11283,"rho_p95":1.20353,"lw_n":250,"lw_t_mean":288.36,"lw_rho_mean":1.14291},{"month":3,"n":729,"p_mean":94301.3,"p_sd":358.4,"p_p05":93821.8,"p_p95":94889.8,"p_min":93633.4,"p_max":95423.7,"t_mean":292.68,"t_p05":280.78,"t_p95":305.78,"rho_mean":1.12322,"rho_p05":1.07122,"rho_p95":1.17306,"lw_n":274,"lw_t_mean":297.86,"lw_rho_mean":1.10377},{"month":4,"n":621,"p_mean":94029.6,"p_sd":356.0,"p_p05":93413.5,"p_p95":94669.9,"p_min":93193.6,"p_max":94952.6,"t_mean":290.79,"t_p05":280.28,"t_p95":301.38,"rho_mean":1.12701,"rho_p05":1.08486,"rho_p95":1.17169,"lw_n":248,"lw_t_mean":295.31,"lw_rho_mean":1.10991},{"month":5,"n":649,"p_mean":93804.3,"p_sd":346.5,"p_p05":93130.8,"p_p95":94280.4,"p_min":92534.0,"p_max":94575.7,"t_mean":296.46,"t_p05":285.78,"t_p95":307.98,"rho_mean":1.10293,"rho_p05":1.05936,"rho_p95":1.14611,"lw_n":253,"lw_t_mean":301.19,"lw_rho_mean":1.08558},{"month":6,"n":623,"p_mean":93708.3,"p_sd":255.2,"p_p05":93287.8,"p_p95":94135.9,"p_min":93068.0,"p_max":94355.8,"t_mean":302.85,"t_p05":291.88,"t_p95":312.48,"rho_mean":1.07841,"rho_p05":1.04343,"rho_p95":1.11792,"lw_n":243,"lw_t_mean":307.3,"lw_rho_mean":1.06303},{"month":7,"n":730,"p_mean":94034.7,"p_sd":228.9,"p_p05":93664.8,"p_p95":94418.6,"p_min":93476.3,"p_max":94638.5,"t_mean":304.97,"t_p05":294.68,"t_p95":315.28,"rho_mean":1.07462,"rho_p05":1.03773,"rho_p95":1.11361,"lw_n":239,"lw_t_mean":309.06,"lw_rho_mean":1.06084},{"month":8,"n":739,"p_mean":94155.6,"p_sd":236.7,"p_p05":93790.4,"p_p95":94544.2,"p_min":93507.7,"p_max":94732.7,"t_mean":304.97,"t_p05":294.68,"t_p95":315.28,"rho_mean":1.07606,"rho_p05":1.03687,"rho_p95":1.11539,"lw_n":277,"lw_t_mean":309.63,"lw_rho_mean":1.06006},{"month":9,"n":679,"p_mean":94102.3,"p_sd":236.5,"p_p05":93693.0,"p_p95":94512.8,"p_min":93539.1,"p_max":94701.3,"t_mean":300.68,"t_p05":291.88,"t_p95":310.28,"rho_mean":1.09067,"rho_p05":1.0562,"rho_p95":1.12349,"lw_n":261,"lw_t_mean":304.48,"lw_rho_mean":1.07725},{"month":10,"n":711,"p_mean":94239.1,"p_sd":373.5,"p_p05":93554.8,"p_p95":94826.9,"p_min":93068.0,"p_max":95141.0,"t_mean":292.34,"t_p05":282.98,"t_p95":302.48,"rho_mean":1.12352,"rho_p05":1.08375,"rho_p95":1.16326,"lw_n":264,"lw_t_mean":297.11,"lw_rho_mean":1.10556},{"month":11,"n":718,"p_mean":94537.4,"p_sd":341.1,"p_p05":93947.5,"p_p95":95141.0,"p_min":93696.2,"p_max":95360.9,"t_mean":287.12,"t_p05":278.58,"t_p95":299.68,"rho_mean":1.1476,"rho_p05":1.09905,"rho_p95":1.18608,"lw_n":270,"lw_t_mean":290.95,"lw_rho_mean":1.13252},{"month":12,"n":739,"p_mean":94635.7,"p_sd":382.3,"p_p05":94038.5,"p_p95":95266.7,"p_min":93727.6,"p_max":95549.4,"t_mean":282.55,"t_p05":274.68,"t_p95":292.48,"rho_mean":1.16736,"rho_p05":1.12313,"rho_p95":1.20505,"lw_n":279,"lw_t_mean":286.5,"lw_rho_mean":1.15124}]}},"upper":{"grid_m":[629.9375687781601,879.9375687781601,1129.93756877816,1379.93756877816,1629.93756877816,1879.93756877816,2129.9375687781603,2379.9375687781603,2629.9375687781603,2879.9375687781603,3129.9375687781603,3379.9375687781603,3629.9375687781603,3879.9375687781603,4129.93756877816,4379.93756877816,4629.93756877816,4879.93756877816,5129.93756877816,5379.93756877816,5629.93756877816,5879.93756877816,6129.93756877816,6379.93756877816,6629.93756877816,6879.93756877816,7129.93756877816,7379.93756877816,7629.93756877816,7879.93756877816,8129.93756877816,8379.93756877816],"datasets":[{"id":"edw-nid","label":"Edwards + China Lake","stations":["EDW","NID"],"pooled":true,"n":1331},{"id":"edw","label":"Edwards AFB","stations":["EDW"],"pooled":false,"n":915},{"id":"nid","label":"China Lake NAF","stations":["NID"],"pooled":false,"n":416},{"id":"vef","label":"Las Vegas","stations":["VEF"],"pooled":false,"n":7263}],"profile":{"edw-nid":[{"month":1,"n":72,"mean":[278.31,281.99,281.81,280.62,279.62,278.58,277.68,276.74,275.83,274.78,273.59,272.28,270.91,269.37,267.85,266.2,264.46,262.79,261.05,259.29,257.51,255.64,253.83,251.92,250.0,248.12,246.36,244.63,242.79,240.98,239.09,237.2],"sd":[11.08,3.49,3.55,3.7,4.03,4.4,4.72,4.88,5.1,5.19,5.06,4.94,4.92,4.89,4.87,4.88,4.97,5.08,5.12,5.16,5.23,5.31,5.35,5.4,5.4,5.35,5.31,4.94,4.6,4.36,4.13,3.95],"p05":[257.53,276.39,276.01,274.5,272.78,270.8,268.91,267.19,265.95,265.07,264.01,262.44,261.12,259.7,259.34,257.6,255.55,253.56,251.73,250.14,248.29,245.99,243.91,242.07,240.16,239.0,238.39,236.54,235.0,233.23,232.81,231.49],"p50":[280.37,281.86,281.67,280.68,279.97,279.2,278.49,277.74,276.94,276.62,275.17,273.39,272.21,270.5,268.65,267.01,265.18,263.49,261.56,259.71,257.8,255.81,254.06,252.11,250.36,248.67,246.82,245.15,243.02,241.2,239.0,236.93],"p95":[293.58,287.19,287.77,286.81,285.63,284.88,283.99,283.05,282.54,281.38,279.98,278.43,276.7,275.55,273.96,272.43,270.44,268.89,267.05,265.51,263.6,261.98,260.52,258.87,256.74,254.7,253.0,251.45,249.37,247.32,245.18,243.05],"eq7_err":[0.0,-5.16,-6.47,-6.77,-7.25,-7.7,-8.29,-8.84,-9.41,-9.85,-10.14,-10.32,-10.43,-10.39,-10.35,-10.19,-9.93,-9.75,-9.5,-9.22,-8.93,-8.54,-8.22,-7.8,-7.37,-6.97,-6.7,-6.46,-6.1,-5.78,-5.38,-4.97]},{"month":2,"n":110,"mean":[281.83,283.23,282.2,280.83,279.37,277.87,276.3,274.87,273.61,272.44,271.19,269.95,268.67,267.21,265.66,264.08,262.45,260.85,259.24,257.57,255.86,254.01,252.18,250.34,248.45,246.54,244.64,242.76,240.83,238.94,237.1,235.25],"sd":[11.8,5.28,5.24,5.4,5.51,5.55,5.67,5.64,5.58,5.47,5.47,5.42,5.43,5.4,5.39,5.4,5.38,5.33,5.28,5.12,5.16,5.19,5.17,5.01,4.91,4.87,4.79,4.77,4.74,4.69,4.62,4.56],"p05":[259.1,274.32,273.18,271.78,270.27,268.38,266.24,264.44,262.92,261.5,260.75,260.3,258.87,257.61,255.7,254.16,252.26,251.21,250.38,249.67,247.61,245.43,243.32,241.92,240.62,239.02,237.52,235.83,233.88,231.79,229.84,228.21],"p50":[283.3,283.81,282.99,281.86,280.43,278.81,277.32,275.94,274.54,273.04,271.52,270.21,268.87,267.43,265.71,263.95,262.33,260.61,259.03,257.56,256.05,254.14,252.39,250.33,248.32,246.25,244.33,242.56,240.51,238.47,236.3,234.63],"p95":[296.9,290.74,289.77,288.82,287.73,286.11,284.72,283.05,281.73,280.43,279.19,278.04,277.41,275.86,274.41,272.84,271.15,269.25,267.34,265.9,264.42,262.62,260.78,259.12,257.06,254.99,252.9,251.04,249.23,247.55,245.96,243.93],"eq7_err":[0.0,-2.97,-3.51,-3.71,-3.82,-3.9,-3.89,-4.03,-4.35,-4.75,-5.07,-5.4,-5.7,-5.8,-5.83,-5.82,-5.76,-5.73,-5.7,-5.59,-5.45,-5.18,-4.91,-4.65,-4.33,-3.99,-3.67,-3.35,-3.0,-2.68,-2.41,-2.13]},{"month":3,"n":183,"mean":[286.28,285.75,284.46,282.73,281.0,279.2,277.59,276.2,275.01,273.71,272.42,271.07,269.67,268.2,266.64,265.01,263.29,261.59,259.84,258.07,256.32,254.52,252.7,250.89,249.05,247.19,245.33,243.43,241.5,239.63,237.7,235.84],"sd":[10.81,5.46,5.57,5.73,5.83,5.87,5.87,5.89,5.88,5.88,5.82,5.74,5.72,5.71,5.71,5.69,5.72,5.73,5.77,5.78,5.79,5.82,5.81,5.73,5.64,5.57,5.37,5.17,5.04,4.85,4.71,4.52],"p05":[267.56,278.16,276.78,274.71,272.84,270.87,268.88,267.35,265.92,264.13,262.07,261.17,259.57,257.56,255.75,254.43,253.48,251.3,248.98,246.6,245.02,243.06,241.14,240.61,238.42,236.95,235.43,234.27,233.11,231.73,230.08,228.88],"p50":[286.57,285.08,284.31,282.06,280.25,278.24,277.41,275.97,275.39,274.16,272.69,271.43,269.97,268.52,267.12,265.47,264.02,262.33,260.54,258.78,256.93,255.33,253.42,251.64,249.74,247.86,245.9,243.7,241.64,239.52,237.42,235.45],"p95":[303.55,296.33,295.58,293.96,292.66,291.53,290.23,289.13,287.87,285.99,284.1,282.45,281.01,279.45,277.51,275.76,273.84,272.49,270.67,268.83,267.02,265.16,262.99,261.08,259.53,257.51,255.75,253.99,252.13,250.14,247.96,245.8],"eq7_err":[0.0,-1.15,-1.53,-1.48,-1.43,-1.31,-1.38,-1.67,-2.15,-2.53,-2.92,-3.25,-3.53,-3.74,-3.86,-3.91,-3.87,-3.84,-3.77,-3.68,-3.61,-3.49,-3.34,-3.22,-3.06,-2.87,-2.69,-2.48,-2.22,-2.03,-1.78,-1.6]},{"month":4,"n":125,"mean":[290.47,289.61,288.29,286.77,285.17,283.53,281.87,280.19,278.67,277.19,275.69,274.21,272.69,271.17,269.66,268.06,266.36,264.66,262.86,261.1,259.31,257.44,255.56,253.76,251.94,250.11,248.26,246.39,244.46,242.52,240.58,238.63],"sd":[13.77,5.41,5.2,5.18,5.11,5.14,5.19,5.23,5.34,5.41,5.32,5.09,5.05,4.91,4.91,4.95,4.99,5.01,5.02,5.02,5.0,5.02,4.99,4.89,4.72,4.59,4.51,4.4,4.34,4.27,4.2,4.08],"p05":[270.69,281.44,279.87,277.85,275.87,274.2,271.96,269.84,267.71,265.91,264.86,262.98,260.87,259.85,258.64,257.09,254.99,253.11,250.82,248.58,246.85,245.31,243.62,242.55,241.44,239.56,237.7,235.89,234.62,233.35,231.54,230.07],"p50":[291.5,289.18,288.64,287.39,285.79,284.46,282.9,280.83,279.78,278.27,276.44,274.98,273.87,272.55,270.9,269.19,267.58,265.74,263.93,262.1,260.41,258.57,256.95,255.1,253.2,251.24,249.2,247.22,245.35,243.41,241.38,239.13],"p95":[308.29,298.47,296.32,294.65,292.36,290.42,288.54,286.57,285.29,283.57,282.13,280.46,278.69,276.74,274.96,273.19,271.69,269.95,268.8,267.06,265.23,263.35,261.49,259.44,257.33,255.44,253.79,251.94,250.24,248.07,246.02,243.87],"eq7_err":[0.0,-0.91,-1.38,-1.64,-1.81,-1.95,-2.07,-2.18,-2.44,-2.74,-3.01,-3.31,-3.57,-3.84,-4.1,-4.28,-4.36,-4.44,-4.42,-4.44,-4.43,-4.34,-4.24,-4.22,-4.18,-4.13,-4.06,-3.97,-3.82,-3.66,-3.5,-3.33]},{"month":5,"n":92,"mean":[296.29,293.61,292.13,290.52,288.77,287.02,285.11,283.22,281.34,279.5,277.69,275.95,274.4,272.89,271.3,269.7,268.09,266.52,264.94,263.27,261.52,259.76,257.92,256.08,254.21,252.34,250.42,248.48,246.56,244.67,242.77,240.87],"sd":[11.58,5.59,5.22,4.94,4.79,4.67,4.63,4.61,4.53,4.43,4.31,4.25,4.22,4.18,4.09,4.11,4.11,4.16,4.12,4.06,4.04,4.05,4.06,4.05,4.02,4.0,4.02,4.03,3.94,3.84,3.69,3.51],"p05":[279.76,285.59,283.8,282.33,280.17,277.93,275.75,273.63,271.38,269.87,267.89,265.86,265.1,263.9,262.11,260.42,259.1,257.18,255.08,253.71,252.08,250.36,248.53,246.56,244.55,242.47,240.24,237.89,236.04,234.64,233.77,233.26],"p50":[298.88,293.14,292.28,291.48,290.06,288.25,286.01,284.2,282.35,280.73,278.88,277.24,275.69,274.05,272.22,270.59,269.07,267.37,265.74,263.94,262.33,260.6,258.7,256.82,254.82,252.78,250.88,249.03,247.08,245.19,243.19,241.25],"p95":[310.14,301.78,299.39,297.34,295.3,293.42,291.67,289.41,287.31,285.48,283.38,281.11,279.82,277.88,276.05,274.38,272.79,271.51,269.94,268.44,267.07,265.33,263.49,261.7,259.76,257.74,255.88,253.83,251.81,249.84,247.66,245.48],"eq7_err":[0.0,0.76,0.33,0.01,-0.15,-0.33,-0.34,-0.37,-0.41,-0.48,-0.59,-0.77,-1.15,-1.55,-1.88,-2.2,-2.52,-2.87,-3.21,-3.45,-3.63,-3.79,-3.87,-3.95,-4.0,-4.05,-4.05,-4.03,-4.03,-4.05,-4.08,-4.09]},{"month":6,"n":86,"mean":[300.83,298.97,297.82,296.32,294.91,293.24,291.46,289.65,287.83,286.02,284.28,282.57,280.99,279.46,277.79,276.05,274.24,272.46,270.68,268.91,267.15,265.38,263.54,261.8,260.02,258.24,256.44,254.53,252.68,250.72,248.79,246.81],"sd":[12.65,6.14,5.54,5.19,4.82,4.66,4.46,4.27,4.19,4.03,3.85,3.7,3.57,3.48,3.47,3.42,3.4,3.35,3.32,3.34,3.35,3.36,3.36,3.33,3.23,3.19,3.18,3.21,3.28,3.34,3.42,3.48],"p05":[282.66,288.2,288.22,286.92,286.23,285.05,283.43,282.06,280.22,278.24,276.99,276.79,275.7,274.31,271.99,269.77,267.97,266.44,264.78,263.18,261.58,259.71,257.66,255.66,253.71,251.75,249.93,247.87,245.63,243.5,241.78,239.83],"p50":[301.8,300.3,298.7,297.25,295.85,294.28,292.42,290.61,288.26,286.27,284.66,283.09,281.57,280.04,278.61,276.7,274.95,273.26,271.47,269.78,267.99,266.03,264.17,262.8,260.91,258.78,257.08,255.09,253.18,251.19,249.4,247.72],"p95":[318.18,307.38,305.31,303.42,301.74,300.16,298.1,295.79,293.71,291.59,289.5,287.61,285.65,283.86,282.14,280.08,278.19,276.69,274.9,273.18,271.2,269.64,267.79,265.89,263.79,261.89,260.13,258.43,256.46,254.44,252.7,250.69],"eq7_err":[0.0,-0.16,-1.04,-1.58,-2.2,-2.55,-2.8,-3.02,-3.24,-3.45,-3.74,-4.06,-4.51,-5.01,-5.37,-5.66,-5.88,-6.13,-6.38,-6.63,-6.91,-7.17,-7.36,-7.65,-7.9,-8.14,-8.38,-8.5,-8.68,-8.75,-8.84,-8.89]},{"month":7,"n":118,"mean":[305.29,302.44,301.18,299.75,298.22,296.61,294.84,293.01,291.15,289.3,287.38,285.48,283.52,281.63,279.76,277.96,276.19,274.4,272.66,270.94,269.27,267.62,265.93,264.17,262.43,260.65,258.82,257.03,255.25,253.39,251.55,249.75],"sd":[12.81,4.1,3.66,3.44,3.31,3.09,2.92,2.74,2.42,2.19,2.07,1.98,1.91,1.9,1.86,1.77,1.68,1.64,1.65,1.65,1.73,1.77,1.81,1.87,1.91,1.93,1.95,2.0,2.12,2.2,2.16,2.16],"p05":[285.15,296.45,295.32,293.86,291.89,290.42,288.81,287.74,287.14,285.88,284.25,282.64,280.47,278.51,276.68,275.62,273.91,272.26,270.25,268.64,266.69,264.75,262.7,260.79,259.01,257.16,255.5,253.79,251.73,249.96,248.34,246.52],"p50":[306.01,301.98,301.17,299.9,298.52,297.09,295.1,293.19,291.26,289.23,287.26,285.38,283.5,281.5,279.59,277.81,276.07,274.28,272.52,270.82,269.21,267.5,265.87,264.15,262.39,260.68,258.89,257.17,255.21,253.61,251.62,250.03],"p95":[322.89,309.75,307.45,305.6,303.88,302.04,300.16,297.94,295.67,293.4,291.11,288.75,286.52,284.49,282.54,280.5,278.56,277.3,275.56,273.77,272.23,270.61,268.92,267.08,265.51,263.56,261.84,260.17,258.6,256.58,254.64,252.67],"eq7_err":[0.0,0.71,-0.17,-0.88,-1.48,-2.0,-2.37,-2.68,-2.96,-3.25,-3.46,-3.7,-3.88,-4.13,-4.39,-4.73,-5.09,-5.44,-5.84,-6.26,-6.72,-7.21,-7.66,-8.03,-8.43,-8.78,-9.09,-9.44,-9.8,-10.07,-10.37,-10.71]},{"month":8,"n":114,"mean":[301.69,301.33,300.63,299.32,297.66,295.95,294.17,292.27,290.34,288.39,286.45,284.57,282.64,280.73,278.85,276.98,275.24,273.46,271.73,270.15,268.6,267.07,265.45,263.77,262.05,260.29,258.61,256.9,255.14,253.32,251.5,249.66],"sd":[11.62,4.35,3.58,3.2,2.97,2.77,2.58,2.43,2.35,2.26,2.17,2.13,2.11,1.99,1.84,1.78,1.74,1.73,1.71,1.67,1.71,1.82,1.92,1.92,1.91,1.93,1.82,1.8,1.75,1.75,1.78,1.82],"p05":[284.59,294.72,295.35,294.91,293.82,292.2,290.79,288.69,286.59,284.57,282.41,280.56,278.85,277.42,275.73,273.92,272.31,270.61,269.27,267.87,266.0,264.3,262.35,260.73,259.07,257.23,255.43,253.62,252.1,250.0,248.14,246.11],"p50":[300.68,301.07,300.73,299.23,297.65,295.88,294.22,292.25,290.27,288.59,286.65,284.76,282.86,280.83,278.88,276.98,275.36,273.45,271.69,270.08,268.47,266.95,265.38,263.7,262.15,260.33,258.63,256.95,255.24,253.45,251.6,249.75],"p95":[320.52,307.94,306.38,304.6,302.35,300.5,298.66,296.45,294.15,292.15,290.01,287.98,285.97,283.86,281.75,279.76,278.11,276.69,274.98,273.4,271.98,270.64,269.12,267.35,265.56,263.57,261.67,259.85,257.89,255.77,254.0,252.11],"eq7_err":[0.0,-1.69,-3.05,-3.78,-4.18,-4.51,-4.78,-4.94,-5.06,-5.16,-5.26,-5.43,-5.55,-5.69,-5.87,-6.05,-6.35,-6.63,-6.94,-7.41,-7.91,-8.44,-8.86,-9.24,-9.56,-9.85,-10.22,-10.57,-10.86,-11.09,-11.32,-11.52]},{"month":9,"n":131,"mean":[297.69,296.16,295.37,293.97,292.52,290.85,289.16,287.47,285.78,284.09,282.43,280.83,279.27,277.78,276.34,274.81,273.26,271.76,270.17,268.58,266.93,265.24,263.51,261.72,259.98,258.22,256.37,254.49,252.62,250.72,248.82,246.89],"sd":[12.21,5.14,4.75,4.55,4.23,4.08,3.86,3.5,3.28,3.13,3.05,3.05,3.01,2.92,2.86,2.92,2.85,2.79,2.77,2.71,2.67,2.66,2.66,2.69,2.59,2.52,2.48,2.44,2.39,2.31,2.25,2.22],"p05":[278.29,287.47,287.05,286.03,285.88,284.39,282.82,281.83,279.88,277.88,276.26,274.81,273.01,271.77,270.74,269.12,267.79,266.47,265.16,264.04,262.62,260.74,258.7,257.0,255.75,254.06,252.04,250.21,248.6,246.95,245.1,243.16],"p50":[297.87,296.48,296.04,294.39,293.09,291.6,290.06,288.31,286.56,284.54,282.95,281.22,279.68,278.37,276.89,275.54,273.81,272.31,270.55,268.9,267.62,265.65,263.87,262.17,260.43,258.57,256.65,254.87,252.89,250.84,249.05,247.1],"p95":[316.12,304.74,302.63,300.43,298.17,296.12,294.18,292.03,290.24,288.34,286.67,285.17,283.19,281.97,280.42,278.73,276.89,275.57,273.8,272.09,270.32,268.52,266.81,264.9,263.31,261.53,259.57,257.76,255.99,253.9,251.81,249.83],"eq7_err":[0.0,-0.42,-1.59,-2.13,-2.64,-2.92,-3.19,-3.45,-3.71,-3.98,-4.28,-4.63,-5.02,-5.49,-6.0,-6.42,-6.83,-7.28,-7.64,-8.01,-8.32,-8.58,-8.8,-8.96,-9.18,-9.37,-9.48,-9.54,-9.63,-9.69,-9.74,-9.76]},{"month":10,"n":109,"mean":[289.84,291.92,291.33,289.95,288.45,286.79,285.25,283.73,282.53,281.37,280.2,278.92,277.41,275.88,274.39,272.77,271.18,269.59,267.98,266.36,264.64,262.8,260.98,259.12,257.29,255.48,253.63,251.69,249.69,247.7,245.72,243.77],"sd":[12.55,5.55,5.11,4.99,4.89,4.86,4.64,4.42,4.01,3.72,3.67,3.66,3.57,3.41,3.34,3.24,3.21,3.16,3.11,3.08,3.08,3.13,3.09,3.07,3.11,3.1,3.15,3.17,3.18,3.16,3.13,3.0],"p05":[268.46,282.54,282.3,280.44,278.52,276.81,275.77,274.74,275.41,275.83,273.86,272.13,270.81,270.09,268.67,267.46,265.4,263.97,262.37,260.51,258.47,256.44,254.88,253.22,251.32,249.79,248.25,246.12,244.13,242.39,240.55,238.65],"p50":[291.43,291.36,291.23,290.31,288.68,286.9,285.78,284.28,282.86,281.34,280.68,279.32,277.63,276.1,274.8,273.22,271.99,270.05,268.49,266.84,265.14,263.5,261.59,259.57,257.72,256.21,254.41,252.49,250.32,248.25,246.32,244.23],"p95":[307.48,302.16,300.21,297.8,296.18,294.03,292.07,290.25,288.58,287.26,285.77,284.05,282.6,280.72,279.08,277.3,275.41,273.81,272.41,270.65,269.0,267.1,265.47,263.51,261.69,259.92,258.06,256.06,254.14,252.03,250.14,248.08],"eq7_err":[0.0,-3.84,-5.02,-5.4,-5.66,-5.77,-5.99,-6.24,-6.8,-7.41,-8.0,-8.48,-8.74,-8.97,-9.25,-9.4,-9.57,-9.75,-9.9,-10.04,-10.09,-10.01,-9.95,-9.87,-9.8,-9.75,-9.66,-9.49,-9.25,-9.03,-8.81,-8.62]},{"month":11,"n":103,"mean":[281.73,285.98,285.87,284.81,283.66,282.43,281.27,280.16,279.11,278.27,277.17,275.82,274.31,272.78,271.29,269.63,267.98,266.32,264.59,262.9,261.22,259.54,257.69,255.85,254.07,252.25,250.35,248.43,246.47,244.5,242.54,240.58],"sd":[13.36,4.0,3.87,4.12,4.25,4.36,4.38,4.43,4.22,3.73,3.3,3.13,3.1,3.1,3.17,3.17,3.08,3.06,3.09,3.07,3.12,3.22,3.22,3.17,3.11,3.18,3.26,3.29,3.29,3.25,3.2,3.2],"p05":[256.28,279.38,279.56,278.3,276.47,274.57,273.6,272.02,271.13,271.05,270.28,269.57,268.11,267.16,265.95,264.23,262.81,260.46,258.53,256.74,254.64,253.08,251.41,250.55,249.56,247.44,245.14,242.84,240.56,238.6,236.73,234.89],"p50":[283.92,285.92,285.81,285.01,284.08,283.46,282.38,281.12,280.06,278.83,277.34,275.98,274.52,272.95,271.57,270.03,268.47,266.7,264.83,263.41,261.78,260.29,258.39,256.44,254.77,253.13,251.18,249.25,247.34,245.49,243.42,241.27],"p95":[300.6,293.54,292.36,290.81,289.55,288.4,287.32,286.07,285.08,283.39,281.71,279.92,278.79,277.04,276.16,274.72,272.82,270.88,268.92,267.24,265.81,264.32,262.48,260.45,258.45,256.59,254.68,252.76,250.75,248.63,246.58,244.8],"eq7_err":[0.0,-5.82,-7.28,-7.79,-8.2,-8.54,-8.95,-9.41,-9.93,-10.66,-11.13,-11.35,-11.4,-11.44,-11.52,-11.43,-11.36,-11.26,-11.1,-10.98,-10.87,-10.76,-10.48,-10.2,-10.0,-9.74,-9.41,-9.06,-8.67,-8.27,-7.88,-7.49]},{"month":12,"n":88,"mean":[282.82,283.53,283.07,281.79,280.42,279.18,278.1,277.21,276.31,275.37,274.25,272.88,271.4,269.96,268.54,267.07,265.52,263.9,262.29,260.56,258.82,257.04,255.27,253.56,251.73,249.87,248.02,246.1,244.1,242.11,240.15,238.19],"sd":[10.82,3.86,3.82,4.1,4.4,4.52,4.51,4.11,3.83,3.51,3.57,3.66,3.71,3.78,3.69,3.62,3.57,3.53,3.48,3.43,3.48,3.55,3.57,3.4,3.38,3.44,3.49,3.53,3.57,3.61,3.64,3.66],"p05":[259.75,278.01,277.73,276.02,274.11,272.48,270.93,270.25,269.43,269.53,267.79,266.25,264.71,263.3,262.0,260.87,259.3,257.92,256.18,254.94,253.22,251.08,249.04,247.31,245.26,243.47,241.56,239.84,238.21,236.15,234.19,232.55],"p50":[285.08,283.28,283.31,281.42,279.8,278.64,278.34,277.32,276.62,275.97,274.51,273.27,271.65,270.2,269.17,267.3,265.54,264.11,262.35,260.64,258.91,256.97,255.53,253.86,252.14,250.06,248.05,246.0,243.89,241.93,239.99,238.04],"p95":[296.43,289.77,288.58,287.54,287.23,286.24,284.95,283.38,281.74,280.4,279.41,278.69,277.36,275.66,273.92,272.07,270.39,268.85,267.11,265.43,264.0,262.52,260.94,259.0,257.04,255.21,253.29,251.35,249.5,247.48,245.53,243.63],"eq7_err":[0.0,-2.31,-3.44,-3.76,-3.98,-4.34,-4.85,-5.56,-6.25,-6.91,-7.39,-7.61,-7.72,-7.88,-8.06,-8.18,-8.22,-8.2,-8.18,-8.05,-7.91,-7.73,-7.55,-7.43,-7.19,-6.93,-6.67,-6.35,-5.95,-5.55,-5.19,-4.82]}],"edw":[{"month":1,"n":48,"mean":[279.0,281.81,281.83,280.74,279.91,279.12,278.45,277.5,276.62,275.62,274.4,272.99,271.54,270.0,268.57,266.97,265.22,263.58,261.87,260.19,258.45,256.55,254.7,252.78,250.87,248.99,247.18,245.42,243.53,241.73,239.85,237.93],"sd":[11.52,3.55,3.33,3.4,3.67,4.04,4.42,4.56,4.81,4.88,4.83,4.73,4.69,4.6,4.54,4.53,4.64,4.74,4.73,4.72,4.76,4.86,4.91,4.91,4.85,4.72,4.56,4.39,4.18,3.99,3.78,3.63],"p05":[259.34,276.33,275.96,274.75,272.92,271.22,269.78,269.01,267.26,265.55,264.83,263.91,262.72,261.44,260.14,258.19,256.11,254.43,252.31,250.4,248.4,246.2,244.1,242.68,240.79,239.79,238.72,236.95,235.3,234.15,233.18,232.12],"p50":[280.83,281.69,281.67,280.82,280.33,279.65,279.06,278.19,277.69,276.9,275.71,274.21,272.77,271.26,269.57,267.83,266.62,265.06,263.6,261.77,259.67,257.63,255.75,253.94,252.05,249.99,247.94,246.19,244.49,242.69,240.42,238.34],"p95":[294.14,287.27,287.02,285.79,285.32,284.8,284.09,283.86,282.34,281.23,279.84,278.47,276.76,275.49,274.2,272.62,270.69,268.92,267.11,265.32,263.62,261.99,260.61,258.88,256.79,254.68,252.96,251.49,249.43,247.34,245.19,243.06],"eq7_err":[0.0,-4.31,-5.84,-6.25,-6.93,-7.64,-8.46,-9.03,-9.65,-10.15,-10.44,-10.52,-10.57,-10.54,-10.61,-10.52,-10.27,-10.13,-9.92,-9.75,-9.52,-9.12,-8.77,-8.35,-7.95,-7.57,-7.26,-7.0,-6.62,-6.32,-5.94,-5.53]},{"month":2,"n":74,"mean":[281.22,282.88,281.92,280.62,279.14,277.76,276.2,274.94,273.87,272.8,271.49,270.3,269.01,267.45,265.89,264.33,262.71,261.05,259.44,257.65,255.86,253.94,252.09,250.23,248.33,246.44,244.59,242.71,240.82,238.97,237.18,235.34],"sd":[12.73,5.69,5.63,5.73,5.71,5.69,5.8,5.71,5.57,5.47,5.52,5.44,5.36,5.33,5.3,5.28,5.25,5.28,5.25,5.2,5.27,5.3,5.29,5.16,5.09,5.04,4.96,4.91,4.85,4.76,4.67,4.61],"p05":[256.1,274.19,273.08,271.53,269.95,268.16,265.91,264.11,262.63,261.48,260.98,260.59,260.11,258.75,257.48,256.1,254.85,253.24,250.96,250.59,248.74,246.62,244.53,242.77,240.73,238.93,237.42,235.85,233.89,231.83,229.76,227.86],"p50":[281.98,283.6,282.76,281.89,280.57,279.28,277.61,276.0,274.63,273.09,271.66,270.5,269.3,267.6,265.76,264.05,262.48,260.58,259.01,257.52,255.8,254.08,252.21,250.22,248.11,246.25,244.3,242.53,240.82,238.73,236.91,235.02],"p95":[297.52,290.44,289.74,288.86,287.84,286.08,284.22,282.48,281.1,280.28,279.52,278.18,277.37,275.6,273.78,272.24,270.54,269.33,267.52,266.12,264.8,262.78,261.0,259.32,257.3,255.21,253.03,250.97,248.71,246.99,245.34,243.81],"eq7_err":[0.0,-3.21,-3.81,-4.07,-4.14,-4.32,-4.32,-4.61,-5.1,-5.59,-5.83,-6.2,-6.47,-6.47,-6.46,-6.46,-6.39,-6.29,-6.24,-6.01,-5.77,-5.41,-5.12,-4.81,-4.47,-4.14,-3.84,-3.52,-3.18,-2.89,-2.66,-2.37]},{"month":3,"n":135,"mean":[286.29,285.07,283.78,282.05,280.33,278.55,276.99,275.72,274.67,273.47,272.24,270.93,269.53,268.07,266.48,264.81,263.09,261.39,259.63,257.87,256.13,254.31,252.5,250.72,248.89,247.02,245.16,243.26,241.31,239.44,237.51,235.65],"sd":[9.76,5.4,5.52,5.69,5.79,5.86,5.87,5.91,5.88,5.87,5.8,5.73,5.69,5.7,5.69,5.7,5.71,5.75,5.8,5.83,5.85,5.89,5.9,5.85,5.78,5.72,5.48,5.27,5.14,4.95,4.82,4.62],"p05":[269.48,277.98,276.69,274.64,272.76,270.69,268.87,267.47,266.05,264.29,262.59,261.48,260.41,258.62,256.92,255.31,253.99,251.97,250.2,248.29,246.19,244.06,242.14,240.67,238.5,237.14,235.31,234.1,232.75,231.13,229.52,228.48],"p50":[286.47,283.94,283.03,281.14,279.3,277.44,276.29,275.56,275.27,273.89,272.54,271.32,269.88,268.47,266.91,265.26,263.56,261.94,260.01,258.41,256.73,255.0,253.15,251.12,249.09,247.17,245.13,243.26,241.27,239.21,237.18,235.14],"p95":[301.48,296.04,294.98,293.52,292.73,291.59,290.37,289.45,287.92,286.11,284.29,282.62,281.24,279.56,277.58,275.91,274.01,272.64,270.97,269.17,267.26,265.31,263.05,261.25,259.57,257.64,255.83,254.01,252.17,250.24,248.07,245.92],"eq7_err":[0.0,-0.46,-0.85,-0.79,-0.75,-0.65,-0.77,-1.17,-1.81,-2.28,-2.74,-3.1,-3.38,-3.6,-3.69,-3.7,-3.66,-3.64,-3.56,-3.48,-3.42,-3.28,-3.14,-3.04,-2.89,-2.7,-2.52,-2.3,-2.03,-1.84,-1.59,-1.4]},{"month":4,"n":91,"mean":[291.29,289.94,288.7,287.24,285.68,284.11,282.53,280.95,279.57,278.11,276.56,275.01,273.48,271.91,270.35,268.77,267.09,265.39,263.59,261.83,260.05,258.17,256.29,254.49,252.62,250.75,248.9,247.02,245.1,243.16,241.2,239.22],"sd":[14.82,5.19,4.88,4.78,4.56,4.5,4.48,4.42,4.46,4.57,4.61,4.53,4.44,4.22,4.17,4.21,4.25,4.31,4.33,4.32,4.24,4.24,4.21,4.08,4.01,3.95,3.91,3.81,3.77,3.7,3.69,3.68],"p05":[272.18,282.31,280.55,278.92,277.6,275.87,274.06,272.19,269.94,268.26,266.41,265.01,264.36,263.19,262.29,260.74,258.79,257.13,255.86,254.65,253.07,251.05,248.92,247.73,245.69,243.51,241.96,240.2,238.58,236.85,234.64,232.58],"p50":[292.36,289.55,289.28,288.35,286.53,285.31,283.89,282.09,280.43,278.96,277.4,276.09,274.88,272.92,271.4,269.72,268.02,266.6,264.56,262.78,260.85,259.26,257.37,255.45,253.39,251.57,249.77,247.8,245.85,243.97,242.03,239.85],"p95":[309.9,298.44,295.92,293.91,291.71,290.01,288.38,286.49,285.07,283.55,282.07,280.43,278.66,276.71,274.96,273.18,271.65,269.91,268.62,266.96,265.14,263.13,261.35,259.42,257.29,255.44,253.78,251.92,250.17,248.05,245.99,243.86],"eq7_err":[0.0,-0.45,-1.01,-1.35,-1.59,-1.82,-2.04,-2.25,-2.68,-3.02,-3.26,-3.52,-3.78,-4.01,-4.26,-4.47,-4.6,-4.69,-4.69,-4.73,-4.75,-4.67,-4.59,-4.59,-4.52,-4.45,-4.4,-4.32,-4.19,-4.05,-3.89,-3.71]},{"month":5,"n":56,"mean":[296.08,292.01,290.58,289.12,287.52,285.94,284.1,282.29,280.53,278.79,277.11,275.5,274.02,272.59,271.01,269.46,267.82,266.17,264.56,262.77,261.0,259.27,257.44,255.64,253.8,251.98,250.09,248.16,246.21,244.32,242.44,240.59],"sd":[11.98,5.17,4.88,4.65,4.55,4.45,4.44,4.45,4.36,4.26,4.14,4.07,3.99,3.95,3.86,3.84,3.83,3.89,3.8,3.74,3.7,3.71,3.71,3.71,3.66,3.62,3.66,3.67,3.63,3.57,3.46,3.22],"p05":[281.4,283.81,283.55,282.12,279.72,277.33,275.04,272.98,271.23,269.86,268.49,267.38,265.85,265.14,263.2,261.66,260.28,258.22,256.07,254.05,252.44,250.49,248.76,247.13,245.24,243.18,241.08,239.16,237.44,235.79,234.08,234.23],"p50":[297.49,291.58,290.13,288.27,287.06,285.8,284.24,283.04,281.24,279.94,278.43,276.57,275.09,273.42,271.98,270.44,268.96,267.26,265.41,263.43,261.95,260.2,258.65,256.78,254.69,252.69,250.81,248.99,246.93,244.95,242.88,241.11],"p95":[310.29,300.45,297.97,295.7,294.12,291.93,290.45,288.76,286.55,284.21,282.17,280.18,278.77,277.28,275.54,273.82,272.28,270.59,268.65,266.9,265.23,263.35,261.69,259.78,257.8,255.69,253.97,252.59,250.49,248.41,246.29,244.36],"eq7_err":[0.0,2.16,1.67,1.22,0.9,0.57,0.5,0.39,0.23,0.06,-0.17,-0.48,-0.91,-1.4,-1.73,-2.1,-2.38,-2.64,-2.95,-3.07,-3.21,-3.4,-3.48,-3.6,-3.68,-3.77,-3.79,-3.78,-3.75,-3.77,-3.8,-3.87]},{"month":6,"n":54,"mean":[299.0,298.13,297.27,295.9,294.69,293.15,291.47,289.78,288.08,286.36,284.69,283.06,281.56,280.05,278.39,276.69,274.89,273.12,271.38,269.61,267.81,266.06,264.18,262.37,260.56,258.72,256.96,255.06,253.2,251.26,249.3,247.3],"sd":[13.46,5.38,4.71,4.38,3.91,3.71,3.55,3.33,3.27,3.14,3.04,2.99,2.81,2.74,2.69,2.61,2.6,2.6,2.53,2.54,2.57,2.57,2.53,2.51,2.5,2.49,2.44,2.49,2.56,2.59,2.66,2.7],"p05":[282.89,288.65,289.43,288.11,287.94,286.46,285.49,284.0,282.63,281.4,279.79,278.39,277.06,275.3,274.01,272.18,270.42,268.47,266.87,265.17,263.45,261.41,260.3,258.24,256.58,254.76,252.56,250.47,248.76,246.68,244.58,242.38],"p50":[298.09,298.42,297.96,296.64,295.62,294.1,292.1,290.47,288.26,286.27,284.66,283.38,281.6,280.52,278.75,276.98,275.28,273.84,272.13,270.23,268.15,266.39,264.67,262.95,261.04,259.24,257.32,255.31,253.29,251.37,249.57,247.72],"p95":[319.43,306.41,304.39,301.99,299.69,297.71,296.12,294.66,293.3,291.41,289.39,287.48,285.85,283.94,282.39,280.43,278.39,276.78,274.97,273.04,271.1,269.82,267.91,265.91,263.86,261.84,260.01,258.37,256.39,254.69,253.29,251.26],"eq7_err":[0.0,-1.11,-2.24,-2.85,-3.63,-4.07,-4.38,-4.68,-4.97,-5.22,-5.55,-5.89,-6.38,-6.86,-7.19,-7.46,-7.65,-7.87,-8.11,-8.33,-8.52,-8.75,-8.86,-9.03,-9.2,-9.35,-9.57,-9.66,-9.79,-9.83,-9.85,-9.84]},{"month":7,"n":78,"mean":[306.84,301.95,300.55,299.01,297.53,296.05,294.38,292.66,290.89,289.11,287.25,285.39,283.46,281.6,279.75,277.93,276.15,274.39,272.7,271.02,269.41,267.73,266.13,264.4,262.63,260.83,258.94,257.11,255.3,253.45,251.56,249.78],"sd":[11.62,3.76,3.38,3.06,2.86,2.67,2.59,2.46,2.15,1.95,1.85,1.81,1.79,1.86,1.84,1.79,1.67,1.58,1.55,1.54,1.62,1.6,1.62,1.67,1.73,1.72,1.72,1.76,1.86,1.9,1.88,1.87],"p05":[291.16,296.36,294.85,293.86,292.65,291.58,289.75,288.04,287.29,285.96,284.62,282.65,280.47,278.51,276.89,275.62,273.91,272.47,270.51,268.64,266.96,265.0,263.65,261.88,260.3,258.38,256.58,254.48,252.5,250.47,248.82,246.7],"p50":[306.51,301.88,300.58,299.32,297.8,296.37,294.68,292.97,291.11,289.04,287.12,285.24,283.25,281.45,279.43,277.67,276.04,274.27,272.59,270.92,269.25,267.61,266.05,264.24,262.51,260.81,259.01,257.23,255.31,253.61,251.61,249.92],"p95":[322.96,307.82,305.94,303.32,301.68,300.02,297.95,296.13,294.12,291.82,289.91,288.3,286.06,284.19,282.43,280.53,278.53,276.49,274.75,273.06,271.48,269.97,268.81,266.96,265.91,263.63,261.86,260.17,258.24,256.13,254.25,252.48],"eq7_err":[0.0,2.72,1.94,1.3,0.61,-0.08,-0.59,-1.04,-1.45,-1.83,-2.15,-2.46,-2.71,-3.03,-3.35,-3.7,-4.1,-4.51,-4.99,-5.49,-6.05,-6.55,-7.13,-7.56,-7.97,-8.34,-8.64,-8.97,-9.34,-9.66,-9.95,-10.34]},{"month":8,"n":66,"mean":[301.71,300.98,300.21,298.97,297.38,295.65,293.87,291.99,290.07,288.11,286.16,284.23,282.31,280.41,278.6,276.75,275.07,273.34,271.63,270.04,268.53,267.07,265.48,263.86,262.17,260.42,258.78,257.13,255.46,253.63,251.82,249.97],"sd":[10.49,4.09,3.44,3.1,2.88,2.69,2.49,2.29,2.19,2.11,2.09,2.11,2.13,1.99,1.81,1.76,1.74,1.73,1.75,1.81,1.87,1.96,2.05,2.0,2.0,2.04,1.89,1.8,1.68,1.7,1.71,1.8],"p05":[285.25,295.3,295.26,295.6,294.04,292.3,290.48,288.46,286.36,284.16,282.29,279.95,278.26,277.35,275.6,273.92,272.52,271.15,269.33,267.78,265.93,264.06,262.34,260.57,258.45,256.86,255.09,253.66,252.36,250.46,248.53,246.6],"p50":[301.27,300.89,300.13,298.99,297.63,295.87,294.34,292.2,290.14,288.51,286.62,284.53,282.58,280.59,278.57,276.69,274.65,272.95,271.03,269.94,268.49,266.93,265.43,263.93,262.33,260.43,258.77,257.36,255.63,253.91,252.13,250.18],"p95":[318.88,307.49,306.08,303.77,301.73,299.65,297.32,295.3,293.35,291.46,289.36,287.4,285.68,283.4,281.39,279.71,278.32,277.1,275.4,273.81,272.13,270.85,269.04,267.5,265.6,263.61,261.64,259.81,257.85,255.82,254.05,252.15],"eq7_err":[0.0,-1.32,-2.6,-3.41,-3.87,-4.19,-4.47,-4.64,-4.76,-4.86,-4.95,-5.08,-5.21,-5.36,-5.6,-5.8,-6.17,-6.49,-6.83,-7.29,-7.83,-8.42,-8.88,-9.31,-9.68,-9.97,-10.39,-10.79,-11.16,-11.39,-11.63,-11.83]},{"month":9,"n":103,"mean":[297.59,295.6,294.92,293.57,292.2,290.61,288.97,287.34,285.69,284.06,282.44,280.89,279.4,277.94,276.51,274.98,273.45,271.92,270.33,268.72,267.07,265.36,263.64,261.84,260.1,258.32,256.5,254.61,252.74,250.84,248.94,247.01],"sd":[11.78,4.98,4.65,4.47,4.16,4.03,3.81,3.41,3.17,3.05,3.02,3.05,2.99,2.86,2.82,2.88,2.82,2.73,2.63,2.55,2.53,2.52,2.52,2.55,2.46,2.41,2.36,2.33,2.25,2.16,2.07,2.03],"p05":[278.25,287.66,287.02,285.66,285.73,284.16,282.69,281.89,280.05,277.94,276.26,274.65,273.01,272.38,270.86,269.5,268.07,266.89,265.66,264.6,262.92,260.8,258.96,257.11,256.01,254.57,252.86,250.81,248.68,247.04,245.47,243.6],"p50":[297.87,296.09,295.51,293.88,292.95,291.52,290.05,288.25,286.29,284.48,283.06,281.28,279.9,278.44,277.1,275.64,274.07,272.45,270.79,269.22,267.67,265.82,264.15,262.23,260.65,258.65,256.82,254.97,252.93,251.1,249.2,247.24],"p95":[315.87,304.63,302.45,300.09,297.83,295.66,294.0,291.62,289.63,288.17,286.66,285.41,283.78,282.19,280.45,278.84,277.26,275.68,273.76,272.06,270.29,268.42,266.73,264.83,263.29,261.47,259.41,257.67,255.61,253.56,251.51,249.79],"eq7_err":[0.0,0.04,-1.23,-1.84,-2.41,-2.78,-3.09,-3.41,-3.71,-4.03,-4.37,-4.77,-5.23,-5.72,-6.24,-6.66,-7.08,-7.5,-7.86,-8.21,-8.51,-8.75,-8.98,-9.13,-9.34,-9.52,-9.64,-9.71,-9.78,-9.83,-9.89,-9.91]},{"month":10,"n":74,"mean":[290.25,291.3,290.94,289.6,288.0,286.27,284.76,283.31,282.19,280.97,279.85,278.58,277.07,275.52,274.0,272.34,270.69,269.11,267.53,265.97,264.24,262.39,260.57,258.76,256.95,255.17,253.3,251.31,249.27,247.25,245.24,243.28],"sd":[12.04,5.13,4.76,4.76,4.68,4.68,4.45,4.22,3.8,3.6,3.57,3.6,3.54,3.41,3.35,3.25,3.24,3.19,3.14,3.1,3.09,3.17,3.12,3.07,3.13,3.14,3.23,3.26,3.26,3.25,3.18,2.99],"p05":[269.35,282.16,282.57,280.51,278.51,276.73,276.14,274.86,276.27,275.89,273.87,271.89,270.4,269.8,268.4,267.06,265.32,263.61,261.97,260.11,258.28,255.97,254.38,252.95,251.08,249.37,247.03,245.27,243.29,241.47,240.29,238.61],"p50":[291.62,290.81,290.98,289.87,288.34,286.66,285.41,284.21,282.88,281.27,280.72,279.17,277.6,276.08,274.75,273.15,271.69,269.83,268.13,266.76,264.78,263.48,261.57,259.49,257.53,255.86,254.02,251.97,250.06,248.04,246.01,243.89],"p95":[307.62,299.6,298.44,296.56,295.01,293.29,291.09,288.94,287.33,285.54,283.84,283.3,282.0,280.53,278.52,276.64,274.88,273.34,271.68,269.98,268.05,266.44,264.53,262.96,261.37,259.4,257.5,255.43,253.47,251.53,249.41,247.05],"eq7_err":[0.0,-2.83,-4.25,-4.68,-4.85,-4.9,-5.16,-5.49,-6.14,-6.69,-7.35,-7.85,-8.12,-8.34,-8.6,-8.71,-8.84,-9.03,-9.22,-9.43,-9.48,-9.41,-9.36,-9.32,-9.29,-9.28,-9.19,-8.97,-8.71,-8.46,-8.22,-8.04]},{"month":11,"n":71,"mean":[282.65,286.01,286.06,284.82,283.55,282.27,281.18,280.14,279.14,278.3,277.23,275.91,274.41,272.83,271.37,269.74,268.16,266.56,264.86,263.16,261.5,259.83,258.01,256.23,254.51,252.73,250.85,248.95,246.96,244.96,242.98,241.02],"sd":[13.56,3.96,3.98,4.18,4.27,4.44,4.42,4.45,4.16,3.75,3.3,3.09,3.08,3.11,3.1,3.08,3.0,2.99,3.05,3.05,3.09,3.13,3.08,2.94,2.86,2.91,3.03,3.1,3.09,3.07,3.05,3.08],"p05":[261.73,279.27,279.41,278.04,275.98,274.37,273.43,271.74,271.08,270.61,270.05,269.79,268.86,267.69,266.15,264.35,262.93,261.14,259.16,257.35,255.27,253.55,252.91,251.59,249.88,248.15,245.99,243.66,241.41,239.66,237.91,236.12],"p50":[283.99,286.44,286.75,285.42,284.13,283.46,282.55,281.45,280.37,279.1,277.38,276.03,274.58,272.97,271.65,270.2,268.74,267.19,265.4,263.73,262.23,260.52,258.65,256.78,255.07,253.25,251.62,249.98,247.91,245.84,243.74,241.81],"p95":[302.12,293.32,292.17,290.7,289.55,287.99,286.94,285.87,284.33,283.24,282.32,280.29,278.87,277.34,276.62,274.96,273.0,271.06,269.46,267.61,266.0,264.69,262.7,260.69,258.6,256.74,254.77,252.82,250.87,248.92,246.87,245.3],"eq7_err":[0.0,-4.95,-6.59,-6.94,-7.26,-7.57,-8.08,-8.62,-9.22,-9.97,-10.49,-10.76,-10.86,-10.86,-11.0,-10.96,-10.97,-10.96,-10.85,-10.74,-10.67,-10.59,-10.36,-10.17,-10.05,-9.85,-9.57,-9.26,-8.86,-8.45,-8.06,-7.7]},{"month":12,"n":65,"mean":[283.68,283.55,283.09,281.69,280.26,278.97,277.96,277.16,276.38,275.42,274.29,272.93,271.44,269.99,268.62,267.17,265.52,263.88,262.27,260.55,258.8,257.05,255.23,253.48,251.61,249.7,247.84,245.91,243.95,241.95,240.0,238.05],"sd":[10.86,4.21,4.09,4.27,4.54,4.58,4.53,3.97,3.56,3.33,3.45,3.49,3.51,3.58,3.45,3.38,3.37,3.31,3.25,3.2,3.28,3.4,3.44,3.49,3.54,3.58,3.65,3.7,3.71,3.72,3.73,3.75],"p05":[259.75,277.61,277.61,275.82,273.96,272.26,270.99,271.19,271.21,269.98,268.31,266.54,264.75,263.31,262.85,261.28,259.8,258.4,256.98,255.26,253.19,250.87,248.86,247.26,245.25,243.44,241.46,239.72,238.19,236.12,234.11,232.45],"p50":[285.34,283.35,283.11,281.45,279.56,278.41,278.14,276.71,276.44,275.74,274.4,273.26,271.62,270.21,269.19,267.37,265.56,264.12,262.38,260.89,259.04,256.88,255.53,253.86,252.15,249.87,247.78,245.81,243.64,241.87,239.69,237.8],"p95":[296.46,289.99,289.21,287.56,288.01,286.28,284.98,283.39,281.78,280.31,279.48,278.92,277.38,275.63,273.92,272.08,270.38,268.78,266.79,264.88,264.05,262.99,261.04,259.05,257.11,255.22,253.32,251.36,249.54,247.55,245.69,243.66],"eq7_err":[0.0,-1.49,-2.64,-2.85,-3.04,-3.37,-3.98,-4.79,-5.62,-6.29,-6.77,-7.02,-7.15,-7.32,-7.56,-7.73,-7.7,-7.67,-7.68,-7.57,-7.44,-7.3,-7.1,-6.97,-6.71,-6.42,-6.17,-5.86,-5.51,-5.13,-4.8,-4.46]}],"nid":[{"month":1,"n":24,"mean":[276.94,282.33,281.77,280.39,279.03,277.49,276.16,275.22,274.25,273.1,271.96,270.86,269.64,268.12,266.4,264.66,262.92,261.22,259.42,257.48,255.62,253.81,252.07,250.19,248.26,246.37,244.71,243.06,241.32,239.49,237.59,235.73],"sd":[9.98,3.35,3.95,4.22,4.62,4.86,4.92,5.14,5.3,5.38,5.14,5.05,5.13,5.2,5.17,5.17,5.25,5.35,5.47,5.52,5.61,5.68,5.74,5.9,5.98,6.06,6.25,5.57,5.05,4.66,4.39,4.13],"p05":[256.84,277.62,276.37,274.52,272.58,270.68,268.73,267.02,265.53,263.83,262.36,260.69,259.05,257.1,255.06,253.04,250.88,248.68,246.57,244.48,242.62,240.61,238.56,236.45,234.32,232.09,230.0,231.13,231.42,231.27,230.79,229.57],"p50":[278.54,281.89,281.73,280.21,278.79,277.12,275.56,274.26,273.02,271.83,271.07,270.39,269.73,268.9,267.1,265.58,263.9,262.09,260.58,258.74,256.9,254.91,253.18,251.48,249.59,247.63,245.62,243.45,241.34,239.3,237.38,235.39],"p95":[288.1,286.84,287.98,287.07,285.73,284.85,283.27,282.65,282.53,281.83,279.93,278.16,276.53,275.28,273.19,271.47,270.05,268.18,266.78,265.3,263.17,261.02,258.91,257.51,256.12,254.39,252.72,250.81,248.77,246.48,244.25,242.19],"eq7_err":[0.0,-6.85,-7.75,-7.81,-7.91,-7.82,-7.95,-8.46,-8.94,-9.25,-9.56,-9.92,-10.15,-10.08,-9.82,-9.52,-9.24,-8.99,-8.64,-8.16,-7.75,-7.4,-7.11,-6.68,-6.2,-5.77,-5.56,-5.36,-5.07,-4.7,-4.26,-3.85]},{"month":2,"n":36,"mean":[283.09,283.95,282.76,281.27,279.85,278.11,276.49,274.72,273.09,271.69,270.58,269.22,267.97,266.71,265.2,263.57,261.93,260.44,258.85,257.4,255.86,254.15,252.34,250.58,248.68,246.73,244.76,242.85,240.86,238.87,236.95,235.07],"sd":[9.47,4.22,4.27,4.6,5.04,5.22,5.39,5.5,5.56,5.41,5.31,5.32,5.49,5.52,5.56,5.62,5.6,5.4,5.31,4.93,4.92,4.96,4.9,4.68,4.53,4.48,4.43,4.46,4.49,4.53,4.53,4.45],"p05":[263.21,277.86,275.85,273.52,271.15,268.75,266.93,265.04,263.39,261.72,260.93,260.12,258.25,256.38,254.51,252.73,251.25,250.79,250.79,248.82,246.83,245.06,243.38,241.76,240.66,239.15,238.02,236.72,234.74,232.77,230.82,229.07],"p50":[285.28,284.2,283.4,281.77,279.68,278.06,277.12,275.55,273.91,272.49,271.24,270.01,268.42,266.87,265.02,263.53,262.26,260.69,259.03,257.59,256.27,254.69,252.57,250.6,248.35,246.48,244.56,242.73,240.34,237.93,235.76,234.17],"p95":[295.71,291.13,289.32,288.52,287.61,286.13,284.83,283.01,281.62,280.38,278.96,277.77,277.2,275.72,274.25,272.73,271.14,269.17,267.11,265.3,263.74,261.78,260.47,258.88,256.75,254.61,252.48,250.98,249.48,247.78,245.9,243.83],"eq7_err":[0.0,-2.46,-2.87,-2.99,-3.16,-3.03,-3.01,-2.84,-2.81,-3.01,-3.51,-3.75,-4.1,-4.44,-4.53,-4.51,-4.47,-4.58,-4.59,-4.74,-4.8,-4.69,-4.49,-4.33,-4.04,-3.68,-3.31,-3.0,-2.62,-2.23,-1.91,-1.64]},{"month":3,"n":48,"mean":[286.25,287.67,286.36,284.64,282.89,281.04,279.26,277.57,275.95,274.39,272.92,271.45,270.06,268.57,267.1,265.56,263.84,262.13,260.4,258.64,256.85,255.09,253.24,251.38,249.5,247.67,245.81,243.93,242.04,240.15,238.24,236.39],"sd":[13.33,5.17,5.28,5.4,5.51,5.49,5.55,5.62,5.77,5.83,5.84,5.74,5.78,5.74,5.75,5.63,5.69,5.66,5.66,5.61,5.58,5.6,5.53,5.35,5.19,5.1,4.99,4.84,4.7,4.51,4.36,4.18],"p05":[265.5,280.22,277.98,275.78,273.61,271.43,269.24,267.3,265.42,263.9,262.18,260.4,258.6,256.55,254.32,253.86,252.15,250.43,248.71,247.23,246.2,244.58,242.73,240.99,239.15,237.78,236.39,235.05,234.09,232.52,231.23,230.11],"p50":[286.64,287.07,286.33,284.7,283.29,281.14,278.86,277.04,276.2,274.56,273.14,271.7,270.15,268.75,267.77,266.5,264.81,263.02,261.42,259.76,257.89,256.33,254.49,252.53,250.43,248.45,246.5,244.51,242.27,240.34,238.53,236.92],"p95":[305.67,297.35,295.47,293.8,291.53,289.22,286.92,284.7,282.51,280.5,278.91,277.98,277.61,276.11,274.37,272.42,270.33,268.29,266.46,265.0,263.24,261.26,259.57,257.83,255.84,253.93,251.7,249.53,247.49,245.94,243.8,241.59],"eq7_err":[0.0,-3.09,-3.46,-3.42,-3.35,-3.18,-3.07,-3.06,-3.12,-3.24,-3.44,-3.65,-3.95,-4.13,-4.34,-4.48,-4.43,-4.4,-4.35,-4.27,-4.16,-4.07,-3.91,-3.72,-3.52,-3.36,-3.18,-2.98,-2.77,-2.56,-2.33,-2.15]},{"month":4,"n":34,"mean":[288.3,288.72,287.19,285.51,283.79,281.97,280.1,278.18,276.28,274.74,273.36,272.06,270.58,269.21,267.8,266.15,264.39,262.7,260.9,259.14,257.33,255.47,253.6,251.79,250.12,248.39,246.55,244.69,242.75,240.81,238.93,237.07],"sd":[10.14,5.87,5.84,5.95,6.15,6.28,6.4,6.52,6.61,6.57,6.29,5.82,5.9,5.97,6.11,6.14,6.16,6.09,6.09,6.11,6.19,6.26,6.21,6.17,5.87,5.64,5.47,5.33,5.22,5.14,4.98,4.65],"p05":[267.96,280.12,278.48,276.06,273.85,271.71,269.67,267.71,265.64,263.96,263.12,261.35,259.23,257.62,255.95,253.91,251.89,249.89,247.92,246.01,244.19,242.32,240.59,238.89,237.47,236.18,235.34,233.8,232.41,230.98,229.97,229.54],"p50":[288.38,288.17,287.0,285.03,283.77,282.14,280.25,278.6,276.59,274.96,274.19,272.93,271.87,270.51,269.89,268.61,266.78,265.05,263.11,261.16,259.39,257.59,255.55,253.56,251.72,249.92,247.97,245.9,243.86,241.81,240.0,237.9],"p95":[301.5,298.45,298.48,297.03,294.91,292.57,290.32,288.08,286.24,284.22,282.13,280.29,278.45,276.63,275.23,273.76,272.09,270.19,268.28,266.46,264.85,263.1,261.16,259.18,257.14,255.09,253.05,251.01,249.0,247.32,245.56,243.54],"eq7_err":[0.0,-2.15,-2.35,-2.4,-2.4,-2.31,-2.16,-1.98,-1.8,-1.99,-2.34,-2.76,-3.01,-3.37,-3.69,-3.77,-3.73,-3.77,-3.69,-3.66,-3.57,-3.45,-3.3,-3.22,-3.28,-3.27,-3.16,-3.03,-2.81,-2.6,-2.45,-2.31]},{"month":5,"n":36,"mean":[296.62,296.11,294.53,292.7,290.7,288.71,286.7,284.67,282.6,280.6,278.59,276.64,275.0,273.35,271.75,270.07,268.52,267.07,265.53,264.03,262.34,260.52,258.67,256.76,254.84,252.9,250.94,248.98,247.1,245.21,243.3,241.3],"sd":[10.92,5.29,4.81,4.58,4.51,4.5,4.48,4.49,4.51,4.46,4.42,4.42,4.49,4.48,4.4,4.46,4.48,4.49,4.51,4.4,4.38,4.42,4.43,4.43,4.45,4.47,4.47,4.47,4.32,4.16,3.96,3.87],"p05":[278.23,286.25,284.38,282.41,280.28,278.13,276.05,273.98,271.89,269.94,267.94,265.94,264.3,262.61,261.21,259.31,257.61,256.05,254.3,252.61,250.84,249.01,247.13,245.05,242.96,240.91,238.87,236.82,235.69,234.66,233.79,232.39],"p50":[301.03,297.43,296.12,293.81,291.72,289.85,287.9,286.18,283.98,281.87,279.64,277.82,276.11,274.47,272.89,271.43,269.73,267.99,266.31,264.62,262.63,261.02,258.94,256.98,255.06,253.15,251.35,249.51,247.47,245.81,243.76,241.69],"p95":[309.74,302.42,300.11,298.0,295.86,293.96,291.91,289.85,287.8,285.78,283.8,281.82,279.91,278.01,276.24,274.69,273.65,272.2,270.7,269.39,267.69,265.97,264.07,262.08,260.14,258.27,256.19,254.03,252.08,249.87,247.74,245.62],"eq7_err":[0.0,-1.42,-1.77,-1.86,-1.79,-1.73,-1.65,-1.55,-1.41,-1.33,-1.25,-1.23,-1.51,-1.79,-2.12,-2.37,-2.74,-3.22,-3.62,-4.04,-4.28,-4.39,-4.47,-4.49,-4.49,-4.48,-4.45,-4.42,-4.46,-4.5,-4.52,-4.44]},{"month":6,"n":32,"mean":[303.92,300.38,298.73,297.03,295.28,293.39,291.45,289.43,287.41,285.46,283.59,281.75,280.02,278.45,276.79,274.97,273.13,271.33,269.52,267.72,266.04,264.25,262.46,260.84,259.12,257.42,255.57,253.65,251.81,249.82,247.93,245.99],"sd":[10.43,7.02,6.62,6.25,6.03,5.92,5.67,5.51,5.37,5.15,4.84,4.54,4.4,4.27,4.29,4.25,4.2,4.1,4.08,4.1,4.13,4.13,4.2,4.2,4.02,3.98,4.01,4.0,4.08,4.17,4.29,4.38],"p05":[284.82,288.54,286.95,286.43,285.08,283.29,281.43,279.52,277.51,275.7,274.52,272.86,271.37,269.87,268.09,266.25,264.42,262.6,260.97,259.13,257.3,255.27,253.35,251.95,250.41,248.81,246.72,244.74,242.68,240.54,238.36,236.16],"p50":[306.76,303.94,301.51,299.03,297.31,295.09,293.02,290.85,288.47,286.13,284.64,282.9,280.89,279.58,278.12,276.44,274.56,272.55,270.72,268.85,266.82,265.19,263.13,261.25,259.51,258.01,256.29,254.65,252.89,250.95,249.2,247.8],"p95":[315.51,308.03,305.78,303.92,302.09,300.43,298.21,295.99,293.81,291.64,289.46,287.28,285.29,283.45,281.71,279.86,277.79,275.88,274.24,272.57,270.67,268.7,267.32,265.71,263.63,262.04,260.01,257.97,255.93,254.29,252.5,250.42],"eq7_err":[0.0,1.44,0.98,0.58,0.23,0.01,-0.15,-0.23,-0.32,-0.47,-0.7,-0.97,-1.35,-1.88,-2.32,-2.61,-2.87,-3.18,-3.46,-3.77,-4.19,-4.51,-4.82,-5.31,-5.69,-6.1,-6.35,-6.54,-6.8,-6.91,-7.12,-7.29]},{"month":7,"n":40,"mean":[302.26,303.38,302.41,301.19,299.57,297.7,295.73,293.69,291.66,289.68,287.64,285.66,283.65,281.69,279.77,278.02,276.27,274.43,272.6,270.79,269.0,267.4,265.55,263.73,262.03,260.3,258.59,256.89,255.16,253.27,251.52,249.7],"sd":[14.38,4.53,3.86,3.69,3.69,3.53,3.31,3.11,2.81,2.56,2.42,2.28,2.11,1.98,1.91,1.72,1.7,1.76,1.82,1.83,1.92,2.04,2.08,2.13,2.17,2.24,2.32,2.4,2.55,2.7,2.62,2.63],"p05":[273.75,297.61,296.43,294.03,291.55,289.4,288.8,286.92,285.76,284.95,284.16,282.56,280.96,278.83,276.46,275.75,274.09,272.26,270.12,268.78,266.65,264.5,262.3,260.76,258.94,256.93,255.16,253.74,251.59,249.24,246.93,244.59],"p50":[303.32,302.73,301.94,300.76,299.52,297.82,295.83,293.86,291.7,289.77,287.62,285.65,283.67,281.51,279.62,278.04,276.45,274.48,272.46,270.44,268.55,266.95,265.38,263.78,261.67,260.09,258.18,256.41,254.84,253.48,251.84,250.12],"p95":[320.85,311.21,308.86,306.89,305.52,303.25,300.98,298.66,296.32,293.98,291.63,289.33,287.04,284.72,282.55,280.22,278.47,277.3,275.7,274.19,272.49,270.59,269.28,267.25,265.31,263.45,261.46,260.01,258.65,256.84,254.98,253.28],"eq7_err":[0.0,-3.19,-4.28,-5.13,-5.57,-5.76,-5.86,-5.88,-5.92,-6.0,-6.02,-6.1,-6.15,-6.26,-6.41,-6.72,-7.03,-7.26,-7.49,-7.74,-8.02,-8.49,-8.69,-8.94,-9.3,-9.64,-9.99,-10.36,-10.69,-10.87,-11.18,-11.42]},{"month":8,"n":48,"mean":[301.66,301.81,301.22,299.79,298.06,296.35,294.57,292.66,290.73,288.78,286.86,285.03,283.09,281.16,279.2,277.3,275.47,273.64,271.87,270.3,268.69,267.07,265.41,263.66,261.88,260.1,258.37,256.59,254.71,252.9,251.06,249.23],"sd":[13.01,4.65,3.7,3.27,3.04,2.83,2.64,2.56,2.51,2.4,2.22,2.07,1.99,1.9,1.83,1.74,1.7,1.71,1.65,1.44,1.47,1.61,1.72,1.79,1.77,1.77,1.69,1.76,1.74,1.74,1.77,1.77],"p05":[284.19,294.63,296.04,294.9,293.77,292.35,290.99,289.23,287.35,285.29,283.4,281.55,280.01,278.19,276.0,274.06,272.29,270.49,268.82,268.05,266.5,264.46,262.75,261.43,259.28,257.39,255.75,253.92,251.9,249.76,247.87,246.04],"p50":[299.03,302.29,301.74,299.87,297.65,295.96,294.06,292.28,290.67,288.78,286.97,285.23,283.21,281.3,279.52,277.7,275.84,273.86,271.96,270.16,268.4,266.96,265.38,263.5,261.67,260.21,258.41,256.81,254.79,253.06,251.3,249.51],"p95":[324.63,308.11,306.41,304.86,302.63,301.01,299.22,297.22,295.21,293.07,290.85,288.63,286.41,284.14,281.92,279.68,277.65,276.17,274.23,272.22,271.03,270.13,268.98,266.9,264.87,263.23,261.68,259.86,257.72,255.6,253.63,251.84],"eq7_err":[0.0,-2.2,-3.66,-4.28,-4.6,-4.94,-5.21,-5.35,-5.46,-5.56,-5.69,-5.92,-6.03,-6.14,-6.24,-6.39,-6.6,-6.82,-7.1,-7.58,-8.02,-8.45,-8.84,-9.14,-9.4,-9.68,-9.99,-10.27,-10.44,-10.67,-10.88,-11.1]},{"month":9,"n":28,"mean":[298.09,298.23,297.05,295.41,293.7,291.71,289.84,287.96,286.08,284.22,282.4,280.6,278.79,277.2,275.71,274.16,272.59,271.18,269.58,268.05,266.43,264.78,263.06,261.28,259.56,257.83,255.91,254.02,252.18,250.3,248.39,246.46],"sd":[13.7,5.21,4.75,4.54,4.28,4.15,3.96,3.77,3.62,3.4,3.17,3.06,3.04,3.06,2.93,2.94,2.86,2.94,3.14,3.19,3.09,3.07,3.06,3.09,2.99,2.87,2.82,2.78,2.78,2.78,2.78,2.78],"p05":[279.01,287.6,289.03,288.13,287.62,285.8,283.76,281.9,279.92,278.14,276.86,275.39,273.54,271.5,270.29,268.97,267.78,266.35,264.73,263.27,262.13,260.48,258.65,256.99,255.74,253.98,251.99,250.17,248.44,246.58,244.66,242.66],"p50":[299.18,298.82,298.65,296.73,294.5,292.33,290.29,288.96,286.89,284.86,282.84,280.56,278.89,277.58,276.08,274.44,272.92,271.27,269.63,267.56,266.28,264.9,263.41,261.83,260.1,258.4,256.22,254.01,251.9,249.95,248.25,246.38],"p95":[318.0,305.51,303.25,301.73,299.84,297.71,295.34,292.9,290.6,288.68,286.53,284.37,282.58,281.12,279.57,278.03,276.44,275.06,273.8,272.97,271.35,269.53,267.94,266.45,264.56,262.8,261.07,259.32,257.4,255.41,253.4,251.38],"eq7_err":[0.0,-2.11,-2.89,-3.21,-3.46,-3.44,-3.53,-3.61,-3.7,-3.8,-3.95,-4.11,-4.26,-4.63,-5.1,-5.52,-5.92,-6.47,-6.83,-7.26,-7.61,-7.92,-8.17,-8.34,-8.59,-8.82,-8.87,-8.94,-9.07,-9.15,-9.2,-9.23]},{"month":10,"n":35,"mean":[288.99,293.22,292.14,290.7,289.4,287.89,286.29,284.62,283.24,282.22,280.93,279.62,278.12,276.63,275.21,273.67,272.21,270.6,268.94,267.19,265.49,263.65,261.84,259.9,258.01,256.15,254.32,252.49,250.57,248.66,246.75,244.8],"sd":[13.53,6.16,5.68,5.37,5.18,5.05,4.85,4.7,4.32,3.84,3.77,3.68,3.52,3.29,3.18,3.02,2.88,2.82,2.82,2.86,2.91,2.86,2.85,2.93,2.94,2.91,2.85,2.79,2.81,2.73,2.74,2.74],"p05":[265.35,284.67,284.46,282.34,280.2,278.66,277.19,275.91,275.66,275.84,274.15,272.28,271.66,270.87,269.91,268.34,266.86,265.08,263.28,261.46,259.85,258.08,257.04,255.14,253.0,250.86,248.81,247.18,245.0,243.07,241.29,239.58],"p50":[290.87,291.82,291.93,290.6,289.35,287.72,286.21,284.28,282.2,282.23,280.59,280.54,278.74,276.79,275.97,274.12,272.35,270.89,269.19,267.39,265.56,263.6,261.76,259.92,258.09,256.4,254.81,252.91,251.18,249.15,247.1,245.28],"p95":[307.41,304.26,301.93,299.63,297.36,295.27,293.4,291.44,289.58,287.94,285.93,284.54,283.16,281.59,279.96,278.19,276.31,274.59,273.01,271.22,269.36,267.62,265.72,263.94,262.11,260.45,258.66,256.56,254.45,252.3,250.44,248.56],"eq7_err":[0.0,-5.97,-6.64,-6.94,-7.38,-7.62,-7.76,-7.83,-8.2,-8.92,-9.37,-9.82,-10.06,-10.31,-10.63,-10.84,-11.12,-11.26,-11.34,-11.33,-11.38,-11.28,-11.21,-11.02,-10.87,-10.76,-10.67,-10.58,-10.41,-10.25,-10.08,-9.87]},{"month":11,"n":32,"mean":[279.69,285.9,285.46,284.79,283.9,282.78,281.45,280.2,279.05,278.21,277.03,275.61,274.07,272.66,271.1,269.37,267.6,265.79,264.0,262.33,260.6,258.91,256.98,255.0,253.09,251.18,249.23,247.27,245.37,243.5,241.58,239.6],"sd":[12.66,4.09,3.58,3.98,4.18,4.15,4.28,4.39,4.35,3.69,3.28,3.2,3.13,3.08,3.31,3.37,3.23,3.16,3.11,3.04,3.09,3.34,3.43,3.49,3.41,3.47,3.46,3.42,3.45,3.4,3.31,3.26],"p05":[253.69,280.1,280.84,279.68,278.12,276.41,274.45,272.54,271.17,271.34,270.73,269.1,267.23,265.45,263.28,261.4,260.03,258.47,256.92,255.3,253.56,251.64,249.72,247.8,246.57,244.88,243.17,241.27,239.29,237.26,235.41,233.64],"p50":[282.5,285.72,284.71,283.98,283.68,283.19,281.88,280.64,279.93,278.55,276.97,275.27,274.12,272.5,271.34,269.5,268.08,266.47,264.58,262.8,261.24,259.33,257.3,255.12,253.34,251.35,249.58,247.89,246.24,244.61,242.79,240.56],"p95":[295.97,293.33,291.77,291.67,289.79,288.48,287.16,286.12,285.02,283.3,281.54,279.87,278.34,276.9,275.12,273.7,271.79,270.01,268.01,266.1,264.37,263.24,261.31,259.37,257.44,255.48,253.5,251.61,249.94,247.93,245.88,243.88],"eq7_err":[0.0,-7.73,-8.81,-9.66,-10.29,-10.69,-10.88,-11.15,-11.52,-12.2,-12.55,-12.64,-12.62,-12.73,-12.69,-12.48,-12.23,-11.94,-11.67,-11.51,-11.31,-11.14,-10.73,-10.26,-9.88,-9.49,-9.05,-8.61,-8.24,-7.88,-7.48,-7.02]},{"month":12,"n":23,"mean":[280.37,283.46,283.0,282.09,280.86,279.77,278.49,277.34,276.12,275.23,274.14,272.75,271.28,269.87,268.34,266.78,265.51,263.96,262.33,260.6,258.89,257.03,255.37,253.76,252.05,250.36,248.51,246.61,244.55,242.58,240.59,238.59],"sd":[10.3,2.66,2.95,3.56,3.95,4.29,4.41,4.48,4.49,3.97,3.89,4.11,4.22,4.3,4.3,4.23,4.08,4.1,4.06,3.98,3.97,3.96,3.91,3.14,2.84,2.95,2.92,2.94,3.08,3.26,3.34,3.37],"p05":[261.98,279.15,278.24,276.77,275.18,273.06,270.94,268.93,266.99,268.06,267.21,266.29,264.97,263.39,261.81,260.21,258.51,256.61,255.78,254.87,253.74,252.71,251.68,249.88,247.92,246.27,244.62,242.55,240.36,238.21,236.03,234.05],"p50":[282.49,283.27,283.58,281.39,280.2,280.77,279.91,279.37,277.9,276.15,274.82,273.33,271.76,270.2,268.63,267.06,265.4,263.69,262.16,260.5,258.87,256.99,255.52,253.87,252.13,250.43,248.58,246.57,244.67,242.88,240.93,239.18],"p95":[292.29,287.49,287.79,287.52,286.97,285.97,284.11,282.43,281.39,280.43,278.96,278.39,276.98,275.48,273.58,271.82,270.3,268.82,267.54,265.61,263.81,262.16,260.44,258.56,256.55,254.54,252.5,250.59,248.76,247.36,245.41,243.37],"eq7_err":[0.0,-4.63,-5.7,-6.33,-6.63,-7.08,-7.34,-7.73,-8.04,-8.68,-9.14,-9.28,-9.35,-9.47,-9.47,-9.45,-9.71,-9.71,-9.61,-9.42,-9.24,-8.92,-8.8,-8.72,-8.55,-8.39,-8.08,-7.71,-7.2,-6.75,-6.3,-5.84]}],"vef":[{"month":1,"n":618,"mean":[282.7,283.21,281.68,280.19,278.75,277.37,276.09,274.92,273.8,272.6,271.3,269.96,268.57,267.17,265.65,264.06,262.46,260.82,259.14,257.44,255.72,253.98,252.17,250.33,248.49,246.63,244.8,242.94,241.09,239.23,237.36,235.53],"sd":[7.04,3.51,3.51,3.66,3.86,4.14,4.38,4.61,4.78,4.91,4.99,5.02,5.04,5.08,5.08,5.09,5.08,5.09,5.11,5.13,5.15,5.17,5.15,5.13,5.11,5.08,5.01,4.94,4.76,4.56,4.38,4.18],"p05":[270.83,277.19,275.72,274.07,272.08,270.27,268.42,266.69,264.87,263.57,261.97,260.49,258.95,257.45,255.72,254.12,252.44,250.48,248.85,247.21,245.61,243.6,241.68,240.13,238.56,236.75,235.24,233.76,232.77,231.56,230.05,228.64],"p50":[283.64,283.37,281.91,280.3,278.81,277.45,276.18,275.2,274.2,273.1,271.84,270.62,269.33,268.01,266.63,265.1,263.51,261.89,260.13,258.52,256.63,254.83,252.99,251.17,249.36,247.45,245.52,243.48,241.54,239.5,237.64,235.88],"p95":[292.42,288.67,287.51,286.42,285.06,283.78,282.88,281.56,280.3,279.6,278.22,276.75,275.48,274.21,272.61,270.96,269.23,267.7,266.09,264.33,262.62,260.83,259.07,257.08,255.33,253.49,251.69,249.83,247.7,245.87,243.8,241.94],"eq7_err":[0.0,-2.11,-2.17,-2.27,-2.43,-2.64,-2.95,-3.37,-3.84,-4.23,-4.52,-4.78,-4.98,-5.17,-5.25,-5.24,-5.24,-5.19,-5.11,-5.0,-4.87,-4.72,-4.5,-4.26,-4.01,-3.74,-3.51,-3.23,-2.98,-2.71,-2.44,-2.19]},{"month":2,"n":565,"mean":[285.32,285.05,283.29,281.44,279.63,277.89,276.22,274.69,273.31,271.96,270.65,269.26,267.83,266.35,264.83,263.23,261.67,260.02,258.3,256.58,254.88,253.11,251.3,249.52,247.73,245.94,244.14,242.32,240.49,238.68,236.87,235.04],"sd":[7.59,4.9,4.85,4.92,5.01,5.09,5.17,5.33,5.48,5.57,5.65,5.7,5.69,5.75,5.75,5.73,5.69,5.64,5.61,5.6,5.6,5.56,5.54,5.45,5.34,5.23,5.12,5.0,4.88,4.72,4.57,4.46],"p05":[273.41,276.35,274.88,273.18,271.14,268.94,266.76,264.77,262.76,261.15,259.23,257.66,256.23,254.51,253.06,251.31,250.16,248.52,247.04,245.43,243.65,242.51,240.2,238.98,237.34,235.71,234.2,233.4,232.06,230.54,228.96,227.69],"p50":[285.14,285.2,283.73,281.94,280.16,278.67,276.97,275.34,274.15,272.85,271.49,270.18,268.93,267.32,265.8,264.26,262.73,261.01,259.14,257.38,255.64,253.82,252.0,250.23,248.42,246.49,244.71,242.87,240.87,239.01,237.16,235.22],"p95":[297.06,292.8,290.71,289.26,287.5,285.81,283.97,282.64,281.33,279.86,278.38,276.86,275.33,273.81,272.44,270.8,269.2,267.46,265.62,263.96,262.39,260.66,259.01,257.05,255.24,253.6,251.98,250.24,248.15,246.14,244.22,242.51],"eq7_err":[0.0,-1.38,-1.28,-1.08,-0.93,-0.84,-0.83,-0.96,-1.23,-1.54,-1.88,-2.15,-2.37,-2.55,-2.69,-2.74,-2.83,-2.84,-2.78,-2.71,-2.66,-2.55,-2.4,-2.27,-2.14,-2.01,-1.86,-1.69,-1.52,-1.37,-1.21,-1.04]},{"month":3,"n":614,"mean":[289.39,288.41,286.45,284.4,282.37,280.38,278.43,276.55,274.76,273.1,271.6,270.08,268.6,267.05,265.49,263.86,262.19,260.49,258.8,257.08,255.34,253.55,251.76,249.93,248.1,246.28,244.47,242.65,240.77,238.89,237.06,235.25],"sd":[7.94,5.71,5.65,5.64,5.59,5.56,5.53,5.5,5.49,5.49,5.5,5.49,5.48,5.48,5.46,5.43,5.41,5.42,5.4,5.4,5.38,5.38,5.35,5.29,5.24,5.17,5.09,4.98,4.9,4.77,4.6,4.37],"p05":[277.14,279.79,278.01,276.15,274.3,272.47,270.58,268.58,266.68,264.68,262.79,260.9,259.39,257.89,256.13,254.41,252.59,250.71,249.27,247.56,245.65,244.19,242.43,240.46,238.64,236.6,234.78,233.54,231.73,230.42,229.09,228.19],"p50":[288.9,287.86,285.83,283.87,281.88,279.85,277.88,276.17,274.58,273.04,271.64,270.13,268.64,267.1,265.67,264.11,262.57,260.91,259.38,257.65,256.02,254.24,252.46,250.67,248.8,246.92,245.07,243.23,241.37,239.53,237.61,235.67],"p95":[303.0,298.93,297.46,295.17,293.0,290.72,288.69,286.67,284.61,282.82,280.83,279.08,277.36,275.75,274.06,272.19,270.26,268.23,266.16,264.49,263.08,261.28,259.16,257.14,255.39,253.45,251.49,249.59,247.39,245.61,243.74,241.71],"eq7_err":[0.0,-0.77,-0.57,-0.27,0.01,0.24,0.44,0.57,0.61,0.51,0.26,0.02,-0.25,-0.46,-0.65,-0.77,-0.85,-0.91,-0.98,-1.01,-1.02,-0.98,-0.95,-0.87,-0.79,-0.73,-0.68,-0.61,-0.48,-0.36,-0.27,-0.22]},{"month":4,"n":584,"mean":[294.4,293.02,291.07,289.02,286.91,284.8,282.71,280.68,278.69,276.75,274.89,273.1,271.42,269.74,268.1,266.51,264.85,263.2,261.55,259.84,258.11,256.31,254.46,252.61,250.77,248.9,247.02,245.14,243.26,241.35,239.46,237.57],"sd":[8.03,5.42,5.21,5.12,5.06,5.01,4.96,4.89,4.82,4.77,4.72,4.69,4.69,4.63,4.6,4.6,4.64,4.63,4.55,4.54,4.53,4.52,4.49,4.48,4.42,4.39,4.39,4.32,4.2,4.1,3.97,3.83],"p05":[282.12,283.92,282.24,280.25,278.18,275.84,274.04,271.95,270.01,267.92,266.16,264.64,262.54,260.96,259.23,257.36,256.05,254.21,252.67,251.0,249.09,247.12,245.2,243.73,242.06,240.61,238.83,237.08,235.37,233.62,232.01,230.07],"p50":[294.14,293.11,291.3,289.26,287.13,285.01,283.01,281.03,279.11,277.17,275.61,273.75,272.19,270.5,268.92,267.35,265.73,264.13,262.3,260.53,258.91,257.14,255.31,253.45,251.61,249.66,247.72,245.79,243.77,241.93,239.93,238.03],"p95":[307.29,301.75,299.1,296.82,294.62,292.35,290.15,287.92,285.64,283.45,281.58,279.5,277.7,275.89,274.19,272.4,271.1,269.45,267.48,265.62,263.94,262.13,260.27,258.39,256.35,254.62,252.65,250.69,248.49,246.53,244.66,242.72],"eq7_err":[0.0,-0.49,-0.42,-0.25,-0.01,0.23,0.44,0.6,0.72,0.78,0.76,0.68,0.49,0.29,0.06,-0.23,-0.44,-0.67,-0.89,-1.05,-1.2,-1.27,-1.3,-1.32,-1.35,-1.36,-1.35,-1.35,-1.34,-1.31,-1.29,-1.27]},{"month":5,"n":607,"mean":[298.48,297.15,295.23,293.19,291.08,288.93,286.81,284.66,282.51,280.4,278.31,276.28,274.31,272.43,270.65,268.96,267.28,265.68,264.07,262.4,260.7,258.97,257.15,255.31,253.45,251.59,249.69,247.79,245.9,243.98,242.07,240.18],"sd":[8.07,5.72,5.45,5.32,5.22,5.11,4.96,4.84,4.73,4.61,4.51,4.41,4.33,4.23,4.14,4.04,3.99,3.98,3.98,3.98,4.01,4.02,4.0,3.97,3.91,3.9,3.91,3.89,3.84,3.8,3.73,3.62],"p05":[286.62,286.26,284.93,282.98,281.09,279.24,277.58,275.59,273.7,272.08,270.14,268.3,266.41,264.64,262.89,261.32,259.61,258.12,256.49,254.82,253.2,251.35,249.4,247.46,245.39,243.66,241.57,240.0,238.31,236.57,234.8,233.39],"p50":[297.82,297.61,295.69,293.94,292.0,289.7,287.5,285.31,283.18,281.04,278.91,276.87,274.9,273.19,271.3,269.6,267.92,266.32,264.67,262.98,261.33,259.59,257.67,255.83,254.0,252.23,250.36,248.36,246.53,244.56,242.64,240.68],"p95":[311.02,305.77,303.39,300.92,298.36,296.03,293.74,291.37,289.03,286.81,284.63,282.53,280.41,278.48,276.61,274.67,272.78,271.18,269.49,267.74,266.07,264.23,262.43,260.71,258.74,256.81,255.08,253.21,251.32,249.32,247.42,245.4],"eq7_err":[0.0,-0.64,-0.7,-0.62,-0.49,-0.31,-0.16,0.01,0.19,0.33,0.44,0.5,0.5,0.41,0.21,-0.07,-0.36,-0.74,-1.1,-1.4,-1.67,-1.91,-2.07,-2.2,-2.31,-2.43,-2.51,-2.58,-2.65,-2.71,-2.77,-2.85]},{"month":6,"n":592,"mean":[304.82,303.74,301.89,299.9,297.83,295.71,293.52,291.33,289.14,286.96,284.82,282.75,280.76,278.82,276.95,275.09,273.3,271.56,269.86,268.14,266.41,264.68,262.93,261.16,259.35,257.53,255.68,253.81,251.95,250.03,248.11,246.15],"sd":[9.66,5.06,4.66,4.46,4.29,4.16,4.06,3.95,3.86,3.79,3.72,3.61,3.51,3.44,3.34,3.3,3.23,3.17,3.14,3.1,3.05,3.07,3.05,3.05,3.05,3.05,3.04,3.05,3.09,3.12,3.13,3.14],"p05":[292.57,294.96,293.45,291.92,290.2,288.28,286.23,284.27,282.53,280.38,278.26,276.2,274.26,272.43,270.47,268.69,267.03,265.49,263.76,261.98,260.58,258.98,257.18,255.44,253.44,251.4,249.63,247.68,245.72,243.7,242.17,240.25],"p50":[304.89,303.81,302.24,300.44,298.35,296.2,294.05,291.78,289.58,287.48,285.3,283.14,281.15,279.28,277.39,275.59,273.84,272.04,270.19,268.57,266.82,265.07,263.38,261.58,259.74,257.94,256.14,254.13,252.24,250.28,248.49,246.52],"p95":[316.97,311.51,308.56,306.23,303.84,301.54,299.2,296.84,294.69,292.5,290.15,287.99,285.85,283.76,281.66,279.72,277.7,275.78,273.88,272.1,270.45,268.91,267.18,265.53,263.63,261.79,259.95,258.07,256.22,254.29,252.32,250.43],"eq7_err":[0.0,-1.05,-1.32,-1.46,-1.52,-1.52,-1.46,-1.39,-1.33,-1.28,-1.26,-1.32,-1.45,-1.63,-1.89,-2.15,-2.49,-2.88,-3.3,-3.71,-4.11,-4.5,-4.87,-5.23,-5.54,-5.85,-6.13,-6.38,-6.64,-6.86,-7.06,-7.23]},{"month":7,"n":638,"mean":[308.22,306.86,304.99,303.0,300.91,298.77,296.59,294.4,292.18,289.98,287.81,285.69,283.6,281.57,279.6,277.7,275.85,274.05,272.3,270.59,268.93,267.26,265.62,263.96,262.27,260.6,258.94,257.23,255.52,253.75,251.96,250.19],"sd":[7.32,4.18,3.63,3.34,3.14,2.96,2.82,2.71,2.63,2.53,2.43,2.32,2.22,2.13,2.03,1.94,1.83,1.73,1.71,1.75,1.73,1.78,1.84,1.88,1.94,2.01,2.09,2.18,2.27,2.33,2.39,2.43],"p05":[296.89,300.0,298.63,297.15,295.6,293.71,291.65,289.59,287.61,285.67,283.66,281.89,279.98,278.13,276.18,274.39,272.88,271.13,269.39,267.66,265.84,264.12,262.4,260.77,258.84,256.97,255.05,253.16,251.21,249.42,247.59,245.78],"p50":[307.77,307.1,305.31,303.33,301.13,298.92,296.74,294.48,292.25,290.01,287.79,285.63,283.61,281.64,279.7,277.71,275.84,274.0,272.27,270.62,268.99,267.29,265.71,264.14,262.44,260.77,259.19,257.58,255.91,254.13,252.33,250.54],"p95":[318.71,313.31,310.59,308.06,305.76,303.61,301.32,299.01,296.67,294.32,291.97,289.6,287.18,284.86,282.84,280.9,279.0,277.05,275.04,273.59,271.83,270.22,268.59,266.95,265.08,263.35,261.86,260.22,258.71,256.96,255.27,253.43],"eq7_err":[0.0,-0.85,-1.19,-1.41,-1.52,-1.59,-1.62,-1.63,-1.63,-1.63,-1.67,-1.76,-1.88,-2.05,-2.29,-2.6,-2.95,-3.36,-3.82,-4.31,-4.86,-5.4,-5.97,-6.51,-7.04,-7.57,-8.12,-8.62,-9.12,-9.55,-9.97,-10.41]},{"month":8,"n":616,"mean":[306.92,305.68,303.82,301.86,299.78,297.64,295.47,293.28,291.09,288.92,286.76,284.67,282.62,280.62,278.68,276.76,274.93,273.18,271.52,269.88,268.29,266.71,265.16,263.55,261.92,260.31,258.65,256.93,255.2,253.39,251.59,249.76],"sd":[7.65,4.2,3.72,3.43,3.19,2.99,2.82,2.67,2.53,2.41,2.31,2.2,2.11,2.04,1.96,1.93,1.89,1.87,1.86,1.84,1.81,1.8,1.75,1.76,1.79,1.79,1.86,1.92,1.96,1.98,2.02,2.04],"p05":[295.26,299.0,297.42,296.07,294.39,292.41,290.52,288.64,286.92,284.82,282.69,280.71,279.01,277.17,275.33,273.36,271.63,269.94,268.38,266.75,265.21,263.65,262.14,260.53,258.86,257.14,255.24,253.38,251.4,249.53,247.56,245.73],"p50":[305.83,305.77,304.25,302.37,300.19,297.93,295.71,293.48,291.17,288.91,286.69,284.67,282.6,280.63,278.73,276.79,274.98,273.21,271.63,269.96,268.33,266.81,265.26,263.58,261.96,260.38,258.78,257.12,255.4,253.54,251.82,250.03],"p95":[317.14,311.7,309.04,306.59,304.22,301.85,299.48,297.1,294.74,292.53,290.19,287.84,285.66,283.58,281.69,279.78,277.92,276.19,274.39,272.86,271.29,269.59,268.06,266.35,264.72,262.93,261.3,259.72,258.1,256.28,254.42,252.65],"eq7_err":[0.0,-0.94,-1.25,-1.47,-1.57,-1.6,-1.61,-1.6,-1.58,-1.59,-1.61,-1.69,-1.82,-1.99,-2.23,-2.48,-2.83,-3.26,-3.78,-4.31,-4.89,-5.49,-6.11,-6.68,-7.23,-7.8,-8.32,-8.77,-9.22,-9.58,-9.96,-10.31]},{"month":9,"n":597,"mean":[302.17,301.92,300.09,298.1,296.01,293.88,291.74,289.62,287.53,285.47,283.48,281.54,279.69,277.93,276.21,274.57,272.95,271.33,269.73,268.15,266.52,264.94,263.3,261.59,259.84,258.06,256.25,254.42,252.59,250.71,248.79,246.88],"sd":[9.05,4.97,4.67,4.51,4.37,4.27,4.16,4.05,3.9,3.78,3.64,3.46,3.29,3.16,3.08,2.99,2.92,2.88,2.84,2.83,2.82,2.82,2.81,2.81,2.79,2.79,2.8,2.81,2.83,2.84,2.86,2.87],"p05":[288.82,293.93,292.43,290.58,288.78,286.72,284.92,282.93,280.89,279.04,277.22,275.47,273.89,272.37,270.89,269.23,267.8,266.63,265.01,263.29,261.56,260.06,258.53,256.8,254.79,252.98,251.03,249.16,247.26,245.28,243.36,241.48],"p50":[301.69,302.05,300.5,298.47,296.38,294.19,291.98,289.89,287.67,285.66,283.58,281.66,279.75,278.14,276.37,274.75,273.14,271.46,269.92,268.45,266.82,265.21,263.65,261.92,260.11,258.35,256.55,254.75,252.97,251.1,249.14,247.21],"p95":[314.88,309.61,307.19,304.87,302.58,300.39,298.17,295.88,293.75,291.57,289.28,286.99,284.8,282.83,280.8,279.03,277.19,275.38,273.73,272.42,270.61,268.97,267.34,265.55,263.71,261.9,260.06,258.31,256.4,254.48,252.58,250.77],"eq7_err":[0.0,-1.81,-2.05,-2.11,-2.09,-2.02,-1.94,-1.88,-1.85,-1.86,-1.92,-2.05,-2.26,-2.56,-2.91,-3.33,-3.77,-4.21,-4.67,-5.15,-5.59,-6.06,-6.48,-6.84,-7.15,-7.44,-7.69,-7.91,-8.14,-8.32,-8.47,-8.63]},{"month":10,"n":619,"mean":[294.44,295.22,293.54,291.68,289.76,287.8,285.88,284.05,282.39,280.78,279.23,277.67,276.12,274.66,273.16,271.64,270.07,268.51,266.9,265.25,263.55,261.84,260.09,258.28,256.46,254.62,252.78,250.93,249.05,247.15,245.24,243.32],"sd":[11.72,5.43,5.32,5.28,5.25,5.19,5.11,4.98,4.84,4.72,4.55,4.43,4.26,4.12,4.05,3.93,3.84,3.81,3.8,3.77,3.72,3.69,3.65,3.66,3.64,3.62,3.59,3.56,3.54,3.51,3.4,3.31],"p05":[281.12,285.94,284.15,282.09,279.9,278.19,276.4,274.5,273.12,271.77,270.31,268.99,267.78,266.6,265.25,264.02,262.56,261.05,259.48,257.84,256.67,254.74,253.04,251.11,249.5,247.54,246.12,244.67,242.4,240.63,238.73,237.17],"p50":[294.65,295.41,293.86,292.08,290.21,288.36,286.47,284.91,283.22,281.75,280.16,278.49,276.67,275.2,273.63,272.18,270.56,268.92,267.43,265.76,264.15,262.39,260.56,258.7,256.82,255.18,253.33,251.46,249.69,247.78,245.76,243.82],"p95":[308.04,303.54,301.6,299.8,297.68,295.54,293.56,291.24,288.88,287.0,285.4,283.51,281.7,280.04,278.31,276.76,275.11,273.49,271.87,270.43,268.7,266.83,265.09,263.36,261.37,259.5,257.5,255.56,253.59,251.66,249.6,247.58],"eq7_err":[0.0,-2.66,-2.86,-2.87,-2.83,-2.74,-2.7,-2.75,-2.95,-3.22,-3.54,-3.86,-4.19,-4.6,-4.97,-5.33,-5.63,-5.95,-6.22,-6.44,-6.62,-6.78,-6.91,-6.98,-7.03,-7.07,-7.11,-7.13,-7.12,-7.1,-7.06,-7.02]},{"month":11,"n":598,"mean":[287.51,288.57,287.03,285.47,283.9,282.3,280.83,279.45,278.15,276.84,275.55,274.21,272.73,271.26,269.72,268.15,266.56,264.99,263.35,261.66,259.93,258.19,256.41,254.63,252.84,251.02,249.18,247.32,245.45,243.57,241.69,239.8],"sd":[8.45,4.88,4.82,5.0,5.14,5.17,5.16,5.12,5.1,5.06,4.98,4.88,4.82,4.81,4.83,4.79,4.8,4.75,4.75,4.72,4.7,4.69,4.68,4.67,4.64,4.6,4.51,4.41,4.31,4.21,4.13,4.05],"p05":[273.77,280.87,279.16,277.37,275.37,273.46,271.67,270.0,268.22,266.95,265.79,264.65,262.93,261.74,260.13,258.95,257.07,255.62,254.4,252.83,251.61,249.8,248.26,246.25,244.49,242.8,241.1,239.66,237.97,236.25,234.62,232.71],"p50":[288.29,288.46,286.91,285.35,284.04,282.64,281.53,280.5,279.16,277.76,276.4,275.18,273.54,272.13,270.64,269.0,267.31,265.61,263.96,262.29,260.49,258.82,257.07,255.29,253.46,251.74,249.87,247.9,246.11,244.2,242.27,240.19],"p95":[300.28,296.35,294.49,292.95,291.49,289.86,288.25,286.48,285.01,283.38,282.16,280.86,279.01,277.61,276.22,274.39,272.71,271.15,269.55,267.94,266.19,264.62,262.98,261.18,259.35,257.66,255.83,253.96,252.23,250.21,248.26,246.31],"eq7_err":[0.0,-2.77,-2.94,-3.08,-3.23,-3.34,-3.57,-3.9,-4.31,-4.7,-5.13,-5.49,-5.72,-5.96,-6.13,-6.27,-6.38,-6.52,-6.6,-6.61,-6.59,-6.55,-6.49,-6.41,-6.33,-6.22,-6.09,-5.93,-5.77,-5.6,-5.43,-5.24]},{"month":12,"n":615,"mean":[283.03,284.05,282.71,281.42,280.2,279.02,277.86,276.71,275.63,274.44,273.16,271.75,270.26,268.78,267.26,265.68,264.08,262.42,260.73,259.04,257.37,255.63,253.87,252.07,250.26,248.4,246.52,244.64,242.74,240.84,238.95,237.06],"sd":[7.31,3.8,3.88,4.22,4.52,4.73,4.89,4.99,5.02,4.94,4.9,4.84,4.77,4.71,4.68,4.66,4.63,4.64,4.62,4.58,4.56,4.52,4.46,4.42,4.4,4.39,4.4,4.39,4.34,4.29,4.22,4.17],"p05":[271.43,277.87,276.36,274.48,272.68,270.88,269.32,267.53,266.22,265.27,264.06,262.77,261.25,259.92,258.16,256.92,255.02,253.21,251.35,250.09,248.16,246.59,245.23,243.69,241.95,240.53,238.55,236.55,235.01,233.18,231.39,229.83],"p50":[283.53,284.06,282.47,281.37,280.22,279.16,278.13,277.28,276.16,274.93,273.84,272.52,271.04,269.46,268.09,266.5,264.97,263.36,261.55,259.84,258.28,256.52,254.59,252.87,251.0,249.1,247.18,245.33,243.35,241.28,239.41,237.64],"p95":[293.88,290.4,289.06,288.27,287.54,286.28,285.38,284.13,282.7,281.44,280.03,278.53,276.95,275.19,273.56,271.79,270.3,268.44,266.67,264.77,263.22,261.37,259.53,257.61,255.89,254.11,252.34,250.52,248.63,246.6,244.82,242.82],"eq7_err":[0.0,-2.63,-2.89,-3.19,-3.57,-3.99,-4.43,-4.89,-5.4,-5.82,-6.13,-6.32,-6.44,-6.55,-6.64,-6.66,-6.65,-6.59,-6.5,-6.42,-6.34,-6.21,-6.05,-5.85,-5.63,-5.38,-5.09,-4.82,-4.52,-4.22,-3.93,-3.64]}]},"lapse":{"edw-nid":[{"month":1,"n":72,"L_mean":-5.986,"L_sd":0.626,"L_p05":-7.17,"L_p95":-5.077,"L_eq7":-5.946,"L_isa":-6.5},{"month":2,"n":110,"L_mean":-6.28,"L_sd":0.723,"L_p05":-7.424,"L_p95":-5.181,"L_eq7":-6.286,"L_isa":-6.5},{"month":3,"n":183,"L_mean":-6.537,"L_sd":0.588,"L_p05":-7.446,"L_p95":-5.612,"L_eq7":-6.715,"L_isa":-6.5},{"month":4,"n":125,"L_mean":-6.721,"L_sd":0.641,"L_p05":-7.781,"L_p95":-5.638,"L_eq7":-7.119,"L_isa":-6.5},{"month":5,"n":92,"L_mean":-6.968,"L_sd":0.681,"L_p05":-7.943,"L_p95":-5.89,"L_eq7":-7.68,"L_isa":-6.5},{"month":6,"n":86,"L_mean":-6.968,"L_sd":0.776,"L_p05":-8.04,"L_p95":-5.57,"L_eq7":-8.118,"L_isa":-6.5},{"month":7,"n":118,"L_mean":-7.135,"L_sd":0.609,"L_p05":-8.062,"L_p95":-6.167,"L_eq7":-8.547,"L_isa":-6.5},{"month":8,"n":114,"L_mean":-6.982,"L_sd":0.615,"L_p05":-7.863,"L_p95":-5.894,"L_eq7":-8.2,"L_isa":-6.5},{"month":9,"n":131,"L_mean":-6.534,"L_sd":0.668,"L_p05":-7.533,"L_p95":-5.489,"L_eq7":-7.815,"L_isa":-6.5},{"month":10,"n":109,"L_mean":-6.289,"L_sd":0.718,"L_p05":-7.389,"L_p95":-5.146,"L_eq7":-7.058,"L_isa":-6.5},{"month":11,"n":103,"L_mean":-5.989,"L_sd":0.593,"L_p05":-6.809,"L_p95":-4.831,"L_eq7":-6.276,"L_isa":-6.5},{"month":12,"n":88,"L_mean":-5.976,"L_sd":0.623,"L_p05":-6.999,"L_p95":-5.063,"L_eq7":-6.381,"L_isa":-6.5}],"edw":[{"month":1,"n":48,"L_mean":-5.919,"L_sd":0.626,"L_p05":-7.137,"L_p95":-4.994,"L_eq7":-6.012,"L_isa":-6.5},{"month":2,"n":74,"L_mean":-6.259,"L_sd":0.733,"L_p05":-7.41,"L_p95":-5.149,"L_eq7":-6.227,"L_isa":-6.5},{"month":3,"n":135,"L_mean":-6.486,"L_sd":0.536,"L_p05":-7.352,"L_p95":-5.582,"L_eq7":-6.716,"L_isa":-6.5},{"month":4,"n":91,"L_mean":-6.716,"L_sd":0.644,"L_p05":-7.748,"L_p95":-5.567,"L_eq7":-7.197,"L_isa":-6.5},{"month":5,"n":56,"L_mean":-6.851,"L_sd":0.704,"L_p05":-7.942,"L_p95":-5.727,"L_eq7":-7.66,"L_isa":-6.5},{"month":6,"n":54,"L_mean":-6.804,"L_sd":0.726,"L_p05":-7.821,"L_p95":-5.528,"L_eq7":-7.941,"L_isa":-6.5},{"month":7,"n":78,"L_mean":-7.079,"L_sd":0.515,"L_p05":-7.831,"L_p95":-6.23,"L_eq7":-8.697,"L_isa":-6.5},{"month":8,"n":66,"L_mean":-6.894,"L_sd":0.587,"L_p05":-7.824,"L_p95":-5.875,"L_eq7":-8.202,"L_isa":-6.5},{"month":9,"n":103,"L_mean":-6.468,"L_sd":0.655,"L_p05":-7.486,"L_p95":-5.466,"L_eq7":-7.805,"L_isa":-6.5},{"month":10,"n":74,"L_mean":-6.304,"L_sd":0.621,"L_p05":-7.348,"L_p95":-5.229,"L_eq7":-7.097,"L_isa":-6.5},{"month":11,"n":71,"L_mean":-5.931,"L_sd":0.571,"L_p05":-6.772,"L_p95":-4.72,"L_eq7":-6.365,"L_isa":-6.5},{"month":12,"n":65,"L_mean":-6.012,"L_sd":0.646,"L_p05":-7.038,"L_p95":-4.986,"L_eq7":-6.464,"L_isa":-6.5}],"nid":[{"month":1,"n":24,"L_mean":-6.122,"L_sd":0.605,"L_p05":-7.199,"L_p95":-5.179,"L_eq7":-5.813,"L_isa":-6.5},{"month":2,"n":36,"L_mean":-6.324,"L_sd":0.702,"L_p05":-7.438,"L_p95":-5.277,"L_eq7":-6.407,"L_isa":-6.5},{"month":3,"n":48,"L_mean":-6.681,"L_sd":0.694,"L_p05":-7.862,"L_p95":-5.776,"L_eq7":-6.712,"L_isa":-6.5},{"month":4,"n":34,"L_mean":-6.735,"L_sd":0.633,"L_p05":-7.676,"L_p95":-5.779,"L_eq7":-6.909,"L_isa":-6.5},{"month":5,"n":36,"L_mean":-7.149,"L_sd":0.6,"L_p05":-7.915,"L_p95":-6.027,"L_eq7":-7.711,"L_isa":-6.5},{"month":6,"n":32,"L_mean":-7.245,"L_sd":0.779,"L_p05":-8.105,"L_p95":-5.754,"L_eq7":-8.416,"L_isa":-6.5},{"month":7,"n":40,"L_mean":-7.246,"L_sd":0.747,"L_p05":-8.648,"L_p95":-6.102,"L_eq7":-8.255,"L_isa":-6.5},{"month":8,"n":48,"L_mean":-7.102,"L_sd":0.631,"L_p05":-7.952,"L_p95":-5.914,"L_eq7":-8.197,"L_isa":-6.5},{"month":9,"n":28,"L_mean":-6.775,"L_sd":0.66,"L_p05":-7.535,"L_p95":-5.718,"L_eq7":-7.853,"L_isa":-6.5},{"month":10,"n":35,"L_mean":-6.258,"L_sd":0.888,"L_p05":-7.449,"L_p95":-4.884,"L_eq7":-6.976,"L_isa":-6.5},{"month":11,"n":32,"L_mean":-6.117,"L_sd":0.619,"L_p05":-7.148,"L_p95":-5.28,"L_eq7":-6.079,"L_isa":-6.5},{"month":12,"n":23,"L_mean":-5.873,"L_sd":0.541,"L_p05":-6.614,"L_p95":-5.093,"L_eq7":-6.145,"L_isa":-6.5}],"vef":[{"month":1,"n":618,"L_mean":-6.233,"L_sd":0.629,"L_p05":-7.228,"L_p95":-5.195,"L_eq7":-6.369,"L_isa":-6.5},{"month":2,"n":565,"L_mean":-6.501,"L_sd":0.643,"L_p05":-7.575,"L_p95":-5.367,"L_eq7":-6.622,"L_isa":-6.5},{"month":3,"n":614,"L_mean":-6.909,"L_sd":0.655,"L_p05":-7.93,"L_p95":-5.767,"L_eq7":-7.015,"L_isa":-6.5},{"month":4,"n":584,"L_mean":-7.233,"L_sd":0.632,"L_p05":-8.26,"L_p95":-6.13,"L_eq7":-7.498,"L_isa":-6.5},{"month":5,"n":607,"L_mean":-7.475,"L_sd":0.689,"L_p05":-8.537,"L_p95":-6.285,"L_eq7":-7.891,"L_isa":-6.5},{"month":6,"n":592,"L_mean":-7.598,"L_sd":0.649,"L_p05":-8.592,"L_p95":-6.474,"L_eq7":-8.502,"L_isa":-6.5},{"month":7,"n":638,"L_mean":-7.555,"L_sd":0.609,"L_p05":-8.497,"L_p95":-6.519,"L_eq7":-8.83,"L_isa":-6.5},{"month":8,"n":616,"L_mean":-7.417,"L_sd":0.578,"L_p05":-8.253,"L_p95":-6.443,"L_eq7":-8.705,"L_isa":-6.5},{"month":9,"n":597,"L_mean":-7.165,"L_sd":0.62,"L_p05":-8.128,"L_p95":-6.098,"L_eq7":-8.247,"L_isa":-6.5},{"month":10,"n":619,"L_mean":-6.689,"L_sd":0.764,"L_p05":-7.853,"L_p95":-5.384,"L_eq7":-7.501,"L_isa":-6.5},{"month":11,"n":598,"L_mean":-6.333,"L_sd":0.612,"L_p05":-7.253,"L_p95":-5.238,"L_eq7":-6.833,"L_isa":-6.5},{"month":12,"n":615,"L_mean":-6.172,"L_sd":0.614,"L_p05":-7.163,"L_p95":-5.115,"L_eq7":-6.401,"L_isa":-6.5}]}},"soundings":{"EDW":[{"id":"EDW-20260722-17Z","station":"EDW","year":2026,"month":7,"day":22,"hour":17,"label":"2026-07-22 17Z","t":[310.04,303.68,301.27,298.85,296.66,294.73,292.93,291.25,289.58,287.9,286.23,284.48,282.71,281.17,279.0,277.68,276.05,274.65,272.99,270.86,270.45,268.39,267.97,266.05,264.13,262.21,260.29,258.46,256.92,254.76,253.18,251.91],"L_fit":-6.811,"L_eq7":-9.006},{"id":"EDW-20260717-19Z","station":"EDW","year":2026,"month":7,"day":17,"hour":19,"label":"2026-07-17 19Z","t":[313.01,304.46,302.19,299.91,297.56,295.11,292.66,291.03,289.43,287.84,285.65,283.83,282.11,280.38,279.23,277.32,275.31,274.28,272.12,270.23,268.93,267.29,265.29,263.05,261.25,259.96,259.61,258.28,256.52,254.3,252.09,250.3],"L_fit":-7.172,"L_eq7":-9.293},{"id":"EDW-20260714-17Z","station":"EDW","year":2026,"month":7,"day":14,"hour":17,"label":"2026-07-14 17Z","t":[306.33,301.86,299.38,297.9,295.94,293.92,291.91,289.9,287.89,285.88,283.98,282.33,280.54,278.61,276.7,275.44,273.92,273.11,273.04,271.16,269.25,267.5,265.5,263.49,262.51,261.82,260.59,259.01,258.63,256.73,254.61,252.49],"L_fit":-6.448,"L_eq7":-8.648},{"id":"EDW-20260702-00Z","station":"EDW","year":2026,"month":7,"day":2,"hour":0,"label":"2026-07-02 00Z","t":[363.45,299.04,296.54,296.63,294.5,292.22,289.95,288.07,286.27,284.47,282.67,280.89,279.05,277.19,275.33,273.46,271.6,269.8,268.15,266.5,264.85,263.6,262.46,260.73,259.01,257.28,255.55,253.44,251.36,249.31,247.26,245.22],"L_fit":-8.488,"L_eq7":-14.156},{"id":"EDW-20260701-19Z","station":"EDW","year":2026,"month":7,"day":1,"hour":19,"label":"2026-07-01 19Z","t":[321.92,299.17,296.82,294.47,291.94,290.27,288.61,287.04,285.77,284.51,283.05,281.03,279.02,277.0,275.0,273.04,271.09,269.19,267.6,266.0,264.4,262.87,261.44,260.01,258.57,256.71,254.72,252.73,250.67,248.57,246.48,244.38],"L_fit":-7.539,"L_eq7":-10.151},{"id":"EDW-20260612-20Z","station":"EDW","year":2026,"month":6,"day":12,"hour":20,"label":"2026-06-12 20Z","t":[317.74,306.01,303.75,301.49,299.29,297.13,294.97,292.81,290.65,288.49,286.33,284.51,282.72,280.93,279.14,277.35,275.55,273.76,271.97,270.18,268.39,266.6,264.78,262.95,261.13,259.31,257.49,255.67,253.8,251.8,249.8,247.79],"L_fit":-7.831,"L_eq7":-9.748},{"id":"EDW-20260601-17Z","station":"EDW","year":2026,"month":6,"day":1,"hour":17,"label":"2026-06-01 17Z","t":[300.08,295.29,293.35,293.44,292.45,290.46,288.22,285.99,283.75,281.52,279.48,279.33,277.65,275.97,274.29,272.61,270.93,269.25,267.57,265.89,264.08,262.01,260.15,258.3,256.44,254.58,252.53,250.4,248.29,246.29,244.36,242.17],"L_fit":-7.116,"L_eq7":-8.046},{"id":"EDW-20260326-14Z","station":"EDW","year":2026,"month":3,"day":26,"hour":14,"label":"2026-03-26 14Z","t":[277.99,293.25,291.63,291.83,292.86,293.06,291.69,289.8,287.91,286.02,284.13,281.96,279.79,277.62,275.45,273.28,271.11,268.94,267.0,265.29,264.11,262.83,261.25,259.69,258.16,256.64,254.76,252.64,250.51,248.37,246.22,244.08],"L_fit":-6.5,"L_eq7":-5.915},{"id":"EDW-20260325-00Z","station":"EDW","year":2026,"month":3,"day":25,"hour":0,"label":"2026-03-25 00Z","t":[308.66,302.03,299.74,297.46,295.11,292.9,291.26,289.61,287.97,286.32,284.68,282.9,281.12,280.13,278.21,276.29,274.37,272.55,270.74,268.93,267.11,265.26,262.99,260.98,259.24,257.51,255.77,254.03,252.23,250.16,247.97,245.78],"L_fit":-7.393,"L_eq7":-8.873},{"id":"EDW-20260324-18Z","station":"EDW","year":2026,"month":3,"day":24,"hour":18,"label":"2026-03-24 18Z","t":[303.38,296.38,294.31,294.03,292.67,291.62,290.56,289.48,287.93,286.72,285.5,283.96,282.18,280.41,278.63,276.85,275.07,273.29,271.52,269.74,267.61,265.42,263.17,261.09,259.58,258.06,256.54,254.73,252.53,250.43,248.32,246.21],"L_fit":-6.855,"L_eq7":-8.364},{"id":"EDW-20260324-00Z","station":"EDW","year":2026,"month":3,"day":24,"hour":0,"label":"2026-03-24 00Z","t":[313.44,301.9,299.34,296.78,294.43,292.48,290.67,289.03,288.44,286.99,285.55,283.54,281.53,279.52,277.52,275.51,273.65,272.83,272.07,269.98,267.86,265.74,263.68,261.62,259.56,257.5,255.59,253.9,252.14,251.15,250.12,248.22],"L_fit":-7.315,"L_eq7":-9.333},{"id":"EDW-20260323-18Z","station":"EDW","year":2026,"month":3,"day":23,"hour":18,"label":"2026-03-23 18Z","t":[303.57,295.9,294.39,292.89,292.58,291.13,289.68,289.81,288.67,287.19,285.43,283.51,281.58,279.65,277.72,275.79,273.86,271.93,270.0,268.07,266.14,264.24,262.99,262.38,260.87,258.84,256.82,254.79,252.72,250.56,248.4,246.24],"L_fit":-6.796,"L_eq7":-8.382},{"id":"EDW-20260320-15Z","station":"EDW","year":2026,"month":3,"day":20,"hour":15,"label":"2026-03-20 15Z","t":[276.49,297.43,297.09,296.75,295.98,294.56,293.14,291.73,290.31,288.89,287.48,285.63,283.66,281.68,279.71,277.73,275.76,273.78,271.81,269.84,267.86,265.89,263.91,261.93,259.95,257.97,255.98,254.0,252.01,249.94,247.87,245.8],"L_fit":-6.656,"L_eq7":-5.77},{"id":"EDW-20260320-12Z","station":"EDW","year":2026,"month":3,"day":20,"hour":12,"label":"2026-03-20 12Z","t":[275.84,295.31,298.64,297.85,295.95,293.91,291.88,289.85,288.73,288.31,287.69,286.08,284.08,282.08,280.08,278.08,276.08,274.09,272.09,270.09,268.09,266.09,264.04,262.06,260.17,258.29,256.41,254.53,252.62,250.51,248.39,246.28],"L_fit":-6.505,"L_eq7":-5.708},{"id":"EDW-20260319-14Z","station":"EDW","year":2026,"month":3,"day":19,"hour":14,"label":"2026-03-19 14Z","t":[276.36,294.47,296.39,295.51,293.78,292.12,290.67,290.2,289.73,288.76,287.8,286.79,284.77,282.71,280.64,278.58,276.52,274.46,272.4,270.33,268.27,266.21,264.53,263.2,261.32,259.04,256.76,254.47,252.57,250.66,248.76,246.85],"L_fit":-6.288,"L_eq7":-5.758},{"id":"EDW-20260318-00Z","station":"EDW","year":2026,"month":3,"day":18,"hour":0,"label":"2026-03-18 00Z","t":[307.18,298.45,297.09,295.73,293.94,291.58,290.29,289.44,287.56,285.69,283.82,282.51,282.63,282.74,280.73,278.72,276.71,274.7,272.7,270.69,268.78,267.32,266.32,264.37,262.42,260.46,258.51,256.56,254.62,252.7,250.37,248.03],"L_fit":-6.666,"L_eq7":-8.73},{"id":"EDW-20260317-14Z","station":"EDW","year":2026,"month":3,"day":17,"hour":14,"label":"2026-03-17 14Z","t":[275.4,294.54,293.92,293.3,292.25,290.66,289.07,287.48,285.89,284.3,282.71,281.38,280.09,278.79,277.49,276.19,274.89,273.59,272.29,270.99,269.69,268.36,266.34,264.32,262.3,260.28,258.27,256.25,254.19,251.99,249.79,247.59],"L_fit":-5.632,"L_eq7":-5.666},{"id":"EDW-20260313-00Z","station":"EDW","year":2026,"month":3,"day":13,"hour":0,"label":"2026-03-13 00Z","t":[301.29,298.19,295.65,293.12,290.61,288.21,286.03,283.84,282.06,280.88,280.58,280.48,278.75,277.01,275.28,273.55,271.81,270.08,268.34,266.61,264.88,262.85,260.69,258.54,256.39,254.23,252.08,249.92,247.82,245.79,243.75,241.96],"L_fit":-7.154,"L_eq7":-8.162},{"id":"EDW-20260312-18Z","station":"EDW","year":2026,"month":3,"day":12,"hour":18,"label":"2026-03-12 18Z","t":[283.5,288.55,290.69,289.64,287.77,285.84,283.91,281.98,280.05,281.34,280.21,278.96,277.68,276.4,275.11,273.57,271.67,269.76,267.86,265.95,264.05,262.14,260.26,258.36,256.17,253.98,251.79,249.6,247.4,245.2,243.0,240.77],"L_fit":-6.309,"L_eq7":-6.446},{"id":"EDW-20260309-18Z","station":"EDW","year":2026,"month":3,"day":9,"hour":18,"label":"2026-03-09 18Z","t":[296.47,287.63,289.04,288.01,286.25,284.41,282.56,280.72,278.88,277.03,275.0,272.85,271.59,270.22,268.68,267.14,265.6,264.06,262.37,260.51,258.65,256.52,254.52,253.16,251.8,250.26,248.26,246.29,244.38,242.48,240.57,238.67],"L_fit":-6.914,"L_eq7":-7.697},{"id":"EDW-20260305-18Z","station":"EDW","year":2026,"month":3,"day":5,"hour":18,"label":"2026-03-05 18Z","t":[289.66,283.94,281.86,279.78,277.53,275.16,272.8,271.05,269.31,267.99,267.57,267.11,265.95,264.79,263.62,261.94,259.75,257.56,255.37,253.18,251.05,251.12,249.73,248.34,246.94,245.55,244.16,242.62,241.0,239.35,237.11,234.87],"L_fit":-6.298,"L_eq7":-7.041},{"id":"EDW-20260304-18Z","station":"EDW","year":2026,"month":3,"day":4,"hour":18,"label":"2026-03-04 18Z","t":[292.88,290.17,287.58,285.9,284.01,282.35,281.35,280.72,280.95,279.42,277.86,276.2,274.54,272.88,270.88,268.88,266.87,264.87,262.86,260.86,258.85,256.99,254.8,252.51,251.1,249.88,247.95,246.0,243.85,242.19,240.25,238.42],"L_fit":-6.898,"L_eq7":-7.351},{"id":"EDW-20260303-20Z","station":"EDW","year":2026,"month":3,"day":3,"hour":20,"label":"2026-03-03 20Z","t":[291.72,288.67,286.6,284.73,282.95,281.26,279.57,277.88,276.44,275.59,276.33,274.69,273.05,271.41,270.11,268.98,267.85,266.73,265.6,264.47,262.41,260.27,258.07,255.87,253.67,251.47,249.27,247.07,244.83,242.58,240.33,238.03],"L_fit":-6.319,"L_eq7":-7.239},{"id":"EDW-20260227-21Z","station":"EDW","year":2026,"month":2,"day":27,"hour":21,"label":"2026-02-27 21Z","t":[299.36,294.12,292.64,291.43,290.16,289.07,288.59,287.98,286.34,284.05,281.75,279.96,278.48,277.02,275.15,273.17,271.49,269.82,268.14,266.46,264.84,263.3,261.34,259.42,258.09,256.67,254.38,252.36,250.48,248.42,246.27,244.38],"L_fit":-6.75,"L_eq7":-7.976},{"id":"EDW-20260227-18Z","station":"EDW","year":2026,"month":2,"day":27,"hour":18,"label":"2026-02-27 18Z","t":[291.09,289.76,290.37,290.9,289.59,288.08,286.57,285.78,285.15,283.66,281.98,280.06,278.11,276.16,274.97,273.44,271.97,270.62,268.67,266.72,265.45,263.75,262.26,260.29,258.33,256.37,254.4,252.44,250.66,248.77,246.87,244.81],"L_fit":-6.25,"L_eq7":-7.178},{"id":"EDW-20260226-18Z","station":"EDW","year":2026,"month":2,"day":26,"hour":18,"label":"2026-02-26 18Z","t":[295.21,289.48,288.35,288.52,288.44,287.63,286.81,285.99,284.45,282.6,280.76,278.92,277.48,276.73,275.28,273.67,272.12,270.57,268.91,266.85,264.79,262.75,260.83,259.5,257.69,255.76,253.83,251.92,250.02,248.2,246.76,245.31],"L_fit":-6.279,"L_eq7":-7.575},{"id":"EDW-20260212-18Z","station":"EDW","year":2026,"month":2,"day":12,"hour":18,"label":"2026-02-12 18Z","t":[281.8,280.19,280.23,279.65,278.78,277.44,275.93,274.42,272.91,271.39,269.55,267.8,265.51,263.22,261.2,259.07,257.09,255.12,253.15,251.63,249.83,248.11,246.38,244.57,242.57,240.57,238.58,236.7,234.9,233.09,231.29,229.49],"L_fit":-7.143,"L_eq7":-6.282},{"id":"EDW-20260210-00Z","station":"EDW","year":2026,"month":2,"day":10,"hour":0,"label":"2026-02-10 00Z","t":[294.12,290.23,288.19,286.16,284.08,281.96,280.91,279.93,278.43,277.43,276.68,275.66,273.98,272.16,270.43,268.7,266.79,264.58,262.37,260.17,258.89,256.97,254.67,252.87,251.27,249.04,249.55,248.1,246.07,244.05,242.03,240.0],"L_fit":-6.659,"L_eq7":-7.47},{"id":"EDW-20260209-20Z","station":"EDW","year":2026,"month":2,"day":9,"hour":20,"label":"2026-02-09 20Z","t":[293.26,287.88,286.64,285.75,284.74,283.63,283.51,281.65,279.9,278.64,277.33,275.79,274.21,272.41,270.62,268.82,266.86,265.25,264.59,262.68,261.02,259.23,257.03,254.82,252.62,251.11,249.66,248.34,246.77,244.83,242.73,240.62],"L_fit":-6.474,"L_eq7":-7.388},{"id":"EDW-20260129-21Z","station":"EDW","year":2026,"month":1,"day":29,"hour":21,"label":"2026-01-29 21Z","t":[290.36,287.03,285.09,283.16,282.22,280.87,279.52,278.3,277.89,277.67,275.73,274.09,272.48,270.87,269.25,267.64,265.84,263.55,261.31,259.56,257.69,255.58,253.46,251.35,249.23,247.11,245.0,242.88,240.64,238.39,236.13,234.35],"L_fit":-6.997,"L_eq7":-7.108},{"id":"EDW-20251021-16Z","station":"EDW","year":2025,"month":10,"day":21,"hour":16,"label":"2025-10-21 16Z","t":[285.23,289.67,290.08,290.5,290.2,288.85,287.5,286.15,284.8,283.44,282.09,280.29,278.43,276.57,274.72,272.86,271.0,269.15,267.29,265.43,263.57,261.71,259.83,257.94,256.06,254.17,252.28,250.4,248.52,246.66,244.79,242.93],"L_fit":-6.527,"L_eq7":-6.613},{"id":"EDW-20251017-18Z","station":"EDW","year":2025,"month":10,"day":17,"hour":18,"label":"2025-10-17 18Z","t":[289.62,287.19,287.07,286.04,284.05,282.03,280.62,281.42,280.64,279.4,278.17,276.97,277.28,277.08,275.12,273.16,271.2,269.23,267.27,265.31,263.35,261.33,259.44,258.33,256.78,254.9,253.02,251.14,249.2,247.16,244.96,242.77],"L_fit":-5.868,"L_eq7":-7.037},{"id":"EDW-20251017-15Z","station":"EDW","year":2025,"month":10,"day":17,"hour":15,"label":"2025-10-17 15Z","t":[273.38,286.87,287.94,286.3,284.37,282.2,280.03,277.86,280.57,279.03,277.5,276.0,274.51,273.02,273.35,272.12,270.89,268.95,266.84,264.74,262.8,261.34,259.95,258.55,256.85,254.85,252.85,250.85,248.75,246.61,244.47,242.33],"L_fit":-5.468,"L_eq7":-5.47},{"id":"EDW-20251015-18Z","station":"EDW","year":2025,"month":10,"day":15,"hour":18,"label":"2025-10-15 18Z","t":[286.56,282.16,280.05,279.52,278.1,276.47,274.85,273.31,272.33,272.13,271.2,271.28,270.26,268.7,267.13,265.43,263.68,261.93,260.18,258.42,256.34,254.16,251.98,249.8,247.62,245.44,243.26,241.12,239.03,236.94,234.85,234.91],"L_fit":-6.42,"L_eq7":-6.741},{"id":"EDW-20251015-15Z","station":"EDW","year":2025,"month":10,"day":15,"hour":15,"label":"2025-10-15 15Z","t":[280.36,281.95,279.78,277.62,277.76,275.77,274.9,274.55,273.0,271.09,270.19,270.38,268.82,267.26,265.7,264.14,262.58,261.02,259.46,257.9,256.16,253.93,251.74,249.57,247.4,245.24,243.07,240.95,238.87,236.8,234.73,234.98],"L_fit":-6.235,"L_eq7":-6.144},{"id":"EDW-20251008-18Z","station":"EDW","year":2025,"month":10,"day":8,"hour":18,"label":"2025-10-08 18Z","t":[293.93,292.17,291.39,290.53,289.64,288.7,287.28,285.86,284.45,283.03,281.6,280.05,278.49,276.94,275.39,273.83,272.28,270.73,269.17,267.62,265.96,264.05,262.21,260.37,258.54,256.7,254.86,253.03,251.08,249.05,247.01,244.98],"L_fit":-6.332,"L_eq7":-7.452},{"id":"EDW-20251008-15Z","station":"EDW","year":2025,"month":10,"day":8,"hour":15,"label":"2025-10-08 15Z","t":[290.14,290.22,291.89,292.53,290.71,288.77,286.84,284.9,283.43,282.42,281.32,280.28,278.94,277.15,275.36,273.57,271.78,271.19,269.41,267.52,265.64,263.8,262.02,260.24,258.46,256.69,254.91,253.13,251.18,249.11,247.04,244.97],"L_fit":-6.239,"L_eq7":-7.087},{"id":"EDW-20250930-18Z","station":"EDW","year":2025,"month":9,"day":30,"hour":18,"label":"2025-09-30 18Z","t":[297.87,290.32,288.4,286.49,287.22,285.57,283.93,283.07,281.5,279.93,278.38,277.03,277.69,276.0,274.21,272.46,270.85,269.25,269.43,268.14,266.84,265.26,263.24,261.74,260.97,259.85,257.95,256.05,254.0,251.83,249.67,247.51],"L_fit":-5.524,"L_eq7":-7.832},{"id":"EDW-20250930-15Z","station":"EDW","year":2025,"month":9,"day":30,"hour":15,"label":"2025-09-30 15Z","t":[287.6,287.73,287.09,285.57,286.28,285.23,283.92,283.23,281.55,280.29,278.52,277.73,276.28,275.72,274.36,272.69,271.01,269.21,267.38,266.3,265.76,264.62,262.79,260.64,258.48,257.15,256.35,255.36,253.33,251.4,249.48,247.55],"L_fit":-5.351,"L_eq7":-6.841},{"id":"EDW-20250911-18Z","station":"EDW","year":2025,"month":9,"day":11,"hour":18,"label":"2025-09-11 18Z","t":[296.23,291.34,289.07,286.8,286.91,285.72,284.52,283.32,282.13,280.93,279.72,278.45,277.19,275.92,274.65,273.03,271.2,269.36,267.52,265.68,263.84,261.96,260.21,258.47,256.72,254.98,253.23,251.49,249.64,247.73,245.83,243.92],"L_fit":-6.296,"L_eq7":-7.674},{"id":"EDW-20250910-18Z","station":"EDW","year":2025,"month":9,"day":10,"hour":18,"label":"2025-09-10 18Z","t":[303.13,291.81,289.5,287.96,286.23,285.22,284.37,283.52,282.38,281.0,279.53,277.8,275.93,273.75,273.37,271.54,270.09,269.61,268.94,267.05,265.01,262.9,260.74,258.58,256.42,254.56,252.86,251.16,249.29,247.39,245.49,243.59],"L_fit":-6.469,"L_eq7":-8.339},{"id":"EDW-20250910-00Z","station":"EDW","year":2025,"month":9,"day":10,"hour":0,"label":"2025-09-10 00Z","t":[310.67,298.42,296.04,293.66,291.24,289.01,287.51,286.01,285.98,284.48,283.49,281.92,280.35,278.78,277.21,275.64,274.07,272.5,270.93,269.36,268.03,266.25,264.39,262.54,260.68,258.83,257.05,255.29,253.58,251.91,250.24,248.48],"L_fit":-6.636,"L_eq7":-9.067},{"id":"EDW-20250909-21Z","station":"EDW","year":2025,"month":9,"day":9,"hour":21,"label":"2025-09-09 21Z","t":[314.07,297.45,295.6,293.76,292.21,290.81,289.41,288.0,286.6,285.2,283.77,282.12,280.47,278.81,277.16,275.51,273.86,272.2,270.55,268.9,267.25,265.58,263.87,262.17,260.46,258.76,257.05,255.34,253.46,251.38,249.31,247.23],"L_fit":-6.887,"L_eq7":-9.395},{"id":"EDW-20250909-18Z","station":"EDW","year":2025,"month":9,"day":9,"hour":18,"label":"2025-09-09 18Z","t":[306.04,296.18,293.18,290.18,289.88,288.76,287.32,285.88,284.16,283.17,282.41,282.12,280.52,278.92,277.32,275.72,274.12,272.52,270.92,269.32,267.72,265.82,263.49,261.45,259.89,258.76,257.28,255.16,253.01,250.84,248.67,246.49],"L_fit":-6.439,"L_eq7":-8.62},{"id":"EDW-20250825-21Z","station":"EDW","year":2025,"month":8,"day":25,"hour":21,"label":"2025-08-25 21Z","t":[314.79,305.71,303.31,300.91,298.53,296.14,293.76,291.38,289.0,286.62,284.24,281.89,279.54,277.55,275.91,274.28,272.48,270.25,269.66,268.07,266.48,264.89,263.12,261.25,259.9,257.86,256.25,254.82,253.21,251.27,249.32,247.4],"L_fit":-7.767,"L_eq7":-9.464},{"id":"EDW-20250825-18Z","station":"EDW","year":2025,"month":8,"day":25,"hour":18,"label":"2025-08-25 18Z","t":[307.94,301.69,299.91,298.3,296.5,294.46,292.42,290.38,288.34,286.3,284.23,282.35,280.07,277.79,275.51,273.47,271.53,270.63,269.12,267.4,265.34,263.56,262.34,261.07,259.36,257.65,256.85,256.18,254.04,251.82,249.6,247.38],"L_fit":-7.293,"L_eq7":-8.803},{"id":"EDW-20250807-18Z","station":"EDW","year":2025,"month":8,"day":7,"hour":18,"label":"2025-08-07 18Z","t":[307.16,301.96,299.8,297.72,296.92,295.86,294.79,292.72,290.37,288.76,287.15,285.61,284.09,282.57,281.05,279.24,277.28,275.32,273.36,271.4,269.64,267.95,266.12,264.26,262.4,260.88,259.35,257.49,255.47,253.46,251.44,249.43],"L_fit":-7.031,"L_eq7":-8.728},{"id":"EDW-20250711-21Z","station":"EDW","year":2025,"month":7,"day":11,"hour":21,"label":"2025-07-11 21Z","t":[318.62,308.88,306.41,303.94,301.51,299.13,296.75,294.37,291.99,289.98,288.27,286.39,285.61,284.56,283.23,281.63,279.47,277.32,275.16,273.01,271.38,269.75,268.3,266.31,264.2,262.18,260.54,259.08,256.98,255.71,254.19,252.03],"L_fit":-7.559,"L_eq7":-9.833},{"id":"EDW-20250711-18Z","station":"EDW","year":2025,"month":7,"day":11,"hour":18,"label":"2025-07-11 18Z","t":[310.84,303.21,300.68,298.62,297.89,297.45,295.96,294.18,292.39,290.6,288.81,287.14,285.48,283.82,282.17,282.09,279.91,277.73,275.56,273.38,271.2,269.5,268.01,266.29,264.16,262.03,259.91,258.17,256.49,254.87,253.78,251.99],"L_fit":-7.029,"L_eq7":-9.083},{"id":"EDW-20250710-18Z","station":"EDW","year":2025,"month":7,"day":10,"hour":18,"label":"2025-07-10 18Z","t":[312.62,305.57,302.9,300.24,297.68,296.1,294.66,293.21,291.77,290.32,288.88,287.38,285.86,284.34,282.82,281.3,279.78,278.27,276.55,274.3,272.05,269.8,267.92,266.26,264.34,262.41,260.81,259.15,257.45,255.43,253.37,251.32],"L_fit":-7.077,"L_eq7":-9.255},{"id":"EDW-20250617-18Z","station":"EDW","year":2025,"month":6,"day":17,"hour":18,"label":"2025-06-17 18Z","t":[314.71,299.56,297.66,295.76,294.05,292.6,291.15,289.69,288.24,287.81,287.56,286.44,285.31,283.88,281.88,279.87,277.87,275.87,273.86,271.86,269.85,267.85,265.74,263.64,262.4,261.16,260.2,258.74,256.53,254.4,252.27,250.14],"L_fit":-6.77,"L_eq7":-9.456},{"id":"EDW-20250603-15Z","station":"EDW","year":2025,"month":6,"day":3,"hour":15,"label":"2025-06-03 15Z","t":[289.63,292.27,292.41,292.45,291.77,290.84,289.51,287.73,285.96,284.18,282.4,280.49,278.41,276.32,274.24,272.15,270.07,267.99,265.9,263.82,261.74,259.62,257.44,255.42,253.5,251.63,250.04,248.44,246.51,244.46,242.41,240.34],"L_fit":-7.31,"L_eq7":-7.037},{"id":"EDW-20250428-20Z","station":"EDW","year":2025,"month":4,"day":28,"hour":20,"label":"2025-04-28 20Z","t":[297.14,289.61,287.36,285.11,282.76,280.32,277.89,276.09,275.14,273.09,271.45,269.93,268.41,266.89,265.37,263.85,262.34,260.82,259.3,257.12,254.92,252.88,250.85,248.67,246.38,244.1,241.81,239.58,237.57,235.56,233.55,231.54],"L_fit":-7.59,"L_eq7":-7.762},{"id":"EDW-20250425-18Z","station":"EDW","year":2025,"month":4,"day":25,"hour":18,"label":"2025-04-25 18Z","t":[303.86,282.05,279.93,277.82,277.26,278.56,277.11,275.55,274.01,272.71,270.55,268.45,266.89,265.46,263.4,261.16,258.93,257.64,259.26,259.84,258.72,256.86,254.91,252.96,251.01,249.06,247.11,245.05,242.91,240.76,238.62,236.48],"L_fit":-6.243,"L_eq7":-8.41},{"id":"EDW-20250409-21Z","station":"EDW","year":2025,"month":4,"day":9,"hour":21,"label":"2025-04-09 21Z","t":[303.29,294.77,293.63,293.36,291.64,289.97,288.3,286.64,284.93,282.83,280.74,278.77,276.82,275.02,273.51,272.0,270.49,268.97,267.4,265.4,263.4,261.35,259.26,257.61,255.96,254.27,252.31,250.34,248.39,246.45,244.52,242.58],"L_fit":-7.219,"L_eq7":-8.355},{"id":"EDW-20250409-18Z","station":"EDW","year":2025,"month":4,"day":9,"hour":18,"label":"2025-04-09 18Z","t":[291.5,289.51,290.02,289.08,290.55,289.57,288.01,286.44,284.88,283.15,281.3,279.54,277.79,276.05,274.3,272.55,270.81,269.06,267.32,265.57,263.82,262.09,259.69,257.7,255.94,254.17,252.24,250.2,248.08,245.88,244.21,242.6],"L_fit":-6.695,"L_eq7":-7.218},{"id":"EDW-20250409-00Z","station":"EDW","year":2025,"month":4,"day":9,"hour":0,"label":"2025-04-09 00Z","t":[311.29,297.96,295.91,293.86,291.63,289.26,286.9,285.06,283.64,282.07,280.64,278.54,276.44,274.34,272.61,271.22,269.82,268.43,266.62,264.64,262.67,260.89,258.7,256.65,255.0,253.34,251.56,249.37,246.99,244.66,242.49,240.81],"L_fit":-7.673,"L_eq7":-9.127},{"id":"EDW-20250408-18Z","station":"EDW","year":2025,"month":4,"day":8,"hour":18,"label":"2025-04-08 18Z","t":[295.3,289.3,287.58,289.62,289.37,287.98,286.6,285.22,283.84,282.45,280.82,278.85,276.87,274.89,272.92,270.94,268.97,266.99,265.01,263.04,261.15,259.33,257.1,256.21,254.55,252.41,250.28,248.14,246.09,244.08,242.06,240.04],"L_fit":-7.01,"L_eq7":-7.584},{"id":"EDW-20250404-00Z","station":"EDW","year":2025,"month":4,"day":4,"hour":0,"label":"2025-04-04 00Z","t":[300.17,286.28,283.78,281.28,278.88,276.52,274.15,271.79,269.42,267.06,264.65,262.44,260.41,259.56,257.48,255.39,253.36,251.34,249.31,247.29,245.27,243.26,241.54,239.96,238.69,237.24,235.82,235.09,233.51,231.41,229.31,227.21],"L_fit":-8.046,"L_eq7":-8.054},{"id":"EDW-20250403-20Z","station":"EDW","year":2025,"month":4,"day":3,"hour":20,"label":"2025-04-03 20Z","t":[292.73,283.61,281.24,278.87,276.54,274.21,271.89,269.56,267.24,265.56,263.7,261.9,260.58,258.68,256.79,254.9,253.01,251.11,249.22,247.33,245.46,243.44,241.38,239.31,237.54,236.24,234.88,234.29,232.92,231.39,229.29,227.19],"L_fit":-7.613,"L_eq7":-7.337}],"NID":[{"id":"NID-20260324-15Z","station":"NID","year":2026,"month":3,"day":24,"hour":15,"label":"2026-03-24 15Z","t":[288.62,293.48,294.95,294.95,294.71,292.65,290.6,289.14,288.32,287.37,284.94,282.95,281.42,279.89,278.36,276.8,274.83,272.86,270.89,268.92,267.47,265.62,263.41,261.19,259.57,258.13,256.7,255.26,253.71,251.51,249.3,247.09],"L_fit":-6.434,"L_eq7":-6.941},{"id":"NID-20260319-21Z","station":"NID","year":2026,"month":3,"day":19,"hour":21,"label":"2026-03-19 21Z","t":[305.25,301.94,299.6,297.26,295.86,293.67,291.48,289.84,288.61,288.51,288.75,287.06,284.59,282.44,281.19,279.92,277.69,275.46,273.23,270.99,268.76,266.53,264.23,262.2,260.31,258.42,256.53,254.64,252.91,250.93,248.9,246.87],"L_fit":-7.266,"L_eq7":-8.544},{"id":"NID-20260311-15Z","station":"NID","year":2026,"month":3,"day":11,"hour":15,"label":"2026-03-11 15Z","t":[271.29,287.12,288.74,288.65,287.96,286.5,284.46,282.6,280.74,280.18,278.56,276.74,275.03,273.95,271.98,270.0,268.03,266.06,264.21,262.49,260.77,259.05,257.41,255.77,254.13,252.4,250.66,248.93,247.28,246.12,243.93,241.74],"L_fit":-6.072,"L_eq7":-5.269},{"id":"NID-20260310-15Z","station":"NID","year":2026,"month":3,"day":10,"hour":15,"label":"2026-03-10 15Z","t":[281.98,283.95,285.65,285.15,283.78,283.01,282.73,281.34,279.95,278.56,277.16,275.1,273.05,271.15,269.31,267.47,265.63,263.94,262.47,261.23,260.0,258.77,257.48,255.51,253.27,251.04,248.8,246.95,244.97,242.95,240.93,238.91],"L_fit":-6.237,"L_eq7":-6.3},{"id":"NID-20260224-15Z","station":"NID","year":2026,"month":2,"day":24,"hour":15,"label":"2026-02-24 15Z","t":[261.95,285.3,284.7,284.7,288.53,287.46,285.92,284.38,282.84,281.3,280.02,278.58,277.09,275.6,274.12,272.63,271.14,269.65,268.16,266.67,265.63,265.63,263.53,261.43,259.26,257.06,254.96,252.97,250.87,249.61,248.32,246.2],"L_fit":-4.972,"L_eq7":-4.369},{"id":"NID-20260126-18Z","station":"NID","year":2026,"month":1,"day":26,"hour":18,"label":"2026-01-26 18Z","t":[282.11,280.84,282.05,280.68,278.59,276.79,275.45,274.12,272.78,271.45,269.89,268.48,267.09,265.71,264.32,262.94,261.07,259.22,257.45,255.51,253.56,251.99,250.17,248.11,246.06,244.23,242.63,240.45,238.39,236.75,234.54,232.33],"L_fit":-6.56,"L_eq7":-6.312},{"id":"NID-20260126-15Z","station":"NID","year":2026,"month":1,"day":26,"hour":15,"label":"2026-01-26 15Z","t":[264.12,279.99,280.31,279.73,278.99,277.44,275.88,274.33,272.77,271.21,269.66,268.06,266.46,264.86,263.84,262.77,261.26,259.36,257.36,255.06,252.65,250.49,249.82,247.9,246.12,244.5,242.66,240.97,239.35,237.31,235.27,233.22],"L_fit":-6.04,"L_eq7":-4.578},{"id":"NID-20260122-12Z","station":"NID","year":2026,"month":1,"day":22,"hour":12,"label":"2026-01-22 12Z","t":[275.09,283.76,284.15,283.16,281.79,280.05,278.42,279.84,278.69,277.55,275.35,273.09,270.83,268.58,266.32,264.06,262.03,260.41,258.78,256.98,256.88,254.93,253.21,251.47,249.7,247.93,245.75,243.57,241.4,239.23,237.05,234.88],"L_fit":-6.459,"L_eq7":-5.636},{"id":"NID-20260122-06Z","station":"NID","year":2026,"month":1,"day":22,"hour":6,"label":"2026-01-22 06Z","t":[279.28,286.69,285.68,284.14,282.3,280.88,280.58,281.04,281.1,279.37,277.56,275.19,272.81,270.44,268.07,265.69,263.32,260.94,259.45,257.99,256.53,254.99,253.37,251.75,250.13,248.51,246.89,245.27,243.62,241.64,239.66,237.61],"L_fit":-6.551,"L_eq7":-6.04},{"id":"NID-20251215-15Z","station":"NID","year":2025,"month":12,"day":15,"hour":15,"label":"2025-12-15 15Z","t":[258.13,284.16,286.94,287.54,287.04,285.8,284.12,282.44,280.75,279.07,277.38,276.09,275.19,274.28,272.39,270.33,268.57,267.14,265.71,264.29,263.18,260.99,258.93,256.87,255.32,253.92,252.34,250.59,248.78,246.89,244.99,243.1],"L_fit":-5.338,"L_eq7":-4.0},{"id":"NID-20251202-21Z","station":"NID","year":2025,"month":12,"day":2,"hour":21,"label":"2025-12-02 21Z","t":[288.18,283.29,282.85,281.31,280.2,282.27,281.66,280.5,278.91,278.61,277.05,275.56,274.18,272.79,271.41,269.78,267.59,265.39,263.2,261.0,258.81,256.71,255.01,253.25,251.2,249.16,247.11,245.07,242.84,240.92,239.07,237.22],"L_fit":-6.484,"L_eq7":-6.898},{"id":"NID-20251105-15Z","station":"NID","year":2025,"month":11,"day":5,"hour":15,"label":"2025-11-05 15Z","t":[273.69,289.28,287.34,289.37,288.54,287.0,285.47,283.93,282.39,281.21,280.47,279.57,278.29,276.95,274.83,272.7,270.57,268.44,266.31,264.18,262.71,264.35,262.37,260.39,258.83,257.46,255.22,252.99,250.78,248.66,246.74,244.81],"L_fit":-5.615,"L_eq7":-5.5},{"id":"NID-20251104-18Z","station":"NID","year":2025,"month":11,"day":4,"hour":18,"label":"2025-11-04 18Z","t":[297.63,291.61,289.38,289.74,288.44,287.32,287.43,286.58,284.89,283.2,281.52,279.82,278.13,276.43,274.74,273.04,271.35,269.65,267.55,265.32,263.09,261.52,259.96,258.39,256.82,255.25,253.66,251.8,249.92,248.0,246.08,244.19],"L_fit":-6.582,"L_eq7":-7.809},{"id":"NID-20251023-15Z","station":"NID","year":2025,"month":10,"day":23,"hour":15,"label":"2025-10-23 15Z","t":[274.17,291.95,290.36,288.28,286.21,284.14,282.07,280.0,277.93,275.86,273.78,272.15,271.81,272.3,270.3,268.31,266.6,264.94,263.28,261.62,259.96,258.18,257.38,255.37,253.13,250.89,248.65,246.41,244.25,242.41,240.48,238.55],"L_fit":-6.375,"L_eq7":-5.547},{"id":"NID-20251020-18Z","station":"NID","year":2025,"month":10,"day":20,"hour":18,"label":"2025-10-20 18Z","t":[293.99,291.55,291.23,290.07,288.89,287.55,286.21,284.87,284.46,284.77,283.52,282.16,280.74,279.33,277.92,276.49,274.65,272.82,270.98,269.14,267.3,265.47,263.56,261.65,260.37,259.07,256.99,254.91,252.81,250.54,248.28,246.01],"L_fit":-6.025,"L_eq7":-7.458},{"id":"NID-20250923-15Z","station":"NID","year":2025,"month":9,"day":23,"hour":15,"label":"2025-09-23 15Z","t":[281.29,298.52,298.18,297.02,295.53,293.42,291.32,289.21,287.1,285.0,282.89,280.5,278.46,277.99,276.2,275.16,273.11,271.71,269.65,267.55,266.45,266.52,264.4,262.28,260.12,258.43,256.15,253.96,251.93,250.07,248.46,246.92],"L_fit":-6.512,"L_eq7":-6.233},{"id":"NID-20250904-18Z","station":"NID","year":2025,"month":9,"day":4,"hour":18,"label":"2025-09-04 18Z","t":[301.84,298.61,299.2,297.82,296.48,294.36,292.25,290.11,287.71,285.3,282.9,280.5,278.5,277.04,275.83,274.28,272.72,273.04,272.17,270.76,268.54,266.31,264.4,262.49,260.59,258.69,256.37,254.06,252.42,251.26,249.97,247.92],"L_fit":-6.931,"L_eq7":-8.215},{"id":"NID-20250818-18Z","station":"NID","year":2025,"month":8,"day":18,"hour":18,"label":"2025-08-18 18Z","t":[309.61,299.16,296.75,294.92,293.7,292.89,292.54,290.46,288.38,287.05,285.73,284.9,283.71,281.86,280.0,278.14,276.28,274.43,272.57,270.71,268.85,267.0,265.43,263.57,261.46,259.35,257.23,255.12,253.01,250.67,248.32,245.98],"L_fit":-7.081,"L_eq7":-8.964},{"id":"NID-20250818-15Z","station":"NID","year":2025,"month":8,"day":18,"hour":15,"label":"2025-08-18 15Z","t":[285.06,294.52,297.19,295.58,293.88,292.08,291.62,290.42,288.55,286.67,285.69,285.27,283.92,282.06,280.2,278.34,276.48,274.62,272.75,270.89,269.03,267.12,265.19,263.29,261.27,259.08,256.88,254.68,252.48,250.27,248.06,245.86],"L_fit":-6.471,"L_eq7":-6.596},{"id":"NID-20250814-15Z","station":"NID","year":2025,"month":8,"day":14,"hour":15,"label":"2025-08-14 15Z","t":[302.59,300.73,301.07,299.23,297.46,295.97,294.48,293.0,291.51,289.88,287.77,285.63,283.49,281.43,279.59,277.75,275.91,274.07,272.19,270.21,268.22,266.23,264.37,261.96,259.55,257.14,254.73,252.51,250.32,248.88,247.76,246.16],"L_fit":-7.64,"L_eq7":-8.287},{"id":"NID-20250813-15Z","station":"NID","year":2025,"month":8,"day":13,"hour":15,"label":"2025-08-13 15Z","t":[288.73,301.59,301.91,301.87,300.79,299.91,298.26,296.05,293.85,291.65,289.44,287.17,284.87,282.57,280.27,277.97,275.7,274.23,272.77,270.9,268.93,267.09,265.19,263.06,260.93,258.82,256.9,254.99,253.07,251.32,249.59,247.85],"L_fit":-7.366,"L_eq7":-6.951},{"id":"NID-20250812-15Z","station":"NID","year":2025,"month":8,"day":12,"hour":15,"label":"2025-08-12 15Z","t":[286.43,301.48,304.0,302.87,301.75,300.63,298.77,296.67,294.56,292.45,290.35,288.1,285.77,283.43,281.1,278.77,276.44,274.11,271.77,269.44,267.89,266.5,265.57,264.06,262.15,259.96,258.01,256.31,254.61,253.06,251.52,249.77],"L_fit":-7.242,"L_eq7":-6.729},{"id":"NID-20250808-15Z","station":"NID","year":2025,"month":8,"day":8,"hour":15,"label":"2025-08-08 15Z","t":[287.83,297.95,301.3,300.09,298.69,297.4,296.11,294.56,292.63,290.71,288.78,286.68,284.49,282.31,280.12,278.13,276.49,274.84,273.2,271.55,269.91,268.26,266.36,264.62,262.57,260.72,258.96,257.2,255.21,253.16,251.03,248.82],"L_fit":-6.772,"L_eq7":-6.864},{"id":"NID-20250806-15Z","station":"NID","year":2025,"month":8,"day":6,"hour":15,"label":"2025-08-06 15Z","t":[288.82,293.93,297.46,297.77,296.58,295.98,294.27,292.49,290.72,288.94,287.17,286.26,284.85,283.33,281.36,279.38,277.41,275.43,273.46,271.48,269.51,267.67,266.05,264.35,262.64,260.94,259.26,257.63,255.52,253.62,251.77,249.8],"L_fit":-6.379,"L_eq7":-6.959},{"id":"NID-20250805-15Z","station":"NID","year":2025,"month":8,"day":5,"hour":15,"label":"2025-08-05 15Z","t":[289.95,294.95,297.16,296.18,295.21,294.28,293.34,292.02,290.41,288.79,287.18,285.77,284.44,283.11,281.48,279.48,277.48,275.47,273.47,271.47,269.46,267.46,265.6,263.82,262.07,260.33,258.58,256.84,255.09,253.38,251.53,249.51],"L_fit":-6.388,"L_eq7":-7.068},{"id":"NID-20250804-18Z","station":"NID","year":2025,"month":8,"day":4,"hour":18,"label":"2025-08-04 18Z","t":[294.17,301.1,298.7,296.3,295.41,294.07,292.98,292.05,291.11,289.35,287.41,285.96,284.68,283.02,281.24,279.46,277.69,275.91,274.12,271.83,269.55,267.26,265.22,263.24,261.54,259.96,258.37,256.79,255.03,252.9,250.77,248.64],"L_fit":-6.728,"L_eq7":-7.476},{"id":"NID-20250804-15Z","station":"NID","year":2025,"month":8,"day":4,"hour":15,"label":"2025-08-04 15Z","t":[290.57,299.21,298.43,296.83,295.32,294.26,293.62,292.74,291.18,289.62,288.06,286.62,285.21,283.8,282.39,280.38,278.35,276.32,274.29,272.25,270.22,268.19,265.96,264.01,262.22,260.42,258.63,256.83,255.05,253.34,251.33,249.73],"L_fit":-6.553,"L_eq7":-7.128},{"id":"NID-20250724-18Z","station":"NID","year":2025,"month":7,"day":24,"hour":18,"label":"2025-07-24 18Z","t":[300.1,295.91,293.7,291.8,290.03,288.5,286.97,286.03,285.78,283.77,281.54,279.94,278.71,277.48,276.25,275.02,273.69,271.61,269.54,267.46,265.38,263.31,261.38,259.4,257.39,255.37,253.36,251.97,249.85,247.59,245.79,244.08],"L_fit":-6.845,"L_eq7":-8.047},{"id":"NID-20250723-18Z","station":"NID","year":2025,"month":7,"day":23,"hour":18,"label":"2025-07-23 18Z","t":[302.36,299.4,296.74,294.08,291.59,289.4,288.85,286.95,285.06,283.17,281.27,279.17,277.76,275.97,274.24,273.07,271.9,270.73,269.6,268.87,266.69,264.46,262.26,260.06,257.89,255.79,253.69,251.59,249.42,247.14,245.12,243.14],"L_fit":-7.117,"L_eq7":-8.266},{"id":"NID-20250722-18Z","station":"NID","year":2025,"month":7,"day":22,"hour":18,"label":"2025-07-22 18Z","t":[305.86,298.04,295.51,292.98,290.89,289.37,287.86,286.34,285.38,285.01,284.3,282.7,281.08,279.37,277.67,275.96,274.25,272.55,270.84,269.14,267.43,265.75,264.02,261.98,259.94,257.9,255.87,253.83,251.74,249.36,246.99,244.61],"L_fit":-6.847,"L_eq7":-8.603},{"id":"NID-20250711-15Z","station":"NID","year":2025,"month":7,"day":11,"hour":15,"label":"2025-07-11 15Z","t":[279.16,299.03,301.87,300.9,299.9,298.86,297.25,295.12,293.0,290.87,288.75,286.56,284.34,282.13,279.91,278.42,277.73,276.42,275.11,273.79,272.48,271.17,269.33,267.24,265.14,263.04,260.94,258.85,256.99,255.48,253.91,252.33],"L_fit":-6.23,"L_eq7":-6.027},{"id":"NID-20250710-15Z","station":"NID","year":2025,"month":7,"day":10,"hour":15,"label":"2025-07-10 15Z","t":[273.85,298.83,300.36,299.28,298.22,297.07,295.25,293.43,291.61,289.8,287.98,286.0,284.92,283.97,282.92,281.09,279.26,277.43,275.59,273.76,271.92,270.07,268.3,266.56,264.82,263.08,261.34,259.75,258.19,256.55,254.31,252.04],"L_fit":-5.885,"L_eq7":-5.516},{"id":"NID-20250709-15Z","station":"NID","year":2025,"month":7,"day":9,"hour":15,"label":"2025-07-09 15Z","t":[279.19,299.33,301.69,300.84,299.15,297.45,295.75,294.06,292.36,290.66,288.53,286.08,283.79,281.41,279.96,277.85,276.5,275.08,273.26,271.45,269.64,268.36,266.18,264.25,262.51,260.94,259.3,257.7,256.01,254.37,252.48,250.6],"L_fit":-6.487,"L_eq7":-6.031},{"id":"NID-20250709-00Z","station":"NID","year":2025,"month":7,"day":9,"hour":0,"label":"2025-07-09 00Z","t":[311.39,308.39,305.94,303.49,301.03,298.54,296.05,293.56,291.07,289.13,287.64,285.9,283.84,281.69,279.53,277.38,275.52,273.78,272.5,271.25,269.81,268.36,266.64,264.45,262.25,260.05,258.2,256.37,254.55,253.0,251.51,250.02],"L_fit":-7.696,"L_eq7":-9.135},{"id":"NID-20250708-15Z","station":"NID","year":2025,"month":7,"day":8,"hour":15,"label":"2025-07-08 15Z","t":[285.35,297.7,298.7,298.97,297.59,295.45,293.31,291.17,289.03,288.3,286.69,284.62,282.53,280.43,278.34,276.24,274.14,272.7,271.99,271.07,269.9,268.51,266.22,263.83,261.45,260.12,258.89,257.66,255.76,253.87,251.99,250.1],"L_fit":-6.357,"L_eq7":-6.625},{"id":"NID-20250604-15Z","station":"NID","year":2025,"month":6,"day":4,"hour":15,"label":"2025-06-04 15Z","t":[292.97,293.45,293.01,292.01,291.27,290.76,288.85,286.92,284.99,283.06,281.14,279.5,277.52,275.54,273.57,271.7,269.75,267.62,265.48,263.59,262.0,260.35,258.89,257.19,256.65,255.31,253.67,252.03,250.75,248.68,246.54,244.4],"L_fit":-6.754,"L_eq7":-7.36},{"id":"NID-20250521-00Z","station":"NID","year":2025,"month":5,"day":21,"hour":0,"label":"2025-05-21 00Z","t":[310.12,301.43,299.06,296.69,294.47,292.43,290.38,288.34,286.3,284.26,282.22,280.37,278.55,276.73,274.91,273.09,271.28,269.46,267.64,265.82,264.0,262.19,260.43,258.67,256.91,255.15,253.39,251.63,249.7,247.57,245.43,243.3],"L_fit":-7.708,"L_eq7":-9.013},{"id":"NID-20250520-15Z","station":"NID","year":2025,"month":5,"day":20,"hour":15,"label":"2025-05-20 15Z","t":[289.02,292.54,292.24,291.39,290.0,288.17,287.08,286.38,284.1,281.82,279.54,277.3,277.12,275.63,274.13,272.63,271.14,269.64,268.14,266.65,265.13,263.23,261.24,259.25,257.41,255.74,253.63,251.52,249.48,247.51,245.54,243.55],"L_fit":-6.438,"L_eq7":-6.979},{"id":"NID-20250430-03Z","station":"NID","year":2025,"month":4,"day":30,"hour":3,"label":"2025-04-30 03Z","t":[298.03,296.58,294.45,292.32,290.09,287.74,285.38,283.02,280.66,278.3,275.94,273.74,271.86,269.98,269.28,269.68,268.13,266.55,264.32,262.1,259.87,257.77,255.6,253.31,251.49,249.57,247.65,245.76,243.77,241.82,239.87,237.93],"L_fit":-7.593,"L_eq7":-7.848},{"id":"NID-20250428-18Z","station":"NID","year":2025,"month":4,"day":28,"hour":18,"label":"2025-04-28 18Z","t":[296.79,288.55,286.27,284.77,283.81,282.11,279.93,277.76,275.58,273.4,271.28,269.65,268.01,266.38,264.75,263.11,261.48,260.11,258.78,257.36,255.37,253.41,251.34,249.08,246.82,244.56,242.47,240.46,238.22,235.98,233.73,231.49],"L_fit":-7.552,"L_eq7":-7.728},{"id":"NID-20250409-15Z","station":"NID","year":2025,"month":4,"day":9,"hour":15,"label":"2025-04-09 15Z","t":[275.01,288.72,289.59,289.72,288.89,288.09,287.29,286.49,285.59,283.51,281.33,279.41,277.55,275.69,273.82,271.96,270.1,268.24,266.41,265.33,264.25,262.53,260.26,257.99,255.73,253.46,251.19,248.92,246.9,244.88,242.86,240.84],"L_fit":-6.405,"L_eq7":-5.628},{"id":"NID-20250408-18Z","station":"NID","year":2025,"month":4,"day":8,"hour":18,"label":"2025-04-08 18Z","t":[298.24,294.48,292.28,290.08,289.19,288.63,286.87,285.11,283.34,281.58,279.82,278.14,276.47,274.8,273.13,271.46,269.48,267.46,265.44,263.42,261.4,259.43,257.42,255.42,253.82,252.78,250.81,248.59,246.48,244.45,242.41,240.38],"L_fit":-7.227,"L_eq7":-7.868},{"id":"NID-20250404-15Z","station":"NID","year":2025,"month":4,"day":4,"hour":15,"label":"2025-04-04 15Z","t":[284.03,284.35,282.34,280.34,278.26,276.08,273.9,271.72,269.54,267.36,265.15,262.82,260.5,258.68,256.74,254.41,253.13,251.5,249.86,248.23,246.64,245.22,243.68,242.4,244.48,244.77,242.77,241.6,240.51,239.41,239.63,237.6],"L_fit":-6.362,"L_eq7":-6.498},{"id":"NID-20250403-15Z","station":"NID","year":2025,"month":4,"day":3,"hour":15,"label":"2025-04-03 15Z","t":[267.12,280.28,279.3,277.74,275.74,273.71,271.69,269.66,267.63,265.6,263.52,261.41,259.34,257.84,256.34,254.38,252.39,250.45,248.54,246.63,245.04,243.27,241.4,239.54,237.67,235.94,234.34,232.73,230.95,229.13,228.49,227.18],"L_fit":-7.012,"L_eq7":-4.867},{"id":"NID-20250402-21Z","station":"NID","year":2025,"month":4,"day":2,"hour":21,"label":"2025-04-02 21Z","t":[295.29,285.41,283.0,280.59,278.09,275.58,273.08,270.57,268.06,265.83,263.58,261.23,258.89,256.78,254.53,253.03,250.94,248.86,246.77,244.69,242.48,240.18,238.47,236.71,236.13,235.95,235.85,235.26,234.18,233.1,231.35,229.56],"L_fit":-7.804,"L_eq7":-7.584},{"id":"NID-20250402-18Z","station":"NID","year":2025,"month":4,"day":2,"hour":18,"label":"2025-04-02 18Z","t":[285.72,281.54,279.38,277.21,274.94,272.64,270.33,268.04,266.08,264.13,262.38,260.75,259.02,257.21,255.23,253.04,250.85,248.66,246.73,244.86,242.61,240.58,239.09,237.7,237.09,236.31,235.28,234.15,233.2,231.99,230.77,229.56],"L_fit":-7.197,"L_eq7":-6.661},{"id":"NID-20250331-18Z","station":"NID","year":2025,"month":3,"day":31,"hour":18,"label":"2025-03-31 18Z","t":[294.3,290.42,287.79,285.47,283.15,280.84,278.53,276.72,275.98,275.24,272.94,271.63,269.93,268.23,267.15,266.81,268.71,266.71,264.71,262.71,260.71,258.52,256.25,253.97,252.56,250.47,248.29,246.25,244.76,243.24,241.73,240.81],"L_fit":-6.355,"L_eq7":-7.488},{"id":"NID-20250331-15Z","station":"NID","year":2025,"month":3,"day":31,"hour":15,"label":"2025-03-31 15Z","t":[286.57,288.19,286.22,284.25,282.1,279.78,277.46,275.28,273.36,271.6,270.87,270.34,269.36,268.35,267.33,266.32,265.31,264.73,264.0,262.06,260.11,258.68,257.02,254.79,253.24,252.44,250.73,248.58,246.35,244.12,241.9,239.67],"L_fit":-5.783,"L_eq7":-6.742},{"id":"NID-20250327-18Z","station":"NID","year":2025,"month":3,"day":27,"hour":18,"label":"2025-03-27 18Z","t":[294.15,291.73,290.2,288.67,286.97,285.13,285.56,283.85,282.13,280.41,278.65,277.38,275.52,273.33,271.15,268.96,267.08,265.51,263.94,262.37,260.84,260.81,259.4,257.75,255.38,253.01,251.52,249.5,247.25,245.02,242.79,240.56],"L_fit":-6.707,"L_eq7":-7.473},{"id":"NID-20250326-21Z","station":"NID","year":2025,"month":3,"day":26,"hour":21,"label":"2025-03-26 21Z","t":[305.9,298.98,296.53,294.07,291.66,289.29,286.92,284.62,282.41,280.21,278.0,275.74,273.48,271.22,269.27,267.7,265.59,264.08,262.49,260.62,258.7,256.6,254.34,252.44,250.53,248.34,246.14,244.05,242.03,240.02,238.0,236.83],"L_fit":-8.34,"L_eq7":-8.606},{"id":"NID-20250326-18Z","station":"NID","year":2025,"month":3,"day":26,"hour":18,"label":"2025-03-26 18Z","t":[291.99,292.01,292.48,291.37,290.36,289.08,286.91,284.74,282.57,280.4,278.23,275.89,273.54,271.2,268.85,266.51,264.33,262.68,260.82,259.06,257.58,256.15,254.64,252.53,250.34,248.14,246.33,244.04,241.73,239.43,237.13,234.85],"L_fit":-7.836,"L_eq7":-7.265},{"id":"NID-20250325-15Z","station":"NID","year":2025,"month":3,"day":25,"hour":15,"label":"2025-03-25 15Z","t":[266.99,292.6,294.15,293.31,291.29,289.04,286.79,284.53,282.28,280.17,278.97,278.3,277.72,276.07,273.98,271.88,269.78,267.68,265.58,263.48,261.81,260.1,257.97,255.84,253.7,251.57,249.33,247.08,244.83,242.6,240.39,238.17],"L_fit":-6.796,"L_eq7":-4.854},{"id":"NID-20250324-15Z","station":"NID","year":2025,"month":3,"day":24,"hour":15,"label":"2025-03-24 15Z","t":[276.67,290.63,292.05,290.86,289.11,286.92,284.74,282.55,280.37,278.6,276.92,275.58,277.41,276.12,274.58,272.71,270.63,268.54,266.46,264.37,262.29,260.19,257.97,255.75,253.54,251.36,249.39,247.43,245.32,243.37,241.4,239.3],"L_fit":-6.609,"L_eq7":-5.788},{"id":"NID-20250319-00Z","station":"NID","year":2025,"month":3,"day":19,"hour":0,"label":"2025-03-19 00Z","t":[299.76,287.01,284.31,281.6,278.96,276.54,274.62,272.86,271.1,269.35,269.39,268.34,267.22,265.37,263.39,261.41,259.43,257.68,256.14,254.61,252.79,250.73,248.83,247.55,245.43,243.32,241.21,239.22,237.2,235.18,233.16,231.13],"L_fit":-7.303,"L_eq7":-8.015},{"id":"NID-20250318-18Z","station":"NID","year":2025,"month":3,"day":18,"hour":18,"label":"2025-03-18 18Z","t":[280.37,280.63,278.89,277.15,275.36,273.45,271.54,269.64,267.73,266.24,265.21,263.76,262.32,260.88,260.35,258.34,256.1,253.86,251.83,250.32,248.83,247.76,246.01,244.18,242.35,240.51,238.68,236.56,234.27,231.99,229.91,229.0],"L_fit":-6.724,"L_eq7":-6.145},{"id":"NID-20250317-18Z","station":"NID","year":2025,"month":3,"day":17,"hour":18,"label":"2025-03-17 18Z","t":[285.32,285.25,285.39,283.6,281.84,280.09,278.34,276.6,275.68,274.67,273.23,271.69,270.15,268.61,268.42,266.8,264.84,263.34,261.66,259.78,257.86,256.26,254.45,253.47,251.28,249.1,246.9,244.67,242.4,240.33,238.32,237.0],"L_fit":-6.36,"L_eq7":-6.622},{"id":"NID-20250307-15Z","station":"NID","year":2025,"month":3,"day":7,"hour":15,"label":"2025-03-07 15Z","t":[279.08,280.14,278.04,275.93,273.85,272.49,271.25,269.08,266.91,264.74,262.46,261.63,260.06,257.9,255.73,253.57,251.41,249.24,247.1,245.56,244.79,242.86,240.97,239.29,237.61,235.92,234.69,233.89,233.09,232.27,231.44,230.61],"L_fit":-6.898,"L_eq7":-6.02},{"id":"NID-20250304-21Z","station":"NID","year":2025,"month":3,"day":4,"hour":21,"label":"2025-03-04 21Z","t":[290.3,286.86,284.43,282.14,280.15,278.22,276.29,274.54,274.41,274.28,274.07,273.31,271.64,270.14,268.69,267.24,265.79,264.34,262.82,261.3,259.77,258.32,256.36,254.11,251.87,249.62,247.77,246.35,244.98,242.91,240.76,238.6],"L_fit":-6.052,"L_eq7":-7.102},{"id":"NID-20241219-18Z","station":"NID","year":2024,"month":12,"day":19,"hour":18,"label":"2024-12-19 18Z","t":[282.51,285.51,287.88,287.49,287.15,285.99,284.03,282.34,281.46,280.58,279.79,278.57,277.14,275.61,273.64,271.67,269.99,268.83,267.58,265.53,263.48,261.42,259.29,257.15,255.01,252.88,250.74,248.6,246.24,244.81,242.78,240.74],"L_fit":-6.252,"L_eq7":-6.351},{"id":"NID-20241217-18Z","station":"NID","year":2024,"month":12,"day":17,"hour":18,"label":"2024-12-17 18Z","t":[268.01,282.74,284.03,283.54,282.92,281.9,280.88,279.86,278.84,277.83,276.75,275.04,273.54,272.72,271.91,271.09,270.28,268.74,267.18,265.62,264.06,262.43,260.57,258.72,256.69,254.6,252.51,250.55,248.57,246.52,244.47,242.43],"L_fit":-5.074,"L_eq7":-4.953}],"VEF":[{"id":"VEF-20260728-12Z","station":"VEF","year":2026,"month":7,"day":28,"hour":12,"label":"2026-07-28 12Z","t":[308.28,306.08,305.79,304.43,302.36,299.97,297.52,295.13,293.05,290.9,288.62,286.38,284.22,282.23,280.4,278.91,277.92,276.24,274.25,272.84,271.56,270.11,268.0,265.89,263.8,262.04,260.04,258.11,256.67,255.11,253.29,251.44],"L_fit":-7.4,"L_eq7":-8.836},{"id":"VEF-20260727-18Z","station":"VEF","year":2026,"month":7,"day":27,"hour":18,"label":"2026-07-27 18Z","t":[311.69,307.11,304.71,302.38,300.11,297.72,295.35,293.27,291.54,289.25,286.96,285.28,283.42,281.33,279.13,277.71,276.93,276.76,275.41,274.07,272.49,270.49,268.51,266.55,264.39,262.22,260.81,260.16,258.79,257.72,255.79,253.58],"L_fit":-6.97,"L_eq7":-9.164},{"id":"VEF-20260727-12Z","station":"VEF","year":2026,"month":7,"day":27,"hour":12,"label":"2026-07-27 12Z","t":[308.26,306.43,304.73,302.58,300.58,298.57,296.44,294.24,292.04,289.67,287.42,286.1,285.22,282.82,280.54,278.62,276.8,274.96,273.03,271.27,269.49,269.16,268.67,267.06,265.18,263.14,261.35,259.56,257.63,255.71,254.61,253.61],"L_fit":-7.081,"L_eq7":-8.834},{"id":"VEF-20260726-18Z","station":"VEF","year":2026,"month":7,"day":26,"hour":18,"label":"2026-07-26 18Z","t":[313.05,308.33,305.75,303.35,300.99,298.6,296.45,294.78,293.06,291.23,289.4,287.38,284.95,282.78,281.2,279.18,277.34,275.07,272.79,270.53,268.99,268.06,266.23,265.32,263.81,262.28,261.11,259.83,257.97,256.54,255.42,254.08],"L_fit":-7.366,"L_eq7":-9.296},{"id":"VEF-20260726-12Z","station":"VEF","year":2026,"month":7,"day":26,"hour":12,"label":"2026-07-26 12Z","t":[307.85,307.08,306.49,305.03,303.56,301.25,298.85,296.86,295.0,292.93,290.76,288.65,286.75,284.62,282.6,280.56,278.35,275.94,273.61,271.77,269.92,268.54,267.02,266.33,265.01,262.77,261.88,260.02,257.75,255.6,253.75,253.09],"L_fit":-7.49,"L_eq7":-8.795},{"id":"VEF-20260725-18Z","station":"VEF","year":2026,"month":7,"day":25,"hour":18,"label":"2026-07-25 18Z","t":[314.2,309.19,306.86,304.52,302.3,299.93,297.69,295.32,293.13,291.44,289.98,287.66,285.26,283.51,282.41,280.55,279.29,277.27,274.97,272.83,270.8,268.97,266.86,264.43,262.41,262.37,260.75,259.28,258.21,257.43,255.68,254.03],"L_fit":-7.501,"L_eq7":-9.407},{"id":"VEF-20260725-12Z","station":"VEF","year":2026,"month":7,"day":25,"hour":12,"label":"2026-07-25 12Z","t":[308.7,307.39,306.25,304.67,302.9,300.67,298.43,296.19,293.95,291.72,289.71,287.95,286.31,284.67,282.96,280.97,278.98,277.0,274.96,273.2,271.34,269.4,267.18,265.14,263.2,261.9,260.7,259.5,258.23,256.42,255.22,253.66],"L_fit":-7.407,"L_eq7":-8.877},{"id":"VEF-20260724-18Z","station":"VEF","year":2026,"month":7,"day":24,"hour":18,"label":"2026-07-24 18Z","t":[314.01,310.15,307.6,305.13,302.59,300.2,297.9,295.53,293.16,290.77,288.47,286.37,284.18,282.07,280.13,278.45,276.79,274.65,272.93,271.3,270.25,269.08,267.57,265.61,264.09,262.95,261.61,259.97,258.43,256.42,254.57,252.58],"L_fit":-7.538,"L_eq7":-9.389},{"id":"VEF-20260724-12Z","station":"VEF","year":2026,"month":7,"day":24,"hour":12,"label":"2026-07-24 12Z","t":[308.17,308.59,307.02,305.05,302.91,300.85,298.83,296.58,294.21,291.92,289.57,287.17,284.77,282.65,280.64,278.72,276.89,275.21,273.56,271.92,270.34,269.03,267.67,266.23,265.03,263.46,261.84,260.12,258.41,257.25,255.67,253.72],"L_fit":-7.339,"L_eq7":-8.825},{"id":"VEF-20260723-18Z","station":"VEF","year":2026,"month":7,"day":23,"hour":18,"label":"2026-07-23 18Z","t":[310.65,307.16,304.71,303.19,301.32,299.17,296.95,295.0,292.9,290.6,288.32,286.15,283.98,281.93,279.74,277.71,275.86,274.36,272.98,271.22,270.95,269.89,267.94,265.72,263.97,262.44,261.51,260.3,258.56,256.46,254.34,253.29],"L_fit":-7.214,"L_eq7":-9.064},{"id":"VEF-20260723-12Z","station":"VEF","year":2026,"month":7,"day":23,"hour":12,"label":"2026-07-23 12Z","t":[306.5,307.0,305.57,303.74,302.28,300.21,298.0,295.64,293.59,291.27,288.96,286.75,284.36,282.41,280.38,278.34,276.45,274.31,272.61,271.5,270.61,270.25,268.56,266.39,264.37,262.44,260.7,259.21,258.57,256.99,254.92,253.14],"L_fit":-7.218,"L_eq7":-8.664},{"id":"VEF-20260722-18Z","station":"VEF","year":2026,"month":7,"day":22,"hour":18,"label":"2026-07-22 18Z","t":[310.28,305.1,302.56,299.98,298.34,296.86,294.95,292.8,290.64,288.4,286.37,284.77,282.59,280.68,278.74,277.27,275.38,273.83,271.98,270.36,269.23,268.27,267.28,266.01,264.36,262.61,261.08,259.94,258.49,256.73,254.84,253.04],"L_fit":-6.868,"L_eq7":-9.029},{"id":"VEF-20260722-12Z","station":"VEF","year":2026,"month":7,"day":22,"hour":12,"label":"2026-07-22 12Z","t":[303.05,302.82,301.22,299.76,298.72,297.06,295.47,293.37,291.14,288.71,286.63,284.5,282.44,280.35,278.55,277.27,275.34,273.99,272.3,271.0,270.07,268.41,266.83,265.28,263.79,262.75,262.01,259.99,258.08,256.51,255.5,254.02],"L_fit":-6.621,"L_eq7":-8.332},{"id":"VEF-20260721-18Z","station":"VEF","year":2026,"month":7,"day":21,"hour":18,"label":"2026-07-21 18Z","t":[310.77,306.14,303.3,300.84,298.85,296.81,294.42,292.27,290.41,288.03,286.12,283.85,281.82,280.07,278.1,276.43,274.09,272.63,271.65,270.14,269.06,267.52,266.62,265.17,264.16,262.14,260.76,259.32,257.82,257.21,255.52,253.73],"L_fit":-6.929,"L_eq7":-9.076},{"id":"VEF-20260721-12Z","station":"VEF","year":2026,"month":7,"day":21,"hour":12,"label":"2026-07-21 12Z","t":[308.26,306.71,305.2,303.25,301.0,298.75,296.63,294.45,292.39,290.17,287.91,285.56,283.28,281.08,279.36,278.17,276.33,274.1,272.09,270.61,268.97,266.74,264.91,263.4,261.92,261.55,260.79,260.67,259.27,257.68,255.74,253.96],"L_fit":-7.174,"L_eq7":-8.834},{"id":"VEF-20260720-18Z","station":"VEF","year":2026,"month":7,"day":20,"hour":18,"label":"2026-07-20 18Z","t":[310.58,306.92,304.28,301.82,299.34,296.95,294.68,292.71,290.74,288.77,286.8,284.54,282.3,280.82,279.41,277.3,275.47,273.71,271.83,270.27,268.61,267.21,265.5,264.44,263.32,261.81,260.33,259.14,257.82,256.11,254.53,252.99],"L_fit":-7.132,"L_eq7":-9.058},{"id":"VEF-20260720-12Z","station":"VEF","year":2026,"month":7,"day":20,"hour":12,"label":"2026-07-20 12Z","t":[305.04,304.09,302.98,301.14,299.39,297.62,295.75,293.65,291.5,289.3,286.87,284.61,282.45,280.25,278.4,276.76,275.28,274.31,272.78,271.17,269.76,268.05,266.79,265.4,263.79,261.72,261.21,260.17,258.64,256.78,255.56,254.01],"L_fit":-6.8,"L_eq7":-8.523},{"id":"VEF-20260719-18Z","station":"VEF","year":2026,"month":7,"day":19,"hour":18,"label":"2026-07-19 18Z","t":[308.27,303.93,301.67,299.15,297.04,296.03,294.2,292.01,290.33,288.25,286.52,284.8,282.87,280.88,278.87,276.87,275.06,273.43,272.16,270.85,269.85,268.01,266.55,264.74,263.16,262.25,261.52,260.16,258.73,257.61,256.68,255.41],"L_fit":-6.62,"L_eq7":-8.835},{"id":"VEF-20260719-12Z","station":"VEF","year":2026,"month":7,"day":19,"hour":12,"label":"2026-07-19 12Z","t":[306.92,305.47,304.02,302.1,299.96,298.29,296.15,294.04,291.88,289.76,287.46,285.39,283.75,281.77,279.79,277.77,276.16,274.31,272.45,270.99,269.35,270.15,268.54,266.72,264.71,263.8,261.92,259.91,258.4,257.15,256.66,254.85],"L_fit":-6.839,"L_eq7":-8.705},{"id":"VEF-20260718-18Z","station":"VEF","year":2026,"month":7,"day":18,"hour":18,"label":"2026-07-18 18Z","t":[304.98,301.24,298.87,297.58,296.63,295.41,293.61,291.35,289.55,287.61,285.8,284.02,281.84,279.97,278.13,276.97,275.8,274.31,272.6,271.28,269.25,267.65,266.2,265.0,263.7,262.7,262.82,260.93,258.87,256.68,254.53,252.44],"L_fit":-6.419,"L_eq7":-8.518},{"id":"VEF-20260718-12Z","station":"VEF","year":2026,"month":7,"day":18,"hour":12,"label":"2026-07-18 12Z","t":[301.16,298.17,298.3,298.16,296.53,295.01,293.06,291.37,289.53,287.83,286.27,284.48,282.63,280.9,278.66,277.07,275.74,274.03,272.16,270.61,268.91,267.16,265.75,264.61,262.79,260.85,258.67,257.66,258.2,257.18,255.24,253.18],"L_fit":-6.415,"L_eq7":-8.149},{"id":"VEF-20260717-18Z","station":"VEF","year":2026,"month":7,"day":17,"hour":18,"label":"2026-07-17 18Z","t":[305.23,301.04,298.47,296.2,296.3,294.18,292.96,290.77,289.14,287.31,286.1,284.8,282.76,280.45,278.19,276.47,275.09,272.99,271.46,269.87,268.33,267.23,266.28,264.69,263.11,261.35,259.66,258.12,256.18,254.06,252.46,250.98],"L_fit":-6.68,"L_eq7":-8.541},{"id":"VEF-20260717-12Z","station":"VEF","year":2026,"month":7,"day":17,"hour":12,"label":"2026-07-17 12Z","t":[303.69,300.44,298.55,297.37,295.69,293.71,291.65,290.23,288.89,286.8,284.88,283.56,281.53,280.18,278.47,276.68,274.97,273.44,271.86,270.13,268.22,266.73,265.24,262.83,261.14,261.98,260.89,259.28,257.59,256.04,254.52,253.1],"L_fit":-6.433,"L_eq7":-8.393},{"id":"VEF-20260716-18Z","station":"VEF","year":2026,"month":7,"day":16,"hour":18,"label":"2026-07-16 18Z","t":[309.9,305.97,303.26,300.92,299.08,297.77,295.69,293.55,291.56,289.59,287.58,285.38,283.16,281.07,279.05,277.13,275.29,273.6,271.99,270.42,269.49,267.56,266.32,264.92,262.91,261.35,259.63,258.33,256.98,255.22,253.55,251.91],"L_fit":-7.217,"L_eq7":-8.992},{"id":"VEF-20260716-12Z","station":"VEF","year":2026,"month":7,"day":16,"hour":12,"label":"2026-07-16 12Z","t":[304.06,305.88,304.16,302.57,301.2,299.53,297.31,295.06,292.89,290.61,288.41,286.02,283.58,281.36,279.05,277.13,275.84,274.28,272.2,270.72,269.18,267.83,266.6,264.99,263.98,262.58,260.69,258.47,257.35,256.04,253.88,252.19],"L_fit":-7.179,"L_eq7":-8.429},{"id":"VEF-20260715-12Z","station":"VEF","year":2026,"month":7,"day":15,"hour":12,"label":"2026-07-15 12Z","t":[303.87,306.56,304.77,302.63,300.38,298.12,296.14,294.09,291.83,289.44,287.05,284.66,282.31,280.22,278.37,276.19,275.3,273.68,272.4,271.05,269.61,268.26,266.63,265.06,264.0,262.92,261.04,259.99,258.4,256.57,254.61,252.72],"L_fit":-6.982,"L_eq7":-8.41},{"id":"VEF-20260715-06Z","station":"VEF","year":2026,"month":7,"day":15,"hour":6,"label":"2026-07-15 06Z","t":[311.51,308.75,306.56,304.18,301.86,299.47,297.17,294.74,292.38,290.18,287.9,285.63,283.52,281.69,279.72,277.96,276.38,274.65,273.17,271.68,269.94,268.35,267.62,265.53,263.75,262.35,260.92,259.77,257.81,256.48,254.17,252.75],"L_fit":-7.388,"L_eq7":-9.148},{"id":"VEF-20260702-12Z","station":"VEF","year":2026,"month":7,"day":2,"hour":12,"label":"2026-07-02 12Z","t":[300.42,299.59,298.55,296.79,294.48,292.13,290.35,288.11,285.81,283.56,281.42,279.15,277.11,274.9,273.49,272.16,271.77,270.5,268.91,266.81,265.12,263.1,261.41,259.72,257.86,255.55,253.8,251.67,249.8,248.45,246.66,244.62],"L_fit":-7.24,"L_eq7":-8.078},{"id":"VEF-20260702-06Z","station":"VEF","year":2026,"month":7,"day":2,"hour":6,"label":"2026-07-02 06Z","t":[306.14,302.74,300.49,298.19,295.89,293.6,291.34,289.05,286.73,284.38,281.95,279.63,277.22,276.29,275.5,274.28,272.28,270.44,268.47,266.89,265.46,263.51,261.37,259.09,256.81,254.94,253.03,251.13,249.39,247.77,246.02,244.08],"L_fit":-7.702,"L_eq7":-8.63},{"id":"VEF-20260701-12Z","station":"VEF","year":2026,"month":7,"day":1,"hour":12,"label":"2026-07-01 12Z","t":[300.04,298.42,297.53,295.82,294.03,291.89,289.69,287.41,284.93,282.75,280.75,278.47,276.93,275.24,273.96,273.08,271.88,270.4,268.97,266.99,265.07,263.32,261.11,258.73,256.44,254.43,252.19,250.69,249.29,247.11,244.89,243.19],"L_fit":-7.306,"L_eq7":-8.041},{"id":"VEF-20260701-06Z","station":"VEF","year":2026,"month":7,"day":1,"hour":6,"label":"2026-07-01 06Z","t":[304.28,301.43,299.48,297.4,295.28,293.05,290.96,288.78,286.34,283.98,281.72,279.33,277.03,274.85,272.55,270.62,270.99,271.12,269.09,267.22,264.85,263.05,261.65,259.77,258.13,256.74,254.6,252.26,250.12,248.23,246.34,244.22],"L_fit":-7.419,"L_eq7":-8.45},{"id":"VEF-20260630-12Z","station":"VEF","year":2026,"month":6,"day":30,"hour":12,"label":"2026-06-30 12Z","t":[299.16,297.29,296.91,295.41,294.07,291.77,289.67,287.32,284.9,282.58,280.24,277.86,275.51,273.1,271.35,269.14,267.07,264.84,262.8,261.94,260.74,258.85,257.32,256.25,254.89,253.9,252.38,250.5,248.25,245.94,243.83,241.85],"L_fit":-7.521,"L_eq7":-7.957},{"id":"VEF-20260630-06Z","station":"VEF","year":2026,"month":6,"day":30,"hour":6,"label":"2026-06-30 06Z","t":[304.53,302.34,300.05,297.99,295.69,293.33,290.97,288.55,286.16,283.76,281.45,279.02,276.64,274.22,271.85,269.66,269.43,267.4,265.1,263.39,261.87,260.06,257.76,256.29,255.0,254.25,252.95,251.1,249.01,246.87,244.91,243.39],"L_fit":-7.838,"L_eq7":-8.474},{"id":"VEF-20260629-12Z","station":"VEF","year":2026,"month":6,"day":29,"hour":12,"label":"2026-06-29 12Z","t":[297.05,294.34,292.38,290.21,288.21,287.06,285.58,284.21,282.85,281.03,279.34,277.15,274.97,272.56,270.48,271.4,270.15,268.76,267.82,267.05,265.91,263.96,262.06,259.95,257.68,255.42,253.41,251.63,249.66,247.75,246.34,245.1],"L_fit":-6.407,"L_eq7":-7.753},{"id":"VEF-20260629-06Z","station":"VEF","year":2026,"month":6,"day":29,"hour":6,"label":"2026-06-29 06Z","t":[304.94,300.37,298.0,295.8,293.57,291.58,289.55,287.2,284.78,282.43,280.18,278.06,276.69,274.65,272.36,270.15,268.15,268.05,267.88,267.95,265.8,265.65,263.48,261.3,259.16,257.17,254.95,252.58,250.61,249.22,248.07,246.39],"L_fit":-7.01,"L_eq7":-8.514},{"id":"VEF-20260628-12Z","station":"VEF","year":2026,"month":6,"day":28,"hour":12,"label":"2026-06-28 12Z","t":[297.45,294.98,294.14,293.38,291.48,290.53,288.84,288.14,286.58,285.28,284.61,282.84,280.37,277.96,276.75,276.12,275.41,274.85,273.24,271.4,270.58,268.47,266.34,264.48,262.19,259.98,257.68,255.54,254.13,252.44,250.9,249.03],"L_fit":-6.123,"L_eq7":-7.791},{"id":"VEF-20260628-06Z","station":"VEF","year":2026,"month":6,"day":28,"hour":6,"label":"2026-06-28 06Z","t":[302.73,299.5,297.09,294.72,293.12,291.21,289.51,288.51,289.9,288.39,287.07,285.24,283.32,281.39,279.32,277.74,276.25,274.39,272.5,270.49,268.8,267.36,266.27,265.75,264.57,262.71,260.58,258.15,255.83,253.84,251.67,249.33],"L_fit":-6.386,"L_eq7":-8.301},{"id":"VEF-20260627-12Z","station":"VEF","year":2026,"month":6,"day":27,"hour":12,"label":"2026-06-27 12Z","t":[300.31,296.71,297.65,297.98,297.0,295.5,293.38,291.96,289.52,286.98,284.33,283.22,281.04,278.88,277.05,275.82,275.3,274.85,274.34,272.7,270.98,268.85,266.46,264.41,262.36,260.16,258.2,256.91,255.27,252.87,250.66,249.18],"L_fit":-6.634,"L_eq7":-8.067},{"id":"VEF-20260627-06Z","station":"VEF","year":2026,"month":6,"day":27,"hour":6,"label":"2026-06-27 06Z","t":[304.78,301.55,299.18,296.93,295.39,294.82,293.78,292.56,290.63,288.48,286.45,285.08,282.94,280.63,278.74,276.54,275.16,273.81,272.15,270.16,268.18,265.95,263.73,261.67,259.89,259.24,257.25,255.81,255.12,253.33,251.18,248.98],"L_fit":-7.087,"L_eq7":-8.498},{"id":"VEF-20260626-12Z","station":"VEF","year":2026,"month":6,"day":26,"hour":12,"label":"2026-06-26 12Z","t":[302.67,301.33,300.18,300.35,298.84,297.26,295.46,294.08,292.59,290.59,288.45,286.25,283.96,281.54,279.15,276.66,274.33,272.14,270.09,269.14,267.61,265.79,263.9,261.91,260.22,258.54,256.81,254.52,252.26,250.13,248.21,246.8],"L_fit":-7.61,"L_eq7":-8.295},{"id":"VEF-20260626-06Z","station":"VEF","year":2026,"month":6,"day":26,"hour":6,"label":"2026-06-26 06Z","t":[295.41,307.1,304.9,303.07,300.75,298.43,296.08,294.12,293.12,291.22,288.83,286.44,284.33,282.28,280.79,278.61,276.39,274.17,272.67,271.01,269.48,267.88,265.76,263.57,261.32,259.23,257.26,255.46,253.59,251.6,249.73,248.04],"L_fit":-7.546,"L_eq7":-7.595},{"id":"VEF-20260625-12Z","station":"VEF","year":2026,"month":6,"day":25,"hour":12,"label":"2026-06-25 12Z","t":[300.53,301.79,300.29,300.03,298.22,296.59,294.56,292.34,290.05,287.95,285.79,283.63,281.5,279.19,277.0,275.57,274.17,272.33,270.52,268.87,267.19,266.09,263.88,261.55,259.27,257.69,257.74,255.96,254.3,252.51,251.17,249.59],"L_fit":-7.173,"L_eq7":-8.089},{"id":"VEF-20260625-06Z","station":"VEF","year":2026,"month":6,"day":25,"hour":6,"label":"2026-06-25 06Z","t":[307.45,306.23,304.42,302.6,300.33,298.09,295.89,293.44,291.04,288.66,286.28,284.09,281.89,280.23,278.58,276.87,274.97,274.3,272.46,270.55,268.67,266.28,263.8,261.54,260.01,259.15,257.68,256.25,254.75,252.68,251.03,249.5],"L_fit":-7.607,"L_eq7":-8.756},{"id":"VEF-20260624-12Z","station":"VEF","year":2026,"month":6,"day":24,"hour":12,"label":"2026-06-24 12Z","t":[303.43,305.26,303.83,302.09,300.04,297.89,295.7,293.28,290.4,286.87,285.33,283.75,281.77,279.93,277.63,275.77,274.43,272.48,270.67,269.02,267.66,266.11,264.37,262.89,261.24,259.37,257.4,255.83,252.54,251.68,250.24,248.89],"L_fit":-7.514,"L_eq7":-8.368},{"id":"VEF-20260624-06Z","station":"VEF","year":2026,"month":6,"day":24,"hour":6,"label":"2026-06-24 06Z","t":[311.02,307.94,305.9,303.65,301.54,299.51,297.49,295.35,293.17,291.01,288.64,286.37,284.19,281.87,279.51,277.2,274.97,272.81,270.7,268.92,266.99,265.08,263.5,262.41,261.01,260.35,258.38,257.39,255.71,253.5,251.35,249.42],"L_fit":-7.896,"L_eq7":-9.1},{"id":"VEF-20260623-12Z","station":"VEF","year":2026,"month":6,"day":23,"hour":12,"label":"2026-06-23 12Z","t":[301.08,303.33,302.65,301.11,299.4,297.53,295.38,293.22,291.13,288.73,286.86,286.06,284.51,282.52,280.19,277.86,276.0,274.63,273.76,272.12,270.74,268.92,266.76,264.38,262.12,260.24,258.33,256.19,254.15,252.26,250.31,248.24],"L_fit":-7.254,"L_eq7":-8.142},{"id":"VEF-20260623-06Z","station":"VEF","year":2026,"month":6,"day":23,"hour":6,"label":"2026-06-23 06Z","t":[307.73,307.07,304.94,302.82,300.55,298.06,295.68,293.48,291.22,290.65,289.68,288.35,286.37,284.38,282.32,280.32,278.17,276.02,274.2,272.39,270.46,268.85,266.89,264.88,262.62,260.76,259.32,257.57,255.95,253.82,251.59,249.27],"L_fit":-7.498,"L_eq7":-8.783},{"id":"VEF-20260622-12Z","station":"VEF","year":2026,"month":6,"day":22,"hour":12,"label":"2026-06-22 12Z","t":[290.07,301.27,301.38,300.18,298.37,296.15,293.99,291.64,289.32,287.29,285.39,284.83,283.38,281.95,280.93,279.71,278.08,275.97,273.8,272.35,271.47,269.82,267.41,264.97,262.52,260.42,259.84,258.07,256.02,254.2,252.29,250.03],"L_fit":-6.533,"L_eq7":-7.08},{"id":"VEF-20260622-06Z","station":"VEF","year":2026,"month":6,"day":22,"hour":6,"label":"2026-06-22 06Z","t":[307.34,305.87,304.14,302.05,299.87,297.59,295.23,292.8,290.37,288.03,286.61,284.57,282.83,281.38,280.26,279.43,278.04,276.24,274.49,272.93,271.26,269.65,268.27,266.08,264.0,261.99,259.87,257.5,255.2,253.23,251.61,249.72],"L_fit":-7.213,"L_eq7":-8.745},{"id":"VEF-20260621-12Z","station":"VEF","year":2026,"month":6,"day":21,"hour":12,"label":"2026-06-21 12Z","t":[300.15,300.9,301.77,300.08,297.83,295.69,293.54,291.5,289.27,287.0,284.62,283.43,281.93,279.86,278.25,276.62,275.08,273.77,272.79,271.55,270.17,268.06,266.37,263.96,261.55,259.4,258.03,255.77,253.85,252.05,251.57,249.87],"L_fit":-6.947,"L_eq7":-8.052},{"id":"VEF-20260621-06Z","station":"VEF","year":2026,"month":6,"day":21,"hour":6,"label":"2026-06-21 06Z","t":[304.46,305.92,303.65,301.47,299.1,296.93,294.9,292.76,290.76,288.79,286.54,284.31,282.47,280.63,278.74,277.29,275.6,274.11,272.74,271.07,269.53,268.37,266.96,265.25,262.97,260.48,258.37,256.84,255.32,253.38,251.28,249.15],"L_fit":-7.248,"L_eq7":-8.468},{"id":"VEF-20260620-12Z","station":"VEF","year":2026,"month":6,"day":20,"hour":12,"label":"2026-06-20 12Z","t":[299.92,299.73,299.81,297.49,295.65,294.44,292.04,289.65,287.56,286.15,284.95,283.31,281.48,279.56,277.86,276.26,274.8,273.09,272.84,272.08,270.01,268.23,266.66,265.05,264.12,262.16,259.97,258.08,256.27,254.24,252.17,249.9],"L_fit":-6.444,"L_eq7":-8.03},{"id":"VEF-20260620-06Z","station":"VEF","year":2026,"month":6,"day":20,"hour":6,"label":"2026-06-20 06Z","t":[307.81,304.47,302.27,299.89,297.54,295.21,293.11,290.95,288.53,286.17,285.65,284.68,283.63,282.18,280.43,278.25,275.88,274.47,273.37,271.5,269.55,268.32,266.84,264.86,263.86,262.46,260.74,258.72,257.05,255.05,253.05,250.93],"L_fit":-6.849,"L_eq7":-8.791},{"id":"VEF-20260619-12Z","station":"VEF","year":2026,"month":6,"day":19,"hour":12,"label":"2026-06-19 12Z","t":[301.64,303.15,301.28,299.04,296.74,294.35,292.04,289.69,288.9,288.25,286.58,285.15,283.13,281.05,278.77,276.49,274.4,272.63,271.28,269.83,267.98,266.13,264.25,264.46,263.09,261.62,260.23,258.43,256.92,255.14,253.12,251.02],"L_fit":-6.721,"L_eq7":-8.196},{"id":"VEF-20260619-06Z","station":"VEF","year":2026,"month":6,"day":19,"hour":6,"label":"2026-06-19 06Z","t":[307.25,306.03,303.86,301.83,300.16,298.27,296.17,293.8,291.4,289.02,287.17,285.33,283.07,280.69,278.36,276.86,275.32,273.27,271.31,269.49,267.72,266.44,264.81,263.19,261.45,259.78,258.92,258.18,256.79,255.06,253.25,251.62],"L_fit":-7.342,"L_eq7":-8.737},{"id":"VEF-20260618-12Z","station":"VEF","year":2026,"month":6,"day":18,"hour":12,"label":"2026-06-18 12Z","t":[305.28,304.36,303.64,302.0,300.77,298.55,296.25,293.98,291.8,289.49,287.19,285.71,283.61,281.62,279.73,277.76,275.58,273.08,270.82,268.88,267.14,264.96,262.72,260.57,258.53,256.35,257.1,255.92,254.13,252.08,250.2,248.05],"L_fit":-7.774,"L_eq7":-8.547},{"id":"VEF-20260618-06Z","station":"VEF","year":2026,"month":6,"day":18,"hour":6,"label":"2026-06-18 06Z","t":[309.45,308.91,306.84,304.71,302.24,299.93,297.86,295.52,293.17,290.9,288.72,286.74,284.63,282.53,280.41,278.47,276.4,274.3,272.05,269.81,267.83,265.64,264.59,262.75,260.55,258.65,256.94,255.66,254.44,252.55,250.24,248.51],"L_fit":-8.083,"L_eq7":-8.949},{"id":"VEF-20260617-12Z","station":"VEF","year":2026,"month":6,"day":17,"hour":12,"label":"2026-06-17 12Z","t":[304.35,305.45,304.21,303.1,301.7,299.6,297.54,295.26,292.91,290.67,288.36,286.25,284.08,281.75,279.3,277.16,275.03,272.83,270.93,268.78,266.42,265.06,264.32,262.84,261.49,259.71,257.35,255.55,253.95,252.27,250.47,248.76],"L_fit":-7.772,"L_eq7":-8.457},{"id":"VEF-20260617-06Z","station":"VEF","year":2026,"month":6,"day":17,"hour":6,"label":"2026-06-17 06Z","t":[309.98,309.59,307.42,305.28,303.22,300.9,298.52,296.08,293.69,291.34,289.12,286.93,284.46,282.05,279.64,277.23,275.02,272.77,271.36,271.49,269.66,268.19,265.95,264.04,261.92,259.82,257.78,255.83,253.83,252.33,250.94,249.05],"L_fit":-8.066,"L_eq7":-9.0},{"id":"VEF-20260616-12Z","station":"VEF","year":2026,"month":6,"day":16,"hour":12,"label":"2026-06-16 12Z","t":[303.58,305.63,304.61,302.69,300.59,298.61,296.47,294.2,292.06,290.2,288.19,286.0,283.85,281.57,279.25,277.14,274.77,272.32,269.83,267.36,265.73,264.34,263.32,261.68,260.05,258.91,257.27,255.13,252.99,250.9,249.34,247.26],"L_fit":-7.864,"L_eq7":-8.383}]}} +{"meta":{"generated":"2026-08-13T20:43:53Z","source":"recovery-calculator/site-climatology/export_json.py","pad":{"name":"Friends of Amateur Rocketry","lat":35.35333,"lon":-117.80717,"elev_m":630.0,"elev_is_estimate":false},"ceiling_agl_ft":25000,"ceiling_msl_m":8250.0,"isa_lapse_k_per_km":-6.5},"isa":{"pad":{"H":629.938,"T":284.0554,"p":93982.796,"rho":1.152612},"T":[284.0554,282.4304,280.8054,279.1804,277.5554,275.9304,274.3054,272.6804,271.0554,269.4304,267.8054,266.1804,264.5554,262.9304,261.3054,259.6804,258.0554,256.4304,254.8054,253.1804,251.5554,249.9304,248.3054,246.6804,245.0554,243.4304,241.8054,240.1804,238.5554,236.9304,235.3054,233.6804],"p":[93982.796,91191.167,88467.065,85809.233,83216.432,80687.436,78221.038,75816.045,73471.281,71185.585,68957.811,66786.831,64671.53,62610.808,60603.582,58648.782,56745.355,54892.262,53088.477,51332.991,49624.808,47962.947,46346.44,44774.334,43245.691,41759.585,40315.104,38911.351,37547.441,36222.503,34935.68,33686.127],"lapse_k_per_km":-6.5},"surface":{"stations":[{"id":"KEDW","name":"Edwards AFB","elev_m":702.0,"gap_m":72.0,"distance_km":50.2,"primary":false,"note":"cross-check: 50 km, +92 m gap. Co-located with RAOB 72381."},{"id":"KMHV","name":"Mojave Air & Space Port","elev_m":849.0,"gap_m":219.0,"distance_km":45.3,"primary":false,"note":"cross-check: 45 km, +239 m gap. Reports temperature overnight."},{"id":"KNID","name":"China Lake NAWS","elev_m":696.0,"gap_m":66.0,"distance_km":38.7,"primary":true,"note":"primary: 39 km, +86 m gap. Temperature drops out ~06-11Z."}],"monthly":{"KEDW":[{"month":1,"n":697,"p_mean":94745.2,"p_sd":512.9,"p_p05":93978.9,"p_p95":95580.8,"p_min":93570.5,"p_max":96051.9,"t_mean":280.9,"t_p05":273.2,"t_p95":290.34,"rho_mean":1.17548,"rho_p05":1.13414,"rho_p95":1.21572,"lw_n":248,"lw_t_mean":284.16,"lw_rho_mean":1.16214},{"month":2,"n":620,"p_mean":94452.3,"p_sd":477.9,"p_p05":93539.1,"p_p95":95172.4,"p_min":93068.0,"p_max":95360.9,"t_mean":283.72,"t_p05":274.82,"t_p95":295.82,"rho_mean":1.16037,"rho_p05":1.11415,"rho_p95":1.20242,"lw_n":216,"lw_t_mean":287.6,"lw_rho_mean":1.14517},{"month":3,"n":671,"p_mean":94261.2,"p_sd":313.5,"p_p05":93884.6,"p_p95":94826.9,"p_min":93601.9,"p_max":95329.5,"t_mean":291.22,"t_p05":278.51,"t_p95":305.27,"rho_mean":1.12846,"rho_p05":1.07317,"rho_p95":1.18163,"lw_n":249,"lw_t_mean":296.48,"lw_rho_mean":1.10859},{"month":4,"n":607,"p_mean":94059.7,"p_sd":264.5,"p_p05":93633.4,"p_p95":94512.8,"p_min":93476.3,"p_max":94795.5,"t_mean":289.56,"t_p05":280.05,"t_p95":300.19,"rho_mean":1.13218,"rho_p05":1.08964,"rho_p95":1.17289,"lw_n":228,"lw_t_mean":294.37,"lw_rho_mean":1.11333},{"month":5,"n":712,"p_mean":93842.3,"p_sd":260.7,"p_p05":93350.7,"p_p95":94198.7,"p_min":93005.2,"p_max":94418.6,"t_mean":294.58,"t_p05":284.32,"t_p95":306.62,"rho_mean":1.11038,"rho_p05":1.06561,"rho_p95":1.15068,"lw_n":265,"lw_t_mean":299.93,"lw_rho_mean":1.09035},{"month":6,"n":705,"p_mean":93784.0,"p_sd":193.4,"p_p05":93476.3,"p_p95":94135.9,"p_min":93319.3,"p_max":94293.0,"t_mean":300.15,"t_p05":290.34,"t_p95":310.82,"rho_mean":1.08901,"rho_p05":1.05123,"rho_p95":1.125,"lw_n":264,"lw_t_mean":305.95,"lw_rho_mean":1.06796},{"month":7,"n":732,"p_mean":94019.7,"p_sd":204.6,"p_p05":93696.2,"p_p95":94355.8,"p_min":93413.5,"p_max":94512.8,"t_mean":301.84,"t_p05":291.92,"t_p95":311.82,"rho_mean":1.08565,"rho_p05":1.04902,"rho_p95":1.12334,"lw_n":278,"lw_t_mean":307.43,"lw_rho_mean":1.06577},{"month":8,"n":689,"p_mean":94078.0,"p_sd":202.1,"p_p05":93759.0,"p_p95":94437.4,"p_min":93570.5,"p_max":94544.2,"t_mean":302.92,"t_p05":293.42,"t_p95":313.22,"rho_mean":1.08243,"rho_p05":1.04396,"rho_p95":1.1188,"lw_n":257,"lw_t_mean":308.35,"lw_rho_mean":1.0632},{"month":9,"n":578,"p_mean":93990.2,"p_sd":217.5,"p_p05":93664.8,"p_p95":94387.2,"p_min":93476.3,"p_max":94638.5,"t_mean":298.34,"t_p05":289.92,"t_p95":308.32,"rho_mean":1.09792,"rho_p05":1.06142,"rho_p95":1.12988,"lw_n":215,"lw_t_mean":302.56,"lw_rho_mean":1.08268},{"month":10,"n":667,"p_mean":94098.8,"p_sd":324.5,"p_p05":93539.1,"p_p95":94607.1,"p_min":93193.6,"p_max":94921.2,"t_mean":290.83,"t_p05":281.15,"t_p95":302.19,"rho_mean":1.12773,"rho_p05":1.0834,"rho_p95":1.16797,"lw_n":229,"lw_t_mean":295.41,"lw_rho_mean":1.11031},{"month":11,"n":638,"p_mean":94348.7,"p_sd":335.6,"p_p05":93790.4,"p_p95":94894.5,"p_min":93507.7,"p_max":95203.9,"t_mean":286.31,"t_p05":277.02,"t_p95":298.42,"rho_mean":1.14859,"rho_p05":1.10069,"rho_p95":1.18825,"lw_n":240,"lw_t_mean":289.93,"lw_rho_mean":1.13451},{"month":12,"n":714,"p_mean":94535.4,"p_sd":347.2,"p_p05":93978.9,"p_p95":95109.6,"p_min":93633.4,"p_max":95392.3,"t_mean":282.75,"t_p05":274.42,"t_p95":292.65,"rho_mean":1.16521,"rho_p05":1.12249,"rho_p95":1.20356,"lw_n":249,"lw_t_mean":286.35,"lw_rho_mean":1.15095}],"KMHV":[{"month":1,"n":360,"p_mean":94839.8,"p_sd":458.5,"p_p05":93912.9,"p_p95":95392.3,"p_min":93664.8,"p_max":95580.8,"t_mean":283.36,"t_p05":275.67,"t_p95":293.08,"rho_mean":1.16643,"rho_p05":1.12636,"rho_p95":1.20251,"lw_n":128,"lw_t_mean":288.12,"lw_rho_mean":1.14749},{"month":2,"n":635,"p_mean":94558.5,"p_sd":488.5,"p_p05":93570.5,"p_p95":95266.7,"p_min":93225.0,"p_max":95423.7,"t_mean":285.46,"t_p05":276.87,"t_p95":295.67,"rho_mean":1.15446,"rho_p05":1.11591,"rho_p95":1.19311,"lw_n":224,"lw_t_mean":289.21,"lw_rho_mean":1.13993},{"month":3,"n":744,"p_mean":94373.1,"p_sd":306.3,"p_p05":93983.6,"p_p95":94921.2,"p_min":93759.0,"p_max":95392.3,"t_mean":293.3,"t_p05":282.59,"t_p95":304.57,"rho_mean":1.12152,"rho_p05":1.0778,"rho_p95":1.16583,"lw_n":279,"lw_t_mean":297.85,"lw_rho_mean":1.10474},{"month":4,"n":717,"p_mean":94154.0,"p_sd":273.6,"p_p05":93696.2,"p_p95":94638.5,"p_min":93507.7,"p_max":94921.2,"t_mean":290.05,"t_p05":282.25,"t_p95":299.57,"rho_mean":1.13125,"rho_p05":1.09425,"rho_p95":1.163,"lw_n":270,"lw_t_mean":294.09,"lw_rho_mean":1.11593},{"month":5,"n":704,"p_mean":93991.6,"p_sd":243.4,"p_p05":93539.1,"p_p95":94355.8,"p_min":93287.8,"p_max":94544.2,"t_mean":295.87,"t_p05":285.39,"t_p95":305.97,"rho_mean":1.10717,"rho_p05":1.0691,"rho_p95":1.14652,"lw_n":270,"lw_t_mean":299.87,"lw_rho_mean":1.09264},{"month":6,"n":704,"p_mean":93923.4,"p_sd":198.9,"p_p05":93601.9,"p_p95":94261.6,"p_min":93413.5,"p_max":94450.0,"t_mean":301.66,"t_p05":293.59,"t_p95":310.57,"rho_mean":1.08498,"rho_p05":1.05356,"rho_p95":1.1136,"lw_n":266,"lw_t_mean":305.81,"lw_rho_mean":1.0704},{"month":7,"n":744,"p_mean":94170.8,"p_sd":202.0,"p_p05":93853.2,"p_p95":94512.8,"p_min":93696.2,"p_max":94701.3,"t_mean":303.01,"t_p05":294.57,"t_p95":310.57,"rho_mean":1.08297,"rho_p05":1.0538,"rho_p95":1.11283,"lw_n":279,"lw_t_mean":306.39,"lw_rho_mean":1.0716},{"month":8,"n":731,"p_mean":94255.5,"p_sd":195.8,"p_p05":93947.5,"p_p95":94575.7,"p_min":93759.0,"p_max":94701.3,"t_mean":304.0,"t_p05":295.57,"t_p95":312.57,"rho_mean":1.08043,"rho_p05":1.04951,"rho_p95":1.11098,"lw_n":278,"lw_t_mean":307.28,"lw_rho_mean":1.06934},{"month":9,"n":710,"p_mean":94156.2,"p_sd":205.1,"p_p05":93853.2,"p_p95":94544.2,"p_min":93696.2,"p_max":94701.3,"t_mean":299.22,"t_p05":291.57,"t_p95":307.57,"rho_mean":1.09653,"rho_p05":1.06578,"rho_p95":1.12567,"lw_n":266,"lw_t_mean":301.99,"lw_rho_mean":1.087},{"month":10,"n":136,"p_mean":94107.5,"p_sd":195.3,"p_p05":93759.0,"p_p95":94387.2,"p_min":93664.8,"p_max":94418.6,"t_mean":293.49,"t_p05":287.57,"t_p95":301.57,"rho_mean":1.11727,"rho_p05":1.08815,"rho_p95":1.14008,"lw_n":46,"lw_t_mean":296.49,"lw_rho_mean":1.10655}],"KNID":[{"month":1,"n":726,"p_mean":94849.1,"p_sd":541.0,"p_p05":93947.5,"p_p95":95698.6,"p_min":93664.8,"p_max":96209.0,"t_mean":281.27,"t_p05":272.98,"t_p95":291.88,"rho_mean":1.17527,"rho_p05":1.13068,"rho_p95":1.21874,"lw_n":269,"lw_t_mean":285.46,"lw_rho_mean":1.15803},{"month":2,"n":667,"p_mean":94527.6,"p_sd":548.4,"p_p05":93485.7,"p_p95":95329.5,"p_min":93068.0,"p_max":95486.5,"t_mean":284.33,"t_p05":274.86,"t_p95":295.78,"rho_mean":1.1588,"rho_p05":1.11283,"rho_p95":1.20353,"lw_n":250,"lw_t_mean":288.36,"lw_rho_mean":1.14291},{"month":3,"n":729,"p_mean":94301.3,"p_sd":358.4,"p_p05":93821.8,"p_p95":94889.8,"p_min":93633.4,"p_max":95423.7,"t_mean":292.68,"t_p05":280.78,"t_p95":305.78,"rho_mean":1.12322,"rho_p05":1.07122,"rho_p95":1.17306,"lw_n":274,"lw_t_mean":297.86,"lw_rho_mean":1.10377},{"month":4,"n":621,"p_mean":94029.6,"p_sd":356.0,"p_p05":93413.5,"p_p95":94669.9,"p_min":93193.6,"p_max":94952.6,"t_mean":290.79,"t_p05":280.28,"t_p95":301.38,"rho_mean":1.12701,"rho_p05":1.08486,"rho_p95":1.17169,"lw_n":248,"lw_t_mean":295.31,"lw_rho_mean":1.10991},{"month":5,"n":649,"p_mean":93804.3,"p_sd":346.5,"p_p05":93130.8,"p_p95":94280.4,"p_min":92534.0,"p_max":94575.7,"t_mean":296.46,"t_p05":285.78,"t_p95":307.98,"rho_mean":1.10293,"rho_p05":1.05936,"rho_p95":1.14611,"lw_n":253,"lw_t_mean":301.19,"lw_rho_mean":1.08558},{"month":6,"n":623,"p_mean":93708.3,"p_sd":255.2,"p_p05":93287.8,"p_p95":94135.9,"p_min":93068.0,"p_max":94355.8,"t_mean":302.85,"t_p05":291.88,"t_p95":312.48,"rho_mean":1.07841,"rho_p05":1.04343,"rho_p95":1.11792,"lw_n":243,"lw_t_mean":307.3,"lw_rho_mean":1.06303},{"month":7,"n":730,"p_mean":94034.7,"p_sd":228.9,"p_p05":93664.8,"p_p95":94418.6,"p_min":93476.3,"p_max":94638.5,"t_mean":304.97,"t_p05":294.68,"t_p95":315.28,"rho_mean":1.07462,"rho_p05":1.03773,"rho_p95":1.11361,"lw_n":239,"lw_t_mean":309.06,"lw_rho_mean":1.06084},{"month":8,"n":739,"p_mean":94155.6,"p_sd":236.7,"p_p05":93790.4,"p_p95":94544.2,"p_min":93507.7,"p_max":94732.7,"t_mean":304.97,"t_p05":294.68,"t_p95":315.28,"rho_mean":1.07606,"rho_p05":1.03687,"rho_p95":1.11539,"lw_n":277,"lw_t_mean":309.63,"lw_rho_mean":1.06006},{"month":9,"n":679,"p_mean":94102.3,"p_sd":236.5,"p_p05":93693.0,"p_p95":94512.8,"p_min":93539.1,"p_max":94701.3,"t_mean":300.68,"t_p05":291.88,"t_p95":310.28,"rho_mean":1.09067,"rho_p05":1.0562,"rho_p95":1.12349,"lw_n":261,"lw_t_mean":304.48,"lw_rho_mean":1.07725},{"month":10,"n":711,"p_mean":94239.1,"p_sd":373.5,"p_p05":93554.8,"p_p95":94826.9,"p_min":93068.0,"p_max":95141.0,"t_mean":292.34,"t_p05":282.98,"t_p95":302.48,"rho_mean":1.12352,"rho_p05":1.08375,"rho_p95":1.16326,"lw_n":264,"lw_t_mean":297.11,"lw_rho_mean":1.10556},{"month":11,"n":718,"p_mean":94537.4,"p_sd":341.1,"p_p05":93947.5,"p_p95":95141.0,"p_min":93696.2,"p_max":95360.9,"t_mean":287.12,"t_p05":278.58,"t_p95":299.68,"rho_mean":1.1476,"rho_p05":1.09905,"rho_p95":1.18608,"lw_n":270,"lw_t_mean":290.95,"lw_rho_mean":1.13252},{"month":12,"n":739,"p_mean":94635.7,"p_sd":382.3,"p_p05":94038.5,"p_p95":95266.7,"p_min":93727.6,"p_max":95549.4,"t_mean":282.55,"t_p05":274.68,"t_p95":292.48,"rho_mean":1.16736,"rho_p05":1.12313,"rho_p95":1.20505,"lw_n":279,"lw_t_mean":286.5,"lw_rho_mean":1.15124}]}},"upper":{"grid_m":[629.9375687781601,879.9375687781601,1129.93756877816,1379.93756877816,1629.93756877816,1879.93756877816,2129.9375687781603,2379.9375687781603,2629.9375687781603,2879.9375687781603,3129.9375687781603,3379.9375687781603,3629.9375687781603,3879.9375687781603,4129.93756877816,4379.93756877816,4629.93756877816,4879.93756877816,5129.93756877816,5379.93756877816,5629.93756877816,5879.93756877816,6129.93756877816,6379.93756877816,6629.93756877816,6879.93756877816,7129.93756877816,7379.93756877816,7629.93756877816,7879.93756877816,8129.93756877816,8379.93756877816],"datasets":[{"id":"edw-nid","label":"Edwards + China Lake","stations":["EDW","NID"],"pooled":true,"n":1331},{"id":"edw","label":"Edwards AFB","stations":["EDW"],"pooled":false,"n":915},{"id":"nid","label":"China Lake NAF","stations":["NID"],"pooled":false,"n":416},{"id":"vef","label":"Las Vegas","stations":["VEF"],"pooled":false,"n":7263}],"profile":{"edw-nid":[{"month":1,"n":72,"mean":[278.31,281.99,281.81,280.62,279.62,278.58,277.68,276.74,275.83,274.78,273.59,272.28,270.91,269.37,267.85,266.2,264.46,262.79,261.05,259.29,257.51,255.64,253.83,251.92,250.0,248.12,246.36,244.63,242.79,240.98,239.09,237.2],"sd":[11.08,3.49,3.55,3.7,4.03,4.4,4.72,4.88,5.1,5.19,5.06,4.94,4.92,4.89,4.87,4.88,4.97,5.08,5.12,5.16,5.23,5.31,5.35,5.4,5.4,5.35,5.31,4.94,4.6,4.36,4.13,3.95],"p05":[257.53,276.39,276.01,274.5,272.78,270.8,268.91,267.19,265.95,265.07,264.01,262.44,261.12,259.7,259.34,257.6,255.55,253.56,251.73,250.14,248.29,245.99,243.91,242.07,240.16,239.0,238.39,236.54,235.0,233.23,232.81,231.49],"p50":[280.37,281.86,281.67,280.68,279.97,279.2,278.49,277.74,276.94,276.62,275.17,273.39,272.21,270.5,268.65,267.01,265.18,263.49,261.56,259.71,257.8,255.81,254.06,252.11,250.36,248.67,246.82,245.15,243.02,241.2,239.0,236.93],"p95":[293.58,287.19,287.77,286.81,285.63,284.88,283.99,283.05,282.54,281.38,279.98,278.43,276.7,275.55,273.96,272.43,270.44,268.89,267.05,265.51,263.6,261.98,260.52,258.87,256.74,254.7,253.0,251.45,249.37,247.32,245.18,243.05],"eq7_err":[0.0,-5.16,-6.47,-6.77,-7.25,-7.7,-8.29,-8.84,-9.41,-9.85,-10.14,-10.32,-10.43,-10.39,-10.35,-10.19,-9.93,-9.75,-9.5,-9.22,-8.93,-8.54,-8.22,-7.8,-7.37,-6.97,-6.7,-6.46,-6.1,-5.78,-5.38,-4.97]},{"month":2,"n":110,"mean":[281.83,283.23,282.2,280.83,279.37,277.87,276.3,274.87,273.61,272.44,271.19,269.95,268.67,267.21,265.66,264.08,262.45,260.85,259.24,257.57,255.86,254.01,252.18,250.34,248.45,246.54,244.64,242.76,240.83,238.94,237.1,235.25],"sd":[11.8,5.28,5.24,5.4,5.51,5.55,5.67,5.64,5.58,5.47,5.47,5.42,5.43,5.4,5.39,5.4,5.38,5.33,5.28,5.12,5.16,5.19,5.17,5.01,4.91,4.87,4.79,4.77,4.74,4.69,4.62,4.56],"p05":[259.1,274.32,273.18,271.78,270.27,268.38,266.24,264.44,262.92,261.5,260.75,260.3,258.87,257.61,255.7,254.16,252.26,251.21,250.38,249.67,247.61,245.43,243.32,241.92,240.62,239.02,237.52,235.83,233.88,231.79,229.84,228.21],"p50":[283.3,283.81,282.99,281.86,280.43,278.81,277.32,275.94,274.54,273.04,271.52,270.21,268.87,267.43,265.71,263.95,262.33,260.61,259.03,257.56,256.05,254.14,252.39,250.33,248.32,246.25,244.33,242.56,240.51,238.47,236.3,234.63],"p95":[296.9,290.74,289.77,288.82,287.73,286.11,284.72,283.05,281.73,280.43,279.19,278.04,277.41,275.86,274.41,272.84,271.15,269.25,267.34,265.9,264.42,262.62,260.78,259.12,257.06,254.99,252.9,251.04,249.23,247.55,245.96,243.93],"eq7_err":[0.0,-2.97,-3.51,-3.71,-3.82,-3.9,-3.89,-4.03,-4.35,-4.75,-5.07,-5.4,-5.7,-5.8,-5.83,-5.82,-5.76,-5.73,-5.7,-5.59,-5.45,-5.18,-4.91,-4.65,-4.33,-3.99,-3.67,-3.35,-3.0,-2.68,-2.41,-2.13]},{"month":3,"n":183,"mean":[286.28,285.75,284.46,282.73,281.0,279.2,277.59,276.2,275.01,273.71,272.42,271.07,269.67,268.2,266.64,265.01,263.29,261.59,259.84,258.07,256.32,254.52,252.7,250.89,249.05,247.19,245.33,243.43,241.5,239.63,237.7,235.84],"sd":[10.81,5.46,5.57,5.73,5.83,5.87,5.87,5.89,5.88,5.88,5.82,5.74,5.72,5.71,5.71,5.69,5.72,5.73,5.77,5.78,5.79,5.82,5.81,5.73,5.64,5.57,5.37,5.17,5.04,4.85,4.71,4.52],"p05":[267.56,278.16,276.78,274.71,272.84,270.87,268.88,267.35,265.92,264.13,262.07,261.17,259.57,257.56,255.75,254.43,253.48,251.3,248.98,246.6,245.02,243.06,241.14,240.61,238.42,236.95,235.43,234.27,233.11,231.73,230.08,228.88],"p50":[286.57,285.08,284.31,282.06,280.25,278.24,277.41,275.97,275.39,274.16,272.69,271.43,269.97,268.52,267.12,265.47,264.02,262.33,260.54,258.78,256.93,255.33,253.42,251.64,249.74,247.86,245.9,243.7,241.64,239.52,237.42,235.45],"p95":[303.55,296.33,295.58,293.96,292.66,291.53,290.23,289.13,287.87,285.99,284.1,282.45,281.01,279.45,277.51,275.76,273.84,272.49,270.67,268.83,267.02,265.16,262.99,261.08,259.53,257.51,255.75,253.99,252.13,250.14,247.96,245.8],"eq7_err":[0.0,-1.15,-1.53,-1.48,-1.43,-1.31,-1.38,-1.67,-2.15,-2.53,-2.92,-3.25,-3.53,-3.74,-3.86,-3.91,-3.87,-3.84,-3.77,-3.68,-3.61,-3.49,-3.34,-3.22,-3.06,-2.87,-2.69,-2.48,-2.22,-2.03,-1.78,-1.6]},{"month":4,"n":125,"mean":[290.47,289.61,288.29,286.77,285.17,283.53,281.87,280.19,278.67,277.19,275.69,274.21,272.69,271.17,269.66,268.06,266.36,264.66,262.86,261.1,259.31,257.44,255.56,253.76,251.94,250.11,248.26,246.39,244.46,242.52,240.58,238.63],"sd":[13.77,5.41,5.2,5.18,5.11,5.14,5.19,5.23,5.34,5.41,5.32,5.09,5.05,4.91,4.91,4.95,4.99,5.01,5.02,5.02,5.0,5.02,4.99,4.89,4.72,4.59,4.51,4.4,4.34,4.27,4.2,4.08],"p05":[270.69,281.44,279.87,277.85,275.87,274.2,271.96,269.84,267.71,265.91,264.86,262.98,260.87,259.85,258.64,257.09,254.99,253.11,250.82,248.58,246.85,245.31,243.62,242.55,241.44,239.56,237.7,235.89,234.62,233.35,231.54,230.07],"p50":[291.5,289.18,288.64,287.39,285.79,284.46,282.9,280.83,279.78,278.27,276.44,274.98,273.87,272.55,270.9,269.19,267.58,265.74,263.93,262.1,260.41,258.57,256.95,255.1,253.2,251.24,249.2,247.22,245.35,243.41,241.38,239.13],"p95":[308.29,298.47,296.32,294.65,292.36,290.42,288.54,286.57,285.29,283.57,282.13,280.46,278.69,276.74,274.96,273.19,271.69,269.95,268.8,267.06,265.23,263.35,261.49,259.44,257.33,255.44,253.79,251.94,250.24,248.07,246.02,243.87],"eq7_err":[0.0,-0.91,-1.38,-1.64,-1.81,-1.95,-2.07,-2.18,-2.44,-2.74,-3.01,-3.31,-3.57,-3.84,-4.1,-4.28,-4.36,-4.44,-4.42,-4.44,-4.43,-4.34,-4.24,-4.22,-4.18,-4.13,-4.06,-3.97,-3.82,-3.66,-3.5,-3.33]},{"month":5,"n":92,"mean":[296.29,293.61,292.13,290.52,288.77,287.02,285.11,283.22,281.34,279.5,277.69,275.95,274.4,272.89,271.3,269.7,268.09,266.52,264.94,263.27,261.52,259.76,257.92,256.08,254.21,252.34,250.42,248.48,246.56,244.67,242.77,240.87],"sd":[11.58,5.59,5.22,4.94,4.79,4.67,4.63,4.61,4.53,4.43,4.31,4.25,4.22,4.18,4.09,4.11,4.11,4.16,4.12,4.06,4.04,4.05,4.06,4.05,4.02,4.0,4.02,4.03,3.94,3.84,3.69,3.51],"p05":[279.76,285.59,283.8,282.33,280.17,277.93,275.75,273.63,271.38,269.87,267.89,265.86,265.1,263.9,262.11,260.42,259.1,257.18,255.08,253.71,252.08,250.36,248.53,246.56,244.55,242.47,240.24,237.89,236.04,234.64,233.77,233.26],"p50":[298.88,293.14,292.28,291.48,290.06,288.25,286.01,284.2,282.35,280.73,278.88,277.24,275.69,274.05,272.22,270.59,269.07,267.37,265.74,263.94,262.33,260.6,258.7,256.82,254.82,252.78,250.88,249.03,247.08,245.19,243.19,241.25],"p95":[310.14,301.78,299.39,297.34,295.3,293.42,291.67,289.41,287.31,285.48,283.38,281.11,279.82,277.88,276.05,274.38,272.79,271.51,269.94,268.44,267.07,265.33,263.49,261.7,259.76,257.74,255.88,253.83,251.81,249.84,247.66,245.48],"eq7_err":[0.0,0.76,0.33,0.01,-0.15,-0.33,-0.34,-0.37,-0.41,-0.48,-0.59,-0.77,-1.15,-1.55,-1.88,-2.2,-2.52,-2.87,-3.21,-3.45,-3.63,-3.79,-3.87,-3.95,-4.0,-4.05,-4.05,-4.03,-4.03,-4.05,-4.08,-4.09]},{"month":6,"n":86,"mean":[300.83,298.97,297.82,296.32,294.91,293.24,291.46,289.65,287.83,286.02,284.28,282.57,280.99,279.46,277.79,276.05,274.24,272.46,270.68,268.91,267.15,265.38,263.54,261.8,260.02,258.24,256.44,254.53,252.68,250.72,248.79,246.81],"sd":[12.65,6.14,5.54,5.19,4.82,4.66,4.46,4.27,4.19,4.03,3.85,3.7,3.57,3.48,3.47,3.42,3.4,3.35,3.32,3.34,3.35,3.36,3.36,3.33,3.23,3.19,3.18,3.21,3.28,3.34,3.42,3.48],"p05":[282.66,288.2,288.22,286.92,286.23,285.05,283.43,282.06,280.22,278.24,276.99,276.79,275.7,274.31,271.99,269.77,267.97,266.44,264.78,263.18,261.58,259.71,257.66,255.66,253.71,251.75,249.93,247.87,245.63,243.5,241.78,239.83],"p50":[301.8,300.3,298.7,297.25,295.85,294.28,292.42,290.61,288.26,286.27,284.66,283.09,281.57,280.04,278.61,276.7,274.95,273.26,271.47,269.78,267.99,266.03,264.17,262.8,260.91,258.78,257.08,255.09,253.18,251.19,249.4,247.72],"p95":[318.18,307.38,305.31,303.42,301.74,300.16,298.1,295.79,293.71,291.59,289.5,287.61,285.65,283.86,282.14,280.08,278.19,276.69,274.9,273.18,271.2,269.64,267.79,265.89,263.79,261.89,260.13,258.43,256.46,254.44,252.7,250.69],"eq7_err":[0.0,-0.16,-1.04,-1.58,-2.2,-2.55,-2.8,-3.02,-3.24,-3.45,-3.74,-4.06,-4.51,-5.01,-5.37,-5.66,-5.88,-6.13,-6.38,-6.63,-6.91,-7.17,-7.36,-7.65,-7.9,-8.14,-8.38,-8.5,-8.68,-8.75,-8.84,-8.89]},{"month":7,"n":118,"mean":[305.29,302.44,301.18,299.75,298.22,296.61,294.84,293.01,291.15,289.3,287.38,285.48,283.52,281.63,279.76,277.96,276.19,274.4,272.66,270.94,269.27,267.62,265.93,264.17,262.43,260.65,258.82,257.03,255.25,253.39,251.55,249.75],"sd":[12.81,4.1,3.66,3.44,3.31,3.09,2.92,2.74,2.42,2.19,2.07,1.98,1.91,1.9,1.86,1.77,1.68,1.64,1.65,1.65,1.73,1.77,1.81,1.87,1.91,1.93,1.95,2.0,2.12,2.2,2.16,2.16],"p05":[285.15,296.45,295.32,293.86,291.89,290.42,288.81,287.74,287.14,285.88,284.25,282.64,280.47,278.51,276.68,275.62,273.91,272.26,270.25,268.64,266.69,264.75,262.7,260.79,259.01,257.16,255.5,253.79,251.73,249.96,248.34,246.52],"p50":[306.01,301.98,301.17,299.9,298.52,297.09,295.1,293.19,291.26,289.23,287.26,285.38,283.5,281.5,279.59,277.81,276.07,274.28,272.52,270.82,269.21,267.5,265.87,264.15,262.39,260.68,258.89,257.17,255.21,253.61,251.62,250.03],"p95":[322.89,309.75,307.45,305.6,303.88,302.04,300.16,297.94,295.67,293.4,291.11,288.75,286.52,284.49,282.54,280.5,278.56,277.3,275.56,273.77,272.23,270.61,268.92,267.08,265.51,263.56,261.84,260.17,258.6,256.58,254.64,252.67],"eq7_err":[0.0,0.71,-0.17,-0.88,-1.48,-2.0,-2.37,-2.68,-2.96,-3.25,-3.46,-3.7,-3.88,-4.13,-4.39,-4.73,-5.09,-5.44,-5.84,-6.26,-6.72,-7.21,-7.66,-8.03,-8.43,-8.78,-9.09,-9.44,-9.8,-10.07,-10.37,-10.71]},{"month":8,"n":114,"mean":[301.69,301.33,300.63,299.32,297.66,295.95,294.17,292.27,290.34,288.39,286.45,284.57,282.64,280.73,278.85,276.98,275.24,273.46,271.73,270.15,268.6,267.07,265.45,263.77,262.05,260.29,258.61,256.9,255.14,253.32,251.5,249.66],"sd":[11.62,4.35,3.58,3.2,2.97,2.77,2.58,2.43,2.35,2.26,2.17,2.13,2.11,1.99,1.84,1.78,1.74,1.73,1.71,1.67,1.71,1.82,1.92,1.92,1.91,1.93,1.82,1.8,1.75,1.75,1.78,1.82],"p05":[284.59,294.72,295.35,294.91,293.82,292.2,290.79,288.69,286.59,284.57,282.41,280.56,278.85,277.42,275.73,273.92,272.31,270.61,269.27,267.87,266.0,264.3,262.35,260.73,259.07,257.23,255.43,253.62,252.1,250.0,248.14,246.11],"p50":[300.68,301.07,300.73,299.23,297.65,295.88,294.22,292.25,290.27,288.59,286.65,284.76,282.86,280.83,278.88,276.98,275.36,273.45,271.69,270.08,268.47,266.95,265.38,263.7,262.15,260.33,258.63,256.95,255.24,253.45,251.6,249.75],"p95":[320.52,307.94,306.38,304.6,302.35,300.5,298.66,296.45,294.15,292.15,290.01,287.98,285.97,283.86,281.75,279.76,278.11,276.69,274.98,273.4,271.98,270.64,269.12,267.35,265.56,263.57,261.67,259.85,257.89,255.77,254.0,252.11],"eq7_err":[0.0,-1.69,-3.05,-3.78,-4.18,-4.51,-4.78,-4.94,-5.06,-5.16,-5.26,-5.43,-5.55,-5.69,-5.87,-6.05,-6.35,-6.63,-6.94,-7.41,-7.91,-8.44,-8.86,-9.24,-9.56,-9.85,-10.22,-10.57,-10.86,-11.09,-11.32,-11.52]},{"month":9,"n":131,"mean":[297.69,296.16,295.37,293.97,292.52,290.85,289.16,287.47,285.78,284.09,282.43,280.83,279.27,277.78,276.34,274.81,273.26,271.76,270.17,268.58,266.93,265.24,263.51,261.72,259.98,258.22,256.37,254.49,252.62,250.72,248.82,246.89],"sd":[12.21,5.14,4.75,4.55,4.23,4.08,3.86,3.5,3.28,3.13,3.05,3.05,3.01,2.92,2.86,2.92,2.85,2.79,2.77,2.71,2.67,2.66,2.66,2.69,2.59,2.52,2.48,2.44,2.39,2.31,2.25,2.22],"p05":[278.29,287.47,287.05,286.03,285.88,284.39,282.82,281.83,279.88,277.88,276.26,274.81,273.01,271.77,270.74,269.12,267.79,266.47,265.16,264.04,262.62,260.74,258.7,257.0,255.75,254.06,252.04,250.21,248.6,246.95,245.1,243.16],"p50":[297.87,296.48,296.04,294.39,293.09,291.6,290.06,288.31,286.56,284.54,282.95,281.22,279.68,278.37,276.89,275.54,273.81,272.31,270.55,268.9,267.62,265.65,263.87,262.17,260.43,258.57,256.65,254.87,252.89,250.84,249.05,247.1],"p95":[316.12,304.74,302.63,300.43,298.17,296.12,294.18,292.03,290.24,288.34,286.67,285.17,283.19,281.97,280.42,278.73,276.89,275.57,273.8,272.09,270.32,268.52,266.81,264.9,263.31,261.53,259.57,257.76,255.99,253.9,251.81,249.83],"eq7_err":[0.0,-0.42,-1.59,-2.13,-2.64,-2.92,-3.19,-3.45,-3.71,-3.98,-4.28,-4.63,-5.02,-5.49,-6.0,-6.42,-6.83,-7.28,-7.64,-8.01,-8.32,-8.58,-8.8,-8.96,-9.18,-9.37,-9.48,-9.54,-9.63,-9.69,-9.74,-9.76]},{"month":10,"n":109,"mean":[289.84,291.92,291.33,289.95,288.45,286.79,285.25,283.73,282.53,281.37,280.2,278.92,277.41,275.88,274.39,272.77,271.18,269.59,267.98,266.36,264.64,262.8,260.98,259.12,257.29,255.48,253.63,251.69,249.69,247.7,245.72,243.77],"sd":[12.55,5.55,5.11,4.99,4.89,4.86,4.64,4.42,4.01,3.72,3.67,3.66,3.57,3.41,3.34,3.24,3.21,3.16,3.11,3.08,3.08,3.13,3.09,3.07,3.11,3.1,3.15,3.17,3.18,3.16,3.13,3.0],"p05":[268.46,282.54,282.3,280.44,278.52,276.81,275.77,274.74,275.41,275.83,273.86,272.13,270.81,270.09,268.67,267.46,265.4,263.97,262.37,260.51,258.47,256.44,254.88,253.22,251.32,249.79,248.25,246.12,244.13,242.39,240.55,238.65],"p50":[291.43,291.36,291.23,290.31,288.68,286.9,285.78,284.28,282.86,281.34,280.68,279.32,277.63,276.1,274.8,273.22,271.99,270.05,268.49,266.84,265.14,263.5,261.59,259.57,257.72,256.21,254.41,252.49,250.32,248.25,246.32,244.23],"p95":[307.48,302.16,300.21,297.8,296.18,294.03,292.07,290.25,288.58,287.26,285.77,284.05,282.6,280.72,279.08,277.3,275.41,273.81,272.41,270.65,269.0,267.1,265.47,263.51,261.69,259.92,258.06,256.06,254.14,252.03,250.14,248.08],"eq7_err":[0.0,-3.84,-5.02,-5.4,-5.66,-5.77,-5.99,-6.24,-6.8,-7.41,-8.0,-8.48,-8.74,-8.97,-9.25,-9.4,-9.57,-9.75,-9.9,-10.04,-10.09,-10.01,-9.95,-9.87,-9.8,-9.75,-9.66,-9.49,-9.25,-9.03,-8.81,-8.62]},{"month":11,"n":103,"mean":[281.73,285.98,285.87,284.81,283.66,282.43,281.27,280.16,279.11,278.27,277.17,275.82,274.31,272.78,271.29,269.63,267.98,266.32,264.59,262.9,261.22,259.54,257.69,255.85,254.07,252.25,250.35,248.43,246.47,244.5,242.54,240.58],"sd":[13.36,4.0,3.87,4.12,4.25,4.36,4.38,4.43,4.22,3.73,3.3,3.13,3.1,3.1,3.17,3.17,3.08,3.06,3.09,3.07,3.12,3.22,3.22,3.17,3.11,3.18,3.26,3.29,3.29,3.25,3.2,3.2],"p05":[256.28,279.38,279.56,278.3,276.47,274.57,273.6,272.02,271.13,271.05,270.28,269.57,268.11,267.16,265.95,264.23,262.81,260.46,258.53,256.74,254.64,253.08,251.41,250.55,249.56,247.44,245.14,242.84,240.56,238.6,236.73,234.89],"p50":[283.92,285.92,285.81,285.01,284.08,283.46,282.38,281.12,280.06,278.83,277.34,275.98,274.52,272.95,271.57,270.03,268.47,266.7,264.83,263.41,261.78,260.29,258.39,256.44,254.77,253.13,251.18,249.25,247.34,245.49,243.42,241.27],"p95":[300.6,293.54,292.36,290.81,289.55,288.4,287.32,286.07,285.08,283.39,281.71,279.92,278.79,277.04,276.16,274.72,272.82,270.88,268.92,267.24,265.81,264.32,262.48,260.45,258.45,256.59,254.68,252.76,250.75,248.63,246.58,244.8],"eq7_err":[0.0,-5.82,-7.28,-7.79,-8.2,-8.54,-8.95,-9.41,-9.93,-10.66,-11.13,-11.35,-11.4,-11.44,-11.52,-11.43,-11.36,-11.26,-11.1,-10.98,-10.87,-10.76,-10.48,-10.2,-10.0,-9.74,-9.41,-9.06,-8.67,-8.27,-7.88,-7.49]},{"month":12,"n":88,"mean":[282.82,283.53,283.07,281.79,280.42,279.18,278.1,277.21,276.31,275.37,274.25,272.88,271.4,269.96,268.54,267.07,265.52,263.9,262.29,260.56,258.82,257.04,255.27,253.56,251.73,249.87,248.02,246.1,244.1,242.11,240.15,238.19],"sd":[10.82,3.86,3.82,4.1,4.4,4.52,4.51,4.11,3.83,3.51,3.57,3.66,3.71,3.78,3.69,3.62,3.57,3.53,3.48,3.43,3.48,3.55,3.57,3.4,3.38,3.44,3.49,3.53,3.57,3.61,3.64,3.66],"p05":[259.75,278.01,277.73,276.02,274.11,272.48,270.93,270.25,269.43,269.53,267.79,266.25,264.71,263.3,262.0,260.87,259.3,257.92,256.18,254.94,253.22,251.08,249.04,247.31,245.26,243.47,241.56,239.84,238.21,236.15,234.19,232.55],"p50":[285.08,283.28,283.31,281.42,279.8,278.64,278.34,277.32,276.62,275.97,274.51,273.27,271.65,270.2,269.17,267.3,265.54,264.11,262.35,260.64,258.91,256.97,255.53,253.86,252.14,250.06,248.05,246.0,243.89,241.93,239.99,238.04],"p95":[296.43,289.77,288.58,287.54,287.23,286.24,284.95,283.38,281.74,280.4,279.41,278.69,277.36,275.66,273.92,272.07,270.39,268.85,267.11,265.43,264.0,262.52,260.94,259.0,257.04,255.21,253.29,251.35,249.5,247.48,245.53,243.63],"eq7_err":[0.0,-2.31,-3.44,-3.76,-3.98,-4.34,-4.85,-5.56,-6.25,-6.91,-7.39,-7.61,-7.72,-7.88,-8.06,-8.18,-8.22,-8.2,-8.18,-8.05,-7.91,-7.73,-7.55,-7.43,-7.19,-6.93,-6.67,-6.35,-5.95,-5.55,-5.19,-4.82]}],"edw":[{"month":1,"n":48,"mean":[279.0,281.81,281.83,280.74,279.91,279.12,278.45,277.5,276.62,275.62,274.4,272.99,271.54,270.0,268.57,266.97,265.22,263.58,261.87,260.19,258.45,256.55,254.7,252.78,250.87,248.99,247.18,245.42,243.53,241.73,239.85,237.93],"sd":[11.52,3.55,3.33,3.4,3.67,4.04,4.42,4.56,4.81,4.88,4.83,4.73,4.69,4.6,4.54,4.53,4.64,4.74,4.73,4.72,4.76,4.86,4.91,4.91,4.85,4.72,4.56,4.39,4.18,3.99,3.78,3.63],"p05":[259.34,276.33,275.96,274.75,272.92,271.22,269.78,269.01,267.26,265.55,264.83,263.91,262.72,261.44,260.14,258.19,256.11,254.43,252.31,250.4,248.4,246.2,244.1,242.68,240.79,239.79,238.72,236.95,235.3,234.15,233.18,232.12],"p50":[280.83,281.69,281.67,280.82,280.33,279.65,279.06,278.19,277.69,276.9,275.71,274.21,272.77,271.26,269.57,267.83,266.62,265.06,263.6,261.77,259.67,257.63,255.75,253.94,252.05,249.99,247.94,246.19,244.49,242.69,240.42,238.34],"p95":[294.14,287.27,287.02,285.79,285.32,284.8,284.09,283.86,282.34,281.23,279.84,278.47,276.76,275.49,274.2,272.62,270.69,268.92,267.11,265.32,263.62,261.99,260.61,258.88,256.79,254.68,252.96,251.49,249.43,247.34,245.19,243.06],"eq7_err":[0.0,-4.31,-5.84,-6.25,-6.93,-7.64,-8.46,-9.03,-9.65,-10.15,-10.44,-10.52,-10.57,-10.54,-10.61,-10.52,-10.27,-10.13,-9.92,-9.75,-9.52,-9.12,-8.77,-8.35,-7.95,-7.57,-7.26,-7.0,-6.62,-6.32,-5.94,-5.53]},{"month":2,"n":74,"mean":[281.22,282.88,281.92,280.62,279.14,277.76,276.2,274.94,273.87,272.8,271.49,270.3,269.01,267.45,265.89,264.33,262.71,261.05,259.44,257.65,255.86,253.94,252.09,250.23,248.33,246.44,244.59,242.71,240.82,238.97,237.18,235.34],"sd":[12.73,5.69,5.63,5.73,5.71,5.69,5.8,5.71,5.57,5.47,5.52,5.44,5.36,5.33,5.3,5.28,5.25,5.28,5.25,5.2,5.27,5.3,5.29,5.16,5.09,5.04,4.96,4.91,4.85,4.76,4.67,4.61],"p05":[256.1,274.19,273.08,271.53,269.95,268.16,265.91,264.11,262.63,261.48,260.98,260.59,260.11,258.75,257.48,256.1,254.85,253.24,250.96,250.59,248.74,246.62,244.53,242.77,240.73,238.93,237.42,235.85,233.89,231.83,229.76,227.86],"p50":[281.98,283.6,282.76,281.89,280.57,279.28,277.61,276.0,274.63,273.09,271.66,270.5,269.3,267.6,265.76,264.05,262.48,260.58,259.01,257.52,255.8,254.08,252.21,250.22,248.11,246.25,244.3,242.53,240.82,238.73,236.91,235.02],"p95":[297.52,290.44,289.74,288.86,287.84,286.08,284.22,282.48,281.1,280.28,279.52,278.18,277.37,275.6,273.78,272.24,270.54,269.33,267.52,266.12,264.8,262.78,261.0,259.32,257.3,255.21,253.03,250.97,248.71,246.99,245.34,243.81],"eq7_err":[0.0,-3.21,-3.81,-4.07,-4.14,-4.32,-4.32,-4.61,-5.1,-5.59,-5.83,-6.2,-6.47,-6.47,-6.46,-6.46,-6.39,-6.29,-6.24,-6.01,-5.77,-5.41,-5.12,-4.81,-4.47,-4.14,-3.84,-3.52,-3.18,-2.89,-2.66,-2.37]},{"month":3,"n":135,"mean":[286.29,285.07,283.78,282.05,280.33,278.55,276.99,275.72,274.67,273.47,272.24,270.93,269.53,268.07,266.48,264.81,263.09,261.39,259.63,257.87,256.13,254.31,252.5,250.72,248.89,247.02,245.16,243.26,241.31,239.44,237.51,235.65],"sd":[9.76,5.4,5.52,5.69,5.79,5.86,5.87,5.91,5.88,5.87,5.8,5.73,5.69,5.7,5.69,5.7,5.71,5.75,5.8,5.83,5.85,5.89,5.9,5.85,5.78,5.72,5.48,5.27,5.14,4.95,4.82,4.62],"p05":[269.48,277.98,276.69,274.64,272.76,270.69,268.87,267.47,266.05,264.29,262.59,261.48,260.41,258.62,256.92,255.31,253.99,251.97,250.2,248.29,246.19,244.06,242.14,240.67,238.5,237.14,235.31,234.1,232.75,231.13,229.52,228.48],"p50":[286.47,283.94,283.03,281.14,279.3,277.44,276.29,275.56,275.27,273.89,272.54,271.32,269.88,268.47,266.91,265.26,263.56,261.94,260.01,258.41,256.73,255.0,253.15,251.12,249.09,247.17,245.13,243.26,241.27,239.21,237.18,235.14],"p95":[301.48,296.04,294.98,293.52,292.73,291.59,290.37,289.45,287.92,286.11,284.29,282.62,281.24,279.56,277.58,275.91,274.01,272.64,270.97,269.17,267.26,265.31,263.05,261.25,259.57,257.64,255.83,254.01,252.17,250.24,248.07,245.92],"eq7_err":[0.0,-0.46,-0.85,-0.79,-0.75,-0.65,-0.77,-1.17,-1.81,-2.28,-2.74,-3.1,-3.38,-3.6,-3.69,-3.7,-3.66,-3.64,-3.56,-3.48,-3.42,-3.28,-3.14,-3.04,-2.89,-2.7,-2.52,-2.3,-2.03,-1.84,-1.59,-1.4]},{"month":4,"n":91,"mean":[291.29,289.94,288.7,287.24,285.68,284.11,282.53,280.95,279.57,278.11,276.56,275.01,273.48,271.91,270.35,268.77,267.09,265.39,263.59,261.83,260.05,258.17,256.29,254.49,252.62,250.75,248.9,247.02,245.1,243.16,241.2,239.22],"sd":[14.82,5.19,4.88,4.78,4.56,4.5,4.48,4.42,4.46,4.57,4.61,4.53,4.44,4.22,4.17,4.21,4.25,4.31,4.33,4.32,4.24,4.24,4.21,4.08,4.01,3.95,3.91,3.81,3.77,3.7,3.69,3.68],"p05":[272.18,282.31,280.55,278.92,277.6,275.87,274.06,272.19,269.94,268.26,266.41,265.01,264.36,263.19,262.29,260.74,258.79,257.13,255.86,254.65,253.07,251.05,248.92,247.73,245.69,243.51,241.96,240.2,238.58,236.85,234.64,232.58],"p50":[292.36,289.55,289.28,288.35,286.53,285.31,283.89,282.09,280.43,278.96,277.4,276.09,274.88,272.92,271.4,269.72,268.02,266.6,264.56,262.78,260.85,259.26,257.37,255.45,253.39,251.57,249.77,247.8,245.85,243.97,242.03,239.85],"p95":[309.9,298.44,295.92,293.91,291.71,290.01,288.38,286.49,285.07,283.55,282.07,280.43,278.66,276.71,274.96,273.18,271.65,269.91,268.62,266.96,265.14,263.13,261.35,259.42,257.29,255.44,253.78,251.92,250.17,248.05,245.99,243.86],"eq7_err":[0.0,-0.45,-1.01,-1.35,-1.59,-1.82,-2.04,-2.25,-2.68,-3.02,-3.26,-3.52,-3.78,-4.01,-4.26,-4.47,-4.6,-4.69,-4.69,-4.73,-4.75,-4.67,-4.59,-4.59,-4.52,-4.45,-4.4,-4.32,-4.19,-4.05,-3.89,-3.71]},{"month":5,"n":56,"mean":[296.08,292.01,290.58,289.12,287.52,285.94,284.1,282.29,280.53,278.79,277.11,275.5,274.02,272.59,271.01,269.46,267.82,266.17,264.56,262.77,261.0,259.27,257.44,255.64,253.8,251.98,250.09,248.16,246.21,244.32,242.44,240.59],"sd":[11.98,5.17,4.88,4.65,4.55,4.45,4.44,4.45,4.36,4.26,4.14,4.07,3.99,3.95,3.86,3.84,3.83,3.89,3.8,3.74,3.7,3.71,3.71,3.71,3.66,3.62,3.66,3.67,3.63,3.57,3.46,3.22],"p05":[281.4,283.81,283.55,282.12,279.72,277.33,275.04,272.98,271.23,269.86,268.49,267.38,265.85,265.14,263.2,261.66,260.28,258.22,256.07,254.05,252.44,250.49,248.76,247.13,245.24,243.18,241.08,239.16,237.44,235.79,234.08,234.23],"p50":[297.49,291.58,290.13,288.27,287.06,285.8,284.24,283.04,281.24,279.94,278.43,276.57,275.09,273.42,271.98,270.44,268.96,267.26,265.41,263.43,261.95,260.2,258.65,256.78,254.69,252.69,250.81,248.99,246.93,244.95,242.88,241.11],"p95":[310.29,300.45,297.97,295.7,294.12,291.93,290.45,288.76,286.55,284.21,282.17,280.18,278.77,277.28,275.54,273.82,272.28,270.59,268.65,266.9,265.23,263.35,261.69,259.78,257.8,255.69,253.97,252.59,250.49,248.41,246.29,244.36],"eq7_err":[0.0,2.16,1.67,1.22,0.9,0.57,0.5,0.39,0.23,0.06,-0.17,-0.48,-0.91,-1.4,-1.73,-2.1,-2.38,-2.64,-2.95,-3.07,-3.21,-3.4,-3.48,-3.6,-3.68,-3.77,-3.79,-3.78,-3.75,-3.77,-3.8,-3.87]},{"month":6,"n":54,"mean":[299.0,298.13,297.27,295.9,294.69,293.15,291.47,289.78,288.08,286.36,284.69,283.06,281.56,280.05,278.39,276.69,274.89,273.12,271.38,269.61,267.81,266.06,264.18,262.37,260.56,258.72,256.96,255.06,253.2,251.26,249.3,247.3],"sd":[13.46,5.38,4.71,4.38,3.91,3.71,3.55,3.33,3.27,3.14,3.04,2.99,2.81,2.74,2.69,2.61,2.6,2.6,2.53,2.54,2.57,2.57,2.53,2.51,2.5,2.49,2.44,2.49,2.56,2.59,2.66,2.7],"p05":[282.89,288.65,289.43,288.11,287.94,286.46,285.49,284.0,282.63,281.4,279.79,278.39,277.06,275.3,274.01,272.18,270.42,268.47,266.87,265.17,263.45,261.41,260.3,258.24,256.58,254.76,252.56,250.47,248.76,246.68,244.58,242.38],"p50":[298.09,298.42,297.96,296.64,295.62,294.1,292.1,290.47,288.26,286.27,284.66,283.38,281.6,280.52,278.75,276.98,275.28,273.84,272.13,270.23,268.15,266.39,264.67,262.95,261.04,259.24,257.32,255.31,253.29,251.37,249.57,247.72],"p95":[319.43,306.41,304.39,301.99,299.69,297.71,296.12,294.66,293.3,291.41,289.39,287.48,285.85,283.94,282.39,280.43,278.39,276.78,274.97,273.04,271.1,269.82,267.91,265.91,263.86,261.84,260.01,258.37,256.39,254.69,253.29,251.26],"eq7_err":[0.0,-1.11,-2.24,-2.85,-3.63,-4.07,-4.38,-4.68,-4.97,-5.22,-5.55,-5.89,-6.38,-6.86,-7.19,-7.46,-7.65,-7.87,-8.11,-8.33,-8.52,-8.75,-8.86,-9.03,-9.2,-9.35,-9.57,-9.66,-9.79,-9.83,-9.85,-9.84]},{"month":7,"n":78,"mean":[306.84,301.95,300.55,299.01,297.53,296.05,294.38,292.66,290.89,289.11,287.25,285.39,283.46,281.6,279.75,277.93,276.15,274.39,272.7,271.02,269.41,267.73,266.13,264.4,262.63,260.83,258.94,257.11,255.3,253.45,251.56,249.78],"sd":[11.62,3.76,3.38,3.06,2.86,2.67,2.59,2.46,2.15,1.95,1.85,1.81,1.79,1.86,1.84,1.79,1.67,1.58,1.55,1.54,1.62,1.6,1.62,1.67,1.73,1.72,1.72,1.76,1.86,1.9,1.88,1.87],"p05":[291.16,296.36,294.85,293.86,292.65,291.58,289.75,288.04,287.29,285.96,284.62,282.65,280.47,278.51,276.89,275.62,273.91,272.47,270.51,268.64,266.96,265.0,263.65,261.88,260.3,258.38,256.58,254.48,252.5,250.47,248.82,246.7],"p50":[306.51,301.88,300.58,299.32,297.8,296.37,294.68,292.97,291.11,289.04,287.12,285.24,283.25,281.45,279.43,277.67,276.04,274.27,272.59,270.92,269.25,267.61,266.05,264.24,262.51,260.81,259.01,257.23,255.31,253.61,251.61,249.92],"p95":[322.96,307.82,305.94,303.32,301.68,300.02,297.95,296.13,294.12,291.82,289.91,288.3,286.06,284.19,282.43,280.53,278.53,276.49,274.75,273.06,271.48,269.97,268.81,266.96,265.91,263.63,261.86,260.17,258.24,256.13,254.25,252.48],"eq7_err":[0.0,2.72,1.94,1.3,0.61,-0.08,-0.59,-1.04,-1.45,-1.83,-2.15,-2.46,-2.71,-3.03,-3.35,-3.7,-4.1,-4.51,-4.99,-5.49,-6.05,-6.55,-7.13,-7.56,-7.97,-8.34,-8.64,-8.97,-9.34,-9.66,-9.95,-10.34]},{"month":8,"n":66,"mean":[301.71,300.98,300.21,298.97,297.38,295.65,293.87,291.99,290.07,288.11,286.16,284.23,282.31,280.41,278.6,276.75,275.07,273.34,271.63,270.04,268.53,267.07,265.48,263.86,262.17,260.42,258.78,257.13,255.46,253.63,251.82,249.97],"sd":[10.49,4.09,3.44,3.1,2.88,2.69,2.49,2.29,2.19,2.11,2.09,2.11,2.13,1.99,1.81,1.76,1.74,1.73,1.75,1.81,1.87,1.96,2.05,2.0,2.0,2.04,1.89,1.8,1.68,1.7,1.71,1.8],"p05":[285.25,295.3,295.26,295.6,294.04,292.3,290.48,288.46,286.36,284.16,282.29,279.95,278.26,277.35,275.6,273.92,272.52,271.15,269.33,267.78,265.93,264.06,262.34,260.57,258.45,256.86,255.09,253.66,252.36,250.46,248.53,246.6],"p50":[301.27,300.89,300.13,298.99,297.63,295.87,294.34,292.2,290.14,288.51,286.62,284.53,282.58,280.59,278.57,276.69,274.65,272.95,271.03,269.94,268.49,266.93,265.43,263.93,262.33,260.43,258.77,257.36,255.63,253.91,252.13,250.18],"p95":[318.88,307.49,306.08,303.77,301.73,299.65,297.32,295.3,293.35,291.46,289.36,287.4,285.68,283.4,281.39,279.71,278.32,277.1,275.4,273.81,272.13,270.85,269.04,267.5,265.6,263.61,261.64,259.81,257.85,255.82,254.05,252.15],"eq7_err":[0.0,-1.32,-2.6,-3.41,-3.87,-4.19,-4.47,-4.64,-4.76,-4.86,-4.95,-5.08,-5.21,-5.36,-5.6,-5.8,-6.17,-6.49,-6.83,-7.29,-7.83,-8.42,-8.88,-9.31,-9.68,-9.97,-10.39,-10.79,-11.16,-11.39,-11.63,-11.83]},{"month":9,"n":103,"mean":[297.59,295.6,294.92,293.57,292.2,290.61,288.97,287.34,285.69,284.06,282.44,280.89,279.4,277.94,276.51,274.98,273.45,271.92,270.33,268.72,267.07,265.36,263.64,261.84,260.1,258.32,256.5,254.61,252.74,250.84,248.94,247.01],"sd":[11.78,4.98,4.65,4.47,4.16,4.03,3.81,3.41,3.17,3.05,3.02,3.05,2.99,2.86,2.82,2.88,2.82,2.73,2.63,2.55,2.53,2.52,2.52,2.55,2.46,2.41,2.36,2.33,2.25,2.16,2.07,2.03],"p05":[278.25,287.66,287.02,285.66,285.73,284.16,282.69,281.89,280.05,277.94,276.26,274.65,273.01,272.38,270.86,269.5,268.07,266.89,265.66,264.6,262.92,260.8,258.96,257.11,256.01,254.57,252.86,250.81,248.68,247.04,245.47,243.6],"p50":[297.87,296.09,295.51,293.88,292.95,291.52,290.05,288.25,286.29,284.48,283.06,281.28,279.9,278.44,277.1,275.64,274.07,272.45,270.79,269.22,267.67,265.82,264.15,262.23,260.65,258.65,256.82,254.97,252.93,251.1,249.2,247.24],"p95":[315.87,304.63,302.45,300.09,297.83,295.66,294.0,291.62,289.63,288.17,286.66,285.41,283.78,282.19,280.45,278.84,277.26,275.68,273.76,272.06,270.29,268.42,266.73,264.83,263.29,261.47,259.41,257.67,255.61,253.56,251.51,249.79],"eq7_err":[0.0,0.04,-1.23,-1.84,-2.41,-2.78,-3.09,-3.41,-3.71,-4.03,-4.37,-4.77,-5.23,-5.72,-6.24,-6.66,-7.08,-7.5,-7.86,-8.21,-8.51,-8.75,-8.98,-9.13,-9.34,-9.52,-9.64,-9.71,-9.78,-9.83,-9.89,-9.91]},{"month":10,"n":74,"mean":[290.25,291.3,290.94,289.6,288.0,286.27,284.76,283.31,282.19,280.97,279.85,278.58,277.07,275.52,274.0,272.34,270.69,269.11,267.53,265.97,264.24,262.39,260.57,258.76,256.95,255.17,253.3,251.31,249.27,247.25,245.24,243.28],"sd":[12.04,5.13,4.76,4.76,4.68,4.68,4.45,4.22,3.8,3.6,3.57,3.6,3.54,3.41,3.35,3.25,3.24,3.19,3.14,3.1,3.09,3.17,3.12,3.07,3.13,3.14,3.23,3.26,3.26,3.25,3.18,2.99],"p05":[269.35,282.16,282.57,280.51,278.51,276.73,276.14,274.86,276.27,275.89,273.87,271.89,270.4,269.8,268.4,267.06,265.32,263.61,261.97,260.11,258.28,255.97,254.38,252.95,251.08,249.37,247.03,245.27,243.29,241.47,240.29,238.61],"p50":[291.62,290.81,290.98,289.87,288.34,286.66,285.41,284.21,282.88,281.27,280.72,279.17,277.6,276.08,274.75,273.15,271.69,269.83,268.13,266.76,264.78,263.48,261.57,259.49,257.53,255.86,254.02,251.97,250.06,248.04,246.01,243.89],"p95":[307.62,299.6,298.44,296.56,295.01,293.29,291.09,288.94,287.33,285.54,283.84,283.3,282.0,280.53,278.52,276.64,274.88,273.34,271.68,269.98,268.05,266.44,264.53,262.96,261.37,259.4,257.5,255.43,253.47,251.53,249.41,247.05],"eq7_err":[0.0,-2.83,-4.25,-4.68,-4.85,-4.9,-5.16,-5.49,-6.14,-6.69,-7.35,-7.85,-8.12,-8.34,-8.6,-8.71,-8.84,-9.03,-9.22,-9.43,-9.48,-9.41,-9.36,-9.32,-9.29,-9.28,-9.19,-8.97,-8.71,-8.46,-8.22,-8.04]},{"month":11,"n":71,"mean":[282.65,286.01,286.06,284.82,283.55,282.27,281.18,280.14,279.14,278.3,277.23,275.91,274.41,272.83,271.37,269.74,268.16,266.56,264.86,263.16,261.5,259.83,258.01,256.23,254.51,252.73,250.85,248.95,246.96,244.96,242.98,241.02],"sd":[13.56,3.96,3.98,4.18,4.27,4.44,4.42,4.45,4.16,3.75,3.3,3.09,3.08,3.11,3.1,3.08,3.0,2.99,3.05,3.05,3.09,3.13,3.08,2.94,2.86,2.91,3.03,3.1,3.09,3.07,3.05,3.08],"p05":[261.73,279.27,279.41,278.04,275.98,274.37,273.43,271.74,271.08,270.61,270.05,269.79,268.86,267.69,266.15,264.35,262.93,261.14,259.16,257.35,255.27,253.55,252.91,251.59,249.88,248.15,245.99,243.66,241.41,239.66,237.91,236.12],"p50":[283.99,286.44,286.75,285.42,284.13,283.46,282.55,281.45,280.37,279.1,277.38,276.03,274.58,272.97,271.65,270.2,268.74,267.19,265.4,263.73,262.23,260.52,258.65,256.78,255.07,253.25,251.62,249.98,247.91,245.84,243.74,241.81],"p95":[302.12,293.32,292.17,290.7,289.55,287.99,286.94,285.87,284.33,283.24,282.32,280.29,278.87,277.34,276.62,274.96,273.0,271.06,269.46,267.61,266.0,264.69,262.7,260.69,258.6,256.74,254.77,252.82,250.87,248.92,246.87,245.3],"eq7_err":[0.0,-4.95,-6.59,-6.94,-7.26,-7.57,-8.08,-8.62,-9.22,-9.97,-10.49,-10.76,-10.86,-10.86,-11.0,-10.96,-10.97,-10.96,-10.85,-10.74,-10.67,-10.59,-10.36,-10.17,-10.05,-9.85,-9.57,-9.26,-8.86,-8.45,-8.06,-7.7]},{"month":12,"n":65,"mean":[283.68,283.55,283.09,281.69,280.26,278.97,277.96,277.16,276.38,275.42,274.29,272.93,271.44,269.99,268.62,267.17,265.52,263.88,262.27,260.55,258.8,257.05,255.23,253.48,251.61,249.7,247.84,245.91,243.95,241.95,240.0,238.05],"sd":[10.86,4.21,4.09,4.27,4.54,4.58,4.53,3.97,3.56,3.33,3.45,3.49,3.51,3.58,3.45,3.38,3.37,3.31,3.25,3.2,3.28,3.4,3.44,3.49,3.54,3.58,3.65,3.7,3.71,3.72,3.73,3.75],"p05":[259.75,277.61,277.61,275.82,273.96,272.26,270.99,271.19,271.21,269.98,268.31,266.54,264.75,263.31,262.85,261.28,259.8,258.4,256.98,255.26,253.19,250.87,248.86,247.26,245.25,243.44,241.46,239.72,238.19,236.12,234.11,232.45],"p50":[285.34,283.35,283.11,281.45,279.56,278.41,278.14,276.71,276.44,275.74,274.4,273.26,271.62,270.21,269.19,267.37,265.56,264.12,262.38,260.89,259.04,256.88,255.53,253.86,252.15,249.87,247.78,245.81,243.64,241.87,239.69,237.8],"p95":[296.46,289.99,289.21,287.56,288.01,286.28,284.98,283.39,281.78,280.31,279.48,278.92,277.38,275.63,273.92,272.08,270.38,268.78,266.79,264.88,264.05,262.99,261.04,259.05,257.11,255.22,253.32,251.36,249.54,247.55,245.69,243.66],"eq7_err":[0.0,-1.49,-2.64,-2.85,-3.04,-3.37,-3.98,-4.79,-5.62,-6.29,-6.77,-7.02,-7.15,-7.32,-7.56,-7.73,-7.7,-7.67,-7.68,-7.57,-7.44,-7.3,-7.1,-6.97,-6.71,-6.42,-6.17,-5.86,-5.51,-5.13,-4.8,-4.46]}],"nid":[{"month":1,"n":24,"mean":[276.94,282.33,281.77,280.39,279.03,277.49,276.16,275.22,274.25,273.1,271.96,270.86,269.64,268.12,266.4,264.66,262.92,261.22,259.42,257.48,255.62,253.81,252.07,250.19,248.26,246.37,244.71,243.06,241.32,239.49,237.59,235.73],"sd":[9.98,3.35,3.95,4.22,4.62,4.86,4.92,5.14,5.3,5.38,5.14,5.05,5.13,5.2,5.17,5.17,5.25,5.35,5.47,5.52,5.61,5.68,5.74,5.9,5.98,6.06,6.25,5.57,5.05,4.66,4.39,4.13],"p05":[256.84,277.62,276.37,274.52,272.58,270.68,268.73,267.02,265.53,263.83,262.36,260.69,259.05,257.1,255.06,253.04,250.88,248.68,246.57,244.48,242.62,240.61,238.56,236.45,234.32,232.09,230.0,231.13,231.42,231.27,230.79,229.57],"p50":[278.54,281.89,281.73,280.21,278.79,277.12,275.56,274.26,273.02,271.83,271.07,270.39,269.73,268.9,267.1,265.58,263.9,262.09,260.58,258.74,256.9,254.91,253.18,251.48,249.59,247.63,245.62,243.45,241.34,239.3,237.38,235.39],"p95":[288.1,286.84,287.98,287.07,285.73,284.85,283.27,282.65,282.53,281.83,279.93,278.16,276.53,275.28,273.19,271.47,270.05,268.18,266.78,265.3,263.17,261.02,258.91,257.51,256.12,254.39,252.72,250.81,248.77,246.48,244.25,242.19],"eq7_err":[0.0,-6.85,-7.75,-7.81,-7.91,-7.82,-7.95,-8.46,-8.94,-9.25,-9.56,-9.92,-10.15,-10.08,-9.82,-9.52,-9.24,-8.99,-8.64,-8.16,-7.75,-7.4,-7.11,-6.68,-6.2,-5.77,-5.56,-5.36,-5.07,-4.7,-4.26,-3.85]},{"month":2,"n":36,"mean":[283.09,283.95,282.76,281.27,279.85,278.11,276.49,274.72,273.09,271.69,270.58,269.22,267.97,266.71,265.2,263.57,261.93,260.44,258.85,257.4,255.86,254.15,252.34,250.58,248.68,246.73,244.76,242.85,240.86,238.87,236.95,235.07],"sd":[9.47,4.22,4.27,4.6,5.04,5.22,5.39,5.5,5.56,5.41,5.31,5.32,5.49,5.52,5.56,5.62,5.6,5.4,5.31,4.93,4.92,4.96,4.9,4.68,4.53,4.48,4.43,4.46,4.49,4.53,4.53,4.45],"p05":[263.21,277.86,275.85,273.52,271.15,268.75,266.93,265.04,263.39,261.72,260.93,260.12,258.25,256.38,254.51,252.73,251.25,250.79,250.79,248.82,246.83,245.06,243.38,241.76,240.66,239.15,238.02,236.72,234.74,232.77,230.82,229.07],"p50":[285.28,284.2,283.4,281.77,279.68,278.06,277.12,275.55,273.91,272.49,271.24,270.01,268.42,266.87,265.02,263.53,262.26,260.69,259.03,257.59,256.27,254.69,252.57,250.6,248.35,246.48,244.56,242.73,240.34,237.93,235.76,234.17],"p95":[295.71,291.13,289.32,288.52,287.61,286.13,284.83,283.01,281.62,280.38,278.96,277.77,277.2,275.72,274.25,272.73,271.14,269.17,267.11,265.3,263.74,261.78,260.47,258.88,256.75,254.61,252.48,250.98,249.48,247.78,245.9,243.83],"eq7_err":[0.0,-2.46,-2.87,-2.99,-3.16,-3.03,-3.01,-2.84,-2.81,-3.01,-3.51,-3.75,-4.1,-4.44,-4.53,-4.51,-4.47,-4.58,-4.59,-4.74,-4.8,-4.69,-4.49,-4.33,-4.04,-3.68,-3.31,-3.0,-2.62,-2.23,-1.91,-1.64]},{"month":3,"n":48,"mean":[286.25,287.67,286.36,284.64,282.89,281.04,279.26,277.57,275.95,274.39,272.92,271.45,270.06,268.57,267.1,265.56,263.84,262.13,260.4,258.64,256.85,255.09,253.24,251.38,249.5,247.67,245.81,243.93,242.04,240.15,238.24,236.39],"sd":[13.33,5.17,5.28,5.4,5.51,5.49,5.55,5.62,5.77,5.83,5.84,5.74,5.78,5.74,5.75,5.63,5.69,5.66,5.66,5.61,5.58,5.6,5.53,5.35,5.19,5.1,4.99,4.84,4.7,4.51,4.36,4.18],"p05":[265.5,280.22,277.98,275.78,273.61,271.43,269.24,267.3,265.42,263.9,262.18,260.4,258.6,256.55,254.32,253.86,252.15,250.43,248.71,247.23,246.2,244.58,242.73,240.99,239.15,237.78,236.39,235.05,234.09,232.52,231.23,230.11],"p50":[286.64,287.07,286.33,284.7,283.29,281.14,278.86,277.04,276.2,274.56,273.14,271.7,270.15,268.75,267.77,266.5,264.81,263.02,261.42,259.76,257.89,256.33,254.49,252.53,250.43,248.45,246.5,244.51,242.27,240.34,238.53,236.92],"p95":[305.67,297.35,295.47,293.8,291.53,289.22,286.92,284.7,282.51,280.5,278.91,277.98,277.61,276.11,274.37,272.42,270.33,268.29,266.46,265.0,263.24,261.26,259.57,257.83,255.84,253.93,251.7,249.53,247.49,245.94,243.8,241.59],"eq7_err":[0.0,-3.09,-3.46,-3.42,-3.35,-3.18,-3.07,-3.06,-3.12,-3.24,-3.44,-3.65,-3.95,-4.13,-4.34,-4.48,-4.43,-4.4,-4.35,-4.27,-4.16,-4.07,-3.91,-3.72,-3.52,-3.36,-3.18,-2.98,-2.77,-2.56,-2.33,-2.15]},{"month":4,"n":34,"mean":[288.3,288.72,287.19,285.51,283.79,281.97,280.1,278.18,276.28,274.74,273.36,272.06,270.58,269.21,267.8,266.15,264.39,262.7,260.9,259.14,257.33,255.47,253.6,251.79,250.12,248.39,246.55,244.69,242.75,240.81,238.93,237.07],"sd":[10.14,5.87,5.84,5.95,6.15,6.28,6.4,6.52,6.61,6.57,6.29,5.82,5.9,5.97,6.11,6.14,6.16,6.09,6.09,6.11,6.19,6.26,6.21,6.17,5.87,5.64,5.47,5.33,5.22,5.14,4.98,4.65],"p05":[267.96,280.12,278.48,276.06,273.85,271.71,269.67,267.71,265.64,263.96,263.12,261.35,259.23,257.62,255.95,253.91,251.89,249.89,247.92,246.01,244.19,242.32,240.59,238.89,237.47,236.18,235.34,233.8,232.41,230.98,229.97,229.54],"p50":[288.38,288.17,287.0,285.03,283.77,282.14,280.25,278.6,276.59,274.96,274.19,272.93,271.87,270.51,269.89,268.61,266.78,265.05,263.11,261.16,259.39,257.59,255.55,253.56,251.72,249.92,247.97,245.9,243.86,241.81,240.0,237.9],"p95":[301.5,298.45,298.48,297.03,294.91,292.57,290.32,288.08,286.24,284.22,282.13,280.29,278.45,276.63,275.23,273.76,272.09,270.19,268.28,266.46,264.85,263.1,261.16,259.18,257.14,255.09,253.05,251.01,249.0,247.32,245.56,243.54],"eq7_err":[0.0,-2.15,-2.35,-2.4,-2.4,-2.31,-2.16,-1.98,-1.8,-1.99,-2.34,-2.76,-3.01,-3.37,-3.69,-3.77,-3.73,-3.77,-3.69,-3.66,-3.57,-3.45,-3.3,-3.22,-3.28,-3.27,-3.16,-3.03,-2.81,-2.6,-2.45,-2.31]},{"month":5,"n":36,"mean":[296.62,296.11,294.53,292.7,290.7,288.71,286.7,284.67,282.6,280.6,278.59,276.64,275.0,273.35,271.75,270.07,268.52,267.07,265.53,264.03,262.34,260.52,258.67,256.76,254.84,252.9,250.94,248.98,247.1,245.21,243.3,241.3],"sd":[10.92,5.29,4.81,4.58,4.51,4.5,4.48,4.49,4.51,4.46,4.42,4.42,4.49,4.48,4.4,4.46,4.48,4.49,4.51,4.4,4.38,4.42,4.43,4.43,4.45,4.47,4.47,4.47,4.32,4.16,3.96,3.87],"p05":[278.23,286.25,284.38,282.41,280.28,278.13,276.05,273.98,271.89,269.94,267.94,265.94,264.3,262.61,261.21,259.31,257.61,256.05,254.3,252.61,250.84,249.01,247.13,245.05,242.96,240.91,238.87,236.82,235.69,234.66,233.79,232.39],"p50":[301.03,297.43,296.12,293.81,291.72,289.85,287.9,286.18,283.98,281.87,279.64,277.82,276.11,274.47,272.89,271.43,269.73,267.99,266.31,264.62,262.63,261.02,258.94,256.98,255.06,253.15,251.35,249.51,247.47,245.81,243.76,241.69],"p95":[309.74,302.42,300.11,298.0,295.86,293.96,291.91,289.85,287.8,285.78,283.8,281.82,279.91,278.01,276.24,274.69,273.65,272.2,270.7,269.39,267.69,265.97,264.07,262.08,260.14,258.27,256.19,254.03,252.08,249.87,247.74,245.62],"eq7_err":[0.0,-1.42,-1.77,-1.86,-1.79,-1.73,-1.65,-1.55,-1.41,-1.33,-1.25,-1.23,-1.51,-1.79,-2.12,-2.37,-2.74,-3.22,-3.62,-4.04,-4.28,-4.39,-4.47,-4.49,-4.49,-4.48,-4.45,-4.42,-4.46,-4.5,-4.52,-4.44]},{"month":6,"n":32,"mean":[303.92,300.38,298.73,297.03,295.28,293.39,291.45,289.43,287.41,285.46,283.59,281.75,280.02,278.45,276.79,274.97,273.13,271.33,269.52,267.72,266.04,264.25,262.46,260.84,259.12,257.42,255.57,253.65,251.81,249.82,247.93,245.99],"sd":[10.43,7.02,6.62,6.25,6.03,5.92,5.67,5.51,5.37,5.15,4.84,4.54,4.4,4.27,4.29,4.25,4.2,4.1,4.08,4.1,4.13,4.13,4.2,4.2,4.02,3.98,4.01,4.0,4.08,4.17,4.29,4.38],"p05":[284.82,288.54,286.95,286.43,285.08,283.29,281.43,279.52,277.51,275.7,274.52,272.86,271.37,269.87,268.09,266.25,264.42,262.6,260.97,259.13,257.3,255.27,253.35,251.95,250.41,248.81,246.72,244.74,242.68,240.54,238.36,236.16],"p50":[306.76,303.94,301.51,299.03,297.31,295.09,293.02,290.85,288.47,286.13,284.64,282.9,280.89,279.58,278.12,276.44,274.56,272.55,270.72,268.85,266.82,265.19,263.13,261.25,259.51,258.01,256.29,254.65,252.89,250.95,249.2,247.8],"p95":[315.51,308.03,305.78,303.92,302.09,300.43,298.21,295.99,293.81,291.64,289.46,287.28,285.29,283.45,281.71,279.86,277.79,275.88,274.24,272.57,270.67,268.7,267.32,265.71,263.63,262.04,260.01,257.97,255.93,254.29,252.5,250.42],"eq7_err":[0.0,1.44,0.98,0.58,0.23,0.01,-0.15,-0.23,-0.32,-0.47,-0.7,-0.97,-1.35,-1.88,-2.32,-2.61,-2.87,-3.18,-3.46,-3.77,-4.19,-4.51,-4.82,-5.31,-5.69,-6.1,-6.35,-6.54,-6.8,-6.91,-7.12,-7.29]},{"month":7,"n":40,"mean":[302.26,303.38,302.41,301.19,299.57,297.7,295.73,293.69,291.66,289.68,287.64,285.66,283.65,281.69,279.77,278.02,276.27,274.43,272.6,270.79,269.0,267.4,265.55,263.73,262.03,260.3,258.59,256.89,255.16,253.27,251.52,249.7],"sd":[14.38,4.53,3.86,3.69,3.69,3.53,3.31,3.11,2.81,2.56,2.42,2.28,2.11,1.98,1.91,1.72,1.7,1.76,1.82,1.83,1.92,2.04,2.08,2.13,2.17,2.24,2.32,2.4,2.55,2.7,2.62,2.63],"p05":[273.75,297.61,296.43,294.03,291.55,289.4,288.8,286.92,285.76,284.95,284.16,282.56,280.96,278.83,276.46,275.75,274.09,272.26,270.12,268.78,266.65,264.5,262.3,260.76,258.94,256.93,255.16,253.74,251.59,249.24,246.93,244.59],"p50":[303.32,302.73,301.94,300.76,299.52,297.82,295.83,293.86,291.7,289.77,287.62,285.65,283.67,281.51,279.62,278.04,276.45,274.48,272.46,270.44,268.55,266.95,265.38,263.78,261.67,260.09,258.18,256.41,254.84,253.48,251.84,250.12],"p95":[320.85,311.21,308.86,306.89,305.52,303.25,300.98,298.66,296.32,293.98,291.63,289.33,287.04,284.72,282.55,280.22,278.47,277.3,275.7,274.19,272.49,270.59,269.28,267.25,265.31,263.45,261.46,260.01,258.65,256.84,254.98,253.28],"eq7_err":[0.0,-3.19,-4.28,-5.13,-5.57,-5.76,-5.86,-5.88,-5.92,-6.0,-6.02,-6.1,-6.15,-6.26,-6.41,-6.72,-7.03,-7.26,-7.49,-7.74,-8.02,-8.49,-8.69,-8.94,-9.3,-9.64,-9.99,-10.36,-10.69,-10.87,-11.18,-11.42]},{"month":8,"n":48,"mean":[301.66,301.81,301.22,299.79,298.06,296.35,294.57,292.66,290.73,288.78,286.86,285.03,283.09,281.16,279.2,277.3,275.47,273.64,271.87,270.3,268.69,267.07,265.41,263.66,261.88,260.1,258.37,256.59,254.71,252.9,251.06,249.23],"sd":[13.01,4.65,3.7,3.27,3.04,2.83,2.64,2.56,2.51,2.4,2.22,2.07,1.99,1.9,1.83,1.74,1.7,1.71,1.65,1.44,1.47,1.61,1.72,1.79,1.77,1.77,1.69,1.76,1.74,1.74,1.77,1.77],"p05":[284.19,294.63,296.04,294.9,293.77,292.35,290.99,289.23,287.35,285.29,283.4,281.55,280.01,278.19,276.0,274.06,272.29,270.49,268.82,268.05,266.5,264.46,262.75,261.43,259.28,257.39,255.75,253.92,251.9,249.76,247.87,246.04],"p50":[299.03,302.29,301.74,299.87,297.65,295.96,294.06,292.28,290.67,288.78,286.97,285.23,283.21,281.3,279.52,277.7,275.84,273.86,271.96,270.16,268.4,266.96,265.38,263.5,261.67,260.21,258.41,256.81,254.79,253.06,251.3,249.51],"p95":[324.63,308.11,306.41,304.86,302.63,301.01,299.22,297.22,295.21,293.07,290.85,288.63,286.41,284.14,281.92,279.68,277.65,276.17,274.23,272.22,271.03,270.13,268.98,266.9,264.87,263.23,261.68,259.86,257.72,255.6,253.63,251.84],"eq7_err":[0.0,-2.2,-3.66,-4.28,-4.6,-4.94,-5.21,-5.35,-5.46,-5.56,-5.69,-5.92,-6.03,-6.14,-6.24,-6.39,-6.6,-6.82,-7.1,-7.58,-8.02,-8.45,-8.84,-9.14,-9.4,-9.68,-9.99,-10.27,-10.44,-10.67,-10.88,-11.1]},{"month":9,"n":28,"mean":[298.09,298.23,297.05,295.41,293.7,291.71,289.84,287.96,286.08,284.22,282.4,280.6,278.79,277.2,275.71,274.16,272.59,271.18,269.58,268.05,266.43,264.78,263.06,261.28,259.56,257.83,255.91,254.02,252.18,250.3,248.39,246.46],"sd":[13.7,5.21,4.75,4.54,4.28,4.15,3.96,3.77,3.62,3.4,3.17,3.06,3.04,3.06,2.93,2.94,2.86,2.94,3.14,3.19,3.09,3.07,3.06,3.09,2.99,2.87,2.82,2.78,2.78,2.78,2.78,2.78],"p05":[279.01,287.6,289.03,288.13,287.62,285.8,283.76,281.9,279.92,278.14,276.86,275.39,273.54,271.5,270.29,268.97,267.78,266.35,264.73,263.27,262.13,260.48,258.65,256.99,255.74,253.98,251.99,250.17,248.44,246.58,244.66,242.66],"p50":[299.18,298.82,298.65,296.73,294.5,292.33,290.29,288.96,286.89,284.86,282.84,280.56,278.89,277.58,276.08,274.44,272.92,271.27,269.63,267.56,266.28,264.9,263.41,261.83,260.1,258.4,256.22,254.01,251.9,249.95,248.25,246.38],"p95":[318.0,305.51,303.25,301.73,299.84,297.71,295.34,292.9,290.6,288.68,286.53,284.37,282.58,281.12,279.57,278.03,276.44,275.06,273.8,272.97,271.35,269.53,267.94,266.45,264.56,262.8,261.07,259.32,257.4,255.41,253.4,251.38],"eq7_err":[0.0,-2.11,-2.89,-3.21,-3.46,-3.44,-3.53,-3.61,-3.7,-3.8,-3.95,-4.11,-4.26,-4.63,-5.1,-5.52,-5.92,-6.47,-6.83,-7.26,-7.61,-7.92,-8.17,-8.34,-8.59,-8.82,-8.87,-8.94,-9.07,-9.15,-9.2,-9.23]},{"month":10,"n":35,"mean":[288.99,293.22,292.14,290.7,289.4,287.89,286.29,284.62,283.24,282.22,280.93,279.62,278.12,276.63,275.21,273.67,272.21,270.6,268.94,267.19,265.49,263.65,261.84,259.9,258.01,256.15,254.32,252.49,250.57,248.66,246.75,244.8],"sd":[13.53,6.16,5.68,5.37,5.18,5.05,4.85,4.7,4.32,3.84,3.77,3.68,3.52,3.29,3.18,3.02,2.88,2.82,2.82,2.86,2.91,2.86,2.85,2.93,2.94,2.91,2.85,2.79,2.81,2.73,2.74,2.74],"p05":[265.35,284.67,284.46,282.34,280.2,278.66,277.19,275.91,275.66,275.84,274.15,272.28,271.66,270.87,269.91,268.34,266.86,265.08,263.28,261.46,259.85,258.08,257.04,255.14,253.0,250.86,248.81,247.18,245.0,243.07,241.29,239.58],"p50":[290.87,291.82,291.93,290.6,289.35,287.72,286.21,284.28,282.2,282.23,280.59,280.54,278.74,276.79,275.97,274.12,272.35,270.89,269.19,267.39,265.56,263.6,261.76,259.92,258.09,256.4,254.81,252.91,251.18,249.15,247.1,245.28],"p95":[307.41,304.26,301.93,299.63,297.36,295.27,293.4,291.44,289.58,287.94,285.93,284.54,283.16,281.59,279.96,278.19,276.31,274.59,273.01,271.22,269.36,267.62,265.72,263.94,262.11,260.45,258.66,256.56,254.45,252.3,250.44,248.56],"eq7_err":[0.0,-5.97,-6.64,-6.94,-7.38,-7.62,-7.76,-7.83,-8.2,-8.92,-9.37,-9.82,-10.06,-10.31,-10.63,-10.84,-11.12,-11.26,-11.34,-11.33,-11.38,-11.28,-11.21,-11.02,-10.87,-10.76,-10.67,-10.58,-10.41,-10.25,-10.08,-9.87]},{"month":11,"n":32,"mean":[279.69,285.9,285.46,284.79,283.9,282.78,281.45,280.2,279.05,278.21,277.03,275.61,274.07,272.66,271.1,269.37,267.6,265.79,264.0,262.33,260.6,258.91,256.98,255.0,253.09,251.18,249.23,247.27,245.37,243.5,241.58,239.6],"sd":[12.66,4.09,3.58,3.98,4.18,4.15,4.28,4.39,4.35,3.69,3.28,3.2,3.13,3.08,3.31,3.37,3.23,3.16,3.11,3.04,3.09,3.34,3.43,3.49,3.41,3.47,3.46,3.42,3.45,3.4,3.31,3.26],"p05":[253.69,280.1,280.84,279.68,278.12,276.41,274.45,272.54,271.17,271.34,270.73,269.1,267.23,265.45,263.28,261.4,260.03,258.47,256.92,255.3,253.56,251.64,249.72,247.8,246.57,244.88,243.17,241.27,239.29,237.26,235.41,233.64],"p50":[282.5,285.72,284.71,283.98,283.68,283.19,281.88,280.64,279.93,278.55,276.97,275.27,274.12,272.5,271.34,269.5,268.08,266.47,264.58,262.8,261.24,259.33,257.3,255.12,253.34,251.35,249.58,247.89,246.24,244.61,242.79,240.56],"p95":[295.97,293.33,291.77,291.67,289.79,288.48,287.16,286.12,285.02,283.3,281.54,279.87,278.34,276.9,275.12,273.7,271.79,270.01,268.01,266.1,264.37,263.24,261.31,259.37,257.44,255.48,253.5,251.61,249.94,247.93,245.88,243.88],"eq7_err":[0.0,-7.73,-8.81,-9.66,-10.29,-10.69,-10.88,-11.15,-11.52,-12.2,-12.55,-12.64,-12.62,-12.73,-12.69,-12.48,-12.23,-11.94,-11.67,-11.51,-11.31,-11.14,-10.73,-10.26,-9.88,-9.49,-9.05,-8.61,-8.24,-7.88,-7.48,-7.02]},{"month":12,"n":23,"mean":[280.37,283.46,283.0,282.09,280.86,279.77,278.49,277.34,276.12,275.23,274.14,272.75,271.28,269.87,268.34,266.78,265.51,263.96,262.33,260.6,258.89,257.03,255.37,253.76,252.05,250.36,248.51,246.61,244.55,242.58,240.59,238.59],"sd":[10.3,2.66,2.95,3.56,3.95,4.29,4.41,4.48,4.49,3.97,3.89,4.11,4.22,4.3,4.3,4.23,4.08,4.1,4.06,3.98,3.97,3.96,3.91,3.14,2.84,2.95,2.92,2.94,3.08,3.26,3.34,3.37],"p05":[261.98,279.15,278.24,276.77,275.18,273.06,270.94,268.93,266.99,268.06,267.21,266.29,264.97,263.39,261.81,260.21,258.51,256.61,255.78,254.87,253.74,252.71,251.68,249.88,247.92,246.27,244.62,242.55,240.36,238.21,236.03,234.05],"p50":[282.49,283.27,283.58,281.39,280.2,280.77,279.91,279.37,277.9,276.15,274.82,273.33,271.76,270.2,268.63,267.06,265.4,263.69,262.16,260.5,258.87,256.99,255.52,253.87,252.13,250.43,248.58,246.57,244.67,242.88,240.93,239.18],"p95":[292.29,287.49,287.79,287.52,286.97,285.97,284.11,282.43,281.39,280.43,278.96,278.39,276.98,275.48,273.58,271.82,270.3,268.82,267.54,265.61,263.81,262.16,260.44,258.56,256.55,254.54,252.5,250.59,248.76,247.36,245.41,243.37],"eq7_err":[0.0,-4.63,-5.7,-6.33,-6.63,-7.08,-7.34,-7.73,-8.04,-8.68,-9.14,-9.28,-9.35,-9.47,-9.47,-9.45,-9.71,-9.71,-9.61,-9.42,-9.24,-8.92,-8.8,-8.72,-8.55,-8.39,-8.08,-7.71,-7.2,-6.75,-6.3,-5.84]}],"vef":[{"month":1,"n":618,"mean":[282.7,283.21,281.68,280.19,278.75,277.37,276.09,274.92,273.8,272.6,271.3,269.96,268.57,267.17,265.65,264.06,262.46,260.82,259.14,257.44,255.72,253.98,252.17,250.33,248.49,246.63,244.8,242.94,241.09,239.23,237.36,235.53],"sd":[7.04,3.51,3.51,3.66,3.86,4.14,4.38,4.61,4.78,4.91,4.99,5.02,5.04,5.08,5.08,5.09,5.08,5.09,5.11,5.13,5.15,5.17,5.15,5.13,5.11,5.08,5.01,4.94,4.76,4.56,4.38,4.18],"p05":[270.83,277.19,275.72,274.07,272.08,270.27,268.42,266.69,264.87,263.57,261.97,260.49,258.95,257.45,255.72,254.12,252.44,250.48,248.85,247.21,245.61,243.6,241.68,240.13,238.56,236.75,235.24,233.76,232.77,231.56,230.05,228.64],"p50":[283.64,283.37,281.91,280.3,278.81,277.45,276.18,275.2,274.2,273.1,271.84,270.62,269.33,268.01,266.63,265.1,263.51,261.89,260.13,258.52,256.63,254.83,252.99,251.17,249.36,247.45,245.52,243.48,241.54,239.5,237.64,235.88],"p95":[292.42,288.67,287.51,286.42,285.06,283.78,282.88,281.56,280.3,279.6,278.22,276.75,275.48,274.21,272.61,270.96,269.23,267.7,266.09,264.33,262.62,260.83,259.07,257.08,255.33,253.49,251.69,249.83,247.7,245.87,243.8,241.94],"eq7_err":[0.0,-2.11,-2.17,-2.27,-2.43,-2.64,-2.95,-3.37,-3.84,-4.23,-4.52,-4.78,-4.98,-5.17,-5.25,-5.24,-5.24,-5.19,-5.11,-5.0,-4.87,-4.72,-4.5,-4.26,-4.01,-3.74,-3.51,-3.23,-2.98,-2.71,-2.44,-2.19]},{"month":2,"n":565,"mean":[285.32,285.05,283.29,281.44,279.63,277.89,276.22,274.69,273.31,271.96,270.65,269.26,267.83,266.35,264.83,263.23,261.67,260.02,258.3,256.58,254.88,253.11,251.3,249.52,247.73,245.94,244.14,242.32,240.49,238.68,236.87,235.04],"sd":[7.59,4.9,4.85,4.92,5.01,5.09,5.17,5.33,5.48,5.57,5.65,5.7,5.69,5.75,5.75,5.73,5.69,5.64,5.61,5.6,5.6,5.56,5.54,5.45,5.34,5.23,5.12,5.0,4.88,4.72,4.57,4.46],"p05":[273.41,276.35,274.88,273.18,271.14,268.94,266.76,264.77,262.76,261.15,259.23,257.66,256.23,254.51,253.06,251.31,250.16,248.52,247.04,245.43,243.65,242.51,240.2,238.98,237.34,235.71,234.2,233.4,232.06,230.54,228.96,227.69],"p50":[285.14,285.2,283.73,281.94,280.16,278.67,276.97,275.34,274.15,272.85,271.49,270.18,268.93,267.32,265.8,264.26,262.73,261.01,259.14,257.38,255.64,253.82,252.0,250.23,248.42,246.49,244.71,242.87,240.87,239.01,237.16,235.22],"p95":[297.06,292.8,290.71,289.26,287.5,285.81,283.97,282.64,281.33,279.86,278.38,276.86,275.33,273.81,272.44,270.8,269.2,267.46,265.62,263.96,262.39,260.66,259.01,257.05,255.24,253.6,251.98,250.24,248.15,246.14,244.22,242.51],"eq7_err":[0.0,-1.38,-1.28,-1.08,-0.93,-0.84,-0.83,-0.96,-1.23,-1.54,-1.88,-2.15,-2.37,-2.55,-2.69,-2.74,-2.83,-2.84,-2.78,-2.71,-2.66,-2.55,-2.4,-2.27,-2.14,-2.01,-1.86,-1.69,-1.52,-1.37,-1.21,-1.04]},{"month":3,"n":614,"mean":[289.39,288.41,286.45,284.4,282.37,280.38,278.43,276.55,274.76,273.1,271.6,270.08,268.6,267.05,265.49,263.86,262.19,260.49,258.8,257.08,255.34,253.55,251.76,249.93,248.1,246.28,244.47,242.65,240.77,238.89,237.06,235.25],"sd":[7.94,5.71,5.65,5.64,5.59,5.56,5.53,5.5,5.49,5.49,5.5,5.49,5.48,5.48,5.46,5.43,5.41,5.42,5.4,5.4,5.38,5.38,5.35,5.29,5.24,5.17,5.09,4.98,4.9,4.77,4.6,4.37],"p05":[277.14,279.79,278.01,276.15,274.3,272.47,270.58,268.58,266.68,264.68,262.79,260.9,259.39,257.89,256.13,254.41,252.59,250.71,249.27,247.56,245.65,244.19,242.43,240.46,238.64,236.6,234.78,233.54,231.73,230.42,229.09,228.19],"p50":[288.9,287.86,285.83,283.87,281.88,279.85,277.88,276.17,274.58,273.04,271.64,270.13,268.64,267.1,265.67,264.11,262.57,260.91,259.38,257.65,256.02,254.24,252.46,250.67,248.8,246.92,245.07,243.23,241.37,239.53,237.61,235.67],"p95":[303.0,298.93,297.46,295.17,293.0,290.72,288.69,286.67,284.61,282.82,280.83,279.08,277.36,275.75,274.06,272.19,270.26,268.23,266.16,264.49,263.08,261.28,259.16,257.14,255.39,253.45,251.49,249.59,247.39,245.61,243.74,241.71],"eq7_err":[0.0,-0.77,-0.57,-0.27,0.01,0.24,0.44,0.57,0.61,0.51,0.26,0.02,-0.25,-0.46,-0.65,-0.77,-0.85,-0.91,-0.98,-1.01,-1.02,-0.98,-0.95,-0.87,-0.79,-0.73,-0.68,-0.61,-0.48,-0.36,-0.27,-0.22]},{"month":4,"n":584,"mean":[294.4,293.02,291.07,289.02,286.91,284.8,282.71,280.68,278.69,276.75,274.89,273.1,271.42,269.74,268.1,266.51,264.85,263.2,261.55,259.84,258.11,256.31,254.46,252.61,250.77,248.9,247.02,245.14,243.26,241.35,239.46,237.57],"sd":[8.03,5.42,5.21,5.12,5.06,5.01,4.96,4.89,4.82,4.77,4.72,4.69,4.69,4.63,4.6,4.6,4.64,4.63,4.55,4.54,4.53,4.52,4.49,4.48,4.42,4.39,4.39,4.32,4.2,4.1,3.97,3.83],"p05":[282.12,283.92,282.24,280.25,278.18,275.84,274.04,271.95,270.01,267.92,266.16,264.64,262.54,260.96,259.23,257.36,256.05,254.21,252.67,251.0,249.09,247.12,245.2,243.73,242.06,240.61,238.83,237.08,235.37,233.62,232.01,230.07],"p50":[294.14,293.11,291.3,289.26,287.13,285.01,283.01,281.03,279.11,277.17,275.61,273.75,272.19,270.5,268.92,267.35,265.73,264.13,262.3,260.53,258.91,257.14,255.31,253.45,251.61,249.66,247.72,245.79,243.77,241.93,239.93,238.03],"p95":[307.29,301.75,299.1,296.82,294.62,292.35,290.15,287.92,285.64,283.45,281.58,279.5,277.7,275.89,274.19,272.4,271.1,269.45,267.48,265.62,263.94,262.13,260.27,258.39,256.35,254.62,252.65,250.69,248.49,246.53,244.66,242.72],"eq7_err":[0.0,-0.49,-0.42,-0.25,-0.01,0.23,0.44,0.6,0.72,0.78,0.76,0.68,0.49,0.29,0.06,-0.23,-0.44,-0.67,-0.89,-1.05,-1.2,-1.27,-1.3,-1.32,-1.35,-1.36,-1.35,-1.35,-1.34,-1.31,-1.29,-1.27]},{"month":5,"n":607,"mean":[298.48,297.15,295.23,293.19,291.08,288.93,286.81,284.66,282.51,280.4,278.31,276.28,274.31,272.43,270.65,268.96,267.28,265.68,264.07,262.4,260.7,258.97,257.15,255.31,253.45,251.59,249.69,247.79,245.9,243.98,242.07,240.18],"sd":[8.07,5.72,5.45,5.32,5.22,5.11,4.96,4.84,4.73,4.61,4.51,4.41,4.33,4.23,4.14,4.04,3.99,3.98,3.98,3.98,4.01,4.02,4.0,3.97,3.91,3.9,3.91,3.89,3.84,3.8,3.73,3.62],"p05":[286.62,286.26,284.93,282.98,281.09,279.24,277.58,275.59,273.7,272.08,270.14,268.3,266.41,264.64,262.89,261.32,259.61,258.12,256.49,254.82,253.2,251.35,249.4,247.46,245.39,243.66,241.57,240.0,238.31,236.57,234.8,233.39],"p50":[297.82,297.61,295.69,293.94,292.0,289.7,287.5,285.31,283.18,281.04,278.91,276.87,274.9,273.19,271.3,269.6,267.92,266.32,264.67,262.98,261.33,259.59,257.67,255.83,254.0,252.23,250.36,248.36,246.53,244.56,242.64,240.68],"p95":[311.02,305.77,303.39,300.92,298.36,296.03,293.74,291.37,289.03,286.81,284.63,282.53,280.41,278.48,276.61,274.67,272.78,271.18,269.49,267.74,266.07,264.23,262.43,260.71,258.74,256.81,255.08,253.21,251.32,249.32,247.42,245.4],"eq7_err":[0.0,-0.64,-0.7,-0.62,-0.49,-0.31,-0.16,0.01,0.19,0.33,0.44,0.5,0.5,0.41,0.21,-0.07,-0.36,-0.74,-1.1,-1.4,-1.67,-1.91,-2.07,-2.2,-2.31,-2.43,-2.51,-2.58,-2.65,-2.71,-2.77,-2.85]},{"month":6,"n":592,"mean":[304.82,303.74,301.89,299.9,297.83,295.71,293.52,291.33,289.14,286.96,284.82,282.75,280.76,278.82,276.95,275.09,273.3,271.56,269.86,268.14,266.41,264.68,262.93,261.16,259.35,257.53,255.68,253.81,251.95,250.03,248.11,246.15],"sd":[9.66,5.06,4.66,4.46,4.29,4.16,4.06,3.95,3.86,3.79,3.72,3.61,3.51,3.44,3.34,3.3,3.23,3.17,3.14,3.1,3.05,3.07,3.05,3.05,3.05,3.05,3.04,3.05,3.09,3.12,3.13,3.14],"p05":[292.57,294.96,293.45,291.92,290.2,288.28,286.23,284.27,282.53,280.38,278.26,276.2,274.26,272.43,270.47,268.69,267.03,265.49,263.76,261.98,260.58,258.98,257.18,255.44,253.44,251.4,249.63,247.68,245.72,243.7,242.17,240.25],"p50":[304.89,303.81,302.24,300.44,298.35,296.2,294.05,291.78,289.58,287.48,285.3,283.14,281.15,279.28,277.39,275.59,273.84,272.04,270.19,268.57,266.82,265.07,263.38,261.58,259.74,257.94,256.14,254.13,252.24,250.28,248.49,246.52],"p95":[316.97,311.51,308.56,306.23,303.84,301.54,299.2,296.84,294.69,292.5,290.15,287.99,285.85,283.76,281.66,279.72,277.7,275.78,273.88,272.1,270.45,268.91,267.18,265.53,263.63,261.79,259.95,258.07,256.22,254.29,252.32,250.43],"eq7_err":[0.0,-1.05,-1.32,-1.46,-1.52,-1.52,-1.46,-1.39,-1.33,-1.28,-1.26,-1.32,-1.45,-1.63,-1.89,-2.15,-2.49,-2.88,-3.3,-3.71,-4.11,-4.5,-4.87,-5.23,-5.54,-5.85,-6.13,-6.38,-6.64,-6.86,-7.06,-7.23]},{"month":7,"n":638,"mean":[308.22,306.86,304.99,303.0,300.91,298.77,296.59,294.4,292.18,289.98,287.81,285.69,283.6,281.57,279.6,277.7,275.85,274.05,272.3,270.59,268.93,267.26,265.62,263.96,262.27,260.6,258.94,257.23,255.52,253.75,251.96,250.19],"sd":[7.32,4.18,3.63,3.34,3.14,2.96,2.82,2.71,2.63,2.53,2.43,2.32,2.22,2.13,2.03,1.94,1.83,1.73,1.71,1.75,1.73,1.78,1.84,1.88,1.94,2.01,2.09,2.18,2.27,2.33,2.39,2.43],"p05":[296.89,300.0,298.63,297.15,295.6,293.71,291.65,289.59,287.61,285.67,283.66,281.89,279.98,278.13,276.18,274.39,272.88,271.13,269.39,267.66,265.84,264.12,262.4,260.77,258.84,256.97,255.05,253.16,251.21,249.42,247.59,245.78],"p50":[307.77,307.1,305.31,303.33,301.13,298.92,296.74,294.48,292.25,290.01,287.79,285.63,283.61,281.64,279.7,277.71,275.84,274.0,272.27,270.62,268.99,267.29,265.71,264.14,262.44,260.77,259.19,257.58,255.91,254.13,252.33,250.54],"p95":[318.71,313.31,310.59,308.06,305.76,303.61,301.32,299.01,296.67,294.32,291.97,289.6,287.18,284.86,282.84,280.9,279.0,277.05,275.04,273.59,271.83,270.22,268.59,266.95,265.08,263.35,261.86,260.22,258.71,256.96,255.27,253.43],"eq7_err":[0.0,-0.85,-1.19,-1.41,-1.52,-1.59,-1.62,-1.63,-1.63,-1.63,-1.67,-1.76,-1.88,-2.05,-2.29,-2.6,-2.95,-3.36,-3.82,-4.31,-4.86,-5.4,-5.97,-6.51,-7.04,-7.57,-8.12,-8.62,-9.12,-9.55,-9.97,-10.41]},{"month":8,"n":616,"mean":[306.92,305.68,303.82,301.86,299.78,297.64,295.47,293.28,291.09,288.92,286.76,284.67,282.62,280.62,278.68,276.76,274.93,273.18,271.52,269.88,268.29,266.71,265.16,263.55,261.92,260.31,258.65,256.93,255.2,253.39,251.59,249.76],"sd":[7.65,4.2,3.72,3.43,3.19,2.99,2.82,2.67,2.53,2.41,2.31,2.2,2.11,2.04,1.96,1.93,1.89,1.87,1.86,1.84,1.81,1.8,1.75,1.76,1.79,1.79,1.86,1.92,1.96,1.98,2.02,2.04],"p05":[295.26,299.0,297.42,296.07,294.39,292.41,290.52,288.64,286.92,284.82,282.69,280.71,279.01,277.17,275.33,273.36,271.63,269.94,268.38,266.75,265.21,263.65,262.14,260.53,258.86,257.14,255.24,253.38,251.4,249.53,247.56,245.73],"p50":[305.83,305.77,304.25,302.37,300.19,297.93,295.71,293.48,291.17,288.91,286.69,284.67,282.6,280.63,278.73,276.79,274.98,273.21,271.63,269.96,268.33,266.81,265.26,263.58,261.96,260.38,258.78,257.12,255.4,253.54,251.82,250.03],"p95":[317.14,311.7,309.04,306.59,304.22,301.85,299.48,297.1,294.74,292.53,290.19,287.84,285.66,283.58,281.69,279.78,277.92,276.19,274.39,272.86,271.29,269.59,268.06,266.35,264.72,262.93,261.3,259.72,258.1,256.28,254.42,252.65],"eq7_err":[0.0,-0.94,-1.25,-1.47,-1.57,-1.6,-1.61,-1.6,-1.58,-1.59,-1.61,-1.69,-1.82,-1.99,-2.23,-2.48,-2.83,-3.26,-3.78,-4.31,-4.89,-5.49,-6.11,-6.68,-7.23,-7.8,-8.32,-8.77,-9.22,-9.58,-9.96,-10.31]},{"month":9,"n":597,"mean":[302.17,301.92,300.09,298.1,296.01,293.88,291.74,289.62,287.53,285.47,283.48,281.54,279.69,277.93,276.21,274.57,272.95,271.33,269.73,268.15,266.52,264.94,263.3,261.59,259.84,258.06,256.25,254.42,252.59,250.71,248.79,246.88],"sd":[9.05,4.97,4.67,4.51,4.37,4.27,4.16,4.05,3.9,3.78,3.64,3.46,3.29,3.16,3.08,2.99,2.92,2.88,2.84,2.83,2.82,2.82,2.81,2.81,2.79,2.79,2.8,2.81,2.83,2.84,2.86,2.87],"p05":[288.82,293.93,292.43,290.58,288.78,286.72,284.92,282.93,280.89,279.04,277.22,275.47,273.89,272.37,270.89,269.23,267.8,266.63,265.01,263.29,261.56,260.06,258.53,256.8,254.79,252.98,251.03,249.16,247.26,245.28,243.36,241.48],"p50":[301.69,302.05,300.5,298.47,296.38,294.19,291.98,289.89,287.67,285.66,283.58,281.66,279.75,278.14,276.37,274.75,273.14,271.46,269.92,268.45,266.82,265.21,263.65,261.92,260.11,258.35,256.55,254.75,252.97,251.1,249.14,247.21],"p95":[314.88,309.61,307.19,304.87,302.58,300.39,298.17,295.88,293.75,291.57,289.28,286.99,284.8,282.83,280.8,279.03,277.19,275.38,273.73,272.42,270.61,268.97,267.34,265.55,263.71,261.9,260.06,258.31,256.4,254.48,252.58,250.77],"eq7_err":[0.0,-1.81,-2.05,-2.11,-2.09,-2.02,-1.94,-1.88,-1.85,-1.86,-1.92,-2.05,-2.26,-2.56,-2.91,-3.33,-3.77,-4.21,-4.67,-5.15,-5.59,-6.06,-6.48,-6.84,-7.15,-7.44,-7.69,-7.91,-8.14,-8.32,-8.47,-8.63]},{"month":10,"n":619,"mean":[294.44,295.22,293.54,291.68,289.76,287.8,285.88,284.05,282.39,280.78,279.23,277.67,276.12,274.66,273.16,271.64,270.07,268.51,266.9,265.25,263.55,261.84,260.09,258.28,256.46,254.62,252.78,250.93,249.05,247.15,245.24,243.32],"sd":[11.72,5.43,5.32,5.28,5.25,5.19,5.11,4.98,4.84,4.72,4.55,4.43,4.26,4.12,4.05,3.93,3.84,3.81,3.8,3.77,3.72,3.69,3.65,3.66,3.64,3.62,3.59,3.56,3.54,3.51,3.4,3.31],"p05":[281.12,285.94,284.15,282.09,279.9,278.19,276.4,274.5,273.12,271.77,270.31,268.99,267.78,266.6,265.25,264.02,262.56,261.05,259.48,257.84,256.67,254.74,253.04,251.11,249.5,247.54,246.12,244.67,242.4,240.63,238.73,237.17],"p50":[294.65,295.41,293.86,292.08,290.21,288.36,286.47,284.91,283.22,281.75,280.16,278.49,276.67,275.2,273.63,272.18,270.56,268.92,267.43,265.76,264.15,262.39,260.56,258.7,256.82,255.18,253.33,251.46,249.69,247.78,245.76,243.82],"p95":[308.04,303.54,301.6,299.8,297.68,295.54,293.56,291.24,288.88,287.0,285.4,283.51,281.7,280.04,278.31,276.76,275.11,273.49,271.87,270.43,268.7,266.83,265.09,263.36,261.37,259.5,257.5,255.56,253.59,251.66,249.6,247.58],"eq7_err":[0.0,-2.66,-2.86,-2.87,-2.83,-2.74,-2.7,-2.75,-2.95,-3.22,-3.54,-3.86,-4.19,-4.6,-4.97,-5.33,-5.63,-5.95,-6.22,-6.44,-6.62,-6.78,-6.91,-6.98,-7.03,-7.07,-7.11,-7.13,-7.12,-7.1,-7.06,-7.02]},{"month":11,"n":598,"mean":[287.51,288.57,287.03,285.47,283.9,282.3,280.83,279.45,278.15,276.84,275.55,274.21,272.73,271.26,269.72,268.15,266.56,264.99,263.35,261.66,259.93,258.19,256.41,254.63,252.84,251.02,249.18,247.32,245.45,243.57,241.69,239.8],"sd":[8.45,4.88,4.82,5.0,5.14,5.17,5.16,5.12,5.1,5.06,4.98,4.88,4.82,4.81,4.83,4.79,4.8,4.75,4.75,4.72,4.7,4.69,4.68,4.67,4.64,4.6,4.51,4.41,4.31,4.21,4.13,4.05],"p05":[273.77,280.87,279.16,277.37,275.37,273.46,271.67,270.0,268.22,266.95,265.79,264.65,262.93,261.74,260.13,258.95,257.07,255.62,254.4,252.83,251.61,249.8,248.26,246.25,244.49,242.8,241.1,239.66,237.97,236.25,234.62,232.71],"p50":[288.29,288.46,286.91,285.35,284.04,282.64,281.53,280.5,279.16,277.76,276.4,275.18,273.54,272.13,270.64,269.0,267.31,265.61,263.96,262.29,260.49,258.82,257.07,255.29,253.46,251.74,249.87,247.9,246.11,244.2,242.27,240.19],"p95":[300.28,296.35,294.49,292.95,291.49,289.86,288.25,286.48,285.01,283.38,282.16,280.86,279.01,277.61,276.22,274.39,272.71,271.15,269.55,267.94,266.19,264.62,262.98,261.18,259.35,257.66,255.83,253.96,252.23,250.21,248.26,246.31],"eq7_err":[0.0,-2.77,-2.94,-3.08,-3.23,-3.34,-3.57,-3.9,-4.31,-4.7,-5.13,-5.49,-5.72,-5.96,-6.13,-6.27,-6.38,-6.52,-6.6,-6.61,-6.59,-6.55,-6.49,-6.41,-6.33,-6.22,-6.09,-5.93,-5.77,-5.6,-5.43,-5.24]},{"month":12,"n":615,"mean":[283.03,284.05,282.71,281.42,280.2,279.02,277.86,276.71,275.63,274.44,273.16,271.75,270.26,268.78,267.26,265.68,264.08,262.42,260.73,259.04,257.37,255.63,253.87,252.07,250.26,248.4,246.52,244.64,242.74,240.84,238.95,237.06],"sd":[7.31,3.8,3.88,4.22,4.52,4.73,4.89,4.99,5.02,4.94,4.9,4.84,4.77,4.71,4.68,4.66,4.63,4.64,4.62,4.58,4.56,4.52,4.46,4.42,4.4,4.39,4.4,4.39,4.34,4.29,4.22,4.17],"p05":[271.43,277.87,276.36,274.48,272.68,270.88,269.32,267.53,266.22,265.27,264.06,262.77,261.25,259.92,258.16,256.92,255.02,253.21,251.35,250.09,248.16,246.59,245.23,243.69,241.95,240.53,238.55,236.55,235.01,233.18,231.39,229.83],"p50":[283.53,284.06,282.47,281.37,280.22,279.16,278.13,277.28,276.16,274.93,273.84,272.52,271.04,269.46,268.09,266.5,264.97,263.36,261.55,259.84,258.28,256.52,254.59,252.87,251.0,249.1,247.18,245.33,243.35,241.28,239.41,237.64],"p95":[293.88,290.4,289.06,288.27,287.54,286.28,285.38,284.13,282.7,281.44,280.03,278.53,276.95,275.19,273.56,271.79,270.3,268.44,266.67,264.77,263.22,261.37,259.53,257.61,255.89,254.11,252.34,250.52,248.63,246.6,244.82,242.82],"eq7_err":[0.0,-2.63,-2.89,-3.19,-3.57,-3.99,-4.43,-4.89,-5.4,-5.82,-6.13,-6.32,-6.44,-6.55,-6.64,-6.66,-6.65,-6.59,-6.5,-6.42,-6.34,-6.21,-6.05,-5.85,-5.63,-5.38,-5.09,-4.82,-4.52,-4.22,-3.93,-3.64]}]},"lapse":{"edw-nid":[{"month":1,"n":72,"L_mean":-5.986,"L_sd":0.626,"L_p05":-7.17,"L_p95":-5.077,"L_eq7":-5.946,"L_isa":-6.5},{"month":2,"n":110,"L_mean":-6.28,"L_sd":0.723,"L_p05":-7.424,"L_p95":-5.181,"L_eq7":-6.286,"L_isa":-6.5},{"month":3,"n":183,"L_mean":-6.537,"L_sd":0.588,"L_p05":-7.446,"L_p95":-5.612,"L_eq7":-6.715,"L_isa":-6.5},{"month":4,"n":125,"L_mean":-6.721,"L_sd":0.641,"L_p05":-7.781,"L_p95":-5.638,"L_eq7":-7.119,"L_isa":-6.5},{"month":5,"n":92,"L_mean":-6.968,"L_sd":0.681,"L_p05":-7.943,"L_p95":-5.89,"L_eq7":-7.68,"L_isa":-6.5},{"month":6,"n":86,"L_mean":-6.968,"L_sd":0.776,"L_p05":-8.04,"L_p95":-5.57,"L_eq7":-8.118,"L_isa":-6.5},{"month":7,"n":118,"L_mean":-7.135,"L_sd":0.609,"L_p05":-8.062,"L_p95":-6.167,"L_eq7":-8.547,"L_isa":-6.5},{"month":8,"n":114,"L_mean":-6.982,"L_sd":0.615,"L_p05":-7.863,"L_p95":-5.894,"L_eq7":-8.2,"L_isa":-6.5},{"month":9,"n":131,"L_mean":-6.534,"L_sd":0.668,"L_p05":-7.533,"L_p95":-5.489,"L_eq7":-7.815,"L_isa":-6.5},{"month":10,"n":109,"L_mean":-6.289,"L_sd":0.718,"L_p05":-7.389,"L_p95":-5.146,"L_eq7":-7.058,"L_isa":-6.5},{"month":11,"n":103,"L_mean":-5.989,"L_sd":0.593,"L_p05":-6.809,"L_p95":-4.831,"L_eq7":-6.276,"L_isa":-6.5},{"month":12,"n":88,"L_mean":-5.976,"L_sd":0.623,"L_p05":-6.999,"L_p95":-5.063,"L_eq7":-6.381,"L_isa":-6.5}],"edw":[{"month":1,"n":48,"L_mean":-5.919,"L_sd":0.626,"L_p05":-7.137,"L_p95":-4.994,"L_eq7":-6.012,"L_isa":-6.5},{"month":2,"n":74,"L_mean":-6.259,"L_sd":0.733,"L_p05":-7.41,"L_p95":-5.149,"L_eq7":-6.227,"L_isa":-6.5},{"month":3,"n":135,"L_mean":-6.486,"L_sd":0.536,"L_p05":-7.352,"L_p95":-5.582,"L_eq7":-6.716,"L_isa":-6.5},{"month":4,"n":91,"L_mean":-6.716,"L_sd":0.644,"L_p05":-7.748,"L_p95":-5.567,"L_eq7":-7.197,"L_isa":-6.5},{"month":5,"n":56,"L_mean":-6.851,"L_sd":0.704,"L_p05":-7.942,"L_p95":-5.727,"L_eq7":-7.66,"L_isa":-6.5},{"month":6,"n":54,"L_mean":-6.804,"L_sd":0.726,"L_p05":-7.821,"L_p95":-5.528,"L_eq7":-7.941,"L_isa":-6.5},{"month":7,"n":78,"L_mean":-7.079,"L_sd":0.515,"L_p05":-7.831,"L_p95":-6.23,"L_eq7":-8.697,"L_isa":-6.5},{"month":8,"n":66,"L_mean":-6.894,"L_sd":0.587,"L_p05":-7.824,"L_p95":-5.875,"L_eq7":-8.202,"L_isa":-6.5},{"month":9,"n":103,"L_mean":-6.468,"L_sd":0.655,"L_p05":-7.486,"L_p95":-5.466,"L_eq7":-7.805,"L_isa":-6.5},{"month":10,"n":74,"L_mean":-6.304,"L_sd":0.621,"L_p05":-7.348,"L_p95":-5.229,"L_eq7":-7.097,"L_isa":-6.5},{"month":11,"n":71,"L_mean":-5.931,"L_sd":0.571,"L_p05":-6.772,"L_p95":-4.72,"L_eq7":-6.365,"L_isa":-6.5},{"month":12,"n":65,"L_mean":-6.012,"L_sd":0.646,"L_p05":-7.038,"L_p95":-4.986,"L_eq7":-6.464,"L_isa":-6.5}],"nid":[{"month":1,"n":24,"L_mean":-6.122,"L_sd":0.605,"L_p05":-7.199,"L_p95":-5.179,"L_eq7":-5.813,"L_isa":-6.5},{"month":2,"n":36,"L_mean":-6.324,"L_sd":0.702,"L_p05":-7.438,"L_p95":-5.277,"L_eq7":-6.407,"L_isa":-6.5},{"month":3,"n":48,"L_mean":-6.681,"L_sd":0.694,"L_p05":-7.862,"L_p95":-5.776,"L_eq7":-6.712,"L_isa":-6.5},{"month":4,"n":34,"L_mean":-6.735,"L_sd":0.633,"L_p05":-7.676,"L_p95":-5.779,"L_eq7":-6.909,"L_isa":-6.5},{"month":5,"n":36,"L_mean":-7.149,"L_sd":0.6,"L_p05":-7.915,"L_p95":-6.027,"L_eq7":-7.711,"L_isa":-6.5},{"month":6,"n":32,"L_mean":-7.245,"L_sd":0.779,"L_p05":-8.105,"L_p95":-5.754,"L_eq7":-8.416,"L_isa":-6.5},{"month":7,"n":40,"L_mean":-7.246,"L_sd":0.747,"L_p05":-8.648,"L_p95":-6.102,"L_eq7":-8.255,"L_isa":-6.5},{"month":8,"n":48,"L_mean":-7.102,"L_sd":0.631,"L_p05":-7.952,"L_p95":-5.914,"L_eq7":-8.197,"L_isa":-6.5},{"month":9,"n":28,"L_mean":-6.775,"L_sd":0.66,"L_p05":-7.535,"L_p95":-5.718,"L_eq7":-7.853,"L_isa":-6.5},{"month":10,"n":35,"L_mean":-6.258,"L_sd":0.888,"L_p05":-7.449,"L_p95":-4.884,"L_eq7":-6.976,"L_isa":-6.5},{"month":11,"n":32,"L_mean":-6.117,"L_sd":0.619,"L_p05":-7.148,"L_p95":-5.28,"L_eq7":-6.079,"L_isa":-6.5},{"month":12,"n":23,"L_mean":-5.873,"L_sd":0.541,"L_p05":-6.614,"L_p95":-5.093,"L_eq7":-6.145,"L_isa":-6.5}],"vef":[{"month":1,"n":618,"L_mean":-6.233,"L_sd":0.629,"L_p05":-7.228,"L_p95":-5.195,"L_eq7":-6.369,"L_isa":-6.5},{"month":2,"n":565,"L_mean":-6.501,"L_sd":0.643,"L_p05":-7.575,"L_p95":-5.367,"L_eq7":-6.622,"L_isa":-6.5},{"month":3,"n":614,"L_mean":-6.909,"L_sd":0.655,"L_p05":-7.93,"L_p95":-5.767,"L_eq7":-7.015,"L_isa":-6.5},{"month":4,"n":584,"L_mean":-7.233,"L_sd":0.632,"L_p05":-8.26,"L_p95":-6.13,"L_eq7":-7.498,"L_isa":-6.5},{"month":5,"n":607,"L_mean":-7.475,"L_sd":0.689,"L_p05":-8.537,"L_p95":-6.285,"L_eq7":-7.891,"L_isa":-6.5},{"month":6,"n":592,"L_mean":-7.598,"L_sd":0.649,"L_p05":-8.592,"L_p95":-6.474,"L_eq7":-8.502,"L_isa":-6.5},{"month":7,"n":638,"L_mean":-7.555,"L_sd":0.609,"L_p05":-8.497,"L_p95":-6.519,"L_eq7":-8.83,"L_isa":-6.5},{"month":8,"n":616,"L_mean":-7.417,"L_sd":0.578,"L_p05":-8.253,"L_p95":-6.443,"L_eq7":-8.705,"L_isa":-6.5},{"month":9,"n":597,"L_mean":-7.165,"L_sd":0.62,"L_p05":-8.128,"L_p95":-6.098,"L_eq7":-8.247,"L_isa":-6.5},{"month":10,"n":619,"L_mean":-6.689,"L_sd":0.764,"L_p05":-7.853,"L_p95":-5.384,"L_eq7":-7.501,"L_isa":-6.5},{"month":11,"n":598,"L_mean":-6.333,"L_sd":0.612,"L_p05":-7.253,"L_p95":-5.238,"L_eq7":-6.833,"L_isa":-6.5},{"month":12,"n":615,"L_mean":-6.172,"L_sd":0.614,"L_p05":-7.163,"L_p95":-5.115,"L_eq7":-6.401,"L_isa":-6.5}]},"wind":{"edw-nid":[{"month":1,"n":72,"u":[-0.32,-0.63,-1.24,-1.67,-1.86,-1.56,-1.05,-0.44,0.15,0.73,1.22,1.79,2.44,3.06,3.69,4.19,4.72,5.26,5.9,6.6,7.12,7.47,7.81,8.14,8.57,9.04,9.47,9.93,10.46,10.86,11.19,11.54],"v":[0.26,-0.5,-1.41,-2.13,-2.58,-2.75,-2.84,-3.01,-3.23,-3.34,-3.53,-3.76,-3.91,-4.15,-4.44,-4.67,-4.79,-4.89,-5.05,-5.1,-5.1,-5.15,-5.14,-5.29,-5.4,-5.51,-5.52,-5.55,-5.74,-5.9,-6.0,-5.9],"spd":[2.81,2.9,4.31,5.42,6.33,6.71,7.15,7.64,8.17,8.66,9.17,9.49,9.81,10.27,10.89,11.53,12.01,12.56,13.21,13.81,14.31,14.71,15.12,15.64,16.18,16.81,17.34,17.93,18.6,19.3,20.02,20.72],"spd_p05":[0.5,0.37,0.73,0.99,1.06,1.19,1.78,2.02,2.37,2.26,2.52,2.8,3.36,3.08,3.38,3.85,3.73,3.79,3.69,4.02,3.86,3.7,3.97,3.65,3.98,4.85,5.24,4.78,5.57,6.02,5.63,5.83],"spd_p95":[6.69,8.56,11.73,10.81,13.14,14.56,14.73,15.68,16.68,19.11,21.21,20.92,22.38,23.48,24.19,26.35,27.03,27.98,29.66,30.1,30.71,31.83,32.83,34.57,35.44,35.93,36.83,38.14,38.93,39.7,40.47,41.24],"dir":[129.6,51.8,41.4,38.2,35.7,29.5,20.3,8.3,357.3,347.7,340.9,334.5,328.0,323.6,320.3,318.1,315.4,312.9,310.6,307.7,305.6,304.6,303.3,303.0,302.2,301.4,300.3,299.2,298.8,298.5,298.2,297.1]},{"month":2,"n":108,"u":[0.53,0.97,1.29,1.12,1.16,1.47,2.03,2.47,3.22,3.8,4.39,5.12,5.81,6.28,6.93,7.61,8.37,9.07,9.71,10.31,10.89,11.44,11.94,12.46,12.9,13.35,13.72,14.05,14.56,15.14,15.78,16.43],"v":[0.63,-0.4,-1.61,-2.32,-2.98,-3.25,-3.6,-3.85,-4.25,-4.63,-5.07,-5.34,-5.52,-5.62,-5.76,-6.0,-6.06,-6.22,-6.47,-6.82,-7.13,-7.22,-7.28,-7.48,-7.66,-7.84,-7.98,-8.15,-8.34,-8.46,-8.46,-8.45],"spd":[3.22,4.38,6.12,7.17,7.92,8.37,9.04,9.73,10.57,11.45,12.32,12.92,13.53,14.09,14.69,15.31,15.94,16.65,17.47,18.4,19.3,19.97,20.69,21.55,22.35,23.19,23.97,24.74,25.51,26.26,26.99,27.79],"spd_p05":[0.61,0.64,1.02,1.28,0.83,1.27,2.32,2.69,3.4,3.49,3.2,3.73,4.27,4.5,4.69,4.71,5.48,5.02,4.79,4.99,5.03,4.96,5.86,5.62,5.66,5.83,5.94,5.5,6.59,7.39,8.19,8.29],"spd_p95":[8.1,11.89,14.84,14.07,15.96,16.21,17.03,18.15,21.51,23.96,25.69,26.95,28.08,28.61,28.98,29.87,31.4,33.14,34.72,38.13,39.24,40.37,41.97,43.22,43.79,45.85,48.74,49.98,51.1,52.7,54.44,56.11],"dir":[220.1,292.4,321.3,334.1,338.6,335.6,330.6,327.3,322.8,320.6,319.1,316.2,313.6,311.8,309.7,308.2,305.9,304.4,303.7,303.5,303.2,302.2,301.4,301.0,300.7,300.4,300.2,300.1,299.8,299.2,298.2,297.2]},{"month":3,"n":178,"u":[1.35,1.69,1.69,1.57,1.68,2.01,2.46,3.02,3.7,4.47,5.28,6.16,6.94,7.65,8.4,9.06,9.67,10.28,10.93,11.64,12.39,13.03,13.75,14.49,15.16,15.81,16.48,17.23,17.88,18.41,18.94,19.47],"v":[0.89,0.23,-0.31,-0.75,-1.04,-1.18,-1.31,-1.37,-1.3,-1.41,-1.54,-1.56,-1.57,-1.61,-1.72,-1.72,-1.65,-1.65,-1.66,-1.74,-1.84,-1.82,-1.78,-1.74,-1.69,-1.67,-1.62,-1.53,-1.43,-1.35,-1.42,-1.56],"spd":[3.78,4.63,5.69,6.44,6.84,7.04,7.49,8.15,8.82,9.54,10.39,11.06,11.64,12.17,12.84,13.57,14.31,15.09,15.88,16.67,17.5,18.21,18.86,19.58,20.3,21.08,21.91,22.75,23.49,24.21,24.94,25.66],"spd_p05":[0.48,0.72,0.96,1.6,1.51,1.16,1.52,1.87,2.25,1.87,1.97,2.46,2.78,3.78,4.12,4.28,4.33,3.98,4.26,4.82,5.4,6.07,5.36,5.71,5.51,5.44,5.75,5.95,5.68,6.12,6.67,6.89],"spd_p95":[8.96,11.46,12.66,13.7,14.29,13.68,13.48,15.95,17.27,19.21,20.45,21.51,23.18,24.33,25.37,26.94,28.2,29.41,30.84,32.86,34.61,35.96,36.43,36.95,38.92,39.73,40.35,40.89,41.47,42.44,44.06,45.45],"dir":[236.6,262.1,280.5,295.6,301.9,300.4,298.0,294.4,289.3,287.5,286.3,284.2,282.8,281.9,281.6,280.7,279.7,279.1,278.6,278.5,278.5,278.0,277.4,276.8,276.4,276.0,275.6,275.1,274.6,274.2,274.3,274.6]},{"month":4,"n":124,"u":[1.77,2.15,2.19,1.93,2.0,2.35,2.76,3.18,3.7,4.15,4.74,5.37,5.99,6.57,7.17,7.94,8.59,9.25,9.83,10.38,10.9,11.41,11.92,12.44,12.83,13.3,13.82,14.3,14.82,15.36,15.77,16.12],"v":[0.79,0.33,-0.05,-0.57,-0.95,-1.3,-1.59,-1.86,-1.97,-2.12,-2.28,-2.55,-2.89,-3.13,-3.36,-3.56,-3.73,-3.83,-3.93,-3.97,-4.08,-4.28,-4.4,-4.53,-4.74,-5.0,-5.16,-5.26,-5.42,-5.56,-5.77,-5.97],"spd":[3.86,4.4,5.17,5.84,6.04,6.14,6.47,6.88,7.5,8.04,8.5,8.9,9.52,10.26,11.0,11.77,12.53,13.25,13.85,14.43,15.08,15.74,16.33,16.98,17.55,18.22,18.89,19.47,20.06,20.7,21.26,21.81],"spd_p05":[0.59,0.99,0.93,1.23,1.24,1.45,1.45,1.5,1.4,1.75,2.01,2.11,2.1,2.45,2.81,3.05,3.48,4.08,4.96,5.21,4.81,4.71,5.05,5.86,6.3,5.93,5.77,5.44,5.73,6.22,7.33,7.36],"spd_p95":[9.51,11.23,12.16,12.82,12.75,13.25,14.68,15.52,17.35,18.22,18.66,20.76,21.9,23.1,24.35,25.33,26.97,28.37,29.79,31.22,32.59,33.64,34.38,34.76,35.35,37.7,39.61,40.34,41.53,42.8,44.08,45.1],"dir":[246.0,261.4,271.4,286.6,295.4,298.8,299.9,300.3,298.0,297.1,295.7,295.4,295.8,295.5,295.1,294.2,293.5,292.5,291.8,290.9,290.5,290.5,290.2,290.0,290.3,290.6,290.5,290.2,290.1,289.9,290.1,290.3]},{"month":5,"n":86,"u":[1.31,1.29,1.56,1.44,1.36,1.28,1.13,1.12,1.08,1.09,1.17,1.63,2.28,2.85,3.41,3.97,4.47,4.86,5.23,5.58,5.9,6.26,6.7,7.27,7.77,8.21,8.63,8.97,9.31,9.72,10.22,10.7],"v":[0.94,1.1,0.57,-0.08,-0.27,-0.28,-0.31,-0.38,-0.56,-0.8,-0.93,-1.2,-1.35,-1.6,-1.85,-2.16,-2.46,-2.81,-3.03,-3.24,-3.48,-3.69,-3.83,-3.9,-4.0,-4.19,-4.34,-4.44,-4.54,-4.71,-4.9,-4.98],"spd":[3.72,4.17,4.33,4.58,4.74,4.65,4.65,4.87,5.34,5.98,6.49,6.82,7.27,7.85,8.48,9.05,9.83,10.6,11.32,12.02,12.72,13.34,13.92,14.63,15.31,16.09,16.86,17.55,18.17,18.83,19.46,19.97],"spd_p05":[0.59,1.05,1.03,1.42,1.04,1.19,1.3,1.37,1.32,1.91,2.12,1.53,1.35,1.82,1.94,1.4,2.34,2.5,2.73,3.01,3.61,3.48,3.53,4.08,4.69,4.97,5.11,4.84,5.47,6.13,6.55,7.36],"spd_p95":[8.18,8.72,10.52,10.61,10.31,9.7,9.3,10.34,11.62,13.0,14.15,14.55,15.85,17.15,18.19,18.11,19.18,20.32,21.65,22.71,23.15,24.56,25.51,26.47,27.7,29.15,31.4,32.1,32.65,33.6,34.26,35.31],"dir":[234.3,229.6,249.9,273.3,281.3,282.4,285.5,288.6,297.1,306.0,308.3,306.3,300.7,299.3,298.5,298.5,298.8,300.0,300.1,300.1,300.6,300.5,299.8,298.2,297.2,297.0,296.7,296.3,296.0,295.9,295.6,295.0]},{"month":6,"n":77,"u":[1.18,1.85,2.01,1.98,1.93,1.92,1.97,2.19,2.41,2.56,2.71,3.08,3.46,3.77,4.09,4.43,4.82,5.18,5.56,5.97,6.36,6.71,7.14,7.54,7.94,8.28,8.6,8.94,9.29,9.53,9.82,10.2],"v":[1.67,0.79,0.34,-0.04,-0.0,0.32,0.61,0.84,1.09,1.33,1.55,1.61,1.74,1.91,1.95,1.93,1.95,1.94,1.94,1.91,2.01,2.02,2.0,2.06,2.11,2.22,2.3,2.3,2.31,2.41,2.5,2.56],"spd":[4.02,3.71,3.89,4.33,4.49,4.46,4.62,4.97,5.43,5.88,6.25,6.28,6.37,6.53,6.76,7.06,7.49,7.96,8.45,9.01,9.58,10.12,10.56,10.97,11.39,11.8,12.24,12.73,13.16,13.41,13.74,14.18],"spd_p05":[0.85,0.86,0.61,0.79,0.9,0.51,0.69,1.05,1.3,1.68,1.53,1.32,1.52,1.67,1.76,2.03,2.03,1.9,1.98,2.53,3.12,3.5,4.08,4.69,4.53,4.41,4.17,3.42,3.01,2.98,3.02,3.36],"spd_p95":[9.87,9.3,9.72,11.23,11.39,11.53,11.81,12.08,12.89,13.49,13.7,14.01,14.15,14.41,14.72,15.23,15.28,15.83,16.56,17.42,18.43,19.4,20.33,21.11,22.2,23.23,24.26,25.28,27.1,27.54,27.98,28.43],"dir":[215.1,246.9,260.5,271.0,270.1,260.5,252.7,248.9,245.7,242.5,240.2,242.5,243.3,243.1,244.5,246.5,248.0,249.4,250.7,252.3,252.5,253.2,254.3,254.7,255.1,255.0,255.0,255.6,256.0,255.8,255.7,255.9]},{"month":7,"n":83,"u":[0.66,1.85,2.6,2.52,2.65,2.69,2.55,2.2,1.87,1.53,1.31,1.22,1.22,1.17,1.13,1.24,1.29,1.34,1.35,1.37,1.42,1.51,1.85,2.23,2.41,2.56,2.81,3.07,3.46,3.89,4.25,4.65],"v":[2.14,1.89,1.64,1.38,1.32,1.54,1.85,2.13,2.49,2.91,3.21,3.3,3.4,3.54,3.65,3.81,3.9,3.82,3.86,3.93,4.03,4.15,4.21,4.3,4.29,4.26,4.22,4.35,4.52,4.84,5.13,5.46],"spd":[3.74,3.94,4.41,4.29,4.47,4.55,4.57,4.62,4.91,5.28,5.71,5.79,5.87,6.0,6.14,6.32,6.49,6.6,6.84,7.1,7.34,7.61,7.83,8.09,8.3,8.54,8.84,9.16,9.55,9.87,10.11,10.43],"spd_p05":[0.52,0.62,0.61,0.82,1.21,1.18,1.04,1.37,1.83,1.83,2.09,2.07,2.01,2.01,1.93,1.83,1.83,2.49,2.61,2.0,1.5,1.52,1.75,1.98,1.81,2.14,2.69,3.09,3.06,2.83,2.94,3.45],"spd_p95":[8.32,8.67,10.1,8.85,8.64,8.99,8.51,8.79,9.25,9.68,10.37,11.07,11.06,10.84,10.85,10.9,11.9,12.75,13.2,13.58,14.3,15.26,15.23,14.64,14.61,14.74,15.15,16.21,18.19,17.82,18.27,19.33],"dir":[197.1,224.4,237.9,241.3,243.5,240.3,234.1,225.9,216.9,207.8,202.3,200.4,199.8,198.3,197.2,198.0,198.3,199.3,199.3,199.3,199.4,200.0,203.8,207.5,209.3,211.0,213.7,215.2,217.4,218.8,219.6,220.4]},{"month":8,"n":110,"u":[1.22,1.66,2.36,2.79,2.97,2.85,2.78,2.64,2.5,2.32,2.16,2.17,2.18,2.14,2.13,2.16,2.17,2.2,2.26,2.37,2.49,2.67,3.03,3.41,3.86,4.35,4.82,5.21,5.57,6.0,6.45,6.96],"v":[1.42,1.49,1.24,1.08,1.18,1.56,1.91,2.21,2.38,2.7,2.99,3.2,3.36,3.48,3.56,3.63,3.66,3.68,3.71,3.64,3.58,3.59,3.56,3.54,3.59,3.6,3.68,3.73,3.83,4.01,4.13,4.34],"spd":[3.29,3.85,4.2,4.65,5.0,5.12,5.25,5.37,5.52,5.77,6.14,6.17,6.18,6.23,6.3,6.4,6.55,6.76,6.99,7.15,7.35,7.68,7.8,7.9,8.13,8.5,8.97,9.53,10.03,10.42,10.86,11.39],"spd_p05":[0.58,1.0,0.86,0.98,0.68,1.46,1.47,1.19,1.25,1.17,1.51,1.14,1.31,1.57,1.51,1.61,1.72,1.6,1.95,1.51,1.47,1.54,1.28,1.01,1.04,1.49,1.67,1.6,1.56,2.23,2.06,2.61],"spd_p95":[7.75,8.99,9.13,9.85,9.94,10.01,10.52,9.88,11.2,11.71,11.75,11.81,11.95,12.2,12.87,13.43,13.51,13.86,14.25,15.04,15.51,15.14,15.23,16.06,17.02,18.36,19.4,20.1,20.5,20.87,21.4,22.17],"dir":[220.6,228.1,242.4,248.9,248.3,241.3,235.5,230.1,226.4,220.7,215.8,214.1,213.0,211.5,210.9,210.7,210.7,210.9,211.4,213.1,214.8,216.6,220.4,223.9,227.1,230.4,232.7,234.4,235.5,236.3,237.4,238.1]},{"month":9,"n":127,"u":[1.25,1.67,1.9,1.56,1.42,1.47,1.6,1.8,2.01,2.25,2.45,2.8,3.15,3.51,3.87,4.4,4.98,5.39,5.73,6.12,6.55,6.94,7.28,7.64,8.08,8.51,8.95,9.3,9.64,10.11,10.66,11.2],"v":[1.15,0.67,0.49,0.33,0.42,0.69,0.97,1.22,1.45,1.69,1.93,2.0,1.93,1.83,1.68,1.58,1.45,1.34,1.23,1.16,1.07,0.97,0.93,0.88,0.82,0.78,0.67,0.54,0.44,0.41,0.44,0.46],"spd":[3.93,3.79,4.67,5.36,5.72,5.87,6.13,6.54,6.94,7.31,7.74,7.98,8.14,8.32,8.55,8.87,9.29,9.78,10.28,10.77,11.25,11.72,12.14,12.58,13.12,13.76,14.45,15.12,15.69,16.21,16.79,17.36],"spd_p05":[0.69,0.68,0.79,1.06,1.3,1.51,1.42,1.7,1.63,1.37,1.51,1.98,2.09,2.02,1.65,1.8,1.62,2.04,2.33,2.57,2.78,2.9,2.63,2.71,2.34,2.12,2.24,2.47,3.46,3.52,3.54,3.77],"spd_p95":[10.53,9.3,11.13,12.05,12.18,12.19,12.53,12.92,14.75,15.72,16.46,17.29,18.14,19.05,19.44,20.16,20.84,21.55,21.88,21.93,22.83,23.71,24.36,27.07,29.56,30.05,31.22,33.32,35.87,38.42,39.58,40.22],"dir":[227.5,247.9,255.5,257.9,253.7,244.8,238.9,235.8,234.2,233.1,231.8,234.4,238.4,242.5,246.5,250.2,253.8,256.0,257.9,259.3,260.7,262.0,262.7,263.5,264.2,264.7,265.7,266.7,267.4,267.7,267.6,267.6]},{"month":10,"n":104,"u":[0.78,0.21,-0.12,-0.28,-0.25,0.06,0.34,0.67,1.06,1.59,2.15,2.69,3.19,3.78,4.49,5.06,5.57,6.07,6.59,7.08,7.49,7.76,7.97,8.23,8.42,8.65,8.97,9.14,9.4,9.79,10.21,10.61],"v":[-0.05,-0.2,-0.34,-0.54,-0.82,-0.98,-1.04,-1.09,-1.24,-1.36,-1.68,-1.92,-2.08,-2.14,-2.23,-2.37,-2.44,-2.56,-2.69,-2.8,-2.83,-2.95,-3.02,-2.96,-2.89,-2.94,-3.03,-2.99,-2.87,-2.79,-2.76,-2.62],"spd":[2.78,3.38,4.08,4.66,5.05,5.18,5.42,5.85,6.38,7.03,7.8,8.27,8.78,9.24,9.75,10.29,10.82,11.35,11.97,12.53,12.93,13.41,13.92,14.34,14.71,15.09,15.56,15.99,16.42,16.84,17.43,18.03],"spd_p05":[0.52,0.5,0.69,1.06,1.38,1.29,1.0,1.27,1.79,2.1,2.45,2.62,2.69,2.99,2.89,3.09,3.09,3.56,3.62,3.35,3.35,3.28,4.09,4.15,4.22,3.25,2.7,2.83,3.1,2.77,2.84,2.76],"spd_p95":[8.15,8.69,9.5,10.03,10.45,10.27,11.28,12.1,12.57,13.77,15.69,18.5,20.5,20.07,20.36,22.01,22.78,22.59,23.49,23.97,23.99,24.8,27.4,28.6,29.11,29.7,30.14,30.3,31.25,32.38,34.26,34.37],"dir":[273.8,314.7,20.4,27.1,17.1,356.7,341.8,328.6,319.3,310.6,308.1,305.6,303.1,299.5,296.4,295.1,293.6,292.8,292.2,291.6,290.7,290.8,290.8,289.8,288.9,288.8,288.7,288.1,287.0,285.9,285.1,283.9]},{"month":11,"n":100,"u":[0.26,0.46,0.74,0.64,0.69,1.33,2.18,3.06,3.95,4.87,5.57,6.2,6.82,7.33,7.9,8.56,9.13,9.54,10.01,10.53,11.17,11.86,12.63,13.47,14.18,14.73,15.3,15.86,16.34,16.88,17.48,18.04],"v":[0.35,0.05,-0.11,-0.25,-0.42,-0.47,-0.51,-0.58,-0.76,-0.83,-0.93,-0.92,-0.95,-1.04,-1.22,-1.43,-1.6,-1.65,-1.82,-1.93,-1.94,-2.0,-1.98,-2.04,-2.18,-2.26,-2.33,-2.38,-2.54,-2.75,-2.94,-3.0],"spd":[2.21,2.73,4.16,5.5,6.11,6.15,6.54,7.18,8.02,8.85,9.64,10.06,10.49,10.92,11.46,12.1,12.75,13.27,13.86,14.49,15.19,15.84,16.54,17.38,18.11,18.69,19.31,19.92,20.53,21.2,21.95,22.69],"spd_p05":[0.5,0.45,0.61,0.97,1.04,1.11,1.34,2.2,2.65,2.4,2.36,2.8,3.16,3.37,3.4,2.59,3.11,3.22,3.4,3.26,3.15,3.21,3.8,4.75,5.57,6.68,7.44,7.57,7.58,8.37,7.87,8.76],"spd_p95":[5.92,8.17,9.89,12.39,12.04,11.35,12.27,14.41,15.26,16.42,18.64,18.82,19.5,20.23,21.6,22.23,23.58,24.96,25.59,26.73,28.37,29.78,31.11,32.47,33.82,35.31,36.36,37.61,37.54,39.46,40.5,43.12],"dir":[216.1,263.2,278.6,291.5,301.4,289.5,283.2,280.8,280.8,279.7,279.5,278.4,277.9,278.1,278.8,279.5,279.9,279.8,280.3,280.4,279.9,279.6,278.9,278.6,278.7,278.7,278.7,278.5,278.8,279.3,279.6,279.5]},{"month":12,"n":86,"u":[0.73,0.87,0.81,0.72,0.89,1.26,1.95,2.86,3.73,4.59,5.37,5.96,6.58,7.17,7.89,8.59,9.26,9.91,10.5,11.06,11.53,12.02,12.59,13.23,13.72,14.13,14.57,15.06,15.61,16.04,16.52,17.01],"v":[0.58,0.02,-0.59,-1.02,-1.5,-1.89,-2.15,-2.2,-2.39,-2.67,-2.84,-2.95,-3.19,-3.36,-3.44,-3.53,-3.65,-3.8,-3.79,-3.83,-3.93,-4.08,-4.21,-4.35,-4.55,-4.86,-5.21,-5.47,-5.68,-5.88,-6.02,-6.12],"spd":[2.7,3.41,4.73,6.07,6.99,7.52,8.12,8.93,10.01,11.07,11.82,12.19,12.76,13.37,13.96,14.56,15.17,15.86,16.63,17.35,17.93,18.46,19.01,19.65,20.3,21.03,21.81,22.57,23.3,23.96,24.63,25.39],"spd_p05":[0.53,0.52,0.86,1.51,1.11,1.82,2.74,3.79,3.64,3.8,3.81,4.26,4.75,5.39,5.54,5.12,4.95,4.43,4.28,4.04,3.81,4.14,4.41,3.4,3.45,4.38,4.17,4.35,4.83,5.26,5.94,7.37],"spd_p95":[7.85,9.21,11.11,11.7,13.7,14.27,15.17,15.76,17.37,18.23,19.53,20.51,21.54,21.91,21.82,23.55,24.89,26.58,28.58,29.2,30.1,29.96,30.37,32.14,33.27,33.65,34.13,34.36,35.62,35.59,36.38,37.31],"dir":[231.7,268.9,306.3,324.6,329.5,326.3,317.7,307.6,302.6,300.2,297.9,296.3,295.9,295.1,293.6,292.4,291.5,291.0,289.8,289.1,288.8,288.7,288.5,288.2,288.3,289.0,289.7,290.0,290.0,290.1,290.0,289.8]}],"nid":[{"month":1,"n":24,"u":[0.47,0.12,0.17,0.15,0.18,0.5,0.84,1.17,1.51,1.84,2.15,2.71,3.28,3.85,4.42,4.99,5.56,6.12,6.69,7.26,7.83,8.2,8.41,8.63,8.84,9.06,9.38,9.81,10.45,11.03,11.62,12.2],"v":[0.41,-0.25,-0.83,-1.27,-1.53,-1.62,-1.73,-1.83,-1.94,-2.04,-2.13,-2.1,-2.06,-2.02,-1.99,-1.95,-1.92,-1.88,-1.84,-1.81,-1.76,-1.73,-1.75,-1.77,-1.79,-1.81,-1.84,-1.69,-1.48,-1.27,-1.06,-0.85],"spd":[2.02,2.51,2.76,3.55,4.3,4.82,5.53,6.31,7.15,8.04,8.88,9.07,9.28,9.55,9.9,10.33,10.82,11.37,11.95,12.56,13.2,13.63,13.93,14.3,14.7,15.15,15.74,16.55,17.09,17.72,18.4,19.12],"spd_p05":[0.21,0.25,0.64,0.83,1.06,1.19,1.79,2.12,2.35,2.55,2.75,3.19,3.38,3.26,3.69,3.88,4.12,4.46,4.87,5.03,5.2,4.7,3.71,3.46,3.31,3.21,3.29,3.69,3.58,3.82,4.35,5.06],"spd_p95":[6.04,6.3,6.94,8.89,8.68,9.63,11.06,13.36,15.73,18.23,20.66,21.41,22.18,22.98,23.8,24.66,25.53,26.43,27.35,28.28,29.24,30.54,32.09,33.65,35.21,36.77,38.33,39.88,40.44,40.97,41.5,42.04],"dir":[228.6,333.4,348.6,353.4,353.4,342.7,334.1,327.4,322.1,317.9,314.7,307.7,302.1,297.7,294.2,291.4,289.0,287.1,285.4,284.0,282.7,281.9,281.7,281.6,281.4,281.3,281.1,279.8,278.1,276.6,275.2,274.0]},{"month":2,"n":34,"u":[0.01,0.58,0.96,1.35,1.69,1.88,2.07,2.25,2.44,2.63,3.0,3.75,4.52,5.29,6.06,6.84,7.61,8.38,9.15,9.93,10.7,11.14,11.49,11.84,12.18,12.53,12.85,13.11,13.55,14.04,14.53,15.03],"v":[0.31,0.09,-1.14,-2.37,-3.44,-3.94,-4.44,-4.94,-5.44,-5.94,-6.45,-6.82,-7.2,-7.58,-7.95,-8.33,-8.71,-9.08,-9.46,-9.84,-10.16,-10.35,-10.59,-10.82,-11.05,-11.28,-11.5,-11.76,-12.04,-12.32,-12.54,-12.75],"spd":[2.55,4.55,5.07,6.33,7.38,7.83,8.58,9.45,10.41,11.43,12.44,13.12,13.86,14.65,15.49,16.36,17.26,18.2,19.16,20.15,21.14,21.77,22.42,23.09,23.83,24.61,25.39,26.08,26.71,27.37,28.01,28.68],"spd_p05":[0.5,0.61,1.05,0.98,0.63,0.89,1.72,2.28,2.94,3.27,3.55,3.28,3.08,2.96,2.91,2.95,3.07,3.32,3.62,3.95,4.32,4.08,3.63,3.23,2.91,2.69,2.59,2.99,3.19,3.39,3.6,3.95],"spd_p95":[5.73,12.38,13.35,14.95,16.18,15.85,17.27,19.54,22.24,25.05,26.87,26.37,25.86,25.3,26.71,30.49,34.59,37.32,40.08,43.9,47.72,49.85,52.01,54.21,55.81,56.79,57.6,58.37,58.78,59.1,59.45,59.85],"dir":[182.6,261.5,320.0,330.4,333.8,334.5,335.0,335.5,335.9,336.2,335.1,331.2,327.9,325.1,322.7,320.6,318.8,317.3,315.9,314.7,313.5,312.9,312.7,312.4,312.2,312.0,311.8,311.9,311.6,311.3,310.8,310.3]},{"month":3,"n":44,"u":[0.1,0.97,1.3,1.63,2.05,2.63,3.21,3.79,4.38,4.96,5.55,6.32,7.12,7.92,8.71,9.51,10.31,11.11,11.91,12.71,13.53,14.28,14.9,15.51,16.14,16.76,17.38,18.0,18.57,19.15,19.74,20.32],"v":[0.75,0.99,0.58,0.17,-0.08,-0.09,-0.11,-0.12,-0.14,-0.15,-0.14,-0.07,-0.02,0.04,0.09,0.15,0.21,0.26,0.32,0.38,0.43,0.41,0.41,0.41,0.38,0.36,0.32,0.29,0.34,0.34,0.34,0.34],"spd":[1.65,3.86,4.0,4.49,5.08,5.72,6.51,7.37,8.29,9.24,10.17,10.79,11.46,12.19,12.97,13.78,14.62,15.49,16.37,17.26,18.23,19.13,19.84,20.57,21.35,22.17,22.99,23.73,24.38,25.05,25.75,26.47],"spd_p05":[0.21,0.92,0.6,0.95,0.68,1.14,1.58,1.95,2.36,2.64,3.01,3.13,3.96,4.01,4.04,4.05,3.91,3.77,3.88,4.67,5.47,5.24,5.0,4.66,4.42,4.08,3.73,3.68,4.04,4.06,3.98,3.83],"spd_p95":[3.8,10.53,10.41,11.12,11.54,11.45,13.14,15.3,17.8,19.54,20.38,21.29,22.93,24.03,25.21,26.44,27.7,29.04,30.56,31.75,32.96,33.99,35.0,36.52,38.65,39.59,40.21,41.42,41.1,41.0,42.55,44.44],"dir":[187.8,224.5,246.0,263.9,272.2,272.1,272.0,271.9,271.8,271.8,271.4,270.7,270.1,269.7,269.4,269.1,268.8,268.6,268.5,268.3,268.2,268.3,268.4,268.5,268.6,268.8,268.9,269.1,268.9,269.0,269.0,269.0]},{"month":4,"n":33,"u":[0.21,0.1,0.32,0.54,0.88,1.32,1.75,2.18,2.62,3.05,3.5,4.15,4.8,5.44,6.09,6.74,7.39,8.03,8.68,9.33,10.06,10.75,11.4,12.06,12.71,13.37,13.99,14.6,15.07,15.46,15.86,16.3],"v":[0.28,0.42,-0.14,-0.7,-1.08,-1.32,-1.56,-1.8,-2.04,-2.28,-2.5,-2.71,-2.93,-3.15,-3.37,-3.59,-3.82,-4.04,-4.26,-4.48,-4.78,-5.24,-5.71,-6.17,-6.64,-7.1,-7.52,-7.8,-8.07,-8.35,-8.63,-8.98],"spd":[1.28,3.3,3.32,3.95,4.42,4.68,5.1,5.61,6.22,6.9,7.55,7.94,8.41,8.95,9.59,10.28,11.0,11.74,12.49,13.26,14.13,14.98,15.76,16.58,17.42,18.29,19.13,19.81,20.33,20.79,21.29,21.84],"spd_p05":[0.32,1.09,0.86,1.17,1.03,1.36,1.71,1.12,1.06,1.63,1.99,2.03,1.92,1.79,2.12,2.71,3.32,4.05,4.89,5.11,5.51,5.45,5.76,6.19,6.6,6.7,6.85,7.02,7.29,7.02,6.77,6.54],"spd_p95":[2.1,9.99,9.81,10.93,11.57,11.33,12.08,13.89,14.27,14.66,14.9,14.96,14.93,16.23,18.01,19.79,21.58,22.91,24.18,25.44,26.71,28.26,29.89,31.55,33.67,36.46,39.02,40.42,41.75,43.11,44.18,45.06],"dir":[217.1,193.0,293.4,322.0,320.7,315.0,311.7,309.5,307.9,306.7,305.6,303.2,301.4,300.1,299.0,298.1,297.3,296.7,296.1,295.7,295.4,296.0,296.6,297.1,297.6,298.0,298.3,298.1,298.2,298.4,298.6,298.8]},{"month":5,"n":33,"u":[-0.13,-0.76,-0.33,0.1,0.3,0.21,0.12,0.03,-0.05,-0.14,-0.13,0.5,1.19,1.87,2.55,3.23,3.92,4.6,5.28,5.96,6.62,7.11,7.48,7.85,8.22,8.59,8.96,9.48,9.96,10.37,10.79,11.2],"v":[0.65,1.36,0.48,-0.4,-0.87,-0.88,-0.89,-0.9,-0.91,-0.92,-0.91,-1.24,-1.61,-1.99,-2.36,-2.73,-3.1,-3.47,-3.85,-4.22,-4.6,-4.92,-5.06,-5.19,-5.32,-5.46,-5.59,-5.67,-5.77,-5.85,-5.92,-6.0],"spd":[1.98,3.66,3.35,4.01,4.29,4.01,3.87,3.86,4.0,4.29,4.63,4.78,5.19,5.84,6.6,7.47,8.39,9.34,10.33,11.33,12.32,13.1,13.61,14.14,14.7,15.29,15.91,16.66,17.37,18.02,18.69,19.36],"spd_p05":[0.37,1.12,0.96,1.19,0.92,1.11,1.3,1.33,1.48,1.24,1.49,0.82,0.89,1.58,1.72,2.26,2.48,2.75,3.27,3.9,4.24,3.64,3.07,2.94,3.0,3.08,3.19,4.35,5.27,5.56,6.09,7.1],"spd_p95":[4.67,7.52,7.03,8.08,8.05,7.57,7.65,7.81,8.03,8.31,8.84,9.24,9.81,10.39,11.47,12.56,14.45,16.26,18.06,19.88,21.7,23.34,24.29,25.27,26.28,27.31,28.36,29.44,30.38,31.31,31.71,31.81],"dir":[169.0,150.9,145.5,346.3,341.3,346.7,352.2,357.8,3.3,8.7,8.4,337.9,323.6,316.7,312.7,310.2,308.4,307.1,306.1,305.3,304.8,304.7,304.1,303.5,302.9,302.4,302.0,300.9,300.1,299.4,298.8,298.2]},{"month":6,"n":23,"u":[-0.66,0.1,-0.02,-0.13,-0.07,0.16,0.39,0.63,0.86,1.09,1.36,1.96,2.57,3.17,3.78,4.38,4.99,5.59,6.2,6.8,7.41,7.97,8.33,8.66,9.0,9.33,9.67,10.01,10.51,10.95,11.4,11.85],"v":[2.3,1.53,0.97,0.41,0.16,0.23,0.29,0.36,0.42,0.49,0.6,0.79,0.97,1.15,1.34,1.52,1.7,1.88,2.06,2.24,2.42,2.54,2.59,2.62,2.66,2.7,2.74,2.77,2.92,3.23,3.54,3.86],"spd":[3.31,3.49,3.01,3.37,3.65,3.65,3.92,4.37,4.97,5.63,6.29,6.39,6.57,6.89,7.28,7.71,8.19,8.73,9.37,10.05,10.77,11.42,11.9,12.41,12.95,13.51,14.08,14.68,15.25,15.6,15.98,16.39],"spd_p05":[0.68,0.85,0.58,0.81,0.86,0.5,0.4,0.47,1.1,1.7,1.82,1.28,1.43,2.01,2.82,2.86,2.4,2.02,1.88,2.52,2.97,3.24,4.14,5.19,6.08,5.31,4.71,5.01,5.17,4.79,4.43,4.1],"spd_p95":[5.24,9.86,8.89,8.64,8.95,8.62,8.72,8.95,9.44,10.06,10.72,10.52,10.74,11.26,12.2,13.19,14.2,15.21,16.23,17.25,18.27,19.26,20.23,21.2,22.43,23.81,25.2,26.6,27.83,28.84,29.87,30.9],"dir":[164.1,183.7,179.0,162.1,156.7,215.5,233.4,240.2,243.7,245.8,246.4,248.0,249.2,250.0,250.5,250.9,251.2,251.4,251.6,251.8,251.9,252.3,252.7,253.2,253.5,253.9,254.2,254.5,254.5,253.6,252.7,252.0]},{"month":7,"n":30,"u":[0.22,-0.89,-0.26,0.38,0.79,0.84,0.89,0.94,1.0,1.05,1.1,1.21,1.32,1.44,1.55,1.66,1.78,1.89,2.0,2.11,2.23,2.34,2.7,3.11,3.52,3.93,4.34,4.75,5.15,5.43,5.7,5.98],"v":[0.45,2.32,1.9,1.49,1.32,1.58,1.83,2.09,2.34,2.6,2.86,3.07,3.25,3.43,3.61,3.79,3.97,4.15,4.33,4.51,4.69,4.87,4.9,4.87,4.84,4.81,4.78,4.75,4.71,4.97,5.26,5.54],"spd":[1.99,3.53,3.36,3.65,3.98,3.94,4.02,4.31,4.71,5.17,5.73,5.82,5.76,5.78,5.87,6.03,6.25,6.5,6.77,7.08,7.43,7.83,8.06,8.3,8.61,8.97,9.36,9.78,10.21,10.48,10.77,11.1],"spd_p05":[0.43,1.26,0.95,1.01,1.17,1.62,1.08,2.05,1.93,2.09,2.09,2.32,2.31,2.07,2.09,1.85,1.78,2.1,2.08,2.09,1.83,1.51,1.71,2.12,2.63,3.18,3.75,3.57,3.09,3.13,3.31,3.62],"spd_p95":[4.9,7.86,7.66,8.29,8.55,8.3,8.42,8.92,9.53,10.22,10.98,11.33,11.62,11.48,11.57,11.67,11.79,11.91,12.54,13.29,14.07,14.92,14.97,14.6,14.41,14.52,15.08,15.75,16.44,17.1,17.75,18.4],"dir":[205.6,158.9,172.4,194.5,210.8,208.1,206.0,204.3,203.0,201.9,201.0,201.5,202.1,202.7,203.2,203.7,204.1,204.5,204.8,205.1,205.4,205.7,208.9,212.6,216.0,219.3,222.3,225.0,227.5,227.5,227.3,227.2]},{"month":8,"n":41,"u":[0.21,-0.41,0.3,1.0,1.5,1.67,1.85,2.02,2.19,2.36,2.54,2.75,2.95,3.16,3.37,3.57,3.78,3.99,4.19,4.4,4.6,4.8,5.18,5.61,6.04,6.47,6.89,7.32,7.75,8.27,8.79,9.32],"v":[1.09,2.01,1.61,1.2,1.06,1.3,1.54,1.78,2.03,2.27,2.51,2.66,2.78,2.89,3.01,3.12,3.24,3.35,3.47,3.59,3.7,3.81,3.83,3.81,3.79,3.77,3.75,3.73,3.73,3.94,4.15,4.37],"spd":[2.14,3.44,3.06,3.54,4.03,4.05,4.16,4.38,4.74,5.23,5.85,5.94,5.93,6.01,6.17,6.43,6.73,7.06,7.42,7.8,8.2,8.62,8.85,9.07,9.38,9.78,10.25,10.8,11.38,11.88,12.37,12.88],"spd_p05":[0.51,0.55,0.69,0.81,0.7,1.35,1.36,1.0,1.23,1.0,1.95,1.69,1.72,1.84,1.7,2.38,2.21,2.08,1.97,1.94,1.97,2.06,2.34,1.97,1.58,1.62,1.82,2.34,2.99,2.58,2.54,2.82],"spd_p95":[5.35,9.21,8.52,8.54,8.39,8.68,8.52,9.09,10.23,10.7,11.34,11.76,11.72,11.96,12.2,12.44,12.7,13.39,14.11,14.5,14.67,15.24,15.31,16.17,17.85,19.7,20.76,21.68,22.6,22.85,23.11,23.36],"dir":[190.8,168.5,190.5,219.9,234.8,232.2,230.1,228.5,227.2,226.2,225.3,225.9,226.8,227.5,228.2,228.8,229.4,229.9,230.4,230.8,231.2,231.6,233.5,235.8,237.9,239.8,241.5,243.0,244.3,244.5,244.7,244.9]},{"month":9,"n":24,"u":[-0.49,-1.36,-1.06,-0.77,-0.48,-0.23,0.02,0.27,0.51,0.76,0.99,1.26,1.56,1.86,2.16,2.45,2.75,3.05,3.35,3.65,3.95,4.2,4.25,4.29,4.33,4.38,4.42,4.46,4.6,5.16,5.75,6.33],"v":[1.28,1.19,0.65,0.11,-0.24,-0.27,-0.3,-0.32,-0.35,-0.38,-0.39,-0.52,-0.72,-0.92,-1.12,-1.32,-1.52,-1.72,-1.92,-2.12,-2.33,-2.54,-2.72,-2.91,-3.1,-3.28,-3.47,-3.65,-3.83,-3.74,-3.63,-3.53],"spd":[2.29,2.9,2.66,3.13,3.65,3.69,3.9,4.3,4.81,5.39,6.0,6.25,6.44,6.69,7.0,7.43,7.94,8.53,9.14,9.77,10.4,11.0,11.49,12.03,12.65,13.3,13.97,14.65,15.25,15.52,15.82,16.17],"spd_p05":[1.01,0.98,0.68,0.81,1.24,1.41,0.91,1.49,1.53,1.52,1.5,2.1,2.38,2.01,1.13,1.22,1.53,1.83,2.14,2.63,3.05,3.15,3.45,3.01,2.56,2.89,3.64,3.69,3.85,4.26,4.59,4.92],"spd_p95":[5.48,7.94,7.34,6.95,6.69,7.04,8.15,9.47,11.15,13.19,15.16,16.19,17.13,18.33,19.54,20.76,21.98,23.21,24.44,25.68,26.92,28.12,29.26,30.6,32.1,33.62,35.15,36.69,37.65,38.44,39.82,40.43],"dir":[159.1,131.3,121.4,97.8,62.9,40.2,356.2,320.5,304.4,296.4,291.3,292.4,294.8,296.4,297.5,298.3,298.9,299.5,299.9,300.2,300.5,301.1,302.7,304.1,305.5,306.9,308.1,309.3,309.8,305.9,302.3,299.1]},{"month":10,"n":31,"u":[0.01,0.22,0.43,0.63,0.95,1.44,1.92,2.4,2.88,3.36,3.84,4.29,4.77,5.26,5.75,6.24,6.72,7.21,7.7,8.19,8.67,9.11,9.31,9.47,9.62,9.78,9.94,10.1,10.38,10.83,11.29,11.74],"v":[0.29,1.2,1.03,0.84,0.69,0.43,0.18,-0.08,-0.34,-0.59,-0.83,-1.04,-1.26,-1.48,-1.7,-1.92,-2.14,-2.36,-2.58,-2.8,-3.02,-3.2,-3.15,-3.07,-2.98,-2.89,-2.81,-2.73,-2.54,-2.45,-2.36,-2.27],"spd":[1.55,2.92,3.1,3.6,4.13,4.3,4.69,5.25,5.95,6.72,7.52,8.01,8.48,8.99,9.54,10.12,10.72,11.33,11.95,12.58,13.22,13.79,13.93,14.06,14.26,14.57,14.95,15.4,15.94,16.38,16.84,17.33],"spd_p05":[0.56,0.35,0.64,0.88,0.65,0.77,0.9,1.18,1.59,1.82,2.03,2.23,2.17,2.7,3.0,3.24,3.48,3.93,4.05,3.74,3.45,3.15,2.84,2.51,2.09,1.81,2.11,2.18,2.58,2.31,2.06,2.21],"spd_p95":[3.18,8.46,8.33,8.49,10.29,11.2,12.98,15.5,18.02,20.54,22.82,22.43,22.42,23.16,23.22,23.31,23.42,24.11,25.38,26.65,27.93,29.03,29.31,29.61,29.92,30.24,30.57,30.92,32.12,33.96,35.8,37.66],"dir":[182.6,190.3,202.5,216.9,234.3,253.3,264.8,271.9,276.6,280.0,282.2,283.6,284.8,285.7,286.5,287.1,287.7,288.1,288.5,288.9,289.2,289.3,288.7,288.0,287.2,286.5,285.8,285.1,283.8,282.7,281.8,281.0]},{"month":11,"n":30,"u":[-0.15,-0.15,0.81,1.79,2.59,3.47,4.34,5.22,6.09,6.97,7.84,8.4,8.96,9.53,10.09,10.66,11.22,11.79,12.35,12.92,13.48,14.03,14.56,15.08,15.6,16.12,16.64,17.19,17.78,18.39,19.0,19.61],"v":[0.44,0.79,1.06,1.33,1.36,1.27,1.17,1.08,0.98,0.89,0.85,0.93,1.0,1.07,1.14,1.21,1.28,1.35,1.42,1.49,1.55,1.64,1.8,1.97,2.13,2.3,2.46,2.65,2.66,2.69,2.73,2.77],"spd":[1.53,1.88,2.76,4.26,5.19,5.6,6.41,7.43,8.58,9.8,11.05,11.62,12.14,12.71,13.31,13.95,14.62,15.31,16.03,16.78,17.53,18.19,18.72,19.29,19.9,20.55,21.22,21.96,22.69,23.44,24.22,25.02],"spd_p05":[0.55,0.42,0.72,0.87,0.55,0.68,1.04,1.47,2.27,3.13,3.63,4.29,4.68,4.6,4.72,4.8,4.88,5.03,5.29,5.57,5.84,6.19,6.46,6.62,6.8,6.87,6.63,6.65,6.85,7.55,8.47,9.42],"spd_p95":[2.51,3.43,6.16,9.72,10.81,11.09,12.01,13.4,15.29,17.2,18.96,19.49,19.9,20.42,21.8,23.34,25.14,27.19,29.25,31.31,33.17,34.27,34.89,35.32,35.78,36.62,38.18,40.19,41.07,41.78,42.52,43.45],"dir":[161.8,168.9,217.5,233.3,242.2,249.9,254.9,258.3,260.8,262.7,263.8,263.7,263.6,263.6,263.5,263.5,263.5,263.5,263.4,263.4,263.5,263.3,262.9,262.6,262.2,261.9,261.6,261.2,261.5,261.7,261.8,262.0]},{"month":12,"n":22,"u":[-0.05,-0.24,-0.21,-0.23,-0.11,0.47,1.04,1.62,2.2,2.78,3.38,3.99,4.65,5.3,5.96,6.61,7.27,7.93,8.58,9.24,9.91,10.55,11.2,11.85,12.49,13.14,13.78,14.32,15.15,16.06,16.98,17.9],"v":[0.12,0.24,-0.35,-1.05,-1.92,-2.17,-2.41,-2.65,-2.89,-3.12,-3.37,-3.63,-3.95,-4.27,-4.59,-4.9,-5.22,-5.54,-5.86,-6.17,-6.5,-6.8,-6.99,-7.18,-7.37,-7.56,-7.74,-7.8,-7.7,-7.63,-7.56,-7.48],"spd":[1.29,1.78,2.31,3.92,5.26,5.67,6.57,7.63,8.75,9.92,11.1,11.73,12.49,13.32,14.19,15.08,15.99,16.93,17.87,18.84,19.83,20.68,21.41,22.16,22.93,23.71,24.5,25.16,25.72,26.23,26.82,27.48],"spd_p05":[0.5,0.48,0.38,0.69,0.94,1.14,1.86,2.69,2.67,2.95,2.72,2.58,4.33,5.29,5.82,6.32,6.82,7.33,7.83,8.34,9.26,10.54,11.77,12.89,13.99,15.11,15.83,15.9,15.72,14.77,13.84,12.94],"spd_p95":[2.31,4.44,5.48,8.87,13.17,13.81,14.43,15.07,15.93,16.77,17.7,18.47,19.18,19.9,21.58,21.39,22.97,24.82,26.69,28.55,30.47,31.87,33.22,34.66,36.09,38.93,42.11,44.59,44.74,44.89,45.67,47.4],"dir":[157.1,135.0,31.4,12.1,3.3,347.9,336.6,328.5,322.7,318.3,314.8,312.3,310.4,308.8,307.6,306.5,305.7,304.9,304.3,303.8,303.2,302.8,302.0,301.2,300.5,299.9,299.3,298.6,297.0,295.4,294.0,292.7]}],"vef":[{"month":1,"n":613,"u":[0.45,-0.37,0.05,0.52,1.14,1.64,2.07,2.52,3.08,3.62,4.15,4.68,5.29,6.06,6.74,7.4,8.11,8.75,9.36,9.94,10.54,11.05,11.52,12.01,12.58,13.07,13.59,14.12,14.68,15.24,15.81,16.36],"v":[0.19,-1.17,-1.82,-2.12,-2.31,-2.32,-2.29,-2.15,-2.15,-2.26,-2.43,-2.68,-3.07,-3.4,-3.64,-3.93,-4.15,-4.48,-4.69,-4.83,-4.96,-5.12,-5.29,-5.49,-5.62,-5.74,-5.88,-6.03,-6.19,-6.23,-6.32,-6.49],"spd":[3.23,3.74,4.85,6.03,6.81,7.39,8.01,8.7,9.45,10.12,10.76,11.44,12.28,13.14,13.89,14.63,15.37,16.1,16.85,17.56,18.23,18.92,19.63,20.33,21.1,21.76,22.47,23.14,23.88,24.66,25.4,26.15],"spd_p05":[0.49,0.61,0.7,1.13,1.23,1.72,1.93,2.27,2.52,2.57,2.75,2.7,3.37,3.58,3.95,4.12,4.25,4.81,5.2,4.85,5.15,4.82,4.99,5.23,5.41,5.3,5.81,5.72,6.11,6.7,6.3,6.67],"spd_p95":[7.19,10.73,12.51,13.2,13.55,14.31,15.52,16.7,18.14,19.78,21.47,23.38,24.85,26.13,27.12,28.54,30.15,32.01,33.61,34.62,34.93,37.78,39.67,40.73,41.3,42.71,43.7,45.4,46.39,47.2,47.75,49.25],"dir":[247.6,17.5,358.4,346.3,333.7,324.7,317.8,310.5,304.8,302.0,300.4,299.8,300.1,299.3,298.4,298.0,297.1,297.1,296.6,295.9,295.2,294.9,294.7,294.6,294.1,293.7,293.4,293.1,292.9,292.3,291.8,291.6]},{"month":2,"n":562,"u":[-0.05,0.47,1.0,1.54,2.11,2.65,3.22,3.83,4.37,4.86,5.58,6.4,7.17,7.91,8.68,9.46,10.18,10.9,11.61,12.35,13.06,13.72,14.43,15.21,15.9,16.54,17.17,17.84,18.5,19.14,19.78,20.37],"v":[-0.21,-0.23,-0.51,-0.59,-0.55,-0.48,-0.31,-0.14,-0.02,-0.05,-0.23,-0.51,-0.75,-0.89,-1.0,-1.16,-1.34,-1.52,-1.61,-1.61,-1.59,-1.59,-1.66,-1.68,-1.64,-1.58,-1.6,-1.64,-1.62,-1.51,-1.48,-1.46],"spd":[3.83,4.63,5.51,6.5,7.1,7.56,8.14,8.71,9.42,10.15,11.0,11.86,12.69,13.46,14.25,15.12,16.03,16.91,17.75,18.61,19.46,20.3,21.2,22.18,23.06,23.99,24.89,25.78,26.65,27.51,28.35,29.16],"spd_p05":[0.72,0.65,0.67,1.15,1.19,1.75,1.86,1.93,2.32,2.36,2.78,3.33,3.48,3.92,4.14,4.16,4.66,4.84,4.77,5.13,5.37,5.27,6.02,6.41,6.49,6.78,7.41,7.84,8.22,8.81,9.3,9.59],"spd_p95":[8.26,11.18,13.07,14.31,14.97,15.26,16.84,18.63,20.57,21.19,22.83,24.6,24.94,26.67,27.69,28.95,30.77,32.14,33.31,35.2,37.21,37.62,39.63,40.74,42.53,44.66,45.94,47.14,48.09,49.6,51.01,52.09],"dir":[12.6,295.8,297.2,291.1,284.7,280.3,275.4,272.1,270.3,270.6,272.4,274.5,275.9,276.4,276.6,277.0,277.5,278.0,277.9,277.4,276.9,276.6,276.6,276.3,275.9,275.5,275.3,275.3,275.0,274.5,274.3,274.1]},{"month":3,"n":608,"u":[0.03,1.41,1.92,2.34,2.63,2.99,3.34,3.62,3.99,4.46,5.06,5.76,6.56,7.37,8.09,8.78,9.46,10.13,10.83,11.54,12.2,12.87,13.46,14.13,14.82,15.47,16.09,16.74,17.46,18.19,18.83,19.52],"v":[-0.12,1.14,0.92,0.79,0.79,0.9,0.96,1.04,1.11,1.12,1.12,0.99,0.86,0.68,0.55,0.47,0.35,0.21,0.11,0.08,0.09,0.05,0.06,0.05,0.05,0.09,0.07,0.11,0.2,0.24,0.22,0.22],"spd":[4.58,5.37,6.06,6.66,7.01,7.42,7.92,8.38,8.83,9.36,10.01,10.72,11.52,12.41,13.21,14.04,14.83,15.69,16.53,17.38,18.28,19.16,20.06,21.0,21.93,22.76,23.6,24.41,25.2,26.0,26.86,27.66],"spd_p05":[0.98,0.86,1.01,1.1,1.4,1.63,1.91,2.28,2.24,2.19,2.4,2.86,3.23,3.72,3.94,4.17,4.44,4.61,4.94,5.13,5.47,5.77,5.97,6.19,6.24,6.26,6.43,6.77,7.03,7.03,7.32,7.42],"spd_p95":[12.72,11.79,13.01,14.47,14.94,15.8,16.62,17.79,18.79,19.93,20.68,21.49,22.45,23.11,24.86,26.16,28.17,30.05,32.01,33.28,33.77,35.91,37.96,40.35,42.16,43.88,45.1,45.96,47.5,48.12,49.79,51.6],"dir":[344.5,231.0,244.3,251.3,253.2,253.2,254.0,253.9,254.5,255.8,257.6,260.3,262.5,264.7,266.1,267.0,267.9,268.8,269.4,269.6,269.6,269.8,269.8,269.8,269.8,269.7,269.8,269.6,269.4,269.3,269.3,269.3]},{"month":4,"n":582,"u":[0.01,1.69,2.2,2.46,2.57,2.77,3.01,3.31,3.61,4.03,4.46,5.07,5.68,6.32,6.94,7.71,8.49,9.26,10.09,10.85,11.66,12.38,13.07,13.74,14.41,15.03,15.65,16.24,16.89,17.5,18.04,18.53],"v":[0.24,1.27,0.78,0.41,0.45,0.64,0.84,1.02,1.12,1.18,1.17,0.92,0.6,0.31,-0.01,-0.32,-0.51,-0.59,-0.73,-0.87,-1.02,-1.09,-1.21,-1.35,-1.52,-1.64,-1.74,-1.81,-1.84,-1.85,-1.95,-1.94],"spd":[5.39,5.83,6.39,6.75,6.86,6.97,7.2,7.49,7.82,8.15,8.73,9.29,9.94,10.73,11.47,12.19,12.96,13.76,14.67,15.49,16.33,17.19,17.96,18.76,19.56,20.33,21.09,21.75,22.5,23.24,23.92,24.6],"spd_p05":[0.95,1.03,0.98,1.01,1.13,1.4,1.57,1.77,1.81,1.87,2.2,2.48,2.66,3.01,3.2,3.32,3.16,3.7,3.53,4.49,4.94,5.23,5.31,5.27,5.55,5.58,6.0,6.4,6.54,7.16,7.55,7.77],"spd_p95":[12.8,13.37,14.47,14.86,15.21,15.5,15.61,16.32,17.28,18.63,18.79,19.16,20.43,21.42,23.26,24.51,25.63,27.97,29.05,30.42,32.11,33.22,34.95,36.17,38.32,39.68,41.76,43.15,43.52,44.07,44.95,45.87],"dir":[183.5,232.9,250.4,260.6,260.2,257.0,254.4,252.8,252.8,253.7,255.3,259.7,264.0,267.2,270.0,272.4,273.4,273.6,274.2,274.6,275.0,275.0,275.3,275.6,276.0,276.2,276.3,276.3,276.2,276.0,276.2,276.0]},{"month":5,"n":601,"u":[-1.28,1.67,2.22,2.36,2.44,2.35,2.28,2.36,2.42,2.44,2.56,2.8,3.17,3.61,4.04,4.64,5.32,5.97,6.79,7.43,8.05,8.62,9.15,9.67,10.25,10.72,11.21,11.73,12.25,12.76,13.25,13.72],"v":[0.28,2.13,1.73,1.51,1.61,1.79,2.06,2.29,2.44,2.5,2.48,2.33,2.23,2.08,1.99,1.94,1.85,1.68,1.56,1.45,1.41,1.32,1.12,1.07,0.99,0.96,0.9,0.79,0.72,0.66,0.62,0.62],"spd":[6.43,5.62,6.19,6.49,6.56,6.49,6.53,6.65,6.89,7.2,7.58,7.88,8.31,8.79,9.28,9.78,10.39,11.06,11.76,12.44,13.08,13.78,14.44,15.06,15.65,16.24,16.79,17.41,18.04,18.63,19.19,19.77],"spd_p05":[0.98,1.18,1.1,1.37,1.18,1.37,1.5,1.55,1.67,1.56,1.97,2.05,2.18,2.37,2.53,2.43,2.94,2.81,2.69,2.89,3.21,3.23,3.55,3.62,3.9,4.1,4.23,4.7,4.58,4.99,5.42,5.58],"spd_p95":[18.61,11.98,13.55,13.74,14.26,14.75,14.26,15.41,15.58,16.13,16.72,16.95,17.35,18.87,19.31,21.37,22.53,23.86,25.37,26.53,27.84,29.57,31.4,32.69,34.52,35.62,36.1,36.67,38.43,39.15,40.31,42.47],"dir":[102.2,218.1,232.2,237.5,236.6,232.8,227.9,225.8,224.7,224.2,226.0,230.2,234.9,240.1,243.8,247.3,250.8,254.3,257.1,258.9,260.0,261.3,263.0,263.7,264.5,264.9,265.4,266.1,266.6,267.0,267.3,267.4]},{"month":6,"n":590,"u":[-0.95,2.33,2.9,3.01,2.93,2.83,2.71,2.65,2.54,2.43,2.47,2.59,2.84,3.16,3.54,3.9,4.27,4.7,5.14,5.73,6.34,6.96,7.48,7.92,8.34,8.72,9.09,9.5,9.86,10.24,10.68,11.14],"v":[-0.93,3.35,2.89,2.6,2.7,3.07,3.39,3.6,3.8,3.91,4.0,3.97,3.94,3.88,3.84,3.86,3.89,3.97,3.98,3.9,3.88,3.79,3.77,3.72,3.7,3.73,3.74,3.85,3.9,3.84,3.84,3.91],"spd":[6.58,6.02,6.42,6.61,6.58,6.55,6.47,6.47,6.53,6.53,6.71,6.87,7.18,7.49,7.8,8.2,8.64,9.07,9.45,9.92,10.46,11.01,11.51,12.01,12.43,12.89,13.34,13.86,14.36,14.78,15.26,15.78],"spd_p05":[1.13,1.27,1.39,1.43,1.29,1.34,1.39,1.33,1.58,1.53,1.63,1.7,1.71,1.9,1.83,1.99,2.11,2.19,2.08,1.99,2.21,2.4,2.79,2.95,2.9,2.8,3.27,3.41,3.45,3.68,3.64,4.33],"spd_p95":[18.41,12.34,13.33,14.39,14.19,14.42,14.69,14.65,14.6,14.04,13.89,13.88,14.64,15.2,15.95,16.85,18.61,19.48,20.43,21.55,22.11,23.06,23.79,24.91,26.27,27.21,27.48,29.37,30.13,30.6,31.3,32.33],"dir":[45.6,214.8,225.2,229.2,227.3,222.7,218.7,216.3,213.8,211.9,211.7,213.1,215.8,219.2,222.7,225.3,227.7,229.8,232.3,235.8,238.5,241.4,243.3,244.9,246.1,246.9,247.6,247.9,248.4,249.4,250.2,250.7]},{"month":7,"n":584,"u":[-0.24,1.67,2.14,2.25,2.26,2.16,2.0,1.87,1.69,1.56,1.45,1.39,1.28,1.3,1.33,1.46,1.62,1.64,1.71,1.84,1.99,2.14,2.43,2.67,2.95,3.24,3.52,3.86,4.19,4.52,4.88,5.2],"v":[0.43,3.18,2.93,2.89,3.13,3.37,3.56,3.69,3.85,3.87,3.87,3.85,3.82,3.79,3.81,3.85,3.88,3.86,3.81,3.79,3.63,3.53,3.47,3.44,3.41,3.44,3.5,3.55,3.65,3.81,3.93,4.16],"spd":[3.88,4.99,5.26,5.41,5.49,5.42,5.42,5.4,5.54,5.66,5.86,5.98,6.07,6.22,6.44,6.66,6.92,7.06,7.18,7.25,7.26,7.43,7.56,7.67,7.8,8.0,8.22,8.59,8.99,9.33,9.68,10.05],"spd_p05":[0.79,1.04,1.01,1.07,1.02,1.03,1.09,1.18,1.13,1.33,1.34,1.37,1.52,1.56,1.69,1.53,1.66,1.61,1.68,1.71,1.56,1.52,1.82,1.76,1.74,2.09,2.16,2.29,2.11,2.64,2.8,3.1],"spd_p95":[8.95,9.99,10.65,10.95,10.85,10.68,10.82,10.84,11.17,11.4,11.81,11.61,11.98,12.61,13.2,12.91,13.84,13.93,14.36,14.46,14.5,14.6,15.52,15.53,15.49,16.0,16.38,17.28,17.77,18.37,19.02,19.09],"dir":[151.0,207.7,216.2,217.8,215.9,212.7,209.3,206.8,203.7,201.9,200.6,199.9,198.5,198.9,199.2,200.8,202.7,203.0,204.2,205.9,208.7,211.3,215.0,217.8,220.8,223.3,225.1,227.4,229.0,229.8,231.1,231.3]},{"month":8,"n":636,"u":[-0.09,1.48,1.96,2.14,2.21,2.19,2.15,2.09,1.98,1.89,1.78,1.74,1.68,1.63,1.66,1.7,1.79,1.9,2.07,2.25,2.57,2.89,3.27,3.6,3.9,4.25,4.61,4.97,5.3,5.73,6.18,6.64],"v":[0.58,2.95,2.83,2.79,2.93,3.21,3.47,3.66,3.82,3.88,3.97,3.95,3.91,3.82,3.79,3.79,3.88,3.94,3.89,3.8,3.67,3.65,3.61,3.63,3.6,3.65,3.72,3.88,4.0,4.15,4.34,4.6],"spd":[3.73,5.03,5.28,5.38,5.41,5.34,5.38,5.5,5.73,5.96,6.26,6.36,6.53,6.68,6.98,7.22,7.46,7.65,7.76,7.8,7.96,8.24,8.35,8.49,8.71,9.03,9.43,9.82,10.25,10.61,11.09,11.57],"spd_p05":[0.76,0.97,0.83,1.02,1.05,0.93,1.03,1.17,1.23,1.45,1.49,1.41,1.64,1.81,1.99,1.84,1.87,1.99,1.71,1.81,1.82,2.02,1.98,2.08,2.12,2.01,1.96,1.99,2.28,2.22,2.36,2.62],"spd_p95":[8.48,10.81,10.74,11.15,11.23,11.63,11.58,11.53,11.71,11.98,12.2,12.48,12.93,13.35,14.2,14.64,15.11,15.5,15.66,15.97,16.45,16.93,17.26,18.47,18.83,18.88,19.57,20.85,21.59,22.22,22.77,24.01],"dir":[171.5,206.6,214.7,217.5,217.1,214.3,211.8,209.7,207.4,206.0,204.1,203.8,203.2,203.1,203.7,204.1,204.7,205.7,208.0,210.6,215.0,218.3,222.2,224.7,227.3,229.3,231.1,232.0,233.0,234.1,235.0,235.3]},{"month":9,"n":597,"u":[0.05,0.89,1.1,1.29,1.39,1.4,1.39,1.42,1.54,1.59,1.66,1.81,2.04,2.29,2.62,3.01,3.31,3.68,4.08,4.47,4.92,5.39,5.8,6.23,6.63,7.04,7.51,7.94,8.38,8.83,9.3,9.81],"v":[0.41,1.75,1.52,1.53,1.77,2.05,2.36,2.64,2.86,3.08,3.22,3.23,3.31,3.3,3.29,3.37,3.34,3.36,3.29,3.26,3.14,3.06,3.03,3.06,3.07,2.99,2.94,2.89,2.86,3.0,3.1,3.18],"spd":[4.06,4.61,5.08,5.42,5.52,5.58,5.74,5.95,6.19,6.54,6.89,7.12,7.45,7.82,8.22,8.65,9.03,9.49,9.89,10.27,10.73,11.21,11.55,12.01,12.51,12.97,13.5,14.05,14.59,15.07,15.53,15.99],"spd_p05":[1.05,0.94,1.0,1.11,1.04,1.08,1.38,1.52,1.66,1.78,1.7,1.75,1.98,1.87,2.16,1.98,2.13,2.43,2.56,2.42,2.64,2.51,2.67,3.09,3.11,3.08,3.5,3.73,3.82,4.16,4.18,4.15],"spd_p95":[9.49,11.17,11.93,12.31,12.72,12.77,12.98,13.57,14.51,14.75,15.09,15.6,16.06,16.99,17.95,18.58,19.47,20.42,20.94,22.65,23.39,25.11,26.39,27.31,28.36,28.74,29.8,30.63,31.51,32.0,33.99,34.84],"dir":[187.3,207.0,216.0,220.1,218.1,214.3,210.5,208.4,208.4,207.3,207.3,209.2,211.6,214.8,218.5,221.8,224.8,227.6,231.1,233.8,237.4,240.4,242.4,243.8,245.2,247.0,248.6,250.0,251.1,251.2,251.5,252.1]},{"month":10,"n":616,"u":[0.18,0.06,0.37,0.71,0.98,1.27,1.55,1.78,1.97,2.29,2.78,3.33,3.91,4.58,5.19,5.84,6.47,7.06,7.64,8.18,8.65,9.05,9.56,10.09,10.58,11.07,11.48,11.92,12.31,12.71,13.16,13.6],"v":[0.07,-0.19,-0.63,-0.73,-0.64,-0.46,-0.21,0.02,0.17,0.24,0.25,0.16,0.09,-0.07,-0.27,-0.46,-0.62,-0.66,-0.64,-0.6,-0.69,-0.78,-0.9,-0.95,-0.89,-0.83,-0.79,-0.75,-0.75,-0.72,-0.72,-0.73],"spd":[3.75,4.09,4.81,5.47,5.79,6.04,6.46,6.83,7.19,7.69,8.24,8.68,9.21,9.79,10.32,10.88,11.49,12.13,12.74,13.31,13.83,14.36,14.97,15.6,16.16,16.7,17.23,17.85,18.42,18.93,19.47,20.02],"spd_p05":[0.69,0.61,0.69,0.89,1.01,1.33,1.54,1.56,1.9,1.92,1.9,2.09,2.12,2.6,2.44,2.5,2.58,2.43,2.75,2.82,3.02,3.16,3.25,3.47,3.29,3.32,3.34,3.38,3.88,4.35,4.63,4.77],"spd_p95":[8.63,11.05,11.86,12.59,12.91,13.62,14.48,15.7,16.38,17.36,18.17,18.53,19.71,21.12,23.2,24.47,26.15,27.88,29.36,30.58,31.51,32.45,33.19,34.18,35.15,36.25,37.6,38.1,38.64,39.72,40.81,41.47],"dir":[247.6,342.2,329.7,316.1,302.9,289.9,277.6,269.3,265.2,264.1,264.8,267.3,268.7,270.9,273.0,274.5,275.5,275.4,274.8,274.2,274.6,274.9,275.4,275.4,274.8,274.3,273.9,273.6,273.5,273.2,273.1,273.1]},{"month":11,"n":598,"u":[0.32,0.07,0.31,0.66,1.1,1.52,1.88,2.3,2.92,3.44,4.0,4.64,5.26,5.84,6.41,7.01,7.67,8.23,8.76,9.32,9.93,10.57,11.13,11.69,12.31,12.83,13.4,13.91,14.42,14.99,15.5,15.99],"v":[0.1,-0.57,-1.1,-1.07,-0.97,-0.71,-0.41,-0.19,-0.06,-0.03,-0.16,-0.32,-0.47,-0.63,-0.76,-0.91,-1.06,-1.18,-1.25,-1.3,-1.42,-1.52,-1.56,-1.63,-1.73,-1.79,-1.82,-1.81,-1.76,-1.69,-1.71,-1.75],"spd":[3.18,3.64,4.6,5.59,6.29,6.65,7.05,7.51,8.03,8.62,9.28,9.85,10.43,11.07,11.73,12.41,13.22,14.0,14.67,15.37,16.09,16.84,17.49,18.24,19.02,19.72,20.45,21.06,21.76,22.48,23.18,23.85],"spd_p05":[0.6,0.6,0.7,1.17,1.62,1.52,1.79,1.81,1.85,1.68,1.83,1.91,2.14,2.49,2.74,2.58,2.85,3.01,3.2,3.45,3.56,3.8,3.99,4.2,4.6,4.82,4.77,4.76,4.67,5.27,5.99,6.44],"spd_p95":[7.48,10.51,11.79,12.84,13.9,13.72,14.59,15.56,16.59,18.16,19.34,20.85,22.13,23.83,25.29,26.59,28.23,29.71,31.38,33.58,34.75,36.26,37.85,38.11,39.17,40.61,41.96,43.21,44.56,45.99,47.32,48.33],"dir":[253.1,352.9,344.2,328.5,311.4,295.0,282.2,274.8,271.3,270.5,272.3,274.0,275.1,276.1,276.8,277.4,277.8,278.1,278.1,278.0,278.1,278.2,278.0,278.0,278.0,277.9,277.8,277.4,277.0,276.4,276.3,276.2]},{"month":12,"n":614,"u":[0.21,-0.21,0.02,0.36,0.98,1.62,2.26,2.87,3.43,4.05,4.76,5.43,6.04,6.73,7.46,8.21,8.97,9.69,10.32,11.0,11.64,12.32,12.86,13.44,14.02,14.6,15.11,15.69,16.24,16.8,17.3,17.85],"v":[-0.04,-0.77,-1.36,-1.59,-1.56,-1.29,-1.0,-0.67,-0.54,-0.68,-0.93,-1.17,-1.41,-1.66,-1.93,-2.21,-2.42,-2.6,-2.63,-2.68,-2.74,-2.87,-3.0,-3.1,-3.15,-3.24,-3.28,-3.31,-3.39,-3.44,-3.44,-3.5],"spd":[2.77,3.12,4.14,5.39,6.31,6.84,7.38,8.06,8.79,9.45,10.18,10.82,11.49,12.31,13.23,14.08,15.0,15.85,16.58,17.37,18.2,18.98,19.72,20.5,21.3,22.06,22.73,23.51,24.3,25.06,25.82,26.59],"spd_p05":[0.4,0.44,0.58,0.92,1.37,1.38,1.64,1.69,2.13,2.23,2.67,2.54,2.98,2.77,3.36,3.14,3.63,3.82,4.29,4.53,4.73,5.0,5.22,5.18,5.29,5.62,5.59,5.54,5.62,5.34,5.35,5.53],"spd_p95":[5.91,9.63,11.44,12.39,12.99,13.88,15.52,16.97,18.59,19.66,20.77,21.66,22.53,24.46,26.07,27.7,29.21,31.2,32.6,33.75,35.05,36.87,38.05,39.11,41.37,41.55,42.64,45.15,46.69,47.21,48.31,49.39],"dir":[280.7,15.5,359.4,347.3,327.9,308.5,293.7,283.2,279.0,279.5,281.1,282.2,283.2,283.9,284.5,285.1,285.1,285.0,284.3,283.7,283.2,283.1,283.1,283.0,282.6,282.5,282.2,281.9,281.8,281.6,281.2,281.1]}]}},"soundings":{"EDW":[{"id":"EDW-20260811-17Z","station":"EDW","year":2026,"month":8,"day":11,"hour":17,"label":"2026-08-11 17Z","t":[307.66,303.18,301.04,300.2,298.1,296.24,294.38,292.53,290.65,288.32,286.0,283.68,281.36,279.14,277.11,275.19,273.91,272.24,270.25,268.25,266.26,264.26,262.27,261.23,260.48,259.8,258.33,256.27,254.06,252.17,251.41,249.52],"L_fit":-7.379,"L_eq7":-8.776},{"id":"EDW-20260805-16Z","station":"EDW","year":2026,"month":8,"day":5,"hour":16,"label":"2026-08-05 16Z","t":[307.35,302.17,302.58,301.61,301.02,299.57,297.68,295.8,293.91,292.02,290.13,288.21,285.96,283.66,281.36,279.06,276.76,274.46,272.16,270.28,268.22,265.96,263.6,262.09,263.69,262.12,260.55,258.98,257.41,255.58,253.75,251.92],"L_fit":-7.322,"L_eq7":-8.747},{"id":"EDW-20260804-19Z","station":"EDW","year":2026,"month":8,"day":4,"hour":19,"label":"2026-08-04 19Z","t":[317.04,307.32,304.94,302.57,300.74,299.32,297.9,296.19,294.15,292.11,290.07,288.07,286.07,284.07,282.07,280.08,278.08,276.09,274.44,272.79,271.14,269.5,267.25,265.73,264.38,263.03,261.69,260.27,258.12,256.02,253.92,251.82],"L_fit":-7.49,"L_eq7":-9.68},{"id":"EDW-20260728-17Z","station":"EDW","year":2026,"month":7,"day":28,"hour":17,"label":"2026-07-28 17Z","t":[301.45,301.45,298.42,297.77,295.68,297.73,296.3,294.87,293.21,290.88,289.0,286.98,284.95,282.91,280.87,278.84,276.93,275.27,273.6,271.93,270.26,268.59,266.91,265.24,263.7,262.24,260.67,259.02,257.36,255.46,253.55,251.65],"L_fit":-6.719,"L_eq7":-8.177},{"id":"EDW-20260722-17Z","station":"EDW","year":2026,"month":7,"day":22,"hour":17,"label":"2026-07-22 17Z","t":[310.04,303.68,301.27,298.85,296.66,294.73,292.93,291.25,289.58,287.9,286.23,284.48,282.71,281.17,279.0,277.68,276.05,274.65,272.99,270.86,270.45,268.39,267.97,266.05,264.13,262.21,260.29,258.46,256.92,254.76,253.18,251.91],"L_fit":-6.811,"L_eq7":-9.006},{"id":"EDW-20260717-19Z","station":"EDW","year":2026,"month":7,"day":17,"hour":19,"label":"2026-07-17 19Z","t":[313.01,304.46,302.19,299.91,297.56,295.11,292.66,291.03,289.43,287.84,285.65,283.83,282.11,280.38,279.23,277.32,275.31,274.28,272.12,270.23,268.93,267.29,265.29,263.05,261.25,259.96,259.61,258.28,256.52,254.3,252.09,250.3],"L_fit":-7.172,"L_eq7":-9.293},{"id":"EDW-20260714-17Z","station":"EDW","year":2026,"month":7,"day":14,"hour":17,"label":"2026-07-14 17Z","t":[306.33,301.86,299.38,297.9,295.94,293.92,291.91,289.9,287.89,285.88,283.98,282.33,280.54,278.61,276.7,275.44,273.92,273.11,273.04,271.16,269.25,267.5,265.5,263.49,262.51,261.82,260.59,259.01,258.63,256.73,254.61,252.49],"L_fit":-6.448,"L_eq7":-8.648},{"id":"EDW-20260702-00Z","station":"EDW","year":2026,"month":7,"day":2,"hour":0,"label":"2026-07-02 00Z","t":[363.45,299.04,296.54,296.63,294.5,292.22,289.95,288.07,286.27,284.47,282.67,280.89,279.05,277.19,275.33,273.46,271.6,269.8,268.15,266.5,264.85,263.6,262.46,260.73,259.01,257.28,255.55,253.44,251.36,249.31,247.26,245.22],"L_fit":-8.488,"L_eq7":-14.156},{"id":"EDW-20260701-19Z","station":"EDW","year":2026,"month":7,"day":1,"hour":19,"label":"2026-07-01 19Z","t":[321.92,299.17,296.82,294.47,291.94,290.27,288.61,287.04,285.77,284.51,283.05,281.03,279.02,277.0,275.0,273.04,271.09,269.19,267.6,266.0,264.4,262.87,261.44,260.01,258.57,256.71,254.72,252.73,250.67,248.57,246.48,244.38],"L_fit":-7.539,"L_eq7":-10.151},{"id":"EDW-20260612-20Z","station":"EDW","year":2026,"month":6,"day":12,"hour":20,"label":"2026-06-12 20Z","t":[317.74,306.01,303.75,301.49,299.29,297.13,294.97,292.81,290.65,288.49,286.33,284.51,282.72,280.93,279.14,277.35,275.55,273.76,271.97,270.18,268.39,266.6,264.78,262.95,261.13,259.31,257.49,255.67,253.8,251.8,249.8,247.79],"L_fit":-7.831,"L_eq7":-9.748},{"id":"EDW-20260601-17Z","station":"EDW","year":2026,"month":6,"day":1,"hour":17,"label":"2026-06-01 17Z","t":[300.08,295.29,293.35,293.44,292.45,290.46,288.22,285.99,283.75,281.52,279.48,279.33,277.65,275.97,274.29,272.61,270.93,269.25,267.57,265.89,264.08,262.01,260.15,258.3,256.44,254.58,252.53,250.4,248.29,246.29,244.36,242.17],"L_fit":-7.116,"L_eq7":-8.046},{"id":"EDW-20260326-14Z","station":"EDW","year":2026,"month":3,"day":26,"hour":14,"label":"2026-03-26 14Z","t":[277.99,293.25,291.63,291.83,292.86,293.06,291.69,289.8,287.91,286.02,284.13,281.96,279.79,277.62,275.45,273.28,271.11,268.94,267.0,265.29,264.11,262.83,261.25,259.69,258.16,256.64,254.76,252.64,250.51,248.37,246.22,244.08],"L_fit":-6.5,"L_eq7":-5.915},{"id":"EDW-20260325-00Z","station":"EDW","year":2026,"month":3,"day":25,"hour":0,"label":"2026-03-25 00Z","t":[308.66,302.03,299.74,297.46,295.11,292.9,291.26,289.61,287.97,286.32,284.68,282.9,281.12,280.13,278.21,276.29,274.37,272.55,270.74,268.93,267.11,265.26,262.99,260.98,259.24,257.51,255.77,254.03,252.23,250.16,247.97,245.78],"L_fit":-7.393,"L_eq7":-8.873},{"id":"EDW-20260324-18Z","station":"EDW","year":2026,"month":3,"day":24,"hour":18,"label":"2026-03-24 18Z","t":[303.38,296.38,294.31,294.03,292.67,291.62,290.56,289.48,287.93,286.72,285.5,283.96,282.18,280.41,278.63,276.85,275.07,273.29,271.52,269.74,267.61,265.42,263.17,261.09,259.58,258.06,256.54,254.73,252.53,250.43,248.32,246.21],"L_fit":-6.855,"L_eq7":-8.364},{"id":"EDW-20260324-00Z","station":"EDW","year":2026,"month":3,"day":24,"hour":0,"label":"2026-03-24 00Z","t":[313.44,301.9,299.34,296.78,294.43,292.48,290.67,289.03,288.44,286.99,285.55,283.54,281.53,279.52,277.52,275.51,273.65,272.83,272.07,269.98,267.86,265.74,263.68,261.62,259.56,257.5,255.59,253.9,252.14,251.15,250.12,248.22],"L_fit":-7.315,"L_eq7":-9.333},{"id":"EDW-20260323-18Z","station":"EDW","year":2026,"month":3,"day":23,"hour":18,"label":"2026-03-23 18Z","t":[303.57,295.9,294.39,292.89,292.58,291.13,289.68,289.81,288.67,287.19,285.43,283.51,281.58,279.65,277.72,275.79,273.86,271.93,270.0,268.07,266.14,264.24,262.99,262.38,260.87,258.84,256.82,254.79,252.72,250.56,248.4,246.24],"L_fit":-6.796,"L_eq7":-8.382},{"id":"EDW-20260320-15Z","station":"EDW","year":2026,"month":3,"day":20,"hour":15,"label":"2026-03-20 15Z","t":[276.49,297.43,297.09,296.75,295.98,294.56,293.14,291.73,290.31,288.89,287.48,285.63,283.66,281.68,279.71,277.73,275.76,273.78,271.81,269.84,267.86,265.89,263.91,261.93,259.95,257.97,255.98,254.0,252.01,249.94,247.87,245.8],"L_fit":-6.656,"L_eq7":-5.77},{"id":"EDW-20260320-12Z","station":"EDW","year":2026,"month":3,"day":20,"hour":12,"label":"2026-03-20 12Z","t":[275.84,295.31,298.64,297.85,295.95,293.91,291.88,289.85,288.73,288.31,287.69,286.08,284.08,282.08,280.08,278.08,276.08,274.09,272.09,270.09,268.09,266.09,264.04,262.06,260.17,258.29,256.41,254.53,252.62,250.51,248.39,246.28],"L_fit":-6.505,"L_eq7":-5.708},{"id":"EDW-20260319-14Z","station":"EDW","year":2026,"month":3,"day":19,"hour":14,"label":"2026-03-19 14Z","t":[276.36,294.47,296.39,295.51,293.78,292.12,290.67,290.2,289.73,288.76,287.8,286.79,284.77,282.71,280.64,278.58,276.52,274.46,272.4,270.33,268.27,266.21,264.53,263.2,261.32,259.04,256.76,254.47,252.57,250.66,248.76,246.85],"L_fit":-6.288,"L_eq7":-5.758},{"id":"EDW-20260318-00Z","station":"EDW","year":2026,"month":3,"day":18,"hour":0,"label":"2026-03-18 00Z","t":[307.18,298.45,297.09,295.73,293.94,291.58,290.29,289.44,287.56,285.69,283.82,282.51,282.63,282.74,280.73,278.72,276.71,274.7,272.7,270.69,268.78,267.32,266.32,264.37,262.42,260.46,258.51,256.56,254.62,252.7,250.37,248.03],"L_fit":-6.666,"L_eq7":-8.73},{"id":"EDW-20260317-14Z","station":"EDW","year":2026,"month":3,"day":17,"hour":14,"label":"2026-03-17 14Z","t":[275.4,294.54,293.92,293.3,292.25,290.66,289.07,287.48,285.89,284.3,282.71,281.38,280.09,278.79,277.49,276.19,274.89,273.59,272.29,270.99,269.69,268.36,266.34,264.32,262.3,260.28,258.27,256.25,254.19,251.99,249.79,247.59],"L_fit":-5.632,"L_eq7":-5.666},{"id":"EDW-20260313-00Z","station":"EDW","year":2026,"month":3,"day":13,"hour":0,"label":"2026-03-13 00Z","t":[301.29,298.19,295.65,293.12,290.61,288.21,286.03,283.84,282.06,280.88,280.58,280.48,278.75,277.01,275.28,273.55,271.81,270.08,268.34,266.61,264.88,262.85,260.69,258.54,256.39,254.23,252.08,249.92,247.82,245.79,243.75,241.96],"L_fit":-7.154,"L_eq7":-8.162},{"id":"EDW-20260312-18Z","station":"EDW","year":2026,"month":3,"day":12,"hour":18,"label":"2026-03-12 18Z","t":[283.5,288.55,290.69,289.64,287.77,285.84,283.91,281.98,280.05,281.34,280.21,278.96,277.68,276.4,275.11,273.57,271.67,269.76,267.86,265.95,264.05,262.14,260.26,258.36,256.17,253.98,251.79,249.6,247.4,245.2,243.0,240.77],"L_fit":-6.309,"L_eq7":-6.446},{"id":"EDW-20260309-18Z","station":"EDW","year":2026,"month":3,"day":9,"hour":18,"label":"2026-03-09 18Z","t":[296.47,287.63,289.04,288.01,286.25,284.41,282.56,280.72,278.88,277.03,275.0,272.85,271.59,270.22,268.68,267.14,265.6,264.06,262.37,260.51,258.65,256.52,254.52,253.16,251.8,250.26,248.26,246.29,244.38,242.48,240.57,238.67],"L_fit":-6.914,"L_eq7":-7.697},{"id":"EDW-20260305-18Z","station":"EDW","year":2026,"month":3,"day":5,"hour":18,"label":"2026-03-05 18Z","t":[289.66,283.94,281.86,279.78,277.53,275.16,272.8,271.05,269.31,267.99,267.57,267.11,265.95,264.79,263.62,261.94,259.75,257.56,255.37,253.18,251.05,251.12,249.73,248.34,246.94,245.55,244.16,242.62,241.0,239.35,237.11,234.87],"L_fit":-6.298,"L_eq7":-7.041},{"id":"EDW-20260304-18Z","station":"EDW","year":2026,"month":3,"day":4,"hour":18,"label":"2026-03-04 18Z","t":[292.88,290.17,287.58,285.9,284.01,282.35,281.35,280.72,280.95,279.42,277.86,276.2,274.54,272.88,270.88,268.88,266.87,264.87,262.86,260.86,258.85,256.99,254.8,252.51,251.1,249.88,247.95,246.0,243.85,242.19,240.25,238.42],"L_fit":-6.898,"L_eq7":-7.351},{"id":"EDW-20260303-20Z","station":"EDW","year":2026,"month":3,"day":3,"hour":20,"label":"2026-03-03 20Z","t":[291.72,288.67,286.6,284.73,282.95,281.26,279.57,277.88,276.44,275.59,276.33,274.69,273.05,271.41,270.11,268.98,267.85,266.73,265.6,264.47,262.41,260.27,258.07,255.87,253.67,251.47,249.27,247.07,244.83,242.58,240.33,238.03],"L_fit":-6.319,"L_eq7":-7.239},{"id":"EDW-20260227-21Z","station":"EDW","year":2026,"month":2,"day":27,"hour":21,"label":"2026-02-27 21Z","t":[299.36,294.12,292.64,291.43,290.16,289.07,288.59,287.98,286.34,284.05,281.75,279.96,278.48,277.02,275.15,273.17,271.49,269.82,268.14,266.46,264.84,263.3,261.34,259.42,258.09,256.67,254.38,252.36,250.48,248.42,246.27,244.38],"L_fit":-6.75,"L_eq7":-7.976},{"id":"EDW-20260227-18Z","station":"EDW","year":2026,"month":2,"day":27,"hour":18,"label":"2026-02-27 18Z","t":[291.09,289.76,290.37,290.9,289.59,288.08,286.57,285.78,285.15,283.66,281.98,280.06,278.11,276.16,274.97,273.44,271.97,270.62,268.67,266.72,265.45,263.75,262.26,260.29,258.33,256.37,254.4,252.44,250.66,248.77,246.87,244.81],"L_fit":-6.25,"L_eq7":-7.178},{"id":"EDW-20260226-18Z","station":"EDW","year":2026,"month":2,"day":26,"hour":18,"label":"2026-02-26 18Z","t":[295.21,289.48,288.35,288.52,288.44,287.63,286.81,285.99,284.45,282.6,280.76,278.92,277.48,276.73,275.28,273.67,272.12,270.57,268.91,266.85,264.79,262.75,260.83,259.5,257.69,255.76,253.83,251.92,250.02,248.2,246.76,245.31],"L_fit":-6.279,"L_eq7":-7.575},{"id":"EDW-20260212-18Z","station":"EDW","year":2026,"month":2,"day":12,"hour":18,"label":"2026-02-12 18Z","t":[281.8,280.19,280.23,279.65,278.78,277.44,275.93,274.42,272.91,271.39,269.55,267.8,265.51,263.22,261.2,259.07,257.09,255.12,253.15,251.63,249.83,248.11,246.38,244.57,242.57,240.57,238.58,236.7,234.9,233.09,231.29,229.49],"L_fit":-7.143,"L_eq7":-6.282},{"id":"EDW-20260210-00Z","station":"EDW","year":2026,"month":2,"day":10,"hour":0,"label":"2026-02-10 00Z","t":[294.12,290.23,288.19,286.16,284.08,281.96,280.91,279.93,278.43,277.43,276.68,275.66,273.98,272.16,270.43,268.7,266.79,264.58,262.37,260.17,258.89,256.97,254.67,252.87,251.27,249.04,249.55,248.1,246.07,244.05,242.03,240.0],"L_fit":-6.659,"L_eq7":-7.47},{"id":"EDW-20260209-20Z","station":"EDW","year":2026,"month":2,"day":9,"hour":20,"label":"2026-02-09 20Z","t":[293.26,287.88,286.64,285.75,284.74,283.63,283.51,281.65,279.9,278.64,277.33,275.79,274.21,272.41,270.62,268.82,266.86,265.25,264.59,262.68,261.02,259.23,257.03,254.82,252.62,251.11,249.66,248.34,246.77,244.83,242.73,240.62],"L_fit":-6.474,"L_eq7":-7.388},{"id":"EDW-20260129-21Z","station":"EDW","year":2026,"month":1,"day":29,"hour":21,"label":"2026-01-29 21Z","t":[290.36,287.03,285.09,283.16,282.22,280.87,279.52,278.3,277.89,277.67,275.73,274.09,272.48,270.87,269.25,267.64,265.84,263.55,261.31,259.56,257.69,255.58,253.46,251.35,249.23,247.11,245.0,242.88,240.64,238.39,236.13,234.35],"L_fit":-6.997,"L_eq7":-7.108},{"id":"EDW-20251021-16Z","station":"EDW","year":2025,"month":10,"day":21,"hour":16,"label":"2025-10-21 16Z","t":[285.23,289.67,290.08,290.5,290.2,288.85,287.5,286.15,284.8,283.44,282.09,280.29,278.43,276.57,274.72,272.86,271.0,269.15,267.29,265.43,263.57,261.71,259.83,257.94,256.06,254.17,252.28,250.4,248.52,246.66,244.79,242.93],"L_fit":-6.527,"L_eq7":-6.613},{"id":"EDW-20251017-18Z","station":"EDW","year":2025,"month":10,"day":17,"hour":18,"label":"2025-10-17 18Z","t":[289.62,287.19,287.07,286.04,284.05,282.03,280.62,281.42,280.64,279.4,278.17,276.97,277.28,277.08,275.12,273.16,271.2,269.23,267.27,265.31,263.35,261.33,259.44,258.33,256.78,254.9,253.02,251.14,249.2,247.16,244.96,242.77],"L_fit":-5.868,"L_eq7":-7.037},{"id":"EDW-20251017-15Z","station":"EDW","year":2025,"month":10,"day":17,"hour":15,"label":"2025-10-17 15Z","t":[273.38,286.87,287.94,286.3,284.37,282.2,280.03,277.86,280.57,279.03,277.5,276.0,274.51,273.02,273.35,272.12,270.89,268.95,266.84,264.74,262.8,261.34,259.95,258.55,256.85,254.85,252.85,250.85,248.75,246.61,244.47,242.33],"L_fit":-5.468,"L_eq7":-5.47},{"id":"EDW-20251015-18Z","station":"EDW","year":2025,"month":10,"day":15,"hour":18,"label":"2025-10-15 18Z","t":[286.56,282.16,280.05,279.52,278.1,276.47,274.85,273.31,272.33,272.13,271.2,271.28,270.26,268.7,267.13,265.43,263.68,261.93,260.18,258.42,256.34,254.16,251.98,249.8,247.62,245.44,243.26,241.12,239.03,236.94,234.85,234.91],"L_fit":-6.42,"L_eq7":-6.741},{"id":"EDW-20251015-15Z","station":"EDW","year":2025,"month":10,"day":15,"hour":15,"label":"2025-10-15 15Z","t":[280.36,281.95,279.78,277.62,277.76,275.77,274.9,274.55,273.0,271.09,270.19,270.38,268.82,267.26,265.7,264.14,262.58,261.02,259.46,257.9,256.16,253.93,251.74,249.57,247.4,245.24,243.07,240.95,238.87,236.8,234.73,234.98],"L_fit":-6.235,"L_eq7":-6.144},{"id":"EDW-20251008-18Z","station":"EDW","year":2025,"month":10,"day":8,"hour":18,"label":"2025-10-08 18Z","t":[293.93,292.17,291.39,290.53,289.64,288.7,287.28,285.86,284.45,283.03,281.6,280.05,278.49,276.94,275.39,273.83,272.28,270.73,269.17,267.62,265.96,264.05,262.21,260.37,258.54,256.7,254.86,253.03,251.08,249.05,247.01,244.98],"L_fit":-6.332,"L_eq7":-7.452},{"id":"EDW-20251008-15Z","station":"EDW","year":2025,"month":10,"day":8,"hour":15,"label":"2025-10-08 15Z","t":[290.14,290.22,291.89,292.53,290.71,288.77,286.84,284.9,283.43,282.42,281.32,280.28,278.94,277.15,275.36,273.57,271.78,271.19,269.41,267.52,265.64,263.8,262.02,260.24,258.46,256.69,254.91,253.13,251.18,249.11,247.04,244.97],"L_fit":-6.239,"L_eq7":-7.087},{"id":"EDW-20250930-18Z","station":"EDW","year":2025,"month":9,"day":30,"hour":18,"label":"2025-09-30 18Z","t":[297.87,290.32,288.4,286.49,287.22,285.57,283.93,283.07,281.5,279.93,278.38,277.03,277.69,276.0,274.21,272.46,270.85,269.25,269.43,268.14,266.84,265.26,263.24,261.74,260.97,259.85,257.95,256.05,254.0,251.83,249.67,247.51],"L_fit":-5.524,"L_eq7":-7.832},{"id":"EDW-20250930-15Z","station":"EDW","year":2025,"month":9,"day":30,"hour":15,"label":"2025-09-30 15Z","t":[287.6,287.73,287.09,285.57,286.28,285.23,283.92,283.23,281.55,280.29,278.52,277.73,276.28,275.72,274.36,272.69,271.01,269.21,267.38,266.3,265.76,264.62,262.79,260.64,258.48,257.15,256.35,255.36,253.33,251.4,249.48,247.55],"L_fit":-5.351,"L_eq7":-6.841},{"id":"EDW-20250911-18Z","station":"EDW","year":2025,"month":9,"day":11,"hour":18,"label":"2025-09-11 18Z","t":[296.23,291.34,289.07,286.8,286.91,285.72,284.52,283.32,282.13,280.93,279.72,278.45,277.19,275.92,274.65,273.03,271.2,269.36,267.52,265.68,263.84,261.96,260.21,258.47,256.72,254.98,253.23,251.49,249.64,247.73,245.83,243.92],"L_fit":-6.296,"L_eq7":-7.674},{"id":"EDW-20250910-18Z","station":"EDW","year":2025,"month":9,"day":10,"hour":18,"label":"2025-09-10 18Z","t":[303.13,291.81,289.5,287.96,286.23,285.22,284.37,283.52,282.38,281.0,279.53,277.8,275.93,273.75,273.37,271.54,270.09,269.61,268.94,267.05,265.01,262.9,260.74,258.58,256.42,254.56,252.86,251.16,249.29,247.39,245.49,243.59],"L_fit":-6.469,"L_eq7":-8.339},{"id":"EDW-20250910-00Z","station":"EDW","year":2025,"month":9,"day":10,"hour":0,"label":"2025-09-10 00Z","t":[310.67,298.42,296.04,293.66,291.24,289.01,287.51,286.01,285.98,284.48,283.49,281.92,280.35,278.78,277.21,275.64,274.07,272.5,270.93,269.36,268.03,266.25,264.39,262.54,260.68,258.83,257.05,255.29,253.58,251.91,250.24,248.48],"L_fit":-6.636,"L_eq7":-9.067},{"id":"EDW-20250909-21Z","station":"EDW","year":2025,"month":9,"day":9,"hour":21,"label":"2025-09-09 21Z","t":[314.07,297.45,295.6,293.76,292.21,290.81,289.41,288.0,286.6,285.2,283.77,282.12,280.47,278.81,277.16,275.51,273.86,272.2,270.55,268.9,267.25,265.58,263.87,262.17,260.46,258.76,257.05,255.34,253.46,251.38,249.31,247.23],"L_fit":-6.887,"L_eq7":-9.395},{"id":"EDW-20250909-18Z","station":"EDW","year":2025,"month":9,"day":9,"hour":18,"label":"2025-09-09 18Z","t":[306.04,296.18,293.18,290.18,289.88,288.76,287.32,285.88,284.16,283.17,282.41,282.12,280.52,278.92,277.32,275.72,274.12,272.52,270.92,269.32,267.72,265.82,263.49,261.45,259.89,258.76,257.28,255.16,253.01,250.84,248.67,246.49],"L_fit":-6.439,"L_eq7":-8.62},{"id":"EDW-20250825-21Z","station":"EDW","year":2025,"month":8,"day":25,"hour":21,"label":"2025-08-25 21Z","t":[314.79,305.71,303.31,300.91,298.53,296.14,293.76,291.38,289.0,286.62,284.24,281.89,279.54,277.55,275.91,274.28,272.48,270.25,269.66,268.07,266.48,264.89,263.12,261.25,259.9,257.86,256.25,254.82,253.21,251.27,249.32,247.4],"L_fit":-7.767,"L_eq7":-9.464},{"id":"EDW-20250825-18Z","station":"EDW","year":2025,"month":8,"day":25,"hour":18,"label":"2025-08-25 18Z","t":[307.94,301.69,299.91,298.3,296.5,294.46,292.42,290.38,288.34,286.3,284.23,282.35,280.07,277.79,275.51,273.47,271.53,270.63,269.12,267.4,265.34,263.56,262.34,261.07,259.36,257.65,256.85,256.18,254.04,251.82,249.6,247.38],"L_fit":-7.293,"L_eq7":-8.803},{"id":"EDW-20250807-18Z","station":"EDW","year":2025,"month":8,"day":7,"hour":18,"label":"2025-08-07 18Z","t":[307.16,301.96,299.8,297.72,296.92,295.86,294.79,292.72,290.37,288.76,287.15,285.61,284.09,282.57,281.05,279.24,277.28,275.32,273.36,271.4,269.64,267.95,266.12,264.26,262.4,260.88,259.35,257.49,255.47,253.46,251.44,249.43],"L_fit":-7.031,"L_eq7":-8.728},{"id":"EDW-20250711-21Z","station":"EDW","year":2025,"month":7,"day":11,"hour":21,"label":"2025-07-11 21Z","t":[318.62,308.88,306.41,303.94,301.51,299.13,296.75,294.37,291.99,289.98,288.27,286.39,285.61,284.56,283.23,281.63,279.47,277.32,275.16,273.01,271.38,269.75,268.3,266.31,264.2,262.18,260.54,259.08,256.98,255.71,254.19,252.03],"L_fit":-7.559,"L_eq7":-9.833},{"id":"EDW-20250711-18Z","station":"EDW","year":2025,"month":7,"day":11,"hour":18,"label":"2025-07-11 18Z","t":[310.84,303.21,300.68,298.62,297.89,297.45,295.96,294.18,292.39,290.6,288.81,287.14,285.48,283.82,282.17,282.09,279.91,277.73,275.56,273.38,271.2,269.5,268.01,266.29,264.16,262.03,259.91,258.17,256.49,254.87,253.78,251.99],"L_fit":-7.029,"L_eq7":-9.083},{"id":"EDW-20250710-18Z","station":"EDW","year":2025,"month":7,"day":10,"hour":18,"label":"2025-07-10 18Z","t":[312.62,305.57,302.9,300.24,297.68,296.1,294.66,293.21,291.77,290.32,288.88,287.38,285.86,284.34,282.82,281.3,279.78,278.27,276.55,274.3,272.05,269.8,267.92,266.26,264.34,262.41,260.81,259.15,257.45,255.43,253.37,251.32],"L_fit":-7.077,"L_eq7":-9.255},{"id":"EDW-20250617-18Z","station":"EDW","year":2025,"month":6,"day":17,"hour":18,"label":"2025-06-17 18Z","t":[314.71,299.56,297.66,295.76,294.05,292.6,291.15,289.69,288.24,287.81,287.56,286.44,285.31,283.88,281.88,279.87,277.87,275.87,273.86,271.86,269.85,267.85,265.74,263.64,262.4,261.16,260.2,258.74,256.53,254.4,252.27,250.14],"L_fit":-6.77,"L_eq7":-9.456},{"id":"EDW-20250603-15Z","station":"EDW","year":2025,"month":6,"day":3,"hour":15,"label":"2025-06-03 15Z","t":[289.63,292.27,292.41,292.45,291.77,290.84,289.51,287.73,285.96,284.18,282.4,280.49,278.41,276.32,274.24,272.15,270.07,267.99,265.9,263.82,261.74,259.62,257.44,255.42,253.5,251.63,250.04,248.44,246.51,244.46,242.41,240.34],"L_fit":-7.31,"L_eq7":-7.037},{"id":"EDW-20250428-20Z","station":"EDW","year":2025,"month":4,"day":28,"hour":20,"label":"2025-04-28 20Z","t":[297.14,289.61,287.36,285.11,282.76,280.32,277.89,276.09,275.14,273.09,271.45,269.93,268.41,266.89,265.37,263.85,262.34,260.82,259.3,257.12,254.92,252.88,250.85,248.67,246.38,244.1,241.81,239.58,237.57,235.56,233.55,231.54],"L_fit":-7.59,"L_eq7":-7.762},{"id":"EDW-20250425-18Z","station":"EDW","year":2025,"month":4,"day":25,"hour":18,"label":"2025-04-25 18Z","t":[303.86,282.05,279.93,277.82,277.26,278.56,277.11,275.55,274.01,272.71,270.55,268.45,266.89,265.46,263.4,261.16,258.93,257.64,259.26,259.84,258.72,256.86,254.91,252.96,251.01,249.06,247.11,245.05,242.91,240.76,238.62,236.48],"L_fit":-6.243,"L_eq7":-8.41},{"id":"EDW-20250409-21Z","station":"EDW","year":2025,"month":4,"day":9,"hour":21,"label":"2025-04-09 21Z","t":[303.29,294.77,293.63,293.36,291.64,289.97,288.3,286.64,284.93,282.83,280.74,278.77,276.82,275.02,273.51,272.0,270.49,268.97,267.4,265.4,263.4,261.35,259.26,257.61,255.96,254.27,252.31,250.34,248.39,246.45,244.52,242.58],"L_fit":-7.219,"L_eq7":-8.355},{"id":"EDW-20250409-18Z","station":"EDW","year":2025,"month":4,"day":9,"hour":18,"label":"2025-04-09 18Z","t":[291.5,289.51,290.02,289.08,290.55,289.57,288.01,286.44,284.88,283.15,281.3,279.54,277.79,276.05,274.3,272.55,270.81,269.06,267.32,265.57,263.82,262.09,259.69,257.7,255.94,254.17,252.24,250.2,248.08,245.88,244.21,242.6],"L_fit":-6.695,"L_eq7":-7.218}],"NID":[{"id":"NID-20260324-15Z","station":"NID","year":2026,"month":3,"day":24,"hour":15,"label":"2026-03-24 15Z","t":[288.62,293.48,294.95,294.95,294.71,292.65,290.6,289.14,288.32,287.37,284.94,282.95,281.42,279.89,278.36,276.8,274.83,272.86,270.89,268.92,267.47,265.62,263.41,261.19,259.57,258.13,256.7,255.26,253.71,251.51,249.3,247.09],"L_fit":-6.434,"L_eq7":-6.941},{"id":"NID-20260319-21Z","station":"NID","year":2026,"month":3,"day":19,"hour":21,"label":"2026-03-19 21Z","t":[305.25,301.94,299.6,297.26,295.86,293.67,291.48,289.84,288.61,288.51,288.75,287.06,284.59,282.44,281.19,279.92,277.69,275.46,273.23,270.99,268.76,266.53,264.23,262.2,260.31,258.42,256.53,254.64,252.91,250.93,248.9,246.87],"L_fit":-7.266,"L_eq7":-8.544},{"id":"NID-20260311-15Z","station":"NID","year":2026,"month":3,"day":11,"hour":15,"label":"2026-03-11 15Z","t":[271.29,287.12,288.74,288.65,287.96,286.5,284.46,282.6,280.74,280.18,278.56,276.74,275.03,273.95,271.98,270.0,268.03,266.06,264.21,262.49,260.77,259.05,257.41,255.77,254.13,252.4,250.66,248.93,247.28,246.12,243.93,241.74],"L_fit":-6.072,"L_eq7":-5.269},{"id":"NID-20260310-15Z","station":"NID","year":2026,"month":3,"day":10,"hour":15,"label":"2026-03-10 15Z","t":[281.98,283.95,285.65,285.15,283.78,283.01,282.73,281.34,279.95,278.56,277.16,275.1,273.05,271.15,269.31,267.47,265.63,263.94,262.47,261.23,260.0,258.77,257.48,255.51,253.27,251.04,248.8,246.95,244.97,242.95,240.93,238.91],"L_fit":-6.237,"L_eq7":-6.3},{"id":"NID-20260224-15Z","station":"NID","year":2026,"month":2,"day":24,"hour":15,"label":"2026-02-24 15Z","t":[261.95,285.3,284.7,284.7,288.53,287.46,285.92,284.38,282.84,281.3,280.02,278.58,277.09,275.6,274.12,272.63,271.14,269.65,268.16,266.67,265.63,265.63,263.53,261.43,259.26,257.06,254.96,252.97,250.87,249.61,248.32,246.2],"L_fit":-4.972,"L_eq7":-4.369},{"id":"NID-20260126-18Z","station":"NID","year":2026,"month":1,"day":26,"hour":18,"label":"2026-01-26 18Z","t":[282.11,280.84,282.05,280.68,278.59,276.79,275.45,274.12,272.78,271.45,269.89,268.48,267.09,265.71,264.32,262.94,261.07,259.22,257.45,255.51,253.56,251.99,250.17,248.11,246.06,244.23,242.63,240.45,238.39,236.75,234.54,232.33],"L_fit":-6.56,"L_eq7":-6.312},{"id":"NID-20260126-15Z","station":"NID","year":2026,"month":1,"day":26,"hour":15,"label":"2026-01-26 15Z","t":[264.12,279.99,280.31,279.73,278.99,277.44,275.88,274.33,272.77,271.21,269.66,268.06,266.46,264.86,263.84,262.77,261.26,259.36,257.36,255.06,252.65,250.49,249.82,247.9,246.12,244.5,242.66,240.97,239.35,237.31,235.27,233.22],"L_fit":-6.04,"L_eq7":-4.578},{"id":"NID-20260122-12Z","station":"NID","year":2026,"month":1,"day":22,"hour":12,"label":"2026-01-22 12Z","t":[275.09,283.76,284.15,283.16,281.79,280.05,278.42,279.84,278.69,277.55,275.35,273.09,270.83,268.58,266.32,264.06,262.03,260.41,258.78,256.98,256.88,254.93,253.21,251.47,249.7,247.93,245.75,243.57,241.4,239.23,237.05,234.88],"L_fit":-6.459,"L_eq7":-5.636},{"id":"NID-20260122-06Z","station":"NID","year":2026,"month":1,"day":22,"hour":6,"label":"2026-01-22 06Z","t":[279.28,286.69,285.68,284.14,282.3,280.88,280.58,281.04,281.1,279.37,277.56,275.19,272.81,270.44,268.07,265.69,263.32,260.94,259.45,257.99,256.53,254.99,253.37,251.75,250.13,248.51,246.89,245.27,243.62,241.64,239.66,237.61],"L_fit":-6.551,"L_eq7":-6.04},{"id":"NID-20251215-15Z","station":"NID","year":2025,"month":12,"day":15,"hour":15,"label":"2025-12-15 15Z","t":[258.13,284.16,286.94,287.54,287.04,285.8,284.12,282.44,280.75,279.07,277.38,276.09,275.19,274.28,272.39,270.33,268.57,267.14,265.71,264.29,263.18,260.99,258.93,256.87,255.32,253.92,252.34,250.59,248.78,246.89,244.99,243.1],"L_fit":-5.338,"L_eq7":-4.0},{"id":"NID-20251202-21Z","station":"NID","year":2025,"month":12,"day":2,"hour":21,"label":"2025-12-02 21Z","t":[288.18,283.29,282.85,281.31,280.2,282.27,281.66,280.5,278.91,278.61,277.05,275.56,274.18,272.79,271.41,269.78,267.59,265.39,263.2,261.0,258.81,256.71,255.01,253.25,251.2,249.16,247.11,245.07,242.84,240.92,239.07,237.22],"L_fit":-6.484,"L_eq7":-6.898},{"id":"NID-20251105-15Z","station":"NID","year":2025,"month":11,"day":5,"hour":15,"label":"2025-11-05 15Z","t":[273.69,289.28,287.34,289.37,288.54,287.0,285.47,283.93,282.39,281.21,280.47,279.57,278.29,276.95,274.83,272.7,270.57,268.44,266.31,264.18,262.71,264.35,262.37,260.39,258.83,257.46,255.22,252.99,250.78,248.66,246.74,244.81],"L_fit":-5.615,"L_eq7":-5.5},{"id":"NID-20251104-18Z","station":"NID","year":2025,"month":11,"day":4,"hour":18,"label":"2025-11-04 18Z","t":[297.63,291.61,289.38,289.74,288.44,287.32,287.43,286.58,284.89,283.2,281.52,279.82,278.13,276.43,274.74,273.04,271.35,269.65,267.55,265.32,263.09,261.52,259.96,258.39,256.82,255.25,253.66,251.8,249.92,248.0,246.08,244.19],"L_fit":-6.582,"L_eq7":-7.809},{"id":"NID-20251023-15Z","station":"NID","year":2025,"month":10,"day":23,"hour":15,"label":"2025-10-23 15Z","t":[274.17,291.95,290.36,288.28,286.21,284.14,282.07,280.0,277.93,275.86,273.78,272.15,271.81,272.3,270.3,268.31,266.6,264.94,263.28,261.62,259.96,258.18,257.38,255.37,253.13,250.89,248.65,246.41,244.25,242.41,240.48,238.55],"L_fit":-6.375,"L_eq7":-5.547},{"id":"NID-20251020-18Z","station":"NID","year":2025,"month":10,"day":20,"hour":18,"label":"2025-10-20 18Z","t":[293.99,291.55,291.23,290.07,288.89,287.55,286.21,284.87,284.46,284.77,283.52,282.16,280.74,279.33,277.92,276.49,274.65,272.82,270.98,269.14,267.3,265.47,263.56,261.65,260.37,259.07,256.99,254.91,252.81,250.54,248.28,246.01],"L_fit":-6.025,"L_eq7":-7.458},{"id":"NID-20250923-15Z","station":"NID","year":2025,"month":9,"day":23,"hour":15,"label":"2025-09-23 15Z","t":[281.29,298.52,298.18,297.02,295.53,293.42,291.32,289.21,287.1,285.0,282.89,280.5,278.46,277.99,276.2,275.16,273.11,271.71,269.65,267.55,266.45,266.52,264.4,262.28,260.12,258.43,256.15,253.96,251.93,250.07,248.46,246.92],"L_fit":-6.512,"L_eq7":-6.233},{"id":"NID-20250904-18Z","station":"NID","year":2025,"month":9,"day":4,"hour":18,"label":"2025-09-04 18Z","t":[301.84,298.61,299.2,297.82,296.48,294.36,292.25,290.11,287.71,285.3,282.9,280.5,278.5,277.04,275.83,274.28,272.72,273.04,272.17,270.76,268.54,266.31,264.4,262.49,260.59,258.69,256.37,254.06,252.42,251.26,249.97,247.92],"L_fit":-6.931,"L_eq7":-8.215},{"id":"NID-20250818-18Z","station":"NID","year":2025,"month":8,"day":18,"hour":18,"label":"2025-08-18 18Z","t":[309.61,299.16,296.75,294.92,293.7,292.89,292.54,290.46,288.38,287.05,285.73,284.9,283.71,281.86,280.0,278.14,276.28,274.43,272.57,270.71,268.85,267.0,265.43,263.57,261.46,259.35,257.23,255.12,253.01,250.67,248.32,245.98],"L_fit":-7.081,"L_eq7":-8.964},{"id":"NID-20250818-15Z","station":"NID","year":2025,"month":8,"day":18,"hour":15,"label":"2025-08-18 15Z","t":[285.06,294.52,297.19,295.58,293.88,292.08,291.62,290.42,288.55,286.67,285.69,285.27,283.92,282.06,280.2,278.34,276.48,274.62,272.75,270.89,269.03,267.12,265.19,263.29,261.27,259.08,256.88,254.68,252.48,250.27,248.06,245.86],"L_fit":-6.471,"L_eq7":-6.596},{"id":"NID-20250814-15Z","station":"NID","year":2025,"month":8,"day":14,"hour":15,"label":"2025-08-14 15Z","t":[302.59,300.73,301.07,299.23,297.46,295.97,294.48,293.0,291.51,289.88,287.77,285.63,283.49,281.43,279.59,277.75,275.91,274.07,272.19,270.21,268.22,266.23,264.37,261.96,259.55,257.14,254.73,252.51,250.32,248.88,247.76,246.16],"L_fit":-7.64,"L_eq7":-8.287},{"id":"NID-20250813-15Z","station":"NID","year":2025,"month":8,"day":13,"hour":15,"label":"2025-08-13 15Z","t":[288.73,301.59,301.91,301.87,300.79,299.91,298.26,296.05,293.85,291.65,289.44,287.17,284.87,282.57,280.27,277.97,275.7,274.23,272.77,270.9,268.93,267.09,265.19,263.06,260.93,258.82,256.9,254.99,253.07,251.32,249.59,247.85],"L_fit":-7.366,"L_eq7":-6.951},{"id":"NID-20250812-15Z","station":"NID","year":2025,"month":8,"day":12,"hour":15,"label":"2025-08-12 15Z","t":[286.43,301.48,304.0,302.87,301.75,300.63,298.77,296.67,294.56,292.45,290.35,288.1,285.77,283.43,281.1,278.77,276.44,274.11,271.77,269.44,267.89,266.5,265.57,264.06,262.15,259.96,258.01,256.31,254.61,253.06,251.52,249.77],"L_fit":-7.242,"L_eq7":-6.729},{"id":"NID-20250808-15Z","station":"NID","year":2025,"month":8,"day":8,"hour":15,"label":"2025-08-08 15Z","t":[287.83,297.95,301.3,300.09,298.69,297.4,296.11,294.56,292.63,290.71,288.78,286.68,284.49,282.31,280.12,278.13,276.49,274.84,273.2,271.55,269.91,268.26,266.36,264.62,262.57,260.72,258.96,257.2,255.21,253.16,251.03,248.82],"L_fit":-6.772,"L_eq7":-6.864},{"id":"NID-20250806-15Z","station":"NID","year":2025,"month":8,"day":6,"hour":15,"label":"2025-08-06 15Z","t":[288.82,293.93,297.46,297.77,296.58,295.98,294.27,292.49,290.72,288.94,287.17,286.26,284.85,283.33,281.36,279.38,277.41,275.43,273.46,271.48,269.51,267.67,266.05,264.35,262.64,260.94,259.26,257.63,255.52,253.62,251.77,249.8],"L_fit":-6.379,"L_eq7":-6.959},{"id":"NID-20250805-15Z","station":"NID","year":2025,"month":8,"day":5,"hour":15,"label":"2025-08-05 15Z","t":[289.95,294.95,297.16,296.18,295.21,294.28,293.34,292.02,290.41,288.79,287.18,285.77,284.44,283.11,281.48,279.48,277.48,275.47,273.47,271.47,269.46,267.46,265.6,263.82,262.07,260.33,258.58,256.84,255.09,253.38,251.53,249.51],"L_fit":-6.388,"L_eq7":-7.068},{"id":"NID-20250804-18Z","station":"NID","year":2025,"month":8,"day":4,"hour":18,"label":"2025-08-04 18Z","t":[294.17,301.1,298.7,296.3,295.41,294.07,292.98,292.05,291.11,289.35,287.41,285.96,284.68,283.02,281.24,279.46,277.69,275.91,274.12,271.83,269.55,267.26,265.22,263.24,261.54,259.96,258.37,256.79,255.03,252.9,250.77,248.64],"L_fit":-6.728,"L_eq7":-7.476},{"id":"NID-20250804-15Z","station":"NID","year":2025,"month":8,"day":4,"hour":15,"label":"2025-08-04 15Z","t":[290.57,299.21,298.43,296.83,295.32,294.26,293.62,292.74,291.18,289.62,288.06,286.62,285.21,283.8,282.39,280.38,278.35,276.32,274.29,272.25,270.22,268.19,265.96,264.01,262.22,260.42,258.63,256.83,255.05,253.34,251.33,249.73],"L_fit":-6.553,"L_eq7":-7.128},{"id":"NID-20250724-18Z","station":"NID","year":2025,"month":7,"day":24,"hour":18,"label":"2025-07-24 18Z","t":[300.1,295.91,293.7,291.8,290.03,288.5,286.97,286.03,285.78,283.77,281.54,279.94,278.71,277.48,276.25,275.02,273.69,271.61,269.54,267.46,265.38,263.31,261.38,259.4,257.39,255.37,253.36,251.97,249.85,247.59,245.79,244.08],"L_fit":-6.845,"L_eq7":-8.047},{"id":"NID-20250723-18Z","station":"NID","year":2025,"month":7,"day":23,"hour":18,"label":"2025-07-23 18Z","t":[302.36,299.4,296.74,294.08,291.59,289.4,288.85,286.95,285.06,283.17,281.27,279.17,277.76,275.97,274.24,273.07,271.9,270.73,269.6,268.87,266.69,264.46,262.26,260.06,257.89,255.79,253.69,251.59,249.42,247.14,245.12,243.14],"L_fit":-7.117,"L_eq7":-8.266},{"id":"NID-20250722-18Z","station":"NID","year":2025,"month":7,"day":22,"hour":18,"label":"2025-07-22 18Z","t":[305.86,298.04,295.51,292.98,290.89,289.37,287.86,286.34,285.38,285.01,284.3,282.7,281.08,279.37,277.67,275.96,274.25,272.55,270.84,269.14,267.43,265.75,264.02,261.98,259.94,257.9,255.87,253.83,251.74,249.36,246.99,244.61],"L_fit":-6.847,"L_eq7":-8.603},{"id":"NID-20250711-15Z","station":"NID","year":2025,"month":7,"day":11,"hour":15,"label":"2025-07-11 15Z","t":[279.16,299.03,301.87,300.9,299.9,298.86,297.25,295.12,293.0,290.87,288.75,286.56,284.34,282.13,279.91,278.42,277.73,276.42,275.11,273.79,272.48,271.17,269.33,267.24,265.14,263.04,260.94,258.85,256.99,255.48,253.91,252.33],"L_fit":-6.23,"L_eq7":-6.027},{"id":"NID-20250710-15Z","station":"NID","year":2025,"month":7,"day":10,"hour":15,"label":"2025-07-10 15Z","t":[273.85,298.83,300.36,299.28,298.22,297.07,295.25,293.43,291.61,289.8,287.98,286.0,284.92,283.97,282.92,281.09,279.26,277.43,275.59,273.76,271.92,270.07,268.3,266.56,264.82,263.08,261.34,259.75,258.19,256.55,254.31,252.04],"L_fit":-5.885,"L_eq7":-5.516},{"id":"NID-20250709-15Z","station":"NID","year":2025,"month":7,"day":9,"hour":15,"label":"2025-07-09 15Z","t":[279.19,299.33,301.69,300.84,299.15,297.45,295.75,294.06,292.36,290.66,288.53,286.08,283.79,281.41,279.96,277.85,276.5,275.08,273.26,271.45,269.64,268.36,266.18,264.25,262.51,260.94,259.3,257.7,256.01,254.37,252.48,250.6],"L_fit":-6.487,"L_eq7":-6.031},{"id":"NID-20250709-00Z","station":"NID","year":2025,"month":7,"day":9,"hour":0,"label":"2025-07-09 00Z","t":[311.39,308.39,305.94,303.49,301.03,298.54,296.05,293.56,291.07,289.13,287.64,285.9,283.84,281.69,279.53,277.38,275.52,273.78,272.5,271.25,269.81,268.36,266.64,264.45,262.25,260.05,258.2,256.37,254.55,253.0,251.51,250.02],"L_fit":-7.696,"L_eq7":-9.135},{"id":"NID-20250708-15Z","station":"NID","year":2025,"month":7,"day":8,"hour":15,"label":"2025-07-08 15Z","t":[285.35,297.7,298.7,298.97,297.59,295.45,293.31,291.17,289.03,288.3,286.69,284.62,282.53,280.43,278.34,276.24,274.14,272.7,271.99,271.07,269.9,268.51,266.22,263.83,261.45,260.12,258.89,257.66,255.76,253.87,251.99,250.1],"L_fit":-6.357,"L_eq7":-6.625},{"id":"NID-20250604-15Z","station":"NID","year":2025,"month":6,"day":4,"hour":15,"label":"2025-06-04 15Z","t":[292.97,293.45,293.01,292.01,291.27,290.76,288.85,286.92,284.99,283.06,281.14,279.5,277.52,275.54,273.57,271.7,269.75,267.62,265.48,263.59,262.0,260.35,258.89,257.19,256.65,255.31,253.67,252.03,250.75,248.68,246.54,244.4],"L_fit":-6.754,"L_eq7":-7.36},{"id":"NID-20250521-00Z","station":"NID","year":2025,"month":5,"day":21,"hour":0,"label":"2025-05-21 00Z","t":[310.12,301.43,299.06,296.69,294.47,292.43,290.38,288.34,286.3,284.26,282.22,280.37,278.55,276.73,274.91,273.09,271.28,269.46,267.64,265.82,264.0,262.19,260.43,258.67,256.91,255.15,253.39,251.63,249.7,247.57,245.43,243.3],"L_fit":-7.708,"L_eq7":-9.013},{"id":"NID-20250520-15Z","station":"NID","year":2025,"month":5,"day":20,"hour":15,"label":"2025-05-20 15Z","t":[289.02,292.54,292.24,291.39,290.0,288.17,287.08,286.38,284.1,281.82,279.54,277.3,277.12,275.63,274.13,272.63,271.14,269.64,268.14,266.65,265.13,263.23,261.24,259.25,257.41,255.74,253.63,251.52,249.48,247.51,245.54,243.55],"L_fit":-6.438,"L_eq7":-6.979},{"id":"NID-20250430-03Z","station":"NID","year":2025,"month":4,"day":30,"hour":3,"label":"2025-04-30 03Z","t":[298.03,296.58,294.45,292.32,290.09,287.74,285.38,283.02,280.66,278.3,275.94,273.74,271.86,269.98,269.28,269.68,268.13,266.55,264.32,262.1,259.87,257.77,255.6,253.31,251.49,249.57,247.65,245.76,243.77,241.82,239.87,237.93],"L_fit":-7.593,"L_eq7":-7.848},{"id":"NID-20250428-18Z","station":"NID","year":2025,"month":4,"day":28,"hour":18,"label":"2025-04-28 18Z","t":[296.79,288.55,286.27,284.77,283.81,282.11,279.93,277.76,275.58,273.4,271.28,269.65,268.01,266.38,264.75,263.11,261.48,260.11,258.78,257.36,255.37,253.41,251.34,249.08,246.82,244.56,242.47,240.46,238.22,235.98,233.73,231.49],"L_fit":-7.552,"L_eq7":-7.728},{"id":"NID-20250409-15Z","station":"NID","year":2025,"month":4,"day":9,"hour":15,"label":"2025-04-09 15Z","t":[275.01,288.72,289.59,289.72,288.89,288.09,287.29,286.49,285.59,283.51,281.33,279.41,277.55,275.69,273.82,271.96,270.1,268.24,266.41,265.33,264.25,262.53,260.26,257.99,255.73,253.46,251.19,248.92,246.9,244.88,242.86,240.84],"L_fit":-6.405,"L_eq7":-5.628},{"id":"NID-20250408-18Z","station":"NID","year":2025,"month":4,"day":8,"hour":18,"label":"2025-04-08 18Z","t":[298.24,294.48,292.28,290.08,289.19,288.63,286.87,285.11,283.34,281.58,279.82,278.14,276.47,274.8,273.13,271.46,269.48,267.46,265.44,263.42,261.4,259.43,257.42,255.42,253.82,252.78,250.81,248.59,246.48,244.45,242.41,240.38],"L_fit":-7.227,"L_eq7":-7.868},{"id":"NID-20250404-15Z","station":"NID","year":2025,"month":4,"day":4,"hour":15,"label":"2025-04-04 15Z","t":[284.03,284.35,282.34,280.34,278.26,276.08,273.9,271.72,269.54,267.36,265.15,262.82,260.5,258.68,256.74,254.41,253.13,251.5,249.86,248.23,246.64,245.22,243.68,242.4,244.48,244.77,242.77,241.6,240.51,239.41,239.63,237.6],"L_fit":-6.362,"L_eq7":-6.498},{"id":"NID-20250403-15Z","station":"NID","year":2025,"month":4,"day":3,"hour":15,"label":"2025-04-03 15Z","t":[267.12,280.28,279.3,277.74,275.74,273.71,271.69,269.66,267.63,265.6,263.52,261.41,259.34,257.84,256.34,254.38,252.39,250.45,248.54,246.63,245.04,243.27,241.4,239.54,237.67,235.94,234.34,232.73,230.95,229.13,228.49,227.18],"L_fit":-7.012,"L_eq7":-4.867},{"id":"NID-20250402-21Z","station":"NID","year":2025,"month":4,"day":2,"hour":21,"label":"2025-04-02 21Z","t":[295.29,285.41,283.0,280.59,278.09,275.58,273.08,270.57,268.06,265.83,263.58,261.23,258.89,256.78,254.53,253.03,250.94,248.86,246.77,244.69,242.48,240.18,238.47,236.71,236.13,235.95,235.85,235.26,234.18,233.1,231.35,229.56],"L_fit":-7.804,"L_eq7":-7.584},{"id":"NID-20250402-18Z","station":"NID","year":2025,"month":4,"day":2,"hour":18,"label":"2025-04-02 18Z","t":[285.72,281.54,279.38,277.21,274.94,272.64,270.33,268.04,266.08,264.13,262.38,260.75,259.02,257.21,255.23,253.04,250.85,248.66,246.73,244.86,242.61,240.58,239.09,237.7,237.09,236.31,235.28,234.15,233.2,231.99,230.77,229.56],"L_fit":-7.197,"L_eq7":-6.661},{"id":"NID-20250331-18Z","station":"NID","year":2025,"month":3,"day":31,"hour":18,"label":"2025-03-31 18Z","t":[294.3,290.42,287.79,285.47,283.15,280.84,278.53,276.72,275.98,275.24,272.94,271.63,269.93,268.23,267.15,266.81,268.71,266.71,264.71,262.71,260.71,258.52,256.25,253.97,252.56,250.47,248.29,246.25,244.76,243.24,241.73,240.81],"L_fit":-6.355,"L_eq7":-7.488},{"id":"NID-20250331-15Z","station":"NID","year":2025,"month":3,"day":31,"hour":15,"label":"2025-03-31 15Z","t":[286.57,288.19,286.22,284.25,282.1,279.78,277.46,275.28,273.36,271.6,270.87,270.34,269.36,268.35,267.33,266.32,265.31,264.73,264.0,262.06,260.11,258.68,257.02,254.79,253.24,252.44,250.73,248.58,246.35,244.12,241.9,239.67],"L_fit":-5.783,"L_eq7":-6.742},{"id":"NID-20250327-18Z","station":"NID","year":2025,"month":3,"day":27,"hour":18,"label":"2025-03-27 18Z","t":[294.15,291.73,290.2,288.67,286.97,285.13,285.56,283.85,282.13,280.41,278.65,277.38,275.52,273.33,271.15,268.96,267.08,265.51,263.94,262.37,260.84,260.81,259.4,257.75,255.38,253.01,251.52,249.5,247.25,245.02,242.79,240.56],"L_fit":-6.707,"L_eq7":-7.473},{"id":"NID-20250326-21Z","station":"NID","year":2025,"month":3,"day":26,"hour":21,"label":"2025-03-26 21Z","t":[305.9,298.98,296.53,294.07,291.66,289.29,286.92,284.62,282.41,280.21,278.0,275.74,273.48,271.22,269.27,267.7,265.59,264.08,262.49,260.62,258.7,256.6,254.34,252.44,250.53,248.34,246.14,244.05,242.03,240.02,238.0,236.83],"L_fit":-8.34,"L_eq7":-8.606},{"id":"NID-20250326-18Z","station":"NID","year":2025,"month":3,"day":26,"hour":18,"label":"2025-03-26 18Z","t":[291.99,292.01,292.48,291.37,290.36,289.08,286.91,284.74,282.57,280.4,278.23,275.89,273.54,271.2,268.85,266.51,264.33,262.68,260.82,259.06,257.58,256.15,254.64,252.53,250.34,248.14,246.33,244.04,241.73,239.43,237.13,234.85],"L_fit":-7.836,"L_eq7":-7.265},{"id":"NID-20250325-15Z","station":"NID","year":2025,"month":3,"day":25,"hour":15,"label":"2025-03-25 15Z","t":[266.99,292.6,294.15,293.31,291.29,289.04,286.79,284.53,282.28,280.17,278.97,278.3,277.72,276.07,273.98,271.88,269.78,267.68,265.58,263.48,261.81,260.1,257.97,255.84,253.7,251.57,249.33,247.08,244.83,242.6,240.39,238.17],"L_fit":-6.796,"L_eq7":-4.854},{"id":"NID-20250324-15Z","station":"NID","year":2025,"month":3,"day":24,"hour":15,"label":"2025-03-24 15Z","t":[276.67,290.63,292.05,290.86,289.11,286.92,284.74,282.55,280.37,278.6,276.92,275.58,277.41,276.12,274.58,272.71,270.63,268.54,266.46,264.37,262.29,260.19,257.97,255.75,253.54,251.36,249.39,247.43,245.32,243.37,241.4,239.3],"L_fit":-6.609,"L_eq7":-5.788},{"id":"NID-20250319-00Z","station":"NID","year":2025,"month":3,"day":19,"hour":0,"label":"2025-03-19 00Z","t":[299.76,287.01,284.31,281.6,278.96,276.54,274.62,272.86,271.1,269.35,269.39,268.34,267.22,265.37,263.39,261.41,259.43,257.68,256.14,254.61,252.79,250.73,248.83,247.55,245.43,243.32,241.21,239.22,237.2,235.18,233.16,231.13],"L_fit":-7.303,"L_eq7":-8.015},{"id":"NID-20250318-18Z","station":"NID","year":2025,"month":3,"day":18,"hour":18,"label":"2025-03-18 18Z","t":[280.37,280.63,278.89,277.15,275.36,273.45,271.54,269.64,267.73,266.24,265.21,263.76,262.32,260.88,260.35,258.34,256.1,253.86,251.83,250.32,248.83,247.76,246.01,244.18,242.35,240.51,238.68,236.56,234.27,231.99,229.91,229.0],"L_fit":-6.724,"L_eq7":-6.145},{"id":"NID-20250317-18Z","station":"NID","year":2025,"month":3,"day":17,"hour":18,"label":"2025-03-17 18Z","t":[285.32,285.25,285.39,283.6,281.84,280.09,278.34,276.6,275.68,274.67,273.23,271.69,270.15,268.61,268.42,266.8,264.84,263.34,261.66,259.78,257.86,256.26,254.45,253.47,251.28,249.1,246.9,244.67,242.4,240.33,238.32,237.0],"L_fit":-6.36,"L_eq7":-6.622},{"id":"NID-20250307-15Z","station":"NID","year":2025,"month":3,"day":7,"hour":15,"label":"2025-03-07 15Z","t":[279.08,280.14,278.04,275.93,273.85,272.49,271.25,269.08,266.91,264.74,262.46,261.63,260.06,257.9,255.73,253.57,251.41,249.24,247.1,245.56,244.79,242.86,240.97,239.29,237.61,235.92,234.69,233.89,233.09,232.27,231.44,230.61],"L_fit":-6.898,"L_eq7":-6.02},{"id":"NID-20250304-21Z","station":"NID","year":2025,"month":3,"day":4,"hour":21,"label":"2025-03-04 21Z","t":[290.3,286.86,284.43,282.14,280.15,278.22,276.29,274.54,274.41,274.28,274.07,273.31,271.64,270.14,268.69,267.24,265.79,264.34,262.82,261.3,259.77,258.32,256.36,254.11,251.87,249.62,247.77,246.35,244.98,242.91,240.76,238.6],"L_fit":-6.052,"L_eq7":-7.102},{"id":"NID-20241219-18Z","station":"NID","year":2024,"month":12,"day":19,"hour":18,"label":"2024-12-19 18Z","t":[282.51,285.51,287.88,287.49,287.15,285.99,284.03,282.34,281.46,280.58,279.79,278.57,277.14,275.61,273.64,271.67,269.99,268.83,267.58,265.53,263.48,261.42,259.29,257.15,255.01,252.88,250.74,248.6,246.24,244.81,242.78,240.74],"L_fit":-6.252,"L_eq7":-6.351},{"id":"NID-20241217-18Z","station":"NID","year":2024,"month":12,"day":17,"hour":18,"label":"2024-12-17 18Z","t":[268.01,282.74,284.03,283.54,282.92,281.9,280.88,279.86,278.84,277.83,276.75,275.04,273.54,272.72,271.91,271.09,270.28,268.74,267.18,265.62,264.06,262.43,260.57,258.72,256.69,254.6,252.51,250.55,248.57,246.52,244.47,242.43],"L_fit":-5.074,"L_eq7":-4.953}],"VEF":[{"id":"VEF-20260812-12Z","station":"VEF","year":2026,"month":8,"day":12,"hour":12,"label":"2026-08-12 12Z","t":[304.08,303.3,301.28,299.33,297.43,295.59,293.29,290.87,288.86,286.76,284.69,282.56,280.74,278.79,276.91,274.79,272.75,271.01,269.89,268.78,267.48,266.11,264.7,263.14,260.87,258.15,255.83,253.89,252.22,250.25,248.89,248.19],"L_fit":-7.361,"L_eq7":-8.431},{"id":"VEF-20260811-18Z","station":"VEF","year":2026,"month":8,"day":11,"hour":18,"label":"2026-08-11 18Z","t":[309.6,304.63,302.18,300.13,298.07,296.02,293.96,292.05,290.41,288.16,286.31,284.42,282.74,280.66,278.26,275.82,273.4,271.52,269.71,267.77,266.39,264.91,264.46,263.1,261.3,260.33,259.07,258.14,256.41,254.44,252.2,250.36],"L_fit":-7.253,"L_eq7":-8.964},{"id":"VEF-20260811-12Z","station":"VEF","year":2026,"month":8,"day":11,"hour":12,"label":"2026-08-11 12Z","t":[305.69,305.24,304.23,302.53,300.69,298.72,296.41,294.14,292.21,289.83,287.48,285.53,283.53,281.42,279.08,276.89,274.5,272.84,272.13,271.08,269.22,267.02,264.84,262.64,261.52,260.59,258.9,257.96,256.21,254.26,252.38,250.53],"L_fit":-7.404,"L_eq7":-8.587},{"id":"VEF-20260810-18Z","station":"VEF","year":2026,"month":8,"day":10,"hour":18,"label":"2026-08-10 18Z","t":[312.66,307.48,305.0,302.87,301.47,299.08,296.71,294.36,292.08,290.02,288.02,285.93,284.04,282.07,279.79,277.86,275.66,273.61,271.4,269.43,267.85,265.86,265.19,264.03,262.08,260.65,259.09,257.96,256.19,254.6,252.51,250.26],"L_fit":-7.667,"L_eq7":-9.258},{"id":"VEF-20260810-12Z","station":"VEF","year":2026,"month":8,"day":10,"hour":12,"label":"2026-08-10 12Z","t":[309.32,306.76,306.03,304.3,301.93,299.65,297.53,295.56,293.24,290.76,288.42,286.08,284.09,282.19,280.58,278.5,276.36,274.32,272.36,271.19,269.57,267.5,265.59,263.52,261.38,260.17,258.58,257.46,256.51,254.6,252.72,251.17],"L_fit":-7.655,"L_eq7":-8.936},{"id":"VEF-20260809-18Z","station":"VEF","year":2026,"month":8,"day":9,"hour":18,"label":"2026-08-09 18Z","t":[313.62,309.08,306.35,303.98,302.01,300.37,298.73,296.43,294.1,291.89,289.74,287.39,285.19,283.0,280.76,278.51,277.0,274.88,272.68,270.4,268.21,265.88,263.94,262.45,260.42,258.51,257.86,256.82,255.61,254.49,253.67,251.65],"L_fit":-7.986,"L_eq7":-9.351},{"id":"VEF-20260809-12Z","station":"VEF","year":2026,"month":8,"day":9,"hour":12,"label":"2026-08-09 12Z","t":[304.19,308.11,305.92,303.88,301.61,299.39,297.95,296.12,294.27,292.13,290.04,287.78,285.43,283.16,281.21,279.24,277.78,275.63,273.58,271.31,269.18,267.03,264.97,263.23,261.57,260.56,258.68,257.59,256.21,254.6,252.81,250.85],"L_fit":-7.628,"L_eq7":-8.442},{"id":"VEF-20260808-18Z","station":"VEF","year":2026,"month":8,"day":8,"hour":18,"label":"2026-08-08 18Z","t":[311.95,308.32,305.84,303.79,301.88,300.46,298.87,296.73,294.57,292.17,289.6,287.16,284.77,283.71,281.78,279.92,278.07,275.77,273.4,271.15,268.82,267.26,265.41,264.27,262.59,260.37,258.32,256.72,255.68,254.19,253.05,252.37],"L_fit":-7.817,"L_eq7":-9.19},{"id":"VEF-20260808-12Z","station":"VEF","year":2026,"month":8,"day":8,"hour":12,"label":"2026-08-08 12Z","t":[305.95,307.71,306.16,304.18,302.14,300.42,298.51,296.19,294.04,292.14,289.8,287.43,285.14,283.03,280.95,279.12,277.34,275.57,273.6,272.26,270.24,268.28,266.45,264.18,262.15,260.31,258.63,256.57,254.58,253.13,252.68,252.53],"L_fit":-7.685,"L_eq7":-8.611},{"id":"VEF-20260807-18Z","station":"VEF","year":2026,"month":8,"day":7,"hour":18,"label":"2026-08-07 18Z","t":[309.75,304.98,302.58,300.43,299.53,297.86,296.47,294.66,292.69,290.77,289.33,287.58,285.26,283.06,280.83,278.89,276.55,274.61,272.42,269.99,267.82,265.89,264.59,263.33,262.11,260.45,259.9,259.56,258.06,256.05,254.17,252.79],"L_fit":-7.263,"L_eq7":-8.977},{"id":"VEF-20260807-12Z","station":"VEF","year":2026,"month":8,"day":7,"hour":12,"label":"2026-08-07 12Z","t":[308.14,306.19,304.41,302.29,300.76,298.83,296.85,295.58,294.13,293.0,290.77,288.46,286.54,284.18,281.95,279.65,277.42,275.56,273.32,270.84,269.14,267.1,264.86,262.71,260.63,259.37,260.34,259.79,258.33,256.27,254.21,252.07],"L_fit":-7.447,"L_eq7":-8.822},{"id":"VEF-20260806-18Z","station":"VEF","year":2026,"month":8,"day":6,"hour":18,"label":"2026-08-06 18Z","t":[309.84,306.32,303.13,300.97,299.06,297.39,296.31,295.68,293.85,292.3,290.35,288.53,286.41,284.28,281.95,279.65,277.58,275.29,272.88,270.44,268.22,266.17,264.15,262.93,260.91,261.15,260.06,258.39,256.42,254.25,252.21,250.38],"L_fit":-7.547,"L_eq7":-8.986},{"id":"VEF-20260806-12Z","station":"VEF","year":2026,"month":8,"day":6,"hour":12,"label":"2026-08-06 12Z","t":[307.58,306.61,305.19,304.19,302.81,300.96,299.01,296.78,294.94,293.01,291.46,289.28,287.05,284.88,282.5,280.2,277.86,275.82,273.51,271.14,268.82,266.46,264.06,261.66,260.01,260.94,259.81,257.92,255.98,254.35,252.38,251.45],"L_fit":-7.816,"L_eq7":-8.768},{"id":"VEF-20260804-18Z","station":"VEF","year":2026,"month":8,"day":4,"hour":18,"label":"2026-08-04 18Z","t":[309.76,308.1,305.56,303.26,300.7,298.26,297.08,296.5,294.72,293.18,290.9,288.62,286.7,285.0,282.84,280.61,278.29,276.69,274.49,272.7,271.34,269.45,267.48,265.76,264.52,262.85,260.81,258.82,256.98,255.58,253.73,251.75],"L_fit":-7.446,"L_eq7":-8.978},{"id":"VEF-20260804-12Z","station":"VEF","year":2026,"month":8,"day":4,"hour":12,"label":"2026-08-04 12Z","t":[306.75,306.95,305.13,303.92,303.32,301.99,299.93,297.48,295.15,292.9,290.78,288.72,286.69,284.71,282.65,280.47,278.3,276.18,273.89,271.47,269.27,267.45,266.44,264.86,263.33,262.1,260.88,258.94,257.95,256.99,255.63,253.49],"L_fit":-7.466,"L_eq7":-8.688},{"id":"VEF-20260803-18Z","station":"VEF","year":2026,"month":8,"day":3,"hour":18,"label":"2026-08-03 18Z","t":[310.43,309.28,306.58,304.53,303.06,301.28,299.19,297.08,294.98,292.85,291.14,289.06,286.75,284.43,282.31,280.82,278.76,276.59,274.56,272.8,271.26,269.22,267.38,266.27,264.41,262.23,260.27,258.17,256.26,256.85,255.22,253.86],"L_fit":-7.589,"L_eq7":-9.044},{"id":"VEF-20260803-12Z","station":"VEF","year":2026,"month":8,"day":3,"hour":12,"label":"2026-08-03 12Z","t":[306.81,306.5,307.4,305.5,303.72,301.95,299.97,297.74,295.58,293.83,291.76,289.42,287.1,284.75,282.5,280.84,278.8,276.48,274.5,273.09,271.37,270.05,268.1,265.98,264.13,262.54,260.97,259.86,259.65,257.99,256.1,254.17],"L_fit":-7.386,"L_eq7":-8.694},{"id":"VEF-20260802-18Z","station":"VEF","year":2026,"month":8,"day":2,"hour":18,"label":"2026-08-02 18Z","t":[314.83,309.99,307.81,305.94,304.19,301.88,299.48,297.19,294.78,292.54,290.38,288.59,286.7,284.86,282.94,280.77,278.64,276.63,274.34,272.13,270.62,269.82,269.1,267.41,265.21,263.06,261.48,260.21,259.26,257.57,256.06,254.64],"L_fit":-7.572,"L_eq7":-9.467},{"id":"VEF-20260802-12Z","station":"VEF","year":2026,"month":8,"day":2,"hour":12,"label":"2026-08-02 12Z","t":[308.16,309.03,308.04,306.72,304.89,302.51,300.03,297.57,295.33,292.92,290.82,288.7,286.22,283.89,281.88,280.05,278.45,277.58,275.65,274.51,272.66,270.48,268.92,267.17,265.66,263.68,262.74,261.99,260.55,258.65,256.72,254.83],"L_fit":-7.297,"L_eq7":-8.825},{"id":"VEF-20260801-18Z","station":"VEF","year":2026,"month":8,"day":1,"hour":18,"label":"2026-08-01 18Z","t":[314.02,308.65,306.77,305.39,303.71,301.79,299.65,297.53,295.41,293.3,291.3,289.19,287.05,284.89,282.48,279.95,277.71,275.99,274.88,273.19,271.23,271.12,269.49,267.47,265.77,264.13,262.32,260.45,259.07,257.33,255.72,253.89],"L_fit":-7.487,"L_eq7":-9.389},{"id":"VEF-20260801-12Z","station":"VEF","year":2026,"month":8,"day":1,"hour":12,"label":"2026-08-01 12Z","t":[303.19,309.34,308.31,306.42,304.73,302.5,300.23,297.89,295.89,293.5,291.2,289.54,287.53,285.72,283.49,281.12,279.15,276.91,275.03,273.15,272.63,271.18,269.84,268.22,267.28,265.58,263.67,261.99,260.38,258.37,256.28,254.16],"L_fit":-7.189,"L_eq7":-8.345},{"id":"VEF-20260731-18Z","station":"VEF","year":2026,"month":7,"day":31,"hour":18,"label":"2026-07-31 18Z","t":[312.11,307.79,306.24,304.16,302.71,300.46,298.16,295.84,293.49,291.18,288.72,286.44,285.0,283.91,282.02,280.72,279.5,277.92,276.26,274.98,273.61,271.84,270.28,268.41,266.57,264.72,263.37,262.06,260.65,258.65,256.4,254.13],"L_fit":-7.022,"L_eq7":-9.205},{"id":"VEF-20260731-12Z","station":"VEF","year":2026,"month":7,"day":31,"hour":12,"label":"2026-07-31 12Z","t":[302.91,308.58,307.05,305.25,303.25,301.06,298.75,296.38,294.04,291.7,289.22,286.81,285.71,283.98,282.45,281.07,279.24,277.82,276.4,274.75,273.15,271.5,269.65,268.32,266.3,264.15,262.47,261.31,259.57,258.24,256.23,253.94],"L_fit":-7.009,"L_eq7":-8.318},{"id":"VEF-20260730-18Z","station":"VEF","year":2026,"month":7,"day":30,"hour":18,"label":"2026-07-30 18Z","t":[310.56,306.67,303.79,302.68,301.37,299.23,296.73,294.33,291.96,289.53,287.02,284.85,283.35,281.79,279.52,277.38,277.21,276.4,275.34,273.91,272.61,271.21,269.53,267.63,265.38,263.06,260.68,258.38,256.93,255.93,254.36,252.49],"L_fit":-7.111,"L_eq7":-9.056},{"id":"VEF-20260730-12Z","station":"VEF","year":2026,"month":7,"day":30,"hour":12,"label":"2026-07-30 12Z","t":[301.27,306.3,305.67,304.37,302.29,299.84,297.96,295.49,293.12,290.71,288.24,285.91,284.56,282.38,280.04,277.96,276.68,276.23,274.84,273.66,271.71,269.86,269.06,266.91,265.21,262.85,260.42,258.23,256.88,254.76,252.79,251.06],"L_fit":-7.203,"L_eq7":-8.16},{"id":"VEF-20260729-18Z","station":"VEF","year":2026,"month":7,"day":29,"hour":18,"label":"2026-07-29 18Z","t":[313.51,306.76,304.32,301.83,299.37,296.97,294.72,292.64,290.37,288.2,286.09,283.75,281.88,280.35,278.69,277.21,275.8,273.84,272.44,271.23,269.95,268.79,267.52,265.66,263.81,262.36,260.24,258.36,256.66,255.57,254.18,252.38],"L_fit":-7.162,"L_eq7":-9.34},{"id":"VEF-20260729-12Z","station":"VEF","year":2026,"month":7,"day":29,"hour":12,"label":"2026-07-29 12Z","t":[306.58,306.1,304.79,302.85,300.61,298.26,295.89,293.48,291.13,289.15,287.25,285.07,283.26,281.6,279.34,277.17,277.07,274.69,273.43,271.78,269.86,268.15,266.5,264.88,263.16,261.84,260.62,258.47,256.6,255.19,253.55,252.49],"L_fit":-7.176,"L_eq7":-8.672},{"id":"VEF-20260728-18Z","station":"VEF","year":2026,"month":7,"day":28,"hour":18,"label":"2026-07-28 18Z","t":[312.36,307.64,304.96,302.74,300.68,298.61,296.3,293.86,291.67,289.29,286.92,284.53,282.9,281.72,279.63,278.66,277.35,276.17,274.25,272.74,271.31,269.39,267.18,265.24,263.29,262.0,260.91,259.15,257.39,255.25,253.3,252.25],"L_fit":-7.294,"L_eq7":-9.229},{"id":"VEF-20260728-12Z","station":"VEF","year":2026,"month":7,"day":28,"hour":12,"label":"2026-07-28 12Z","t":[308.28,306.08,305.79,304.43,302.36,299.97,297.52,295.13,293.05,290.9,288.62,286.38,284.22,282.23,280.4,278.91,277.92,276.24,274.25,272.84,271.56,270.11,268.0,265.89,263.8,262.04,260.04,258.11,256.67,255.11,253.29,251.44],"L_fit":-7.4,"L_eq7":-8.836},{"id":"VEF-20260727-18Z","station":"VEF","year":2026,"month":7,"day":27,"hour":18,"label":"2026-07-27 18Z","t":[311.69,307.11,304.71,302.38,300.11,297.72,295.35,293.27,291.54,289.25,286.96,285.28,283.42,281.33,279.13,277.71,276.93,276.76,275.41,274.07,272.49,270.49,268.51,266.55,264.39,262.22,260.81,260.16,258.79,257.72,255.79,253.58],"L_fit":-6.97,"L_eq7":-9.164},{"id":"VEF-20260727-12Z","station":"VEF","year":2026,"month":7,"day":27,"hour":12,"label":"2026-07-27 12Z","t":[308.26,306.43,304.73,302.58,300.58,298.57,296.44,294.24,292.04,289.67,287.42,286.1,285.22,282.82,280.54,278.62,276.8,274.96,273.03,271.27,269.49,269.16,268.67,267.06,265.18,263.14,261.35,259.56,257.63,255.71,254.61,253.61],"L_fit":-7.081,"L_eq7":-8.834},{"id":"VEF-20260726-18Z","station":"VEF","year":2026,"month":7,"day":26,"hour":18,"label":"2026-07-26 18Z","t":[313.05,308.33,305.75,303.35,300.99,298.6,296.45,294.78,293.06,291.23,289.4,287.38,284.95,282.78,281.2,279.18,277.34,275.07,272.79,270.53,268.99,268.06,266.23,265.32,263.81,262.28,261.11,259.83,257.97,256.54,255.42,254.08],"L_fit":-7.366,"L_eq7":-9.296},{"id":"VEF-20260726-12Z","station":"VEF","year":2026,"month":7,"day":26,"hour":12,"label":"2026-07-26 12Z","t":[307.85,307.08,306.49,305.03,303.56,301.25,298.85,296.86,295.0,292.93,290.76,288.65,286.75,284.62,282.6,280.56,278.35,275.94,273.61,271.77,269.92,268.54,267.02,266.33,265.01,262.77,261.88,260.02,257.75,255.6,253.75,253.09],"L_fit":-7.49,"L_eq7":-8.795},{"id":"VEF-20260725-18Z","station":"VEF","year":2026,"month":7,"day":25,"hour":18,"label":"2026-07-25 18Z","t":[314.2,309.19,306.86,304.52,302.3,299.93,297.69,295.32,293.13,291.44,289.98,287.66,285.26,283.51,282.41,280.55,279.29,277.27,274.97,272.83,270.8,268.97,266.86,264.43,262.41,262.37,260.75,259.28,258.21,257.43,255.68,254.03],"L_fit":-7.501,"L_eq7":-9.407},{"id":"VEF-20260725-12Z","station":"VEF","year":2026,"month":7,"day":25,"hour":12,"label":"2026-07-25 12Z","t":[308.7,307.39,306.25,304.67,302.9,300.67,298.43,296.19,293.95,291.72,289.71,287.95,286.31,284.67,282.96,280.97,278.98,277.0,274.96,273.2,271.34,269.4,267.18,265.14,263.2,261.9,260.7,259.5,258.23,256.42,255.22,253.66],"L_fit":-7.407,"L_eq7":-8.877},{"id":"VEF-20260724-18Z","station":"VEF","year":2026,"month":7,"day":24,"hour":18,"label":"2026-07-24 18Z","t":[314.01,310.15,307.6,305.13,302.59,300.2,297.9,295.53,293.16,290.77,288.47,286.37,284.18,282.07,280.13,278.45,276.79,274.65,272.93,271.3,270.25,269.08,267.57,265.61,264.09,262.95,261.61,259.97,258.43,256.42,254.57,252.58],"L_fit":-7.538,"L_eq7":-9.389},{"id":"VEF-20260724-12Z","station":"VEF","year":2026,"month":7,"day":24,"hour":12,"label":"2026-07-24 12Z","t":[308.17,308.59,307.02,305.05,302.91,300.85,298.83,296.58,294.21,291.92,289.57,287.17,284.77,282.65,280.64,278.72,276.89,275.21,273.56,271.92,270.34,269.03,267.67,266.23,265.03,263.46,261.84,260.12,258.41,257.25,255.67,253.72],"L_fit":-7.339,"L_eq7":-8.825},{"id":"VEF-20260723-18Z","station":"VEF","year":2026,"month":7,"day":23,"hour":18,"label":"2026-07-23 18Z","t":[310.65,307.16,304.71,303.19,301.32,299.17,296.95,295.0,292.9,290.6,288.32,286.15,283.98,281.93,279.74,277.71,275.86,274.36,272.98,271.22,270.95,269.89,267.94,265.72,263.97,262.44,261.51,260.3,258.56,256.46,254.34,253.29],"L_fit":-7.214,"L_eq7":-9.064},{"id":"VEF-20260723-12Z","station":"VEF","year":2026,"month":7,"day":23,"hour":12,"label":"2026-07-23 12Z","t":[306.5,307.0,305.57,303.74,302.28,300.21,298.0,295.64,293.59,291.27,288.96,286.75,284.36,282.41,280.38,278.34,276.45,274.31,272.61,271.5,270.61,270.25,268.56,266.39,264.37,262.44,260.7,259.21,258.57,256.99,254.92,253.14],"L_fit":-7.218,"L_eq7":-8.664},{"id":"VEF-20260722-18Z","station":"VEF","year":2026,"month":7,"day":22,"hour":18,"label":"2026-07-22 18Z","t":[310.28,305.1,302.56,299.98,298.34,296.86,294.95,292.8,290.64,288.4,286.37,284.77,282.59,280.68,278.74,277.27,275.38,273.83,271.98,270.36,269.23,268.27,267.28,266.01,264.36,262.61,261.08,259.94,258.49,256.73,254.84,253.04],"L_fit":-6.868,"L_eq7":-9.029},{"id":"VEF-20260722-12Z","station":"VEF","year":2026,"month":7,"day":22,"hour":12,"label":"2026-07-22 12Z","t":[303.05,302.82,301.22,299.76,298.72,297.06,295.47,293.37,291.14,288.71,286.63,284.5,282.44,280.35,278.55,277.27,275.34,273.99,272.3,271.0,270.07,268.41,266.83,265.28,263.79,262.75,262.01,259.99,258.08,256.51,255.5,254.02],"L_fit":-6.621,"L_eq7":-8.332},{"id":"VEF-20260721-18Z","station":"VEF","year":2026,"month":7,"day":21,"hour":18,"label":"2026-07-21 18Z","t":[310.77,306.14,303.3,300.84,298.85,296.81,294.42,292.27,290.41,288.03,286.12,283.85,281.82,280.07,278.1,276.43,274.09,272.63,271.65,270.14,269.06,267.52,266.62,265.17,264.16,262.14,260.76,259.32,257.82,257.21,255.52,253.73],"L_fit":-6.929,"L_eq7":-9.076},{"id":"VEF-20260721-12Z","station":"VEF","year":2026,"month":7,"day":21,"hour":12,"label":"2026-07-21 12Z","t":[308.26,306.71,305.2,303.25,301.0,298.75,296.63,294.45,292.39,290.17,287.91,285.56,283.28,281.08,279.36,278.17,276.33,274.1,272.09,270.61,268.97,266.74,264.91,263.4,261.92,261.55,260.79,260.67,259.27,257.68,255.74,253.96],"L_fit":-7.174,"L_eq7":-8.834},{"id":"VEF-20260720-18Z","station":"VEF","year":2026,"month":7,"day":20,"hour":18,"label":"2026-07-20 18Z","t":[310.58,306.92,304.28,301.82,299.34,296.95,294.68,292.71,290.74,288.77,286.8,284.54,282.3,280.82,279.41,277.3,275.47,273.71,271.83,270.27,268.61,267.21,265.5,264.44,263.32,261.81,260.33,259.14,257.82,256.11,254.53,252.99],"L_fit":-7.132,"L_eq7":-9.058},{"id":"VEF-20260720-12Z","station":"VEF","year":2026,"month":7,"day":20,"hour":12,"label":"2026-07-20 12Z","t":[305.04,304.09,302.98,301.14,299.39,297.62,295.75,293.65,291.5,289.3,286.87,284.61,282.45,280.25,278.4,276.76,275.28,274.31,272.78,271.17,269.76,268.05,266.79,265.4,263.79,261.72,261.21,260.17,258.64,256.78,255.56,254.01],"L_fit":-6.8,"L_eq7":-8.523},{"id":"VEF-20260719-18Z","station":"VEF","year":2026,"month":7,"day":19,"hour":18,"label":"2026-07-19 18Z","t":[308.27,303.93,301.67,299.15,297.04,296.03,294.2,292.01,290.33,288.25,286.52,284.8,282.87,280.88,278.87,276.87,275.06,273.43,272.16,270.85,269.85,268.01,266.55,264.74,263.16,262.25,261.52,260.16,258.73,257.61,256.68,255.41],"L_fit":-6.62,"L_eq7":-8.835},{"id":"VEF-20260719-12Z","station":"VEF","year":2026,"month":7,"day":19,"hour":12,"label":"2026-07-19 12Z","t":[306.92,305.47,304.02,302.1,299.96,298.29,296.15,294.04,291.88,289.76,287.46,285.39,283.75,281.77,279.79,277.77,276.16,274.31,272.45,270.99,269.35,270.15,268.54,266.72,264.71,263.8,261.92,259.91,258.4,257.15,256.66,254.85],"L_fit":-6.839,"L_eq7":-8.705},{"id":"VEF-20260718-18Z","station":"VEF","year":2026,"month":7,"day":18,"hour":18,"label":"2026-07-18 18Z","t":[304.98,301.24,298.87,297.58,296.63,295.41,293.61,291.35,289.55,287.61,285.8,284.02,281.84,279.97,278.13,276.97,275.8,274.31,272.6,271.28,269.25,267.65,266.2,265.0,263.7,262.7,262.82,260.93,258.87,256.68,254.53,252.44],"L_fit":-6.419,"L_eq7":-8.518},{"id":"VEF-20260718-12Z","station":"VEF","year":2026,"month":7,"day":18,"hour":12,"label":"2026-07-18 12Z","t":[301.16,298.17,298.3,298.16,296.53,295.01,293.06,291.37,289.53,287.83,286.27,284.48,282.63,280.9,278.66,277.07,275.74,274.03,272.16,270.61,268.91,267.16,265.75,264.61,262.79,260.85,258.67,257.66,258.2,257.18,255.24,253.18],"L_fit":-6.415,"L_eq7":-8.149},{"id":"VEF-20260717-18Z","station":"VEF","year":2026,"month":7,"day":17,"hour":18,"label":"2026-07-17 18Z","t":[305.23,301.04,298.47,296.2,296.3,294.18,292.96,290.77,289.14,287.31,286.1,284.8,282.76,280.45,278.19,276.47,275.09,272.99,271.46,269.87,268.33,267.23,266.28,264.69,263.11,261.35,259.66,258.12,256.18,254.06,252.46,250.98],"L_fit":-6.68,"L_eq7":-8.541},{"id":"VEF-20260717-12Z","station":"VEF","year":2026,"month":7,"day":17,"hour":12,"label":"2026-07-17 12Z","t":[303.69,300.44,298.55,297.37,295.69,293.71,291.65,290.23,288.89,286.8,284.88,283.56,281.53,280.18,278.47,276.68,274.97,273.44,271.86,270.13,268.22,266.73,265.24,262.83,261.14,261.98,260.89,259.28,257.59,256.04,254.52,253.1],"L_fit":-6.433,"L_eq7":-8.393},{"id":"VEF-20260716-18Z","station":"VEF","year":2026,"month":7,"day":16,"hour":18,"label":"2026-07-16 18Z","t":[309.9,305.97,303.26,300.92,299.08,297.77,295.69,293.55,291.56,289.59,287.58,285.38,283.16,281.07,279.05,277.13,275.29,273.6,271.99,270.42,269.49,267.56,266.32,264.92,262.91,261.35,259.63,258.33,256.98,255.22,253.55,251.91],"L_fit":-7.217,"L_eq7":-8.992},{"id":"VEF-20260716-12Z","station":"VEF","year":2026,"month":7,"day":16,"hour":12,"label":"2026-07-16 12Z","t":[304.06,305.88,304.16,302.57,301.2,299.53,297.31,295.06,292.89,290.61,288.41,286.02,283.58,281.36,279.05,277.13,275.84,274.28,272.2,270.72,269.18,267.83,266.6,264.99,263.98,262.58,260.69,258.47,257.35,256.04,253.88,252.19],"L_fit":-7.179,"L_eq7":-8.429},{"id":"VEF-20260715-12Z","station":"VEF","year":2026,"month":7,"day":15,"hour":12,"label":"2026-07-15 12Z","t":[303.87,306.56,304.77,302.63,300.38,298.12,296.14,294.09,291.83,289.44,287.05,284.66,282.31,280.22,278.37,276.19,275.3,273.68,272.4,271.05,269.61,268.26,266.63,265.06,264.0,262.92,261.04,259.99,258.4,256.57,254.61,252.72],"L_fit":-6.982,"L_eq7":-8.41},{"id":"VEF-20260715-06Z","station":"VEF","year":2026,"month":7,"day":15,"hour":6,"label":"2026-07-15 06Z","t":[311.51,308.75,306.56,304.18,301.86,299.47,297.17,294.74,292.38,290.18,287.9,285.63,283.52,281.69,279.72,277.96,276.38,274.65,273.17,271.68,269.94,268.35,267.62,265.53,263.75,262.35,260.92,259.77,257.81,256.48,254.17,252.75],"L_fit":-7.388,"L_eq7":-9.148},{"id":"VEF-20260702-12Z","station":"VEF","year":2026,"month":7,"day":2,"hour":12,"label":"2026-07-02 12Z","t":[300.42,299.59,298.55,296.79,294.48,292.13,290.35,288.11,285.81,283.56,281.42,279.15,277.11,274.9,273.49,272.16,271.77,270.5,268.91,266.81,265.12,263.1,261.41,259.72,257.86,255.55,253.8,251.67,249.8,248.45,246.66,244.62],"L_fit":-7.24,"L_eq7":-8.078},{"id":"VEF-20260702-06Z","station":"VEF","year":2026,"month":7,"day":2,"hour":6,"label":"2026-07-02 06Z","t":[306.14,302.74,300.49,298.19,295.89,293.6,291.34,289.05,286.73,284.38,281.95,279.63,277.22,276.29,275.5,274.28,272.28,270.44,268.47,266.89,265.46,263.51,261.37,259.09,256.81,254.94,253.03,251.13,249.39,247.77,246.02,244.08],"L_fit":-7.702,"L_eq7":-8.63},{"id":"VEF-20260701-12Z","station":"VEF","year":2026,"month":7,"day":1,"hour":12,"label":"2026-07-01 12Z","t":[300.04,298.42,297.53,295.82,294.03,291.89,289.69,287.41,284.93,282.75,280.75,278.47,276.93,275.24,273.96,273.08,271.88,270.4,268.97,266.99,265.07,263.32,261.11,258.73,256.44,254.43,252.19,250.69,249.29,247.11,244.89,243.19],"L_fit":-7.306,"L_eq7":-8.041},{"id":"VEF-20260701-06Z","station":"VEF","year":2026,"month":7,"day":1,"hour":6,"label":"2026-07-01 06Z","t":[304.28,301.43,299.48,297.4,295.28,293.05,290.96,288.78,286.34,283.98,281.72,279.33,277.03,274.85,272.55,270.62,270.99,271.12,269.09,267.22,264.85,263.05,261.65,259.77,258.13,256.74,254.6,252.26,250.12,248.23,246.34,244.22],"L_fit":-7.419,"L_eq7":-8.45},{"id":"VEF-20260630-12Z","station":"VEF","year":2026,"month":6,"day":30,"hour":12,"label":"2026-06-30 12Z","t":[299.16,297.29,296.91,295.41,294.07,291.77,289.67,287.32,284.9,282.58,280.24,277.86,275.51,273.1,271.35,269.14,267.07,264.84,262.8,261.94,260.74,258.85,257.32,256.25,254.89,253.9,252.38,250.5,248.25,245.94,243.83,241.85],"L_fit":-7.521,"L_eq7":-7.957}]}} diff --git a/recovery-calculator/frontend/src/lib/wind.ts b/recovery-calculator/frontend/src/lib/wind.ts new file mode 100644 index 000000000..7cbef81ba --- /dev/null +++ b/recovery-calculator/frontend/src/lib/wind.ts @@ -0,0 +1,111 @@ +/** + * The wind climatology, reduced to what the Drift tab needs, and the resolver + * that turns a selection into a `WindInput` for the backend. + * + * A hook rather than a context, exactly like `usePadClimatology`: the bundle is + * a one-shot cached fetch, so a second caller costs nothing, and a provider + * would put the app inside a subscription for a value that never changes after + * load. + * + * The reduction and the resolution both live here, in one place, because the + * "values travel, not the recipe" contract with the backend means the profile + * arrays the tab posts have to be built the same way every time -- and the + * worst-case (p95) construction in particular is a real choice, not a lookup. + */ + +import { useEffect, useState } from 'react' +import { getClimatology } from '../api/client' +import type { WindMonth } from '../types/climatology' +import type { WindInput } from '../types/schema' + +/** How the tab picks a wind. Climatology mean, its p95 strong-wind sibling, or + * a single value the user types. */ +export type WindMode = 'climatology' | 'worst' | 'manual' + +export interface WindTag { + id: string + label: string +} + +export interface WindClimatology { + /** Shared height grid, geopotential metres MSL. Null until the bundle lands. */ + grid_m: number[] | null + /** dataset tag -> calendar month -> that month's wind. */ + byTag: Record> | null + /** Tags that actually carry wind, with human labels, most-relevant first. */ + tags: WindTag[] +} + +/** + * The pooled Edwards + China Lake set is the default and the only dataset + * inside 50 km of the pad, so it leads the tag list -- the same dataset the + * temperature profile and lapse rates come from, so a Drift run and the + * Atmospheric Data tab cannot disagree about what January looks like. + */ +export function useWindClimatology(): WindClimatology { + const [state, setState] = useState({ + grid_m: null, byTag: null, tags: [], + }) + + useEffect(() => { + let live = true + getClimatology().then((res) => { + if (!live || !res.data) return + const wind = res.data.upper.wind + if (!wind) return + + const labelOf: Record = {} + for (const d of res.data.upper.datasets) labelOf[d.id] = d.label + + const byTag: Record> = {} + for (const [tag, months] of Object.entries(wind)) { + const byMonth: Record = {} + for (const m of months) byMonth[m.month] = m + byTag[tag] = byMonth + } + + // edw-nid first (the pooled default), then the rest alphabetical. + const tags = Object.keys(byTag) + .sort((a, b) => (a === 'edw-nid' ? -1 : b === 'edw-nid' ? 1 + : a.localeCompare(b))) + .map((id) => ({ id, label: labelOf[id] ?? id })) + + setState({ grid_m: res.data.upper.grid_m, byTag, tags }) + }) + return () => { live = false } + }, []) + + return state +} + +/** (u_east, v_north) m/s from a speed and the bearing the wind blows FROM. + * The same meteorological convention as physics/wind.py. */ +export function uvFromSpeedDir(speed: number, directionFrom: number): [number, number] { + const r = (directionFrom * Math.PI) / 180 + return [-speed * Math.sin(r), -speed * Math.cos(r)] +} + +/** + * Build the `WindInput` for a climatology month. + * + * The **mean** profile posts the mean vector at each level directly. The + * **worst-case** profile keeps the mean bearing at each level but swaps in the + * p95 speed -- a coherent strong-wind vector profile, which is what a + * deterministic worst-case drift wants, rather than the (incoherent) p95 of + * each component independently. + */ +export function profileWindInput( + wm: WindMonth, grid: number[], worst: boolean, +): WindInput { + if (!worst) { + return { kind: 'profile', heights_msl: grid, u: wm.u, v: wm.v } + } + const u: number[] = [] + const v: number[] = [] + for (let i = 0; i < grid.length; i++) { + const [uu, vv] = uvFromSpeedDir(wm.spd_p95[i], wm.dir[i]) + u.push(uu) + v.push(vv) + } + return { kind: 'profile', heights_msl: grid, u, v } +} diff --git a/recovery-calculator/frontend/src/types/climatology.ts b/recovery-calculator/frontend/src/types/climatology.ts index 34fb424a3..fac00e743 100644 --- a/recovery-calculator/frontend/src/types/climatology.ts +++ b/recovery-calculator/frontend/src/types/climatology.ts @@ -69,6 +69,25 @@ export interface UpperMonth { eq7_err: number[] } +/** + * One calendar month of wind, as parallel arrays down the shared height grid. + * + * Stored as u (east) / v (north) components -- the RocketPy convention and what + * the drift model consumes -- plus speed quantiles for the day-to-day spread. + * `spd_p95` is the deterministic "worst-case wind" the Drift tab offers; `dir` + * is the bearing the mean wind blows FROM. + */ +export interface WindMonth { + month: number + n: number + u: number[] + v: number[] + spd: number[] + spd_p05: number[] + spd_p95: number[] + dir: number[] +} + export interface LapseMonth { month: number n: number @@ -141,6 +160,10 @@ export interface Climatology { datasets: UpperDataset[] profile: Record lapse: Record + /** Monthly wind per dataset tag. Optional: generated by wind_profile.py, + * which runs separately from the temperature profile, so a tag can have a + * temperature profile without a wind one. */ + wind?: Record } soundings: Record } diff --git a/recovery-calculator/frontend/src/types/schema.ts b/recovery-calculator/frontend/src/types/schema.ts index 65aebc085..9295996e3 100644 --- a/recovery-calculator/frontend/src/types/schema.ts +++ b/recovery-calculator/frontend/src/types/schema.ts @@ -463,3 +463,40 @@ export interface Result { /** Non-null only when the §6.4 band was run both ways. */ body_drag_band: { axial: number; broadside: number } | null } + +// ============================================================================ +// DRIFT -- PLAN.md §21 +// ============================================================================ + +/** + * The wind a drift run is carried by, as `/api/drift` wants it. + * + * A discriminated union on `kind`, mirroring the backend's `WindInput`. The + * frontend resolves a climatology month/percentile to the `profile` arrays + * before posting -- values travel, not the recipe, the same way a study carries + * a resolved `PadState` rather than a lookup key. + */ +export type WindInput = + | { kind: 'constant'; speed: number; direction: number } + | { kind: 'profile'; heights_msl: number[]; u: number[]; v: number[] } + +/** One point on the horizontal ground track. East = +x, North = +y, metres. */ +export interface DriftTrackSample { + t: number + z: number + x: number + y: number +} + +export interface DriftResult { + /** Straight-line pad-to-landing distance, m. */ + distance: number + /** Compass bearing pad -> landing, degrees (0 = north, 90 = east). */ + bearing_deg: number + descent_time: number + landing: { x: number; y: number } + track: DriftTrackSample[] + /** What the wind actually was at the ground in the run. */ + wind_ground: { speed: number; heading_deg: number } + airframe_bound: string +} diff --git a/recovery-calculator/physics/drift.py b/recovery-calculator/physics/drift.py new file mode 100644 index 000000000..28966985f --- /dev/null +++ b/recovery-calculator/physics/drift.py @@ -0,0 +1,83 @@ +"""Downwind drift under recovery. PLAN.md §21 (Phase 2). + +Post-processing, not a second integration: it takes the descent a `solver.run` +already produced and carries the vehicle sideways with the wind. That is +sufficient here because the model is deliberately the **equilibrium** one -- + + horizontally the only force on the canopy is drag, and drag drives its + horizontal velocity to match the local wind, so v_horizontal(z) = v_wind(z) + +-- which needs only the altitude-vs-time history, not a coupled 2-D state. The +same Cd*S that sets the descent rate is what couples the canopy to the wind, so +there is no separate "how much wind it catches" term; a round (non-gliding) +canopy simply goes where the air goes. + +Assumptions, all first-order and matching §21: + * **Horizontal wind only** -- no vertical air motion (thermals are left as + future uncertainty, not modelled here). + * **No response lag** -- the ~1 s relaxation to a new wind is neglected, so + the canopy is taken to match the wind instantly. This biases drift very + slightly high in shear, which is the conservative direction. + * **No pendulum / glide** -- a round canopy, so no net lift. + +This is the altitude-resolved version of the mastersheet's scalar estimate +(`mastersheet.py`: drift = wind * descent_time). Integrating over the trajectory +instead weights the wind by the time spent at each altitude, so the slow descent +under the main correctly picks up more of the low-altitude wind. +""" + +import math + +import numpy as np + + +class DriftResult: + """Horizontal ground track and its summary. East = +x, North = +y.""" + + __slots__ = ("t", "z", "x", "y", "distance", "bearing_deg") + + def __init__(self, t, z, x, y, distance, bearing_deg): + self.t = t # s, from apogee + self.z = z # m AGL, matches the descent trajectory + self.x = x # m east of the pad + self.y = y # m north of the pad + self.distance = distance # m, straight-line pad-to-landing + self.bearing_deg = bearing_deg # compass bearing pad->landing, deg + + def __repr__(self): + return ("DriftResult(distance=%.0f m, bearing=%.0f deg)" + % (self.distance, self.bearing_deg)) + + +def compute_drift(run, wind): + """Integrate the wind over `run`'s descent. Returns a `DriftResult`. + + `run` is a `solver.RunResult`; `wind` is a `wind.WindProfile`. The track + starts at the pad (0, 0) at apogee and accumulates by the trapezoid rule, + so it lands where the summed wind carried it. + """ + t = np.asarray(run.traj.t, dtype=float) + z = np.asarray(run.traj.z, dtype=float) + + if t.size < 2: + # A degenerate run (never left the pad). No descent, no drift. + zero = np.zeros(t.size) + return DriftResult(t, z, zero, zero, 0.0, 0.0) + + # Wind at each trajectory altitude. WindProfile is scalar per call; the + # trajectory is ~a few thousand samples, evaluated once. + u = np.array([wind.u(zi) for zi in z]) + v = np.array([wind.v(zi) for zi in z]) + + dt = np.diff(t) + # Trapezoid: mean of the endpoint winds over each step, since the canopy + # moves with the local wind at every instant. + x = np.concatenate(([0.0], np.cumsum(0.5 * (u[:-1] + u[1:]) * dt))) + y = np.concatenate(([0.0], np.cumsum(0.5 * (v[:-1] + v[1:]) * dt))) + + x_end, y_end = float(x[-1]), float(y[-1]) + distance = math.hypot(x_end, y_end) + # Compass bearing pad -> landing: 0 = north, 90 = east. + bearing = math.degrees(math.atan2(x_end, y_end)) % 360.0 if distance else 0.0 + + return DriftResult(t, z, x, y, distance, bearing) diff --git a/recovery-calculator/physics/wind.py b/recovery-calculator/physics/wind.py new file mode 100644 index 000000000..a66694fde --- /dev/null +++ b/recovery-calculator/physics/wind.py @@ -0,0 +1,146 @@ +"""Horizontal wind profile. PLAN.md §21 (Phase 2 wind/drift). + +Stdlib only, like `atmosphere.py`, so `site-climatology/` can import it without +a venv and the CLI stays dependency-light. Immutable once constructed. + +**Shape is chosen for RocketPy.** The unified simulator we are heading toward +runs on RocketPy, whose `Environment.set_atmospheric_model("custom_atmosphere", +wind_u=..., wind_v=...)` wants wind as two orthogonal components, in m/s, as a +function of altitude MSL: + + wind_u east (x) component + wind_v north (y) component + +So that is exactly what this stores and returns. `to_rocketpy()` emits the +`[height_msl, value]` point arrays RocketPy accepts directly, and the drift +integrator in `drift.py` is the only other consumer. + +**Meteorological convention.** A reported wind *direction* is the compass +bearing the wind blows *from*, clockwise from north (270 deg = a westerly, out +of the west, blowing toward the east). The vector the vehicle actually feels +points the other way, so: + + u_east = -speed * sin(dir) + v_north = -speed * cos(dir) + +`heading()` inverts this back to the bearing the wind blows *toward*, which is +the direction a drifting canopy travels. + +**Altitude convention** matches `Atmosphere`: methods take geometric altitude +AGL (the solver's state variable z, §1.1) and add `site_elev` internally to +reach the MSL grid. The climatology grid is geopotential MSL; the +geopotential/geometric gap is under 0.13% at 8 km, four orders below the wind's +own month-to-month spread, so it is treated as MSL directly rather than carrying +the eq (1) conversion into a quantity this uncertain. +""" + +import bisect +import math + +from physics.site import FAR_ELEV_M + + +def uv_from_speed_dir(speed, direction_from_deg): + """(u_east, v_north) m/s from speed and the bearing wind blows *from*.""" + r = math.radians(direction_from_deg) + return (-speed * math.sin(r), -speed * math.cos(r)) + + +class WindProfile: + """Horizontal wind as (u_east, v_north) m/s vs altitude. Immutable. + + Construct with `constant(...)` for a uniform wind or `from_grid(...)` for a + tabulated profile (e.g. a monthly climatology). Altitudes passed to `u`, + `v`, `speed` and `heading` are geometric AGL; `site_elev` is added to reach + the MSL grid. + """ + + __slots__ = ("site_elev", "_h", "_u", "_v") + + def __init__(self, heights_msl, u, v, site_elev=FAR_ELEV_M): + if not (len(heights_msl) == len(u) == len(v)): + raise ValueError("heights, u and v must be the same length") + if len(heights_msl) == 0: + raise ValueError("wind profile needs at least one level") + # Sort by height so bisect works and callers need not pre-sort. + order = sorted(range(len(heights_msl)), key=lambda i: heights_msl[i]) + self._h = [float(heights_msl[i]) for i in order] + self._u = [float(u[i]) for i in order] + self._v = [float(v[i]) for i in order] + self.site_elev = float(site_elev) + + # -- constructors ------------------------------------------------------- + + @classmethod + def constant(cls, speed, direction_from_deg, site_elev=FAR_ELEV_M): + """A uniform wind of `speed` m/s blowing *from* `direction_from_deg`.""" + if speed < 0.0: + raise ValueError("wind speed must be non-negative, got %r" % speed) + u, v = uv_from_speed_dir(speed, direction_from_deg) + # A single level suffices; interpolation holds it at every altitude. + return cls([site_elev], [u], [v], site_elev=site_elev) + + @classmethod + def from_grid(cls, heights_msl, u, v, site_elev=FAR_ELEV_M): + """A tabulated profile: u/v m/s at each MSL height. See class docstring.""" + return cls(heights_msl, u, v, site_elev=site_elev) + + # -- evaluation --------------------------------------------------------- + + def _interp(self, z_agl, table): + """Linear interpolation of `table` at geometric altitude AGL, held flat + outside the tabulated band (no extrapolation of a fitted slope).""" + z = z_agl + self.site_elev + h = self._h + if len(h) == 1 or z <= h[0]: + return table[0] + if z >= h[-1]: + return table[-1] + i = bisect.bisect_right(h, z) + h0, h1 = h[i - 1], h[i] + t0, t1 = table[i - 1], table[i] + return t0 + (t1 - t0) * (z - h0) / (h1 - h0) + + def u(self, z_agl): + """East (x) component, m/s, at geometric altitude AGL.""" + return self._interp(z_agl, self._u) + + def v(self, z_agl): + """North (y) component, m/s, at geometric altitude AGL.""" + return self._interp(z_agl, self._v) + + def speed(self, z_agl): + """Wind speed magnitude, m/s.""" + return math.hypot(self.u(z_agl), self.v(z_agl)) + + def heading(self, z_agl): + """Bearing the wind blows *toward*, degrees clockwise from north. + + This is the direction a drifting canopy travels; it is the reported + met direction plus 180. Returns 0 for calm. + """ + u, v = self.u(z_agl), self.v(z_agl) + if u == 0.0 and v == 0.0: + return 0.0 + return math.degrees(math.atan2(u, v)) % 360.0 + + # -- RocketPy handoff --------------------------------------------------- + + def to_rocketpy(self): + """`(wind_u, wind_v)` as `[[height_msl, value], ...]` point arrays. + + Feeds straight into + `Environment.set_atmospheric_model("custom_atmosphere", + wind_u=..., wind_v=...)` -- the whole reason this class stores u/v vs + MSL altitude. + """ + wind_u = [[h, u] for h, u in zip(self._h, self._u)] + wind_v = [[h, v] for h, v in zip(self._h, self._v)] + return wind_u, wind_v + + def __repr__(self): + if len(self._h) == 1: + return ("WindProfile(constant u=%.2f v=%.2f, |v|=%.2f m/s)" + % (self._u[0], self._v[0], math.hypot(self._u[0], self._v[0]))) + return ("WindProfile(%d levels, %.0f-%.0f m MSL)" + % (len(self._h), self._h[0], self._h[-1])) diff --git a/recovery-calculator/site-climatology/data/edw-nid-wprofile-monthly.csv b/recovery-calculator/site-climatology/data/edw-nid-wprofile-monthly.csv new file mode 100644 index 000000000..947ed12fa --- /dev/null +++ b/recovery-calculator/site-climatology/data/edw-nid-wprofile-monthly.csv @@ -0,0 +1,385 @@ +month,n_soundings,H_msl_m,H_agl_ft,u_mean_ms,v_mean_ms,spd_mean_ms,spd_sd_ms,spd_p05_ms,spd_p50_ms,spd_p95_ms,dir_mean_deg +1,72,630,0,-0.32,0.26,2.81,3.81,0.50,2.18,6.69,129.6 +1,72,880,820,-0.63,-0.50,2.90,2.95,0.37,1.75,8.56,51.8 +1,72,1130,1640,-1.24,-1.41,4.31,3.44,0.73,3.94,11.73,41.4 +1,72,1380,2461,-1.67,-2.13,5.42,3.65,0.99,4.63,10.81,38.2 +1,72,1630,3281,-1.86,-2.58,6.33,4.04,1.06,5.55,13.14,35.7 +1,72,1880,4101,-1.56,-2.75,6.71,4.26,1.19,5.80,14.56,29.5 +1,72,2130,4921,-1.05,-2.84,7.15,4.26,1.78,6.23,14.73,20.3 +1,72,2380,5741,-0.44,-3.01,7.64,4.51,2.02,6.52,15.68,8.3 +1,72,2630,6562,0.15,-3.23,8.17,4.95,2.37,7.17,16.68,357.3 +1,72,2880,7382,0.73,-3.34,8.66,5.33,2.26,7.22,19.11,347.7 +1,72,3130,8202,1.22,-3.53,9.17,5.73,2.52,7.72,21.21,340.9 +1,72,3380,9022,1.79,-3.76,9.49,5.85,2.80,8.32,20.92,334.5 +1,72,3630,9843,2.44,-3.91,9.81,6.14,3.36,8.33,22.38,328.0 +1,72,3880,10663,3.06,-4.15,10.27,6.53,3.08,8.78,23.48,323.6 +1,72,4130,11483,3.69,-4.44,10.89,7.04,3.38,9.21,24.19,320.3 +1,72,4380,12303,4.19,-4.67,11.53,7.43,3.85,9.37,26.35,318.1 +1,72,4630,13123,4.72,-4.79,12.01,7.58,3.73,9.90,27.03,315.4 +1,72,4880,13944,5.26,-4.89,12.56,7.77,3.79,10.60,27.98,312.9 +1,72,5130,14764,5.90,-5.05,13.21,8.06,3.69,11.48,29.66,310.6 +1,72,5380,15584,6.60,-5.10,13.81,8.18,4.02,11.91,30.10,307.7 +1,72,5630,16404,7.12,-5.10,14.31,8.35,3.86,12.54,30.71,305.6 +1,72,5880,17224,7.47,-5.15,14.71,8.52,3.70,12.88,31.83,304.6 +1,72,6130,18045,7.81,-5.14,15.12,8.68,3.97,13.50,32.83,303.3 +1,72,6380,18865,8.14,-5.29,15.64,8.77,3.65,13.74,34.57,303.0 +1,72,6630,19685,8.57,-5.40,16.18,8.87,3.98,14.29,35.44,302.2 +1,72,6880,20505,9.04,-5.51,16.81,9.10,4.85,14.85,35.93,301.4 +1,72,7130,21325,9.47,-5.52,17.34,9.50,5.24,16.41,36.83,300.3 +1,72,7380,22146,9.93,-5.55,17.93,9.84,4.78,16.47,38.14,299.2 +1,72,7630,22966,10.46,-5.74,18.60,10.03,5.57,16.87,38.93,298.8 +1,72,7880,23786,10.86,-5.90,19.30,10.31,6.02,17.28,39.70,298.5 +1,72,8130,24606,11.19,-6.00,20.02,10.64,5.63,18.14,40.47,298.2 +1,72,8380,25427,11.54,-5.90,20.72,11.03,5.83,18.39,41.24,297.1 +2,108,630,0,0.53,0.63,3.22,2.45,0.61,2.61,8.10,220.1 +2,108,880,820,0.97,-0.40,4.38,3.61,0.64,3.35,11.89,292.4 +2,108,1130,1640,1.29,-1.61,6.12,4.25,1.02,5.57,14.84,321.3 +2,108,1380,2461,1.12,-2.32,7.17,4.28,1.28,6.75,14.07,334.1 +2,108,1630,3281,1.16,-2.98,7.92,4.64,0.83,7.25,15.96,338.6 +2,108,1880,4101,1.47,-3.25,8.37,4.64,1.27,7.94,16.21,335.6 +2,108,2130,4921,2.03,-3.60,9.04,4.79,2.32,8.74,17.03,330.6 +2,108,2380,5741,2.47,-3.85,9.73,5.06,2.69,9.37,18.15,327.3 +2,108,2630,6562,3.22,-4.25,10.57,5.59,3.40,9.60,21.51,322.8 +2,108,2880,7382,3.80,-4.63,11.45,6.16,3.49,10.09,23.96,320.6 +2,108,3130,8202,4.39,-5.07,12.32,6.60,3.20,10.95,25.69,319.1 +2,108,3380,9022,5.12,-5.34,12.92,6.91,3.73,11.72,26.95,316.2 +2,108,3630,9843,5.81,-5.52,13.53,7.22,4.27,12.04,28.08,313.6 +2,108,3880,10663,6.28,-5.62,14.09,7.48,4.50,12.30,28.61,311.8 +2,108,4130,11483,6.93,-5.76,14.69,7.68,4.69,12.99,28.98,309.7 +2,108,4380,12303,7.61,-6.00,15.31,7.97,4.71,13.59,29.87,308.2 +2,108,4630,13123,8.37,-6.06,15.94,8.40,5.48,14.03,31.40,305.9 +2,108,4880,13944,9.07,-6.22,16.65,9.00,5.02,14.32,33.14,304.4 +2,108,5130,14764,9.71,-6.47,17.47,9.74,4.79,15.03,34.72,303.7 +2,108,5380,15584,10.31,-6.82,18.40,10.36,4.99,16.42,38.13,303.5 +2,108,5630,16404,10.89,-7.13,19.30,10.88,5.03,17.27,39.24,303.2 +2,108,5880,17224,11.44,-7.22,19.97,11.15,4.96,18.20,40.37,302.2 +2,108,6130,18045,11.94,-7.28,20.69,11.34,5.86,18.82,41.97,301.4 +2,108,6380,18865,12.46,-7.48,21.55,11.52,5.62,19.79,43.22,301.0 +2,108,6630,19685,12.90,-7.66,22.35,11.80,5.66,20.63,43.79,300.7 +2,108,6880,20505,13.35,-7.84,23.19,12.12,5.83,21.43,45.85,300.4 +2,108,7130,21325,13.72,-7.98,23.97,12.42,5.94,22.12,48.74,300.2 +2,108,7380,22146,14.05,-8.15,24.74,12.72,5.50,22.73,49.98,300.1 +2,108,7630,22966,14.56,-8.34,25.51,13.06,6.59,23.13,51.10,299.8 +2,108,7880,23786,15.14,-8.46,26.26,13.43,7.39,24.07,52.70,299.2 +2,108,8130,24606,15.78,-8.46,26.99,13.82,8.19,24.13,54.44,298.2 +2,108,8380,25427,16.43,-8.45,27.79,14.18,8.29,24.86,56.11,297.2 +3,178,630,0,1.35,0.89,3.78,3.74,0.48,2.85,8.96,236.6 +3,178,880,820,1.69,0.23,4.63,3.45,0.72,3.59,11.46,262.1 +3,178,1130,1640,1.69,-0.31,5.69,3.95,0.96,5.06,12.66,280.5 +3,178,1380,2461,1.57,-0.75,6.44,4.13,1.60,5.92,13.70,295.6 +3,178,1630,3281,1.68,-1.04,6.84,4.24,1.51,6.57,14.29,301.9 +3,178,1880,4101,2.01,-1.18,7.04,4.21,1.16,6.86,13.68,300.4 +3,178,2130,4921,2.46,-1.31,7.49,4.26,1.52,7.25,13.48,298.0 +3,178,2380,5741,3.02,-1.37,8.15,4.39,1.87,7.93,15.95,294.4 +3,178,2630,6562,3.70,-1.30,8.82,4.75,2.25,8.12,17.27,289.3 +3,178,2880,7382,4.47,-1.41,9.54,5.27,1.87,8.90,19.21,287.5 +3,178,3130,8202,5.28,-1.54,10.39,5.70,1.97,10.04,20.45,286.3 +3,178,3380,9022,6.16,-1.56,11.06,6.07,2.46,10.60,21.51,284.2 +3,178,3630,9843,6.94,-1.57,11.64,6.43,2.78,10.87,23.18,282.8 +3,178,3880,10663,7.65,-1.61,12.17,6.59,3.78,11.32,24.33,281.9 +3,178,4130,11483,8.40,-1.72,12.84,6.82,4.12,11.64,25.37,281.6 +3,178,4380,12303,9.06,-1.72,13.57,7.16,4.28,12.07,26.94,280.7 +3,178,4630,13123,9.67,-1.65,14.31,7.55,4.33,12.76,28.20,279.7 +3,178,4880,13944,10.28,-1.65,15.09,7.90,3.98,13.60,29.41,279.1 +3,178,5130,14764,10.93,-1.66,15.88,8.22,4.26,14.19,30.84,278.6 +3,178,5380,15584,11.64,-1.74,16.67,8.55,4.82,14.98,32.86,278.5 +3,178,5630,16404,12.39,-1.84,17.50,8.94,5.40,15.31,34.61,278.5 +3,178,5880,17224,13.03,-1.82,18.21,9.15,6.07,16.04,35.96,278.0 +3,178,6130,18045,13.75,-1.78,18.86,9.39,5.36,17.30,36.43,277.4 +3,178,6380,18865,14.49,-1.74,19.58,9.70,5.71,17.79,36.95,276.8 +3,178,6630,19685,15.16,-1.69,20.30,10.05,5.51,18.72,38.92,276.4 +3,178,6880,20505,15.81,-1.67,21.08,10.39,5.44,19.49,39.73,276.0 +3,178,7130,21325,16.48,-1.62,21.91,10.70,5.75,20.50,40.35,275.6 +3,178,7380,22146,17.23,-1.53,22.75,11.08,5.95,21.40,40.89,275.1 +3,178,7630,22966,17.88,-1.43,23.49,11.44,5.68,22.74,41.47,274.6 +3,178,7880,23786,18.41,-1.35,24.21,11.78,6.12,23.55,42.44,274.2 +3,178,8130,24606,18.94,-1.42,24.94,12.07,6.67,24.00,44.06,274.3 +3,178,8380,25427,19.47,-1.56,25.66,12.43,6.89,24.33,45.45,274.6 +4,124,630,0,1.77,0.79,3.86,3.02,0.59,3.25,9.51,246.0 +4,124,880,820,2.15,0.33,4.40,3.27,0.99,3.04,11.23,261.4 +4,124,1130,1640,2.19,-0.05,5.17,3.84,0.93,4.09,12.16,271.4 +4,124,1380,2461,1.93,-0.57,5.84,3.79,1.23,5.10,12.82,286.6 +4,124,1630,3281,2.00,-0.95,6.04,3.84,1.24,5.18,12.75,295.4 +4,124,1880,4101,2.35,-1.30,6.14,4.05,1.45,5.11,13.25,298.8 +4,124,2130,4921,2.76,-1.59,6.47,4.30,1.45,5.62,14.68,299.9 +4,124,2380,5741,3.18,-1.86,6.88,4.48,1.50,5.78,15.52,300.3 +4,124,2630,6562,3.70,-1.97,7.50,4.77,1.40,6.28,17.35,298.0 +4,124,2880,7382,4.15,-2.12,8.04,5.05,1.75,6.92,18.22,297.1 +4,124,3130,8202,4.74,-2.28,8.50,5.36,2.01,7.45,18.66,295.7 +4,124,3380,9022,5.37,-2.55,8.90,5.67,2.11,7.95,20.76,295.4 +4,124,3630,9843,5.99,-2.89,9.52,5.81,2.10,8.70,21.90,295.8 +4,124,3880,10663,6.57,-3.13,10.26,6.10,2.45,9.17,23.10,295.5 +4,124,4130,11483,7.17,-3.36,11.00,6.50,2.81,9.85,24.35,295.1 +4,124,4380,12303,7.94,-3.56,11.77,6.88,3.05,10.40,25.33,294.2 +4,124,4630,13123,8.59,-3.73,12.53,7.12,3.48,11.45,26.97,293.5 +4,124,4880,13944,9.25,-3.83,13.25,7.30,4.08,11.90,28.37,292.5 +4,124,5130,14764,9.83,-3.93,13.85,7.62,4.96,12.50,29.79,291.8 +4,124,5380,15584,10.38,-3.97,14.43,7.97,5.21,13.05,31.22,290.9 +4,124,5630,16404,10.90,-4.08,15.08,8.37,4.81,13.67,32.59,290.5 +4,124,5880,17224,11.41,-4.28,15.74,8.64,4.71,14.07,33.64,290.5 +4,124,6130,18045,11.92,-4.40,16.33,8.94,5.05,14.58,34.38,290.2 +4,124,6380,18865,12.44,-4.53,16.98,9.16,5.86,15.64,34.76,290.0 +4,124,6630,19685,12.83,-4.74,17.55,9.40,6.30,16.19,35.35,290.3 +4,124,6880,20505,13.30,-5.00,18.22,9.75,5.93,16.81,37.70,290.6 +4,124,7130,21325,13.82,-5.16,18.89,10.16,5.77,17.31,39.61,290.5 +4,124,7380,22146,14.30,-5.26,19.47,10.51,5.44,17.85,40.34,290.2 +4,124,7630,22966,14.82,-5.42,20.06,10.76,5.73,18.37,41.53,290.1 +4,124,7880,23786,15.36,-5.56,20.70,10.95,6.22,18.65,42.80,289.9 +4,124,8130,24606,15.77,-5.77,21.26,11.08,7.33,18.55,44.08,290.1 +4,124,8380,25427,16.12,-5.97,21.81,11.27,7.36,18.87,45.10,290.3 +5,86,630,0,1.31,0.94,3.72,2.72,0.59,2.82,8.18,234.3 +5,86,880,820,1.29,1.10,4.17,2.57,1.05,3.40,8.72,229.6 +5,86,1130,1640,1.56,0.57,4.33,3.02,1.03,3.51,10.52,249.9 +5,86,1380,2461,1.44,-0.08,4.58,2.88,1.42,3.79,10.61,273.3 +5,86,1630,3281,1.36,-0.27,4.74,2.77,1.04,4.41,10.31,281.3 +5,86,1880,4101,1.28,-0.28,4.65,2.74,1.19,4.21,9.70,282.4 +5,86,2130,4921,1.13,-0.31,4.65,2.72,1.30,4.00,9.30,285.5 +5,86,2380,5741,1.12,-0.38,4.87,2.88,1.37,4.07,10.34,288.6 +5,86,2630,6562,1.08,-0.56,5.34,3.18,1.32,4.92,11.62,297.1 +5,86,2880,7382,1.09,-0.80,5.98,3.46,1.91,5.38,13.00,306.0 +5,86,3130,8202,1.17,-0.93,6.49,3.64,2.12,6.13,14.15,308.3 +5,86,3380,9022,1.63,-1.20,6.82,3.90,1.53,6.32,14.55,306.3 +5,86,3630,9843,2.28,-1.35,7.27,4.20,1.35,6.44,15.85,300.7 +5,86,3880,10663,2.85,-1.60,7.85,4.69,1.82,7.08,17.15,299.3 +5,86,4130,11483,3.41,-1.85,8.48,5.10,1.94,8.02,18.19,298.5 +5,86,4380,12303,3.97,-2.16,9.05,5.56,1.40,8.59,18.11,298.5 +5,86,4630,13123,4.47,-2.46,9.83,5.74,2.34,9.35,19.18,298.8 +5,86,4880,13944,4.86,-2.81,10.60,5.95,2.50,9.82,20.32,300.0 +5,86,5130,14764,5.23,-3.03,11.32,6.37,2.73,10.69,21.65,300.1 +5,86,5380,15584,5.58,-3.24,12.02,6.67,3.01,11.88,22.71,300.1 +5,86,5630,16404,5.90,-3.48,12.72,6.90,3.61,12.10,23.15,300.6 +5,86,5880,17224,6.26,-3.69,13.34,7.13,3.48,13.11,24.56,300.5 +5,86,6130,18045,6.70,-3.83,13.92,7.32,3.53,13.39,25.51,299.8 +5,86,6380,18865,7.27,-3.90,14.63,7.59,4.08,14.01,26.47,298.2 +5,86,6630,19685,7.77,-4.00,15.31,7.82,4.69,14.48,27.70,297.2 +5,86,6880,20505,8.21,-4.19,16.09,8.11,4.97,14.98,29.15,297.0 +5,86,7130,21325,8.63,-4.34,16.86,8.47,5.11,15.38,31.40,296.7 +5,86,7380,22146,8.97,-4.44,17.55,8.64,4.84,15.65,32.10,296.3 +5,86,7630,22966,9.31,-4.54,18.17,8.56,5.47,16.27,32.65,296.0 +5,86,7880,23786,9.72,-4.71,18.83,8.50,6.13,17.22,33.60,295.9 +5,86,8130,24606,10.22,-4.90,19.46,8.54,6.55,18.15,34.26,295.6 +5,86,8380,25427,10.70,-4.98,19.97,8.56,7.36,19.14,35.31,295.0 +6,77,630,0,1.18,1.67,4.02,4.29,0.85,3.13,9.87,215.1 +6,77,880,820,1.85,0.79,3.71,2.70,0.86,2.91,9.30,246.9 +6,77,1130,1640,2.01,0.34,3.89,3.20,0.61,2.92,9.72,260.5 +6,77,1380,2461,1.98,-0.04,4.33,3.29,0.79,3.09,11.23,271.0 +6,77,1630,3281,1.93,-0.00,4.49,3.24,0.90,3.44,11.39,270.1 +6,77,1880,4101,1.92,0.32,4.46,3.20,0.51,3.28,11.53,260.5 +6,77,2130,4921,1.97,0.61,4.62,3.24,0.69,3.88,11.81,252.7 +6,77,2380,5741,2.19,0.84,4.97,3.40,1.05,4.21,12.08,248.9 +6,77,2630,6562,2.41,1.09,5.43,3.62,1.30,4.66,12.89,245.7 +6,77,2880,7382,2.56,1.33,5.88,3.81,1.68,4.62,13.49,242.5 +6,77,3130,8202,2.71,1.55,6.25,3.99,1.53,4.87,13.70,240.2 +6,77,3380,9022,3.08,1.61,6.28,4.15,1.32,5.07,14.01,242.5 +6,77,3630,9843,3.46,1.74,6.37,4.24,1.52,4.87,14.15,243.3 +6,77,3880,10663,3.77,1.91,6.53,4.33,1.67,5.52,14.41,243.1 +6,77,4130,11483,4.09,1.95,6.76,4.30,1.76,5.82,14.72,244.5 +6,77,4380,12303,4.43,1.93,7.06,4.24,2.03,5.86,15.23,246.5 +6,77,4630,13123,4.82,1.95,7.49,4.33,2.03,6.44,15.28,248.0 +6,77,4880,13944,5.18,1.94,7.96,4.47,1.90,6.60,15.83,249.4 +6,77,5130,14764,5.56,1.94,8.45,4.63,1.98,6.95,16.56,250.7 +6,77,5380,15584,5.97,1.91,9.01,4.79,2.53,7.55,17.42,252.3 +6,77,5630,16404,6.36,2.01,9.58,4.90,3.12,8.25,18.43,252.5 +6,77,5880,17224,6.71,2.02,10.12,5.04,3.50,9.12,19.40,253.2 +6,77,6130,18045,7.14,2.00,10.56,5.14,4.08,8.94,20.33,254.3 +6,77,6380,18865,7.54,2.06,10.97,5.30,4.69,9.40,21.11,254.7 +6,77,6630,19685,7.94,2.11,11.39,5.53,4.53,10.32,22.20,255.1 +6,77,6880,20505,8.28,2.22,11.80,5.82,4.41,10.60,23.23,255.0 +6,77,7130,21325,8.60,2.30,12.24,6.16,4.17,11.29,24.26,255.0 +6,77,7380,22146,8.94,2.30,12.73,6.54,3.42,11.70,25.28,255.6 +6,77,7630,22966,9.29,2.31,13.16,6.87,3.01,12.34,27.10,256.0 +6,77,7880,23786,9.53,2.41,13.41,7.17,2.98,12.66,27.54,255.8 +6,77,8130,24606,9.82,2.50,13.74,7.48,3.02,12.46,27.98,255.7 +6,77,8380,25427,10.20,2.56,14.18,7.75,3.36,13.10,28.43,255.9 +7,83,630,0,0.66,2.14,3.74,5.80,0.52,2.49,8.32,197.1 +7,83,880,820,1.85,1.89,3.94,2.52,0.62,3.35,8.67,224.4 +7,83,1130,1640,2.60,1.64,4.41,3.06,0.61,3.55,10.10,237.9 +7,83,1380,2461,2.52,1.38,4.29,2.66,0.82,3.74,8.85,241.3 +7,83,1630,3281,2.65,1.32,4.47,2.48,1.21,4.10,8.64,243.5 +7,83,1880,4101,2.69,1.54,4.55,2.44,1.18,3.96,8.99,240.3 +7,83,2130,4921,2.55,1.85,4.57,2.44,1.04,4.38,8.51,234.1 +7,83,2380,5741,2.20,2.13,4.62,2.37,1.37,4.40,8.79,225.9 +7,83,2630,6562,1.87,2.49,4.91,2.38,1.83,4.85,9.25,216.9 +7,83,2880,7382,1.53,2.91,5.28,2.51,1.83,5.04,9.68,207.8 +7,83,3130,8202,1.31,3.21,5.71,2.75,2.09,5.32,10.37,202.3 +7,83,3380,9022,1.22,3.30,5.79,2.76,2.07,5.28,11.07,200.4 +7,83,3630,9843,1.22,3.40,5.87,2.68,2.01,5.65,11.06,199.8 +7,83,3880,10663,1.17,3.54,6.00,2.65,2.01,5.88,10.84,198.3 +7,83,4130,11483,1.13,3.65,6.14,2.70,1.93,6.04,10.85,197.2 +7,83,4380,12303,1.24,3.81,6.32,2.81,1.83,6.04,10.90,198.0 +7,83,4630,13123,1.29,3.90,6.49,2.96,1.83,6.08,11.90,198.3 +7,83,4880,13944,1.34,3.82,6.60,3.15,2.49,6.07,12.75,199.3 +7,83,5130,14764,1.35,3.86,6.84,3.45,2.61,6.22,13.20,199.3 +7,83,5380,15584,1.37,3.93,7.10,3.74,2.00,6.43,13.58,199.3 +7,83,5630,16404,1.42,4.03,7.34,4.07,1.50,6.79,14.30,199.4 +7,83,5880,17224,1.51,4.15,7.61,4.30,1.52,7.15,15.26,200.0 +7,83,6130,18045,1.85,4.21,7.83,4.22,1.75,7.32,15.23,203.8 +7,83,6380,18865,2.23,4.30,8.09,4.08,1.98,7.99,14.64,207.5 +7,83,6630,19685,2.41,4.29,8.30,4.02,1.81,8.41,14.61,209.3 +7,83,6880,20505,2.56,4.26,8.54,4.06,2.14,8.53,14.74,211.0 +7,83,7130,21325,2.81,4.22,8.84,4.12,2.69,8.93,15.15,213.7 +7,83,7380,22146,3.07,4.35,9.16,4.29,3.09,9.25,16.21,215.2 +7,83,7630,22966,3.46,4.52,9.55,4.55,3.06,9.73,18.19,217.4 +7,83,7880,23786,3.89,4.84,9.87,4.57,2.83,10.27,17.82,218.8 +7,83,8130,24606,4.25,5.13,10.11,4.58,2.94,10.01,18.27,219.6 +7,83,8380,25427,4.65,5.46,10.43,4.60,3.45,9.85,19.33,220.4 +8,110,630,0,1.22,1.42,3.29,2.50,0.58,2.60,7.75,220.6 +8,110,880,820,1.66,1.49,3.85,2.48,1.00,3.29,8.99,228.1 +8,110,1130,1640,2.36,1.24,4.20,2.70,0.86,3.23,9.13,242.4 +8,110,1380,2461,2.79,1.08,4.65,2.69,0.98,4.10,9.85,248.9 +8,110,1630,3281,2.97,1.18,5.00,2.79,0.68,4.50,9.94,248.3 +8,110,1880,4101,2.85,1.56,5.12,2.68,1.46,4.62,10.01,241.3 +8,110,2130,4921,2.78,1.91,5.25,2.77,1.47,4.77,10.52,235.5 +8,110,2380,5741,2.64,2.21,5.37,2.89,1.19,4.91,9.88,230.1 +8,110,2630,6562,2.50,2.38,5.52,3.02,1.25,5.20,11.20,226.4 +8,110,2880,7382,2.32,2.70,5.77,3.23,1.17,5.31,11.71,220.7 +8,110,3130,8202,2.16,2.99,6.14,3.46,1.51,5.52,11.75,215.8 +8,110,3380,9022,2.17,3.20,6.17,3.58,1.14,5.50,11.81,214.1 +8,110,3630,9843,2.18,3.36,6.18,3.59,1.31,5.41,11.95,213.0 +8,110,3880,10663,2.14,3.48,6.23,3.63,1.57,5.41,12.20,211.5 +8,110,4130,11483,2.13,3.56,6.30,3.68,1.51,5.43,12.87,210.9 +8,110,4380,12303,2.16,3.63,6.40,3.75,1.61,5.65,13.43,210.7 +8,110,4630,13123,2.17,3.66,6.55,3.79,1.72,5.80,13.51,210.7 +8,110,4880,13944,2.20,3.68,6.76,3.85,1.60,5.85,13.86,210.9 +8,110,5130,14764,2.26,3.71,6.99,3.98,1.95,6.26,14.25,211.4 +8,110,5380,15584,2.37,3.64,7.15,4.17,1.51,6.71,15.04,213.1 +8,110,5630,16404,2.49,3.58,7.35,4.28,1.47,6.69,15.51,214.8 +8,110,5880,17224,2.67,3.59,7.68,4.35,1.54,6.70,15.14,216.6 +8,110,6130,18045,3.03,3.56,7.80,4.54,1.28,6.96,15.23,220.4 +8,110,6380,18865,3.41,3.54,7.90,4.80,1.01,7.15,16.06,223.9 +8,110,6630,19685,3.86,3.59,8.13,5.11,1.04,7.47,17.02,227.1 +8,110,6880,20505,4.35,3.60,8.50,5.35,1.49,7.76,18.36,230.4 +8,110,7130,21325,4.82,3.68,8.97,5.58,1.67,8.10,19.40,232.7 +8,110,7380,22146,5.21,3.73,9.53,5.73,1.60,8.39,20.10,234.4 +8,110,7630,22966,5.57,3.83,10.03,5.84,1.56,8.86,20.50,235.5 +8,110,7880,23786,6.00,4.01,10.42,5.89,2.23,10.10,20.87,236.3 +8,110,8130,24606,6.45,4.13,10.86,5.98,2.06,10.73,21.40,237.4 +8,110,8380,25427,6.96,4.34,11.39,6.11,2.61,10.98,22.17,238.1 +9,127,630,0,1.25,1.15,3.93,3.63,0.69,2.70,10.53,227.5 +9,127,880,820,1.67,0.67,3.79,2.93,0.68,3.02,9.30,247.9 +9,127,1130,1640,1.90,0.49,4.67,3.32,0.79,3.97,11.13,255.5 +9,127,1380,2461,1.56,0.33,5.36,3.38,1.06,4.69,12.05,257.9 +9,127,1630,3281,1.42,0.42,5.72,3.47,1.30,4.89,12.18,253.7 +9,127,1880,4101,1.47,0.69,5.87,3.42,1.51,5.17,12.19,244.8 +9,127,2130,4921,1.60,0.97,6.13,3.47,1.42,5.84,12.53,238.9 +9,127,2380,5741,1.80,1.22,6.54,3.59,1.70,6.24,12.92,235.8 +9,127,2630,6562,2.01,1.45,6.94,3.85,1.63,6.31,14.75,234.2 +9,127,2880,7382,2.25,1.69,7.31,4.13,1.37,6.67,15.72,233.1 +9,127,3130,8202,2.45,1.93,7.74,4.35,1.51,6.74,16.46,231.8 +9,127,3380,9022,2.80,2.00,7.98,4.56,1.98,7.22,17.29,234.4 +9,127,3630,9843,3.15,1.93,8.14,4.85,2.09,7.58,18.14,238.4 +9,127,3880,10663,3.51,1.83,8.32,5.11,2.02,7.47,19.05,242.5 +9,127,4130,11483,3.87,1.68,8.55,5.37,1.65,7.49,19.44,246.5 +9,127,4380,12303,4.40,1.58,8.87,5.64,1.80,7.75,20.16,250.2 +9,127,4630,13123,4.98,1.45,9.29,5.88,1.62,8.06,20.84,253.8 +9,127,4880,13944,5.39,1.34,9.78,6.10,2.04,8.57,21.55,256.0 +9,127,5130,14764,5.73,1.23,10.28,6.32,2.33,9.08,21.88,257.9 +9,127,5380,15584,6.12,1.16,10.77,6.65,2.57,9.61,21.93,259.3 +9,127,5630,16404,6.55,1.07,11.25,6.94,2.78,9.84,22.83,260.7 +9,127,5880,17224,6.94,0.97,11.72,7.22,2.90,10.40,23.71,262.0 +9,127,6130,18045,7.28,0.93,12.14,7.52,2.63,11.07,24.36,262.7 +9,127,6380,18865,7.64,0.88,12.58,7.84,2.71,11.31,27.07,263.5 +9,127,6630,19685,8.08,0.82,13.12,8.22,2.34,11.95,29.56,264.2 +9,127,6880,20505,8.51,0.78,13.76,8.61,2.12,12.47,30.05,264.7 +9,127,7130,21325,8.95,0.67,14.45,9.03,2.24,13.51,31.22,265.7 +9,127,7380,22146,9.30,0.54,15.12,9.41,2.47,13.64,33.32,266.7 +9,127,7630,22966,9.64,0.44,15.69,9.62,3.46,14.22,35.87,267.4 +9,127,7880,23786,10.11,0.41,16.21,9.85,3.52,14.95,38.42,267.7 +9,127,8130,24606,10.66,0.44,16.79,10.01,3.54,15.33,39.58,267.6 +9,127,8380,25427,11.20,0.46,17.36,10.20,3.77,15.11,40.22,267.6 +10,104,630,0,0.78,-0.05,2.78,2.41,0.52,1.81,8.15,273.8 +10,104,880,820,0.21,-0.20,3.38,2.72,0.50,2.43,8.69,314.7 +10,104,1130,1640,-0.12,-0.34,4.08,2.89,0.69,3.21,9.50,20.4 +10,104,1380,2461,-0.28,-0.54,4.66,3.02,1.06,3.66,10.03,27.1 +10,104,1630,3281,-0.25,-0.82,5.05,3.09,1.38,4.44,10.45,17.1 +10,104,1880,4101,0.06,-0.98,5.18,3.20,1.29,4.29,10.27,356.7 +10,104,2130,4921,0.34,-1.04,5.42,3.46,1.00,4.59,11.28,341.8 +10,104,2380,5741,0.67,-1.09,5.85,3.74,1.27,4.81,12.10,328.6 +10,104,2630,6562,1.06,-1.24,6.38,4.15,1.79,5.26,12.57,319.3 +10,104,2880,7382,1.59,-1.36,7.03,4.37,2.10,5.73,13.77,310.6 +10,104,3130,8202,2.15,-1.68,7.80,4.55,2.45,6.89,15.69,308.1 +10,104,3380,9022,2.69,-1.92,8.27,4.79,2.62,7.04,18.50,305.6 +10,104,3630,9843,3.19,-2.08,8.78,5.15,2.69,7.30,20.50,303.1 +10,104,3880,10663,3.78,-2.14,9.24,5.42,2.99,7.88,20.07,299.5 +10,104,4130,11483,4.49,-2.23,9.75,5.73,2.89,8.65,20.36,296.4 +10,104,4380,12303,5.06,-2.37,10.29,5.98,3.09,9.53,22.01,295.1 +10,104,4630,13123,5.57,-2.44,10.82,6.20,3.09,10.10,22.78,293.6 +10,104,4880,13944,6.07,-2.56,11.35,6.37,3.56,10.83,22.59,292.8 +10,104,5130,14764,6.59,-2.69,11.97,6.65,3.62,11.34,23.49,292.2 +10,104,5380,15584,7.08,-2.80,12.53,6.95,3.35,11.89,23.97,291.6 +10,104,5630,16404,7.49,-2.83,12.93,7.23,3.35,12.68,23.99,290.7 +10,104,5880,17224,7.76,-2.95,13.41,7.36,3.28,13.39,24.80,290.8 +10,104,6130,18045,7.97,-3.02,13.92,7.44,4.09,13.80,27.40,290.8 +10,104,6380,18865,8.23,-2.96,14.34,7.73,4.15,13.98,28.60,289.8 +10,104,6630,19685,8.42,-2.89,14.71,8.06,4.22,14.36,29.11,288.9 +10,104,6880,20505,8.65,-2.94,15.09,8.30,3.25,15.11,29.70,288.8 +10,104,7130,21325,8.97,-3.03,15.56,8.57,2.70,15.54,30.14,288.7 +10,104,7380,22146,9.14,-2.99,15.99,8.77,2.83,16.77,30.30,288.1 +10,104,7630,22966,9.40,-2.87,16.42,9.01,3.10,16.77,31.25,287.0 +10,104,7880,23786,9.79,-2.79,16.84,9.24,2.77,17.34,32.38,285.9 +10,104,8130,24606,10.21,-2.76,17.43,9.49,2.84,18.26,34.26,285.1 +10,104,8380,25427,10.61,-2.62,18.03,9.82,2.76,18.53,34.37,283.9 +11,100,630,0,0.26,0.35,2.21,1.69,0.50,1.73,5.92,216.1 +11,100,880,820,0.46,0.05,2.73,2.43,0.45,2.05,8.17,263.2 +11,100,1130,1640,0.74,-0.11,4.16,3.38,0.61,3.40,9.89,278.6 +11,100,1380,2461,0.64,-0.25,5.50,3.50,0.97,5.14,12.39,291.5 +11,100,1630,3281,0.69,-0.42,6.11,3.62,1.04,5.86,12.04,301.4 +11,100,1880,4101,1.33,-0.47,6.15,3.73,1.11,5.60,11.35,289.5 +11,100,2130,4921,2.18,-0.51,6.54,3.86,1.34,5.58,12.27,283.2 +11,100,2380,5741,3.06,-0.58,7.18,4.13,2.20,6.01,14.41,280.8 +11,100,2630,6562,3.95,-0.76,8.02,4.43,2.65,6.95,15.26,280.8 +11,100,2880,7382,4.87,-0.83,8.85,4.85,2.40,8.28,16.42,279.7 +11,100,3130,8202,5.57,-0.93,9.64,5.27,2.36,8.70,18.64,279.5 +11,100,3380,9022,6.20,-0.92,10.06,5.43,2.80,8.97,18.82,278.4 +11,100,3630,9843,6.82,-0.95,10.49,5.64,3.16,9.05,19.50,277.9 +11,100,3880,10663,7.33,-1.04,10.92,5.92,3.37,9.55,20.23,278.1 +11,100,4130,11483,7.90,-1.22,11.46,6.21,3.40,10.07,21.60,278.8 +11,100,4380,12303,8.56,-1.43,12.10,6.60,2.59,10.81,22.23,279.5 +11,100,4630,13123,9.13,-1.60,12.75,6.90,3.11,11.48,23.58,279.9 +11,100,4880,13944,9.54,-1.65,13.27,7.03,3.22,12.05,24.96,279.8 +11,100,5130,14764,10.01,-1.82,13.86,7.26,3.40,12.67,25.59,280.3 +11,100,5380,15584,10.53,-1.93,14.49,7.57,3.26,13.28,26.73,280.4 +11,100,5630,16404,11.17,-1.94,15.19,7.79,3.15,14.01,28.37,279.9 +11,100,5880,17224,11.86,-2.00,15.84,7.84,3.21,14.78,29.78,279.6 +11,100,6130,18045,12.63,-1.98,16.54,7.96,3.80,15.18,31.11,278.9 +11,100,6380,18865,13.47,-2.04,17.38,7.99,4.75,15.81,32.47,278.6 +11,100,6630,19685,14.18,-2.18,18.11,8.15,5.57,16.73,33.82,278.7 +11,100,6880,20505,14.73,-2.26,18.69,8.41,6.68,17.17,35.31,278.7 +11,100,7130,21325,15.30,-2.33,19.31,8.71,7.44,17.23,36.36,278.7 +11,100,7380,22146,15.86,-2.38,19.92,9.16,7.57,17.73,37.61,278.5 +11,100,7630,22966,16.34,-2.54,20.53,9.54,7.58,18.25,37.54,278.8 +11,100,7880,23786,16.88,-2.75,21.20,9.83,8.37,18.53,39.46,279.3 +11,100,8130,24606,17.48,-2.94,21.95,10.00,7.87,19.85,40.50,279.6 +11,100,8380,25427,18.04,-3.00,22.69,10.18,8.76,21.37,43.12,279.5 +12,86,630,0,0.73,0.58,2.70,2.26,0.53,1.79,7.85,231.7 +12,86,880,820,0.87,0.02,3.41,2.79,0.52,2.51,9.21,268.9 +12,86,1130,1640,0.81,-0.59,4.73,3.37,0.86,3.87,11.11,306.3 +12,86,1380,2461,0.72,-1.02,6.07,3.45,1.51,5.25,11.70,324.6 +12,86,1630,3281,0.89,-1.50,6.99,3.80,1.11,6.33,13.70,329.5 +12,86,1880,4101,1.26,-1.89,7.52,3.93,1.82,7.38,14.27,326.3 +12,86,2130,4921,1.95,-2.15,8.12,4.03,2.74,7.57,15.17,317.7 +12,86,2380,5741,2.86,-2.20,8.93,4.15,3.79,8.37,15.76,307.6 +12,86,2630,6562,3.73,-2.39,10.01,4.35,3.64,9.71,17.37,302.6 +12,86,2880,7382,4.59,-2.67,11.07,4.61,3.80,10.43,18.23,300.2 +12,86,3130,8202,5.37,-2.84,11.82,4.90,3.81,11.60,19.53,297.9 +12,86,3380,9022,5.96,-2.95,12.19,4.93,4.26,12.01,20.51,296.3 +12,86,3630,9843,6.58,-3.19,12.76,5.01,4.75,12.74,21.54,295.9 +12,86,3880,10663,7.17,-3.36,13.37,5.18,5.39,13.29,21.91,295.1 +12,86,4130,11483,7.89,-3.44,13.96,5.35,5.54,14.00,21.82,293.6 +12,86,4380,12303,8.59,-3.53,14.56,5.58,5.12,14.39,23.55,292.4 +12,86,4630,13123,9.26,-3.65,15.17,6.04,4.95,15.76,24.89,291.5 +12,86,4880,13944,9.91,-3.80,15.86,6.35,4.43,16.29,26.58,291.0 +12,86,5130,14764,10.50,-3.79,16.63,6.79,4.28,17.30,28.58,289.8 +12,86,5380,15584,11.06,-3.83,17.35,7.09,4.04,18.24,29.20,289.1 +12,86,5630,16404,11.53,-3.93,17.93,7.37,3.81,18.45,30.10,288.8 +12,86,5880,17224,12.02,-4.08,18.46,7.49,4.14,19.36,29.96,288.7 +12,86,6130,18045,12.59,-4.21,19.01,7.67,4.41,20.03,30.37,288.5 +12,86,6380,18865,13.23,-4.35,19.65,7.98,3.40,20.88,32.14,288.2 +12,86,6630,19685,13.72,-4.55,20.30,8.26,3.45,21.62,33.27,288.3 +12,86,6880,20505,14.13,-4.86,21.03,8.47,4.38,22.06,33.65,289.0 +12,86,7130,21325,14.57,-5.21,21.81,8.80,4.17,23.19,34.13,289.7 +12,86,7380,22146,15.06,-5.47,22.57,9.10,4.35,23.83,34.36,290.0 +12,86,7630,22966,15.61,-5.68,23.30,9.26,4.83,23.92,35.62,290.0 +12,86,7880,23786,16.04,-5.88,23.96,9.37,5.26,24.67,35.59,290.1 +12,86,8130,24606,16.52,-6.02,24.63,9.61,5.94,24.73,36.38,290.0 +12,86,8380,25427,17.01,-6.12,25.39,9.87,7.37,25.24,37.31,289.8 diff --git a/recovery-calculator/site-climatology/data/nid-wprofile-monthly.csv b/recovery-calculator/site-climatology/data/nid-wprofile-monthly.csv new file mode 100644 index 000000000..6b21c8d86 --- /dev/null +++ b/recovery-calculator/site-climatology/data/nid-wprofile-monthly.csv @@ -0,0 +1,385 @@ +month,n_soundings,H_msl_m,H_agl_ft,u_mean_ms,v_mean_ms,spd_mean_ms,spd_sd_ms,spd_p05_ms,spd_p50_ms,spd_p95_ms,dir_mean_deg +1,24,630,0,0.47,0.41,2.02,1.81,0.21,1.48,6.04,228.6 +1,24,880,820,0.12,-0.25,2.51,2.49,0.25,1.49,6.30,333.4 +1,24,1130,1640,0.17,-0.83,2.76,2.69,0.64,1.24,6.94,348.6 +1,24,1380,2461,0.15,-1.27,3.55,2.71,0.83,2.64,8.89,353.4 +1,24,1630,3281,0.18,-1.53,4.30,2.93,1.06,3.83,8.68,353.4 +1,24,1880,4101,0.50,-1.62,4.82,3.05,1.19,4.38,9.63,342.7 +1,24,2130,4921,0.84,-1.73,5.53,3.36,1.79,4.58,11.06,334.1 +1,24,2380,5741,1.17,-1.83,6.31,3.89,2.12,5.35,13.36,327.4 +1,24,2630,6562,1.51,-1.94,7.15,4.56,2.35,5.62,15.73,322.1 +1,24,2880,7382,1.84,-2.04,8.04,5.32,2.55,6.18,18.23,317.9 +1,24,3130,8202,2.15,-2.13,8.88,5.95,2.75,6.94,20.66,314.7 +1,24,3380,9022,2.71,-2.10,9.07,6.18,3.19,7.24,21.41,307.7 +1,24,3630,9843,3.28,-2.06,9.28,6.45,3.38,7.16,22.18,302.1 +1,24,3880,10663,3.85,-2.02,9.55,6.74,3.26,7.23,22.98,297.7 +1,24,4130,11483,4.42,-1.99,9.90,7.03,3.69,7.16,23.80,294.2 +1,24,4380,12303,4.99,-1.95,10.33,7.31,3.88,7.46,24.66,291.4 +1,24,4630,13123,5.56,-1.92,10.82,7.58,4.12,8.00,25.53,289.0 +1,24,4880,13944,6.12,-1.88,11.37,7.85,4.46,8.43,26.43,287.1 +1,24,5130,14764,6.69,-1.84,11.95,8.13,4.87,8.94,27.35,285.4 +1,24,5380,15584,7.26,-1.81,12.56,8.42,5.03,9.83,28.28,284.0 +1,24,5630,16404,7.83,-1.76,13.20,8.72,5.20,10.78,29.24,282.7 +1,24,5880,17224,8.20,-1.73,13.63,8.96,4.70,11.52,30.54,281.9 +1,24,6130,18045,8.41,-1.75,13.93,9.22,3.71,11.91,32.09,281.7 +1,24,6380,18865,8.63,-1.77,14.30,9.46,3.46,11.97,33.65,281.6 +1,24,6630,19685,8.84,-1.79,14.70,9.70,3.31,11.92,35.21,281.4 +1,24,6880,20505,9.06,-1.81,15.15,9.95,3.21,11.87,36.77,281.3 +1,24,7130,21325,9.38,-1.84,15.74,10.15,3.29,12.08,38.33,281.1 +1,24,7380,22146,9.81,-1.69,16.55,10.34,3.69,13.00,39.88,279.8 +1,24,7630,22966,10.45,-1.48,17.09,10.51,3.58,13.83,40.44,278.1 +1,24,7880,23786,11.03,-1.27,17.72,10.70,3.82,15.07,40.97,276.6 +1,24,8130,24606,11.62,-1.06,18.40,11.00,4.35,16.34,41.50,275.2 +1,24,8380,25427,12.20,-0.85,19.12,11.41,5.06,17.50,42.04,274.0 +2,34,630,0,0.01,0.31,2.55,2.26,0.50,2.15,5.73,182.6 +2,34,880,820,0.58,0.09,4.55,3.94,0.61,3.39,12.38,261.5 +2,34,1130,1640,0.96,-1.14,5.07,4.03,1.05,3.33,13.35,320.0 +2,34,1380,2461,1.35,-2.37,6.33,4.64,0.98,5.23,14.95,330.4 +2,34,1630,3281,1.69,-3.44,7.38,5.36,0.63,5.98,16.18,333.8 +2,34,1880,4101,1.88,-3.94,7.83,5.33,0.89,6.69,15.85,334.5 +2,34,2130,4921,2.07,-4.44,8.58,5.30,1.72,8.43,17.27,335.0 +2,34,2380,5741,2.25,-4.94,9.45,5.48,2.28,9.41,19.54,335.5 +2,34,2630,6562,2.44,-5.44,10.41,5.85,2.94,9.60,22.24,335.9 +2,34,2880,7382,2.63,-5.94,11.43,6.39,3.27,10.37,25.05,336.2 +2,34,3130,8202,3.00,-6.45,12.44,6.74,3.55,11.07,26.87,335.1 +2,34,3380,9022,3.75,-6.82,13.12,6.68,3.28,12.88,26.37,331.2 +2,34,3630,9843,4.52,-7.20,13.86,6.84,3.08,14.62,25.86,327.9 +2,34,3880,10663,5.29,-7.58,14.65,7.24,2.96,14.54,25.30,325.1 +2,34,4130,11483,6.06,-7.95,15.49,7.83,2.91,15.07,26.71,322.7 +2,34,4380,12303,6.84,-8.33,16.36,8.59,2.95,15.65,30.49,320.6 +2,34,4630,13123,7.61,-8.71,17.26,9.47,3.07,15.96,34.59,318.8 +2,34,4880,13944,8.38,-9.08,18.20,10.44,3.32,16.27,37.32,317.3 +2,34,5130,14764,9.15,-9.46,19.16,11.47,3.62,16.58,40.08,315.9 +2,34,5380,15584,9.93,-9.84,20.15,12.55,3.95,16.93,43.90,314.7 +2,34,5630,16404,10.70,-10.16,21.14,13.58,4.32,17.91,47.72,313.5 +2,34,5880,17224,11.14,-10.35,21.77,13.86,4.08,18.65,49.85,312.9 +2,34,6130,18045,11.49,-10.59,22.42,14.20,3.63,19.62,52.01,312.7 +2,34,6380,18865,11.84,-10.82,23.09,14.58,3.23,20.12,54.21,312.4 +2,34,6630,19685,12.18,-11.05,23.83,14.96,2.91,21.00,55.81,312.2 +2,34,6880,20505,12.53,-11.28,24.61,15.35,2.69,21.49,56.79,312.0 +2,34,7130,21325,12.85,-11.50,25.39,15.75,2.59,22.15,57.60,311.8 +2,34,7380,22146,13.11,-11.76,26.08,16.02,2.99,23.07,58.37,311.9 +2,34,7630,22966,13.55,-12.04,26.71,16.20,3.19,24.08,58.78,311.6 +2,34,7880,23786,14.04,-12.32,27.37,16.38,3.39,25.71,59.10,311.3 +2,34,8130,24606,14.53,-12.54,28.01,16.56,3.60,26.02,59.45,310.8 +2,34,8380,25427,15.03,-12.75,28.68,16.75,3.95,26.18,59.85,310.3 +3,44,630,0,0.10,0.75,1.65,1.52,0.21,1.33,3.80,187.8 +3,44,880,820,0.97,0.99,3.86,3.01,0.92,2.60,10.53,224.5 +3,44,1130,1640,1.30,0.58,4.00,3.19,0.60,2.80,10.41,246.0 +3,44,1380,2461,1.63,0.17,4.49,3.44,0.95,2.83,11.12,263.9 +3,44,1630,3281,2.05,-0.08,5.08,3.72,0.68,3.80,11.54,272.2 +3,44,1880,4101,2.63,-0.09,5.72,3.90,1.14,4.59,11.45,272.1 +3,44,2130,4921,3.21,-0.11,6.51,4.12,1.58,5.42,13.14,272.0 +3,44,2380,5741,3.79,-0.12,7.37,4.43,1.95,6.57,15.30,271.9 +3,44,2630,6562,4.38,-0.14,8.29,4.81,2.36,7.41,17.80,271.8 +3,44,2880,7382,4.96,-0.15,9.24,5.25,2.64,8.29,19.54,271.8 +3,44,3130,8202,5.55,-0.14,10.17,5.62,3.01,9.19,20.38,271.4 +3,44,3380,9022,6.32,-0.07,10.79,5.83,3.13,10.29,21.29,270.7 +3,44,3630,9843,7.12,-0.02,11.46,6.09,3.96,10.98,22.93,270.1 +3,44,3880,10663,7.92,0.04,12.19,6.38,4.01,12.04,24.03,269.7 +3,44,4130,11483,8.71,0.09,12.97,6.73,4.04,12.40,25.21,269.4 +3,44,4380,12303,9.51,0.15,13.78,7.11,4.05,13.19,26.44,269.1 +3,44,4630,13123,10.31,0.21,14.62,7.52,3.91,13.68,27.70,268.8 +3,44,4880,13944,11.11,0.26,15.49,7.98,3.77,14.65,29.04,268.6 +3,44,5130,14764,11.91,0.32,16.37,8.46,3.88,15.26,30.56,268.5 +3,44,5380,15584,12.71,0.38,17.26,8.98,4.67,15.91,31.75,268.3 +3,44,5630,16404,13.53,0.43,18.23,9.51,5.47,17.20,32.96,268.2 +3,44,5880,17224,14.28,0.41,19.13,9.73,5.24,18.06,33.99,268.3 +3,44,6130,18045,14.90,0.41,19.84,9.98,5.00,18.79,35.00,268.4 +3,44,6380,18865,15.51,0.41,20.57,10.29,4.66,20.13,36.52,268.5 +3,44,6630,19685,16.14,0.38,21.35,10.64,4.42,20.32,38.65,268.6 +3,44,6880,20505,16.76,0.36,22.17,11.04,4.08,21.67,39.59,268.8 +3,44,7130,21325,17.38,0.32,22.99,11.45,3.73,22.70,40.21,268.9 +3,44,7380,22146,18.00,0.29,23.73,11.80,3.68,22.86,41.42,269.1 +3,44,7630,22966,18.57,0.34,24.38,12.08,4.04,23.36,41.10,268.9 +3,44,7880,23786,19.15,0.34,25.05,12.38,4.06,23.88,41.00,269.0 +3,44,8130,24606,19.74,0.34,25.75,12.69,3.98,24.19,42.55,269.0 +3,44,8380,25427,20.32,0.34,26.47,13.03,3.83,24.51,44.44,269.0 +4,33,630,0,0.21,0.28,1.28,0.66,0.32,1.39,2.10,217.1 +4,33,880,820,0.10,0.42,3.30,2.79,1.09,2.50,9.99,193.0 +4,33,1130,1640,0.32,-0.14,3.32,2.92,0.86,2.30,9.81,293.4 +4,33,1380,2461,0.54,-0.70,3.95,3.07,1.17,2.97,10.93,322.0 +4,33,1630,3281,0.88,-1.08,4.42,3.21,1.03,3.36,11.57,320.7 +4,33,1880,4101,1.32,-1.32,4.68,3.21,1.36,3.64,11.33,315.0 +4,33,2130,4921,1.75,-1.56,5.10,3.35,1.71,3.64,12.08,311.7 +4,33,2380,5741,2.18,-1.80,5.61,3.68,1.12,4.42,13.89,309.5 +4,33,2630,6562,2.62,-2.04,6.22,4.10,1.06,5.20,14.27,307.9 +4,33,2880,7382,3.05,-2.28,6.90,4.59,1.63,6.31,14.66,306.7 +4,33,3130,8202,3.50,-2.50,7.55,4.95,1.99,7.20,14.90,305.6 +4,33,3380,9022,4.15,-2.71,7.94,4.99,2.03,8.18,14.96,303.2 +4,33,3630,9843,4.80,-2.93,8.41,5.07,1.92,8.71,14.93,301.4 +4,33,3880,10663,5.44,-3.15,8.95,5.24,1.79,9.22,16.23,300.1 +4,33,4130,11483,6.09,-3.37,9.59,5.42,2.12,9.34,18.01,299.0 +4,33,4380,12303,6.74,-3.59,10.28,5.66,2.71,10.30,19.79,298.1 +4,33,4630,13123,7.39,-3.82,11.00,5.97,3.32,10.83,21.58,297.3 +4,33,4880,13944,8.03,-4.04,11.74,6.37,4.05,11.37,22.91,296.7 +4,33,5130,14764,8.68,-4.26,12.49,6.82,4.89,11.90,24.18,296.1 +4,33,5380,15584,9.33,-4.48,13.26,7.33,5.11,12.44,25.44,295.7 +4,33,5630,16404,10.06,-4.78,14.13,7.69,5.51,12.98,26.71,295.4 +4,33,5880,17224,10.75,-5.24,14.98,7.82,5.45,14.49,28.26,296.0 +4,33,6130,18045,11.40,-5.71,15.76,8.09,5.76,15.12,29.89,296.6 +4,33,6380,18865,12.06,-6.17,16.58,8.46,6.19,15.64,31.55,297.1 +4,33,6630,19685,12.71,-6.64,17.42,8.93,6.60,16.19,33.67,297.6 +4,33,6880,20505,13.37,-7.10,18.29,9.46,6.70,16.74,36.46,298.0 +4,33,7130,21325,13.99,-7.52,19.13,9.99,6.85,17.30,39.02,298.3 +4,33,7380,22146,14.60,-7.80,19.81,10.32,7.02,17.82,40.42,298.1 +4,33,7630,22966,15.07,-8.07,20.33,10.47,7.29,18.49,41.75,298.2 +4,33,7880,23786,15.46,-8.35,20.79,10.69,7.02,19.12,43.11,298.4 +4,33,8130,24606,15.86,-8.63,21.29,10.93,6.77,19.26,44.18,298.6 +4,33,8380,25427,16.30,-8.98,21.84,11.20,6.54,19.19,45.06,298.8 +5,33,630,0,-0.13,0.65,1.98,1.64,0.37,1.60,4.67,169.0 +5,33,880,820,-0.76,1.36,3.66,1.96,1.12,3.16,7.52,150.9 +5,33,1130,1640,-0.33,0.48,3.35,2.13,0.96,2.83,7.03,145.5 +5,33,1380,2461,0.10,-0.40,4.01,2.24,1.19,3.83,8.08,346.3 +5,33,1630,3281,0.30,-0.87,4.29,2.33,0.92,4.06,8.05,341.3 +5,33,1880,4101,0.21,-0.88,4.01,2.19,1.11,3.98,7.57,346.7 +5,33,2130,4921,0.12,-0.89,3.87,2.12,1.30,3.68,7.65,352.2 +5,33,2380,5741,0.03,-0.90,3.86,2.17,1.33,3.49,7.81,357.8 +5,33,2630,6562,-0.05,-0.91,4.00,2.31,1.48,3.22,8.03,3.3 +5,33,2880,7382,-0.14,-0.92,4.29,2.47,1.24,3.37,8.31,8.7 +5,33,3130,8202,-0.13,-0.91,4.63,2.55,1.49,3.55,8.84,8.4 +5,33,3380,9022,0.50,-1.24,4.78,2.76,0.82,4.14,9.24,337.9 +5,33,3630,9843,1.19,-1.61,5.19,2.96,0.89,4.50,9.81,323.6 +5,33,3880,10663,1.87,-1.99,5.84,3.12,1.58,5.06,10.39,316.7 +5,33,4130,11483,2.55,-2.36,6.60,3.38,1.72,5.75,11.47,312.7 +5,33,4380,12303,3.23,-2.73,7.47,3.63,2.26,6.59,12.56,310.2 +5,33,4630,13123,3.92,-3.10,8.39,3.96,2.48,7.96,14.45,308.4 +5,33,4880,13944,4.60,-3.47,9.34,4.32,2.75,9.23,16.26,307.1 +5,33,5130,14764,5.28,-3.85,10.33,4.69,3.27,10.43,18.06,306.1 +5,33,5380,15584,5.96,-4.22,11.33,5.10,3.90,11.11,19.88,305.3 +5,33,5630,16404,6.62,-4.60,12.32,5.57,4.24,11.80,21.70,304.8 +5,33,5880,17224,7.11,-4.92,13.10,5.98,3.64,12.49,23.34,304.7 +5,33,6130,18045,7.48,-5.06,13.61,6.20,3.07,13.26,24.29,304.1 +5,33,6380,18865,7.85,-5.19,14.14,6.44,2.94,14.04,25.27,303.5 +5,33,6630,19685,8.22,-5.32,14.70,6.70,3.00,14.81,26.28,302.9 +5,33,6880,20505,8.59,-5.46,15.29,6.97,3.08,15.00,27.31,302.4 +5,33,7130,21325,8.96,-5.59,15.91,7.22,3.19,15.46,28.36,302.0 +5,33,7380,22146,9.48,-5.67,16.66,7.28,4.35,15.82,29.44,300.9 +5,33,7630,22966,9.96,-5.77,17.37,7.18,5.27,16.55,30.38,300.1 +5,33,7880,23786,10.37,-5.85,18.02,7.07,5.56,17.81,31.31,299.4 +5,33,8130,24606,10.79,-5.92,18.69,7.04,6.09,18.20,31.71,298.8 +5,33,8380,25427,11.20,-6.00,19.36,7.08,7.10,19.03,31.81,298.2 +6,23,630,0,-0.66,2.30,3.31,6.20,0.68,1.58,5.24,164.1 +6,23,880,820,0.10,1.53,3.49,2.73,0.85,2.82,9.86,183.7 +6,23,1130,1640,-0.02,0.97,3.01,2.60,0.58,2.37,8.89,179.0 +6,23,1380,2461,-0.13,0.41,3.37,2.58,0.81,2.54,8.64,162.1 +6,23,1630,3281,-0.07,0.16,3.65,2.72,0.86,2.88,8.95,156.7 +6,23,1880,4101,0.16,0.23,3.65,2.75,0.50,2.53,8.62,215.5 +6,23,2130,4921,0.39,0.29,3.92,2.72,0.40,3.32,8.72,233.4 +6,23,2380,5741,0.63,0.36,4.37,2.72,0.47,3.76,8.95,240.2 +6,23,2630,6562,0.86,0.42,4.97,2.67,1.10,5.03,9.44,243.7 +6,23,2880,7382,1.09,0.49,5.63,2.70,1.70,6.45,10.06,245.8 +6,23,3130,8202,1.36,0.60,6.29,2.83,1.82,6.65,10.72,246.4 +6,23,3380,9022,1.96,0.79,6.39,2.96,1.28,6.70,10.52,248.0 +6,23,3630,9843,2.57,0.97,6.57,3.01,1.43,6.88,10.74,249.2 +6,23,3880,10663,3.17,1.15,6.89,3.06,2.01,6.85,11.26,250.0 +6,23,4130,11483,3.78,1.34,7.28,3.24,2.82,7.38,12.20,250.5 +6,23,4380,12303,4.38,1.52,7.71,3.52,2.86,8.00,13.19,250.9 +6,23,4630,13123,4.99,1.70,8.19,3.89,2.40,8.34,14.20,251.2 +6,23,4880,13944,5.59,1.88,8.73,4.26,2.02,8.50,15.21,251.4 +6,23,5130,14764,6.20,2.06,9.37,4.55,1.88,8.67,16.23,251.6 +6,23,5380,15584,6.80,2.24,10.05,4.84,2.52,9.69,17.25,251.8 +6,23,5630,16404,7.41,2.42,10.77,5.13,2.97,10.77,18.27,251.9 +6,23,5880,17224,7.97,2.54,11.42,5.39,3.24,11.29,19.26,252.3 +6,23,6130,18045,8.33,2.59,11.90,5.60,4.14,11.47,20.23,252.7 +6,23,6380,18865,8.66,2.62,12.41,5.85,5.19,11.16,21.20,253.2 +6,23,6630,19685,9.00,2.66,12.95,6.13,6.08,11.27,22.43,253.5 +6,23,6880,20505,9.33,2.70,13.51,6.46,5.31,11.07,23.81,253.9 +6,23,7130,21325,9.67,2.74,14.08,6.83,4.71,11.37,25.20,254.2 +6,23,7380,22146,10.01,2.77,14.68,7.22,5.01,12.40,26.60,254.5 +6,23,7630,22966,10.51,2.92,15.25,7.52,5.17,13.73,27.83,254.5 +6,23,7880,23786,10.95,3.23,15.60,7.90,4.79,13.66,28.84,253.6 +6,23,8130,24606,11.40,3.54,15.98,8.32,4.43,14.89,29.87,252.7 +6,23,8380,25427,11.85,3.86,16.39,8.78,4.10,14.96,30.90,252.0 +7,30,630,0,0.22,0.45,1.99,2.17,0.43,1.53,4.90,205.6 +7,30,880,820,-0.89,2.32,3.53,1.99,1.26,2.84,7.86,158.9 +7,30,1130,1640,-0.26,1.90,3.36,1.89,0.95,3.00,7.66,172.4 +7,30,1380,2461,0.38,1.49,3.65,2.13,1.01,3.38,8.29,194.5 +7,30,1630,3281,0.79,1.32,3.98,2.29,1.17,3.61,8.55,210.8 +7,30,1880,4101,0.84,1.58,3.94,2.20,1.62,3.52,8.30,208.1 +7,30,2130,4921,0.89,1.83,4.02,2.30,1.08,3.66,8.42,206.0 +7,30,2380,5741,0.94,2.09,4.31,2.38,2.05,3.61,8.92,204.3 +7,30,2630,6562,1.00,2.34,4.71,2.58,1.93,4.02,9.53,203.0 +7,30,2880,7382,1.05,2.60,5.17,2.89,2.09,4.38,10.22,201.9 +7,30,3130,8202,1.10,2.86,5.73,3.22,2.09,4.92,10.98,201.0 +7,30,3380,9022,1.21,3.07,5.82,3.25,2.32,5.12,11.33,201.5 +7,30,3630,9843,1.32,3.25,5.76,3.14,2.31,5.13,11.62,202.1 +7,30,3880,10663,1.44,3.43,5.78,3.06,2.07,5.17,11.48,202.7 +7,30,4130,11483,1.55,3.61,5.87,3.01,2.09,5.24,11.57,203.2 +7,30,4380,12303,1.66,3.79,6.03,2.99,1.85,5.49,11.67,203.7 +7,30,4630,13123,1.78,3.97,6.25,3.02,1.78,5.98,11.79,204.1 +7,30,4880,13944,1.89,4.15,6.50,3.13,2.10,6.15,11.91,204.5 +7,30,5130,14764,2.00,4.33,6.77,3.33,2.08,6.28,12.54,204.8 +7,30,5380,15584,2.11,4.51,7.08,3.59,2.09,6.44,13.29,205.1 +7,30,5630,16404,2.23,4.69,7.43,3.85,1.83,6.67,14.07,205.4 +7,30,5880,17224,2.34,4.87,7.83,4.11,1.51,7.03,14.92,205.7 +7,30,6130,18045,2.70,4.90,8.06,4.17,1.71,7.17,14.97,208.9 +7,30,6380,18865,3.11,4.87,8.30,4.14,2.12,7.95,14.60,212.6 +7,30,6630,19685,3.52,4.84,8.61,4.14,2.63,8.51,14.41,216.0 +7,30,6880,20505,3.93,4.81,8.97,4.20,3.18,9.03,14.52,219.3 +7,30,7130,21325,4.34,4.78,9.36,4.33,3.75,9.82,15.08,222.3 +7,30,7380,22146,4.75,4.75,9.78,4.53,3.57,10.85,15.75,225.0 +7,30,7630,22966,5.15,4.71,10.21,4.78,3.09,11.26,16.44,227.5 +7,30,7880,23786,5.43,4.97,10.48,4.69,3.13,10.79,17.10,227.5 +7,30,8130,24606,5.70,5.26,10.77,4.63,3.31,10.35,17.75,227.3 +7,30,8380,25427,5.98,5.54,11.10,4.63,3.62,10.15,18.40,227.2 +8,41,630,0,0.21,1.09,2.14,1.47,0.51,1.68,5.35,190.8 +8,41,880,820,-0.41,2.01,3.44,2.33,0.55,3.09,9.21,168.5 +8,41,1130,1640,0.30,1.61,3.06,2.19,0.69,2.50,8.52,190.5 +8,41,1380,2461,1.00,1.20,3.54,2.14,0.81,3.26,8.54,219.9 +8,41,1630,3281,1.50,1.06,4.03,2.19,0.70,3.74,8.39,234.8 +8,41,1880,4101,1.67,1.30,4.05,2.10,1.35,3.40,8.68,232.2 +8,41,2130,4921,1.85,1.54,4.16,2.22,1.36,3.69,8.52,230.1 +8,41,2380,5741,2.02,1.78,4.38,2.52,1.00,3.99,9.09,228.5 +8,41,2630,6562,2.19,2.03,4.74,2.84,1.23,4.19,10.23,227.2 +8,41,2880,7382,2.36,2.27,5.23,3.14,1.00,4.59,10.70,226.2 +8,41,3130,8202,2.54,2.51,5.85,3.40,1.95,5.43,11.34,225.3 +8,41,3380,9022,2.75,2.66,5.94,3.50,1.69,5.10,11.76,225.9 +8,41,3630,9843,2.95,2.78,5.93,3.55,1.72,4.66,11.72,226.8 +8,41,3880,10663,3.16,2.89,6.01,3.58,1.84,4.86,11.96,227.5 +8,41,4130,11483,3.37,3.01,6.17,3.60,1.70,5.17,12.20,228.2 +8,41,4380,12303,3.57,3.12,6.43,3.59,2.38,5.71,12.44,228.8 +8,41,4630,13123,3.78,3.24,6.73,3.61,2.21,6.07,12.70,229.4 +8,41,4880,13944,3.99,3.35,7.06,3.67,2.08,6.46,13.39,229.9 +8,41,5130,14764,4.19,3.47,7.42,3.79,1.97,7.00,14.11,230.4 +8,41,5380,15584,4.40,3.59,7.80,3.94,1.94,7.27,14.50,230.8 +8,41,5630,16404,4.60,3.70,8.20,4.11,1.97,7.67,14.67,231.2 +8,41,5880,17224,4.80,3.81,8.62,4.31,2.06,8.47,15.24,231.6 +8,41,6130,18045,5.18,3.83,8.85,4.54,2.34,8.22,15.31,233.5 +8,41,6380,18865,5.61,3.81,9.07,4.86,1.97,8.82,16.17,235.8 +8,41,6630,19685,6.04,3.79,9.38,5.18,1.58,9.42,17.85,237.9 +8,41,6880,20505,6.47,3.77,9.78,5.48,1.62,10.03,19.70,239.8 +8,41,7130,21325,6.89,3.75,10.25,5.78,1.82,10.95,20.76,241.5 +8,41,7380,22146,7.32,3.73,10.80,6.04,2.34,11.24,21.68,243.0 +8,41,7630,22966,7.75,3.73,11.38,6.22,2.99,11.31,22.60,244.3 +8,41,7880,23786,8.27,3.94,11.88,6.32,2.58,11.42,22.85,244.5 +8,41,8130,24606,8.79,4.15,12.37,6.48,2.54,11.83,23.11,244.7 +8,41,8380,25427,9.32,4.37,12.88,6.69,2.82,12.49,23.36,244.9 +9,24,630,0,-0.49,1.28,2.29,1.81,1.01,1.76,5.48,159.1 +9,24,880,820,-1.36,1.19,2.90,2.39,0.98,1.94,7.94,131.3 +9,24,1130,1640,-1.06,0.65,2.66,2.31,0.68,2.26,7.34,121.4 +9,24,1380,2461,-0.77,0.11,3.13,2.29,0.81,2.69,6.95,97.8 +9,24,1630,3281,-0.48,-0.24,3.65,2.24,1.24,3.28,6.69,62.9 +9,24,1880,4101,-0.23,-0.27,3.69,2.20,1.41,3.20,7.04,40.2 +9,24,2130,4921,0.02,-0.30,3.90,2.40,0.91,3.27,8.15,356.2 +9,24,2380,5741,0.27,-0.32,4.30,2.70,1.49,3.49,9.47,320.5 +9,24,2630,6562,0.51,-0.35,4.81,3.13,1.53,4.08,11.15,304.4 +9,24,2880,7382,0.76,-0.38,5.39,3.65,1.52,4.32,13.19,296.4 +9,24,3130,8202,0.99,-0.39,6.00,4.20,1.50,4.74,15.16,291.3 +9,24,3380,9022,1.26,-0.52,6.25,4.45,2.10,4.53,16.19,292.4 +9,24,3630,9843,1.56,-0.72,6.44,4.75,2.38,4.60,17.13,294.8 +9,24,3880,10663,1.86,-0.92,6.69,5.09,2.01,5.01,18.33,296.4 +9,24,4130,11483,2.16,-1.12,7.00,5.48,1.13,5.46,19.54,297.5 +9,24,4380,12303,2.45,-1.32,7.43,5.81,1.22,5.95,20.76,298.3 +9,24,4630,13123,2.75,-1.52,7.94,6.14,1.53,6.71,21.98,298.9 +9,24,4880,13944,3.05,-1.72,8.53,6.42,1.83,6.71,23.21,299.5 +9,24,5130,14764,3.35,-1.92,9.14,6.74,2.14,7.29,24.44,299.9 +9,24,5380,15584,3.65,-2.12,9.77,7.09,2.63,7.84,25.68,300.2 +9,24,5630,16404,3.95,-2.33,10.40,7.47,3.05,8.51,26.92,300.5 +9,24,5880,17224,4.20,-2.54,11.00,7.78,3.15,8.72,28.12,301.1 +9,24,6130,18045,4.25,-2.72,11.49,8.07,3.45,9.26,29.26,302.7 +9,24,6380,18865,4.29,-2.91,12.03,8.39,3.01,10.15,30.60,304.1 +9,24,6630,19685,4.33,-3.10,12.65,8.69,2.56,10.86,32.10,305.5 +9,24,6880,20505,4.38,-3.28,13.30,9.04,2.89,11.65,33.62,306.9 +9,24,7130,21325,4.42,-3.47,13.97,9.43,3.64,12.41,35.15,308.1 +9,24,7380,22146,4.46,-3.65,14.65,9.87,3.69,13.17,36.69,309.3 +9,24,7630,22966,4.60,-3.83,15.25,10.26,3.85,13.50,37.65,309.8 +9,24,7880,23786,5.16,-3.74,15.52,10.53,4.26,12.46,38.44,305.9 +9,24,8130,24606,5.75,-3.63,15.82,10.87,4.59,12.69,39.82,302.3 +9,24,8380,25427,6.33,-3.53,16.17,11.27,4.92,12.07,40.43,299.1 +10,31,630,0,0.01,0.29,1.55,0.86,0.56,1.32,3.18,182.6 +10,31,880,820,0.22,1.20,2.92,2.92,0.35,1.56,8.46,190.3 +10,31,1130,1640,0.43,1.03,3.10,2.80,0.64,2.03,8.33,202.5 +10,31,1380,2461,0.63,0.84,3.60,2.87,0.88,2.52,8.49,216.9 +10,31,1630,3281,0.95,0.69,4.13,3.15,0.65,3.46,10.29,234.3 +10,31,1880,4101,1.44,0.43,4.30,3.51,0.77,3.07,11.20,253.3 +10,31,2130,4921,1.92,0.18,4.69,3.96,0.90,2.85,12.98,264.8 +10,31,2380,5741,2.40,-0.08,5.25,4.45,1.18,3.15,15.50,271.9 +10,31,2630,6562,2.88,-0.34,5.95,4.97,1.59,3.76,18.02,276.6 +10,31,2880,7382,3.36,-0.59,6.72,5.53,1.82,4.61,20.54,280.0 +10,31,3130,8202,3.84,-0.83,7.52,6.05,2.03,5.65,22.82,282.2 +10,31,3380,9022,4.29,-1.04,8.01,6.07,2.23,6.15,22.43,283.6 +10,31,3630,9843,4.77,-1.26,8.48,6.16,2.17,6.72,22.42,284.8 +10,31,3880,10663,5.26,-1.48,8.99,6.30,2.70,7.21,23.16,285.7 +10,31,4130,11483,5.75,-1.70,9.54,6.49,3.00,7.79,23.22,286.5 +10,31,4380,12303,6.24,-1.92,10.12,6.72,3.24,8.66,23.31,287.1 +10,31,4630,13123,6.72,-2.14,10.72,7.02,3.48,9.53,23.42,287.7 +10,31,4880,13944,7.21,-2.36,11.33,7.36,3.93,9.97,24.11,288.1 +10,31,5130,14764,7.70,-2.58,11.95,7.74,4.05,10.80,25.38,288.5 +10,31,5380,15584,8.19,-2.80,12.58,8.17,3.74,11.65,26.65,288.9 +10,31,5630,16404,8.67,-3.02,13.22,8.63,3.45,12.46,27.93,289.2 +10,31,5880,17224,9.11,-3.20,13.79,8.90,3.15,12.89,29.03,289.3 +10,31,6130,18045,9.31,-3.15,13.93,9.15,2.84,13.23,29.31,288.7 +10,31,6380,18865,9.47,-3.07,14.06,9.47,2.51,13.80,29.61,288.0 +10,31,6630,19685,9.62,-2.98,14.26,9.77,2.09,13.64,29.92,287.2 +10,31,6880,20505,9.78,-2.89,14.57,10.01,1.81,13.46,30.24,286.5 +10,31,7130,21325,9.94,-2.81,14.95,10.22,2.11,13.81,30.57,285.8 +10,31,7380,22146,10.10,-2.73,15.40,10.43,2.18,13.86,30.92,285.1 +10,31,7630,22966,10.38,-2.54,15.94,10.57,2.58,15.03,32.12,283.8 +10,31,7880,23786,10.83,-2.45,16.38,10.76,2.31,15.40,33.96,282.7 +10,31,8130,24606,11.29,-2.36,16.84,10.97,2.06,15.77,35.80,281.8 +10,31,8380,25427,11.74,-2.27,17.33,11.22,2.21,16.15,37.66,281.0 +11,30,630,0,-0.15,0.44,1.53,1.12,0.55,1.24,2.51,161.8 +11,30,880,820,-0.15,0.79,1.88,1.38,0.42,1.70,3.43,168.9 +11,30,1130,1640,0.81,1.06,2.76,1.94,0.72,2.02,6.16,217.5 +11,30,1380,2461,1.79,1.33,4.26,2.97,0.87,3.55,9.72,233.3 +11,30,1630,3281,2.59,1.36,5.19,3.71,0.55,4.61,10.81,242.2 +11,30,1880,4101,3.47,1.27,5.60,4.05,0.68,4.99,11.09,249.9 +11,30,2130,4921,4.34,1.17,6.41,4.32,1.04,5.49,12.01,254.9 +11,30,2380,5741,5.22,1.08,7.43,4.63,1.47,6.08,13.40,258.3 +11,30,2630,6562,6.09,0.98,8.58,4.98,2.27,7.95,15.29,260.8 +11,30,2880,7382,6.97,0.89,9.80,5.39,3.13,9.70,17.20,262.7 +11,30,3130,8202,7.84,0.85,11.05,5.77,3.63,11.04,18.96,263.8 +11,30,3380,9022,8.40,0.93,11.62,5.85,4.29,11.73,19.49,263.7 +11,30,3630,9843,8.96,1.00,12.14,5.99,4.68,12.42,19.90,263.6 +11,30,3880,10663,9.53,1.07,12.71,6.19,4.60,13.15,20.42,263.6 +11,30,4130,11483,10.09,1.14,13.31,6.42,4.72,13.65,21.80,263.5 +11,30,4380,12303,10.66,1.21,13.95,6.68,4.80,13.69,23.34,263.5 +11,30,4630,13123,11.22,1.28,14.62,6.96,4.88,14.30,25.14,263.5 +11,30,4880,13944,11.79,1.35,15.31,7.26,5.03,15.01,27.19,263.5 +11,30,5130,14764,12.35,1.42,16.03,7.57,5.29,15.45,29.25,263.4 +11,30,5380,15584,12.92,1.49,16.78,7.89,5.57,15.92,31.31,263.4 +11,30,5630,16404,13.48,1.55,17.53,8.20,5.84,16.39,33.17,263.5 +11,30,5880,17224,14.03,1.64,18.19,8.40,6.19,16.76,34.27,263.3 +11,30,6130,18045,14.56,1.80,18.72,8.62,6.46,17.13,34.89,262.9 +11,30,6380,18865,15.08,1.97,19.29,8.87,6.62,18.31,35.32,262.6 +11,30,6630,19685,15.60,2.13,19.90,9.15,6.80,19.59,35.78,262.2 +11,30,6880,20505,16.12,2.30,20.55,9.47,6.87,20.96,36.62,261.9 +11,30,7130,21325,16.64,2.46,21.22,9.83,6.63,21.57,38.18,261.6 +11,30,7380,22146,17.19,2.65,21.96,10.29,6.65,21.94,40.19,261.2 +11,30,7630,22966,17.78,2.66,22.69,10.62,6.85,22.74,41.07,261.5 +11,30,7880,23786,18.39,2.69,23.44,10.93,7.55,23.97,41.78,261.7 +11,30,8130,24606,19.00,2.73,24.22,11.29,8.47,24.61,42.52,261.8 +11,30,8380,25427,19.61,2.77,25.02,11.70,9.42,25.21,43.45,262.0 +12,22,630,0,-0.05,0.12,1.29,0.69,0.50,1.23,2.31,157.1 +12,22,880,820,-0.24,0.24,1.78,1.28,0.48,1.48,4.44,135.0 +12,22,1130,1640,-0.21,-0.35,2.31,1.57,0.38,1.84,5.48,31.4 +12,22,1380,2461,-0.23,-1.05,3.92,2.62,0.69,3.26,8.87,12.1 +12,22,1630,3281,-0.11,-1.92,5.26,3.93,0.94,4.39,13.17,3.3 +12,22,1880,4101,0.47,-2.17,5.67,3.98,1.14,5.50,13.81,347.9 +12,22,2130,4921,1.04,-2.41,6.57,3.83,1.86,5.75,14.43,336.6 +12,22,2380,5741,1.62,-2.65,7.63,3.91,2.69,6.99,15.07,328.5 +12,22,2630,6562,2.20,-2.89,8.75,4.26,2.67,8.16,15.93,322.7 +12,22,2880,7382,2.78,-3.12,9.92,4.82,2.95,9.64,16.77,318.3 +12,22,3130,8202,3.38,-3.37,11.10,5.49,2.72,11.55,17.70,314.8 +12,22,3380,9022,3.99,-3.63,11.73,5.45,2.58,12.37,18.47,312.3 +12,22,3630,9843,4.65,-3.95,12.49,5.30,4.33,13.84,19.18,310.4 +12,22,3880,10663,5.30,-4.27,13.32,5.23,5.29,14.38,19.90,308.8 +12,22,4130,11483,5.96,-4.59,14.19,5.30,5.82,14.97,21.58,307.6 +12,22,4380,12303,6.61,-4.90,15.08,5.49,6.32,15.83,21.39,306.5 +12,22,4630,13123,7.27,-5.22,15.99,5.81,6.82,16.37,22.97,305.7 +12,22,4880,13944,7.93,-5.54,16.93,6.23,7.33,17.79,24.82,304.9 +12,22,5130,14764,8.58,-5.86,17.87,6.74,7.83,19.10,26.69,304.3 +12,22,5380,15584,9.24,-6.17,18.84,7.32,8.34,19.80,28.55,303.8 +12,22,5630,16404,9.91,-6.50,19.83,7.92,9.26,20.00,30.47,303.2 +12,22,5880,17224,10.55,-6.80,20.68,8.06,10.54,20.53,31.87,302.8 +12,22,6130,18045,11.20,-6.99,21.41,8.16,11.77,21.29,33.22,302.0 +12,22,6380,18865,11.85,-7.18,22.16,8.38,12.89,21.30,34.66,301.2 +12,22,6630,19685,12.49,-7.37,22.93,8.73,13.99,22.06,36.09,300.5 +12,22,6880,20505,13.14,-7.56,23.71,9.18,15.11,23.19,38.93,299.9 +12,22,7130,21325,13.78,-7.74,24.50,9.71,15.83,23.70,42.11,299.3 +12,22,7380,22146,14.32,-7.80,25.16,10.20,15.90,23.93,44.59,298.6 +12,22,7630,22966,15.15,-7.70,25.72,10.46,15.72,23.21,44.74,297.0 +12,22,7880,23786,16.06,-7.63,26.23,10.81,14.77,22.93,44.89,295.4 +12,22,8130,24606,16.98,-7.56,26.82,11.14,13.84,23.30,45.67,294.0 +12,22,8380,25427,17.90,-7.48,27.48,11.45,12.94,24.97,47.40,292.7 diff --git a/recovery-calculator/site-climatology/data/vef-wprofile-monthly.csv b/recovery-calculator/site-climatology/data/vef-wprofile-monthly.csv new file mode 100644 index 000000000..2e1531df4 --- /dev/null +++ b/recovery-calculator/site-climatology/data/vef-wprofile-monthly.csv @@ -0,0 +1,385 @@ +month,n_soundings,H_msl_m,H_agl_ft,u_mean_ms,v_mean_ms,spd_mean_ms,spd_sd_ms,spd_p05_ms,spd_p50_ms,spd_p95_ms,dir_mean_deg +1,613,630,0,0.45,0.19,3.23,2.42,0.49,2.79,7.19,247.6 +1,613,880,820,-0.37,-1.17,3.74,3.36,0.61,2.56,10.73,17.5 +1,613,1130,1640,0.05,-1.82,4.85,3.89,0.70,3.46,12.51,358.4 +1,613,1380,2461,0.52,-2.12,6.03,3.98,1.13,5.25,13.20,346.3 +1,613,1630,3281,1.14,-2.31,6.81,4.00,1.23,6.11,13.55,333.7 +1,613,1880,4101,1.64,-2.32,7.39,4.04,1.72,6.93,14.31,324.7 +1,613,2130,4921,2.07,-2.29,8.01,4.24,1.93,7.49,15.52,317.8 +1,613,2380,5741,2.52,-2.15,8.70,4.50,2.27,8.35,16.70,310.5 +1,613,2630,6562,3.08,-2.15,9.45,4.96,2.52,8.99,18.14,304.8 +1,613,2880,7382,3.62,-2.26,10.12,5.38,2.57,9.64,19.78,302.0 +1,613,3130,8202,4.15,-2.43,10.76,5.74,2.75,10.03,21.47,300.4 +1,613,3380,9022,4.68,-2.68,11.44,6.12,2.70,10.70,23.38,299.8 +1,613,3630,9843,5.29,-3.07,12.28,6.53,3.37,11.12,24.85,300.1 +1,613,3880,10663,6.06,-3.40,13.14,6.94,3.58,12.13,26.13,299.3 +1,613,4130,11483,6.74,-3.64,13.89,7.27,3.95,12.78,27.12,298.4 +1,613,4380,12303,7.40,-3.93,14.63,7.59,4.12,13.55,28.54,298.0 +1,613,4630,13123,8.11,-4.15,15.37,7.85,4.25,14.41,30.15,297.1 +1,613,4880,13944,8.75,-4.48,16.10,8.18,4.81,14.93,32.01,297.1 +1,613,5130,14764,9.36,-4.69,16.85,8.61,5.20,15.81,33.61,296.6 +1,613,5380,15584,9.94,-4.83,17.56,9.05,4.85,16.39,34.62,295.9 +1,613,5630,16404,10.54,-4.96,18.23,9.47,5.15,16.90,34.93,295.2 +1,613,5880,17224,11.05,-5.12,18.92,9.84,4.82,17.68,37.78,294.9 +1,613,6130,18045,11.52,-5.29,19.63,10.14,4.99,18.28,39.67,294.7 +1,613,6380,18865,12.01,-5.49,20.33,10.48,5.23,19.12,40.73,294.6 +1,613,6630,19685,12.58,-5.62,21.10,10.81,5.41,19.91,41.30,294.1 +1,613,6880,20505,13.07,-5.74,21.76,11.18,5.30,20.11,42.71,293.7 +1,613,7130,21325,13.59,-5.88,22.47,11.49,5.81,20.90,43.70,293.4 +1,613,7380,22146,14.12,-6.03,23.14,11.75,5.72,21.41,45.40,293.1 +1,613,7630,22966,14.68,-6.19,23.88,12.03,6.11,22.65,46.39,292.9 +1,613,7880,23786,15.24,-6.23,24.66,12.34,6.70,23.01,47.20,292.3 +1,613,8130,24606,15.81,-6.32,25.40,12.67,6.30,23.49,47.75,291.8 +1,613,8380,25427,16.36,-6.49,26.15,13.03,6.67,23.97,49.25,291.6 +2,562,630,0,-0.05,-0.21,3.83,3.97,0.72,3.07,8.26,12.6 +2,562,880,820,0.47,-0.23,4.63,3.74,0.65,3.15,11.18,295.8 +2,562,1130,1640,1.00,-0.51,5.51,4.17,0.67,4.38,13.07,297.2 +2,562,1380,2461,1.54,-0.59,6.50,4.31,1.15,5.65,14.31,291.1 +2,562,1630,3281,2.11,-0.55,7.10,4.37,1.19,6.18,14.97,284.7 +2,562,1880,4101,2.65,-0.48,7.56,4.34,1.75,6.85,15.26,280.3 +2,562,2130,4921,3.22,-0.31,8.14,4.60,1.86,7.39,16.84,275.4 +2,562,2380,5741,3.83,-0.14,8.71,4.99,1.93,7.86,18.63,272.1 +2,562,2630,6562,4.37,-0.02,9.42,5.41,2.32,8.48,20.57,270.3 +2,562,2880,7382,4.86,-0.05,10.15,5.76,2.36,9.08,21.19,270.6 +2,562,3130,8202,5.58,-0.23,11.00,6.12,2.78,9.90,22.83,272.4 +2,562,3380,9022,6.40,-0.51,11.86,6.41,3.33,10.60,24.60,274.5 +2,562,3630,9843,7.17,-0.75,12.69,6.64,3.48,11.43,24.94,275.9 +2,562,3880,10663,7.91,-0.89,13.46,6.93,3.92,12.44,26.67,276.4 +2,562,4130,11483,8.68,-1.00,14.25,7.26,4.14,13.14,27.69,276.6 +2,562,4380,12303,9.46,-1.16,15.12,7.66,4.16,14.24,28.95,277.0 +2,562,4630,13123,10.18,-1.34,16.03,8.11,4.66,15.11,30.77,277.5 +2,562,4880,13944,10.90,-1.52,16.91,8.52,4.84,16.14,32.14,278.0 +2,562,5130,14764,11.61,-1.61,17.75,8.85,4.77,17.15,33.31,277.9 +2,562,5380,15584,12.35,-1.61,18.61,9.19,5.13,17.98,35.20,277.4 +2,562,5630,16404,13.06,-1.59,19.46,9.54,5.37,19.00,37.21,276.9 +2,562,5880,17224,13.72,-1.59,20.30,9.81,5.27,19.74,37.62,276.6 +2,562,6130,18045,14.43,-1.66,21.20,10.18,6.02,20.69,39.63,276.6 +2,562,6380,18865,15.21,-1.68,22.18,10.60,6.41,21.58,40.74,276.3 +2,562,6630,19685,15.90,-1.64,23.06,11.12,6.49,22.71,42.53,275.9 +2,562,6880,20505,16.54,-1.58,23.99,11.57,6.78,23.21,44.66,275.5 +2,562,7130,21325,17.17,-1.60,24.89,11.95,7.41,23.64,45.94,275.3 +2,562,7380,22146,17.84,-1.64,25.78,12.27,7.84,24.61,47.14,275.3 +2,562,7630,22966,18.50,-1.62,26.65,12.52,8.22,25.69,48.09,275.0 +2,562,7880,23786,19.14,-1.51,27.51,12.85,8.81,26.31,49.60,274.5 +2,562,8130,24606,19.78,-1.48,28.35,13.17,9.30,26.98,51.01,274.3 +2,562,8380,25427,20.37,-1.46,29.16,13.59,9.59,27.57,52.09,274.1 +3,608,630,0,0.03,-0.12,4.58,4.32,0.98,3.54,12.72,344.5 +3,608,880,820,1.41,1.14,5.37,3.59,0.86,4.69,11.79,231.0 +3,608,1130,1640,1.92,0.92,6.06,3.96,1.01,5.39,13.01,244.3 +3,608,1380,2461,2.34,0.79,6.66,4.22,1.10,6.24,14.47,251.3 +3,608,1630,3281,2.63,0.79,7.01,4.27,1.40,6.38,14.94,253.2 +3,608,1880,4101,2.99,0.90,7.42,4.34,1.63,6.78,15.80,253.2 +3,608,2130,4921,3.34,0.96,7.92,4.50,1.91,7.11,16.62,254.0 +3,608,2380,5741,3.62,1.04,8.38,4.68,2.28,7.42,17.79,253.9 +3,608,2630,6562,3.99,1.11,8.83,4.93,2.24,8.10,18.79,254.5 +3,608,2880,7382,4.46,1.12,9.36,5.33,2.19,8.67,19.93,255.8 +3,608,3130,8202,5.06,1.12,10.01,5.61,2.40,9.14,20.68,257.6 +3,608,3380,9022,5.76,0.99,10.72,5.77,2.86,9.68,21.49,260.3 +3,608,3630,9843,6.56,0.86,11.52,5.96,3.23,10.36,22.45,262.5 +3,608,3880,10663,7.37,0.68,12.41,6.21,3.72,11.54,23.11,264.7 +3,608,4130,11483,8.09,0.55,13.21,6.54,3.94,12.42,24.86,266.1 +3,608,4380,12303,8.78,0.47,14.04,6.91,4.17,13.08,26.16,267.0 +3,608,4630,13123,9.46,0.35,14.83,7.29,4.44,13.70,28.17,267.9 +3,608,4880,13944,10.13,0.21,15.69,7.64,4.61,14.48,30.05,268.8 +3,608,5130,14764,10.83,0.11,16.53,8.10,4.94,15.35,32.01,269.4 +3,608,5380,15584,11.54,0.08,17.38,8.59,5.13,16.35,33.28,269.6 +3,608,5630,16404,12.20,0.09,18.28,8.95,5.47,17.08,33.77,269.6 +3,608,5880,17224,12.87,0.05,19.16,9.29,5.77,17.93,35.91,269.8 +3,608,6130,18045,13.46,0.06,20.06,9.63,5.97,18.60,37.96,269.8 +3,608,6380,18865,14.13,0.05,21.00,10.14,6.19,19.67,40.35,269.8 +3,608,6630,19685,14.82,0.05,21.93,10.59,6.24,20.37,42.16,269.8 +3,608,6880,20505,15.47,0.09,22.76,11.13,6.26,21.13,43.88,269.7 +3,608,7130,21325,16.09,0.07,23.60,11.67,6.43,22.12,45.10,269.8 +3,608,7380,22146,16.74,0.11,24.41,12.12,6.77,23.05,45.96,269.6 +3,608,7630,22966,17.46,0.20,25.20,12.49,7.03,23.93,47.50,269.4 +3,608,7880,23786,18.19,0.24,26.00,12.80,7.03,25.00,48.12,269.3 +3,608,8130,24606,18.83,0.22,26.86,13.05,7.32,25.76,49.79,269.3 +3,608,8380,25427,19.52,0.22,27.66,13.39,7.42,26.40,51.60,269.3 +4,582,630,0,0.01,0.24,5.39,7.01,0.95,3.78,12.80,183.5 +4,582,880,820,1.69,1.27,5.83,3.94,1.03,5.08,13.37,232.9 +4,582,1130,1640,2.20,0.78,6.39,4.34,0.98,5.60,14.47,250.4 +4,582,1380,2461,2.46,0.41,6.75,4.39,1.01,6.06,14.86,260.6 +4,582,1630,3281,2.57,0.45,6.86,4.36,1.13,6.11,15.21,260.2 +4,582,1880,4101,2.77,0.64,6.97,4.33,1.40,6.12,15.50,257.0 +4,582,2130,4921,3.01,0.84,7.20,4.35,1.57,6.34,15.61,254.4 +4,582,2380,5741,3.31,1.02,7.49,4.54,1.77,6.54,16.32,252.8 +4,582,2630,6562,3.61,1.12,7.82,4.69,1.81,6.96,17.28,252.8 +4,582,2880,7382,4.03,1.18,8.15,4.86,1.87,7.23,18.63,253.7 +4,582,3130,8202,4.46,1.17,8.73,5.02,2.20,7.91,18.79,255.3 +4,582,3380,9022,5.07,0.92,9.29,5.17,2.48,8.60,19.16,259.7 +4,582,3630,9843,5.68,0.60,9.94,5.43,2.66,9.21,20.43,264.0 +4,582,3880,10663,6.32,0.31,10.73,5.70,3.01,9.99,21.42,267.2 +4,582,4130,11483,6.94,-0.01,11.47,6.04,3.20,10.58,23.26,270.0 +4,582,4380,12303,7.71,-0.32,12.19,6.50,3.32,11.20,24.51,272.4 +4,582,4630,13123,8.49,-0.51,12.96,6.81,3.16,12.25,25.63,273.4 +4,582,4880,13944,9.26,-0.59,13.76,7.25,3.70,13.01,27.97,273.6 +4,582,5130,14764,10.09,-0.73,14.67,7.75,3.53,13.61,29.05,274.2 +4,582,5380,15584,10.85,-0.87,15.49,8.12,4.49,14.20,30.42,274.6 +4,582,5630,16404,11.66,-1.02,16.33,8.50,4.94,14.71,32.11,275.0 +4,582,5880,17224,12.38,-1.09,17.19,8.82,5.23,15.61,33.22,275.0 +4,582,6130,18045,13.07,-1.21,17.96,9.21,5.31,16.88,34.95,275.3 +4,582,6380,18865,13.74,-1.35,18.76,9.61,5.27,17.82,36.17,275.6 +4,582,6630,19685,14.41,-1.52,19.56,10.03,5.55,18.49,38.32,276.0 +4,582,6880,20505,15.03,-1.64,20.33,10.40,5.58,19.40,39.68,276.2 +4,582,7130,21325,15.65,-1.74,21.09,10.76,6.00,20.05,41.76,276.3 +4,582,7380,22146,16.24,-1.81,21.75,11.06,6.40,20.60,43.15,276.3 +4,582,7630,22966,16.89,-1.84,22.50,11.29,6.54,21.19,43.52,276.2 +4,582,7880,23786,17.50,-1.85,23.24,11.49,7.16,22.05,44.07,276.0 +4,582,8130,24606,18.04,-1.95,23.92,11.73,7.55,22.48,44.95,276.2 +4,582,8380,25427,18.53,-1.94,24.60,11.98,7.77,22.93,45.87,276.0 +5,601,630,0,-1.28,0.28,6.43,10.93,0.98,3.88,18.61,102.2 +5,601,880,820,1.67,2.13,5.62,3.56,1.18,5.02,11.98,218.1 +5,601,1130,1640,2.22,1.73,6.19,3.95,1.10,5.60,13.55,232.2 +5,601,1380,2461,2.36,1.51,6.49,4.07,1.37,5.70,13.74,237.5 +5,601,1630,3281,2.44,1.61,6.56,4.06,1.18,5.79,14.26,236.6 +5,601,1880,4101,2.35,1.79,6.49,4.09,1.37,5.71,14.75,232.8 +5,601,2130,4921,2.28,2.06,6.53,4.07,1.50,5.57,14.26,227.9 +5,601,2380,5741,2.36,2.29,6.65,4.13,1.55,5.69,15.41,225.8 +5,601,2630,6562,2.42,2.44,6.89,4.21,1.67,6.00,15.58,224.7 +5,601,2880,7382,2.44,2.50,7.20,4.27,1.56,6.31,16.13,224.2 +5,601,3130,8202,2.56,2.48,7.58,4.43,1.97,6.79,16.72,226.0 +5,601,3380,9022,2.80,2.33,7.88,4.55,2.05,7.11,16.95,230.2 +5,601,3630,9843,3.17,2.23,8.31,4.73,2.18,7.56,17.35,234.9 +5,601,3880,10663,3.61,2.08,8.79,4.98,2.37,7.86,18.87,240.1 +5,601,4130,11483,4.04,1.99,9.28,5.27,2.53,8.46,19.31,243.8 +5,601,4380,12303,4.64,1.94,9.78,5.66,2.43,8.89,21.37,247.3 +5,601,4630,13123,5.32,1.85,10.39,6.06,2.94,9.15,22.53,250.8 +5,601,4880,13944,5.97,1.68,11.06,6.50,2.81,9.68,23.86,254.3 +5,601,5130,14764,6.79,1.56,11.76,6.92,2.69,10.48,25.37,257.1 +5,601,5380,15584,7.43,1.45,12.44,7.31,2.89,10.98,26.53,258.9 +5,601,5630,16404,8.05,1.41,13.08,7.79,3.21,11.56,27.84,260.0 +5,601,5880,17224,8.62,1.32,13.78,8.21,3.23,12.05,29.57,261.3 +5,601,6130,18045,9.15,1.12,14.44,8.53,3.55,12.62,31.40,263.0 +5,601,6380,18865,9.67,1.07,15.06,8.87,3.62,13.22,32.69,263.7 +5,601,6630,19685,10.25,0.99,15.65,9.24,3.90,13.65,34.52,264.5 +5,601,6880,20505,10.72,0.96,16.24,9.66,4.10,14.09,35.62,264.9 +5,601,7130,21325,11.21,0.90,16.79,10.01,4.23,14.70,36.10,265.4 +5,601,7380,22146,11.73,0.79,17.41,10.34,4.70,15.32,36.67,266.1 +5,601,7630,22966,12.25,0.72,18.04,10.71,4.58,15.88,38.43,266.6 +5,601,7880,23786,12.76,0.66,18.63,10.97,4.99,16.35,39.15,267.0 +5,601,8130,24606,13.25,0.62,19.19,11.16,5.42,17.12,40.31,267.3 +5,601,8380,25427,13.72,0.62,19.77,11.34,5.58,17.70,42.47,267.4 +6,590,630,0,-0.95,-0.93,6.58,10.56,1.13,3.83,18.41,45.6 +6,590,880,820,2.33,3.35,6.02,3.53,1.27,5.69,12.34,214.8 +6,590,1130,1640,2.90,2.89,6.42,3.84,1.39,5.98,13.33,225.2 +6,590,1380,2461,3.01,2.60,6.61,3.97,1.43,6.09,14.39,229.2 +6,590,1630,3281,2.93,2.70,6.58,4.00,1.29,5.90,14.19,227.3 +6,590,1880,4101,2.83,3.07,6.55,3.98,1.34,5.96,14.42,222.7 +6,590,2130,4921,2.71,3.39,6.47,3.99,1.39,5.76,14.69,218.7 +6,590,2380,5741,2.65,3.60,6.47,3.98,1.33,5.74,14.65,216.3 +6,590,2630,6562,2.54,3.80,6.53,3.94,1.58,5.88,14.60,213.8 +6,590,2880,7382,2.43,3.91,6.53,3.93,1.53,5.87,14.04,211.9 +6,590,3130,8202,2.47,4.00,6.71,3.93,1.63,6.08,13.89,211.7 +6,590,3380,9022,2.59,3.97,6.87,3.97,1.70,6.21,13.88,213.1 +6,590,3630,9843,2.84,3.94,7.18,4.12,1.71,6.57,14.64,215.8 +6,590,3880,10663,3.16,3.88,7.49,4.33,1.90,6.87,15.20,219.2 +6,590,4130,11483,3.54,3.84,7.80,4.69,1.83,6.98,15.95,222.7 +6,590,4380,12303,3.90,3.86,8.20,4.93,1.99,7.26,16.85,225.3 +6,590,4630,13123,4.27,3.89,8.64,5.29,2.11,7.48,18.61,227.7 +6,590,4880,13944,4.70,3.97,9.07,5.62,2.19,8.10,19.48,229.8 +6,590,5130,14764,5.14,3.98,9.45,5.87,2.08,8.57,20.43,232.3 +6,590,5380,15584,5.73,3.90,9.92,6.21,1.99,9.01,21.55,235.8 +6,590,5630,16404,6.34,3.88,10.46,6.57,2.21,8.84,22.11,238.5 +6,590,5880,17224,6.96,3.79,11.01,6.78,2.40,9.50,23.06,241.4 +6,590,6130,18045,7.48,3.77,11.51,6.96,2.79,10.04,23.79,243.3 +6,590,6380,18865,7.92,3.72,12.01,7.14,2.95,10.64,24.91,244.9 +6,590,6630,19685,8.34,3.70,12.43,7.39,2.90,11.01,26.27,246.1 +6,590,6880,20505,8.72,3.73,12.89,7.62,2.80,11.57,27.21,246.9 +6,590,7130,21325,9.09,3.74,13.34,7.84,3.27,11.86,27.48,247.6 +6,590,7380,22146,9.50,3.85,13.86,8.06,3.41,12.51,29.37,247.9 +6,590,7630,22966,9.86,3.90,14.36,8.38,3.45,13.01,30.13,248.4 +6,590,7880,23786,10.24,3.84,14.78,8.59,3.68,13.06,30.60,249.4 +6,590,8130,24606,10.68,3.84,15.26,8.83,3.64,13.61,31.30,250.2 +6,590,8380,25427,11.14,3.91,15.78,9.09,4.33,13.98,32.33,250.7 +7,584,630,0,-0.24,0.43,3.88,2.91,0.79,3.21,8.95,151.0 +7,584,880,820,1.67,3.18,4.99,2.92,1.04,4.45,9.99,207.7 +7,584,1130,1640,2.14,2.93,5.26,3.11,1.01,4.78,10.65,216.2 +7,584,1380,2461,2.25,2.89,5.41,3.12,1.07,4.99,10.95,217.8 +7,584,1630,3281,2.26,3.13,5.49,3.10,1.02,5.22,10.85,215.9 +7,584,1880,4101,2.16,3.37,5.42,3.03,1.03,5.42,10.68,212.7 +7,584,2130,4921,2.00,3.56,5.42,3.05,1.09,5.03,10.82,209.3 +7,584,2380,5741,1.87,3.69,5.40,3.04,1.18,5.06,10.84,206.8 +7,584,2630,6562,1.69,3.85,5.54,3.15,1.13,5.15,11.17,203.7 +7,584,2880,7382,1.56,3.87,5.66,3.23,1.33,5.09,11.40,201.9 +7,584,3130,8202,1.45,3.87,5.86,3.29,1.34,5.42,11.81,200.6 +7,584,3380,9022,1.39,3.85,5.98,3.27,1.37,5.54,11.61,199.9 +7,584,3630,9843,1.28,3.82,6.07,3.28,1.52,5.64,11.98,198.5 +7,584,3880,10663,1.30,3.79,6.22,3.38,1.56,5.87,12.61,198.9 +7,584,4130,11483,1.33,3.81,6.44,3.47,1.69,6.05,13.20,199.2 +7,584,4380,12303,1.46,3.85,6.66,3.57,1.53,6.39,12.91,200.8 +7,584,4630,13123,1.62,3.88,6.92,3.70,1.66,6.65,13.84,202.7 +7,584,4880,13944,1.64,3.86,7.06,3.83,1.61,6.65,13.93,203.0 +7,584,5130,14764,1.71,3.81,7.18,3.89,1.68,6.77,14.36,204.2 +7,584,5380,15584,1.84,3.79,7.25,3.97,1.71,6.87,14.46,205.9 +7,584,5630,16404,1.99,3.63,7.26,4.05,1.56,6.82,14.50,208.7 +7,584,5880,17224,2.14,3.53,7.43,4.09,1.52,6.98,14.60,211.3 +7,584,6130,18045,2.43,3.47,7.56,4.13,1.82,7.03,15.52,215.0 +7,584,6380,18865,2.67,3.44,7.67,4.19,1.76,7.11,15.53,217.8 +7,584,6630,19685,2.95,3.41,7.80,4.30,1.74,7.08,15.49,220.8 +7,584,6880,20505,3.24,3.44,8.00,4.36,2.09,7.26,16.00,223.3 +7,584,7130,21325,3.52,3.50,8.22,4.46,2.16,7.51,16.38,225.1 +7,584,7380,22146,3.86,3.55,8.59,4.59,2.29,8.17,17.28,227.4 +7,584,7630,22966,4.19,3.65,8.99,4.71,2.11,8.56,17.77,229.0 +7,584,7880,23786,4.52,3.81,9.33,4.78,2.64,8.75,18.37,229.8 +7,584,8130,24606,4.88,3.93,9.68,4.93,2.80,9.11,19.02,231.1 +7,584,8380,25427,5.20,4.16,10.05,5.11,3.10,9.50,19.09,231.3 +8,636,630,0,-0.09,0.58,3.73,2.86,0.76,3.19,8.48,171.5 +8,636,880,820,1.48,2.95,5.03,3.08,0.97,4.52,10.81,206.6 +8,636,1130,1640,1.96,2.83,5.28,3.25,0.83,5.01,10.74,214.7 +8,636,1380,2461,2.14,2.79,5.38,3.22,1.02,5.00,11.15,217.5 +8,636,1630,3281,2.21,2.93,5.41,3.22,1.05,4.89,11.23,217.1 +8,636,1880,4101,2.19,3.21,5.34,3.32,0.93,4.88,11.63,214.3 +8,636,2130,4921,2.15,3.47,5.38,3.37,1.03,4.76,11.58,211.8 +8,636,2380,5741,2.09,3.66,5.50,3.42,1.17,4.81,11.53,209.7 +8,636,2630,6562,1.98,3.82,5.73,3.49,1.23,5.12,11.71,207.4 +8,636,2880,7382,1.89,3.88,5.96,3.54,1.45,5.40,11.98,206.0 +8,636,3130,8202,1.78,3.97,6.26,3.61,1.49,5.67,12.20,204.1 +8,636,3380,9022,1.74,3.95,6.36,3.73,1.41,5.97,12.48,203.8 +8,636,3630,9843,1.68,3.91,6.53,3.81,1.64,5.90,12.93,203.2 +8,636,3880,10663,1.63,3.82,6.68,3.87,1.81,6.03,13.35,203.1 +8,636,4130,11483,1.66,3.79,6.98,3.98,1.99,6.39,14.20,203.7 +8,636,4380,12303,1.70,3.79,7.22,4.22,1.84,6.67,14.64,204.1 +8,636,4630,13123,1.79,3.88,7.46,4.39,1.87,6.84,15.11,204.7 +8,636,4880,13944,1.90,3.94,7.65,4.57,1.99,7.06,15.50,205.7 +8,636,5130,14764,2.07,3.89,7.76,4.68,1.71,7.03,15.66,208.0 +8,636,5380,15584,2.25,3.80,7.80,4.76,1.81,6.89,15.97,210.6 +8,636,5630,16404,2.57,3.67,7.96,4.79,1.82,7.06,16.45,215.0 +8,636,5880,17224,2.89,3.65,8.24,4.87,2.02,7.55,16.93,218.3 +8,636,6130,18045,3.27,3.61,8.35,4.92,1.98,7.67,17.26,222.2 +8,636,6380,18865,3.60,3.63,8.49,5.05,2.08,7.62,18.47,224.7 +8,636,6630,19685,3.90,3.60,8.71,5.20,2.12,7.74,18.83,227.3 +8,636,6880,20505,4.25,3.65,9.03,5.40,2.01,8.12,18.88,229.3 +8,636,7130,21325,4.61,3.72,9.43,5.57,1.96,8.48,19.57,231.1 +8,636,7380,22146,4.97,3.88,9.82,5.83,1.99,8.72,20.85,232.0 +8,636,7630,22966,5.30,4.00,10.25,6.02,2.28,9.11,21.59,233.0 +8,636,7880,23786,5.73,4.15,10.61,6.28,2.22,9.70,22.22,234.1 +8,636,8130,24606,6.18,4.34,11.09,6.52,2.36,10.08,22.77,235.0 +8,636,8380,25427,6.64,4.60,11.57,6.79,2.62,10.41,24.01,235.3 +9,597,630,0,0.05,0.41,4.06,3.49,1.05,3.22,9.49,187.3 +9,597,880,820,0.89,1.75,4.61,3.25,0.94,3.69,11.17,207.0 +9,597,1130,1640,1.10,1.52,5.08,3.56,1.00,4.19,11.93,216.0 +9,597,1380,2461,1.29,1.53,5.42,3.69,1.11,4.70,12.31,220.1 +9,597,1630,3281,1.39,1.77,5.52,3.75,1.04,4.84,12.72,218.1 +9,597,1880,4101,1.40,2.05,5.58,3.73,1.08,4.84,12.77,214.3 +9,597,2130,4921,1.39,2.36,5.74,3.72,1.38,4.84,12.98,210.5 +9,597,2380,5741,1.42,2.64,5.95,3.79,1.52,4.95,13.57,208.4 +9,597,2630,6562,1.54,2.86,6.19,3.90,1.66,5.12,14.51,208.4 +9,597,2880,7382,1.59,3.08,6.54,3.96,1.78,5.67,14.75,207.3 +9,597,3130,8202,1.66,3.22,6.89,4.07,1.70,6.18,15.09,207.3 +9,597,3380,9022,1.81,3.23,7.12,4.19,1.75,6.37,15.60,209.2 +9,597,3630,9843,2.04,3.31,7.45,4.41,1.98,6.58,16.06,211.6 +9,597,3880,10663,2.29,3.30,7.82,4.60,1.87,6.88,16.99,214.8 +9,597,4130,11483,2.62,3.29,8.22,4.83,2.16,7.22,17.95,218.5 +9,597,4380,12303,3.01,3.37,8.65,5.13,1.98,7.68,18.58,221.8 +9,597,4630,13123,3.31,3.34,9.03,5.44,2.13,8.04,19.47,224.8 +9,597,4880,13944,3.68,3.36,9.49,5.74,2.43,8.48,20.42,227.6 +9,597,5130,14764,4.08,3.29,9.89,5.99,2.56,8.74,20.94,231.1 +9,597,5380,15584,4.47,3.26,10.27,6.35,2.42,8.95,22.65,233.8 +9,597,5630,16404,4.92,3.14,10.73,6.59,2.64,9.47,23.39,237.4 +9,597,5880,17224,5.39,3.06,11.21,6.91,2.51,9.88,25.11,240.4 +9,597,6130,18045,5.80,3.03,11.55,7.12,2.67,10.02,26.39,242.4 +9,597,6380,18865,6.23,3.06,12.01,7.31,3.09,10.46,27.31,243.8 +9,597,6630,19685,6.63,3.07,12.51,7.55,3.11,10.79,28.36,245.2 +9,597,6880,20505,7.04,2.99,12.97,7.78,3.08,11.20,28.74,247.0 +9,597,7130,21325,7.51,2.94,13.50,8.01,3.50,11.72,29.80,248.6 +9,597,7380,22146,7.94,2.89,14.05,8.27,3.73,12.22,30.63,250.0 +9,597,7630,22966,8.38,2.86,14.59,8.56,3.82,12.83,31.51,251.1 +9,597,7880,23786,8.83,3.00,15.07,8.86,4.16,13.07,32.00,251.2 +9,597,8130,24606,9.30,3.10,15.53,9.15,4.18,13.66,33.99,251.5 +9,597,8380,25427,9.81,3.18,15.99,9.48,4.15,14.06,34.84,252.1 +10,616,630,0,0.18,0.07,3.75,4.58,0.69,2.93,8.63,247.6 +10,616,880,820,0.06,-0.19,4.09,3.41,0.61,2.85,11.05,342.2 +10,616,1130,1640,0.37,-0.63,4.81,3.81,0.69,3.59,11.86,329.7 +10,616,1380,2461,0.71,-0.73,5.47,3.95,0.89,4.44,12.59,316.1 +10,616,1630,3281,0.98,-0.64,5.79,3.83,1.01,4.84,12.91,302.9 +10,616,1880,4101,1.27,-0.46,6.04,3.85,1.33,5.20,13.62,289.9 +10,616,2130,4921,1.55,-0.21,6.46,4.04,1.54,5.75,14.48,277.6 +10,616,2380,5741,1.78,0.02,6.83,4.30,1.56,5.85,15.70,269.3 +10,616,2630,6562,1.97,0.17,7.19,4.56,1.90,6.28,16.38,265.2 +10,616,2880,7382,2.29,0.24,7.69,4.74,1.92,6.97,17.36,264.1 +10,616,3130,8202,2.78,0.25,8.24,5.01,1.90,7.27,18.17,264.8 +10,616,3380,9022,3.33,0.16,8.68,5.27,2.09,7.63,18.53,267.3 +10,616,3630,9843,3.91,0.09,9.21,5.54,2.12,7.96,19.71,268.7 +10,616,3880,10663,4.58,-0.07,9.79,5.86,2.60,8.48,21.12,270.9 +10,616,4130,11483,5.19,-0.27,10.32,6.35,2.44,8.96,23.20,273.0 +10,616,4380,12303,5.84,-0.46,10.88,6.84,2.50,9.49,24.47,274.5 +10,616,4630,13123,6.47,-0.62,11.49,7.27,2.58,9.94,26.15,275.5 +10,616,4880,13944,7.06,-0.66,12.13,7.68,2.43,10.48,27.88,275.4 +10,616,5130,14764,7.64,-0.64,12.74,8.11,2.75,11.00,29.36,274.8 +10,616,5380,15584,8.18,-0.60,13.31,8.42,2.82,11.52,30.58,274.2 +10,616,5630,16404,8.65,-0.69,13.83,8.76,3.02,11.88,31.51,274.6 +10,616,5880,17224,9.05,-0.78,14.36,9.05,3.16,12.59,32.45,274.9 +10,616,6130,18045,9.56,-0.90,14.97,9.40,3.25,12.89,33.19,275.4 +10,616,6380,18865,10.09,-0.95,15.60,9.66,3.47,13.42,34.18,275.4 +10,616,6630,19685,10.58,-0.89,16.16,9.91,3.29,14.00,35.15,274.8 +10,616,6880,20505,11.07,-0.83,16.70,10.21,3.32,14.71,36.25,274.3 +10,616,7130,21325,11.48,-0.79,17.23,10.52,3.34,15.21,37.60,273.9 +10,616,7380,22146,11.92,-0.75,17.85,10.78,3.38,15.65,38.10,273.6 +10,616,7630,22966,12.31,-0.75,18.42,11.00,3.88,16.47,38.64,273.5 +10,616,7880,23786,12.71,-0.72,18.93,11.31,4.35,16.83,39.72,273.2 +10,616,8130,24606,13.16,-0.72,19.47,11.58,4.63,17.28,40.81,273.1 +10,616,8380,25427,13.60,-0.73,20.02,11.78,4.77,17.86,41.47,273.1 +11,598,630,0,0.32,0.10,3.18,2.40,0.60,2.66,7.48,253.1 +11,598,880,820,0.07,-0.57,3.64,3.28,0.60,2.44,10.51,352.9 +11,598,1130,1640,0.31,-1.10,4.60,3.74,0.70,3.36,11.79,344.2 +11,598,1380,2461,0.66,-1.07,5.59,3.84,1.17,4.64,12.84,328.5 +11,598,1630,3281,1.10,-0.97,6.29,3.82,1.62,5.66,13.90,311.4 +11,598,1880,4101,1.52,-0.71,6.65,3.84,1.52,6.06,13.72,295.0 +11,598,2130,4921,1.88,-0.41,7.05,4.05,1.79,6.49,14.59,282.2 +11,598,2380,5741,2.30,-0.19,7.51,4.36,1.81,7.09,15.56,274.8 +11,598,2630,6562,2.92,-0.06,8.03,4.85,1.85,7.38,16.59,271.3 +11,598,2880,7382,3.44,-0.03,8.62,5.25,1.68,7.86,18.16,270.5 +11,598,3130,8202,4.00,-0.16,9.28,5.62,1.83,8.49,19.34,272.3 +11,598,3380,9022,4.64,-0.32,9.85,5.99,1.91,8.82,20.85,274.0 +11,598,3630,9843,5.26,-0.47,10.43,6.42,2.14,9.77,22.13,275.1 +11,598,3880,10663,5.84,-0.63,11.07,6.75,2.49,10.41,23.83,276.1 +11,598,4130,11483,6.41,-0.76,11.73,7.12,2.74,10.72,25.29,276.8 +11,598,4380,12303,7.01,-0.91,12.41,7.55,2.58,11.54,26.59,277.4 +11,598,4630,13123,7.67,-1.06,13.22,8.03,2.85,12.41,28.23,277.8 +11,598,4880,13944,8.23,-1.18,14.00,8.50,3.01,13.00,29.71,278.1 +11,598,5130,14764,8.76,-1.25,14.67,8.89,3.20,13.44,31.38,278.1 +11,598,5380,15584,9.32,-1.30,15.37,9.33,3.45,14.15,33.58,278.0 +11,598,5630,16404,9.93,-1.42,16.09,9.71,3.56,14.79,34.75,278.1 +11,598,5880,17224,10.57,-1.52,16.84,10.02,3.80,15.49,36.26,278.2 +11,598,6130,18045,11.13,-1.56,17.49,10.33,3.99,16.10,37.85,278.0 +11,598,6380,18865,11.69,-1.63,18.24,10.70,4.20,16.88,38.11,278.0 +11,598,6630,19685,12.31,-1.73,19.02,11.09,4.60,17.64,39.17,278.0 +11,598,6880,20505,12.83,-1.79,19.72,11.46,4.82,17.95,40.61,277.9 +11,598,7130,21325,13.40,-1.82,20.45,11.80,4.77,18.79,41.96,277.8 +11,598,7380,22146,13.91,-1.81,21.06,12.12,4.76,19.49,43.21,277.4 +11,598,7630,22966,14.42,-1.76,21.76,12.26,4.67,20.23,44.56,277.0 +11,598,7880,23786,14.99,-1.69,22.48,12.50,5.27,21.02,45.99,276.4 +11,598,8130,24606,15.50,-1.71,23.18,12.78,5.99,21.41,47.32,276.3 +11,598,8380,25427,15.99,-1.75,23.85,13.10,6.44,22.00,48.33,276.2 +12,614,630,0,0.21,-0.04,2.77,2.61,0.40,2.36,5.91,280.7 +12,614,880,820,-0.21,-0.77,3.12,3.08,0.44,1.95,9.63,15.5 +12,614,1130,1640,0.02,-1.36,4.14,3.60,0.58,2.95,11.44,359.4 +12,614,1380,2461,0.36,-1.59,5.39,3.73,0.92,4.66,12.39,347.3 +12,614,1630,3281,0.98,-1.56,6.31,3.86,1.37,5.89,12.99,327.9 +12,614,1880,4101,1.62,-1.29,6.84,3.99,1.38,6.16,13.88,308.5 +12,614,2130,4921,2.26,-1.00,7.38,4.23,1.64,6.84,15.52,293.7 +12,614,2380,5741,2.87,-0.67,8.06,4.59,1.69,7.65,16.97,283.2 +12,614,2630,6562,3.43,-0.54,8.79,5.03,2.13,8.11,18.59,279.0 +12,614,2880,7382,4.05,-0.68,9.45,5.34,2.23,8.70,19.66,279.5 +12,614,3130,8202,4.76,-0.93,10.18,5.71,2.67,9.38,20.77,281.1 +12,614,3380,9022,5.43,-1.17,10.82,5.96,2.54,10.21,21.66,282.2 +12,614,3630,9843,6.04,-1.41,11.49,6.24,2.98,10.78,22.53,283.2 +12,614,3880,10663,6.73,-1.66,12.31,6.66,2.77,11.57,24.46,283.9 +12,614,4130,11483,7.46,-1.93,13.23,6.99,3.36,12.32,26.07,284.5 +12,614,4380,12303,8.21,-2.21,14.08,7.41,3.14,13.10,27.70,285.1 +12,614,4630,13123,8.97,-2.42,15.00,7.88,3.63,13.88,29.21,285.1 +12,614,4880,13944,9.69,-2.60,15.85,8.28,3.82,14.79,31.20,285.0 +12,614,5130,14764,10.32,-2.63,16.58,8.62,4.29,15.52,32.60,284.3 +12,614,5380,15584,11.00,-2.68,17.37,8.94,4.53,16.21,33.75,283.7 +12,614,5630,16404,11.64,-2.74,18.20,9.33,4.73,16.91,35.05,283.2 +12,614,5880,17224,12.32,-2.87,18.98,9.77,5.00,17.79,36.87,283.1 +12,614,6130,18045,12.86,-3.00,19.72,10.23,5.22,18.34,38.05,283.1 +12,614,6380,18865,13.44,-3.10,20.50,10.64,5.18,19.59,39.11,283.0 +12,614,6630,19685,14.02,-3.15,21.30,11.03,5.29,20.31,41.37,282.6 +12,614,6880,20505,14.60,-3.24,22.06,11.36,5.62,20.87,41.55,282.5 +12,614,7130,21325,15.11,-3.28,22.73,11.71,5.59,21.63,42.64,282.2 +12,614,7380,22146,15.69,-3.31,23.51,12.13,5.54,22.66,45.15,281.9 +12,614,7630,22966,16.24,-3.39,24.30,12.50,5.62,23.53,46.69,281.8 +12,614,7880,23786,16.80,-3.44,25.06,12.85,5.34,24.04,47.21,281.6 +12,614,8130,24606,17.30,-3.44,25.82,13.18,5.35,24.63,48.31,281.2 +12,614,8380,25427,17.85,-3.50,26.59,13.47,5.53,25.79,49.39,281.1 diff --git a/recovery-calculator/site-climatology/export_json.py b/recovery-calculator/site-climatology/export_json.py index f3d86f1d0..9067c6a56 100644 --- a/recovery-calculator/site-climatology/export_json.py +++ b/recovery-calculator/site-climatology/export_json.py @@ -165,7 +165,7 @@ def upper_block(): of repeated 48 times. """ grid = temp_profile.height_grid() - datasets, profile, lapse = [], {}, {} + datasets, profile, lapse, wind = [], {}, {}, {} for tag, label, members, pooled in DATASETS: prof_rows = load_csv("%s-tprofile-monthly.csv" % tag) @@ -212,7 +212,33 @@ def upper_block(): L_isa=f(r, "L_isa_k_per_km"), ) for r in lapse_rows] - return dict(grid_m=grid, datasets=datasets, profile=profile, lapse=lapse) + # Wind is optional per tag: it is generated by wind_profile.py, which is + # run separately from temp_profile.py, so a tag can have a temperature + # profile without a wind one yet. Same regrouping as the T profile -- + # one record per month with parallel arrays down the shared grid. + wind_rows = load_csv("%s-wprofile-monthly.csv" % tag) + if wind_rows is not None: + wmonths = {} + for r in wind_rows: + m = int(r["month"]) + rec = wmonths.setdefault(m, dict( + month=m, n=int(r["n_soundings"]), u=[], v=[], + spd=[], spd_p05=[], spd_p95=[], dir=[])) + rec["u"].append(f(r, "u_mean_ms")) + rec["v"].append(f(r, "v_mean_ms")) + rec["spd"].append(f(r, "spd_mean_ms")) + rec["spd_p05"].append(f(r, "spd_p05_ms")) + rec["spd_p95"].append(f(r, "spd_p95_ms")) + rec["dir"].append(f(r, "dir_mean_deg")) + bad = [m for m, rec in wmonths.items() if len(rec["u"]) != len(grid)] + if bad: + raise SystemExit( + "%s: wind months %s do not match the %d-level grid; " + "regenerate with wind_profile.py." % (tag, bad, len(grid))) + wind[tag] = [wmonths[m] for m in sorted(wmonths)] + + return dict(grid_m=grid, datasets=datasets, profile=profile, lapse=lapse, + wind=wind) def soundings_block(years, sample): diff --git a/recovery-calculator/site-climatology/igra.py b/recovery-calculator/site-climatology/igra.py index ae1574ef0..342a37e21 100644 --- a/recovery-calculator/site-climatology/igra.py +++ b/recovery-calculator/site-climatology/igra.py @@ -44,14 +44,26 @@ class Level: - __slots__ = ("p", "t", "gph", "is_surface", "z") + __slots__ = ("p", "t", "gph", "is_surface", "z", "wdir", "wspd", "u", "v") - def __init__(self, p, t, gph, is_surface): + def __init__(self, p, t, gph, is_surface, wdir=None, wspd=None): self.p = p # Pa self.t = t # K, or None self.gph = gph # m, reported geopotential height, or None self.is_surface = is_surface self.z = None # m, our hydrostatic height (see build_heights) + self.wdir = wdir # deg the wind blows FROM, or None + self.wspd = wspd # m/s, or None + # East/north components, meteorological convention (wind FROM wdir), so + # the vector points where the air -- and a drifting canopy -- travels. + # Kept in step with physics/wind.py's uv_from_speed_dir. + if wdir is not None and wspd is not None: + r = math.radians(wdir) + self.u = -wspd * math.sin(r) # east + self.v = -wspd * math.cos(r) # north + else: + self.u = None + self.v = None class Sounding: @@ -157,6 +169,8 @@ def parse(stream, since=None, until=None, p_floor=0.0): p = _int(line[9:15]) # spec 10-15, Pa gph = _int(line[16:21]) # spec 17-21, m t = _int(line[22:27]) # spec 23-27, tenths of degC + wdir = _int(line[40:45]) # spec 41-45, degrees + wspd = _int(line[46:51]) # spec 47-51, tenths of m/s if p is None or p < p_floor: continue cur.levels.append(Level( @@ -164,6 +178,8 @@ def parse(stream, since=None, until=None, p_floor=0.0): t=None if t is None else t / 10.0 + 273.15, gph=None if gph is None else float(gph), is_surface=(lvltyp2 == "1"), + wdir=None if wdir is None else float(wdir), + wspd=None if wspd is None else wspd / 10.0, )) if cur is not None and keep and cur.levels: yield cur @@ -251,15 +267,18 @@ def gph_residual(levels): if l.z is not None and l.gph is not None] -def interp(levels, targets): - """Temperature at each target geopotential height, linear in height. +EXTRAP_M = 200.0 + - Returns None for a target outside the profile, except that up to - EXTRAP_M below the lowest level it extrapolates on the lowest layer's own - lapse rate -- the pad sits ~90 m under Edwards and refusing to answer for - the bottom 90 m of a 7.6 km profile would be pedantry. +def _interp_series(levels, targets, get): + """`get(level)` at each target height, linear in height. + + Returns None for a target outside the profile, except that up to EXTRAP_M + below the lowest level it extrapolates on the lowest layer's own slope -- + the pad sits ~90 m under Edwards and refusing to answer for the bottom 90 m + of a 7.6 km profile would be pedantry. `levels` must already be sorted + ascending by `z` and carry a non-None value at `get`. """ - EXTRAP_M = 200.0 if len(levels) < 2: return [None] * len(targets) out = [] @@ -269,8 +288,8 @@ def interp(levels, targets): out.append(None) continue a, b = levels[0], levels[1] - lapse = (b.t - a.t) / (b.z - a.z) - out.append(a.t + lapse * (z - a.z)) + slope = (get(b) - get(a)) / (b.z - a.z) + out.append(get(a) + slope * (z - a.z)) continue if z > levels[-1].z: out.append(None) @@ -278,10 +297,32 @@ def interp(levels, targets): for a, b in zip(levels, levels[1:]): if a.z <= z <= b.z: if b.z == a.z: - out.append(a.t) + out.append(get(a)) else: - out.append(a.t + (b.t - a.t) * (z - a.z) / (b.z - a.z)) + out.append(get(a) + (get(b) - get(a)) * (z - a.z) / (b.z - a.z)) break else: out.append(None) return out + + +def interp(levels, targets): + """Temperature at each target geopotential height, linear in height.""" + return _interp_series(levels, targets, lambda l: l.t) + + +def interp_wind(levels, targets): + """(u_east, v_north) m/s at each target height, linear in height. + + Interpolates the two components independently -- the correct thing to do, + since interpolating speed and direction would swing the vector the long way + round a backing wind. `levels` comes from `build_heights` (so it carries + `z`); levels lacking a wind observation are filtered out first, which is why + a profile can cover the temperature grid yet return None for wind where the + radiosonde reported no wind. Returns a list of (u, v) tuples, (None, None) + outside the wind-reporting band. + """ + w = [l for l in levels if l.u is not None and l.v is not None] + us = _interp_series(w, targets, lambda l: l.u) + vs = _interp_series(w, targets, lambda l: l.v) + return list(zip(us, vs)) diff --git a/recovery-calculator/site-climatology/test_site_climatology.py b/recovery-calculator/site-climatology/test_site_climatology.py index 822e085a1..7431e015a 100644 --- a/recovery-calculator/site-climatology/test_site_climatology.py +++ b/recovery-calculator/site-climatology/test_site_climatology.py @@ -79,6 +79,18 @@ def check_eq(name, got, want): floored = list(igra.parse(io.StringIO(IGRA_SAMPLE), p_floor=85000.0)) check_eq("p_floor drops levels above the ceiling", len(floored[0].levels), 4) +# Wind columns sit further right on the same fixed-width records (WDIR 41-45, +# WSPD 47-51 in tenths of m/s) -- one slice off by a column parses the neighbour. +check("surface wind direction, deg", l0.wdir, 240.0, 0.0) +check("surface wind speed, tenths m/s -> m/s", l0.wspd, 4.6, 1e-9) +check("925 hPa wind direction", l2.wdir, 275.0, 0.0) +check("925 hPa wind speed", l2.wspd, 4.6, 1e-9) +# A wind FROM 275 deg (near-westerly) blows toward the east: u positive, v small. +check_eq("westerly gives an eastward u component", l2.u > 0.0, True) +check("v component near zero for a near-westerly", l2.v, 0.0, 0.6) +check_eq("missing wind speed -> None", snds[0].levels[1].wspd, None) +check_eq("missing wind -> no u component", snds[0].levels[1].u, None) + # --- hydrostatic heights --------------------------------------------------- # Isothermal column: dZ = (Rd T / g0) ln(p1/p2) is exact, not an approximation, @@ -158,6 +170,29 @@ def iso_sounding(ratios): below, 300.0 - lapse * 100.0, 1e-9) +# --- wind interpolation ---------------------------------------------------- +# Components interpolate independently. Both legs blow from the west (270), so +# u = +speed and v = 0, and the midpoint speed is the average of the two. + +wind = igra.Sounding("TEST", 2020, 1, 1, 12) +wind.levels = [igra.Level(90000.0, 300.0, 1000.0, True, wdir=270.0, wspd=10.0), + igra.Level(70000.0, 280.0, 3000.0, False, wdir=270.0, wspd=20.0)] +ls = igra.build_heights(wind, station_elev=1000.0) +mid = 0.5 * (ls[0].z + ls[1].z) +u_mid, v_mid = igra.interp_wind(ls, [mid])[0] +check("interp_wind is linear in u at the midpoint", u_mid, 15.0, 1e-9) +check("interp_wind keeps v ~zero for a pure westerly", v_mid, 0.0, 1e-9) +check_eq("interp_wind refuses above the top level", + igra.interp_wind(ls, [ls[-1].z + 1.0])[0], (None, None)) + +# A profile whose levels carry temperature but no wind returns (None, None): +# the wind grid is independent of the temperature grid. +nowind = iso_sounding([1.0, 0.8, 0.6]) +ls = igra.build_heights(nowind, station_elev=1000.0) +check_eq("interp_wind is None where no wind was reported", + igra.interp_wind(ls, [ls[1].z])[0], (None, None)) + + # --- lapse fitting --------------------------------------------------------- grid = [sites.FAR_ELEV + 250.0 * i for i in range(31)] @@ -356,6 +391,45 @@ def check_range(name, rows, col, lo, hi): float(jan[0]["eq7_minus_measured_k"]), 0.0, 1e-9) +# --- committed wind products ----------------------------------------------- +# Same gate as the temperature profiles, on the wind CSVs wind_profile.py +# writes. nid alone is the sparsest tag (~22/month), so it sets the floor. + +WIND_TAGS = ("edw-nid", "vef", "nid") + +for tag in WIND_TAGS: + name = "%s-wprofile-monthly.csv" % tag + rows = load_csv(name) + check_eq("%s is non-empty" % name, len(rows) > 0, True) + check_eq("%s covers all 12 months" % name, + sorted({int(r["month"]) for r in rows}), list(range(1, 13))) + check_cols("%s-wprofile" % tag, rows, + ["month", "n_soundings", "H_msl_m", "H_agl_ft", + "u_mean_ms", "v_mean_ms", "spd_mean_ms", "spd_p05_ms", + "spd_p50_ms", "spd_p95_ms", "dir_mean_deg"]) + # Speed is a magnitude, so non-negative; 80 m/s covers the winter jet aloft + # with headroom. A negative or absurd value means a component/parse error. + check_range("%s-wprofile" % tag, rows, "spd_mean_ms", 0.0, 80.0) + check_range("%s-wprofile" % tag, rows, "spd_p95_ms", 0.0, 80.0) + check_range("%s-wprofile" % tag, rows, "dir_mean_deg", 0.0, 360.0) + check_eq("%s-wprofile speed quantiles are ordered" % tag, + [r["H_msl_m"] for r in rows + if not (float(r["spd_p05_ms"]) <= float(r["spd_p50_ms"]) + <= float(r["spd_p95_ms"]))][:3], []) + check_eq("%s-wprofile mean speed dominates its components" % tag, + [r["H_msl_m"] for r in rows + if float(r["spd_mean_ms"]) + 1e-6 + < math.hypot(float(r["u_mean_ms"]), float(r["v_mean_ms"]))][:3], []) + check_eq("%s-wprofile has enough soundings per month" % tag, + [r["month"] for r in rows if int(r["n_soundings"]) < 20], []) + jan = [r for r in rows if r["month"] == "1"] + hs = [float(r["H_msl_m"]) for r in jan] + check_eq("%s-wprofile heights ascend within a month" % tag, + hs == sorted(hs), True) + check_eq("%s-wprofile reaches the 25 kft AGL ceiling" % tag, + max(float(r["H_agl_ft"]) for r in jan) >= 25000.0, True) + + print() if FAILS: print("%d FAILED: %s" % (len(FAILS), ", ".join(FAILS))) diff --git a/recovery-calculator/site-climatology/wind_profile.py b/recovery-calculator/site-climatology/wind_profile.py new file mode 100644 index 000000000..9e5853b2b --- /dev/null +++ b/recovery-calculator/site-climatology/wind_profile.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python3 +"""Low-altitude wind climatology, pad to 25,000 ft AGL. PLAN.md §21. + +The sibling of `temp_profile.py`, on the same soundings and the same height +grid, answering the drift question instead of the density one: + + over the band the vehicle descends through, which way and how hard does the + wind blow each month, and how much does it vary day to day? + +Wind is stored as **u (east) / v (north) components** rather than speed and +direction, because that is what the drift model and RocketPy both consume, and +because components interpolate correctly where speed/direction would swing the +vector the long way round a backing wind. Per grid level and month we publish +the mean vector, the day-to-day speed quantiles (the p95 is the deterministic +"worst-case wind" the Drift tab offers), and the mean bearing the wind blows +from. + +IGRA reports wind direction (degrees the wind blows *from*) and speed; the +component conversion and the meteorological convention live in +`igra.Level`/`igra.interp_wind`, kept in step with `physics/wind.py`. + +Usage: + python3 wind_profile.py # Edwards+China Lake, 10 yr + python3 wind_profile.py --station VEF --years 10 +""" + +import argparse +import csv +import datetime as dt +import math +import os +import statistics +import sys + +import igra +import sites +from metar_history import MONTH, pct +from temp_profile import GRID_STEP, height_grid + +HERE = os.path.dirname(os.path.abspath(__file__)) +DATA = os.path.join(HERE, "data") + + +def profiles(stations, since, until, grid): + """One (u, v) vector pair per sounding, on the shared grid. + + Pools stations exactly as `temp_profile.profiles` does, and drops whole any + sounding that cannot supply wind at every grid level -- so each month's + quantiles down a column rest on the same set of ascents. A sounding may + cover the temperature grid yet miss wind (older or automated releases), + which is why this is filtered independently of the temperature pass. + """ + kept, dropped = [], 0 + per_station = {} + for station in stations: + st = sites.UPPER[station] + snds = igra.load(st.igra_id, since, until, p_floor=30000.0) + n = 0 + for s in snds: + ls = igra.build_heights(s, st.elev_m) + if len(ls) < 5: + dropped += 1 + continue + uv = igra.interp_wind(ls, grid) + if any(u is None or v is None for u, v in uv): + dropped += 1 + continue + us = [u for u, v in uv] + vs = [v for u, v in uv] + kept.append((s, us, vs)) + n += 1 + per_station[station] = n + return kept, dropped, per_station + + +def _dir_from(u_mean, v_mean): + """Bearing the mean wind blows *from*, degrees clockwise from north. + + The inverse of the component convention: the wind vector (u, v) points where + the air travels, so the direction it came from is that reversed. + """ + if u_mean == 0.0 and v_mean == 0.0: + return 0.0 + return math.degrees(math.atan2(-u_mean, -v_mean)) % 360.0 + + +def monthly(kept, grid): + """Per calendar month: u/v mean and speed quantiles at every grid height.""" + out = [] + for m in range(1, 13): + sel = [(us, vs) for s, us, vs in kept if s.month == m] + if not sel: + continue + rec = dict(month=m, n=len(sel), levels=[]) + for i, h in enumerate(grid): + us_col = [us[i] for us, vs in sel] + vs_col = [vs[i] for us, vs in sel] + spd_col = [math.hypot(u, v) for u, v in zip(us_col, vs_col)] + u_mean = statistics.fmean(us_col) + v_mean = statistics.fmean(vs_col) + rec["levels"].append(dict( + h=h, + u_mean=u_mean, v_mean=v_mean, + spd_mean=statistics.fmean(spd_col), + spd_sd=statistics.pstdev(spd_col) if len(spd_col) > 1 else 0.0, + spd_p05=pct(spd_col, 0.05), + spd_p50=pct(spd_col, 0.50), + spd_p95=pct(spd_col, 0.95), + dir_mean=_dir_from(u_mean, v_mean), + )) + out.append(rec) + return out + + +# --- output ---------------------------------------------------------------- + +COLUMNS = ["month", "n_soundings", "H_msl_m", "H_agl_ft", + "u_mean_ms", "v_mean_ms", "spd_mean_ms", "spd_sd_ms", + "spd_p05_ms", "spd_p50_ms", "spd_p95_ms", "dir_mean_deg"] + + +def write_csv(path, rows, grid): + with open(path, "w", newline="") as f: + w = csv.writer(f) + w.writerow(COLUMNS) + H_pad = grid[0] + for r in rows: + for lv in r["levels"]: + w.writerow([r["month"], r["n"], "%.0f" % lv["h"], + "%.0f" % ((lv["h"] - H_pad) / 0.3048), + "%.2f" % lv["u_mean"], "%.2f" % lv["v_mean"], + "%.2f" % lv["spd_mean"], "%.2f" % lv["spd_sd"], + "%.2f" % lv["spd_p05"], "%.2f" % lv["spd_p50"], + "%.2f" % lv["spd_p95"], "%.1f" % lv["dir_mean"]]) + + +def report(rows, grid, stations, dropped, since, until, per_station): + H_pad = grid[0] + print() + print("WIND PROFILE, %04d-%02d to %04d-%02d" + % (since[0], since[1], until[0], until[1])) + for s in stations: + st = sites.UPPER[s] + print(" %-4s %-16s %s %4d usable" + % (s, st.name, st.igra_id, per_station[s])) + print("grid %.0f-%.0f m MSL (0-%.0f ft AGL over a %.0f m pad), %.0f m steps" + % (grid[0], grid[-1], (grid[-1] - H_pad) / 0.3048, + sites.FAR_ELEV, GRID_STEP)) + print("%d soundings usable, %d dropped (burst low, gappy, or no wind)" + % (sum(r["n"] for r in rows), dropped)) + + show = [i for i, h in enumerate(grid) + if round((h - H_pad) / 0.3048) % 5000 < GRID_STEP / 0.3048] + + print() + print("MEAN WIND SPEED (m/s) BY MONTH AND ALTITUDE AGL") + print(" mon n " + "".join("%8.0fft" % ((grid[i] - H_pad) / 0.3048) + for i in show)) + print(" " + "-" * (11 + 10 * len(show))) + for r in rows: + print(" %-3s %4d " % (MONTH[r["month"]], r["n"]) + + "".join("%10.1f" % r["levels"][i]["spd_mean"] for i in show)) + + print() + print("WORST-CASE SPEED (p95, m/s) -- the Drift tab's strong-wind profile") + print(" mon " + "".join("%8.0fft" % ((grid[i] - H_pad) / 0.3048) + for i in show)) + print(" " + "-" * (11 + 10 * len(show))) + for r in rows: + print(" %-3s " % MONTH[r["month"]] + + "".join("%10.1f" % r["levels"][i]["spd_p95"] for i in show)) + + +def main(): + ap = argparse.ArgumentParser(description=__doc__.split("\n")[0]) + ap.add_argument("--station", default=",".join(sites.PRIMARY_UPPER), + help="comma-separated IGRA stations to pool: %s (default %s)" + % ("/".join(sorted(sites.UPPER)), + ",".join(sites.PRIMARY_UPPER))) + ap.add_argument("--years", type=int, default=10, + help="years of soundings to pool (default 10)") + ap.add_argument("--elev", type=float, default=sites.FAR_ELEV) + args = ap.parse_args() + + stations = [s.strip().upper() for s in args.station.split(",") if s.strip()] + unknown = [s for s in stations if s not in sites.UPPER] + if unknown: + raise SystemExit("unknown station(s): %s. Known: %s" + % (", ".join(unknown), ", ".join(sorted(sites.UPPER)))) + + today = dt.date.today() + until = (today.year, today.month) + since = (today.year - args.years, today.month) + + grid = height_grid(args.elev) + print("%s, pooling %d years" % ("+".join(stations), args.years), + file=sys.stderr) + kept, dropped, per_station = profiles(stations, since, until, grid) + if not kept: + raise SystemExit("no usable soundings in that window") + + rows = monthly(kept, grid) + os.makedirs(DATA, exist_ok=True) + tag = "-".join(s.lower() for s in stations) + write_csv(os.path.join(DATA, "%s-wprofile-monthly.csv" % tag), rows, grid) + report(rows, grid, stations, dropped, since, until, per_station) + print() + print("wrote data/%s-wprofile-monthly.csv" % tag) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/recovery-calculator/tests/test_api.py b/recovery-calculator/tests/test_api.py index 9b8f74e45..0f8bef907 100644 --- a/recovery-calculator/tests/test_api.py +++ b/recovery-calculator/tests/test_api.py @@ -875,3 +875,55 @@ def test_crosscheck_rejects_an_unrunnable_config(): bad = load_fixture() bad["devices"][0]["CdS"] = -1.0 assert client().post("/api/crosscheck", json=bad).status_code == 422 + + +# --- drift (PLAN.md §21) --------------------------------------------------- + + +def _drift_body(wind): + return {"config": load_fixture(), "wind": wind} + + +def test_drift_constant_wind_matches_speed_times_descent_time(): + with client() as c: + body = c.post("/api/drift", json=_drift_body( + {"kind": "constant", "speed": 8.0, "direction": 270.0})).json() + # A westerly blows toward the east: bearing 90, distance = speed*t. + assert abs(body["distance"] - 8.0 * body["descent_time"]) < 1e-3 + assert abs(body["bearing_deg"] - 90.0) < 1e-3 + assert body["landing"]["x"] > 0.0 + assert abs(body["landing"]["y"]) < 1e-3 + + +def test_drift_zero_wind_is_no_drift(): + with client() as c: + body = c.post("/api/drift", json=_drift_body( + {"kind": "constant", "speed": 0.0, "direction": 0.0})).json() + assert body["distance"] == 0.0 + + +def test_drift_track_is_time_ordered_and_starts_at_the_pad(): + with client() as c: + body = c.post("/api/drift", json=_drift_body( + {"kind": "constant", "speed": 5.0, "direction": 180.0})).json() + track = body["track"] + assert track[0]["x"] == 0.0 and track[0]["y"] == 0.0 + assert all(b["t"] >= a["t"] for a, b in zip(track, track[1:])) + # Wire contract for the ground-track plot. + assert set(track[0]) == {"t", "z", "x", "y"} + + +def test_drift_accepts_a_resolved_profile(): + prof = {"kind": "profile", + "heights_msl": [630.0, 1630.0, 4630.0], + "u": [3.0, 6.0, 12.0], "v": [0.0, 0.0, 0.0]} + with client() as c: + body = c.post("/api/drift", json=_drift_body(prof)).json() + assert body["distance"] > 0.0 + assert abs(body["bearing_deg"] - 90.0) < 1e-6 # all eastward + + +def test_drift_rejects_an_unrunnable_config(): + bad = _drift_body({"kind": "constant", "speed": 5.0, "direction": 0.0}) + bad["config"]["devices"][0]["CdS"] = -1.0 + assert client().post("/api/drift", json=bad).status_code == 422 diff --git a/recovery-calculator/tests/test_drift.py b/recovery-calculator/tests/test_drift.py new file mode 100644 index 000000000..7bdf589de --- /dev/null +++ b/recovery-calculator/tests/test_drift.py @@ -0,0 +1,69 @@ +"""Drift: zero-wind, the constant-wind identity, and altitude weighting.""" + +from physics.drift import compute_drift +from physics.schema import Config, Device, Site, Trigger, TriggerKind, Vehicle +from physics.solver import integrate +from physics.site import FAR_ELEV_M +from physics.wind import WindProfile + +# ISA temperature at the FAR pad, keeping the eq (7) re-fit the identity. +FAR_ISA_T = 284.1854 + + +def _run(h_a=3000.0): + """A drogue-then-main descent from `h_a`, so there is a fast high-altitude + phase and a slow low-altitude one -- which is what the weighting test needs. + """ + cfg = Config( + vehicle=Vehicle(m=5.67, h_a=h_a, d_body=0.1016, l_body=1.44), + site=Site(T_pad=FAR_ISA_T), + devices=[ + Device(name="drogue", CdS=0.3, D0=0.6, m_c=0.05, + trigger=Trigger(kind=TriggerKind.TIME, value=1.0)), + Device(name="main", CdS=6.0, D0=2.4, m_c=0.3, + trigger=Trigger(kind=TriggerKind.ALTITUDE, value=300.0)), + ], + ) + return integrate(cfg, "axial") + + +def test_zero_wind_gives_zero_drift(): + run = _run() + d = compute_drift(run, WindProfile.constant(0.0, 0.0)) + assert d.distance == 0.0 + assert abs(d.x[-1]) < 1e-12 and abs(d.y[-1]) < 1e-12 + + +def test_constant_wind_drift_equals_speed_times_descent_time(): + run = _run() + speed, direction = 7.0, 270.0 # a westerly, blowing toward the east + d = compute_drift(run, WindProfile.constant(speed, direction)) + # With a uniform wind the integral collapses to speed * descent_time, and + # the canopy heads the way the wind blows (east, bearing 90). + assert abs(d.distance - speed * run.t_ground) < 1e-6 + assert abs(d.bearing_deg - 90.0) < 1e-6 + # Drift is due east: +x, ~zero y. + assert d.x[-1] > 0.0 + assert abs(d.y[-1]) < 1e-6 + + +def test_low_altitude_wind_drifts_more_than_high_altitude_wind(): + run = _run() + # Same speed, placed in the bottom 300 m (under the slow main) vs the top, + # both zero elsewhere. The main dwells low, so the low wind wins. + low = WindProfile.from_grid( + [FAR_ELEV_M, FAR_ELEV_M + 300.0, FAR_ELEV_M + 400.0], + [5.0, 5.0, 0.0], [0.0, 0.0, 0.0]) + high = WindProfile.from_grid( + [FAR_ELEV_M + 2600.0, FAR_ELEV_M + 2700.0, FAR_ELEV_M + 3000.0], + [0.0, 5.0, 5.0], [0.0, 0.0, 0.0]) + d_low = compute_drift(run, low) + d_high = compute_drift(run, high) + assert d_low.distance > d_high.distance + + +def test_track_starts_at_pad_and_matches_trajectory_length(): + run = _run() + d = compute_drift(run, WindProfile.constant(5.0, 180.0)) + assert d.x[0] == 0.0 and d.y[0] == 0.0 + assert len(d.x) == len(run.traj.t) == len(d.z) diff --git a/recovery-calculator/tests/test_wind.py b/recovery-calculator/tests/test_wind.py new file mode 100644 index 000000000..76044cb43 --- /dev/null +++ b/recovery-calculator/tests/test_wind.py @@ -0,0 +1,98 @@ +"""WindProfile: the meteorological convention, interpolation, RocketPy shape.""" + +import math + +from physics.site import FAR_ELEV_M +from physics.wind import WindProfile, uv_from_speed_dir + + +# --- meteorological convention: direction is where wind blows FROM ---------- + + +def test_wind_from_north_blows_south(): + # A northerly (from 0 deg) pushes toward the south: v negative, u zero. + u, v = uv_from_speed_dir(10.0, 0.0) + assert abs(u) < 1e-12 + assert v == -10.0 + + +def test_wind_from_west_blows_east(): + # A westerly (from 270) pushes toward the east: u positive, v zero. + u, v = uv_from_speed_dir(10.0, 270.0) + assert u == 10.0 + assert abs(v) < 1e-12 + + +def test_wind_from_east_blows_west(): + u, v = uv_from_speed_dir(10.0, 90.0) + assert u == -10.0 + assert abs(v) < 1e-12 + + +# --- constant profile ------------------------------------------------------- + + +def test_constant_is_uniform_with_altitude(): + w = WindProfile.constant(8.0, 270.0) + for z in (0.0, 500.0, 3000.0): + assert w.u(z) == 8.0 + assert abs(w.v(z)) < 1e-12 + assert w.speed(z) == 8.0 + + +def test_constant_heading_is_direction_wind_travels(): + # From the west -> travels toward the east -> heading 90 deg. + w = WindProfile.constant(8.0, 270.0) + assert abs(w.heading(0.0) - 90.0) < 1e-9 + + +def test_calm_heading_is_zero_not_nan(): + w = WindProfile.constant(0.0, 123.0) + assert w.speed(0.0) == 0.0 + assert w.heading(0.0) == 0.0 + + +# --- tabulated profile: interpolation and clamping -------------------------- + + +def test_from_grid_interpolates_linearly_in_agl(): + # Heights are MSL; site_elev default is FAR (630 m), so AGL 0 and 1000 map + # to MSL 630 and 1630. u climbs 0 -> 10, v is flat. + w = WindProfile.from_grid([FAR_ELEV_M, FAR_ELEV_M + 1000.0], + [0.0, 10.0], [0.0, 0.0]) + assert abs(w.u(0.0) - 0.0) < 1e-9 + assert abs(w.u(500.0) - 5.0) < 1e-9 + assert abs(w.u(1000.0) - 10.0) < 1e-9 + + +def test_from_grid_holds_flat_outside_the_band(): + w = WindProfile.from_grid([FAR_ELEV_M, FAR_ELEV_M + 1000.0], + [2.0, 10.0], [0.0, 0.0]) + # Below the lowest level and above the highest: held, never extrapolated. + assert w.u(-100.0) == 2.0 + assert w.u(5000.0) == 10.0 + + +def test_unsorted_grid_is_accepted(): + w = WindProfile.from_grid([FAR_ELEV_M + 1000.0, FAR_ELEV_M], + [10.0, 0.0], [0.0, 0.0]) + assert abs(w.u(500.0) - 5.0) < 1e-9 + + +# --- RocketPy handoff ------------------------------------------------------- + + +def test_to_rocketpy_emits_height_value_points_in_msl(): + w = WindProfile.from_grid([FAR_ELEV_M + 1000.0, FAR_ELEV_M], + [10.0, 3.0], [-2.0, 1.0]) + wind_u, wind_v = w.to_rocketpy() + # Ascending MSL height, [height, value] pairs -- the custom_atmosphere form. + assert wind_u[0] == [FAR_ELEV_M, 3.0] + assert wind_u[1] == [FAR_ELEV_M + 1000.0, 10.0] + assert wind_v[0] == [FAR_ELEV_M, 1.0] + assert wind_v[1] == [FAR_ELEV_M + 1000.0, -2.0] + + +def test_speed_is_component_magnitude(): + w = WindProfile.from_grid([FAR_ELEV_M], [3.0], [4.0]) + assert abs(w.speed(0.0) - 5.0) < 1e-12 From 68828ab55f4b845f834c6a068ed0610d263496f6 Mon Sep 17 00:00:00 2001 From: Aidan Rickert Date: Thu, 13 Aug 2026 17:26:43 -0700 Subject: [PATCH 008/205] deploy: pin apps stack to STAR_IMAGE_TAG (sha-) image tag, default latest --- .env.example | 11 +++++++++++ deploy/apps/README.md | 21 ++++++++++++++++++++- docker-compose.yml | 28 +++++++++++++++++----------- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/.env.example b/.env.example index 64304de7f..c565ca948 100644 --- a/.env.example +++ b/.env.example @@ -31,6 +31,17 @@ AUTH_PUBLIC_URL=https://auth.starberkeley.org SCHEME=https ACME_EMAIL=infra@starberkeley.org +# ── Image version ────────────────────────────────────────────────────────── +# Which tag of the ghcr.io/calstar/star-* images the stack runs. CI publishes +# two tags on every push to main: `latest` (moving) and `sha-` (immutable, +# e.g. sha-abc1234). +# unset / latest → track the newest build on main (current default). +# sha- → pin the whole stack to one build; roll back by editing this +# one line and re-running `docker compose … up -d`. +# Pin to a sha that CI actually published (check the repo's GHCR packages, or the +# short hash of a commit that ran the publish workflow). See deploy/apps/README.md. +STAR_IMAGE_TAG=latest + # Only needed with `--profile tunnel`. From the Cloudflare Zero Trust # dashboard: Networks → Tunnels → your tunnel → install connector. # CLOUDFLARE_TUNNEL_TOKEN= diff --git a/deploy/apps/README.md b/deploy/apps/README.md index e8c97062c..bad7322d8 100644 --- a/deploy/apps/README.md +++ b/deploy/apps/README.md @@ -91,6 +91,23 @@ docker compose ps ``` (Building on the box instead — needs a full clone and ≥4 GB RAM for the React builds — is `docker compose --profile tunnel up -d --build`.) + +**Image version (`STAR_IMAGE_TAG`).** Every `star-*` image is pulled at the tag +`${STAR_IMAGE_TAG:-latest}`. CI publishes two tags on each push to `main`: +`latest` (moving) and an immutable `sha-` (e.g. `sha-abc1234`). +- **Default — `latest`:** leave `STAR_IMAGE_TAG` unset (or `=latest`). `pull` then + `up -d` moves the stack to the newest build. This is the current workflow. +- **Pinned — `sha-`:** set `STAR_IMAGE_TAG=sha-abc1234` in `.env` to lock the + whole stack to one build. `pull` + `up -d` fetches exactly that build; nothing + moves until you change the line. Roll back the same way — set an older `sha-…` + and `up -d`. + + Pin only to a sha CI actually published: `publish-apps.yml` builds *all* app + images together and `publish-auth.yml` builds auth, each on their own path + filters, so a given commit's `sha-…` exists for every image only if that commit + touched both an app path and `auth/`. Check the repo's GHCR **Packages** for the + tags that exist. `docker compose config --images` prints the exact tags Compose + will pull, so you can confirm the pin before `up -d`. Then drop the host's published web ports (cloudflared is the only ingress): remove the `80:80` / `443:443` lines from the `caddy` service, or block them at the firewall. SSH (22) is all you need inbound. @@ -170,4 +187,6 @@ own `…/releases/
@@ -377,9 +470,9 @@ export default function ConfigPage() {
)} - {!controlEnabled && ( + {!canEdit && (
- Viewer mode: configuration changes are disabled. Unlock controls in the top bar to enable saving. + Read-only — you are not an approved operator. Fields are disabled and saving/uploading is blocked (also enforced server-side).
)} @@ -402,54 +495,34 @@ export default function ConfigPage() {
- {/* Tab Content */} -
- {activeTab === 'system' && ( -
-

System

-
- {renderField( - 'Mode', - config.system?.mode, - (val) => updateField('system', 'mode', val), - 'select', - ['GROUND', 'FLIGHT'] - )} - {renderField( - 'Initial State', - config.system?.state, - (val) => updateField('system', 'state', val) - )} -
-
- )} - + {/* Tab Content — a disabled fieldset greys out and blocks every control + inside for non-operators (mirrors the server-side operator gate). */} +
{activeTab === 'network' && (
-

Network

+

Network

+

+ Read-only — these are startup-only binds for the pipeline services and must match the + board firmware. Changing them requires a deploy/restart, not a live edit. +

{renderField( 'Bind IP', config.network?.bind_ip, - (val) => updateField('network', 'bind_ip', val) + (val) => updateField('network', 'bind_ip', val), + 'text', undefined, 'DAQ bridge sensor-socket interface', true )} {renderField( 'Sensor Port', config.network?.sensor_port, (val) => updateField('network', 'sensor_port', val), - 'number' + 'number', undefined, 'UDP port boards send sensor data to', true )} {renderField( 'Actuator Command Port', config.network?.actuator_cmd_port, (val) => updateField('network', 'actuator_cmd_port', val), - 'number' - )} - {renderField( - 'Buffer Size', - config.network?.buffer_size, - (val) => updateField('network', 'buffer_size', val), - 'number' + 'number', undefined, 'Port boards listen on for actuator commands', true )}
@@ -718,7 +791,8 @@ export default function ConfigPage() {