2 from django.db import models
3 from django.contrib.auth.models import User, UserManager
4 from django.db.models.signals import pre_save, post_save
5 from django.db import connection
6 from htsworkflow.frontend import settings
7 from htsworkflow.frontend.reports.libinfopar import *
9 # Create your models here.
11 class Antibody(models.Model):
12 antigene = models.CharField(max_length=500, db_index=True)
15 # alter table fctracker_antibody add column "nickname" varchar(20) NULL;
16 nickname = models.CharField(
21 verbose_name = 'Short Name'
23 catalog = models.CharField(max_length=50, unique=True, db_index=True)
24 antibodies = models.CharField(max_length=500, db_index=True)
25 source = models.CharField(max_length=500, blank=True, db_index=True)
26 biology = models.TextField(blank=True)
27 notes = models.TextField(blank=True)
28 def __unicode__(self):
29 return u'%s - %s (%s)' % (self.antigene, self.antibodies, self.catalog)
31 verbose_name_plural = "antibodies"
32 ordering = ["antigene"]
34 class Cellline(models.Model):
35 cellline_name = models.CharField(max_length=100, unique=True, db_index=True)
36 nickname = models.CharField(max_length=20,
40 verbose_name = 'Short Name')
41 notes = models.TextField(blank=True)
42 def __unicode__(self):
43 return unicode(self.cellline_name)
46 ordering = ["cellline_name"]
48 class Condition(models.Model):
49 condition_name = models.CharField(
50 max_length=2000, unique=True, db_index=True)
51 nickname = models.CharField(max_length=20,
55 verbose_name = 'Short Name')
56 notes = models.TextField(blank=True)
58 def __unicode__(self):
59 return unicode(self.condition_name)
62 ordering = ["condition_name"]
64 class ExperimentType(models.Model):
65 name = models.CharField(max_length=50, unique=True)
67 def __unicode__(self):
68 return unicode(self.name)
70 class Tag(models.Model):
71 tag_name = models.CharField(max_length=100, db_index=True,blank=False,null=False)
73 #('Antibody','Antibody'),
74 #('Cellline', 'Cellline'),
75 #('Condition', 'Condition'),
76 ('Library', 'Library'),
79 context = models.CharField(max_length=50,
80 choices=TAG_CONTEXT, default='Library')
82 def __unicode__(self):
83 return u'%s' % (self.tag_name)
86 ordering = ["context","tag_name"]
88 class Species(models.Model):
89 scientific_name = models.CharField(max_length=256,
93 common_name = models.CharField(max_length=256, blank=True)
94 #use_genome_build = models.CharField(max_length=100, blank=False, null=False)
96 def __unicode__(self):
97 return u'%s (%s)' % (self.scientific_name, self.common_name)
100 verbose_name_plural = "species"
101 ordering = ["scientific_name"]
103 class Affiliation(models.Model):
104 name = models.CharField(max_length=256, db_index=True, verbose_name='Name')
105 contact = models.CharField(max_length=256, null=True, blank=True,verbose_name='Lab Name')
106 email = models.EmailField(null=True,blank=True)
107 users = models.ManyToManyField('HTSUser', null=True, blank=True)
108 users.admin_order_field = "username"
110 def __unicode__(self):
111 str = unicode(self.name)
112 if self.contact is not None and len(self.contact) > 0:
113 str += u' ('+self.contact+u')'
117 users = self.users.all().order_by('username')
118 return ", ".join([unicode(a) for a in users ])
121 ordering = ["name","contact"]
122 unique_together = (("name", "contact"),)
124 class LibraryType(models.Model):
125 name = models.CharField(max_length=255, unique=True)
127 def __unicode__(self):
128 return unicode(self.name)
131 class Library(models.Model):
132 id = models.CharField(max_length=10, primary_key=True)
133 library_name = models.CharField(max_length=100, unique=True)
134 library_species = models.ForeignKey(Species)
135 # new field 2008 Mar 5, alter table samples_library add column "hidden" NOT NULL default 0;
136 hidden = models.BooleanField()
137 # new field 2009 Oct 6, alter table samples_library add column "account_number" varchar(100) NULL
138 account_number = models.CharField(max_length=100, null=True, blank=True)
139 cell_line = models.ForeignKey(Cellline, blank=True, null=True, verbose_name="Background")
140 condition = models.ForeignKey(Condition, blank=True, null=True)
141 antibody = models.ForeignKey(Antibody,blank=True,null=True)
142 # New field Aug/25/08. SQL: alter table fctracker_library add column "lib_affiliation" varchar(256) NULL;
143 affiliations = models.ManyToManyField(Affiliation,related_name='library_affiliations',null=True)
144 # new field Nov/14/08
145 tags = models.ManyToManyField(Tag,related_name='library_tags',blank=True,null=True)
146 # New field Aug/19/08
147 # SQL to add column: alter table fctracker_library add column "replicate" smallint unsigned NULL;
148 REPLICATE_NUM = ((1,1),(2,2),(3,3),(4,4))
149 replicate = models.PositiveSmallIntegerField(choices=REPLICATE_NUM,default=1)
150 experiment_type = models.ForeignKey(ExperimentType)
151 library_type = models.ForeignKey(LibraryType, blank=True, null=True)
152 creation_date = models.DateField(blank=True, null=True)
153 made_for = models.CharField(max_length=50, blank=True,
154 verbose_name='ChIP/DNA/RNA Made By')
155 made_by = models.CharField(max_length=50, blank=True, default="Lorian")
157 PROTOCOL_END_POINTS = (
159 ('Sample', 'Raw sample'),
160 ('Progress', 'In progress'),
161 ('1A', 'Ligation, then gel'),
162 ('PCR', 'Ligation, then PCR'),
163 ('1Ab', 'Ligation, PCR, then gel'),
164 ('1Aa', 'Ligation, gel, then PCR'),
165 ('2A', 'Ligation, PCR, gel, PCR'),
166 ('Done', 'Completed'),
168 stopping_point = models.CharField(max_length=25, choices=PROTOCOL_END_POINTS, default='Done')
169 amplified_from_sample = models.ForeignKey('self', blank=True, null=True, related_name='amplified_into_sample')
171 undiluted_concentration = models.DecimalField("Concentration",
172 max_digits=5, decimal_places=2, blank=True, null=True,
173 help_text=u"Undiluted concentration (ng/\u00b5l)")
174 # note \u00b5 is the micro symbol in unicode
175 successful_pM = models.DecimalField(max_digits=9, decimal_places=1, blank=True, null=True)
176 ten_nM_dilution = models.BooleanField()
177 gel_cut_size = models.IntegerField(default=225, blank=True, null=True)
178 insert_size = models.IntegerField(blank=True, null=True)
179 notes = models.TextField(blank=True)
181 def __unicode__(self):
182 return u'#%s: %s' % (self.id, self.library_name)
185 verbose_name_plural = "libraries"
186 #ordering = ["-creation_date"]
189 def antibody_name(self):
190 str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>'
192 antibody_name.allow_tags = True
195 return self.library_species.common_name
197 def affiliation(self):
198 affs = self.affiliations.all().order_by('name')
202 ar.append(t.__unicode__())
203 return '%s' % (", ".join(ar))
205 def is_archived(self):
207 returns True if archived else False
209 if self.longtermstorage_set.count() > 0:
215 affs = self.tags.all().order_by('tag_name')
218 ar.append(t.__unicode__())
219 return u'%s' % ( ", ".join(ar))
222 str ='<a target=_self href="/admin/experiments/datarun/?q='+self.id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>'
224 DataRun.allow_tags = True
226 def aligned_m_reads(self):
227 return getLibReads(self.id)
229 def aligned_reads(self):
230 res = getLibReads(self.id)
234 return u'<div style="border:solid red 2px">'+res[2]+'</div>'
236 rc = "%1.2f" % (res[1]/1000000.0)
237 # 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
239 bgcolor = '#ff3300' # Red
240 rc_thr = [10000000,5000000,3000000]
241 if self.experiment_type == 'RNA-seq':
242 rc_thr = [20000000,10000000,6000000]
244 if res[1] > rc_thr[0]:
245 bgcolor = '#66ff66' # Green
247 if res[1] > rc_thr[1]:
248 bgcolor ='#00ccff' # Blue
250 if res[1] > rc_thr[2]:
251 bgcolor ='#ffcc33' # Orange
252 tstr = '<div style="background-color:'+bgcolor+';color:black">'
253 tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
255 else: tstr = 'not processed yet'
257 aligned_reads.allow_tags = True
261 summary_url = self.get_absolute_url()
262 return '<a href="%s">S</a>' % (summary_url,)
263 public.allow_tags = True
266 def get_absolute_url(self):
267 return ('htsworkflow.frontend.samples.views.library_to_flowcells', [str(self.id)])
275 Provide some site-specific customization for the django user class
277 #objects = UserManager()
280 ordering = ['first_name', 'last_name', 'username']
283 return '/admin/%s/%s/%d' % (self._meta.app_label, self._meta.module_name, self.id)
285 def __unicode__(self):
286 #return unicode(self.username) + u" (" + unicode(self.get_full_name()) + u")"
287 return unicode(self.get_full_name()) + u' (' + unicode(self.username) + ')'
289 def HTSUserInsertID(sender, instance, **kwargs):
291 Force addition of HTSUsers when someone just modifies the auth_user object
293 u = HTSUser.objects.filter(pk=instance.id)
295 cursor = connection.cursor()
296 cursor.execute('INSERT INTO samples_htsuser (user_ptr_id) VALUES (%s);' % (instance.id,))
299 post_save.connect(HTSUserInsertID, sender=User)