26d718576d9c45905b9544d733087099d3ec20a3
[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 Library(models.Model):
117   id = models.AutoField(primary_key=True)
118   library_id = models.CharField(max_length=30, db_index=True, unique=True)
119   library_name = models.CharField(max_length=100, unique=True)
120   library_species = models.ForeignKey(Species)
121   # new field 2008 Mar 5, alter table samples_library add column "hidden" NOT NULL default 0;
122   hidden = models.BooleanField()
123   cell_line = models.ForeignKey(Cellline, null=True)
124   condition = models.ForeignKey(Condition, null=True)
125   antibody = models.ForeignKey(Antibody,blank=True,null=True)
126   # New field Aug/25/08. SQL: alter table fctracker_library add column "lib_affiliation" varchar(256)  NULL;
127   affiliations = models.ManyToManyField(Affiliation,related_name='library_affiliations',null=True)
128   # new field Nov/14/08
129   tags = models.ManyToManyField(Tag,related_name='library_tags',blank=True,null=True)
130   # New field Aug/19/08
131   # SQL to add column: alter table fctracker_library add column "replicate" smallint unsigned NULL;
132   REPLICATE_NUM = ((1,1),(2,2),(3,3),(4,4))
133   replicate =  models.PositiveSmallIntegerField(choices=REPLICATE_NUM,default=1) 
134   experiment_type = models.ForeignKey(ExperimentType)
135   creation_date = models.DateField(blank=True, null=True)
136   made_for = models.CharField(max_length=50, blank=True, 
137       verbose_name='ChIP/DNA/RNA Made By')
138   made_by = models.CharField(max_length=50, blank=True, default="Lorian")
139   
140   PROTOCOL_END_POINTS = (
141       ('?', 'Unknown'),
142       ('Sample', 'Raw sample'),
143       ('Progress', 'In progress'),
144       ('1A', 'Ligation, then gel'),
145       ('PCR', 'Ligation, then PCR'),
146       ('1Ab', 'Ligation, PCR, then gel'),
147       ('1Aa', 'Ligation, gel, then PCR'),
148       ('2A', 'Ligation, PCR, gel, PCR'),
149       ('Done', 'Completed'),
150     )
151   stopping_point = models.CharField(max_length=25, choices=PROTOCOL_END_POINTS, default='Done')
152   amplified_from_sample = models.ForeignKey('self', blank=True, null=True, related_name='amplified_into_sample')  
153   
154   undiluted_concentration = models.DecimalField("Concentration", 
155       max_digits=5, decimal_places=2, blank=True, null=True,
156       help_text=u"Undiluted concentration (ng/\u00b5l)") 
157       # note \u00b5 is the micro symbol in unicode
158   successful_pM = models.DecimalField(max_digits=9, decimal_places=1, 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"] 
169     ordering = ["-library_id"]
170   
171   def antibody_name(self):
172     str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>' 
173     return str
174   antibody_name.allow_tags = True
175
176   def organism(self):
177     return self.library_species.common_name
178
179   def affiliation(self):
180     affs = self.affiliations.all().order_by('name')
181     tstr = ''
182     ar = []
183     for t in affs:
184         ar.append(t.__unicode__())
185     return '%s' % (", ".join(ar))
186
187   def libtags(self):
188     affs = self.tags.all().order_by('tag_name')
189     ar = []
190     for t in affs:
191       ar.append(t.__unicode__())
192     return u'%s' % ( ", ".join(ar))
193
194   def DataRun(self):
195     str ='<a target=_self href="/admin/experiments/datarun/?q='+self.library_id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>' 
196     return str
197   DataRun.allow_tags = True
198
199   def aligned_m_reads(self):
200     return getLibReads(self.library_id)
201
202   def aligned_reads(self):
203     res = getLibReads(self.library_id)
204
205     # Check data sanity
206     if res[2] != "OK":
207       return u'<div style="border:solid red 2px">'+res[2]+'</div>'
208
209     rc = "%1.2f" % (res[1]/1000000.0)
210     # 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
211     if res[0] > 0:
212       bgcolor = '#ff3300'  # Red
213       rc_thr = [10000000,5000000,3000000]
214       if self.experiment_type == 'RNA-seq':
215         rc_thr = [20000000,10000000,6000000]
216
217       if res[1] > rc_thr[0]:
218         bgcolor = '#66ff66'  # Green
219       else:
220         if res[1] > rc_thr[1]:
221           bgcolor ='#00ccff'  # Blue
222         else:
223            if res[1] > rc_thr[2]: 
224              bgcolor ='#ffcc33'  # Orange
225       tstr = '<div style="background-color:'+bgcolor+';color:black">'
226       tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
227       tstr += '</div>'
228     else: tstr = 'not processed yet' 
229     return tstr
230   aligned_reads.allow_tags = True
231
232   def public(self):
233     SITE_ROOT = '/'
234     summary_url = self.get_absolute_url()
235     return '<a href="%s">S</a>' % (summary_url,)
236   public.allow_tags = True
237
238   @models.permalink
239   def get_absolute_url(self):
240     return ('htsworkflow.frontend.samples.views.library_to_flowcells', [str(self.id)])