diff --git a/bgcval2/download_from_mass.py b/bgcval2/download_from_mass.py index 461e24c8..17b9f8fe 100755 --- a/bgcval2/download_from_mass.py +++ b/bgcval2/download_from_mass.py @@ -409,7 +409,11 @@ def download_from_mass( outputFold = folder([paths.ModelFolder_pref, jobID,] ) # make this folder group writeable. st = os.stat(outputFold) - os.chmod(outputFold, st.st_mode | stat.S_IWGRP) + + try: + os.chmod(outputFold, st.st_mode | stat.S_IWGRP) + except OSError: + print('Unable to change permissions:', outputFold) deleteBadLinksAndZeroSize(outputFold, jobID) @@ -417,7 +421,12 @@ def download_from_mass( deleteBadLinksAndZeroSize(outputFold, jobID) # Set up a file to save command to a new file. - download_script_path = ''.join([folder('mass_scripts/'), jobID,'.sh']) + try: + username = os.getlogin() + except OSError: + import getpass + username = getpass.getuser() + download_script_path = ''.join([folder('mass_scripts/'), jobID, '_', username, '.sh']) header_lines = ['# Run this script on mass-cli1.jasmin.ac.uk\n',] header_lines.append('# from login1.jasmin.ac.uk, ssh to the mass machine:\n# ssh -X mass-cli\n') header_lines.append(''.join(['# run script with:\n# source ', os.path.abspath(download_script_path),'\n'])) @@ -483,7 +492,10 @@ def download_from_mass( if auto_download: shared_file_path = os.path.join(paths.shared_mass_scripts, os.path.basename(download_script_path)) print('writing file in shared path', shared_file_path) - shutil.copy(download_script_path, shared_file_path) + try: + shutil.copy(download_script_path, shared_file_path) + except EnvironmentError: + print('Error copying file', download_script_path, 'to', shared_file_path) fixFilePaths(outputFold, jobID, debug=False,) deleteBadLinksAndZeroSize(outputFold, jobID, debug=False,) diff --git a/bgcval2/functions/AirSeaFluxCO2.py b/bgcval2/functions/AirSeaFluxCO2.py index 93116547..b320435d 100644 --- a/bgcval2/functions/AirSeaFluxCO2.py +++ b/bgcval2/functions/AirSeaFluxCO2.py @@ -32,6 +32,7 @@ import numpy as np from bgcval2.bgcvaltools.dataset import dataset from bgcval2.functions.get_kwarg_file import get_kwarg_file +from bgcval2.functions.tools import load_area global loaded_area_and_mask global tmask @@ -46,7 +47,7 @@ def load_area_and_mask(areafile): if isinstance(areafile, list) and len(areafile)==1: areafile = areafile[0] nc = dataset(areafile, 'r') - area = nc.variables['e2t'][:] * nc.variables['e1t'][:] + area = load_area(nc) nc.close() loaded_area_and_mask = True return area diff --git a/bgcval2/functions/BenCa.py b/bgcval2/functions/BenCa.py index e62cba89..40ea0d18 100644 --- a/bgcval2/functions/BenCa.py +++ b/bgcval2/functions/BenCa.py @@ -32,6 +32,7 @@ import numpy as np from bgcval2.bgcvaltools.dataset import dataset from bgcval2.functions.get_kwarg_file import get_kwarg_file +from bgcval2.functions.tools import load_area global loaded_area_and_mask global tmask @@ -48,7 +49,7 @@ def load_area_and_mask(areafile): else: raise ValueError(f"{areafile} must be a length=1 list containing a single file descriptor.") nc = dataset(areafile, 'r') - area = nc.variables['e2t'][:] * nc.variables['e1t'][:] + area = load_area(nc) nc.close() loaded_area_and_mask = True return area diff --git a/bgcval2/functions/InvtAlk.py b/bgcval2/functions/InvtAlk.py index 88b7d30e..dc8d05f3 100644 --- a/bgcval2/functions/InvtAlk.py +++ b/bgcval2/functions/InvtAlk.py @@ -32,6 +32,7 @@ import numpy as np from bgcval2.bgcvaltools.dataset import dataset from bgcval2.functions.get_kwarg_file import get_kwarg_file +from bgcval2.functions.tools import load_area global loaded_area_and_mask global tmask @@ -48,7 +49,7 @@ def load_area_and_mask(areafile): else: raise ValueError(f"{areafile} must be a length=1 list containing a single file descriptor.") nc = dataset(areafile, 'r') - area = nc.variables['e2t'][:] * nc.variables['e1t'][:] + area = load_area(nc) nc.close() loaded_area_and_mask = True return area diff --git a/bgcval2/functions/TotalIntPP.py b/bgcval2/functions/TotalIntPP.py index 6226fc56..294ee877 100644 --- a/bgcval2/functions/TotalIntPP.py +++ b/bgcval2/functions/TotalIntPP.py @@ -31,6 +31,7 @@ from bgcval2.bgcvaltools.dataset import dataset from bgcval2.functions.get_kwarg_file import get_kwarg_file from bgcval2.functions.standard_functions import find_best_var +from bgcval2.functions.tools import load_area global loadedArea global model_area @@ -41,10 +42,7 @@ def loadDataMask(gridfn): nc = dataset(gridfn,'r') - try: - model_area = nc.variables['area'][:] - except: - model_area = nc.variables['e1t'][:]*nc.variables['e2t'][:] + model_area = load_area(nc) nc.close() loadedArea = True return model_area diff --git a/bgcval2/functions/dust.py b/bgcval2/functions/dust.py index 702f71f9..02aa64db 100644 --- a/bgcval2/functions/dust.py +++ b/bgcval2/functions/dust.py @@ -42,7 +42,8 @@ def loadDataMask(gridfn): global loadedArea global masked_area nc = dataset(gridfn,'r') - masked_area = nc.variables['e2t'][:] * nc.variables['e1t'][:]*nc.variables['tmask'][0] + area = load_area(nc) + masked_area = area *nc.variables['tmask'][0] nc.close() loadedArea = True diff --git a/bgcval2/functions/globalVolMean.py b/bgcval2/functions/globalVolMean.py index 5d7f9ebb..e9b2bb43 100644 --- a/bgcval2/functions/globalVolMean.py +++ b/bgcval2/functions/globalVolMean.py @@ -31,15 +31,18 @@ import numpy as np from bgcval2.functions.standard_functions import choose_best_var - +from bgcval2.functions.tools import load_area def calc_vol(nc): """ Calculate volume from the (grid-T) netcdf file. """ - area = nc.variables['area'][:] + area = load_area(nc) thkcello = nc.variables['thkcello'][:] - area = area[None, None,:, :] + if area.ndim == 4: + area = area[None, None,:, :] + if area.ndim == 3: + area = area[None, :, :] return thkcello * area diff --git a/bgcval2/functions/ice.py b/bgcval2/functions/ice.py index e719d22b..0b830584 100644 --- a/bgcval2/functions/ice.py +++ b/bgcval2/functions/ice.py @@ -32,6 +32,7 @@ import numpy as np from bgcval2.bgcvaltools.dataset import dataset from bgcval2.functions.get_kwarg_file import get_kwarg_file +from bgcval2.functions.tools import load_area global loaded_area_and_mask global tmask @@ -50,7 +51,7 @@ def load_area_and_mask(gridfn, maskname,): gridfn = gridfn[0] nc = dataset(gridfn, 'r') tmask = nc.variables[maskname][0] - area = nc.variables['e2t'][:] * nc.variables['e1t'][:] + area = load_area(nc) lat = nc.variables['nav_lat'][:] nc.close() loaded_area_and_mask = True @@ -74,7 +75,7 @@ def calculate_ice_extent(nc, keys, **kwargs): if 'area' not in nc.variables and not loaded_area_and_mask: area, tmask, lat = load_area_and_mask(areafile, maskname) else: - area = nc.variables['area'][:] + area = load_area(nc) lat = nc.variables['nav_lat'][:] tmask = nc.variables[keys[0]][:].squeeze().mask diff --git a/bgcval2/functions/tools.py b/bgcval2/functions/tools.py new file mode 100644 index 00000000..74937784 --- /dev/null +++ b/bgcval2/functions/tools.py @@ -0,0 +1,48 @@ +# Copyright 2023, Plymouth Marine Laboratory +# +# This file is part of the bgc-val library. +# +# bgc-val is free software: you can redistribute it and/or modify it +# under the terms of the Revised Berkeley Software Distribution (BSD) 3-clause license. + +# bgc-val is distributed in the hope that it will be useful, but +# without any warranty; without even the implied warranty of merchantability +# or fitness for a particular purpose. See the revised BSD license for more details. +# You should have received a copy of the revised BSD license along with bgc-val. +# If not, see . +# +# Address: +# Plymouth Marine Laboratory +# Prospect Place, The Hoe +# Plymouth, PL1 3DH, UK +# +# Email: +# ledm@pml.ac.uk +# +""" +.. module:: tools + :platform: Unix + :synopsis: This uses some tools for the functions library. + +.. moduleauthor:: Lee de Mora + +""" + + +import numpy as np +from bgcval2.functions.standard_functions import choose_best_var + + +def load_area(nc): + """ + Generic tool for loading area: + """ + area_keys = ['area', 'area_grid_T', 'area_grid_W', 'area_grid_V', 'area_grid_U'] + if set(area_keys).intersection(set(nc.variables.keys())): + area = choose_best_var(nc, area_keys) + elif set(['e1t', 'e2t']).intersection(set(nc.variables.keys())): + area = nc.variables['e1t'][:]*nc.variables['e2t'][:] + else: + raise ValueError(f"Provided {nc} file doesn't contain any of permitted area variables {area_keys}") + return area +