Merged much of the stanford htsworkflow frontend into trunk.
[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.frontend.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: 
12     # alter table fctracker_antibody add column "nickname" varchar(20) NULL;
13     nickname = models.CharField(
14         max_length=20,
15         blank=True,
16         null=True, 
17         db_index=True,
18         verbose_name = 'Short Name'
19     )
20     catalog = models.CharField(max_length=50, unique=True, db_index=True)
21     antibodies = models.CharField(max_length=500, db_index=True)
22     source = models.CharField(max_length=500, blank=True, db_index=True)
23     biology = models.TextField(blank=True)
24     notes = models.TextField(blank=True)
25     def __unicode__(self):
26         return u'%s - %s (%s)' % (self.antigene, self.antibodies, self.catalog)
27     class Meta:
28         verbose_name_plural = "antibodies"
29         ordering = ["antigene"]
30
31 class Cellline(models.Model):
32     cellline_name = models.CharField(max_length=100, unique=True, db_index=True)
33     nickname = models.CharField(max_length=20,
34         blank=True,
35         null=True, 
36         db_index=True,
37         verbose_name = 'Short Name')
38     notes = models.TextField(blank=True)
39     def __unicode__(self):
40         return unicode(self.cellline_name)
41
42     class Meta:
43         ordering = ["cellline_name"]
44
45 class Condition(models.Model):
46     condition_name = models.CharField(
47         max_length=2000, unique=True, db_index=True)
48     nickname = models.CharField(max_length=20,
49         blank=True,
50         null=True, 
51         db_index=True,
52         verbose_name = 'Short Name')
53     notes = models.TextField(blank=True)
54
55     def __unicode__(self):
56         return unicode(self.condition_name)
57
58     class Meta:
59         ordering = ["condition_name"]
60
61 class Tag(models.Model): 
62   tag_name = models.CharField(max_length=100, db_index=True,blank=False,null=False) 
63   TAG_CONTEXT = ( 
64       #('Antibody','Antibody'), 
65       #('Cellline', 'Cellline'), 
66       #('Condition', 'Condition'), 
67       ('Library', 'Library'), 
68       ('ANY','ANY'), 
69   ) 
70   context = models.CharField(max_length=50, 
71       choices=TAG_CONTEXT, default='Library') 
72  
73   def __unicode__(self): 
74     return u'%s' % (self.tag_name) 
75  
76   class Meta: 
77     ordering = ["context","tag_name"] 
78  
79 class Species(models.Model):
80   scientific_name = models.CharField(max_length=256, 
81       unique=False, 
82       db_index=True
83   )
84   common_name = models.CharField(max_length=256, blank=True)
85   #use_genome_build = models.CharField(max_length=100, blank=False, null=False)
86
87   def __unicode__(self):
88     return u'%s (%s)' % (self.scientific_name, self.common_name)
89   
90   class Meta:
91     verbose_name_plural = "species"
92     ordering = ["scientific_name"]
93   
94 class Affiliation(models.Model):
95   name = models.CharField(max_length=256, db_index=True, verbose_name='Group Name')
96   contact = models.CharField(max_length=256, null=True, blank=True,verbose_name='Contact Name')  
97   email = models.EmailField(null=True,blank=True)
98   
99   def __unicode__(self):
100     str = unicode(self.name)
101     if len(self.contact) != 0:
102       str += u' ('+self.contact+u')' 
103     return str
104
105   class Meta:
106     ordering = ["name","contact"]
107     unique_together = (("name", "contact"),)
108
109 class Library(models.Model):
110   
111   library_id = models.CharField(max_length=30, primary_key=True, db_index=True)
112   library_name = models.CharField(max_length=100, unique=True)
113   library_species = models.ForeignKey(Species)
114   cell_line = models.ForeignKey(Cellline)
115   condition = models.ForeignKey(Condition)
116   antibody = models.ForeignKey(Antibody,blank=True,null=True)
117   # New field Aug/25/08. SQL: alter table fctracker_library add column "lib_affiliation" varchar(256)  NULL;
118   affiliations = models.ManyToManyField(Affiliation,related_name='library_affiliations',null=True)
119   # new field Nov/14/08
120   tags = models.ManyToManyField(Tag,related_name='library_tags',blank=True,null=True)
121   # New field Aug/19/08
122   # SQL to add column: alter table fctracker_library add column "replicate" smallint unsigned NULL;
123   REPLICATE_NUM = ((1,1),(2,2),(3,3),(4,4))
124   replicate =  models.PositiveSmallIntegerField(choices=REPLICATE_NUM,default=1) 
125
126   EXPERIMENT_TYPES = (
127       ('INPUT_RXLCh','INPUT_RXLCh'),
128       ('ChIP-seq', 'ChIP-seq'),
129       ('Sheared', 'Sheared'),
130       ('RNA-seq', 'RNA-seq'),
131       ('Methyl-seq', 'Methyl-seq'),
132       ('DIP-seq', 'DIP-seq'),
133     ) 
134   experiment_type = models.CharField(max_length=50, choices=EXPERIMENT_TYPES,
135                                      default='RNA-seq')
136   
137   creation_date = models.DateField(blank=True, null=True)
138   made_for = models.ForeignKey(User)
139   made_by = models.CharField(max_length=50, blank=True, default="Lorian")
140   
141   PROTOCOL_END_POINTS = (
142       ('?', 'Unknown'),
143       ('Sample', 'Raw sample'),
144       ('Progress', 'In progress'),
145       ('1A', 'Ligation, then gel'),
146       ('PCR', 'Ligation, then PCR'),
147       ('1Ab', 'Ligation, PCR, then gel'),
148       ('1Aa', 'Ligation, gel, then PCR'),
149       ('2A', 'Ligation, PCR, gel, PCR'),
150       ('Done', 'Completed'),
151     )
152   stopping_point = models.CharField(max_length=25, choices=PROTOCOL_END_POINTS, default='Done')
153   amplified_from_sample = models.ForeignKey('self', blank=True, null=True)  
154   
155   undiluted_concentration = models.DecimalField("Undiluted concentration (ng/ul)", max_digits=5, decimal_places=2, default=0, blank=True, null=True)
156   successful_pM = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
157   ten_nM_dilution = models.BooleanField()
158   avg_lib_size = models.IntegerField(default=225, blank=True, null=True)
159   notes = models.TextField(blank=True)
160   
161   def __unicode__(self):
162     return u'#%s: %s' % (self.library_id, self.library_name)
163   
164   class Meta:
165     verbose_name_plural = "libraries"
166     ordering = ["-creation_date"] #["-library_id"]
167   
168   def antibody_name(self):
169     str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>' 
170     return str
171   antibody_name.allow_tags = True
172
173   def organism(self):
174     return self.library_species.common_name
175
176   def affiliation(self):
177     affs = self.affiliations.all().order_by('name')
178     tstr = ''
179     ar = []
180     for t in affs:
181         ar.append(t.__unicode__())
182     return '%s' % (", ".join(ar))
183
184   def libtags(self):
185     affs = self.tags.all().order_by('tag_name')
186     ar = []
187     for t in affs:
188       ar.append(t.__unicode__())
189     return u'%s' % ( ", ".join(ar))
190
191   def DataRun(self):
192     str ='<a target=_self href="/admin/experiments/datarun/?q='+self.library_id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>' 
193     return str
194   DataRun.allow_tags = True
195
196   def aligned_m_reads(self):
197     return getLibReads(self.library_id)
198
199   def aligned_reads(self):
200     res = getLibReads(self.library_id)
201
202     # Check data sanity
203     if res[2] != "OK":
204       return u'<div style="border:solid red 2px">'+res[2]+'</div>'
205
206     rc = "%1.2f" % (res[1]/1000000.0)
207     # 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
208     if res[0] > 0:
209       bgcolor = '#ff3300'  # Red
210       rc_thr = [10000000,5000000,3000000]
211       if self.experiment_type == 'RNA-seq':
212         rc_thr = [20000000,10000000,6000000]
213
214       if res[1] > rc_thr[0]:
215         bgcolor = '#66ff66'  # Green
216       else:
217         if res[1] > rc_thr[1]:
218           bgcolor ='#00ccff'  # Blue
219         else:
220            if res[1] > rc_thr[2]: 
221              bgcolor ='#ffcc33'  # Orange
222       tstr = '<div style="background-color:'+bgcolor+';color:black">'
223       tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
224       tstr += '</div>'
225     else: tstr = 'not processed yet' 
226     return tstr
227   aligned_reads.allow_tags = True
228