pikobs 3.0.332__tar.gz → 3.0.334__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pikobs-3.0.332 → pikobs-3.0.334}/CHANGELOG.md +8 -0
- {pikobs-3.0.332/pikobs.egg-info → pikobs-3.0.334}/PKG-INFO +1 -1
- pikobs-3.0.334/VERSION +1 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obstimedb/obstimedb.py +19 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obstimedb/obstimedb_plot.py +72 -24
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_obstimedb.sh +2 -2
- {pikobs-3.0.332 → pikobs-3.0.334/pikobs.egg-info}/PKG-INFO +1 -1
- pikobs-3.0.332/VERSION +0 -1
- {pikobs-3.0.332 → pikobs-3.0.334}/.gitignore +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/MANIFEST.in +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/README.md +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/clear.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/conda_build/pikobs/activate.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/conda_build/pikobs/build.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/conda_build/pikobs/meta.yaml +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/conda_build/pikobs/pikobs.yml +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/Makefile +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/make.bat +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/cardio.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/conf.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/families.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/flag.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/flags_criteria.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/histogram.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/index.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/mapobs.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/obscountdb.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/obstimedb.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/pikobsburp2rdb.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/profile.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/profile_ft.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/profile_ft2.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/projection.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/region.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/scatter.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/spatial.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/timeserie.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/unittest.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/varno.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/vdedr.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/docs/source/zone.rst +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/env/.mambarc +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/env/conda-meta/history +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/env/etc/aau_token +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/__not_used/plot_proj.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/__not_used/vdedr2.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/__not_used/vdedr3.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/cardio/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/cardio/cardio.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/cardio/cardio_plot.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/cardio/cardio_plot_old.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/delete_folder.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/families.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/familyobs.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/flags_criteria.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/regionsobs.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/special_family.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/type_boxes.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/type_projection.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/configobs/type_varno.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/extension/color_mapping.json +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/extension/libudfsqlite-shared.so +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/flags.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/flags_count.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/flags_plot.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/flags_plot0.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/flags_plot3.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/flags_plotv2.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/plotpo.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/plotpo2.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/plotpo3.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/plotpo4.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/plotpo5.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/plotpo7.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/plotpo8.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/flags/plotpo9.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/histogram/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/histogram/histogram.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/histogram/histogram_plot.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/mapobs/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/mapobs/color.j +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/mapobs/mapobs.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obscountdb/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obscountdb/obscountdb.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obscountdb/obscountdb_old.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obscountdb/obscountdb_plot.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obscutoff/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obscutoff/obscutoff.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obscutoff/obscutoff_plot.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/obstimedb/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/pbs_submit/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/pbs_submit/pbs_submit.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/pikobsburp2rdb/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/pikobsburp2rdb/pikobsburp2rdb.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/profile/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/profile/profile.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/profile/profile_plot.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/progps/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/progps/progps.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/progps2/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/progps2/progps2.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/scatter/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/scatter/scatter.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/remove.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/remove2.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_2exp.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_cardio.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_cardio_lco.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_cardio_sky.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_flag.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_histogra.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_mapobs.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_obscountdb.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_obscountdb_1.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_pikobsburp2rdb.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_profile.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_profile_1.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_profile_ra.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_profile_radar.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_profile_s.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_progps.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_progps2.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_scatter.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_scatter_diff.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_scatter_one.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_scatter_two_sw.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_spatial.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_timeserie.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_timeserie_radar.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_vdedr.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/run_zone2.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/setup_pikobs.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/script/setup_pikobs.sh.1 +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/spatial/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/spatial/spatial.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/timeserie/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/timeserie/timeserie.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/timeserie/timeserie_plot.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/unittestpikobs/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/unittestpikobs/test_pikobs.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/unittestpikobs/unittest_timeserie.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/vdedr/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/vdedr/vdedr.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/vdedr/vdedr_plot.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/web/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/web/viewer.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/zone/__init__.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/zone/zone.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs/zone/zone_plot.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs.egg-info/SOURCES.txt +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs.egg-info/dependency_links.txt +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs.egg-info/requires.txt +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs.egg-info/top_level.txt +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs_env.yml +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/pikobs_env2.yml +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/publique.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/publique.txt +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/readme/flag_criteria.md +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/readme/geographic.md +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/readme/read_projection.md +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/readme/readme_cardiograme.md +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/readme/readme_scatter.md +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/setup.cfg +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/setup.py +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/setup_pikobs.sh +0 -0
- {pikobs-3.0.332 → pikobs-3.0.334}/setup_pikobs.sh.1 +0 -0
pikobs-3.0.334/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.0.334
|
|
@@ -303,6 +303,24 @@ def create_table_if_not_exists(cursor: sqlite3.Cursor) -> None:
|
|
|
303
303
|
|
|
304
304
|
|
|
305
305
|
def combine(pathfileout: str, filememory: str) -> None:
|
|
306
|
+
# Made idempotent: DELETE any existing rows in the target for the
|
|
307
|
+
# SAME date(s) about to be inserted, before inserting. Without this,
|
|
308
|
+
# re-running the extraction for a date already in the accumulator
|
|
309
|
+
# (a retried/resumed job, or two separate --datestart/--dateend runs
|
|
310
|
+
# with an overlapping date range writing to the same output db)
|
|
311
|
+
# silently DUPLICATES that date's rows -- confirmed directly:
|
|
312
|
+
# extracting the same file twice into the same accumulator produced
|
|
313
|
+
# the SAME (date, id_stn) row twice, doubling every downstream sum
|
|
314
|
+
# for that date (and, since different runs can overlap different
|
|
315
|
+
# date spans by different amounts, this produces INCONSISTENT
|
|
316
|
+
# inflation across periods -- e.g. Today off by one factor, This
|
|
317
|
+
# week by another -- rather than one uniform, easy-to-spot scale
|
|
318
|
+
# error). This delete makes a re-run REPLACE that date's data
|
|
319
|
+
# instead of stacking a duplicate on top of it.
|
|
320
|
+
delete_sql = """
|
|
321
|
+
DELETE FROM moyenne
|
|
322
|
+
WHERE date IN (SELECT DISTINCT date FROM this_avg_db.moyenne);
|
|
323
|
+
"""
|
|
306
324
|
insert_sql = """
|
|
307
325
|
INSERT INTO moyenne (Nobsdata, Nobsprofile, avg_omp, avg_oma, id_stn, channel, date)
|
|
308
326
|
SELECT Nobsdata, Nobsprofile, avg_omp, avg_oma, id_stn, channel, date
|
|
@@ -315,6 +333,7 @@ def combine(pathfileout: str, filememory: str) -> None:
|
|
|
315
333
|
create_table_if_not_exists(conn)
|
|
316
334
|
|
|
317
335
|
conn.execute(f"ATTACH DATABASE '{filememory}' AS this_avg_db;")
|
|
336
|
+
conn.execute(delete_sql)
|
|
318
337
|
conn.execute(insert_sql)
|
|
319
338
|
conn.commit()
|
|
320
339
|
conn.execute("DETACH DATABASE this_avg_db;")
|
|
@@ -459,6 +459,11 @@ def _draw_profile_summary_table(df_all, run_time, name_in='experience'):
|
|
|
459
459
|
'DIFF_10DAY': _calc_pct_diff(at_run, tenday_avg),
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
+
# Grand-total row: FAMILY='ALL', ID_STN='ALL', summing across EVERY
|
|
463
|
+
# family and station combined -- matches the reference report's own
|
|
464
|
+
# first row exactly (it puts this ahead of the per-family rows).
|
|
465
|
+
rows.append(_build_row('ALL', 'ALL', df_all))
|
|
466
|
+
|
|
462
467
|
for family, g_fam in df_all.groupby('family', sort=False):
|
|
463
468
|
for id_stn, g_stn in g_fam.groupby('id_stn', sort=False):
|
|
464
469
|
rows.append(_build_row(family, id_stn, g_stn))
|
|
@@ -499,14 +504,27 @@ def _draw_profile_summary_table(df_all, run_time, name_in='experience'):
|
|
|
499
504
|
"</tr>")
|
|
500
505
|
body_rows = []
|
|
501
506
|
for _, r in df_summary.iterrows():
|
|
502
|
-
|
|
503
|
-
if
|
|
507
|
+
is_grand_total = (r['FAMILY'] == 'ALL' and r['ID_STN'] == 'ALL')
|
|
508
|
+
if is_grand_total:
|
|
509
|
+
row_style = "background:#dbe4f7;font-weight:bold;border-top:2px solid #4C72B0;"
|
|
510
|
+
elif r['ID_STN'] == 'ALL':
|
|
511
|
+
row_style = "background:#f5f7ff;font-weight:bold;"
|
|
512
|
+
else:
|
|
513
|
+
row_style = ""
|
|
514
|
+
if is_grand_total:
|
|
515
|
+
# No single section corresponds to "every family combined" --
|
|
516
|
+
# nothing meaningful to jump to, so this row isn't clickable.
|
|
517
|
+
onclick_attr = ""
|
|
518
|
+
elif r['ID_STN'] == 'ALL':
|
|
504
519
|
target = f"#family-{_safe_anchor(r['FAMILY'])}"
|
|
520
|
+
row_style += "cursor:pointer;"
|
|
521
|
+
onclick_attr = f" onclick=\"location.href='{target}'\""
|
|
505
522
|
else:
|
|
506
523
|
target = f"#station-{_safe_anchor(r['FAMILY'])}-{_safe_anchor(r['ID_STN'])}"
|
|
507
|
-
|
|
524
|
+
row_style += "cursor:pointer;"
|
|
525
|
+
onclick_attr = f" onclick=\"location.href='{target}'\""
|
|
508
526
|
body_rows.append(
|
|
509
|
-
f"<tr style='{row_style}'
|
|
527
|
+
f"<tr style='{row_style}'{onclick_attr}>"
|
|
510
528
|
f"<td data-v='{r['FAMILY']}'>{r['FAMILY']}</td>"
|
|
511
529
|
f"<td data-v='{r['ID_STN']}'>{r['ID_STN']}</td>"
|
|
512
530
|
f"<td data-v='{r['NB_TODAY']}'>{_fmt_int(r['NB_TODAY'])}</td>"
|
|
@@ -703,13 +721,46 @@ def _draw_channel_mosaic(df_chan_stn, family, stn, region, flag_criteria,
|
|
|
703
721
|
# the HTML note can say how many cycles this affected.
|
|
704
722
|
n_gap_cycles = int(np.all(np.isnan(grid), axis=0).sum())
|
|
705
723
|
|
|
706
|
-
|
|
724
|
+
# Every OTHER chart in this report (mosaic, global time series,
|
|
725
|
+
# per-station time series) uses left=0.06/right=0.99 of
|
|
726
|
+
# _shared_fig_width(n_date) for its plot area -- no colorbar to eat
|
|
727
|
+
# into that. This chart has a colorbar, which (via the old
|
|
728
|
+
# `fig.colorbar(im, ax=ax, fraction=.., pad=..)` approach) SHRINKS
|
|
729
|
+
# the main axes to make room, so the DATA columns end up narrower
|
|
730
|
+
# and don't line up pixel-for-pixel with every other chart's columns
|
|
731
|
+
# despite the total figure width matching. Fix: reserve a FIXED
|
|
732
|
+
# extra width JUST for the colorbar, and place the main axes
|
|
733
|
+
# explicitly at the same absolute left/right (in inches) as every
|
|
734
|
+
# other chart, so the colorbar never touches that space.
|
|
735
|
+
base_fig_w = _shared_fig_width(n_date)
|
|
736
|
+
cbar_w_inches = 0.9
|
|
737
|
+
fig_w = base_fig_w + cbar_w_inches
|
|
707
738
|
fig_h = max(3.0, min(0.18 * n_chan, 40)) + 1.4
|
|
708
|
-
|
|
739
|
+
|
|
740
|
+
# Margins reserved in roughly FIXED inches (title ~0.5", hierarchical
|
|
741
|
+
# x-axis labels ~1.5"), converted to a fraction of THIS figure's own
|
|
742
|
+
# height -- a plain fixed fraction is fine for a short mosaic but
|
|
743
|
+
# wastes enormous whitespace on a tall one (300+ channels can make
|
|
744
|
+
# fig_h > 40"), since the x-axis labels need the same few inches
|
|
745
|
+
# regardless of how tall the figure is.
|
|
746
|
+
top_frac = max(0.80, 1.0 - 0.5 / fig_h)
|
|
747
|
+
bottom_frac = min(0.28, 1.5 / fig_h)
|
|
748
|
+
|
|
749
|
+
left_frac = (0.06 * base_fig_w) / fig_w
|
|
750
|
+
plot_right_frac = (0.99 * base_fig_w) / fig_w # main axes ends here
|
|
751
|
+
cbar_left_frac = plot_right_frac + (0.10 / fig_w)
|
|
752
|
+
cbar_width_frac = 0.18 / fig_w
|
|
753
|
+
|
|
754
|
+
fig = plt.figure(figsize=(fig_w, fig_h))
|
|
755
|
+
ax = fig.add_axes([left_frac, bottom_frac, plot_right_frac - left_frac,
|
|
756
|
+
top_frac - bottom_frac])
|
|
709
757
|
cmap = plt.get_cmap('viridis').copy()
|
|
710
758
|
cmap.set_bad(color='#D9D9D9') # explicit grey for NaN, not blank/white
|
|
711
759
|
im = ax.imshow(grid, aspect='auto', cmap=cmap, interpolation='nearest')
|
|
712
|
-
|
|
760
|
+
|
|
761
|
+
cbar_ax = fig.add_axes([cbar_left_frac, bottom_frac, cbar_width_frac,
|
|
762
|
+
top_frac - bottom_frac])
|
|
763
|
+
cbar = fig.colorbar(im, cax=cbar_ax)
|
|
713
764
|
cbar.set_label('Nobs', fontsize=9)
|
|
714
765
|
|
|
715
766
|
# Keep channel labels readable even with many channels: thin them
|
|
@@ -726,15 +777,6 @@ def _draw_channel_mosaic(df_chan_stn, family, stn, region, flag_criteria,
|
|
|
726
777
|
title += f' (grey = no channel data, {n_gap_cycles} cycle{"s" if n_gap_cycles != 1 else ""})'
|
|
727
778
|
ax.set_title(title, fontsize=11)
|
|
728
779
|
|
|
729
|
-
# Margins reserved in roughly FIXED inches (title ~0.5", hierarchical
|
|
730
|
-
# x-axis labels ~1.5"), converted to a fraction of THIS figure's own
|
|
731
|
-
# height -- a plain fixed fraction (e.g. bottom=0.28) is fine for a
|
|
732
|
-
# short mosaic but wastes enormous whitespace on a tall one (300+
|
|
733
|
-
# channels can make fig_h > 40"), since the x-axis labels need the
|
|
734
|
-
# same few inches regardless of how tall the figure is.
|
|
735
|
-
top_frac = max(0.80, 1.0 - 0.5 / fig_h)
|
|
736
|
-
bottom_frac = min(0.28, 1.5 / fig_h)
|
|
737
|
-
fig.subplots_adjust(left=0.08, right=0.94, top=top_frac, bottom=bottom_frac)
|
|
738
780
|
fig.savefig(out_path, dpi=70)
|
|
739
781
|
plt.close(fig)
|
|
740
782
|
return out_path, n_gap_cycles
|
|
@@ -818,18 +860,24 @@ def _draw_station_full_timeseries(df_stn, stn, family, region, flag_criteria,
|
|
|
818
860
|
stn_col = _stn_color(stn)
|
|
819
861
|
|
|
820
862
|
fig, ax = plt.subplots(figsize=(fig_w, 4.6))
|
|
821
|
-
ax.
|
|
822
|
-
|
|
823
|
-
zorder=2)
|
|
824
|
-
|
|
825
|
-
|
|
863
|
+
ax.axhline(0.0, color='red', lw=1.0, ls='-', alpha=0.65, zorder=1)
|
|
864
|
+
ax.plot(df_stn['_x'], df_stn['Nobs'], linestyle='-', linewidth=1.6,
|
|
865
|
+
color=REF_COLOR, zorder=2)
|
|
866
|
+
|
|
867
|
+
# Every point gets a marker in its OWN status colour (not just the
|
|
868
|
+
# alert-worthy tiers) -- green for normal, dark green for above
|
|
869
|
+
# baseline, yellow/orange/red for the drop tiers, grey for
|
|
870
|
+
# insufficient history -- so the curve communicates status at a
|
|
871
|
+
# glance along its whole length, the same colour scheme as the
|
|
872
|
+
# mosaic above it, not just where something's flagged.
|
|
873
|
+
for tier, label in ((STATUS_GREEN, 'Normal'), (STATUS_DARKGREEN, 'Above baseline'),
|
|
826
874
|
(STATUS_YELLOW, 'Yellow'), (STATUS_ORANGE, 'Orange'),
|
|
827
|
-
(STATUS_RED, 'Red')):
|
|
875
|
+
(STATUS_RED, 'Red'), (STATUS_GREY, 'Insufficient history')):
|
|
828
876
|
pts = df_stn[df_stn['status'] == tier]
|
|
829
877
|
if not pts.empty:
|
|
830
|
-
ax.scatter(pts['_x'], pts['Nobs'], marker='o', s=
|
|
878
|
+
ax.scatter(pts['_x'], pts['Nobs'], marker='o', s=40,
|
|
831
879
|
color=_STATUS_COLORS[tier], edgecolor='#333',
|
|
832
|
-
linewidth=0.
|
|
880
|
+
linewidth=0.6, zorder=3, label=label)
|
|
833
881
|
|
|
834
882
|
n_alerts = int(df_stn['status'].isin([STATUS_YELLOW, STATUS_ORANGE, STATUS_RED]).sum())
|
|
835
883
|
ax.set_ylabel('Nobs', fontsize=13, fontweight='bold')
|
|
@@ -14,8 +14,8 @@ EXPERIENCE_NAME="GDPS-SN"
|
|
|
14
14
|
# Output directory where the generated results will be saved.
|
|
15
15
|
PATHWORK="/home/dlo001/sites8/pikobs_obstimedb"
|
|
16
16
|
# Start and end dates for the processing window in YYYYMMDDHH format (UTC).
|
|
17
|
-
DATESTART="
|
|
18
|
-
DATEEND="
|
|
17
|
+
DATESTART="2026082118"
|
|
18
|
+
DATEEND="2026090100"
|
|
19
19
|
# Region to process.
|
|
20
20
|
REGION="Monde"
|
|
21
21
|
# Observation families to process (space-separated list).
|
pikobs-3.0.332/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3.0.332
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|