diff --git a/gplately/__init__.py b/gplately/__init__.py index 2def5970..9b5b399a 100644 --- a/gplately/__init__.py +++ b/gplately/__init__.py @@ -204,7 +204,7 @@ from .utils.log_utils import get_debug_level, setup_logging, turn_on_debug_logging from .utils.version import get_distribution_version -REQUIRED_PMM_VERSION = "1.2.0" # TODO: get this from package meta +REQUIRED_PMM_VERSION = "1.2.1" # TODO: get this from package meta USING_DEV_VERSION = True ## change this to False before official release __version__ = get_distribution_version() @@ -274,7 +274,6 @@ "pygplates", "io_utils", "reconstruction", - "plate_model_manager", "ptt", "spatial", # Classes diff --git a/gplately/commands/create_age_grids.py b/gplately/commands/create_age_grids.py index 84ee170a..ec6d3ccc 100644 --- a/gplately/commands/create_age_grids.py +++ b/gplately/commands/create_age_grids.py @@ -21,20 +21,20 @@ import multiprocessing import time import warnings -from typing import Optional, Sequence, Union +from typing import List from plate_model_manager import PlateModel, PlateModelManager from gplately import PlateReconstruction, PlotTopologies, SeafloorGrid from ..pygplates import FeatureCollection as gFeatureCollection -from ..pygplates import FeaturesFunctionArgument +from ..pygplates import FeaturesFunctionArgument # type: ignore from ..pygplates import RotationModel as gRotationModel logger = logging.getLogger("gplately") -def add_parser(parser: argparse.ArgumentParser): +def add_parser(parser): """add command line argument parser""" agegrid_cmd = parser.add_parser( @@ -74,7 +74,6 @@ def add_parser(parser: argparse.ArgumentParser): nargs="*", help="input continental polygons files", dest="continents_filenames", - default=None, ) agegrid_cmd.add_argument( "-r", @@ -158,14 +157,14 @@ def add_parser(parser: argparse.ArgumentParser): Example usage: - gplately ag output -m merdith2021 -e 0 -s 10 - - gplately ag plate-model-repo/muller2019/Rotations/Muller_etal_2019_CombinedRotations.rot plate-model-repo/muller2019/Topologies/Muller_etal_2019_PlateBoundaries_DeformingNetworks.gpmlz output -c plate-model-repo/muller2019/ContinentalPolygons/Global_EarthByte_GPlates_PresentDay_ContinentalPolygons_2019_v1.shp -e 0 -s 10 + - gplately ag rotations.rot topologies.gpmlz output -c continental_polygons.gpmlz -e 0 -s 10 """ def create_agegrids( model_name: str, - input_filenames: Union[str, Sequence[str]], - continents_filenames: Union[str, Sequence[str]], + input_filenames: List[str], + continents_filenames: List[str], output_dir: str, min_time: float, max_time: float, @@ -175,26 +174,47 @@ def create_agegrids( grid_spacing: float = 0.1, ridge_sampling: float = 0.5, initial_spreadrate: float = 75, - file_collection: Optional[str] = None, + file_collection: str = "", unmasked: bool = False, + plate_model_repo: str = "plate-model-repo", ) -> None: """Create age grids for a plate model.""" if model_name: + if input_filenames or continents_filenames: + raise Exception( + f"The model name({model_name}) is provided with -m or --model. \n" + + f"But the INPUT_FILES and/or CONTINENTS_FILE are also provided. \n" + + f"The MODEL_NAME and (INPUT_FILES, CONTINENTS_FILE) are mutually exclusive. \n" + + f"You either use (-m,--model) to specify a model name or use the first positional arguments and (-c,--continents) to specify the file paths. But not both.\n" + + f"Fix your command line and try again." + ) try: + # TODO: make "plate-model-repo" an optional parameter plate_model = PlateModelManager().get_model( - model_name, data_dir="plate-model-repo" + model_name, data_dir=plate_model_repo ) except: + # try to use the plate model in the local folder if the network is down. plate_model = PlateModel( - model_name, data_dir="plate-model-repo", readonly=True + model_name, data_dir=plate_model_repo, readonly=True + ) + + if not plate_model: + raise Exception( + f"Unable to create PlateModel object for model {model_name}. " + + f"Check your network connection and make sure the model name is correct. Run `pmm ls` to get a list of available model names." ) rotation_files = plate_model.get_rotation_model() - topology_files = plate_model.get_topologies() - continent_files = plate_model.get_layer("ContinentalPolygons") + topology_files = plate_model.get_layer( + "Topologies", return_none_if_not_exist=True + ) + continent_files = plate_model.get_layer( + "ContinentalPolygons", return_none_if_not_exist=True + ) if "Cratons" in plate_model.get_avail_layers(): - continent_files += plate_model.get_layer("Cratons") + continent_files += plate_model.get_layer("Cratons") # type: ignore else: rotation_files = [] @@ -212,8 +232,28 @@ def create_agegrids( continent_files = continents_filenames + if not rotation_files: + raise Exception( + "No rotation file(s) found. User must either provide rotation file(s) in the first positional arguments or specify a model name with (-m,--model)." + ) rotations = gRotationModel(rotation_files) + + if not topology_files: + error_msg = "No topology file(s) found. " + if model_name: + error_msg += f"Make sure the model ({model_name}) has topology. Run `pmm ls {model_name}` to check the model." + else: + error_msg += f"You need to specify the topology files in the first positional arguments." + raise Exception(error_msg) topologies = gFeatureCollection.from_file_list(topology_files) + + if not continent_files: + error_msg = "No continental polygon file(s) found. " + if model_name: + error_msg += f"Make sure the model ({model_name}) has continental polygons. Run `pmm ls {model_name}` to check the model." + else: + error_msg += f"You need to specify the continental polygon files with (-c,--continents). Run `gplately ag -h` to see help." + raise Exception(error_msg) continents = gFeatureCollection.from_file_list(continent_files) with warnings.catch_warnings(): diff --git a/gplately/commands/regrid.py b/gplately/commands/regrid.py index a1885197..2290b011 100644 --- a/gplately/commands/regrid.py +++ b/gplately/commands/regrid.py @@ -30,7 +30,7 @@ logger = logging.getLogger("gplately") -def add_parser(parser: argparse.ArgumentParser): +def add_parser(parser): """add command line argument parser""" grid_cmd = parser.add_parser( @@ -92,19 +92,18 @@ def add_parser(parser: argparse.ArgumentParser): - gplately grid inputDirectory --significant-digits 2 outputDirectory """ + def _batch_regrid_netcdf4( - input_raster_filename, + input_raster_filename, output_raster_filename, resample=None, - significant_digits=None): + significant_digits=None, +): - grid = read_netcdf_grid( - input_raster_filename, - resample=resample) + grid = read_netcdf_grid(input_raster_filename, resample=resample) write_netcdf_grid( - output_raster_filename, - grid, - significant_digits=significant_digits) + output_raster_filename, grid, significant_digits=significant_digits + ) print(" {} complete!".format(output_raster_filename)) @@ -120,14 +119,13 @@ def _regrid_netcdf4(args): # determine if directory or filename p_input = pathlib.Path(args.input_grid_filename) - p_output= pathlib.Path(args.output_grid_filename) + p_output = pathlib.Path(args.output_grid_filename) if args.grid_spacing is None: grid_spacing = None else: grid_spacing = (args.grid_spacing, args.grid_spacing) - if p_input.is_file(): input_filename = p_input if p_output.suffix: @@ -137,10 +135,11 @@ def _regrid_netcdf4(args): output_filename = p_output.joinpath(p_input.name) _batch_regrid_netcdf4( - input_filename, - output_filename, - resample=grid_spacing, - significant_digits=args.significant_digits) + input_filename, + output_filename, + resample=grid_spacing, + significant_digits=args.significant_digits, + ) elif p_input.is_dir(): if p_output.suffix: @@ -150,19 +149,28 @@ def _regrid_netcdf4(args): input_raster_filenames = [] output_raster_filenames = [] for pathname in p_input.iterdir(): - if pathname.suffix == '.nc' and pathname.is_file() and not pathname.name.startswith('.'): + if ( + pathname.suffix == ".nc" + and pathname.is_file() + and not pathname.name.startswith(".") + ): input_raster_filenames.append(pathname) output_raster_filenames.append(p_output.joinpath(pathname.name)) - print("Found {} netCDF files. Processing...".format(len(input_raster_filenames))) + print( + "Found {} netCDF files. Processing...".format(len(input_raster_filenames)) + ) if n_jobs == 1: - for in_name, out_name in zip(input_raster_filenames, output_raster_filenames): + for in_name, out_name in zip( + input_raster_filenames, output_raster_filenames + ): _batch_regrid_netcdf4( in_name, out_name, resample=grid_spacing, - significant_digits=args.significant_digits) + significant_digits=args.significant_digits, + ) else: with multiprocessing.Pool(n_jobs) as pool: @@ -171,7 +179,8 @@ def _regrid_netcdf4(args): _batch_regrid_netcdf4, resample=grid_spacing, significant_digits=args.significant_digits, - ), zip(input_raster_filenames, output_raster_filenames) + ), + zip(input_raster_filenames, output_raster_filenames), ) else: diff --git a/gplately/utils/dev_warning.py b/gplately/utils/dev_warning.py index 088be3e3..23cda8bb 100644 --- a/gplately/utils/dev_warning.py +++ b/gplately/utils/dev_warning.py @@ -61,11 +61,19 @@ def print_using_source_code_warning(version: str): if not disable_dev_warning: if os.path.isdir( f"{os.path.dirname(os.path.realpath(__file__))}/../.git" - ) or not os.path.isfile( - f"{os.path.dirname(os.path.realpath(__file__))}/../../../../bin/gplately" + ) or not ( + os.path.isfile( + f"{os.path.dirname(os.path.realpath(__file__))}/../../../../bin/gplately" + ) + or os.path.isfile( + f"{os.path.dirname(os.path.realpath(__file__))}/../../../../Scripts/gplately.exe" + ) ): logger.warning( - f"The location of GPlately currently in use is {os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}. " - + f"It seems that you are using GPlately source code directly or installed editable package with `pip install -e .`, " + f"It seems that you are using GPlately source code directly or installed editable package with `pip install -e .`, " + f"the version number({version}) may not be accurate in these cases." ) + + logger.info( + f"The location of GPlately currently in use is {os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}. " + ) diff --git a/pyproject.toml b/pyproject.toml index 3cd2956c..7ca1623b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ dependencies = [ "rasterio", "geopandas", "stripy", - "plate-model-manager>=1.2.0", + "plate-model-manager>=1.2.1", "pyyaml", "pygmt", "rioxarray", diff --git a/setup.py b/setup.py index cbf50e70..b3e18d42 100644 --- a/setup.py +++ b/setup.py @@ -97,7 +97,7 @@ def _minimal_ext_cmd(cmd): "rasterio", "geopandas", "stripy", - "plate-model-manager", + "plate-model-manager>=1.2.1", "pyyaml", "pygmt", "rioxarray",