Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 53 additions & 16 deletions utils/soca/fig_gallery/gdassoca_obsstats.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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')
Expand Down Expand Up @@ -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"]
Expand All @@ -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)
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
padding: 16px;
}
img {
width: 90%;
width: auto;
height: auto;
border: 1px solid #ccc;
box-shadow: 2px 2px 6px #888888;
Expand All @@ -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;
Expand All @@ -50,14 +50,17 @@
</style>
</head>
<body>
<div>
<!-- Label and input for base path -->
<label for="basePathInput">Path to figures: </label>
<input type="text" id="basePathInput" placeholder="Enter base path for images" value="/path/to/figures/">
<div style="text-align: center; font-family: Arial, sans-serif; margin-top: 20px;">
<h1 style="color: #2c3e50; font-size: 1.5em; border-bottom: 2px solid #3498db; display: inline-block; padding-bottom: 5px;">
Time Series of (Observation - Background) Statistics
</h1>
<p style="margin-top: 15px; font-size: 1.4em; color: #34495e;">
Experiments: {{ experiments|join(', ') }}
</p>
</div>
<div>
<!-- Buttons for selecting oceans -->
<button class="button" id="Global" onclick="showImages(currentType, 'Global')">Global</button>
<button class="button" id="Global" onclick="showImages(currentType, 'Global')">Global</button>
<button class="button" id="Arctic" onclick="showImages(currentType, 'Arctic')">Arctic</button>
<button class="button" id="Atlantic" onclick="showImages(currentType, 'Atlantic')">Atlantic</button>
<button class="button" id="Indian" onclick="showImages(currentType, 'Indian')">Indian</button>
Expand All @@ -67,18 +70,9 @@
<div>
<!-- Dropdown for selecting type of observation -->
<select id="typeSelect" onchange="setType(this.value)">
<option value="adt_rads_all">ADT RADS All</option>
<option value="sst_abi_g16_l3c">SST ABI G16 L3C</option>
<option value="sst_abi_g17_l3c">SST ABI G17 L3C</option>
<option value="sst_ahi_h08_l3c">SST AHI H08 L3C</option>
<option value="sst_avhrr_ma_l3u">SST AVHRR MA L3C</option>
<option value="sst_avhrr_mb_l3u">SST AVHRR MB L3C</option>
<option value="sst_avhrr_mc_l3u">SST AVHRR MC L3C</option>
<option value="sst_viirs_n20_l3u">SST VIIRS N20 L3C</option>
<option value="sst_viirs_npp_l3u">SST VIIRS NPP L3C</option>
<option value="icec_amsr2_north">ICEC AMSR2 NORTH</option>
<option value="icec_amsr2_south">ICEC AMSR2 SOUTH</option>

{% for inst in insts %}
<option value="{{ inst }}">{{ inst }}</option>
{% endfor %}
</select>
</div>

Expand All @@ -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 = `<div class="gallery" style="display: grid;">
<img src="${basePath}${type}_ombg_noqc_${ocean}.png" alt="${ocean} No QC">
<img src="${basePath}${type}_ombg_qc_${ocean}.png" alt="${ocean} QC">

// Use grid layout for proper alignment
container.innerHTML = `
<div class="gallery" style="display: grid;">
<div class="image-wrapper" style="display: flex; justify-content: center; width: 100%;"><img src="${basePath}${type}_ombg_noqc_${ocean}.png" alt="${ocean} No QC" style="width: 100%;"></div>
<div class="image-wrapper" style="display: flex; justify-content: center; width: 100%;"><img src="${basePath}${type}_ombg_qc_${ocean}.png" alt="${ocean} QC" style="width: 100%;"></div>
</div>`;
document.querySelector('.gallery').style.display = 'grid'; // Ensure gallery is displayed as grid
}


function updateActiveButton(selectedId, buttonClass) {
var buttons = document.querySelectorAll('.' + buttonClass);
buttons.forEach(button => {
Expand Down