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 bioanalyzer_summary = models.TextField(blank=True,default="")
182 bioanalyzer_concentration = models.DecimalField(max_digits=5,
183 decimal_places=2, blank=True, null=True,
184 help_text=u"(ng/\u00b5l)")
185 bioanalyzer_image_url = models.URLField(blank=True,default="")
187 def __unicode__(self):
188 return u'#%s: %s' % (self.id, self.library_name)
191 verbose_name_plural = "libraries"
192 #ordering = ["-creation_date"]
195 def antibody_name(self):
196 str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>'
198 antibody_name.allow_tags = True
201 return self.library_species.common_name
203 def affiliation(self):
204 affs = self.affiliations.all().order_by('name')
208 ar.append(t.__unicode__())
209 return '%s' % (", ".join(ar))
211 def is_archived(self):
213 returns True if archived else False
215 if self.longtermstorage_set.count() > 0:
221 affs = self.tags.all().order_by('tag_name')
224 ar.append(t.__unicode__())
225 return u'%s' % ( ", ".join(ar))
228 str ='<a target=_self href="/admin/experiments/datarun/?q='+self.id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>'
230 DataRun.allow_tags = True
232 def aligned_m_reads(self):
233 return getLibReads(self.id)
235 def aligned_reads(self):
236 res = getLibReads(self.id)
240 return u'<div style="border:solid red 2px">'+res[2]+'</div>'
242 rc = "%1.2f" % (res[1]/1000000.0)
243 # 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
245 bgcolor = '#ff3300' # Red
246 rc_thr = [10000000,5000000,3000000]
247 if self.experiment_type == 'RNA-seq':
248 rc_thr = [20000000,10000000,6000000]
250 if res[1] > rc_thr[0]:
251 bgcolor = '#66ff66' # Green
253 if res[1] > rc_thr[1]:
254 bgcolor ='#00ccff' # Blue
256 if res[1] > rc_thr[2]:
257 bgcolor ='#ffcc33' # Orange
258 tstr = '<div style="background-color:'+bgcolor+';color:black">'
259 tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
261 else: tstr = 'not processed yet'
263 aligned_reads.allow_tags = True
267 summary_url = self.get_absolute_url()
268 return '<a href="%s">S</a>' % (summary_url,)
269 public.allow_tags = True
272 def get_absolute_url(self):
273 return ('htsworkflow.frontend.samples.views.library_to_flowcells', [str(self.id)])
281 Provide some site-specific customization for the django user class
283 #objects = UserManager()
286 ordering = ['first_name', 'last_name', 'username']
289 return '/admin/%s/%s/%d' % (self._meta.app_label, self._meta.module_name, self.id)
291 def __unicode__(self):
292 #return unicode(self.username) + u" (" + unicode(self.get_full_name()) + u")"
293 return unicode(self.get_full_name()) + u' (' + unicode(self.username) + ')'
295 def HTSUserInsertID(sender, instance, **kwargs):
297 Force addition of HTSUsers when someone just modifies the auth_user object
299 u = HTSUser.objects.filter(pk=instance.id)
301 cursor = connection.cursor()
302 cursor.execute('INSERT INTO samples_htsuser (user_ptr_id) VALUES (%s);' % (instance.id,))
305 post_save.connect(HTSUserInsertID, sender=User)