diff --git a/utils/soca/fig_gallery/gdassoca_obsstats.py b/utils/soca/fig_gallery/gdassoca_obsstats.py index 960dfbf79..00c60b971 100644 --- a/utils/soca/fig_gallery/gdassoca_obsstats.py +++ b/utils/soca/fig_gallery/gdassoca_obsstats.py @@ -7,24 +7,28 @@ import os import glob import pandas as pd +from jinja2 import Template import matplotlib.pyplot as plt import matplotlib.dates as mdates colors = [ "lightsteelblue", "lightgreen", + "peachpuff", "lightpink", - "lightsalmon", - "lightcoral", "lightgoldenrodyellow", "paleturquoise", + "lightcoral", "palegreen", "palegoldenrod", - "peachpuff", "mistyrose", "lavender" + "lightsalmon", ] +def get_inst(csv_file_name): + """Extract the instrument name from the csv file name. gdas.t00z.ocn.sst_ahi_h08_l3c.stats.csv -> sst_ahi_h08_l3c""" + return csv_file_name.split('.')[-3] class ObsStats: def __init__(self): @@ -41,17 +45,18 @@ def read_csv(self, filepaths): self.data.sort_values('date', inplace=True) def plot_timeseries(self, ocean, variable, inst="", dirout=""): + # 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 + return [] # Get unique experiments experiments = filtered_data['Exp'].unique() experiments.sort() print(experiments) - + # Plot settings fig, axs = plt.subplots(3, 1, figsize=(10, 15), sharex=True) fig.suptitle(f'{inst} {variable} statistics, {ocean} ocean', fontsize=18, fontweight='bold') @@ -88,10 +93,14 @@ def plot_timeseries(self, ocean, variable, inst="", dirout=""): axs[2].grid(True) exp_counter += 1 - + # Improve layout and show plot plt.tight_layout(rect=[0, 0.03, 1, 0.95]) plt.savefig(f'{dirout}/{inst}_{variable}_{ocean}.png') + # close the figure + plt.close(fig) + + return experiments if __name__ == "__main__": epilog = ["Usage examples: ./gdassoca_obsstats.py --exps cp1/COMROOT/cp1 cp2/COMROOT/cp2 --inst sst_abi_g16_l3c --dirout cp1vscp2"] @@ -100,21 +109,49 @@ def plot_timeseries(self, ocean, variable, inst="", dirout=""): epilog=os.linesep.join(epilog)) parser.add_argument("--exps", nargs='+', required=True, help="Path to the experiment's COMROOT") - parser.add_argument("--inst", required=True, help="The name of the instrument/platform (ex: sst_abi_g16_l3c)") + parser.add_argument("--inst", required=True, help="The name of the instrument/platform (ex: sst_abi_g16_l3c) or a wild card (eg sst*)") parser.add_argument("--dirout", required=True, help="Output directory") args = parser.parse_args() - flist = [] + insts = [] inst = args.inst os.makedirs(args.dirout, exist_ok=True) + # Get all instruments/obs spaces for exp in args.exps: wc = exp + f'/*.*/??/analysis/ocean/*{inst}*.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'], - ['Global', 'Atlantic', 'Pacific', 'Indian', 'Arctic', 'Southern']): - obsStats.plot_timeseries(ocean, var, inst=inst, dirout=args.dirout) + flist = glob.glob(wc) + for fname in flist: + insts.append(get_inst(fname)) + insts = list(set(insts)) + insts.sort() + print(insts) + + experiments = [] + for inst in insts: + print(f"Processing {inst}") + flist = [] + for exp in args.exps: + wc = exp + f'/*.*/??/analysis/ocean/*{inst}*.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'], + ['Global', 'Atlantic', 'Pacific', 'Indian', 'Arctic', 'Southern']): + experiments.extend(obsStats.plot_timeseries(ocean, var, inst=inst, dirout=args.dirout)) + + # Select unique elements of experiments + experiments = list(set(experiments)) + experiments.sort() + + # Create the html document from the jinja2 template + template_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'gdassoca_obsstats_template.html') + template = Template(open(template_path).read()) + context = {'insts': insts, 'experiments': experiments} + indexhtml = template.render(context) + + # Write the rendered HTML to a file + with open(f'{args.dirout}/index.html', 'w') as f: + f.write(indexhtml) diff --git a/utils/soca/fig_gallery/time_series_omb.html b/utils/soca/fig_gallery/gdassoca_obsstats_template.html similarity index 69% rename from utils/soca/fig_gallery/time_series_omb.html rename to utils/soca/fig_gallery/gdassoca_obsstats_template.html index c3c70eb75..ba717da0d 100644 --- a/utils/soca/fig_gallery/time_series_omb.html +++ b/utils/soca/fig_gallery/gdassoca_obsstats_template.html @@ -11,7 +11,7 @@ padding: 16px; } img { - width: 90%; + width: auto; height: auto; border: 1px solid #ccc; box-shadow: 2px 2px 6px #888888; @@ -24,14 +24,14 @@ color: white; border: none; border-radius: 5px; - font-size: 0.6em; /* Smaller font size */ + font-size: 1.0em; /* Smaller font size */ } .button:hover, .active { background-color: #0056b3; } select { padding: 3px 10px; /* Reduced padding */ - font-size: 0.4em; /* Smaller font size */ + font-size: 1.0em; /* Smaller font size */ border-radius: 5px; cursor: pointer; border: 1px solid #ccc; @@ -50,14 +50,17 @@ -
- - - +
+

+ Time Series of (Observation - Background) Statistics +

+

+ Experiments: {{ experiments|join(', ') }} +

- + @@ -67,18 +70,9 @@
@@ -97,15 +91,20 @@ function showImages(type, ocean) { currentOcean = ocean; - var basePath = document.getElementById('basePathInput').value; + var basePath = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1); updateActiveButton(ocean, 'button'); // Update active state for ocean buttons var container = document.getElementById('imageContainer'); - container.innerHTML = `