34cf26077bf08310d4164cb079c09d485669815e
[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_for = models.CharField(max_length=50, blank=True, 
140       verbose_name='ChIP/DNA/RNA Made By')
141   made_by = models.CharField(max_length=50, blank=True, default="Lorian")
142   
143   PROTOCOL_END_POINTS = (
144       ('?', 'Unknown'),
145       ('Sample', 'Raw sample'),
146       ('Progress', 'In progress'),
147       ('1A', 'Ligation, then gel'),
148       ('PCR', 'Ligation, then PCR'),
149       ('1Ab', 'Ligation, PCR, then gel'),
150       ('1Aa', 'Ligation, gel, then PCR'),
151       ('2A', 'Ligation, PCR, gel, PCR'),
152       ('Done', 'Completed'),
153     )
154   stopping_point = models.CharField(max_length=25, choices=PROTOCOL_END_POINTS, default='Done')
155   amplified_from_sample = models.ForeignKey('self', blank=True, null=True)  
156   
157   undiluted_concentration = models.DecimalField("Undiluted concentration (ng/ul)", max_digits=5, decimal_places=2, default=0, blank=True, null=True)
158   successful_pM = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
159   ten_nM_dilution = models.BooleanField()
160   avg_lib_size = models.IntegerField(default=225, blank=True, null=True)
161   notes = models.TextField(blank=True)
162   
163   def __unicode__(self):
164     return u'#%s: %s' % (self.library_id, self.library_name)
165   
166   class Meta:
167     verbose_name_plural = "libraries"
168     ordering = ["-creation_date"] #["-library_id"]
169   
170   def antibody_name(self):
171     str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>' 
172     return str
173   antibody_name.allow_tags = True
174
175   def organism(self):
176     return self.library_species.common_name
177
178   def affiliation(self):
179     affs = self.affiliations.all().order_by('name')
180     tstr = ''
181     ar = []
182     for t in affs:
183         ar.append(t.__unicode__())
184     return '%s' % (", ".join(ar))
185
186   def libtags(self):
187     affs = self.tags.all().order_by('tag_name')
188     ar = []
189     for t in affs:
190       ar.append(t.__unicode__())
191     return u'%s' % ( ", ".join(ar))
192
193   def DataRun(self):
194     str ='<a target=_self href="/admin/experiments/datarun/?q='+self.library_id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>' 
195     return str
196   DataRun.allow_tags = True
197
198   def aligned_m_reads(self):
199     return getLibReads(self.library_id)
200
201   def aligned_reads(self):
202     res = getLibReads(self.library_id)
203
204     # Check data sanity
205     if res[2] != "OK":
206       return u'<div style="border:solid red 2px">'+res[2]+'</div>'
207
208     rc = "%1.2f" % (res[1]/1000000.0)
209     # 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
210     if res[0] > 0:
211       bgcolor = '#ff3300'  # Red
212       rc_thr = [10000000,5000000,3000000]
213       if self.experiment_type == 'RNA-seq':
214         rc_thr = [20000000,10000000,6000000]
215
216       if res[1] > rc_thr[0]:
217         bgcolor = '#66ff66'  # Green
218       else:
219         if res[1] > rc_thr[1]:
220           bgcolor ='#00ccff'  # Blue
221         else:
222            if res[1] > rc_thr[2]: 
223              bgcolor ='#ffcc33'  # Orange
224       tstr = '<div style="background-color:'+bgcolor+';color:black">'
225       tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
226       tstr += '</div>'
227     else: tstr = 'not processed yet' 
228     return tstr
229   aligned_reads.allow_tags = True
230