Skip to content

Commit 43e3117

Browse files
authored
Merge pull request #13 from LIVVkit/mkstratos/tsc_merge_fix
Bugfix for new pandas version
2 parents b0d023d + 1650321 commit 43e3117

File tree

9 files changed

+1022
-585
lines changed

9 files changed

+1022
-585
lines changed

.git-blame-ignore-revs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0e03e4395fae0aa0b6ab475feb054e53135f2352

evv4esm/__init__.py

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,50 @@
2828
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2929

3030

31-
__version_info__ = (0, 5, 0)
32-
__version__ = '.'.join(str(vi) for vi in __version_info__)
31+
__version_info__ = (0, 5, 1)
32+
__version__ = ".".join(str(vi) for vi in __version_info__)
3333

34-
PASS_COLOR = '#389933'
35-
L_PASS_COLOR = '#93DA90'
34+
PASS_COLOR = "#389933"
35+
L_PASS_COLOR = "#93DA90"
3636

37-
FAIL_COLOR = '#BF3F46'
38-
L_FAIL_COLOR = '#E68388'
37+
FAIL_COLOR = "#BF3F46"
38+
L_FAIL_COLOR = "#E68388"
3939

40-
human_color_names = {'pass': ('green', 'light green'),
41-
PASS_COLOR: 'green',
42-
L_PASS_COLOR: 'light green',
43-
'fail': ('red', 'light red'),
44-
FAIL_COLOR: 'red',
45-
L_FAIL_COLOR: 'light red'}
40+
human_color_names = {
41+
"pass": ("green", "light green"),
42+
PASS_COLOR: "green",
43+
L_PASS_COLOR: "light green",
44+
"fail": ("red", "light red"),
45+
FAIL_COLOR: "red",
46+
L_FAIL_COLOR: "light red",
47+
}
4648

47-
pf_color_picker = {'Pass': PASS_COLOR, 'pass': PASS_COLOR,
48-
'Accept': PASS_COLOR, 'accept': PASS_COLOR,
49-
'Fail': FAIL_COLOR, 'fail': FAIL_COLOR,
50-
'Reject': FAIL_COLOR, 'reject': FAIL_COLOR}
49+
pf_color_picker = {
50+
"Pass": PASS_COLOR,
51+
"pass": PASS_COLOR,
52+
"Accept": PASS_COLOR,
53+
"accept": PASS_COLOR,
54+
"Fail": FAIL_COLOR,
55+
"fail": FAIL_COLOR,
56+
"Reject": FAIL_COLOR,
57+
"reject": FAIL_COLOR,
58+
}
5159

52-
light_pf_color_picker = {'Pass': L_PASS_COLOR, 'pass': L_PASS_COLOR,
53-
'Accept': L_PASS_COLOR, 'accept': L_PASS_COLOR,
54-
PASS_COLOR: L_PASS_COLOR,
55-
'Fail': L_FAIL_COLOR, 'fail': L_FAIL_COLOR,
56-
'Reject': L_FAIL_COLOR, 'reject': L_FAIL_COLOR,
57-
FAIL_COLOR: L_FAIL_COLOR}
60+
light_pf_color_picker = {
61+
"Pass": L_PASS_COLOR,
62+
"pass": L_PASS_COLOR,
63+
"Accept": L_PASS_COLOR,
64+
"accept": L_PASS_COLOR,
65+
PASS_COLOR: L_PASS_COLOR,
66+
"Fail": L_FAIL_COLOR,
67+
"fail": L_FAIL_COLOR,
68+
"Reject": L_FAIL_COLOR,
69+
"reject": L_FAIL_COLOR,
70+
FAIL_COLOR: L_FAIL_COLOR,
71+
}
5872

5973

6074
class EVVException(Exception):
6175
"""Base class for EVV exceptions"""
76+
6277
pass

evv4esm/__main__.py

Lines changed: 84 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22
# coding=utf-8
33
# Copyright (c) 2018 UT-BATTELLE, LLC
44
# All rights reserved.
5-
#
5+
#
66
# Redistribution and use in source and binary forms, with or without
77
# modification, are permitted provided that the following conditions are met:
8-
#
8+
#
99
# 1. Redistributions of source code must retain the above copyright notice, this
1010
# list of conditions and the following disclaimer.
11-
#
11+
#
1212
# 2. Redistributions in binary form must reproduce the above copyright notice,
1313
# this list of conditions and the following disclaimer in the documentation
1414
# and/or other materials provided with the distribution.
15-
#
15+
#
1616
# 3. Neither the name of the copyright holder nor the names of its contributors
1717
# may be used to endorse or promote products derived from this software without
1818
# specific prior written permission.
19-
#
19+
#
2020
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2121
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2222
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -39,53 +39,72 @@
3939

4040

