benchflow-ai/skillsbench/glm-output

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Read and process GLM output files. Use when you need to extract temperature data from NetCDF output, convert depth coordinates, or calculate RMSE against observations.

Install

npx vskill@latest install benchflow-ai/skillsbench/glm-output

SKILL.md

GLM Output Guide

Overview

GLM produces NetCDF output containing simulated water temperature profiles. Processing this output requires understanding the coordinate system and matching with observations.

Output File

After running GLM, results are in output/output.nc:

VariableDescriptionShape
timeHours since simulation start(n_times,)
zHeight from lake bottom (not depth!)(n_times, n_layers, 1, 1)
tempWater temperature (°C)(n_times, n_layers, 1, 1)

Reading Output with Python

python
from netCDF4 import Dataset
import numpy as np
import pandas as pd
from datetime import datetime
nc = Dataset('output/output.nc', 'r')
time = nc.variables['time'][:]
z = nc.variables['z'][:]
temp = nc.variables['temp'][:]
nc.close()

Coordinate Conversion

Important: GLM z is height from lake bottom, not depth from surface.

python
# Convert to depth from surface
# Set LAKE_DEPTH based on lake_depth in &init_profiles section of glm3.nml
LAKE_DEPTH = <lake_depth_from_nml>
depth_from_surface = LAKE_DEPTH - z

Complete Output Processing

python
from netCDF4 import Dataset
import numpy as np
import pandas as pd
from datetime import datetime
def read_glm_output(nc_path, lake_depth):
nc = Dataset(nc_path, 'r')
time = nc.variables['time'][:]
z = nc.variables['z'][:]
temp = nc.variables['temp'][:]
start_date = datetime(2009, 1, 1, 12, 0, 0)
records = []
for t_idx in range(len(time)):
hours = float(time[t_idx])
date = pd.Timestamp(start_date) + pd.Timedelta(hours=hours)
heights = z[t_idx, :, 0, 0]
temps = temp[t_idx, :, 0, 0]
for d_idx in range(len(heights)):
h_val = heights[d_idx]
t_val = temps[d_idx]
if not np.ma.is_masked(h_val) and not np.ma.is_masked(t_val):
depth = lake_depth - float(h_val)
if 0 <= depth <= lake_depth:
records.append({
'datetime': date,
'depth': round(depth),
'temp_sim': float(t_val)
})
nc.close()
df = pd.DataFrame(records)
df = df.groupby(['datetime', 'depth']).agg({'temp_sim': 'mean'}).reset_index()
return df

Reading Observations

python
def read_observations(obs_path):
df = pd.read_csv(obs_path)
df['datetime'] = pd.to_datetime(df['datetime'])
df['depth'] = df['depth'].round().astype(int)
df = df.rename(columns={'temp': 'temp_obs'})
return df[['datetime', 'depth', 'temp_obs']]

Calculating RMSE

python
def calculate_rmse(sim_df, obs_df):
merged = pd.merge(obs_df, sim_df, on=['datetime', 'depth'], how='inner')
if len(merged) == 0:
return 999.0
rmse = np.sqrt(np.mean((merged['temp_sim'] - merged['temp_obs'])**2))
return rmse
# Usage: get lake_depth from glm3.nml &init_profiles section
sim_df = read_glm_output('output/output.nc', lake_depth=25)
obs_df = read_observations('field_temp_oxy.csv')
rmse = calculate_rmse(sim_df, obs_df)
print(f"RMSE: {rmse:.2f}C")

Common Issues

IssueCauseSolution
RMSE very highWrong depth conversionUse lake_depth - z, not z directly
No matched observationsDatetime mismatchCheck datetime format consistency
Empty merged dataframeDepth rounding issuesRound depths to integers

Best Practices

  • Check lake_depth in &init_profiles section of glm3.nml
  • Always convert z to depth from surface before comparing with observations
  • Round depths to integers for matching
  • Group by datetime and depth to handle duplicate records
  • Check number of matched observations after merge

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
1,772
Repository forks
367
7-day trend score
37

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 14 Sep 2026, a month ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/benchflow-ai/skillsbench/glm-output/badge)](https://verified-skill.com/skills/benchflow-ai/skillsbench/glm-output)

Something wrong with this skill or its page? Tell us.