Add a link to the public library summary page off from the libray admin list
[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 Tag(models.Model): 
63   tag_name = models.CharField(max_length=100, db_index=True,blank=False,null=False) 
64   TAG_CONTEXT = ( 
65       #('Antibody','Antibody'), 
66       #('Cellline', 'Cellline'), 
67       #('Condition', 'Condition'), 
68       ('Library', 'Library'), 
69       ('ANY','ANY'), 
70   ) 
71   context = models.CharField(max_length=50, 
72       choices=TAG_CONTEXT, default='Library') 
73  
74   def __unicode__(self): 
75     return u'%s' % (self.tag_name) 
76  
77   class Meta: 
78     ordering = ["context","tag_name"] 
79  
80 class Species(models.Model):
81   scientific_name = models.CharField(max_length=256, 
82       unique=False, 
83       db_index=True
84   )
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 __unicode__(self):
89     return u'%s (%s)' % (self.scientific_name, self.common_name)
90   
91   class Meta:
92     verbose_name_plural = "species"
93     ordering = ["scientific_name"]
94   
95 class Affiliation(models.Model):
96   name = models.CharField(max_length=256, db_index=True, verbose_name='Group Name')
97   contact = models.CharField(max_length=256, null=True, blank=True,verbose_name='Contact Name')  
98   email = models.EmailField(null=True,blank=True)
99   
100   def __unicode__(self):
101     str = unicode(self.name)
102     if self.contact is not None and len(self.contact) > 0:
103       str += u' ('+self.contact+u')' 
104     return str
105
106   class Meta:
107     ordering = ["name","contact"]
108     unique_together = (("name", "contact"),)
109
110 class Library(models.Model):
111   id = models.AutoField(primary_key=True)
112   library_id = models.CharField(max_length=30, db_index=True)
113   library_name = models.CharField(max_length=100, unique=True)
114   library_species = models.ForeignKey(Species)
115   cell_line = models.ForeignKey(Cellline)
116   condition = models.ForeignKey(Condition)
117   antibody = models.ForeignKey(Antibody,blank=True,null=True)
118   # New field Aug/25/08. SQL: alter table fctracker_library add column "lib_affiliation" varchar(256)  NULL;
119   affiliations = models.ManyToManyField(Affiliation,related_name='library_affiliations',null=True)
120   # new field Nov/14/08
121   tags = models.ManyToManyField(Tag,related_name='library_tags',blank=True,null=True)
122   # New field Aug/19/08
123   # SQL to add column: alter table fctracker_library add column "replicate" smallint unsigned NULL;
124   REPLICATE_NUM = ((1,1),(2,2),(3,3),(4,4))
125   replicate =  models.PositiveSmallIntegerField(choices=REPLICATE_NUM,default=1) 
126
127   EXPERIMENT_TYPES = (
128       ('INPUT_RXLCh','INPUT_RXLCh'),
129       ('ChIP-seq', 'ChIP-seq'),
130       ('Sheared', 'Sheared'),
131       ('RNA-seq', 'RNA-seq'),
132       ('Methyl-seq', 'Methyl-seq'),
133       ('DIP-seq', 'DIP-seq'),
134     ) 
135   experiment_type = models.CharField(max_length=50, choices=EXPERIMENT_TYPES,
136                                      default='RNA-seq')
137   
138   creation_date = models.DateField(blank=True, null=True)
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("Concentration", 
158       max_digits=5, decimal_places=2, default=0, blank=True, null=True,
159       help_text="Undiluted concentration (ng/ul)")
160   successful_pM = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
161   ten_nM_dilution = models.BooleanField()
162   avg_lib_size = models.IntegerField(default=225, blank=True, null=True)
163   notes = models.TextField(blank=True)
164   
165   def __unicode__(self):
166     return u'#%s: %s' % (self.library_id, self.library_name)
167   
168   class Meta:
169     verbose_name_plural = "libraries"
170     ordering = ["-creation_date"] #["-library_id"]
171   
172   def antibody_name(self):
173     str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>' 
174     return str
175   antibody_name.allow_tags = True
176
177   def organism(self):
178     return self.library_species.common_name
179
180   def affiliation(self):
181     affs = self.affiliations.all().order_by('name')
182     tstr = ''
183     ar = []
184     for t in affs:
185         ar.append(t.__unicode__())
186     return '%s' % (", ".join(ar))
187
188   def libtags(self):
189     affs = self.tags.all().order_by('tag_name')
190     ar = []
191     for t in affs:
192       ar.append(t.__unicode__())
193     return u'%s' % ( ", ".join(ar))
194
195   def DataRun(self):
196     str ='<a target=_self href="/admin/experiments/datarun/?q='+self.library_id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>' 
197     return str
198   DataRun.allow_tags = True
199
200   def aligned_m_reads(self):
201     return getLibReads(self.library_id)
202
203   def aligned_reads(self):
204     res = getLibReads(self.library_id)
205
206     # Check data sanity
207     if res[2] != "OK":
208       return u'<div style="border:solid red 2px">'+res[2]+'</div>'
209
210     rc = "%1.2f" % (res[1]/1000000.0)
211     # 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
212     if res[0] > 0:
213       bgcolor = '#ff3300'  # Red
214       rc_thr = [10000000,5000000,3000000]
215       if self.experiment_type == 'RNA-seq':
216         rc_thr = [20000000,10000000,6000000]
217
218       if res[1] > rc_thr[0]:
219         bgcolor = '#66ff66'  # Green
220       else:
221         if res[1] > rc_thr[1]:
222           bgcolor ='#00ccff'  # Blue
223         else:
224            if res[1] > rc_thr[2]: 
225              bgcolor ='#ffcc33'  # Orange
226       tstr = '<div style="background-color:'+bgcolor+';color:black">'
227       tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
228       tstr += '</div>'
229     else: tstr = 'not processed yet' 
230     return tstr
231   aligned_reads.allow_tags = True
232
233   def public(self):
234     SITE_ROOT = '/'
235     summary_url = urlparse.urljoin(SITE_ROOT, 'library/%s' % (self.library_id))
236     return '<a href="%s">S</a>' % (summary_url,)
237   public.allow_tags = True