Merge in new modules from htsworkflow branch.
[htsworkflow.git] / htsworkflow / frontend / samples / models.py
1 from django.db import models
2 from django.contrib.auth.models import User
3 from htsworkflow.frontend import settings
4 from htsworkflow.reports.libinfopar import *
5
6 # Create your models here.
7
8 class Antibody(models.Model):
9   antigene = models.CharField(max_length=500, db_index=True)
10   # New field Aug/20/08                                                                                                                                                            
11   # SQL to add column: alter table fctracker_antibody add column "nickname" varchar(20) NULL;
12   nickname = models.CharField(max_length=20,blank=True,null=True, db_index=True,verbose_name = 'Short Name')
13   catalog = models.CharField(max_length=50, unique=True, db_index=True)
14   antibodies = models.CharField(max_length=500, db_index=True)
15   source = models.CharField(max_length=500, blank=True, db_index=True)
16   biology = models.TextField(blank=True)
17   notes = models.TextField(blank=True)
18   def __str__(self):
19     return '%s - %s (%s)' % (self.antigene, self.antibodies, self.catalog)
20   class Meta:
21     verbose_name_plural = "antibodies"
22     ordering = ["antigene"]
23   class Admin:
24       list_display = ('antigene','nickname','antibodies','catalog','source','biology','notes')
25       list_filter = ('antibodies','source')
26       fields = (
27         (None, {
28             'fields': (('antigene','nickname','antibodies'),('catalog','source'),('biology'),('notes'))
29         }),
30        )
31
32 class Cellline(models.Model):
33   cellline_name = models.CharField(max_length=100, unique=True, db_index=True)
34   notes = models.TextField(blank=True)
35   def __str__(self):
36     return '%s' % (self.cellline_name)
37
38   class Meta:
39     ordering = ["cellline_name"]
40
41   class Admin:
42       fields = (
43         (None, {
44             'fields': (('cellline_name'),('notes'),)
45         }),
46        )
47
48 class Condition(models.Model):
49   condition_name = models.CharField(max_length=2000, unique=True, db_index=True)
50   notes = models.TextField(blank=True)
51   def __str__(self):
52     return '%s' % (self.condition_name)
53
54   class Meta:
55     ordering = ["condition_name"]
56
57   class Admin:
58       fields = (
59         (None, {
60             'fields': (('condition_name'),('notes'),)
61         }),
62        )
63
64 class Species(models.Model):
65   
66   scientific_name = models.CharField(max_length=256, unique=False, db_index=True, core=True)
67   common_name = models.CharField(max_length=256, blank=True)
68   use_genome_build = models.CharField(max_length=100, blank=False, null=False)
69
70   def __str__(self):
71     return '%s (%s)|%s' % (self.scientific_name, self.common_name, self.use_genome_build)
72   
73   class Meta:
74     verbose_name_plural = "species"
75     ordering = ["scientific_name"]
76   
77   class Admin:
78       fields = (
79         (None, {
80             'fields': (('scientific_name', 'common_name'), ('use_genome_build'))
81         }),
82       )
83
84 class Affiliation(models.Model):
85   name = models.CharField(max_length=256, db_index=True, core=True,verbose_name='Group Name')
86   contact = models.CharField(max_length=256, null=True, blank=True,verbose_name='Contact Name')  
87   email = models.EmailField(null=True,blank=True)
88   
89   def __str__(self):
90     str = self.name
91     if self.contact != '':
92       str += ' ('+self.contact+')' 
93     return str
94
95   class Meta:
96     ordering = ["name","contact"]
97     unique_together = (("name", "contact"),)
98
99   class Admin:
100       list_display = ('name','contact','email')
101       fields = (
102         (None, {
103             'fields': (('name','contact','email'))
104         }),
105       )
106
107 class Library(models.Model):
108   
109   library_id = models.CharField(max_length=30, primary_key=True, db_index=True, core=True)
110   library_name = models.CharField(max_length=100, unique=True, core=True)
111   library_species = models.ForeignKey(Species, core=True)
112   cell_line = models.ForeignKey(Cellline,core=True)
113   condition = models.ForeignKey(Condition,core=True)
114   antibody = models.ForeignKey(Antibody,blank=True,null=True,core=True)
115   # New field Aug/25/08. SQL: alter table fctracker_library add column "lib_affiliation" varchar(256)  NULL;
116   affiliations = models.ManyToManyField(Affiliation,related_name='library_affiliations',null=True,filter_interface=models.HORIZONTAL)
117   # New field Aug/19/08
118   # SQL to add column: alter table fctracker_library add column "replicate" smallint unsigned NULL;
119   REPLICATE_NUM = ((1,1),(2,2),(3,3),(4,4))
120   replicate =  models.PositiveSmallIntegerField(choices=REPLICATE_NUM,default=1) 
121
122   EXPERIMENT_TYPES = (
123       ('INPUT_RXLCh','INPUT_RXLCh'),
124       ('ChIP-seq', 'ChIP-seq'),
125       ('Sheared', 'Sheared'),
126       ('RNA-seq', 'RNA-seq'),
127       ('Methyl-seq', 'Methyl-seq'),
128       ('DIP-seq', 'DIP-seq'),
129     ) 
130   experiment_type = models.CharField(max_length=50, choices=EXPERIMENT_TYPES,
131                                      default='RNA-seq')
132   
133   creation_date = models.DateField(blank=True, null=True)
134   made_for = models.ForeignKey(User)
135   made_by = models.CharField(max_length=50, blank=True, default="Lorian")
136   
137   PROTOCOL_END_POINTS = (
138       ('?', 'Unknown'),
139       ('Sample', 'Raw sample'),
140       ('Progress', 'In progress'),
141       ('1A', 'Ligation, then gel'),
142       ('PCR', 'Ligation, then PCR'),
143       ('1Ab', 'Ligation, PCR, then gel'),
144       ('1Aa', 'Ligation, gel, then PCR'),
145       ('2A', 'Ligation, PCR, gel, PCR'),
146       ('Done', 'Completed'),
147     )
148   stopping_point = models.CharField(max_length=25, choices=PROTOCOL_END_POINTS, default='Done')
149   amplified_from_sample = models.ForeignKey('self', blank=True, null=True)  
150   
151   undiluted_concentration = models.DecimalField("Undiluted concentration (ng/ul)", max_digits=5, decimal_places=2, default=0, blank=True, null=True)
152   successful_pM = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
153   ten_nM_dilution = models.BooleanField()
154   avg_lib_size = models.IntegerField(default=225, blank=True, null=True)
155   notes = models.TextField(blank=True)
156   
157   def __str__(self):
158     return '#%s: %s' % (self.library_id, self.library_name)
159   
160   class Meta:
161     verbose_name_plural = "libraries"
162     ordering = ["-creation_date"] #["-library_id"]
163   
164   def antibody_name(self):
165     return self.antibody.nickname
166
167   def org(self):
168     return self.library_species.common_name
169
170   def affiliation(self):
171     affs = self.affiliations.all().order_by('name')
172     tstr = ''
173     ar = []
174     for t in affs:
175         ar.append(t.__str__())
176     return '%s' % (", ".join(ar))
177
178
179   def aligned_reads(self):
180     res = getLibReads(self.library_id)
181     rc = "%1.2f" % (res[1]/1000000.0)
182     # Color Scheme: green is more than 10M, blue is more than 5M, orange is more than 3M and red is less. For RNAseq, all those thresholds should be doubled
183     if res[0] > 0:
184       bgcolor = '#ff3300'  # Red
185       rc_thr = [10000000,5000000,3000000]
186       if self.experiment_type == 'RNA-seq':
187         rc_thr = [20000000,10000000,6000000]
188
189       if res[1] > rc_thr[0]:
190         bgcolor = '#66ff66'  # Green
191       else:
192         if res[1] > rc_thr[1]:
193           bgcolor ='#00ccff'  # Blue
194         else:
195            if res[1] > rc_thr[2]: 
196              bgcolor ='#ffcc33'  # Orange
197       tstr = '<div style="background-color:'+bgcolor+';color:black">'
198       tstr += res[0].__str__()+' Lanes, '+rc+' M Reads'
199       tstr += '</div>'
200     else: tstr = 'not processed yet' 
201     return tstr
202   aligned_reads.allow_tags = True
203
204   class Admin:
205     date_hierarchy = "creation_date"
206     save_as = True
207     save_on_top = True
208     ##search_fields = ['library_id','library_name','affiliations__name','affiliations__contact','made_by','made_for','antibody__antigene','antibody__catalog','antibody__antibodies','antibody__source','cell_line__cellline_name','library_species__scientific_name','library_species__common_name','library_species__use_genome_build']
209     search_fields = ['library_id','library_name','cell_line__cellline_name','library_species__scientific_name','library_species__common_name','library_species__use_genome_build']
210     list_display = ('affiliation','library_id','aligned_reads','library_name','experiment_type','org','replicate','antibody_name','cell_line','made_by','creation_date')
211     list_display_links = ('library_id', 'library_name')
212
213     list_filter = ('experiment_type','affiliations','library_species','made_for', 'made_by','replicate')
214     fields = (
215         (None, {
216             'fields': (('replicate','library_id','library_name'),('library_species'),('experiment_type'),('cell_line','condition','antibody'),)
217         }),
218         ('Creation Information:', {
219             'fields' : (('made_for', 'made_by', 'creation_date'), ('stopping_point', 'amplified_from_sample'), ('undiluted_concentration', 'library_size'), 'notes',)
220         }),
221         ('Library/Project Affiliation:', {
222             'fields' : (('affiliations'),)
223         }),
224         )
225