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 ('1Ac', 'Ligation, gel, then 12x PCR'),
165 ('1Aa', 'Ligation, gel, then 18x PCR'),
166 ('2A', 'Ligation, PCR, gel, PCR'),
167 ('Done', 'Completed'),
169 stopping_point = models.CharField(max_length=25, choices=PROTOCOL_END_POINTS, default='Done')
170 amplified_from_sample = models.ForeignKey('self', blank=True, null=True, related_name='amplified_into_sample')
172 undiluted_concentration = models.DecimalField("Concentration",
173 max_digits=5, decimal_places=2, blank=True, null=True,
174 help_text=u"Undiluted concentration (ng/\u00b5l)")
175 # note \u00b5 is the micro symbol in unicode
176 successful_pM = models.DecimalField(max_digits=9, decimal_places=1, blank=True, null=True)
177 ten_nM_dilution = models.BooleanField()
178 gel_cut_size = models.IntegerField(default=225, blank=True, null=True)
179 insert_size = models.IntegerField(blank=True, null=True)
180 notes = models.TextField(blank=True)
182 bioanalyzer_summary = models.TextField(blank=True,default="")
183 bioanalyzer_concentration = models.DecimalField(max_digits=5,
184 decimal_places=2, blank=True, null=True,
185 help_text=u"(ng/\u00b5l)")
186 bioanalyzer_image_url = models.URLField(blank=True,default="")
188 def __unicode__(self):
189 return u'#%s: %s' % (self.id, self.library_name)
192 verbose_name_plural = "libraries"
193 #ordering = ["-creation_date"]
196 def antibody_name(self):
197 str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>'
199 antibody_name.allow_tags = True
202 return self.library_species.common_name
204 def affiliation(self):
205 affs = self.affiliations.all().order_by('name')
209 ar.append(t.__unicode__())
210 return '%s' % (", ".join(ar))
212 def is_archived(self):
214 returns True if archived else False
216 if self.longtermstorage_set.count() > 0:
222 affs = self.tags.all().order_by('tag_name')
225 ar.append(t.__unicode__())
226 return u'%s' % ( ", ".join(ar))
229 str ='<a target=_self href="/admin/experiments/datarun/?q='+self.id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>'
231 DataRun.allow_tags = True
233 def aligned_m_reads(self):
234 return getLibReads(self.id)
236 def aligned_reads(self):
237 res = getLibReads(self.id)
241 return u'<div style="border:solid red 2px">'+res[2]+'</div>'
243 rc = "%1.2f" % (res[1]/1000000.0)
244 # 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
246 bgcolor = '#ff3300' # Red
247 rc_thr = [10000000,5000000,3000000]
248 if self.experiment_type == 'RNA-seq':
249 rc_thr = [20000000,10000000,6000000]
251 if res[1] > rc_thr[0]:
252 bgcolor = '#66ff66' # Green
254 if res[1] > rc_thr[1]:
255 bgcolor ='#00ccff' # Blue
257 if res[1] > rc_thr[2]:
258 bgcolor ='#ffcc33' # Orange
259 tstr = '<div style="background-color:'+bgcolor+';color:black">'
260 tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
262 else: tstr = 'not processed yet'
264 aligned_reads.allow_tags = True
268 summary_url = self.get_absolute_url()
269 return '<a href="%s">S</a>' % (summary_url,)
270 public.allow_tags = True
273 def get_absolute_url(self):
274 return ('htsworkflow.frontend.samples.views.library_to_flowcells', [str(self.id)])
282 Provide some site-specific customization for the django user class
284 #objects = UserManager()
287 ordering = ['first_name', 'last_name', 'username']
290 return '/admin/%s/%s/%d' % (self._meta.app_label, self._meta.module_name, self.id)
292 def __unicode__(self):
293 #return unicode(self.username) + u" (" + unicode(self.get_full_name()) + u")"
294 return unicode(self.get_full_name()) + u' (' + unicode(self.username) + ')'
296 def HTSUserInsertID(sender, instance, **kwargs):
298 Force addition of HTSUsers when someone just modifies the auth_user object
300 u = HTSUser.objects.filter(pk=instance.id)
302 cursor = connection.cursor()
303 cursor.execute('INSERT INTO samples_htsuser (user_ptr_id) VALUES (%s);' % (instance.id,))
306 post_save.connect(HTSUserInsertID, sender=User)