diff --git a/src/frontend_celery/start_keycloak.sh b/src/frontend_celery/start_keycloak.sh index 54535edf..7e6d4d4f 100755 --- a/src/frontend_celery/start_keycloak.sh +++ b/src/frontend_celery/start_keycloak.sh @@ -59,8 +59,8 @@ keycloak_path=$tools/keycloak if [ "${WEBAPP_ENV}" == "dev" ] then - export NO_PROXY=srv018.img.med.uni-tuebingen.de - $keycloak_path/bin/kc.sh start-dev --hostname srv018.img.med.uni-tuebingen.de --http-port 5050 #--features=admin-fine-grained-authz # --log-level debug + export NO_PROXY=srv020.img.med.uni-tuebingen.de + $keycloak_path/bin/kc.sh start-dev --hostname srv020.img.med.uni-tuebingen.de --http-port 5050 #--features=admin-fine-grained-authz # --log-level debug fi if [ "${WEBAPP_ENV}" == "prod" ] diff --git a/src/frontend_celery/webapp/io/download_routes.py b/src/frontend_celery/webapp/io/download_routes.py index 9adfe907..7bf7c8ea 100644 --- a/src/frontend_celery/webapp/io/download_routes.py +++ b/src/frontend_celery/webapp/io/download_routes.py @@ -285,18 +285,21 @@ def calculate_class(scheme_type, selected_classes = ''): if scheme_type == 'task-force': final_class = decide_for_class_task_force(selected_classes) - if scheme_type == 'acmg-enigma-brca1': + if 'acmg' in scheme_type: selected_classes = [re.sub(r'[0-9]+', '', x) for x in selected_classes] # remove numbers from critera if there are any class_counts = get_class_counts(selected_classes) # count how often we have each strength - #print(class_counts) - possible_classes = get_possible_classes_enigma_brca1(class_counts) # get a set of possible classes depending on selected criteria - final_class = decide_for_class_acmg(possible_classes) # decide for class - if scheme_type == 'acmg-enigma-brca2': - selected_classes = [re.sub(r'[0-9]+', '', x) for x in selected_classes] # remove numbers from critera if there are any - class_counts = get_class_counts(selected_classes) # count how often we have each strength - #print(class_counts) - possible_classes = get_possible_classes_enigma_brca2(class_counts) # get a set of possible classes depending on selected criteria + if 'brca1' in scheme_type: + possible_classes = get_possible_classes_enigma_brca1(class_counts) # get a set of possible classes depending on selected criteria + elif 'brca2' in scheme_type: + possible_classes = get_possible_classes_enigma_brca2(class_counts) # get a set of possible classes depending on selected criteria + elif 'palb2' in scheme_type: + possible_classes = get_possible_classes_enigma_palb2(class_counts) # get a set of possible classes depending on selected criteria + elif 'tp53' in scheme_type: + possible_classes = get_possible_classes_enigma_tp53(class_counts) # get a set of possible classes depending on selected criteria + else: + raise RuntimeError('The class could not be calculated with given parameters. Did you specify a supported scheme? (either "acmg" or VUS "task-force" based)') + final_class = decide_for_class_acmg(possible_classes) # decide for class if final_class is None: @@ -308,6 +311,108 @@ def calculate_class(scheme_type, selected_classes = ''): +def get_possible_classes_enigma_tp53(class_counts): + + possible_classes = set() + + # numbering comments are nubmers from the official ACMG paper: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4544753/ (TABLE 5) + # pathogenic + if class_counts['pvs'] == 1: # 1 + if class_counts['ps'] == 1 or class_counts['pm'] >= 2 or (class_counts['pm'] == 1 and class_counts['pp'] == 1) or class_counts['pp'] >= 2: + possible_classes.add(5) + if class_counts['ps'] >= 2: # 2 + possible_classes.add(5) + if class_counts['ps'] == 1: # 3 + if class_counts['pm'] >= 3 or (class_counts['pm'] == 2 and class_counts['pp'] >= 2) or (class_counts['pm'] == 1 and class_counts['pp'] >= 4): + possible_classes.add(5) + + # likely pathogenic + if class_counts['ps'] == 1: + if class_counts['pm'] >= 1 or class_counts['pp'] >= 2: # 3 + possible_classes.add(4) + if class_counts['pm'] >= 3: # 4 + possible_classes.add(4) + if class_counts['pm'] == 2 and class_counts['pp'] >= 2: # 5 + possible_classes.add(4) + if class_counts['pm'] == 1 and class_counts['pp'] >= 4: # 6 + possible_classes.add(4) + if class_counts['pvs'] == 1: + if class_counts['pm'] == 1 or class_counts['pp'] == 1: + possible_classes.add(4) + + # benign + if class_counts['ba'] == 1: # 1 + possible_classes.add(1) + if class_counts['bs'] >= 2: # 2 + possible_classes.add(1) + + # likely benign + if class_counts['bs'] == 1 and class_counts['bp'] == 1: # 1 + possible_classes.add(2) + if class_counts['bp'] >= 2: # 2 + possible_classes.add(2) + + #print(class_counts) + #print(possible_classes) + + return possible_classes + + + + +def get_possible_classes_enigma_palb2(class_counts): + + possible_classes = set() + + # numbering comments are nubmers from the official ACMG paper: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4544753/ (TABLE 5) + # pathogenic + if class_counts['pvs'] == 1: # 1 + if class_counts['ps'] == 1 or class_counts['pm'] >= 2 or (class_counts['pm'] == 1 and class_counts['pp'] == 1) or class_counts['pp'] >= 2: + possible_classes.add(5) + if class_counts['ps'] >= 2: # 2 + possible_classes.add(5) + if class_counts['ps'] == 1: # 3 + if class_counts['pm'] >= 3 or (class_counts['pm'] == 2 and class_counts['pp'] >= 2) or (class_counts['pm'] == 1 and class_counts['pp'] >= 4): + possible_classes.add(5) + + # likely pathogenic + if class_counts['ps'] == 1: + if class_counts['pm'] == 1 or class_counts['pp'] >= 2 or class_counts['pm'] == 2: # 3 + possible_classes.add(4) + if class_counts['pm'] >= 3: # 4 + possible_classes.add(4) + if class_counts['pm'] == 2 and class_counts['pp'] >= 2: # 5 + possible_classes.add(4) + if class_counts['pm'] == 1 and class_counts['pp'] >= 4: # 6 + possible_classes.add(4) + if class_counts['pvs'] == 1: + if class_counts['pm'] == 1 or class_counts['pp'] == 1: + possible_classes.add(4) + + # benign + if class_counts['ba'] == 1: # 1 + possible_classes.add(1) + if class_counts['bs'] >= 2: # 2 + possible_classes.add(1) + + # likely benign + if class_counts['bs'] == 1 and class_counts['bp'] == 1: # 1 + possible_classes.add(2) + if class_counts['bp'] >= 2: # 2 + possible_classes.add(2) + if class_counts['bs'] == 1: # 2 + possible_classes.add(2) + + #print(class_counts) + #print(possible_classes) + + return possible_classes + + + + + + def get_possible_classes_enigma_brca2(class_counts): possible_classes = set() diff --git a/src/frontend_celery/webapp/static/js/classify.js b/src/frontend_celery/webapp/static/js/classify.js index ec556cdf..0ca7b70f 100644 --- a/src/frontend_celery/webapp/static/js/classify.js +++ b/src/frontend_celery/webapp/static/js/classify.js @@ -724,7 +724,7 @@ function create_criteria_buttons() { var default_strength = current_criterium['default_strength'] var criterium_type = criterium_id[0] // a task force criterium -> the type is determined by the first digit - if (scheme_type === 'acmg' || scheme_type === 'acmg-enigma-brca1'|| scheme_type === 'acmg-enigma-brca2') { + if (scheme_type.includes('acmg')) { criterium_type = criterium_id.replace(/\d+/g, '') // an acmg criterium. The type is determined by the first two or three letters } @@ -769,7 +769,7 @@ function create_criteria_buttons() { // sort helper function compare_criteria() { return function(a, b) { - if (scheme_type === 'acmg' || scheme_type === 'acmg-enigma-brca1' || scheme_type === 'acmg-enigma-brca2') { + if (scheme_type.includes('acmg')) { const criterium_order = {'PVS': 1, 'PS': 2, 'PM': 3, 'PP': 4, 'BP': 5, 'BS': 6, 'BA': 7} const a_letters = a.slice(0, -1) const a_crit_num = parseInt(a.slice(-1)) diff --git a/src/frontend_celery/webapp/utils/create_classification_scheme.py b/src/frontend_celery/webapp/utils/create_classification_scheme.py index a7404756..9d0303c4 100644 --- a/src/frontend_celery/webapp/utils/create_classification_scheme.py +++ b/src/frontend_celery/webapp/utils/create_classification_scheme.py @@ -4,7 +4,7 @@ from common.db_IO import Connection import common.functions as functions import json - +import argparse def insert_criterium_scheme(conn: Connection, data): @@ -82,61 +82,9 @@ def get_criterium(all_criteria, criterium_name): return criterium return None -if __name__ == "__main__": - - conn = Connection(roles = ['super_user']) - - data = json.loads(open("/mnt/storage2/users/ahdoebm1/HerediVar/resources/classification_schemes/ClinGen_BRCA1_v1.0.0.json").read()) - - """ - data = { - 'classification_scheme_id': "10", # leave blank to specify new scheme or provide id to specify an update - 'name': "testscheme", - 'display_name': "yoyotest", - 'type': "acmg", - 'reference': "#", - 'criteria': [ # compute classification_scheme_id - { - "name": "PSVS1", # has to be unique because of the mutually exclusive criteria list - "description": "THIS IS A TEST", - "is_selectable": "1", - "relevant_info": "", - "strengths": [ # compute classification_criterium_id - { - 'name': "pvs", - 'description': "pathogenic very strong", - 'is_default': "1" - }, - { - 'name': "ps", - 'description': "pathogenic strong", - 'is_default': "0" - } - ], - "mutually_exclusive_criteria": [ # list of criterium names - "PS1" - ] - }, - - { - "name": "PS1", # has to be unique because of the mutually exclusive criteria list - "description": "ps1 test yoo", - "is_selectable": "1", - "relevant_info": "", - "strengths": [ # compute classification_criterium_id - { - 'name': "ps", - 'description': "pathogenic strong", - 'is_default': "1" - } - ], - "mutually_exclusive_criteria": [ # list of criterium names - - ] - }, - ] - } - """ + +def insert_scheme(conn, data_path): + data = json.loads(open(data_path).read()) classification_scheme_id = insert_criterium_scheme(conn, data) insert_criteria(conn, data, classification_scheme_id) @@ -145,18 +93,35 @@ def get_criterium(all_criteria, criterium_name): +parser = argparse.ArgumentParser(description="") +parser.add_argument("-p", "--paths", nargs="+", help="one or more paths to scheme .json files to be saved to the database") +args = parser.parse_args() +conn = Connection(roles = ['super_user']) +data_paths = args.paths +print(data_paths) +for data_path in data_paths: + if not path.exists(data_path): + print("SKIPPING: path does not exist: " + data_path) + continue + insert_scheme(conn, data_path) +#/mnt/storage2/users/ahdoebm1/HerediVar/resources/classification_schemes/ClinGen_BRCA1_v1.0.0.json +#/mnt/storage2/users/ahdoebm1/HerediVar/resources/classification_schemes/ClinGen_BRCA2_v1.0.0.json - - - +#if __name__ == "__main__": +# +# conn = Connection(roles = ['super_user']) +# +# data_path = "/mnt/storage2/users/ahdoebm1/HerediVar/resources/classification_schemes/ClinGen_BRCA1_v1.0.0.json" +# +# insert_scheme(conn, data_path)