Skip to content

Commit 53f5ce8

Browse files
author
Steve Goldhaber
committed
Use chemistry diags for a specific package, not from master list
Parse history handling flags from spreadsheets
1 parent 3caaad8 commit 53f5ce8

6 files changed

Lines changed: 1014 additions & 1290 deletions

File tree

tools/cmip_namelists/chemistry.py

100644100755
Lines changed: 135 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,140 @@
1+
#! /bin/env python3
12

3+
"""Utilities for parsing and organizing diagnostic fieldnames for chemical
4+
species in a given chemistry scheme.
5+
"""
6+
import glob
7+
import re
8+
import os
29

3-
## chemistry species diags to not add to master list
4-
__CHEM_SPECIES = ['BC_A', 'BC_AC', 'BC_AI', 'BC_AX', 'BC_N', 'BC_NI',
5-
'CFC11', 'CFC12', 'CH4', 'CO2', 'DMS', 'DST_A2', 'DST_A3',
6-
'H2O', 'H2O2', 'H2SO4', 'N2O', 'OM_AC', 'OM_AI', 'OM_NI',
7-
'SO2', 'SO4_A1', 'SO4_A2', 'SO4_AC', 'SO4_NA', 'SO4_PR',
8-
'SOA_A1', 'SOA_LV', 'SOA_NA', 'SOA_SV',
9-
'SS_A1', 'SS_A2', 'SS_A3', 'isoprene', 'monoterp']
10+
## Save our location
11+
__MYDIR = os.path.abspath(os.path.dirname(__file__))
12+
__CAMDIR = os.path.dirname(os.path.dirname(__MYDIR))
13+
__CHEMDIR = os.path.join(__CAMDIR, "src", "chemistry")
1014

