From e3e56087c2a56b189210068fa28412f961ffde2d Mon Sep 17 00:00:00 2001 From: ckoven Date: Wed, 24 Jan 2018 21:48:43 -0700 Subject: [PATCH 1/3] fixes to scalar logic in modify_fates_paramfile.py --- tools/modify_fates_paramfile.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/modify_fates_paramfile.py b/tools/modify_fates_paramfile.py index 92ab14dab1..c48efdf8ce 100755 --- a/tools/modify_fates_paramfile.py +++ b/tools/modify_fates_paramfile.py @@ -58,22 +58,25 @@ def main(): ### check to make sure that, if a PFT is specified, the variable has a PFT dimension, and if not, then it doesn't. and also that shape is reasonable. ndim_file = len(var.dimensions) ispftvar = False + # for purposes of current stat eof this script, assume 1D + if ndim_file > 1: + raise ValueError('variable dimensionality is too high for this script') + if ndim_file < 1: + raise ValueError('variable dimensionality is too low for this script. FATES assumes even scalars have a 1-length dimension') for i in range(ndim_file): if var.dimensions[i] == 'fates_pft': ispftvar = True npft_file = var.shape[i] pftdim = 0 - else: + elif var.dimensions[i] == 'fates_scalar': npft_file = None pftdim = None + else: + raise ValueError('variable is not on either the PFT or scalar dimension') if args.pftnum == None and ispftvar: raise ValueError('pft value is missing but variable has pft dimension.') if args.pftnum != None and not ispftvar: raise ValueError('pft value is present but variable does not have pft dimension.') - if ndim_file > 1: - raise ValueError('variable dimensionality is too high for this script') - if ndim_file == 1 and not ispftvar: - raise ValueError('variable dimensionality is too high for this script') if args.pftnum != None and ispftvar: if args.pftnum > npft_file: raise ValueError('PFT specified ('+str(args.pftnum)+') is larger than the number of PFTs in the file ('+str(npft_file)+').') From e3e4d029e264a57d98a743575c4451ad2a7d83db Mon Sep 17 00:00:00 2001 From: ckoven Date: Wed, 24 Jan 2018 22:35:36 -0700 Subject: [PATCH 2/3] changed modify_fates_paramfile.py to first write to temp file and then move that --- tools/modify_fates_paramfile.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/tools/modify_fates_paramfile.py b/tools/modify_fates_paramfile.py index c48efdf8ce..0f7ee15e8e 100755 --- a/tools/modify_fates_paramfile.py +++ b/tools/modify_fates_paramfile.py @@ -19,6 +19,8 @@ from scipy.io import netcdf as nc import argparse import shutil +import tempfile + # ======================================================================================== # ======================================================================================== @@ -38,20 +40,13 @@ def main(): parser.add_argument('--silent', '--s', dest='silent', help="prevent writing of output.", action="store_true") # args = parser.parse_args() - # print(args.varname, args.pftnum, args.inputfname, args.outputfname, args.val, args.overwrite) # - # check to see if output file exists - if os.path.isfile(args.outputfname): - if args.overwrite: - if not args.silent: - print('replacing file: '+args.outputfname) - os.remove(args.outputfname) - else: - raise ValueError('Output file already exists and overwrite flag not specified for filename: '+args.outputfname) + # work with the file in some random temprary place so that if something goes wrong nothing happens to original file and it doesn't make an output file + tempfilename = os.path.join(tempfile.mkdtemp(), 'temp_fates_param_file.nc') # - shutil.copyfile(args.inputfname, args.outputfname) + shutil.copyfile(args.inputfname, tempfilename) # - ncfile = nc.netcdf_file(args.outputfname, 'a') + ncfile = nc.netcdf_file(tempfilename, 'a') # var = ncfile.variables[args.varname] # @@ -93,6 +88,20 @@ def main(): # # ncfile.close() + # + # + # now move file from temprary location to final location + # + # check to see if output file exists + if os.path.isfile(args.outputfname): + if args.overwrite: + if not args.silent: + print('replacing file: '+args.outputfname) + os.remove(args.outputfname) + else: + raise ValueError('Output file already exists and overwrite flag not specified for filename: '+args.outputfname) + # + shutil.move(tempfilename, args.outputfname) From ce6ac7409bbe1bef2e5bd93c7e257b632d2c83c1 Mon Sep 17 00:00:00 2001 From: ckoven Date: Wed, 24 Jan 2018 22:52:50 -0700 Subject: [PATCH 3/3] added tempdir cleanup and better exception handling --- tools/modify_fates_paramfile.py | 122 +++++++++++++++++--------------- 1 file changed, 63 insertions(+), 59 deletions(-) diff --git a/tools/modify_fates_paramfile.py b/tools/modify_fates_paramfile.py index 0f7ee15e8e..53bd82decc 100755 --- a/tools/modify_fates_paramfile.py +++ b/tools/modify_fates_paramfile.py @@ -42,68 +42,72 @@ def main(): args = parser.parse_args() # # work with the file in some random temprary place so that if something goes wrong nothing happens to original file and it doesn't make an output file - tempfilename = os.path.join(tempfile.mkdtemp(), 'temp_fates_param_file.nc') + tempdir = tempfile.mkdtemp() + tempfilename = os.path.join(tempdir, 'temp_fates_param_file.nc') # - shutil.copyfile(args.inputfname, tempfilename) - # - ncfile = nc.netcdf_file(tempfilename, 'a') - # - var = ncfile.variables[args.varname] - # - ### check to make sure that, if a PFT is specified, the variable has a PFT dimension, and if not, then it doesn't. and also that shape is reasonable. - ndim_file = len(var.dimensions) - ispftvar = False - # for purposes of current stat eof this script, assume 1D - if ndim_file > 1: - raise ValueError('variable dimensionality is too high for this script') - if ndim_file < 1: - raise ValueError('variable dimensionality is too low for this script. FATES assumes even scalars have a 1-length dimension') - for i in range(ndim_file): - if var.dimensions[i] == 'fates_pft': - ispftvar = True - npft_file = var.shape[i] - pftdim = 0 - elif var.dimensions[i] == 'fates_scalar': - npft_file = None - pftdim = None - else: - raise ValueError('variable is not on either the PFT or scalar dimension') - if args.pftnum == None and ispftvar: - raise ValueError('pft value is missing but variable has pft dimension.') - if args.pftnum != None and not ispftvar: - raise ValueError('pft value is present but variable does not have pft dimension.') - if args.pftnum != None and ispftvar: - if args.pftnum > npft_file: - raise ValueError('PFT specified ('+str(args.pftnum)+') is larger than the number of PFTs in the file ('+str(npft_file)+').') - if pftdim == 0: + try: + shutil.copyfile(args.inputfname, tempfilename) + # + ncfile = nc.netcdf_file(tempfilename, 'a') + # + var = ncfile.variables[args.varname] + # + ### check to make sure that, if a PFT is specified, the variable has a PFT dimension, and if not, then it doesn't. and also that shape is reasonable. + ndim_file = len(var.dimensions) + ispftvar = False + # for purposes of current stat eof this script, assume 1D + if ndim_file > 1: + raise ValueError('variable dimensionality is too high for this script') + if ndim_file < 1: + raise ValueError('variable dimensionality is too low for this script. FATES assumes even scalars have a 1-length dimension') + for i in range(ndim_file): + if var.dimensions[i] == 'fates_pft': + ispftvar = True + npft_file = var.shape[i] + pftdim = 0 + elif var.dimensions[i] == 'fates_scalar': + npft_file = None + pftdim = None + else: + raise ValueError('variable is not on either the PFT or scalar dimension') + if args.pftnum == None and ispftvar: + raise ValueError('pft value is missing but variable has pft dimension.') + if args.pftnum != None and not ispftvar: + raise ValueError('pft value is present but variable does not have pft dimension.') + if args.pftnum != None and ispftvar: + if args.pftnum > npft_file: + raise ValueError('PFT specified ('+str(args.pftnum)+') is larger than the number of PFTs in the file ('+str(npft_file)+').') + if pftdim == 0: + if not args.silent: + print('replacing prior value of variable '+args.varname+', for PFT '+str(args.pftnum)+', which was '+str(var[args.pftnum-1])+', with new value of '+str(args.val)) + var[args.pftnum-1] = args.val + elif args.pftnum == None and not ispftvar: if not args.silent: - print('replacing prior value of variable '+args.varname+', for PFT '+str(args.pftnum)+', which was '+str(var[args.pftnum-1])+', with new value of '+str(args.val)) - var[args.pftnum-1] = args.val - elif args.pftnum == None and not ispftvar: - if not args.silent: - print('replacing prior value of variable '+args.varname+', which was '+str(var[:])+', with new value of '+str(args.val)) - var[:] = args.val - else: - raise ValueError('Nothing happened somehow.') - # - # - ncfile.close() - # - # - # now move file from temprary location to final location - # - # check to see if output file exists - if os.path.isfile(args.outputfname): - if args.overwrite: - if not args.silent: - print('replacing file: '+args.outputfname) - os.remove(args.outputfname) + print('replacing prior value of variable '+args.varname+', which was '+str(var[:])+', with new value of '+str(args.val)) + var[:] = args.val else: - raise ValueError('Output file already exists and overwrite flag not specified for filename: '+args.outputfname) - # - shutil.move(tempfilename, args.outputfname) - - + raise ValueError('Nothing happened somehow.') + # + # + ncfile.close() + # + # + # now move file from temprary location to final location + # + # check to see if output file exists + if os.path.isfile(args.outputfname): + if args.overwrite: + if not args.silent: + print('replacing file: '+args.outputfname) + os.remove(args.outputfname) + else: + raise ValueError('Output file already exists and overwrite flag not specified for filename: '+args.outputfname) + # + shutil.move(tempfilename, args.outputfname) + shutil.rmtree(tempdir, ignore_errors=True) + except: + shutil.rmtree(tempdir, ignore_errors=True) + raise # =======================================================================================