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