forked from UW-Hydro/VIC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild_vic_namelist
executable file
·177 lines (137 loc) · 5.39 KB
/
build_vic_namelist
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#!/usr/bin/env python
from __future__ import print_function
import os
import stat
import shutil
try:
from ConfigParser import SafeConfigParser
except ImportError:
# ConfigParser was renamed to configparser in Python 3
from configparser import SafeConfigParser
class VIC_Error(Exception):
pass
# header to put above VIC style config files
header_template = '''# CESM-VIC Input File: {0}
# CASEID: {1}
# READ ONLY: DO NOT EDIT THIS FILE!!!
'''
# CESM - VIC input file config
config_file = 'vic.inputfiles.cfg'
def main():
# get CESM environment variables
try:
grid = os.environ['LND_GRID']
casebld = os.environ['CASEBUILD']
rundir = os.environ['RUNDIR']
runtype = os.environ['RUN_TYPE']
coderoot = os.environ['CODEROOT']
caseroot = os.environ['CASEROOT']
except KeyError as e:
print('KeyError was raised accessing CESM environment variables')
raise(e)
caseid = os.path.normpath(casebld).split(os.sep)[-2]
casedocs = os.path.join(caseroot, 'CaseDocs')
# stop script if hybrid run is requested
if runtype.lower() == 'hybrid':
raise ValueError('Hybrid runs are not supported in RASM')
# create vicconf if it doesn't exist already
confdir = os.path.join(casebld, 'vicconf')
if not os.path.isdir(confdir):
os.makedirs(confdir)
# copy input files config to
conf_file_path = copy_to_vicconf(coderoot, confdir, config_file)
# parse the config file
all_grids = read_config(conf_file_path)
# Get the config for the current LND_GRID
try:
grid_config = all_grids[grid]
except KeyError:
raise KeyError('Requested Grid "{0}" is not '
'defined in {1}'.format(grid, config_file))
# copy VIC files to confdir
for key in ['vic_global_param', 'vic_constants']:
grid_config[key] = copy_to_vicconf(coderoot, confdir, grid_config[key])
# copy Constants and Global Parameters to RUNDIR
copy_to_rundir(grid_config, caseid, rundir, casedocs)
# write input files list
dst_file = os.path.join(casebld, 'vic.input_data_list')
# if file exists so add temporarily write permissions
if os.path.isfile(dst_file):
os.chmod(dst_file, stat.S_IWUSR)
write_input_data_list(grid_config, dst_file)
set_readonly(dst_file)
def copy_to_rundir(grid_config, caseid, rundir, casedocs):
for filekey, header_txt in [('vic_constants', 'Constants'),
('vic_global_param', 'Global Parameters')]:
header = header_template.format(header_txt, caseid)
fname = os.path.basename(grid_config[filekey])
dst_file = os.path.join(rundir, fname)
# if file exists so add temporarily write permissions
if os.path.isfile(dst_file):
os.chmod(dst_file, stat.S_IWUSR)
# copy file
copy_clean_vic_config(grid_config[filekey], dst_file,
header=header, rundir=rundir,
caseid=caseid, **grid_config)
# update the grid config
grid_config[filekey] = dst_file
# change permissions to read only
set_readonly(dst_file)
if casedocs and os.path.isdir(casedocs):
doc_file = os.path.join(casedocs, fname)
if os.path.isfile(doc_file):
os.remove(doc_file)
shutil.copy(dst_file, doc_file)
set_readonly(doc_file)
def set_readonly(fname):
os.chmod(fname, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
def read_config(config_file):
"""
Return a dictionary with subdictionaries of all configFile options/values
"""
if not os.path.isfile(config_file):
raise VIC_Error('Config File {0} does not exist'.format(config_file))
config = SafeConfigParser()
config.optionxform = str
config.read(config_file)
sections = config.sections()
dict1 = {}
for section in sections:
options = config.options(section)
dict2 = {}
for option in options:
dict2[option] = config.get(section, option)
dict1[section] = dict2
return dict1
def copy_clean_vic_config(src, dst, header=None, **kwargs):
"""Copy VIC style ASCII configuration file from src to dst
remove comments and empty lines
"""
with open(src, 'r') as fsrc:
with open(dst, 'w') as fdst:
lines = fsrc.readlines()
if header is not None:
fdst.write(header)
for line in lines:
line = line.format(**kwargs)
line = os.path.expandvars(line.split('#', 1)[0].strip())
if line:
fdst.write(line + '\n')
def copy_to_vicconf(coderoot, confdir, fname):
"""wrapper to copy files from vic/drivers/cesm/bld to case confdir"""
src_file = os.path.join(coderoot, 'lnd/vic/vic/drivers/cesm/bld', fname)
dst_file = os.path.join(confdir, fname)
if not os.path.isfile(dst_file):
shutil.copy(src_file, dst_file)
# make files readable to all, writable to user
os.chmod(dst_file,
stat.S_IWUSR | stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
return dst_file
def write_input_data_list(files, fname):
"""Write standard CESM input data namelist"""
with open(fname, 'w') as f:
for k, v in files.items():
line = '{0} = {1}\n'.format(k, os.path.expandvars(v))
f.write(line)
if __name__ == "__main__":
main()