diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..6df7ed09a088452955ac736d2f21729ad6810fb3 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,9 @@ +test-centos7: + image: centos:centos7 + stage: test + script: + - yum install -y epel-release + - yum install install -y python34-pip python34-devel + - cd ippisite + - pip3 install -r requirements.txt + - python3 manage.py test \ No newline at end of file diff --git a/ippisite/db.sqlite3 b/ippisite/db.sqlite3 index 89d5cf044b79d1546780d04ccc912a4742b52c8c..47ec17349e4b67ca860f635c93619456554a9e2f 100644 Binary files a/ippisite/db.sqlite3 and b/ippisite/db.sqlite3 differ diff --git a/ippisite/ippidb/admin.py b/ippisite/ippidb/admin.py index 29b059b53b45ac71042ed0257ab091187cf3c2a9..da7c16f971962cd68c714bfdd3cbfff2d9088f3f 100644 --- a/ippisite/ippidb/admin.py +++ b/ippisite/ippidb/admin.py @@ -14,6 +14,10 @@ class ProteinAdmin(admin.ModelAdmin): class TaxonomyAdmin(admin.ModelAdmin): list_display = ('taxonomy_id', 'name') +@admin.register(Domain) +class DomainAdmin(admin.ModelAdmin): + list_display = ('pfam_acc', 'pfam_id', 'pfam_description', 'domain_family') + for model in apps.get_app_config('ippidb').models.values(): try: admin.site.register(model) diff --git a/ippisite/ippidb/management/commands/import_v1_data.py b/ippisite/ippidb/management/commands/import_v1_data.py index 5d6592cc642cec1bcbbe1e0e411930ac3fec7eed..11861016c345b4d89e79b9960b7ddb8fce10db9e 100644 --- a/ippisite/ippidb/management/commands/import_v1_data.py +++ b/ippisite/ippidb/management/commands/import_v1_data.py @@ -1,7 +1,7 @@ from django.core.management import BaseCommand, CommandError import mysql.connector -from ippidb.models import Bibliography, Protein, Taxonomy, MolecularFunction +from ippidb.models import Bibliography, Protein, Taxonomy, MolecularFunction, Domain class Command(BaseCommand): @@ -22,6 +22,13 @@ class Command(BaseCommand): default=False, help='Flush and migrate proteins', ) + parser.add_argument( + '--domains', + action='store_true', + dest='domains', + default=False, + help='Flush and migrate domains', + ) parser.add_argument( '--stoponfail', action='store_true', @@ -75,4 +82,24 @@ class Command(BaseCommand): self.stdout.write(self.style.ERROR('Failed inserting {} {}'.format(row[1], row[2]))) else: self.stdout.write(self.style.SUCCESS('Successfully inserted {} {}'.format(row[1], row[2]))) + if options['domains']: + cursor.execute("""SELECT * FROM domain""") + rows = cursor.fetchall() + Domain.objects.all().delete() + self.stdout.write(self.style.SUCCESS('Successfully flushed domain table')) + for row in rows: + try: + p = Domain() + p.pfam_acc = row[2] + p.domain_family = row[4] + p.save() + except Exception as e: + if options['stoponfail']: + import traceback + self.stderr.write(traceback.format_exc()) + raise CommandError('Failed inserting {} {}'.format(row[1], row[2])) + else: + self.stdout.write(self.style.ERROR('Failed inserting {} {}'.format(row[1], row[2]))) + else: + self.stdout.write(self.style.SUCCESS('Successfully inserted {} {}'.format(row[1], row[2]))) diff --git a/ippisite/ippidb/migrations/0007_auto_20170328_2045.py b/ippisite/ippidb/migrations/0007_auto_20170328_2045.py new file mode 100644 index 0000000000000000000000000000000000000000..47a59cc6b02bd96637dc325113682f9f3a82d2fc --- /dev/null +++ b/ippisite/ippidb/migrations/0007_auto_20170328_2045.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-03-28 20:45 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('ippidb', '0006_auto_20170327_1439'), + ] + + operations = [ + migrations.RenameField( + model_name='domain', + old_name='domainfamily', + new_name='domain_family', + ), + ] diff --git a/ippisite/ippidb/migrations/0008_auto_20170329_1441.py b/ippisite/ippidb/migrations/0008_auto_20170329_1441.py new file mode 100644 index 0000000000000000000000000000000000000000..a4226179155219adea04ba3b82a39d7d71e0d581 --- /dev/null +++ b/ippisite/ippidb/migrations/0008_auto_20170329_1441.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-03-29 14:41 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('ippidb', '0007_auto_20170328_2045'), + ] + + operations = [ + migrations.CreateModel( + name='RefCompoundBiblio', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('compound_name', models.CharField(max_length=50, verbose_name='Compound name in the publication')), + ('bibliography_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ippidb.Bibliography')), + ('compound_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ippidb.Compound')), + ], + ), + migrations.AddField( + model_name='cmpdaction', + name='nb_copy_compounds', + field=models.IntegerField(default=1, verbose_name='Number of copies for the compound'), + preserve_default=False, + ), + migrations.AddField( + model_name='cmpdaction', + name='pdb_id', + field=models.CharField(default='NA', max_length=4, verbose_name='PDB ID'), + preserve_default=False, + ), + migrations.AddField( + model_name='cmpdaction', + name='ppi_id', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='ippidb.Ppi'), + preserve_default=False, + ), + migrations.AddField( + model_name='compoundactivityresult', + name='modulation_type', + field=models.CharField(choices=[('B', 'Binding'), ('I', 'Inhibition'), ('S', 'Stabilization')], default='B', max_length=1, verbose_name='Modulation type'), + preserve_default=False, + ), + migrations.AlterField( + model_name='cmpdaction', + name='activation_mode', + field=models.CharField(choices=[('O', 'Orthosteric'), ('A', 'Allosteric')], max_length=1, verbose_name='Activation mode'), + ), + migrations.RemoveField( + model_name='cmpdaction', + name='modulation_type', + ), + migrations.AlterUniqueTogether( + name='cmpdaction', + unique_together=set([('complex_id', 'compound_id', 'pdb_id')]), + ), + migrations.AlterUniqueTogether( + name='refcompoundbiblio', + unique_together=set([('compound_id', 'bibliography_id')]), + ), + ] diff --git a/ippisite/ippidb/models.py b/ippisite/ippidb/models.py index 4ce93714c4252e463804ef049342e5a135f2f92d..73de8458539437385dce0540cea8f25e73073cf9 100644 --- a/ippisite/ippidb/models.py +++ b/ippisite/ippidb/models.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals from django.db import models from django.forms import ModelForm -from .ws import get_pubmed_info, get_epo_info, get_uniprot_info, get_taxonomy_info, get_go_info +from .ws import get_pubmed_info, get_epo_info, get_uniprot_info, get_taxonomy_info, get_go_info, get_pfam_info class Bibliography(models.Model): """ @@ -111,7 +111,16 @@ class Domain(models.Model): pfam_acc = models.CharField('Pfam Accession', max_length=10, unique=True) pfam_id = models.CharField('Pfam Family Identifier', max_length=20) pfam_description = models.CharField('Pfam Description', max_length=100) - domainfamily = models.CharField('Domain family', max_length=25) #TODO: what is this field? check database contents + domain_family = models.CharField('Domain family', max_length=25) #TODO: what is this field? check database contents + + def save(self, *args, **kwargs): + info = get_pfam_info(self.pfam_acc) + self.pfam_id = info['id'] + self.pfam_description = info['description'] + super(Domain, self).save(*args, **kwargs) + + def __str__(self): + return '{} ({}-{})'.format(self.pfam_acc, self.pfam_id, self.pfam_description) class ProteinDomainComplex(models.Model): protein_id = models.ForeignKey('Protein') @@ -271,10 +280,16 @@ class ActivityType(models.Model): name = models.CharField('Name', max_length=50, unique=True) class CompoundActivityResult(models.Model): + MODULATION_TYPES = ( + ('B', 'Binding'), + ('I', 'Inhibition'), + ('S', 'Stabilization') + ) compound_id = models.ForeignKey(Compound) test_activity_description_id = models.ForeignKey(TestActivityDescription) activity_type_id = models.ForeignKey(ActivityType) activity = models.DecimalField('Activity', max_digits=12, decimal_places=10) + modulation_type = models.CharField('Modulation type', max_length=1, choices=MODULATION_TYPES) class Meta: unique_together = (('compound_id', 'test_activity_description_id', 'activity_type_id'),) @@ -323,43 +338,22 @@ class CompoundPKResult(models.Model): class CmpdAction(models.Model): ACTIVATION_MODES = ( ('O', 'Orthosteric'), - ('A', 'Allosteric'), - ('U', 'Unspecified') - ) - MODULATION_TYPES = ( - ('I', 'Inhibition'), - ('S', 'Stabilization') + ('A', 'Allosteric') ) complex_id = models.ForeignKey(ProteinDomainBoundComplex) compound_id = models.ForeignKey(Compound) activation_mode = models.CharField('Activation mode', max_length=1, choices=ACTIVATION_MODES) - modulation_type = models.CharField('Modulation type', max_length=1, choices=MODULATION_TYPES) - -"""" -class Actionevidencetest(models.Model): - idcmpdaction = models.ForeignKey('Cmpdaction', models.DO_NOTHING, ='IDCmpdAction') - idtestactivity = models.ForeignKey('Testactivitydescription', models.DO_NOTHING, ='IDTestActivity') - nbcopycompound = models.IntegerField(='NbCopyCompound', blank=True, null=True) + ppi_id = models.ForeignKey(Ppi) + pdb_id = models.CharField('PDB ID', max_length=4) + nb_copy_compounds = models.IntegerField('Number of copies for the compound') class Meta: -# managed = False - db_table = 'actionEvidenceTest' - unique_together = (('idcmpdaction', 'idtestactivity'),) - - + unique_together = (('complex_id', 'compound_id', 'pdb_id'),) - - - - -class Refcmpdbiblio(models.Model): - idcompound = models.ForeignKey(Compound, models.DO_NOTHING, ='IDCompound') - idbiblio = models.ForeignKey(Biblio, models.DO_NOTHING, ='IDBiblio') - cmpdnameinbiblio = models.CharField(='CmpdNameInBiblio', max_length=20, blank=True, null=True) +class RefCompoundBiblio(models.Model): + compound_id = models.ForeignKey(Compound) + bibliography_id = models.ForeignKey(Bibliography) + compound_name = models.CharField('Compound name in the publication', max_length=50) class Meta: -# managed = False - db_table = 'refCmpdBiblio' - unique_together = (('idcompound', 'idbiblio'),) - -""" + unique_together = (('compound_id', 'bibliography_id'),) diff --git a/ippisite/ippidb/ws.py b/ippisite/ippidb/ws.py index 768d0afb7775f26deba7d7a32b0da3231a776ee3..2c178fc1e80ca0bdb39e41d30571bde6756a9797 100644 --- a/ippisite/ippidb/ws.py +++ b/ippisite/ippidb/ws.py @@ -1,6 +1,6 @@ from bioservices.eutils import EUtils from bioservices.uniprot import UniProt -from xml.etree.ElementTree import register_namespace +import xml.etree.ElementTree as ET import requests def get_pubmed_info(pmid): @@ -66,4 +66,15 @@ def get_taxonomy_info(taxonomy_id): eu = EUtils() r = eu.EFetch('taxonomy', taxonomy_id, retmode='dict') scientific_name = r['TaxaSet']['Taxon']['ScientificName'] - return {'scientific_name': scientific_name} + return {'scientific_name': scientific_name} + +def get_pfam_info(pfam_acc): + resp = requests.get('http://pfam.xfam.org/family/{}?output=xml'.format(pfam_acc)) + root = ET.fromstring(resp.text) + ns = {'pfam': 'http://pfam.xfam.org/'} + entry = root.findall('pfam:entry', ns)[0] + pfam_id = entry.attrib['id'] + description = entry.findall('pfam:description', ns)[0].text.strip() + domain_family = '' + return {'id': pfam_id, + 'description': description} diff --git a/ippisite/requirements.txt b/ippisite/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..cd634ed6600b9499d62c890ffe7005b60be0c12b --- /dev/null +++ b/ippisite/requirements.txt @@ -0,0 +1,3 @@ +Django +django-bootstrap3 +bioservices \ No newline at end of file