minor changes
[htsworkflow.git] / htswfrontend / htswfrontend / fctracker / models.py
1 from django.db import models
2 from htswfrontend import settings
3 from htswfrontend.htsw_reports.libinfopar import *
4
5 class Primer(models.Model):
6   primer_name = models.CharField(max_length=100, db_index=True)
7   primer_seq = models.CharField(max_length=50, blank=True, null=True)
8   notes = models.TextField(blank=True)
9   def __str__(self):
10     return '%s' % (self.primer_name)
11   class Meta:
12     ordering = ["primer_name"]
13   class Admin:
14       list_display = ('primer_name','primer_seq','notes')
15       fields = (
16         (None, {
17             'fields': (('primer_name'),('primer_seq'),('notes'))
18         }),
19        )
20
21 class Antibody(models.Model):
22   antigene = models.CharField(max_length=500, db_index=True)
23   # New field Aug/20/08                                                                                                                                                            
24   # SQL to add column: alter table fctracker_antibody add column "nickname" varchar(20) NULL;
25   nickname = models.CharField(max_length=20,blank=True,null=True, db_index=True,verbose_name = 'Short Name')
26   catalog = models.CharField(max_length=50, unique=True, db_index=True)
27   antibodies = models.CharField(max_length=500, db_index=True)
28   source = models.CharField(max_length=500, blank=True, db_index=True)
29   biology = models.TextField(blank=True)
30   notes = models.TextField(blank=True)
31   def __str__(self):
32     return '%s - %s (%s)' % (self.antigene, self.antibodies, self.catalog)
33   class Meta:
34     verbose_name_plural = "antibodies"
35     ordering = ["antigene"]
36   class Admin:
37       list_display = ('antigene','nickname','antibodies','catalog','source','biology','notes')
38       list_filter = ('antibodies','source')
39       search_fields = ['antigene','nickname','catalog','antibodies','source','biology','notes']
40       fields = (
41         (None, {
42             'fields': (('antigene','nickname','antibodies'),('catalog','source'),('biology'),('notes'))
43         }),
44        )
45
46 class Cellline(models.Model):
47   cellline_name = models.CharField(max_length=100, unique=True, db_index=True)
48   nickname = models.CharField(max_length=20,blank=True,null=True, db_index=True,verbose_name = 'Short Name')
49   notes = models.TextField(blank=True)
50   def __str__(self):
51     return '%s' % (self.cellline_name)
52
53   class Meta:
54     ordering = ["cellline_name"]
55     
56   class Admin:
57       list_display = ('cellline_name','nickname','notes')
58       search_fields = ['cellline_name','nickname','notes']
59       fields = (
60         (None, {
61             'fields': (('cellline_name','nickname'),('notes'),)
62         }),
63        )
64
65 class Condition(models.Model):
66   condition_name = models.CharField(max_length=2000, unique=True, db_index=True)
67   nickname = models.CharField(max_length=20,blank=True,null=True, db_index=True,verbose_name = 'Short Name')
68   notes = models.TextField(blank=True)
69   def __str__(self):
70     return '%s' % (self.condition_name)
71
72   class Meta:
73     ordering = ["condition_name"]
74
75   class Admin:
76       list_display = ('condition_name','nickname','notes')
77       fields = (
78         (None, {
79             'fields': (('condition_name','nickname'),('notes'),)
80         }),
81        )
82
83 class Species(models.Model):
84   scientific_name = models.CharField(max_length=256, unique=False, db_index=True, core=True)
85   common_name = models.CharField(max_length=256, blank=True)
86   use_genome_build = models.CharField(max_length=100, blank=False, null=False)
87
88   def __str__(self):
89     return '%s (%s)|%s' % (self.scientific_name, self.common_name, self.use_genome_build)
90   
91   class Meta:
92     verbose_name_plural = "species"
93     ordering = ["scientific_name"]
94   
95   class Admin:
96       fields = (
97         (None, {
98             'fields': (('scientific_name', 'common_name'), ('use_genome_build'))
99         }),
100       )
101
102 class Affiliation(models.Model):
103   name = models.CharField(max_length=256, db_index=True, core=True,verbose_name='Group Name')
104   contact = models.CharField(max_length=256, null=True, blank=True,verbose_name='Contact Name')  
105   email = models.EmailField(null=True,blank=True)
106   
107   def __str__(self):
108     str = self.name
109     if self.contact != '':
110       str += ' ('+self.contact+')' 
111     return str
112
113   class Meta:
114     ordering = ["name","contact"]
115     unique_together = (("name", "contact"),)
116
117   class Admin:
118       list_display = ('name','contact','email')
119       fields = (
120         (None, {
121             'fields': (('name','contact','email'))
122         }),
123       )
124
125 class Tag(models.Model):
126   tag_name = models.CharField(max_length=100,unique=True, db_index=True,core=True,blank=False,null=False)
127   TAG_CONTEXT = (
128       #('Antibody','Antibody'),
129       #('Cellline', 'Cellline'),
130       #('Condition', 'Condition'),
131       ('Library', 'Library'),
132       ('ANY','ANY'),
133     )
134   context = models.CharField(max_length=50, choices=TAG_CONTEXT, default='Library')
135
136   def __str__(self):
137     return '%s' % (self.tag_name)
138
139   class Meta:
140     ordering = ["context","tag_name"]
141
142   class Admin:
143       list_display = ('tag_name','context')
144       fields = (
145         (None, {
146             'fields': ('tag_name','context')
147         }),
148       )
149
150 class Library(models.Model):
151   library_id = models.CharField(max_length=30, unique=True, db_index=True, core=True)
152   library_name = models.CharField(max_length=100, unique=True, core=True)
153   library_species = models.ForeignKey(Species, core=True)
154   cell_line = models.ForeignKey(Cellline,core=True)
155   condition = models.ForeignKey(Condition,core=True)
156   antibody = models.ForeignKey(Antibody,blank=True,null=True,core=True)
157   # New field Aug/25/08. SQL: alter table fctracker_library add column "lib_affiliation" varchar(256)  NULL;
158   affiliations = models.ManyToManyField(Affiliation,related_name='library_affiliations',null=True,filter_interface=models.HORIZONTAL)
159   # New field Nov/14/08
160   tags = models.ManyToManyField(Tag,related_name='library_tags',null=True,blank=True,filter_interface=models.HORIZONTAL)
161   # New field Aug/19/08
162   # SQL to add column: alter table fctracker_library add column "replicate" smallint unsigned NULL;
163   REPLICATE_NUM = ((1,1),(2,2),(3,3),(4,4))
164   replicate =  models.PositiveSmallIntegerField(choices=REPLICATE_NUM,default=1) 
165
166   EXPERIMENT_TYPES = (
167       ('INPUT_RXLCh','INPUT_RXLCh'),
168       ('ChIP-seq', 'ChIP-seq'),
169       ('Sheared', 'Sheared'),
170       ('RNA-seq', 'RNA-seq'),
171       ('Methyl-seq', 'Methyl-seq'),
172       ('DIP-seq', 'DIP-seq'),
173     ) 
174   experiment_type = models.CharField(max_length=50, choices=EXPERIMENT_TYPES, default='ChIP-seq')
175
176   creation_date = models.DateField(blank=True, null=True)
177   made_for = models.CharField(max_length=50, blank=True,verbose_name = 'ChIP/DNA/RNA Made By')
178   made_by = models.CharField(max_length=50, blank=True,verbose_name = 'Library Made By')
179   
180   PROTOCOL_END_POINTS = (
181       ('Completed','Completed'),
182       ('?', 'Unknown'),
183       ('Sample', 'Raw sample'),
184       ('Progress', 'In progress'),
185       ('1A', 'Ligation, then gel'),
186       ('PCR', 'Ligation, then PCR'),
187       ('1Ab', 'Ligation, PCR, then gel'),
188       ('1Aa', 'Ligation, gel, then PCR'),
189       ('2A', 'Ligation, PCR, gel, PCR'),
190     )
191   stopping_point = models.CharField(max_length=50, choices=PROTOCOL_END_POINTS, default='Completed')
192   amplified_from_sample = models.ForeignKey('self', blank=True, null=True)
193   
194   undiluted_concentration = models.DecimalField("Template concentr. (ng/ul)",max_digits=5, decimal_places=2, blank=True, null=True)
195   ten_nM_dilution = models.BooleanField()
196   successful_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=True, null=True)
197   avg_lib_size = models.IntegerField(default=225, blank=True, null=True)
198   notes = models.TextField(blank=True)
199   
200   def __str__(self):
201     return '%s: %s' % (self.library_id, self.library_name)
202   
203   class Meta:
204     verbose_name_plural = "libraries"
205     ordering = ["-creation_date"] #["-library_id"]
206   
207   def antibody_name(self):
208     str ='<a target=_self href="/admin/fctracker/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>'
209     return str
210   antibody_name.allow_tags = True
211
212   def org(self):
213     return self.library_species.common_name
214
215   def cond(self):
216     return self.condition.nickname
217
218   def affiliation(self):
219     affs = self.affiliations.all().order_by('name')
220     tstr = ''
221     ar = []
222     for t in affs:
223         ar.append(t.__str__())
224     return '%s' % (", ".join(ar))
225
226   def libtags(self):
227     affs = self.tags.all().order_by('tag_name')
228     tstr = ''
229     ar = []
230     for t in affs:
231         ar.append(t.__str__())
232     return '%s' % (", ".join(ar))
233
234   def DataRun(self):
235     str ='<a target=_self href="/admin/exp_track/datarun/?q='+self.library_id+'" title="Check All Data Runs for This Specific Library ..." ">DataRuns ..</a>'
236     return str
237   DataRun.allow_tags = True
238
239   def aligned_m_reads(self):
240     return getLibReads(self.library_id)
241
242   def aligned_reads(self):
243     res = getLibReads(self.library_id)
244
245     # Check data sanlty                                                                                                                                    
246     if res[2] != 'OK':
247       return '<div style="border:solid red 2px">'+res[2]+'</div>'
248
249     rc = "%1.2f" % (res[1]/1000000.0)
250     # Color Scheme: green is more than 12M, blue is more than 5M, orange is more than 3M and red is less. For RNAseq, all those thresholds should be doubled
251
252     bgcolor = '#FFCDD0'  # Red, the color for minimum read count
253     rc_thr = [12000000,5000000,3000000]
254     if self.experiment_type == 'RNA-seq':
255       rc_thr = [20000000,10000000,6000000]
256
257     if self.libtags().find('Bad library')!=-1:
258       bgcolor = '#cccccc'
259     else:
260       if res[1] > rc_thr[0]:
261         bgcolor = '#66ff66'  # Green                                                                                                                                                                                                      
262       else:
263         if res[1] > rc_thr[1]:
264           bgcolor ='#00ccff'  # Blue                                                                                                                                                                                                  
265         else:
266            if res[1] > rc_thr[2]:
267              bgcolor ='#ffcc33'  # Orange
268
269     tstr = '<div style="background-color:'+bgcolor+';color:black">'
270     if res[0] > 0:  tstr += res[0].__str__()+' Lanes, '+rc+' M'
271     else: tstr += 'not processed yet'
272     tstr += '</div>'
273  
274     return tstr
275   aligned_reads.allow_tags = True
276
277   class Admin:
278     date_hierarchy = "creation_date"
279     save_as = True
280     save_on_top = True
281     ##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']
282     search_fields = ['library_id','library_name','cell_line__cellline_name','library_species__scientific_name','library_species__common_name','library_species__use_genome_build']
283     list_display = ('affiliation','library_id','aligned_reads','DataRun','library_name','experiment_type','org','replicate','antibody_name','cell_line','cond','libtags','made_by','creation_date')
284     list_display_links = ('library_id', 'library_name')
285     list_filter = ('experiment_type','affiliations','library_species','tags','made_for', 'made_by','replicate','antibody','cell_line','condition')
286     fields = (
287         (None, {
288             'fields': (('replicate','library_id','library_name'),('library_species'),('experiment_type'),('cell_line','condition','antibody'),)
289         }),
290         ('Creation Information:', {
291             'fields' : (('made_for', 'made_by', 'creation_date'), ('stopping_point', 'amplified_from_sample'), ('avg_lib_size','undiluted_concentration', 'ten_nM_dilution', 'successful_pM'), 'notes',)
292         }),
293         ('Library/Project Affiliation:', {
294             'fields' : (('affiliations'),('tags'),)
295         }),
296         )