diff --git a/README.md b/README.md index 5540948..3a846e3 100644 --- a/README.md +++ b/README.md @@ -56,15 +56,22 @@ Go to root of the repository (e.g. `cd .../omicspred_backend`) python manage.py search_index --rebuild -f ``` -* For **local** deployment, run the command: +## Deployment - ```bash - python manage.py runserver - ``` +First of all, you need to rename and then update the file `app.yaml_template` to `app.yaml`. + +### Local + +Run the command: +```bash +python manage.py runserver +``` + +This will create an instance of the Django apps on your local machine on `http://127.0.0.1:8000/` - This will create an instance of the Django apps on your local machine on `http://127.0.0.1:8000/` +### Cloud -* For **cloud** deployment (e.g. Google Cloud App Engine), after setting up the Cloud account on your laptop and updating the **app.yaml** file, run the command: +For **cloud** deployment (e.g. Google Cloud App Engine), after setting up the Cloud account on your laptop and updating the **app.yaml** file, run the command: ```bash gcloud app deploy @@ -74,8 +81,8 @@ Go to root of the repository (e.g. `cd .../omicspred_backend`) > You will need to deploy the backend twice: > > * One for the [Public REST API](https://rest.omicspred.org/) with the app deployment name `service: rest` and the variable `PUBLIC_SITE: 'True'`. -> * One for the **Private REST API** (i.e. the one consumed by the OmicsPred website) with the app deployment name `service: rest-private` and the variable `PUBLIC_SITE: 'False'`. -> See the different **app.yaml** configuration files already set in the Group Google Drive directory `Website -> Systems/Settings -> REST API (back-end)` +> * One for the **Private REST API** (i.e. the one consumed by the OmicsPred frontend website) with the app deployment name, e.g. `service: rest-private`, and the variable `PUBLIC_SITE: 'False'`. +> See the different **app.yaml** configuration files already set in the Group Google Drive directory `Website -> Systems/Settings -> REST API (back-end)`. ## Tests diff --git a/applications/__init__.py b/applications/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/applications/admin.py b/applications/admin.py deleted file mode 100644 index 8c38f3f..0000000 --- a/applications/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/applications/apps.py b/applications/apps.py deleted file mode 100644 index 4ec33d8..0000000 --- a/applications/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class ApplicationsConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'applications' diff --git a/applications/migrations/0001_initial.py b/applications/migrations/0001_initial.py deleted file mode 100644 index a7ecc8c..0000000 --- a/applications/migrations/0001_initial.py +++ /dev/null @@ -1,152 +0,0 @@ -# Generated by Django 5.1.8 on 2025-04-14 10:38 - -import django.contrib.postgres.fields.ranges -import django.core.validators -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='CohortApplications', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name_short', models.CharField(db_index=True, max_length=100, verbose_name='Cohort Short Name')), - ('name_full', models.CharField(max_length=1000, verbose_name='Cohort Full Name')), - ('name_others', models.TextField(null=True, verbose_name='Previous/other/additional names (e.g. sub-cohorts)')), - ('url', models.CharField(max_length=100, verbose_name='Cohort URL')), - ('description', models.TextField(null=True, verbose_name='Cohort additional information')), - ], - ), - migrations.CreateModel( - name='GeneApplications', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=150, null=True, verbose_name='Gene name')), - ('external_id', models.CharField(db_index=True, max_length=100, null=True, verbose_name='External ID')), - ], - ), - migrations.CreateModel( - name='MetaboliteApplications', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=150, null=True, verbose_name='Metabolite name')), - ('external_id', models.CharField(db_index=True, max_length=100, null=True, verbose_name='External ID')), - ], - ), - migrations.CreateModel( - name='MolecularTraitApplications', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=150, null=True, verbose_name='Molecular trait name')), - ('external_id', models.CharField(db_index=True, max_length=100, null=True, verbose_name='External ID')), - ('type', models.CharField(choices=[('gene', 'gene'), ('protein', 'protein'), ('metabolite', 'metabolite')], default='', max_length=20)), - ], - ), - migrations.CreateModel( - name='PlatformMasterApplications', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100, verbose_name='Platform name')), - ('full_name', models.CharField(max_length=100, verbose_name='Platform full name')), - ('technic', models.CharField(max_length=100, verbose_name='Platform technic')), - ('type', models.CharField(max_length=100, verbose_name='Platform type')), - ], - ), - migrations.CreateModel( - name='ProteinApplications', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=150, null=True, verbose_name='Protein name')), - ('external_id', models.CharField(db_index=True, max_length=100, null=True, verbose_name='External ID')), - ], - ), - migrations.CreateModel( - name='PublicationApplications', - fields=[ - ('num', models.IntegerField(primary_key=True, serialize=False, verbose_name='Publication Number (OPP)')), - ('id', models.CharField(db_index=True, max_length=20, verbose_name='Publication ID (OPP)')), - ('pmid', models.IntegerField(verbose_name='PubMed ID (PMID)')), - ('doi', models.CharField(max_length=100, verbose_name='digital object identifier (doi)')), - ('journal', models.CharField(max_length=100, verbose_name='Journal Name')), - ('firstauthor', models.CharField(max_length=50, verbose_name='First Author')), - ('authors', models.TextField(verbose_name='Authors')), - ('title', models.TextField(verbose_name='Title')), - ('date_publication', models.DateField(verbose_name='Publication Date')), - ], - options={ - 'get_latest_by': 'id', - }, - ), - migrations.CreateModel( - name='SampleApplications', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sample_number', models.IntegerField(null=True, verbose_name='Number of Individuals')), - ('sample_cases', models.IntegerField(null=True, verbose_name='Number of Cases')), - ('sample_controls', models.IntegerField(null=True, verbose_name='Number of Controls')), - ('sample_percent_female', models.FloatField(null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)], verbose_name='Percent of Participants Who are Female')), - ('sample_age', models.FloatField(null=True, verbose_name='Sample Age')), - ('sample_age_sd', models.FloatField(null=True, verbose_name='Mean standard deviation of Age')), - ], - ), - migrations.CreateModel( - name='Phenotype', - fields=[ - ('id', models.CharField(max_length=30, primary_key=True, serialize=False, verbose_name='Phenotype ID')), - ('name', models.CharField(max_length=150, null=True, verbose_name='Phenotype Name')), - ('category', models.CharField(max_length=100, null=True, verbose_name='Phenotype Category')), - ('source', models.CharField(max_length=100, null=True, verbose_name='Phenotype source')), - ('child_phenotype', models.ManyToManyField(related_name='parent_phenotype', to='applications.phenotype', verbose_name='Children Phenotype')), - ], - ), - migrations.CreateModel( - name='PlatformApplications', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100, verbose_name='Platform name')), - ('version', models.CharField(max_length=50, verbose_name='Platform version')), - ('platform_master', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='platform_version', to='applications.platformmasterapplications', verbose_name='Platform')), - ], - ), - migrations.CreateModel( - name='SampleApplicationsLegacy', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sample_number', models.IntegerField(null=True, verbose_name='Number of Individuals')), - ('sample_cases', models.IntegerField(null=True, verbose_name='Number of Cases')), - ('sample_percent_female', models.FloatField(null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)], verbose_name='Percent of Participants Who are Female')), - ('sample_age', models.FloatField(null=True, verbose_name='Sample Age')), - ('sample_age_sd', models.FloatField(null=True, verbose_name='Mean standard deviation of Age')), - ('platform_counts', models.JSONField(null=True, verbose_name='Associations by platform')), - ('phenotype', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='phenotype_sample', to='applications.phenotype', verbose_name='Phenotype')), - ], - ), - migrations.CreateModel( - name='ScoreApplications', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('score_id', models.CharField(db_index=True, max_length=30, verbose_name='Omicspred ID')), - ('r2', models.FloatField(verbose_name='R2')), - ('hr', models.FloatField(verbose_name='Hazard Ratio')), - ('hr_ci', django.contrib.postgres.fields.ranges.DecimalRangeField(null=True, verbose_name='Hazard Ratio Confidence Interval')), - ('fdr', models.FloatField(verbose_name='FDR adjusted P-value')), - ('cohort', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cohort_score', to='applications.cohortapplications', verbose_name='Cohort')), - ('genes', models.ManyToManyField(related_name='genes_score', to='applications.geneapplications', verbose_name='Genes')), - ('metabolites', models.ManyToManyField(related_name='metabolites_score', to='applications.metaboliteapplications', verbose_name='Metabolites')), - ('molecular_traits', models.ManyToManyField(related_name='molecular_trait_score', to='applications.moleculartraitapplications', verbose_name='Molecular traits')), - ('phenotype', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='phenotype_score', to='applications.phenotype', verbose_name='Phenotype')), - ('platform', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='platform_score', to='applications.platformapplications', verbose_name='Platform')), - ('proteins', models.ManyToManyField(related_name='proteins_score', to='applications.proteinapplications', verbose_name='Proteins')), - ('publication', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='publication_score', to='applications.publicationapplications', verbose_name='Publication')), - ('sample', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='sample_score', to='applications.sampleapplications', verbose_name='Sample information')), - ], - ), - ] diff --git a/applications/migrations/__init__.py b/applications/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/applications/models.py b/applications/models.py deleted file mode 100644 index 3c38e12..0000000 --- a/applications/models.py +++ /dev/null @@ -1,212 +0,0 @@ -from django.db import models -from django.core.validators import MaxValueValidator, MinValueValidator -from django.contrib.postgres.fields import DecimalRangeField - -applications_db = 'applications' -# applications_db = 'default' - -class CohortApplications(models.Model): - """ Class to describe cohorts used in samples """ - name_short = models.CharField('Cohort Short Name', max_length=100, db_index=True) - name_full = models.CharField('Cohort Full Name', max_length=1000) - name_others = models.TextField('Previous/other/additional names (e.g. sub-cohorts)', null=True) - url = models.CharField('Cohort URL', max_length=100) - description = models.TextField('Cohort additional information', null=True) - - def __str__(self): - return self.name_short - - -class PublicationApplications(models.Model): - """ Class for publications """ - num = models.IntegerField('Publication Number (OPP)', primary_key=True) - id = models.CharField('Publication ID (OPP)', max_length=20, db_index=True) - - pmid = models.IntegerField('PubMed ID (PMID)', null=False) - - # Key information (also) in the spreadsheet - doi = models.CharField('digital object identifier (doi)', max_length=100) - - journal = models.CharField('Journal Name', max_length=100) - firstauthor = models.CharField('First Author', max_length=50) - - # Information extracted from EuropePMC - authors = models.TextField('Authors') - title = models.TextField('Title') - date_publication = models.DateField('Publication Date') - - # Methods - def __str__(self): - return f'{self.firstauthor} | PMID:{self.pmid}' - - class Meta: - get_latest_by = 'id' - - # @property - # def is_preprint(self): - # return 'bioRxiv' in self.journal or 'medRxiv' in self.journal - - @property - def pub_year(self): - # Dependant on the context, sometimes the date_publication is returned as a string - pub_date = self.date_publication - if type(pub_date) == str: - pub_date = datetime.strptime(pub_date, '%Y-%m-%d') - return pub_date.strftime('%Y') - - -class Phenotype(models.Model): - """ Class for individual Phenotype entry """ - # PheWAS identifiers - id = models.CharField('Phenotype ID', max_length=30, primary_key=True) - name = models.CharField('Phenotype Name', max_length=150, null=True) - category = models.CharField('Phenotype Category', max_length=100, null=True) - source = models.CharField('Phenotype source', max_length=100, null=True) - - child_phenotype = models.ManyToManyField('self', verbose_name='Children Phenotype', symmetrical=False, related_name='parent_phenotype') - - @property - def scores_count(self): - scores = self.phenotype_score.count() - return scores - - - @property - def score_number(self): - scores = ScoreApplications.objects.using(applications_db).select_related('phenotype','platform').filter(phenotype=self) - data = {} - for score in scores.all(): - platform = score.platform.name - if platform in data.keys(): - data[platform] += 1 - else: - data[platform] = 1 - return data - - - @property - def platforms(self): - scores = ScoreApplications.objects.using(applications_db).select_related('phenotype','platform').filter(phenotype=self) - platforms = set() - for score in scores.all(): - platform = score.platform.name - platforms.add(platform) - return list(platforms) - - @property - def omics_types(self): - scores = ScoreApplications.objects.using(applications_db).select_related('phenotype','platform','platform__platform_master').filter(phenotype=self) - types = set() - for score in scores.all(): - type = score.platform.platform_master.type - types.add(type) - return list(types) - - -class PlatformMasterApplications(models.Model): - """ Class to describe the platform used to get the omics data """ - name = models.CharField('Platform name', max_length=100) - full_name = models.CharField('Platform full name', max_length=100) - technic = models.CharField('Platform technic', max_length=100) - type = models.CharField('Platform type', max_length=100) - - @property - def versions(self): - print(self.platform_version) - versions_list = [] - for platform in self.platform_version.all(): - if platform.version: - versions_list.append(platform.version) - return sorted(versions_list) - - -class PlatformApplications(models.Model): - """ Class to describe the platform used to get the omics data """ - name = models.CharField('Platform name', max_length=100) - # full_name = models.CharField('Platform full name', max_length=100) - version = models.CharField('Platform version', max_length=50) - # technic = models.CharField('Platform technic', max_length=100) - # type = models.CharField('Platform type', max_length=100) - platform_master = models.ForeignKey(PlatformMasterApplications, on_delete=models.CASCADE, related_name='platform_version', verbose_name='Platform') - - -# Legacy model! It will need to be removed in a near future # -class SampleApplicationsLegacy(models.Model): - sample_number = models.IntegerField('Number of Individuals', null=True) - sample_cases = models.IntegerField('Number of Cases', null=True) - sample_percent_female = models.FloatField('Percent of Participants Who are Female', validators=[MinValueValidator(0), MaxValueValidator(100)], null=True) - sample_age = models.FloatField('Sample Age', null=True) - sample_age_sd = models.FloatField('Mean standard deviation of Age', null=True) - phenotype = models.ForeignKey(Phenotype, on_delete=models.PROTECT, related_name='phenotype_sample', verbose_name='Phenotype') - platform_counts = models.JSONField('Associations by platform', null=True) - - -class SampleApplications(models.Model): - sample_number = models.IntegerField('Number of Individuals', null=True) - sample_cases = models.IntegerField('Number of Cases', null=True) - sample_controls = models.IntegerField('Number of Controls', null=True) - sample_percent_female = models.FloatField('Percent of Participants Who are Female', validators=[MinValueValidator(0), MaxValueValidator(100)], null=True) - sample_age = models.FloatField('Sample Age', null=True) - sample_age_sd = models.FloatField('Mean standard deviation of Age', null=True) - - -# TODO: To be removed from the schema -class MolecularTraitApplications(models.Model): - TYPE_CHOICES = [ - ('gene', 'gene'), - ('protein', 'protein'), - ('metabolite', 'metabolite') - ] - name = models.CharField('Molecular trait name', max_length=150, null=True) - external_id = models.CharField('External ID', max_length=100, db_index=True, null=True) - type = models.CharField(max_length=20, - choices=TYPE_CHOICES, - default='' - ) - - -class GeneApplications(models.Model): - name = models.CharField('Gene name', max_length=150, null=True) - external_id = models.CharField('External ID', max_length=100, db_index=True, null=True) - - -class ProteinApplications(models.Model): - name = models.CharField('Protein name', max_length=150, null=True) - external_id = models.CharField('External ID', max_length=100, db_index=True, null=True) - - -class MetaboliteApplications(models.Model): - name = models.CharField('Metabolite name', max_length=150, null=True) - external_id = models.CharField('External ID', max_length=100, db_index=True, null=True) - - -class ScoreApplications(models.Model): - """ Class for score association for the application """ - score_id = models.CharField('Omicspred ID', max_length=30, db_index=True) - phenotype = models.ForeignKey(Phenotype, on_delete=models.PROTECT, related_name='phenotype_score', verbose_name='Phenotype') - sample = models.ForeignKey(SampleApplications, on_delete=models.PROTECT, related_name='sample_score', verbose_name='Sample information') - publication = models.ForeignKey(PublicationApplications, on_delete=models.PROTECT, related_name='publication_score', verbose_name='Publication') - platform = models.ForeignKey(PlatformApplications, on_delete=models.PROTECT, related_name='platform_score', verbose_name='Platform') - cohort = models.ForeignKey(CohortApplications, on_delete=models.PROTECT, related_name='cohort_score', verbose_name='Cohort') - molecular_traits = models.ManyToManyField(MolecularTraitApplications, related_name='molecular_trait_score', verbose_name='Molecular traits') - genes = models.ManyToManyField(GeneApplications, related_name='genes_score', verbose_name='Genes') - proteins = models.ManyToManyField(ProteinApplications, related_name='proteins_score', verbose_name='Proteins') - metabolites = models.ManyToManyField(MetaboliteApplications, related_name='metabolites_score', verbose_name='Metabolites') - # Values - r2 = models.FloatField(verbose_name='R2', null=False) - hr = models.FloatField(verbose_name='Hazard Ratio', null=False) - hr_ci = DecimalRangeField(verbose_name='Hazard Ratio Confidence Interval', null=True) - fdr = models.FloatField(verbose_name='FDR adjusted P-value', null=False) - - @property - def values_dict(self): - l = {} - # l['R2'] = self.r2 - l['HR'] = self.hr - if self.hr_ci != None: - l['HR_lower'] = float(self.hr_ci.lower) - l['HR_upper'] = float(self.hr_ci.upper) - l['FDR'] = self.fdr - return l - -# Downloads ? diff --git a/applications/tests.py b/applications/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/applications/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/applications/views.py b/applications/views.py deleted file mode 100644 index 91ea44a..0000000 --- a/applications/views.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here. diff --git a/config/settings.py b/config/settings.py index 9fb25e5..e32fd0e 100644 --- a/config/settings.py +++ b/config/settings.py @@ -78,7 +78,6 @@ INSTALLED_APPS = [ 'omicspred.apps.OmicspredConfig', - 'applications.apps.ApplicationsConfig', 'plot.apps.PlotConfig', 'rest_api.apps.RestApiConfig', 'django.contrib.admin', @@ -168,14 +167,6 @@ 'HOST': os.environ['DATABASE_HOST'], 'PORT': os.environ['DATABASE_PORT'] }, - 'applications': { - 'ENGINE': DB_ENGINE, - 'NAME': os.environ['DATABASE_NAME_2'], - 'USER': os.environ['DATABASE_USER_2'], - 'PASSWORD': os.environ['DATABASE_PASSWORD_2'], - 'HOST': os.environ['DATABASE_HOST_2'], - 'PORT': os.environ['DATABASE_PORT_2'] - }, 'plot': { 'ENGINE': DB_ENGINE, 'NAME': os.environ['DATABASE_NAME_3'], @@ -195,14 +186,6 @@ 'HOST': 'localhost', 'PORT': os.environ['DATABASE_PORT_LOCAL'] }, - 'applications': { - 'ENGINE': DB_ENGINE, - 'NAME': os.environ['DATABASE_NAME_2'], - 'USER': os.environ['DATABASE_USER_2'], - 'PASSWORD': os.environ['DATABASE_PASSWORD_2'], - 'HOST': 'localhost', - 'PORT': os.environ['DATABASE_PORT_LOCAL_2'] - }, 'plot': { 'ENGINE': DB_ENGINE, 'NAME': os.environ['DATABASE_NAME_3'], diff --git a/imports/applications/models/cohort.py b/imports/applications/models/cohort.py deleted file mode 100644 index 50b2fb3..0000000 --- a/imports/applications/models/cohort.py +++ /dev/null @@ -1,63 +0,0 @@ -from django.db import IntegrityError, transaction -from imports.generic_model import GenericData -from applications.models import CohortApplications -from omicspred.models import Cohort as OPCohort - - -class CohortData(GenericData): - - def __init__(self,data): - GenericData.__init__(self) - self.name = data['name_short'] - self.data = data - - def check_cohort(self): - ''' - Check if a CohortApplications model already exists in the Applications DB. - Return type: CohortApplications model (Applications) - ''' - try: - cohort = CohortApplications.objects.using(self.applications_db).get(name_short__iexact=self.name) - self.model = cohort - except CohortApplications.DoesNotExist: - self.model = None - - - def get_omicspred_cohort(self): - ''' - Get Cohort model from Omicspred DB - Return type: Cohort model (Omicspred) - ''' - try: - cohort = OPCohort.objects.get(name_short__iexact=self.name) - return cohort - except OPCohort.DoesNotExist: - return None - - - @transaction.atomic - def create_model(self): - ''' - Retrieve/Create an instance of the CohortApplications model. - Return type: CohortApplications model - ''' - try: - with transaction.atomic(): - self.check_cohort() - if not self.model: - self.model = CohortApplications() - op_cohort_model = self.get_omicspred_cohort() - if op_cohort_model: - self.model.name_short=op_cohort_model.name_short - self.model.name_full=op_cohort_model.name_full - self.model.url=op_cohort_model.url - else: - for field, val in self.data.items(): - setattr(self.model, field, val) - self.model.save(using=self.applications_db) - - except IntegrityError as e: - self.model = None - print('Error with the creation of the CohortApplications') - - return self.model diff --git a/imports/applications/models/phecode.py b/imports/applications/models/phecode.py deleted file mode 100644 index 6dbd385..0000000 --- a/imports/applications/models/phecode.py +++ /dev/null @@ -1,46 +0,0 @@ -from django.db import IntegrityError, transaction -from imports.generic_model import GenericData -from applications.models import Phecode - -class PhecodeData(GenericData): - - def __init__(self,data): - GenericData.__init__(self) - - # 'id': data_info['PheCode'], - # 'name': data_info['Phenotype'], - # 'category': data_info['Category'] - self.id = data['id'] - self.data = data - - def check_phecode(self): - ''' - Check if a Phecode model already exists. - Return type: Phecode model - ''' - try: - phecode = Phecode.objects.using(self.applications_db).get(id=self.id) - self.model = phecode - except Phecode.DoesNotExist: - self.model = None - - - @transaction.atomic - def create_model(self): - ''' - Retrieve/Create an instance of the Phecode model. - Return type: Cohort model - ''' - try: - with transaction.atomic(): - self.check_phecode() - if not self.model: - self.model = Phecode() - for field, val in self.data.items(): - setattr(self.model, field, val) - self.model.save(using=self.applications_db) - except IntegrityError as e: - self.model = None - print('Error with the creation of the Phecode') - - return self.model diff --git a/imports/applications/models/platform.py b/imports/applications/models/platform.py deleted file mode 100644 index df4a5bb..0000000 --- a/imports/applications/models/platform.py +++ /dev/null @@ -1,66 +0,0 @@ -from django.db import IntegrityError, transaction -from imports.generic_model import GenericData -from applications.models import PlatformApplications -from omicspred.models import Platform as OPPlatform - - -class PlatformData(GenericData): - - def __init__(self,data): - GenericData.__init__(self) - self.name = data['name'] - self.data = data - - - def check_platform(self): - ''' - Check if a Platform, model already exists in the Applications DB. - Return type: Platform model (Applications) - ''' - try: - platform = PlatformApplications.objects.using(self.applications_db).get(name__iexact=self.name) - self.model = platform - except PlatformApplications.DoesNotExist: - self.model = None - - - def get_omicspred_platform(self): - ''' - Get Platform model from Omicspred DB - Return type: Platform model (Omicspred) - ''' - try: - platform = OPPlatform.objects.get(name__iexact=self.name) - return platform - except OPPlatform.DoesNotExist: - return None - - - @transaction.atomic - def create_model(self): - ''' - Retrieve/Create an instance of the PlatformApplications model. - Return type: PlatformApplications model - ''' - try: - with transaction.atomic(): - self.check_platform() - if not self.model: - self.model = PlatformApplications() - op_platform_model = self.get_omicspred_platform() - if op_platform_model: - self.model.name=op_platform_model.name - self.model.full_name=op_platform_model.full_name - self.model.version=op_platform_model.version - self.model.technic=op_platform_model.technic - self.model.type=op_platform_model.type - else: - for field, val in self.data.items(): - setattr(self.model, field, val) - self.model.save(using=self.applications_db) - - except IntegrityError as e: - self.model = None - print('Error with the creation of the PlatformApplications') - - return self.model diff --git a/imports/applications/models/sample.py b/imports/applications/models/sample.py deleted file mode 100644 index 7121de9..0000000 --- a/imports/applications/models/sample.py +++ /dev/null @@ -1,28 +0,0 @@ -from django.db import IntegrityError, transaction -from imports.generic_model import GenericData -from applications.models import SampleApplications - - -class SampleData(GenericData): - - def __init__(self,data): - GenericData.__init__(self) - self.data = data - - @transaction.atomic - def create_model(self): - ''' - Retrieve/Create an instance of the SampleApplications model. - Return type: SampleApplications model - ''' - try: - with transaction.atomic(): - self.model = SampleApplications() - for field, val in self.data.items(): - setattr(self.model, field, val) - self.model.save(using=self.applications_db) - except IntegrityError as e: - self.model = None - print('Error with the creation of the SampleApplications') - - return self.model \ No newline at end of file diff --git a/imports/applications/models/score.py b/imports/applications/models/score.py deleted file mode 100644 index e368b5f..0000000 --- a/imports/applications/models/score.py +++ /dev/null @@ -1,93 +0,0 @@ -from django.db.models import Q -from django.db import IntegrityError, transaction -from imports.generic_model import GenericData -from applications.models import ScoreApplications, MolecularTraitApplications -from omicspred.models import Score - - -class ScoreData(GenericData): - - def __init__(self,data): - GenericData.__init__(self) - self.id = data['score_id'] - self.data = data - - - # def check_score(self): - # ''' - # Check if a ScoreApplications model already exists. - # Return type: ScoreApplications model - # ''' - # try: - # score_app = ScoreApplications.objects.using(self.applications_db).get(score_id=self.id) - # self.model = score_app - # except ScoreApplications.DoesNotExist: - # self.model = None - - def check_omicspred_id(self): - ''' - Check if a Score model (Omicspred) exists with the given ID. - Return type: Score model - ''' - try: - score = Score.objects.get(id=self.id) - return score - except Score.DoesNotExist: - return None - - def add_molecular_traits(self,mt_type,molecular_traits,mt_list): - if molecular_traits: - for molecular_trait in molecular_traits.all(): - mt_pr = MolecularTraitApplications.objects.using(self.applications_db).filter(Q(external_id=molecular_trait.external_id) | Q(name=molecular_trait.name)) - if mt_pr: - mt_pr = mt_pr[0] - else: - mt_pr = MolecularTraitApplications(type=mt_type) - if molecular_trait.name: - mt_pr.name=molecular_trait.name - if molecular_trait.external_id: - mt_pr.external_id=molecular_trait.external_id - mt_pr.save(using=self.applications_db) - if mt_pr: - mt_list.append(mt_pr) - return mt_list - - @transaction.atomic - def create_model(self): - ''' - Retrieve/Create an instance of the ScoreApplications model. - Return type: ScoreApplications model - ''' - try: - with transaction.atomic(): - # self.check_score() - # if not self.model: - op_obj = self.check_omicspred_id() - if op_obj: - self.model = ScoreApplications() - for field, val in self.data.items(): - setattr(self.model, field, val) - self.model.save(using=self.applications_db) - ## Molecular traits - mt_list = [] - # Genes - genes = op_obj.genes - mt_list = self.add_molecular_traits('gene',genes,mt_list) - # Protein - proteins = op_obj.proteins - mt_list = self.add_molecular_traits('protein',proteins,mt_list) - # Metabolite - metabolites = op_obj.metabolites - mt_list = self.add_molecular_traits('metabolite',metabolites,mt_list) - - if mt_list: - for mt in mt_list: - self.model.molecular_traits.add(mt) - self.model.save(using=self.applications_db) - else: - print(f"- Error: Score {self.id} can't be found in OmicsPred") - except IntegrityError as e: - self.model = None - print('Error with the creation of the ScoreApplications') - - return self.model diff --git a/imports/applications/parsers/__init__.py b/imports/applications/parsers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/imports/applications/parsers/phecode.py b/imports/applications/parsers/phecode.py deleted file mode 100644 index 3c6517b..0000000 --- a/imports/applications/parsers/phecode.py +++ /dev/null @@ -1,92 +0,0 @@ -import re -from psycopg.types.range import Range - -class PhecodeFullParser(): - - def __init__(self, data_info:dict): - - self.phecode = { - 'id': data_info['PheCode'], - 'name': data_info['Phenotype'], - 'category': data_info['Category'] - } - self.score_application = { - 'score_id': data_info['OMICSPRED ID'], - 'r2': data_info['Internal R2'], - 'fdr': data_info['FDR adjusted P-value'] - } - self.platform = { - 'name': data_info['Platform'] - } - - self.cohort = { - 'name_short': 'INTERVAL' - } - self.hazard_ratio = data_info['Hazard Ratio'] - - - def parse_hazard_ratio(self): - values = self.hazard_ratio.split(' ') - self.score_application['hr'] = values[0] - if len(values) == 3: - ci_low = values[1].replace('(','') - ci_upper = values[2].replace(')','') - self.score_application['hr_ci'] = Range(lower=float(ci_low), upper=float(ci_upper), bounds='[]') - - - def fix_phecode_id(self): - phecode_id = str(self.phecode['id']) - new_phecode_id = re.sub('\.0$', '',phecode_id) - self.phecode['id'] = new_phecode_id - - - def parse_data(self): - self.parse_hazard_ratio() - self.fix_phecode_id() - # print(self.score_application) - - - - -class PhecodeSumParser(): - - def __init__(self, data_info:dict): - - self.phecode = { - 'id': data_info['Phecode'], - 'name': data_info['Phenotype'], - 'category': data_info['Category'] - } - self.sample_application = { - # 'sample_number': data_info['#Cases/#Samples'].split('/')[1], - # 'sample_cases': data_info['#Cases/#Samples'].split('/')[0], - 'sample_percent_female': data_info['%Female'].replace('%',''), - # 'sample_age': data_info['Mean Age'].split(' \u00b1 ')[0], - # 'sample_age_sd': data_info['Mean Age'].split(' \u00b1 ')[1], - } - - self.sample_count = data_info['#Cases/#Samples'] - self.sample_age = data_info['Mean Age'] - - - def parse_sample(self): - # Sample count - [cases,number] = self.sample_count.split('/') - self.sample_application['sample_cases'] = cases - self.sample_application['sample_number'] = number - - # Sample age - [age,age_sd] = self.sample_age.split(' \u00b1 ') - self.sample_application['sample_age'] = age - self.sample_application['sample_age_sd'] = age_sd - - - def fix_phecode_id(self): - phecode_id = str(self.phecode['id']) - new_phecode_id = re.sub('\.0$', '',phecode_id) - self.phecode['id'] = new_phecode_id - - - def parse_data(self): - self.parse_sample() - self.fix_phecode_id() diff --git a/imports/scripts/update_applications_platform_count.py b/imports/scripts/update_applications_platform_count.py deleted file mode 100644 index 516e924..0000000 --- a/imports/scripts/update_applications_platform_count.py +++ /dev/null @@ -1,25 +0,0 @@ -from applications.models import SampleApplications, ScoreApplications - -applications_db = 'applications' - -def run(): - scores_app = ScoreApplications.objects.using(applications_db).select_related('phecode','platform','cohort').all() - - phecode_platform = {} - for score_app in scores_app: - phecode_id = score_app.phecode.id - platform_name = score_app.platform.name - - if phecode_id not in phecode_platform.keys(): - phecode_platform[phecode_id] = {} - if platform_name not in phecode_platform[phecode_id].keys(): - phecode_platform[phecode_id][platform_name] = 0 - phecode_platform[phecode_id][platform_name] += 1 - - for phecode_id in phecode_platform.keys(): - try: - sample_app = SampleApplications.objects.using(applications_db).select_related('phecode').get(phecode__id=phecode_id) - sample_app.platform_counts = phecode_platform[phecode_id] - sample_app.save() - except SampleApplications.DoesNotExist: - print(f'X {phecode_id}: no entry in SampleApplications') \ No newline at end of file diff --git a/rest_api/fixtures/db_test.applications.json b/rest_api/fixtures/db_test.applications.json deleted file mode 100644 index dc5b70d..0000000 --- a/rest_api/fixtures/db_test.applications.json +++ /dev/null @@ -1,283 +0,0 @@ -[ - { - "model": "applications.Phenotype", - "pk": "555.2", - "fields": { - "name": "Ulcerative colitis", - "category": "digestive" - } - }, - { - "model": "applications.Phenotype", - "pk": "250.2", - "fields": { - "name": "Type 2 diabetes", - "category": "endocrine/metabolic" - } - }, - { - "model": "applications.Phenotype", - "pk": "250", - "fields": { - "name": "Diabetes mellitus", - "category": "endocrine/metabolic", - "child_phenotype": [ "250.2" ] - } - }, - { - "model": "applications.Phenotype", - "pk": "278.1", - "fields": { - "name": "Obesity", - "category": "endocrine/metabolic" - } - }, - { - "model": "applications.CohortApplications", - "pk": 1, - "fields": { - "name_short": "INTERVAL", - "name_full": "INTERVAL", - "name_others": null, - "description": "A cohort of healthy blood donors in England", - "url": "https://www.intervalstudy.org.uk/" - } - }, - { - "model": "applications.PlatformMasterApplications", - "pk": 1, - "fields": { - "name": "Somalogic", - "full_name": "Somalogic", - "technic": "aptamer-based multiplex protein assay", - "type": "Proteomics" - } - }, - { - "model": "applications.PlatformMasterApplications", - "pk": 2, - "fields": { - "name": "Olink", - "full_name": "Olink", - "technic": "antibody-based proximity extension assay for proteins", - "type": "Proteomics" - } - }, - { - "model": "applications.PlatformMasterApplications", - "pk": 4, - "fields": { - "name": "Metabolon", - "full_name": "Metabolon Discovery HD4", - "technic": "untargeted mass spectrometry metabolomics platform", - "type": "Metabolomics" - } - }, - { - "model": "applications.PlatformApplications", - "pk": 1, - "fields": { - "name": "Somalogic", - "version": "3.0", - "platform_master_id": 1 - } - }, - { - "model": "applications.PlatformApplications", - "pk": 2, - "fields": { - "name": "Olink", - "version": "Target", - "platform_master_id": 2 - } - }, - { - "model": "applications.PlatformApplications", - "pk": 4, - "fields": { - "name": "Metabolon", - "platform_master_id": 4 - } - }, - { - "model": "applications.PublicationApplications", - "pk": 1, - "fields": { - "id": "OPP000001", - "pmid": 36991119, - "doi": "10.1038/s41586-023-05844-9", - "journal": "Nature", - "firstauthor": "Xu Y", - "authors": "Xu Y, ..., Butterworth AS, Inouye M.", - "title": "An atlas of genetic scores to predict multi-omic traits.", - "date_publication": "2023-03-29" - } - }, - { - "model": "applications.GeneApplications", - "pk": 23326, - "fields": { - "name": "FCGR2B", - "external_id": "ENSG00000072694" - } - }, - { - "model": "applications.ProteinApplications", - "pk": 23327, - "fields": { - "name": "Low affinity immunoglobulin gamma Fc region receptor II-b", - "external_id": "P31994" - } - }, - { - "model": "applications.MetaboliteApplications", - "pk": 19736, - "fields": { - "name": "cholesterol", - "external_id": "CHEBI_16113" - } - }, - { - "model": "applications.ScoreApplications", - "pk": 24380, - "fields": { - "score_id": "OPGS000005", - "r2": 0.727, - "hr": 0.92, - "hr_ci": [0.89,0.95], - "fdr": 0.000225, - "cohort_id": 1, - "phenotype_id": "555.2", - "platform_id": 1, - "publication_id": 1, - "sample_id": 678, - "genes": [ 23326 ], - "proteins": [], - "metabolites": [] - } - }, - { - "model": "applications.ScoreApplications", - "pk": 24390, - "fields": { - "score_id": "OPGS002385", - "r2": 0.615, - "hr": 0.9, - "hr_ci": [0.87,0.93], - "fdr": 1.17e-06, - "cohort_id": 1, - "phenotype_id": "555.2", - "platform_id": 2, - "publication_id": 1, - "sample_id": 678, - "genes": [ 23326 ], - "proteins": [ 23327 ], - "metabolites": [] - } - }, - { - "model": "applications.ScoreApplications", - "pk": 15066, - "fields": { - "score_id": "OPGS003006", - "r2": 0.03, - "hr": 0.97, - "hr_ci": [0.96,0.99], - "fdr": 0.00554, - "cohort_id": 1, - "phenotype_id": "278.1", - "platform_id": 4, - "publication_id": 1, - "sample_id": 218, - "genes": [], - "proteins": [], - "metabolites": [ 19736 ] - } - }, - { - "model": "applications.SampleApplicationsLegacy", - "pk": 166, - "fields": { - "sample_number": 406673, - "sample_cases": 28709, - "sample_percent_female": 54, - "sample_age": 67.62, - "sample_age_sd": 8.06, - "platform_counts": { - "Olink": 5, - "SomaScan": 65, - "Metabolon": 21 - }, - "phenotype_id": "250" - } - }, - { - "model": "applications.SampleApplicationsLegacy", - "pk": 678, - "fields": { - "sample_number": 296948, - "sample_cases": 3878, - "sample_percent_female": 53, - "sample_age": 67.24, - "sample_age_sd": 8.13, - "platform_counts": { - "Olink": 1, - "SomaScan": 3 - }, - "phenotype_id": "555.2" - } - }, - { - "model": "applications.SampleApplicationsLegacy", - "pk": 218, - "fields": { - "sample_number": 409104, - "sample_cases": 24338, - "sample_percent_female": 54, - "sample_age": 67.82, - "sample_age_sd": 8.083, - "platform_counts": { - "Olink": 1, - "SomaScan": 9, - "Metabolon": 2 - }, - "phenotype_id": "278.1" - } - }, - { - "model": "applications.SampleApplications", - "pk": 166, - "fields": { - "sample_number": 406673, - "sample_cases": 28709, - "sample_controls": 377964, - "sample_percent_female": 54, - "sample_age": 67.62, - "sample_age_sd": 8.06 - } - }, - { - "model": "applications.SampleApplications", - "pk": 678, - "fields": { - "sample_number": 296948, - "sample_cases": 3878, - "sample_controls": 293070, - "sample_percent_female": 53, - "sample_age": 67.24, - "sample_age_sd": 8.13 - } - }, - { - "model": "applications.SampleApplications", - "pk": 218, - "fields": { - "sample_number": 409104, - "sample_cases": 24338, - "sample_controls": 384766, - "sample_percent_female": 54, - "sample_age": 67.82, - "sample_age_sd": 8.083 - } - } -] \ No newline at end of file diff --git a/rest_api/serializers.py b/rest_api/serializers.py index c6bfd30..9389c56 100644 --- a/rest_api/serializers.py +++ b/rest_api/serializers.py @@ -1,7 +1,5 @@ from rest_framework import serializers from omicspred.models import * -from applications.models import Phenotype as PhenotypeOld -from applications.models import ScoreApplications,SampleApplications,SampleApplicationsLegacy,PlatformApplications,CohortApplications,MolecularTraitApplications,GeneApplications,ProteinApplications,MetaboliteApplications from plot.models import * @@ -776,126 +774,6 @@ def get_data_values(self, obj): return obj.values_dict -###################### -#### Applications #### -###################### - -class PhenotypeOldSerializer(serializers.ModelSerializer): - class Meta: - model = PhenotypeOld - meta_fields = ('id','name','category','source') - fields = meta_fields - read_only_fields = meta_fields - - -class PhenotypeOldSerializerScoresCount(PhenotypeOldSerializer): - class Meta(PhenotypeOldSerializer.Meta): - meta_fields = scores_count - fields = PhenotypeOldSerializer.Meta.fields + meta_fields - read_only_fields = PhenotypeOldSerializer.Meta.read_only_fields + meta_fields - - -class PhenotypeOldSerializerExtended(PhenotypeOldSerializerScoresCount): - # child_phenotype = PhenotypeOldSerializer(many=True,read_only=True) - child_phenotype = serializers.SerializerMethodField() - - class Meta(PhenotypeOldSerializerScoresCount.Meta): - meta_fields = ('child_phenotype',) - fields = PhenotypeOldSerializerScoresCount.Meta.fields + meta_fields - read_only_fields = PhenotypeOldSerializerScoresCount.Meta.read_only_fields + meta_fields - - def get_child_phenotype(self, obj): - ''' Sort phenotype child terms by their IDs ''' - children = obj.child_phenotype.prefetch_related('phenotype_score').order_by('id') - return PhenotypeOldSerializerScoresCount(children, many=True).data - - -class PlatformApplicationsSerializer(PlatformSerializer): - class Meta: - model = PlatformApplications - fields = PlatformSerializer.Meta.fields - read_only_fields = PlatformSerializer.Meta.read_only_fields - - -class SampleApplicationsSerializer(serializers.ModelSerializer): - class Meta: - model = SampleApplications - meta_fields = ('sample_number','sample_cases','sample_controls','sample_percent_female','sample_age', 'sample_age_sd') - fields = meta_fields - read_only_fields = meta_fields - - -class CohortApplicationsSerializer(CohortSerializer): - class Meta: - model = CohortApplications - fields = CohortSerializer.Meta.fields - read_only_fields = CohortSerializer.Meta.read_only_fields - - -class MolecularTraitApplicationsSerializer(serializers.ModelSerializer): - class Meta: - model = MolecularTraitApplications - meta_fields = ('name','external_id','type') - fields = meta_fields - read_only_fields = meta_fields - - -class GeneApplicationsSerializer(serializers.ModelSerializer): - class Meta: - model = GeneApplications - meta_fields = ('name','external_id') - fields = meta_fields - read_only_fields = meta_fields - -class ProteinApplicationsSerializer(serializers.ModelSerializer): - class Meta: - model = ProteinApplications - meta_fields = ('name','external_id') - fields = meta_fields - read_only_fields = meta_fields - -class MetaboliteApplicationsSerializer(serializers.ModelSerializer): - class Meta: - model = MetaboliteApplications - meta_fields = ('name','external_id') - fields = meta_fields - read_only_fields = meta_fields - - -class ScoreApplicationsSerializer(serializers.ModelSerializer): - phenotype = PhenotypeOldSerializer(many=False,read_only=True) - platform = PlatformApplicationsSerializer(many=False,read_only=True) - sample = SampleApplicationsSerializer(many=False,read_only=True) - cohort = CohortApplicationsSerializer(many=False,read_only=True) - genes = GeneApplicationsSerializer(many=True,read_only=True) - proteins = ProteinApplicationsSerializer(many=True,read_only=True) - metabolites = MetaboliteApplicationsSerializer(many=True,read_only=True) - # molecular_traits = MolecularTraitApplicationsSerializer(many=True,read_only=True) - data_values = serializers.SerializerMethodField('get_data_values') - - class Meta: - model = ScoreApplications - # meta_fields = ('score_id','phenotype','platform','sample','cohort','genes','proteins','metabolites','molecular_traits','data_values') - meta_fields = ('score_id','phenotype','platform','sample','cohort','genes','proteins','metabolites','data_values') - fields = meta_fields - read_only_fields = meta_fields - - def get_data_values(self, obj): - return obj.values_dict - - -class SampleApplicationsLegacySerializer(serializers.ModelSerializer): - phenotype = PhenotypeOldSerializerScoresCount(many=False,read_only=True) - - class Meta: - model = SampleApplicationsLegacy - meta_fields = ('sample_number','sample_cases','sample_percent_female','sample_age','sample_age_sd','phenotype','platform_counts') - fields = meta_fields - read_only_fields = meta_fields - - - - ############### #### TESTS #### ############### @@ -905,78 +783,4 @@ class Meta: model = Plot meta_fields = ('dataset_id','dataset_name','plot_data','score_data') fields = meta_fields - read_only_fields = meta_fields - -# class ScoreExtendedSerializer(serializers.ModelSerializer): -# publication = PublicationSerializer(many=False, read_only=True) -# platform = PlatformSerializer(many=False, read_only=True) - -# genes = GeneSerializer(many=True, read_only=True) -# transcripts = TranscriptSerializer(many=True, read_only=True) -# proteins = ProteinSerializer(many=True, read_only=True) -# metabolites = MetaboliteSerializer(many=True, read_only=True) -# score_performance = PerformanceLightSerializer(many=True, read_only=True) - -# class Meta: -# model = Score -# meta_fields = ('id', 'name', 'trait_reported', 'trait_reported_id', 'method_name', 'method_params', -# 'publication', 'platform', 'score_performance', 'genes', 'transcripts', 'proteins', 'metabolites', -# 'variants_number', 'variants_interactions', 'variants_genomebuild',) -# fields = meta_fields -# read_only_fields = meta_fields - - -# class OmicsScoreSerializer(serializers.ModelSerializer): -# publication = PublicationSerializer(many=False, read_only=True) -# platform = PlatformSerializer(many=False, read_only=True) - -# metabolites = MetaboliteSerializer(many=True, read_only=True) -# score_performance = PerformanceLightSerializer(many=True, read_only=True) - -# class Meta: -# model = Score -# meta_fields = ('id', 'name', 'trait_reported', 'trait_reported_id', 'method_name', 'method_params', -# 'publication', 'platform', 'score_performance', -# 'variants_number', 'variants_interactions', 'variants_genomebuild') -# fields = meta_fields -# read_only_fields = meta_fields - - -# class MetaboliteScoreSerializer(OmicsScoreSerializer): -# metabolites = MetaboliteSerializer(many=True, read_only=True) - -# class Meta(OmicsScoreSerializer): -# meta_fields = ('metabolites',) -# fields = OmicsScoreSerializer.Meta.fields + meta_fields -# read_only_fields = OmicsScoreSerializer.Meta.read_only_fields + meta_fields - - -# class ProteinScoreSerializer(OmicsScoreSerializer): -# genes = GeneSerializer(many=True, read_only=True) -# proteins = ProteinSerializer(many=True, read_only=True) - -# class Meta(OmicsScoreSerializer): -# meta_fields = ('genes', 'proteins') -# fields = OmicsScoreSerializer.Meta.fields + meta_fields -# read_only_fields = OmicsScoreSerializer.Meta.read_only_fields + meta_fields - - -# class TranscriptScoreSerializer(OmicsScoreSerializer): -# genes = GeneSerializer(many=True, read_only=True) - -# class Meta(OmicsScoreSerializer): -# meta_fields = ('genes',) # transcripts -# fields = OmicsScoreSerializer.Meta.fields + meta_fields -# read_only_fields = OmicsScoreSerializer.Meta.read_only_fields + meta_fields - - - -# class OmicsPlotSerializer(serializers.ModelSerializer): -# platform = PlatformSerializer(many=False, read_only=True) -# sample = SampleSerializer(many=False, read_only=True) - -# class Meta: -# model = Performance -# meta_fields = ('score_id', 'platform', 'sample', 'performance_metrics') -# fields = meta_fields -# read_only_fields = meta_fields \ No newline at end of file + read_only_fields = meta_fields \ No newline at end of file diff --git a/rest_api/templates/rest_api/rest_doc.html b/rest_api/templates/rest_api/rest_doc.html index de65b25..0b5152f 100644 --- a/rest_api/templates/rest_api/rest_doc.html +++ b/rest_api/templates/rest_api/rest_doc.html @@ -52,7 +52,8 @@ // Remove Swagger header //var topbar = document.getElementsByClassName("topbar")[0]; //topbar.parentNode.removeChild(topbar); - + let swagger_ui = document.getElementsByClassName("swagger-ui")[0]; + swagger_ui.style.containerType = 'normal'; // Add Swagger logo var hgroup = document.getElementsByTagName("hgroup")[0]; // Create 'div' class and add it ti the hgroup diff --git a/rest_api/tests.py b/rest_api/tests.py index 978a6b7..2beec71 100644 --- a/rest_api/tests.py +++ b/rest_api/tests.py @@ -15,7 +15,6 @@ class BrowseEndpointTest(APITestCase): # Load data in DB - Must live in the rest_api/fixtures/ directory fixtures = ['db_test'] - # databases = {'default', 'applications'} databases = {'default'} # Change throttle rates for the tests @@ -221,8 +220,6 @@ class BrowseEndpointTest(APITestCase): endpoints_with_filter_ids = ( ('Scores / filter_ids', 'score/all' , scores_list[1:]), # Exclude 1st element ('Publications / filter_ids', 'publication/all' , publication_ids_list[1:]), # Exclude 1st element - # ('Applications - Score / filter_ids', 'applications_score/all', scores_list[1:]), # Exclude 1st element - # ('Applications - Sample', 'applications_sample/all', phenotypes_list[1:]) # Exclude 1st element ) diff --git a/rest_api/urls.py b/rest_api/urls.py index 2082847..9c81246 100644 --- a/rest_api/urls.py +++ b/rest_api/urls.py @@ -13,8 +13,6 @@ url_prefix = 'api' rest_urls = { - 'applications_score': f'{url_prefix}/applications_score/', - 'applications_sample': f'{url_prefix}/applications_sample/', 'cohort': f'{url_prefix}/cohort/', 'dataset': f'{url_prefix}/dataset/', 'external_source': f'{url_prefix}/external_source/', @@ -97,13 +95,6 @@ re_path(r'^'+rest_urls['plot']+'file/search'+slash, cache_page(cache_time)(RestPlotFileSearch.as_view()), name="searchFilePlots"), re_path(r'^'+rest_urls['plot']+'score/search'+slash, cache_page(cache_time)(RestPlotScoreSearch.as_view()), name="searchScorePlots"), - # Applications [DEPRECATED] - re_path(r'^'+rest_urls['phenotype_old']+'(?P[^/]+)'+slash, RestPhenotypeOld.as_view(), name="getPhenotypeOld"), - re_path(r'^'+rest_urls['applications_score']+'all'+slash, cache_page(cache_time)(RestListPhenotypeScore.as_view()), name="getAllPhenotypeScores"), - re_path(r'^'+rest_urls['applications_score']+'search'+slash, RestPhenotypeScoreSearch.as_view(), name="searchPhenotypeScores"), - re_path(r'^'+rest_urls['applications_score']+'(?P[^/]+)'+slash, RestPhenotypeScore.as_view(), name="getPhenotypeScore"), - re_path(r'^'+rest_urls['applications_sample']+'all'+slash, cache_page(cache_time)(RestListPhenotypeSample.as_view()), name="getAllPhenotypeSamples"), - # Other re_path(r'^'+rest_urls['info']+slash, RestInfo.as_view(), name="getInfo"), # -> External sources diff --git a/rest_api/views.py b/rest_api/views.py index a6e7095..ae6d4a6 100644 --- a/rest_api/views.py +++ b/rest_api/views.py @@ -10,7 +10,6 @@ from django.core.exceptions import MultipleObjectsReturned from django.conf import settings from omicspred.models import * -from applications.models import * from .serializers import * opgs_prefix = 'OPGS' @@ -40,8 +39,7 @@ 'dataset__publication__curation_status', 'dataset__publication__date_released', 'dataset__publication__authors'], - 'publication_defer': ['curation_notes','curation_status'], - 'publication_applications': [f'publication__{x}' for x in ['doi','journal','firstauthor','authors','title','date_publication']] + 'publication_defer': ['curation_notes','curation_status'] } performance_metric = [Prefetch('performance_metric', queryset=Metric.objects.only('id','performance_id','name_short','estimate').all())] @@ -80,8 +78,6 @@ 'dataset_prefetch': ['samples_training','samples_training__cohorts','samples_validation','samples_validation__cohorts'],#,'dataset_score'], 'platform_prefetch': ['platform_version','platform_version__platform_dataset'], 'publication_datasets': Prefetch('datasets',queryset=Dataset.objects.select_related('platform','platform__platform_master','tissue').all().prefetch_related('samples_training','samples_training__cohorts','samples_validation','samples_validation__cohorts').order_by('num')), - 'score_applications_select': ['phenotype','platform','platform__platform_master','sample','cohort'], - 'score_applications_prefetch': ['genes','proteins','metabolites'], 'score_dataset': ['dataset','dataset__publication','dataset__platform', 'dataset__tissue'], 'score_dataset_full': [ 'dataset', @@ -1816,162 +1812,6 @@ def get_queryset(self): return queryset -################## -## Applications ## -################## -applications_db = 'applications' - -class RestPhenotypeOld(generics.RetrieveAPIView): - """ - Retrieve the Phenotype information - Endpoint: /api/phenotype_old/ - """ - - def get(self, request, phenotype_id): - param_inc_children = self.request.query_params.get('include_children') - try: - queryset = Phenotype.objects.using(applications_db).prefetch_related('phenotype_score').get(id=phenotype_id) - except Phenotype.DoesNotExist: - queryset = None - if (param_inc_children and str(param_inc_children)=='1'): - serializer = PhenotypeOldSerializerExtended(queryset,many=False) - else: - serializer = PhenotypeOldSerializerScoresCount(queryset,many=False) - return Response(serializer.data) - - -class RestListPhenotypeScore(generics.ListAPIView): - """ - Retrieve all the Phenotype Score Applications - Endpoint: /api/applications_score/all - """ - serializer_class = ScoreApplicationsSerializer - - def get_queryset(self): - # Fetch all the ScoresApplications - # queryset = ScoreApplications.objects.using(applications_db).select_related(*related_dict['score_applications_select']).all().prefetch_related('molecular_traits').annotate(phenotype_as_float=Cast('phenotype__id', output_field=FloatField())) - queryset = ScoreApplications.objects.using(applications_db).select_related(*related_dict['score_applications_select']).all().prefetch_related(*related_dict['score_applications_prefetch']).annotate(phenotype_as_float=Cast('phenotype__id', output_field=FloatField())) - - # Filter by list of Score IDs - ids_list = get_ids_list(self) - if ids_list: - queryset = queryset.filter(score_id__in=ids_list) - - # Filter data - FOR PRIVATE USE CASE - filter_term = self.request.query_params.get('filter') - if filter_term and filter_term is not None: - queryset = queryset.filter(Q(score_id__iexact=filter_term) | Q(platform__name__iexact=filter_term) | Q(platform__platform_master__type__iexact=filter_term) | - Q(phenotype__id__iexact=filter_term) | Q(phenotype__name__icontains=filter_term) | Q(phenotype__category__icontains=filter_term) | - Q(cohort__name_short__iexact=filter_term) | Q(cohort__name_full__iexact=filter_term) | - Q(genes__external_id__iexact=filter_term) | Q(genes__name__icontains=filter_term) | - Q(proteins__external_id__iexact=filter_term) | Q(proteins__name__icontains=filter_term) | - Q(metabolites__external_id__iexact=filter_term) | Q(metabolites__name__icontains=filter_term)) - # Sort data + distinct data - queryset = sort_data_list(self.request,'score_application',queryset,'phenotype_as_float') - # return queryset.distinct() - return queryset - - -class RestPhenotypeScore(generics.ListAPIView): - """ - Retrieve all the Phenotype Score Application for a given Score ID - Endpoint: /api/applications_score/ - """ - - serializer_class = ScoreApplicationsSerializer - - def get_queryset(self): - opgs_id = self.kwargs['opgs_id'].upper() - # queryset = ScoreApplications.objects.using(applications_db).select_related(*related_dict['score_applications_select']).prefetch_related('molecular_traits').filter(score_id=opgs_id) - queryset = ScoreApplications.objects.using(applications_db).select_related(*related_dict['score_applications_select']).prefetch_related(*related_dict['score_applications_prefetch']).filter(score_id=opgs_id) - return queryset - - -class RestPhenotypeScoreSearch(generics.ListAPIView): - """ - Search the Phenotype Score Application using query - Endpoint: /api/applications_score/search - """ - serializer_class = ScoreApplicationsSerializer - - def get_queryset(self): - # queryset = ScoreApplications.objects.using(applications_db).defer(*defer_dict['publication_applications']).select_related(*related_dict['score_applications_select'],'publication').prefetch_related('molecular_traits').all() - queryset = ScoreApplications.objects.using(applications_db).defer(*defer_dict['publication_applications']).select_related(*related_dict['score_applications_select'],'publication').prefetch_related(*related_dict['score_applications_prefetch']).all() - params = 0 - - # Search by Score ID - opgs_id = self.request.query_params.get('opgs_id') - if opgs_id and opgs_id is not None: - opgs_id = opgs_id.upper() - queryset = queryset.filter(score_id=opgs_id) - params += 1 - # Search by PubMed ID - opp_id = self.request.query_params.get('opp_id') - if opp_id and opp_id is not None: - if opp_id.upper().startswith(opp_prefix): - publication_num = get_publication_num(opp_id) - queryset = queryset.filter(Q(publication__num=publication_num)) - # queryset = queryset.filter(Q(publication__id=opp_id)) - params += 1 - pmid = self.request.query_params.get('pmid') - if pmid and pmid.isnumeric(): - queryset = queryset.filter(publication__pmid=pmid) - params += 1 - # Search by Phenotype ID - phenotype_id = self.request.query_params.get('phenotype_id') - if phenotype_id and re.match(r'^\d+\.?\d*$',phenotype_id): - queryset = queryset.filter(phenotype__id=phenotype_id) - params += 1 - # # Search by Molecular Trait ID/name (gene, protein, metabolite) - molecular_trait = self.request.query_params.get('molecular_trait') - if molecular_trait and molecular_trait is not None: - queryset = queryset.filter(Q(genes__name__iexact=molecular_trait) | Q(genes__external_id__iexact=molecular_trait) | - Q(proteins__name__iexact=molecular_trait) | Q(proteins__external_id__iexact=molecular_trait) | - Q(metabolites__name__iexact=molecular_trait) | Q(metabolites__external_id__iexact=molecular_trait)) - params += 1 - - # # Filter data - FOR PRIVATE USE CASE - # filter_term = self.request.query_params.get('filter') - # if filter_term and filter_term is not None: - # # queryset = queryset.filter(Q(score_id__iexact=filter_term) | Q(molecular_traits__external_id__iexact=filter_term) | Q(molecular_traits__name__icontains=filter_term)) - # queryset = queryset.filter(Q(score_id__iexact=filter_term) | - # Q(genes__external_id__iexact=filter_term) | Q(genes__name__icontains=filter_term) | - # Q(proteins__external_id__iexact=filter_term) | Q(proteins__name__icontains=filter_term) | - # Q(metabolites__external_id__iexact=filter_term) | Q(metabolites__name__icontains=filter_term) | - # Q(publication__id__iexact=filter_term)) - - if params == 0: - queryset = [] - - return queryset - - -class RestListPhenotypeSample(generics.ListAPIView): - """ - Retrieve all the Phenotype Sample Applications - Endpoint: /api/applications_sample/all - """ - serializer_class = SampleApplicationsLegacySerializer - - def get_queryset(self): - # Fetch all the ScoresApplications - queryset = SampleApplicationsLegacy.objects.using(applications_db).select_related('phenotype',).all().prefetch_related('phenotype__phenotype_score').annotate(phenotype_as_float=Cast('phenotype__id', output_field=FloatField())) - - # Filter by list of PheCode IDs - ids_list = get_ids_list(self) - if ids_list: - queryset = queryset.filter(phenotype__id__in=ids_list) - - # Filter data - FOR PRIVATE USE CASE - filter_term = self.request.query_params.get('filter') - if filter_term and filter_term is not None: - queryset = queryset.filter(Q(phenotype__id__iexact=filter_term) | Q(phenotype__name__icontains=filter_term) | Q(phenotype__category__icontains=filter_term)) - # Sort data - queryset = sort_data_list(self.request,'sample_application',queryset,'phenotype_as_float') - - return queryset - - class RestInfo(generics.RetrieveAPIView): """ Return diverse information related to the REST API and the PGS Catalog @@ -1992,8 +1832,6 @@ def get(self, request): 'pathways': Pathway.objects.count(), 'phenotypes': Phenotype.objects.count(), 'phewas': ScorePheWAS.objects.count(), - # 'phenotypes': PhenotypeOld.objects.using(applications_db).count(), - # 'phenotype_associations': ScoreApplications.objects.using(applications_db).count(), 'tissues': Tissue.objects.filter(type='tissue').count() } }