diff --git a/release/scripts/OnlyUpdateEFOAssociations.py b/release/scripts/OnlyUpdateEFOAssociations.py new file mode 100644 index 00000000..41beebfe --- /dev/null +++ b/release/scripts/OnlyUpdateEFOAssociations.py @@ -0,0 +1,45 @@ +from django.db import transaction +from catalog.models import EFOTrait_Ontology, Score, Release + + +class OnlyUpdateEFOAssociations: + """This class updates the EFO trait associations of the given scores without rebuilding + the whole EFO ontology as UpdateEFO does. This might be useful when one or several + EFO traits went obsolete, although we don't want to reflect this change yet in the PGS Catalog.""" + + def get_current_release_scores(self): + """Retrieve the scores of the ongoing release, assuming this process is executed + as part of the release post-processing.""" + latest_release = Release.objects.latest('date') + return Score.objects.filter(date_released=latest_release.date) + + def add_score_efo_trait_associations(self, score): + """Add EFO trait associations to the given score.""" + efo_traits = score.trait_efo.all() + for efo_trait in efo_traits: + try: + efo_trait_ontology = EFOTrait_Ontology.objects.get(id=efo_trait.id) + efo_trait_ontology.scores_direct_associations.add(score) + efo_trait_ontology.save() + for efo_trait_parent in efo_trait_ontology.parent_traits.all(): + efo_trait_parent.scores_child_associations.add(score) + efo_trait_parent.save() + except EFOTrait_Ontology.DoesNotExist as e: + print(f'ERROR: {efo_trait.id} is a new trait, UpdateEFO cannot be bypassed.') + raise e + + def add_efo_trait_associations(self): + """Main function.""" + latest_scores = self.get_current_release_scores() + with transaction.atomic(): + try: + for score in latest_scores: + self.add_score_efo_trait_associations(score) + except Exception as e: + transaction.rollback() + raise e + + +def run(): + only_update_efo_associations = OnlyUpdateEFOAssociations() + only_update_efo_associations.add_efo_trait_associations() \ No newline at end of file diff --git a/release/scripts/run_post_processing_script.py b/release/scripts/run_post_processing_script.py index be71a64b..8d24f093 100644 --- a/release/scripts/run_post_processing_script.py +++ b/release/scripts/run_post_processing_script.py @@ -1,13 +1,14 @@ -import sys, os.path, shutil, glob from django.db.models import Count from catalog.models import * from release.scripts.RemoveDataForRelease import NonReleasedDataToRemove +from release.scripts.OnlyUpdateEFOAssociations import OnlyUpdateEFOAssociations from release.scripts.UpdateScoreAncestry import UpdateScoreAncestry from release.scripts.UpdateScoreEvaluated import UpdateScoreEvaluated from release.scripts.UpdateReleasedCohorts import UpdateReleasedCohorts from release.scripts.UpdateEFO import UpdateEFO -def run(): + +def run(*args): """ Main method executed by the Django command: `python manage.py runscript run_post_processing_script` @@ -30,8 +31,12 @@ def run(): # Update the cohorts (update the Cohort "released" field) update_released_cohorts() - # Update the trait information and ontology - update_efo() + if 'update_efo_associations_only' in args: + # Simply update trait associations without rebuilding the ontology + update_efo_associations_only() + else: + # Update the trait information and ontology + update_efo() # Display the list of new EFO traits in the catalog display_new_efo() @@ -76,6 +81,13 @@ def update_efo(): update_efo.launch_efo_updates() +def update_efo_associations_only(): + """ Skipping EFO rebuilding, just adding scores and traits associations """ + report_header("kipping EFO rebuilding, just adding scores and traits associations.") + update_efo_associations = OnlyUpdateEFOAssociations() + update_efo_associations.add_efo_trait_associations() + + def display_new_efo(): """ Display the list of new Traits added with the new release """ new_release = Release.objects.latest('date').date