11#! /bin/bash
22
33# ===============================================================================
4- # E3SM Atmospheric River (AR) Detection and Analysis Script
4+ # E3SM Feature Detection and Analysis Script
55# ===============================================================================
66#
7- # Purpose: Post-process E3SM 6-hourly (h2) instantaneous output to detect
8- # atmospheric rivers while filtering out tropical cyclones
7+ # Purpose: Post-process E3SM 6-hourly (h2) instantaneous output to detect and
8+ # analyze atmospheric rivers (ARs), tropical cyclones (TCs), and
9+ # extratropical cyclones (ETCs), including their interactions
10+ #
11+ # Features:
12+ # - Tropical cyclone detection with radial wind profiles and masking
13+ # - Extratropical cyclone detection with warm-core filtering
14+ # - Atmospheric river detection with TC filtering
15+ # - Variable masking and regridding for analysis-ready outputs
916#
1017# Requirements:
1118# - TempestRemap and TempestExtremes (available in e3sm-unified v1.5.0+)
12- # - E3SM h2 (6-hourly) output files with TUQ/TVQ variables
19+ # - NCO (ncclimo) for concatenation and regridding
20+ # - E3SM h2 (6-hourly) output files with required variables:
21+ # TUQ/TVQ (integrated water vapor transport), PSL, U10/V10, T200/T500, PRECT
1322#
1423# Usage: bash postprocessing_E3SM_data_for_AR_analysis.sh
1524#
16- # Author: Jill Zhang,
17- # Based on Paul Ullrich et al. 2021: TempestExtremes v2.1: a community framework for feature detection, tracking, and analysis in large datasets, and
18- # Reed et al. 2023: Evaluating the Simulation of CONUS Precipitation by Storm Type in E3SM.
25+ # Workflow:
26+ # Step 1: Tropical cyclone detection and tracking
27+ # - Detect TCs using SLP minima and temperature criteria
28+ # - Calculate radial wind profiles and circulation size
29+ # - Create TC masks for precipitation identification
30+ # Step 2: Extratropical cyclone detection and tracking
31+ # - Detect ETCs using SLP minima with warm-core filtering
32+ # - Track ETCs with trajectory and duration requirements
33+ # - Create ETC masks for regional analysis
34+ # Step 3: Atmospheric river detection
35+ # - Detect ARs using IVT Laplacian thresholding
36+ # - Apply geometric filters (latitude, area)
37+ # Step 4: Filter ARs to remove TC influence
38+ # - Remove AR detections within TC circulation radius
39+ # Step 5: Apply AR masks to meteorological variables
40+ # - Create AR/non-AR tagged variables (TVQ, PRECT)
41+ # Step 6: Regrid and process with ncclimo
42+ # - Concatenate, split, and regrid to lat-lon for analysis
43+ #
44+ # Outputs:
45+ # - AR masks (filtered and unfiltered)
46+ # - TC/ETC masks and tracks with radial profiles
47+ # - AR-tagged meteorological variables
48+ # - Analysis-ready datasets on native and lat-lon grids
49+ #
50+ # Author: Jill Zhang
51+ # Based on:
52+ # - Paul Ullrich et al. 2021: TempestExtremes v2.1: a community framework for feature detection, tracking, and analysis in large datasets
53+ # - Reed et al. 2023: Evaluating the Simulation of CONUS Precipitation by Storm Type in E3SM
1954# Date: July 2025
20- # Version: 1.0
2155# ===============================================================================
2256
2357# ===============================================================================
@@ -43,6 +77,9 @@ pg2=true # Use pg2 grids (true for v2/v3,
4377drc_in=" /lcrc/group/e3sm/ac.forsyth2/E3SMv3/${caseid} /${caseid} /archive/atm/hist"
4478result_dir=" /lcrc/group/e3sm/ac.zhang40/tests/ar_analysis/ar-${caseid} .${start} _${end} /"
4579
80+ # Regridding configuration
81+ map_file=" /lcrc/group/e3sm/diagnostics/maps/map_ne30pg2_to_cmip6_180x360_aave.20200201.nc"
82+
4683# Derived variables
4784file_name=" ${caseid} _${start} _${end} "
4885
@@ -64,10 +101,10 @@ echo "==========================================================================
64101echo " Setting up output directories..."
65102mkdir -p " ${result_dir} "
66103mkdir -p " ${result_dir} AR_mask_nofilt"
67- mkdir -p " ${result_dir} AR_mask_filt "
104+ mkdir -p " ${result_dir} AR_mask "
68105mkdir -p " ${result_dir} TVQ_PRECT_AR_mask"
69- mkdir -p " ${result_dir} TC_masks "
70- mkdir -p " ${result_dir} ETC_masks "
106+ mkdir -p " ${result_dir} TC_mask "
107+ mkdir -p " ${result_dir} ETC_mask "
71108
72109# ===============================================================================
73110# GRID GENERATION
@@ -134,10 +171,10 @@ for f in $(eval echo "${drc_in}/${caseid}.${atm_name}.h2.*{${start}..${end}}*.nc
134171 date_part=" ${date_part% .nc} "
135172
136173 ar_nofilt_file=" ${result_dir} AR_mask_nofilt/${caseid} .${atm_name} .h2.${date_part} .AR_mask_nofilt.nc"
137- ar_filt_file=" ${result_dir} AR_mask_filt /${caseid} .${atm_name} .h2.${date_part} .AR_mask_filt .nc"
174+ ar_filt_file=" ${result_dir} AR_mask /${caseid} .${atm_name} .h2.${date_part} .AR_mask .nc"
138175 tvq_prect_ar_file=" ${result_dir} TVQ_PRECT_AR_mask/${caseid} .${atm_name} .h2.${date_part} .TVQ_PRECT_AR_mask.nc"
139- tc_mask_file=" ${result_dir} TC_masks /${caseid} .${atm_name} .h2.${date_part} .TC_mask.nc"
140- etc_mask_file=" ${result_dir} ETC_masks /${caseid} .${atm_name} .h2.${date_part} .ETC_mask.nc"
176+ tc_mask_file=" ${result_dir} TC_mask /${caseid} .${atm_name} .h2.${date_part} .TC_mask.nc"
177+ etc_mask_file=" ${result_dir} ETC_mask /${caseid} .${atm_name} .h2.${date_part} .ETC_mask.nc"
141178 echo " $f " >> " ${result_dir} inputfile_${file_name} .txt"
142179 echo " ${ar_nofilt_file} " >> " ${result_dir} ar_nofilt_files_out.txt"
143180 echo " ${ar_filt_file} " >> " ${result_dir} ar_filt_files_out.txt"
@@ -243,7 +280,7 @@ NodeFileFilter \
243280 --in_data_list " ${result_dir} inputfile_${file_name} .txt" \
244281 --out_data_list " ${result_dir} tc_mask_files_out.txt" \
245282 --bydist " rsize" \
246- --maskvar " storm_mask "
283+ --maskvar " tc_mask "
247284
248285echo " TC mask creation completed"
249286
@@ -322,7 +359,7 @@ NodeFileFilter \
322359 --in_data_list " ${result_dir} inputfile_${file_name} .txt" \
323360 --out_data_list " ${result_dir} etc_mask_files_out.txt" \
324361 --bydist 6.0 \
325- --maskvar " storm_mask "
362+ --maskvar " etc_mask "
326363
327364echo " ETC mask creation completed"
328365echo " ETC detection, tracking, and masking completed"
@@ -385,6 +422,41 @@ VariableProcessor \
385422
386423echo " Vapor transport and precipitation masking completed"
387424
425+ # ===============================================================================
426+ # STEP 6: REGRID AND PROCESS MASKS WITH NCCLIMO
427+ # ===============================================================================
428+
429+ echo " Step 6: Processing masks with ncclimo..."
430+ echo " Concatenating, splitting, and regridding to regular lat-lon grid"
431+ echo " Map file: ${map_file} "
432+ echo " Output directories: native/ and rgr/"
433+
434+ # Create output directories
435+ mkdir -p " ${result_dir} native"
436+ mkdir -p " ${result_dir} rgr"
437+
438+ # Process AR masks
439+ echo " Processing AR masks..."
440+ cd " ${result_dir} "
441+ eval ls AR_mask/${caseid} .* .nc | ncclimo -P ${atm_name} --clm_md=hfc --caseid=${caseid} .${atm_name} .h2 -v ar_mask --yr_srt=${start} --yr_end=${end} --drc_out=${result_dir} native -O ${result_dir} rgr --map=${map_file} --tpd=4 --split
442+
443+ # Process TC masks
444+ echo " Processing TC masks..."
445+ cd " ${result_dir} "
446+ eval ls TC_mask/${caseid} .* .nc | ncclimo -P ${atm_name} --clm_md=hfc --caseid=${caseid} .${atm_name} .h2 -v tc_mask --yr_srt=${start} --yr_end=${end} --drc_out=${result_dir} native -O ${result_dir} rgr --map=${map_file} --tpd=4 --split
447+
448+ # Process ETC masks
449+ echo " Processing ETC masks..."
450+ cd " ${result_dir} "
451+ eval ls ETC_mask/${caseid} .* .nc | ncclimo -P ${atm_name} --clm_md=hfc --caseid=${caseid} .${atm_name} .h2 -v etc_mask --yr_srt=${start} --yr_end=${end} --drc_out=${result_dir} native -O ${result_dir} rgr --map=${map_file} --tpd=4 --split
452+
453+ # Process AR-masked variables
454+ echo " Processing AR-masked TVQ/PRECT variables..."
455+ cd " ${result_dir} "
456+ eval ls TVQ_PRECT_AR_mask/${caseid} .* .nc | ncclimo -P ${atm_name} --clm_md=hfc --caseid=${caseid} .${atm_name} .h2 -v TVQ_AR,TVQ_NONAR,PRECT_AR --yr_srt=${start} --yr_end=${end} --drc_out=${result_dir} native -O ${result_dir} rgr --map=${map_file} --tpd=4 --split
457+
458+ echo " ncclimo processing completed"
459+
388460# ===============================================================================
389461# COMPLETION
390462# ===============================================================================
@@ -394,13 +466,15 @@ echo "Processing completed successfully!"
394466echo " =============================================================================="
395467echo " Output files:"
396468echo " Unfiltered AR masks: ${result_dir} AR_mask_nofilt/"
397- echo " TC-filtered AR masks: ${result_dir} AR_mask_filt /"
469+ echo " TC-filtered AR masks: ${result_dir} AR_mask /"
398470echo " AR-masked TVQ/PRECT: ${result_dir} TVQ_PRECT_AR_mask/"
399471echo " TC tracks: ${result_dir} cyclones_stitch_${file_name} .dat"
400472echo " TC radial profiles: ${result_dir} cyclones_radprof_${file_name} .dat"
401- echo " TC masks: ${result_dir} TC_masks /"
473+ echo " TC masks: ${result_dir} TC_mask /"
402474echo " ETC tracks: ${result_dir} etc_tracks_${file_name} .dat"
403- echo " ETC masks: ${result_dir} ETC_masks/"
475+ echo " ETC masks: ${result_dir} ETC_mask/"
476+ echo " Native grid (concatenated): ${result_dir} native/"
477+ echo " Regridded to lat-lon: ${result_dir} rgr/"
404478echo " =============================================================================="
405479
406480# Optional cleanup (uncomment if needed)
0 commit comments