From 06be40d5df1599fdabec9482077852f65cbf1fd8 Mon Sep 17 00:00:00 2001 From: michaelchin Date: Mon, 19 Aug 2024 19:26:51 +1000 Subject: [PATCH 1/5] filter the feature collection by feature type --- gplately/commands/feature_filter.py | 78 ++++++++++++++++++++++++++--- scripts/test_feature_filter.sh | 8 +++ 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/gplately/commands/feature_filter.py b/gplately/commands/feature_filter.py index 89f61851..1e7b42fd 100644 --- a/gplately/commands/feature_filter.py +++ b/gplately/commands/feature_filter.py @@ -17,10 +17,14 @@ import abc import argparse +import logging +import re from typing import List import pygplates +logger = logging.getLogger("gplately") + class FeatureFilter(metaclass=abc.ABCMeta): @classmethod @@ -135,6 +139,34 @@ def should_keep(self, feature: pygplates.Feature) -> bool: return False +class FeatureTypeFilter(FeatureFilter): + """filter features by the feature type(regular expression) + + examples: + - gplately filter "$IN_FILE" output/basins.gpmlz -t gpml:Basin + - gplately filter "$IN_FILE" output/basin_islandarc.gpmlz -t "gpml:IslandArc|gpml:Basin" + + :param feature_type_re: the regular expression to match the feature type + + """ + + def __init__(self, feature_type_re: str): + self._feature_type_re = feature_type_re + + def should_keep(self, feature: pygplates.Feature) -> bool: + feature_type = feature.get_feature_type() + if re.fullmatch(self._feature_type_re, feature_type.to_qualified_string()): + logger.debug( + f"feature type match: {self._feature_type_re} {feature_type.to_qualified_string()}" + ) + return True + else: + logger.debug( + f"feature type not match: {self._feature_type_re} {feature_type.to_qualified_string()}" + ) + return False + + def filter_feature_collection( feature_collection: pygplates.FeatureCollection, filters: List[FeatureFilter] ): @@ -168,27 +200,56 @@ def add_parser(subparser): filter_cmd.add_argument("filter_input_file", type=str) filter_cmd.add_argument("filter_output_file", type=str) + # filter by feature name name_group = filter_cmd.add_mutually_exclusive_group() - name_group.add_argument("-n", "--names", type=str, dest="names", nargs="+") name_group.add_argument( - "--exclude-names", type=str, dest="exclude_names", nargs="+" + "-n", "--names", type=str, dest="names", nargs="+", metavar="feature_name" + ) + name_group.add_argument( + "--exclude-names", + type=str, + dest="exclude_names", + nargs="+", + metavar="feature_name", ) + # filter by plate ID pid_group = filter_cmd.add_mutually_exclusive_group() - pid_group.add_argument("-p", "--pids", type=int, dest="pids", nargs="+") - pid_group.add_argument("--exclude-pids", type=int, dest="exclude_pids", nargs="+") + pid_group.add_argument( + "-p", "--pids", type=int, dest="pids", nargs="+", metavar="pid" + ) + pid_group.add_argument( + "--exclude-pids", type=int, dest="exclude_pids", nargs="+", metavar="pid" + ) + # filter by birth age birth_age_group = filter_cmd.add_mutually_exclusive_group() birth_age_group.add_argument( - "-a", "--min-birth-age", type=float, dest="min_birth_age" + "-a", + "--min-birth-age", + type=float, + dest="min_birth_age", + metavar="min_birth_age", + ) + birth_age_group.add_argument( + "--max-birth-age", type=float, dest="max_birth_age", metavar="max_birth_age" ) - birth_age_group.add_argument("--max-birth-age", type=float, dest="max_birth_age") filter_cmd.add_argument( "--case-sensitive", dest="case_sensitive", action="store_true" ) filter_cmd.add_argument("--exact-match", dest="exact_match", action="store_true") + # filter by feature type + filter_cmd.add_argument( + "-t", + "--feature-type", + type=str, + dest="feature_type_re", + metavar="feature_type", + help="the regular expression of feature type", + ) + def run_filter_feature_collection(args): """Filter the input feature collection according to command line arguments.""" @@ -224,12 +285,15 @@ def run_filter_feature_collection(args): elif args.min_birth_age is not None: filters.append(BirthAgeFilter(args.min_birth_age)) + if args.feature_type_re is not None: + filters.append(FeatureTypeFilter(args.feature_type_re)) + new_fc = filter_feature_collection( input_feature_collection, filters, ) new_fc.write(args.filter_output_file) - print( + logger.info( f"Done! The filtered feature collection has been saved to {args.filter_output_file}." ) diff --git a/scripts/test_feature_filter.sh b/scripts/test_feature_filter.sh index cafab546..879075b5 100755 --- a/scripts/test_feature_filter.sh +++ b/scripts/test_feature_filter.sh @@ -60,3 +60,11 @@ gplately filter "$IN_FILE" output/no_africa_north_america.gpmlz --exclude-names # get features whose name does not conain "Africa" or "North America" and plate ID is not in 401 702 gplately filter "$IN_FILE" output/no_africa_north_america_no_401_702.gpmlz --exclude-names Africa "North America" --exclude-pids 401 702 + +# get all gpml:Basin features + +gplately filter "$IN_FILE" output/basins.gpmlz -t gpml:Basin + +# get all gpml:Basin + gpml:IslandArc features + +gplately filter "$IN_FILE" output/basin_islandarc.gpmlz -t "gpml:IslandArc|gpml:Basin" From f277a069877cda7ee94e779415b41a8775b944a0 Mon Sep 17 00:00:00 2001 From: michaelchin Date: Mon, 26 Aug 2024 12:57:04 +1000 Subject: [PATCH 2/5] check in some experimental code --- gplately/commands/reset_feature_type.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 gplately/commands/reset_feature_type.py diff --git a/gplately/commands/reset_feature_type.py b/gplately/commands/reset_feature_type.py new file mode 100644 index 00000000..34fa4d58 --- /dev/null +++ b/gplately/commands/reset_feature_type.py @@ -0,0 +1,15 @@ +import pygplates + +new_fc = pygplates.FeatureCollection() +for f in pygplates.FeatureCollection("shapes_continents.gpml"): + # print(f.get_feature_type()) + new_f = pygplates.Feature( + pygplates.FeatureType.gpml_unclassified_feature, + f.get_feature_id(), + pygplates.VerifyInformationModel.yes, + ) + for p in f: + new_f.add(p.get_name(), p.get_value()) + new_fc.add(new_f) + +new_fc.write("new_shapes_continents.gpmlz") From 110a09b85f1f161769b55cf01ff98967a15b59f6 Mon Sep 17 00:00:00 2001 From: michaelchin Date: Mon, 26 Aug 2024 13:20:56 +1000 Subject: [PATCH 3/5] set VerifyInformationModel.yes when adding property --- gplately/commands/reset_feature_type.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gplately/commands/reset_feature_type.py b/gplately/commands/reset_feature_type.py index 34fa4d58..b4363fb5 100644 --- a/gplately/commands/reset_feature_type.py +++ b/gplately/commands/reset_feature_type.py @@ -9,7 +9,7 @@ pygplates.VerifyInformationModel.yes, ) for p in f: - new_f.add(p.get_name(), p.get_value()) + new_f.add(p.get_name(), p.get_value(), pygplates.VerifyInformationModel.yes) new_fc.add(new_f) new_fc.write("new_shapes_continents.gpmlz") From 205872cdb774d2fca2547908d1a69eb42d433596 Mon Sep 17 00:00:00 2001 From: michaelchin Date: Mon, 26 Aug 2024 17:09:28 +1000 Subject: [PATCH 4/5] use setuptools-git-versioning --- gplately/__init__.py | 22 ++++++++++++++++------ pyproject.toml | 9 ++++++--- tests-dir/unittest/test_plate_model.py | 5 +++++ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/gplately/__init__.py b/gplately/__init__.py index 5a134542..91de58c5 100644 --- a/gplately/__init__.py +++ b/gplately/__init__.py @@ -200,7 +200,17 @@ """ -__version__ = "1.3.0" + +def get_distribution_version(): + from importlib.metadata import PackageNotFoundError, version + + try: + return version(__name__) + except PackageNotFoundError: + return "UNKNOWN VERSION" + + +__version__ = get_distribution_version() REQUIRED_PMM_VERSION = "1.2.0" USING_DEV_VERSION = True ## change this to False before official release @@ -214,16 +224,16 @@ print() print("##########################################################################") print( - """ + f""" WARNING: - You are using a DEV version GPlately. Some functionalities have not been tested thoroughly. - The DEV version may break your code or produce wrong results due to its unstable nature(DEV in progress). + You are using a DEV version 👉({__version__})👈 GPlately. Some functionalities have not been tested thoroughly. + The DEV version may break your code or produce wrong results due to its unstable nature (DEV in progress). You might also need to install the DEV version plate_model_manager from https://github.com/michaelchin/plate-model-manager to use this DEV version GPlately. - To disable this warning, set USING_DEV_VERSION to False in __init__.py or + 🚫 To disable this warning, set USING_DEV_VERSION to False in __init__.py or set DISABLE_GPLATELY_DEV_WARNING environment variable to true. - `export DISABLE_GPLATELY_DEV_WARNING=true` + 👉`export DISABLE_GPLATELY_DEV_WARNING=true`👈 """ ) print("##########################################################################") diff --git a/pyproject.toml b/pyproject.toml index 40244f99..f7fc58e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,10 @@ [build-system] -requires = ["setuptools>=61.0.0", "wheel"] +requires = ["setuptools>=61.0.0", "wheel", "setuptools-git-versioning"] build-backend = "setuptools.build_meta" +[tool.setuptools-git-versioning] +enabled = true + [project] name = "gplately" dynamic = ["version"] @@ -42,8 +45,8 @@ where = ["."] exclude = ['*.examples*','*.notebooks*','tests-dir*','Notebooks*', 'scripts*'] namespaces = true -[tool.setuptools.dynamic] -version = {attr = "gplately.__version__"} +#[tool.setuptools.dynamic] +#version = {attr = "gplately.__version__"} [project.optional-dependencies] dev = ["black", "bumpver", "isort", "pip-tools", "pytest"] diff --git a/tests-dir/unittest/test_plate_model.py b/tests-dir/unittest/test_plate_model.py index 9b4badc2..49c07aa6 100755 --- a/tests-dir/unittest/test_plate_model.py +++ b/tests-dir/unittest/test_plate_model.py @@ -3,6 +3,11 @@ from common import MODEL_REPO_DIR from plate_model_manager import PlateModelManager +import gplately + +print(gplately.__version__) +print(gplately.__file__) + def main(): pm_manger = PlateModelManager() From ce0f89400adcbc1f69629975d9a4b72d7ae07f77 Mon Sep 17 00:00:00 2001 From: michaelchin Date: Wed, 28 Aug 2024 19:27:11 +1000 Subject: [PATCH 5/5] test workflow --- gplately/__init__.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/gplately/__init__.py b/gplately/__init__.py index 91de58c5..29c5b09c 100644 --- a/gplately/__init__.py +++ b/gplately/__init__.py @@ -226,14 +226,7 @@ def get_distribution_version(): print( f""" WARNING: - You are using a DEV version 👉({__version__})👈 GPlately. Some functionalities have not been tested thoroughly. - The DEV version may break your code or produce wrong results due to its unstable nature (DEV in progress). - You might also need to install the DEV version plate_model_manager - from https://github.com/michaelchin/plate-model-manager to use this DEV version GPlately. - - 🚫 To disable this warning, set USING_DEV_VERSION to False in __init__.py or - set DISABLE_GPLATELY_DEV_WARNING environment variable to true. - 👉`export DISABLE_GPLATELY_DEV_WARNING=true`👈 + git """ ) print("##########################################################################")