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 avg_lib_size = models.IntegerField(default=225, blank=True, null=True)
178 notes = models.TextField(blank=True)
180 def __unicode__(self):
181 return u'#%s: %s' % (self.id, self.library_name)
184 verbose_name_plural = "libraries"
185 #ordering = ["-creation_date"]
188 def antibody_name(self):
189 str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>'
191 antibody_name.allow_tags = True
194 return self.library_species.common_name
196 def affiliation(self):
197 affs = self.affiliations.all().order_by('name')
201 ar.append(t.__unicode__())
202 return '%s' % (", ".join(ar))
204 def is_archived(self):
206 returns True if archived else False
208 if self.longtermstorage_set.count() > 0:
214 affs = self.tags.all().order_by('tag_name')
217 ar.append(t.__unicode__())
218 return u'%s' % ( ", ".join(ar))
221 str ='<a target=_self href="/admin/experiments/datarun/?q='+self.id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>'
223 DataRun.allow_tags = True
225 def aligned_m_reads(self):
226 return getLibReads(self.id)
228 def aligned_reads(self):
229 res = getLibReads(self.id)
233 return u'<div style="border:solid red 2px">'+res[2]+'</div>'
235 rc = "%1.2f" % (res[1]/1000000.0)
236 # 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
238 bgcolor = '#ff3300' # Red
239 rc_thr = [10000000,5000000,3000000]
240 if self.experiment_type == 'RNA-seq':
241 rc_thr = [20000000,10000000,6000000]
243 if res[1] > rc_thr[0]:
244 bgcolor = '#66ff66' # Green
246 if res[1] > rc_thr[1]:
247 bgcolor ='#00ccff' # Blue
249 if res[1] > rc_thr[2]:
250 bgcolor ='#ffcc33' # Orange
251 tstr = '<div style="background-color:'+bgcolor+';color:black">'
252 tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
254 else: tstr = 'not processed yet'
256 aligned_reads.allow_tags = True
260 summary_url = self.get_absolute_url()
261 return '<a href="%s">S</a>' % (summary_url,)
262 public.allow_tags = True
265 def get_absolute_url(self):
266 return ('htsworkflow.frontend.samples.views.library_to_flowcells', [str(self.id)])
274 Provide some site-specific customization for the django user class
276 #objects = UserManager()
279 ordering = ['first_name', 'last_name', 'username']
282 return '/admin/%s/%s/%d' % (self._meta.app_label, self._meta.module_name, self.id)
284 def __unicode__(self):
285 #return unicode(self.username) + u" (" + unicode(self.get_full_name()) + u")"
286 return unicode(self.get_full_name()) + u' (' + unicode(self.username) + ')'
288 def HTSUserInsertID(sender, instance, **kwargs):
290 Force addition of HTSUsers when someone just modifies the auth_user object
292 u = HTSUser.objects.filter(pk=instance.id)
294 cursor = connection.cursor()
295 cursor.execute('INSERT INTO samples_htsuser (user_ptr_id) VALUES (%s);' % (instance.id,))
298 post_save.connect(HTSUserInsertID, sender=User)