-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Save basic stats in csv at each cycle (#1040)
### Work done Computes basic stats (count, bias and rmse of omb's and oma's) for different ocean basins, this assumes the obs were flagged with the ocean mask from `RECCAP2_region_masks_all_v20221025.nc`. - The stats are computed within the post ocean analysis jjob. Failure of this job will only results in a warning. - I provided a simple plotting script that will accept multiple experiments as arguments and plot time series. Not sure if we want this in the vrfy job ### Work left to do We're not flagging the obs currently, so that code will do nothing until we update the prep ocean obs yaml to point to `RECCAP2_region_masks_all_v20221025.nc` (it's been copied to the soca fix dir on hera and orion). To have the obs flagged in develop will require the ioda converters to not fail if the `RECCAP2_region_masks_all_v20221025` isn't found.
- Loading branch information
1 parent
6f7bd18
commit 420459c
Showing
6 changed files
with
406 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
time window: | ||
begin: '1900-01-01T00:00:00Z' | ||
end: '2035-01-01T00:00:00Z' | ||
bound to include: begin | ||
|
||
obs spaces: | ||
{{ obs_spaces }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#!/usr/bin/env python3 | ||
|
||
|
||
# creates figures of timeseries from the csv outputs computed by gdassoca_obsstats.x | ||
import argparse | ||
from itertools import product | ||
import os | ||
import glob | ||
import pandas as pd | ||
import matplotlib.pyplot as plt | ||
import matplotlib.dates as mdates | ||
|
||
|
||
class ObsStats: | ||
def __init__(self): | ||
self.data = pd.DataFrame() | ||
|
||
def read_csv(self, filepaths): | ||
# Iterate through the list of file paths and append their data | ||
for filepath in filepaths: | ||
new_data = pd.read_csv(filepath) | ||
# Convert date to datetime for easier plotting | ||
new_data['date'] = pd.to_datetime(new_data['date'], format='%Y%m%d%H') | ||
self.data = pd.concat([self.data, new_data], ignore_index=True) | ||
|
||
def plot_timeseries(self, ocean, variable): | ||
# Filter data for the given ocean and variable | ||
filtered_data = self.data[(self.data['Ocean'] == ocean) & (self.data['Variable'] == variable)] | ||
|
||
if filtered_data.empty: | ||
print("No data available for the given ocean and variable combination.") | ||
return | ||
|
||
# Get unique experiments | ||
experiments = filtered_data['Exp'].unique() | ||
|
||
# Plot settings | ||
fig, axs = plt.subplots(3, 1, figsize=(10, 15), sharex=True) | ||
fig.suptitle(f'{variable} statistics, {ocean} ocean', fontsize=16, fontweight='bold') | ||
|
||
for exp in experiments: | ||
exp_data = filtered_data[filtered_data['Exp'] == exp] | ||
|
||
# Plot RMSE | ||
axs[0].plot(exp_data['date'], exp_data['RMSE'], marker='o', linestyle='-', label=exp) | ||
axs[0].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H')) | ||
axs[0].xaxis.set_major_locator(mdates.DayLocator()) | ||
axs[0].tick_params(labelbottom=False) | ||
axs[0].set_ylabel('RMSE') | ||
axs[0].legend() | ||
axs[0].grid(True) | ||
|
||
# Plot Bias | ||
axs[1].plot(exp_data['date'], exp_data['Bias'], marker='o', linestyle='-', label=exp) | ||
axs[1].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H')) | ||
axs[1].xaxis.set_major_locator(mdates.DayLocator()) | ||
axs[1].tick_params(labelbottom=False) | ||
axs[1].set_ylabel('Bias') | ||
axs[1].legend() | ||
axs[1].grid(True) | ||
|
||
# Plot Count | ||
axs[2].plot(exp_data['date'], exp_data['Count'], marker='o', linestyle='-', label=exp) | ||
axs[2].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H')) | ||
axs[2].xaxis.set_major_locator(mdates.DayLocator()) | ||
axs[2].set_ylabel('Count') | ||
axs[2].legend() | ||
axs[2].grid(True) | ||
|
||
# Improve layout and show plot | ||
plt.tight_layout(rect=[0, 0.03, 1, 0.95]) | ||
plt.savefig(f'{ocean}_test.png') | ||
|
||
|
||
if __name__ == "__main__": | ||
epilog = ["Usage examples: ./gdassoca_obsstats.py --exp gdas.*.csv"] | ||
parser = argparse.ArgumentParser(description="Observation space RMSE's and BIAS's", | ||
formatter_class=argparse.RawDescriptionHelpFormatter, | ||
epilog=os.linesep.join(epilog)) | ||
parser.add_argument("--exps", nargs='+', required=True, | ||
help="Path to the experiment's COMROOT") | ||
parser.add_argument("--variable", required=True, help="ombg_qc or ombg_noqc") | ||
parser.add_argument("--figname", required=True, help="The name of the output figure") | ||
args = parser.parse_args() | ||
|
||
flist = [] | ||
for exp in args.exps: | ||
print(exp) | ||
wc = exp + '/*.*/??/analysis/ocean/*.t??z.stats.csv' | ||
flist.append(glob.glob(wc)) | ||
|
||
flist = sum(flist, []) | ||
obsStats = ObsStats() | ||
obsStats.read_csv(flist) | ||
for var, ocean in product(['ombg_noqc', 'ombg_qc'], | ||
['Atlantic', 'Pacific', 'Indian', 'Arctic', 'Southern']): | ||
obsStats.plot_timeseries(ocean, var) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include "gdassoca_obsstats.h" | ||
#include "oops/runs/Run.h" | ||
|
||
// this application computes a few basic statistics in obs space | ||
|
||
int main(int argc, char ** argv) { | ||
oops::Run run(argc, argv); | ||
gdasapp::ObsStats obsStats; | ||
return run.execute(obsStats); | ||
} |
Oops, something went wrong.