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