4141
def parse_args(args=None):
42-
parser = argparse.ArgumentParser(description=__doc__,
43-
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
44-
45-
parser.add_argument('-e', '--extensions',
46-
action='store',
47-
nargs='+',
48-
default=None,
49-
help='Specify the location of the JSON configuration files for the extended V&V tests to run.')
50-
51-
parser.add_argument('-o', '--out-dir',
52-
default=os.path.join(os.getcwd(), "vv_" + time.strftime("%Y-%m-%d")),
53-
help='Location to output the EVV webpages.')
54-
55-
parser.add_argument('-s', '--serve',
56-
nargs='?', type=int, const=8000,
57-
help=' '.join(['Start a simple HTTP server for the output website specified',
58-
'by OUT_DIR on port SERVE.'
59-
])
60-
)
61-
62-
parser.add_argument('-p', '--pool-size',
63-
nargs='?',
64-
type=int,
65-
default=(options.mp.cpu_count() - 1 or 1),
66-
help='The number of multiprocessing processes to run '
67-
'analyses in. If zero, processes will run serially '
68-
'outside of the multiprocessing module.')
69-
70-
parser.add_argument('--version',
71-
action='version',
72-
version='EVV {}'.format(evv4esm.__version__),
73-
help="Show EVV's version number and exit"
74-
)
42+
parser = argparse.ArgumentParser(
43+
description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter
44+
)
45+
46+
parser.add_argument(
47+
"-e",
48+
"--extensions",
49+
action="store",
50+
nargs="+",
51+
default=None,
52+
help="Specify the location of the JSON configuration files for the extended V&V tests to run.",
53+
)
54+
55+
parser.add_argument(
56+
"-o",
57+
"--out-dir",
58+
default=os.path.join(os.getcwd(), "vv_" + time.strftime("%Y-%m-%d")),
59+
help="Location to output the EVV webpages.",
60+
)
61+
62+
parser.add_argument(
63+
"-s",
64+
"--serve",
65+
nargs="?",
66+
type=int,
67+
const=8000,
68+
help=" ".join(
69+
[
70+
"Start a simple HTTP server for the output website specified",
71+
"by OUT_DIR on port SERVE.",
72+
]
73+
),
74+
)
75+
76+
parser.add_argument(
77+
"-p",
78+
"--pool-size",
79+
nargs="?",
80+
type=int,
81+
default=(options.mp.cpu_count() - 1 or 1),
82+
help="The number of multiprocessing processes to run "
83+
"analyses in. If zero, processes will run serially "
84+
"outside of the multiprocessing module.",
85+
)
86+
87+
parser.add_argument(
88+
"--version",
89+
action="version",
90+
version="EVV {}".format(evv4esm.__version__),
91+
help="Show EVV's version number and exit",
92+
)
7593

7694
args = parser.parse_args(args)
7795

7896
if args.extensions:
79-
options.parse_args(['-V']+args.extensions + ['-o', args.out_dir])
80-
97+
options.parse_args(["-V"] + args.extensions + ["-o", args.out_dir])
98+
8199
from evv4esm import resources
100+
82101
args.livv_resource_dir = livvkit.resource_dir
83102
livvkit.resource_dir = os.sep.join(resources.__path__)
84103
return args
85104

86105

87106
def main(cl_args=None):
88-
""" Direct execution. """
107+
"""Direct execution."""
89108

90109
if cl_args is None and len(sys.argv) > 1:
91110
cl_args = sys.argv[1:]
@@ -123,10 +142,14 @@ def main(cl_args=None):
123142
print(" -----------------------------------------------------------------")
124143
print("")
125144
for conf in livvkit.validation_model_configs:
126-
validation_config = functions.merge_dicts(validation_config,
127-
functions.read_json(conf))
128-
summary_elements.extend(scheduler.run_quiet("validation", validation, validation_config,
129-
group=False))
145+
validation_config = functions.merge_dicts(
146+
validation_config, functions.read_json(conf)
147+
)
148+
summary_elements.extend(
149+
scheduler.run_quiet(
150+
"validation", validation, validation_config, group=False
151+
)
152+
)
130153
print(" -----------------------------------------------------------------")
131154
print(" Extensions test suite complete ")
132155
print(" -----------------------------------------------------------------")
@@ -137,28 +160,34 @@ def main(cl_args=None):
137160
index_data.write(result._repr_json())
138161
print("-------------------------------------------------------------------")
139162
print(" Done! Results can be seen in a web browser at:")
140-
print(" " + os.path.join(livvkit.output_dir, 'index.html'))
163+
print(" " + os.path.join(livvkit.output_dir, "index.html"))
141164
print("-------------------------------------------------------------------")
142165

143166
if args.serve:
144167
import http.server as server
145168
import socketserver as socket
146169

147-
httpd = socket.TCPServer(('', args.serve), server.SimpleHTTPRequestHandler)
170+
httpd = socket.TCPServer(("", args.serve), server.SimpleHTTPRequestHandler)
148171

149172
sa = httpd.socket.getsockname()
150-
print('\nServing HTTP on {host} port {port} (http://{host}:{port}/)'.format(host=sa[0], port=sa[1]))
151-
print('\nView the generated website by navigating to:')
152-
print('\n http://{host}:{port}/{path}/index.html'.format(host=sa[0], port=sa[1],
153-
path=os.path.relpath(args.out_dir)
154-
))
155-
print('\nExit by pressing `ctrl+c` to send a keyboard interrupt.\n')
173+
print(
174+
"\nServing HTTP on {host} port {port} (http://{host}:{port}/)".format(
175+
host=sa[0], port=sa[1]
176+
)
177+
)
178+
print("\nView the generated website by navigating to:")
179+
print(
180+
"\n http://{host}:{port}/{path}/index.html".format(
181+
host=sa[0], port=sa[1], path=os.path.relpath(args.out_dir)
182+
)
183+
)
184+
print("\nExit by pressing `ctrl+c` to send a keyboard interrupt.\n")
156185
try:
157186
httpd.serve_forever()
158187
except KeyboardInterrupt:
159-
print('\nKeyboard interrupt received, exiting.\n')
188+
print("\nKeyboard interrupt received, exiting.\n")
160189
sys.exit(0)
161190

162191

163-
if __name__ == '__main__':
192+
if __name__ == "__main__":
164193
main()

evv4esm/ensembles/e3sm.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,19 @@ def file_date_str(case_file, style="short", hist_name="h0"):
6464
return result.replace("{}.".format(hist_name), "").replace(".nc", "")
6565

6666

67-
def component_monthly_files(dir_, component, ninst, hist_name="h0", nmonth_max=12, date_style="short"):
67+
def component_monthly_files(
68+
dir_, component, ninst, hist_name="h0", nmonth_max=12, date_style="short"
69+
):
6870
if date_style == "full":
6971
date_search = "????-??-??-??"
7072
elif date_style == "med":
7173
date_search = "????-??-??"
7274
else:
7375
date_search = "????-??"
7476

75-
base = "{d}/*{c}_????.{n}.{ds}.nc".format(d=dir_, c=component, n=hist_name, ds=date_search)
77+
base = "{d}/*{c}_????.{n}.{ds}.nc".format(
78+
d=dir_, c=component, n=hist_name, ds=date_search
79+
)
7680
search = os.path.normpath(base)
7781
result = sorted(glob.glob(search))
7882

@@ -115,22 +119,36 @@ def gather_monthly_averages(ensemble_files, variable_set=None):
115119
if variable_set is None:
116120
variable_set = set(data.variables.keys())
117121
except OSError as E:
118-
six.raise_from(BaseException('Could not open netCDF dataset: {}'.format(file_)), E)
122+
six.raise_from(
123+
BaseException(
124+
"Could not open netCDF dataset: {}".format(file_)
125+
),
126+
E,
127+
)
119128

120129
for var in data.variables.keys():
121130
if var not in variable_set:
122131
continue
123-
if len(data.variables[var].shape) < 2 or var in ['time_bnds', 'date_written', 'time_written']:
132+
if len(data.variables[var].shape) < 2 or var in [
133+
"time_bnds",
134+
"date_written",
135+
"time_written",
136+
]:
124137
continue
125-
elif 'ncol' not in data.variables[var].dimensions:
138+
elif "ncol" not in data.variables[var].dimensions:
126139
continue
127140
else:
128141
m = np.mean(data.variables[var][0, ...])
129142

130143
desc = "{long_name}{units}".format(**get_variable_meta(data, var))
131-
monthly_avgs.append((case, var, '{:04}'.format(inst), date_str, m, desc))
132-
133-
monthly_avgs = pd.DataFrame(monthly_avgs, columns=('case', 'variable', 'instance', 'date', 'monthly_mean', 'desc'))
144+
monthly_avgs.append(
145+
(case, var, "{:04}".format(inst), date_str, m, desc)
146+
)
147+
148+
monthly_avgs = pd.DataFrame(
149+
monthly_avgs,
150+
columns=("case", "variable", "instance", "date", "monthly_mean", "desc"),
151+
)
134152
return monthly_avgs
135153

136154

evv4esm/ensembles/tools.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,16 @@ def prob_plot(
170170

171171
else:
172172
ax3.hist(
173-
norm_ref, bins=n_q, color=pf_color_picker.get(pf, "#1F77B4"), edgecolor="k"
173+
norm_ref,
174+
bins=n_q,
175+
color=pf_color_picker.get(pf, "#1F77B4"),
176+
edgecolor="k",
174177
)
175178
ax4.hist(
176-
norm_test, bins=n_q, color=pf_color_picker.get(pf, "#1F77B4"), edgecolor="k"
179+
norm_test,
180+
bins=n_q,
181+
color=pf_color_picker.get(pf, "#1F77B4"),
182+
edgecolor="k",
177183
)
178184

179185
# Check if these distributions are wildly different. If they are, use different

0 commit comments

Comments
 (0)