1115
## chemistry diag pre- and post-fixes
1216
## Each list entry is a pair of possible new chemistry names
13-
__CHEM_DIAG_PRE_POST = [('GS_', ''), ('AQ_', ''), ('AQ_', '_OCW')]
17+
__CHEM_DIAG_PRE_POST = [('GS_', ''), ('AQ_', ''), ('AQ_', '_OCW'),
18+
('sink_', ''), ('sink_', '_S'),
19+
('CT_', ''), ('SF', ''), ('emis_', ''),
20+
('D', 'CHM'), ('F', '_fvm'), ('TA', ''), ('TM', ''),
21+
('VD', ''), ('', 'CONU'), ('', 'DDF'), ('', 'DDV'),
22+
('', 'DTQ'), ('', 'GVF'), ('', 'INS'), ('', 'SBC'),
23+
('', 'SBS'), ('', 'SF'), ('', 'SFSBC'), ('', 'SFSBD'),
24+
('', 'SFSBS'), ('', 'SFSEC'), ('', 'SFSED'),
25+
('', 'SFSES'), ('', 'SFSIC'), ('', 'SFSID'),
26+
('', 'SFSIS'), ('', 'SFWET'), ('', 'SFWETC'),
27+
('', 'SIC'), ('', 'SIS'), ('', 'TBF'), ('', 'WET'),
28+
('', 'WETC'), ('', '_CHML'), ('', '_CHMP'),
29+
('', '_SRF'), ('', '_fvm'), ('', '_mixnuc1'),
30+
('', '_num'), ('', '_qneg3'), ('', '_qneg3_col'),
31+
('', '_sfcoag1'), ('', '_sfcsiz3'), ('', '_sfcsiz4'),
32+
('', '_sfgaex2')]
33+
34+
## Find chem species in mo_sim_dat.F90
35+
__SOLSYM_RE = re.compile(r"solsym[(][: 0-9]+[)] = [(]/(.*)$")
36+
__END_SSYM_RE = re.compile(r"(.*)/[)]")
37+
38+
def read_fieldname_file(filename):
39+
"""Read a fieldname file and return all fieldnames as a list."""
40+
diag_fieldname_file = os.path.join(__MYDIR, filename)
41+
all_fieldnames = []
42+
with open(diag_fieldname_file, mode='r') as infile:
43+
for line in infile:
44+
fieldnames = [x.strip() for x in line.split()]
45+
all_fieldnames.extend(fieldnames)
46+
# end for
47+
# end with
48+
return all_fieldnames
49+
50+
def parse_chem_spec_line(species_text):
51+
"""Extract and return a list of chemical species names from the
52+
Fortran line fragment, <species_text>.
53+
"""
54+
# Store species without quotes
55+
match_text = species_text.rstrip('[/), &]')
56+
slist = [x.strip("[' ]") for x in match_text.split(',')]
57+
return slist
58+
59+
def read_chem_species(chem_name):
60+
"""Extract species names from the mo_sim_dat.F90 file from the
61+
chemistry scheme represented by <chem_name>. Return a list of
62+
species names extracted from solsym entries.
63+
"""
64+
# Validate directory exists
65+
chem_src_dir = os.path.join(__CHEMDIR, f"pp_{chem_name}")
66+
if not os.path.isdir(chem_src_dir):
67+
emsg = f"ERROR: read_chem_species cannot find {chem_src_dir}"
68+
raise FileNotFoundError(emsg)
69+
# end if
70+
71+
species_list = []
72+
filepath = os.path.join(chem_src_dir, "mo_sim_dat.F90")
73+
74+
try:
75+
in_solsym = False
76+
with open(filepath, 'r') as infile:
77+
for line in infile:
78+
beg_match = __SOLSYM_RE.match(line.strip())
79+
end_match = __END_SSYM_RE.match(line.strip())
80+
if beg_match is not None:
81+
slist = parse_chem_spec_line(beg_match.group(1))
82+
species_list.extend(slist)
83+
in_solsym = end_match is None
84+
if not in_solsym:
85+
# We are done with this file, one-line solsym def
86+
exit
87+
# end if
88+
elif in_solsym:
89+
if end_match is not None:
90+
in_solsym = False
91+
slist = parse_chem_spec_line(end_match.group(1))
92+
else:
93+
slist = parse_chem_spec_line(line.strip())
94+
# end if
95+
species_list.extend(slist)
96+
if not in_solsym:
97+
# We are done with this file
98+
exit
99+
# end if
100+
# end if
101+
# end for
102+
# end with
103+
except FileNotFoundError:
104+
emsg = f"File mo_sim_dat.F90 not found in {chem_src_dir}"
105+
raise FileNotFoundError(emsg)
106+
# end try
107+
108+
return species_list
109+
110+
def all_chem_names(chem_name=None):
111+
"""Return a set containing all chemistry diagnostic names for one
112+
chemistry scheme (chem_name==None) or for all chemistry schemes
113+
(chem_name!=None).
114+
"""
115+
diag_names = set()
116+
if chem_name != None:
117+
all_species = read_chem_species(chem_name)
118+
else:
119+
all_chem_file = os.path.join(__MYDIR, "chemistry_fieldlist.txt")
120+
all_species = read_fieldname_file(all_chem_file)
121+
# end if
122+
for chem_speci in all_species:
123+
diag_names.add(chem_speci)
124+
for decor in __CHEM_DIAG_PRE_POST:
125+
diag_names.add(f"{decor[0]}{chem_speci}{decor[1]}")
126+
# end if
127+
# end for
128+
return diag_names
129+
130+
###############################################################################
131+
132+
if __name__ == "__main__":
133+
all_specs = set()
134+
chem_dirs = glob.glob(os.path.join(__CHEMDIR, "pp_*"))
135+
for chem_name in [os.path.basename(x)[3:] for x in chem_dirs]:
136+
if chem_name != "none":
137+
all_specs |= set(read_chem_species(chem_name))
138+
# end if
139+
# end for
140+
print(f"{sorted(all_specs)}")
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
ACBZO2 ALKNIT ALKO2 ALKOOH
2+
AOA_NH APIN APINNO3 APINO2
3+
APINO2VBS BCARY BCARYNO3 BCARYO2
4+
BCARYO2VBS BC_A BC_AC BC_AI
5+
BC_AX BC_N BC_NI BENZENE
6+
BENZO2 BENZO2VBS BENZOOH BEPOMUC
7+
BIGALD BIGALD1 BIGALD2 BIGALD3
8+
BIGALD4 BIGALK BIGENE BPIN
9+
BPINNO3 BPINO2 BPINO2VBS BR
10+
BRCL BRO BRONO2 BRY
11+
BZALD BZOO BZOOH C10H16
12+
C2H2 C2H4 C2H5O2 C2H5OH
13+
C2H5OOH C2H6 C3H6 C3H7O2
14+
C3H7OOH C3H8 C6H5O2 C6H5OOH
15+
CB1 CB2 CCL4 CF2CLBR
16+
CF3BR CFC11 CFC113 CFC114
17+
CFC115 CFC12 CH2BR2 CH2O
18+
CH3BR CH3CCL3 CH3CHO CH3CL
19+
CH3CN CH3CO3 CH3COCH3 CH3COCHO
20+
CH3COOH CH3COOOH CH3O2 CH3OH
21+
CH3OOH CH4 CHBR3 CL
22+
CL2 CL2O2 CLO CLONO2
23+
CLOm CLY CLm CLm_H2O
24+
CLm_HCL CO CO2 CO3m
25+
CO3m2H2O CO3m_H2O CO4m COF2
26+
COFCL CRESOL DHPMPAL DICARBO2
27+
DMS DST01 DST02 DST03
28+
DST04 DST_A2 DST_A3 E90
29+
ENEO2 EO EO2 EOOH
30+
F GLYALD GLYOXAL H
31+
H2 H2402 H2O H2O2
32+
H2SO4 H3Op_OH HBR HCFC141B
33+
HCFC142B HCFC22 HCL HCN
34+
HCO3m HCOCH2OOH HCOOH HF
35+
HMHP HNO3 HO2 HO2NO2
36+
HOBR HOCH2OO HOCL HONITR
37+
HONO HPALD HPALD1 HPALD4
38+
HPALDB1C HPALDB4C HSO3 HYAC
39+
HYDRALD HYPERACET Hp_2H2O Hp_3H2O
40+
Hp_3N1 Hp_4H2O Hp_4N1 Hp_5H2O
41+
Hp_H2O ICHE IEPOX IEPOXOO
42+
INHEB INHED ISOP ISOPAO2
43+
ISOPB1O2 ISOPB4O2 ISOPBO2 ISOPC1C
44+
ISOPC1T ISOPC4C ISOPC4T ISOPED1O2
45+
ISOPED4O2 ISOPFDN ISOPFDNC ISOPFNC
46+
ISOPFNP ISOPHFP ISOPN1D ISOPN1DO2
47+
ISOPN2B ISOPN2BO2 ISOPN3B ISOPN3BO2
48+
ISOPN4D ISOPN4DO2 ISOPNBNO3 ISOPNBNO3O2
49+
ISOPNITA ISOPNITB ISOPNO3 ISOPNOOH
50+
ISOPNOOHB ISOPNOOHBO2 ISOPNOOHD ISOPNOOHDO2
51+
ISOPO2 ISOPO2VBS ISOPOH ISOPOOH
52+
ISOPZD1O2 ISOPZD4O2 IVOC IVOCO2VBS
53+
IVOCbb IVOCbbO2VBS IVOCff IVOCffO2VBS
54+
LIMON LIMONNO3 LIMONO2 LIMONO2VBS
55+
MACR MACRN MACRO2 MACROOH
56+
MALO2 MCO3 MDIALO2 MEK
57+
MEKO2 MEKOOH MPAN MTERP
58+
MTERPO2VBS MVK MVKN MVKO2
59+
MVKOOH MYRC MYRCNO3 MYRCO2
60+
MYRCO2VBS N N2D N2O
61+
N2O5 N2p NC4CH2OH NC4CHO
62+
NC4CHOO2 NDEP NH3 NH4
63+
NH4NO3 NHDEP NH_5 NH_50
64+
NO NO2 NO2m NO2m_H2O
65+
NO3 NO3CH2CHO NO3m NO3m2H2O
66+
NO3mHNO3 NO3m_H2O NO3m_HCL NOA
67+
NOp NOp_2H2O NOp_3H2O NOp_CO2
68+
NOp_H2O NOp_N2 NTERPO2 NTERPOOH
69+
Np O O1D O2
70+
O2_1D O2_1S O2m O2p
71+
O2p_H2O O3 O3S O3m
72+
O4m O4p OC1 OC2
73+
OCLO OCS OH OHm
74+
OM_AC OM_AI OM_NI ONIT
75+
ONITR Om Op Op2D
76+
Op2P PAN PBZNIT PHENO
77+
PHENO2 PHENOL PHENOOH PO2
78+
POOH Pb RHO RO2
79+
ROOH Rn S SF6
80+
SO SO2 SO3 SO4
81+
SO4_A1 SO4_A2 SO4_AC SO4_NA
82+
SO4_PR SOA SOAE SOAG
83+
SOAG0 SOAG1 SOAG2 SOAG3
84+
SOAG4 SOAGbb0 SOAGbb1 SOAGbb2
85+
SOAGbb3 SOAGbb4 SOAGbg0 SOAGbg1
86+
SOAGbg2 SOAGbg3 SOAGbg4 SOAGff0
87+
SOAGff1 SOAGff2 SOAGff3 SOAGff4
88+
SOA_A1 SOA_LV SOA_NA SOA_SV
89+
SQTN SSLT01 SSLT02 SSLT03
90+
SSLT04 SS_A1 SS_A2 SS_A3
91+
ST80_25 SVOC SVOCbb SVOCff
92+
TEPOMUC TERP TERP1OOH TERP1OOHO2
93+
TERP2AOOH TERP2O2 TERP2OOH TERP2OOHO2
94+
TERPA TERPA1O2 TERPA2 TERPA2CO3
95+
TERPA2O2 TERPA2PAN TERPA3 TERPA3CO3
96+
TERPA3O2 TERPA3PAN TERPA4O2 TERPACID
97+
TERPACID2 TERPACID3 TERPACO3 TERPAPAN
98+
TERPDHDP TERPF1 TERPF1O2 TERPF2
99+
TERPF2O2 TERPFDN TERPHFN TERPK
100+
TERPNIT TERPNPS TERPNPS1 TERPNPS1O2
101+
TERPNPT TERPNPT1 TERPNPT1O2 TERPNS
102+
TERPNS1 TERPNS1O2 TERPNT TERPNT1
103+
TERPNT1O2 TERPO2 TERPOOH TERPOOHL
104+
TERPROD1 TERPROD2 TOLO2 TOLOOH
105+
TOLUENE TOLUO2VBS XO2 XOH
106+
XOOH XYLENES XYLENO2 XYLENOOH
107+
XYLEO2VBS XYLOL XYLOLO2 XYLOLOOH
108+
bc_a1 bc_a3 bc_a4 dst_a1
109+
dst_a2 dst_a3 dst_a5 dst_a7
110+
e isoprene monoterp ncl_a1
111+
ncl_a2 ncl_a3 ncl_a4 ncl_a6
112+
nh4_a1 nh4_a2 nh4_a4 nh4_a5
113+
nh4_a6 nh4_a7 num_a1 num_a2
114+
num_a3 num_a4 num_a5 num_a6
115+
num_a7 pom_a1 pom_a3 pom_a4
116+
pombb1_a1 pombb1_a4 pomff1_a1 pomff1_a4
117+
so4_a1 so4_a2 so4_a3 so4_a4
118+
so4_a5 so4_a6 so4_a7 soa1_a1
119+
soa1_a2 soa2_a1 soa2_a2 soa3_a1
120+
soa3_a2 soa4_a1 soa4_a2 soa5_a1
121+
soa5_a2 soa_a1 soa_a2 soabb1_a1
122+
soabb1_a2 soabb2_a1 soabb2_a2 soabb3_a1
123+
soabb3_a2 soabb4_a1 soabb4_a2 soabb5_a1
124+
soabb5_a2 soabg1_a1 soabg1_a2 soabg2_a1
125+
soabg2_a2 soabg3_a1 soabg3_a2 soabg4_a1
126+
soabg4_a2 soabg5_a1 soabg5_a2 soaff1_a1
127+
soaff1_a2 soaff2_a1 soaff2_a2 soaff3_a1
128+
soaff3_a2 soaff4_a1 soaff4_a2 soaff5_a1
129+
soaff5_a2

0 commit comments

Comments
 (0)