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)
130 class Library(models.Model):
131 id = models.CharField(max_length=10, primary_key=True)
132 library_name = models.CharField(max_length=100, unique=True)
133 library_species = models.ForeignKey(Species)
134 # new field 2008 Mar 5, alter table samples_library add column "hidden" NOT NULL default 0;
135 hidden = models.BooleanField()
136 # new field 2009 Oct 6, alter table samples_library add column "account_number" varchar(100) NULL
137 account_number = models.CharField(max_length=100, null=True, blank=True)
138 cell_line = models.ForeignKey(Cellline, blank=True, null=True, verbose_name="Background")
139 condition = models.ForeignKey(Condition, blank=True, null=True)
140 antibody = models.ForeignKey(Antibody,blank=True,null=True)
141 # New field Aug/25/08. SQL: alter table fctracker_library add column "lib_affiliation" varchar(256) NULL;
142 affiliations = models.ManyToManyField(Affiliation,related_name='library_affiliations',null=True)
143 # new field Nov/14/08
144 tags = models.ManyToManyField(Tag,related_name='library_tags',blank=True,null=True)
145 # New field Aug/19/08
146 # SQL to add column: alter table fctracker_library add column "replicate" smallint unsigned NULL;
147 REPLICATE_NUM = ((1,1),(2,2),(3,3),(4,4))
148 replicate = models.PositiveSmallIntegerField(choices=REPLICATE_NUM,default=1)
149 experiment_type = models.ForeignKey(ExperimentType)
150 library_type = models.ForeignKey(LibraryType, blank=True, null=True)
151 creation_date = models.DateField(blank=True, null=True)
152 made_for = models.CharField(max_length=50, blank=True,
153 verbose_name='ChIP/DNA/RNA Made By')
154 made_by = models.CharField(max_length=50, blank=True, default="Lorian")
156 PROTOCOL_END_POINTS = (
158 ('Sample', 'Raw sample'),
159 ('Progress', 'In progress'),
160 ('1A', 'Ligation, then gel'),
161 ('PCR', 'Ligation, then PCR'),
162 ('1Ab', 'Ligation, PCR, then gel'),
163 ('1Aa', 'Ligation, gel, then PCR'),
164 ('2A', 'Ligation, PCR, gel, PCR'),
165 ('Done', 'Completed'),
167 stopping_point = models.CharField(max_length=25, choices=PROTOCOL_END_POINTS, default='Done')
168 amplified_from_sample = models.ForeignKey('self', blank=True, null=True, related_name='amplified_into_sample')
170 undiluted_concentration = models.DecimalField("Concentration",
171 max_digits=5, decimal_places=2, blank=True, null=True,
172 help_text=u"Undiluted concentration (ng/\u00b5l)")
173 # note \u00b5 is the micro symbol in unicode
174 successful_pM = models.DecimalField(max_digits=9, decimal_places=1, blank=True, null=True)
175 ten_nM_dilution = models.BooleanField()
176 avg_lib_size = models.IntegerField(default=225, blank=True, null=True)
177 notes = models.TextField(blank=True)
179 def __unicode__(self):
180 return u'#%s: %s' % (self.id, self.library_name)
183 verbose_name_plural = "libraries"
184 #ordering = ["-creation_date"]
187 def antibody_name(self):
188 str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>'
190 antibody_name.allow_tags = True
193 return self.library_species.common_name
195 def affiliation(self):
196 affs = self.affiliations.all().order_by('name')
200 ar.append(t.__unicode__())
201 return '%s' % (", ".join(ar))
203 def is_archived(self):
205 returns True if archived else False
207 if self.longtermstorage_set.count() > 0:
213 affs = self.tags.all().order_by('tag_name')
216 ar.append(t.__unicode__())
217 return u'%s' % ( ", ".join(ar))
220 str ='<a target=_self href="/admin/experiments/datarun/?q='+self.id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>'
222 DataRun.allow_tags = True
224 def aligned_m_reads(self):
225 return getLibReads(self.id)
227 def aligned_reads(self):
228 res = getLibReads(self.id)
232 return u'<div style="border:solid red 2px">'+res[2]+'</div>'
234 rc = "%1.2f" % (res[1]/1000000.0)
235 # 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
237 bgcolor = '#ff3300' # Red
238 rc_thr = [10000000,5000000,3000000]
239 if self.experiment_type == 'RNA-seq':
240 rc_thr = [20000000,10000000,6000000]
242 if res[1] > rc_thr[0]:
243 bgcolor = '#66ff66' # Green
245 if res[1] > rc_thr[1]:
246 bgcolor ='#00ccff' # Blue
248 if res[1] > rc_thr[2]:
249 bgcolor ='#ffcc33' # Orange
250 tstr = '<div style="background-color:'+bgcolor+';color:black">'
251 tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
253 else: tstr = 'not processed yet'
255 aligned_reads.allow_tags = True
259 summary_url = self.get_absolute_url()
260 return '<a href="%s">S</a>' % (summary_url,)
261 public.allow_tags = True
264 def get_absolute_url(self):
265 return ('htsworkflow.frontend.samples.views.library_to_flowcells', [str(self.id)])
269 Provide some site-specific customization for the django user class
271 #objects = UserManager()
274 ordering = ['username']
277 return '/admin/%s/%s/%d' % (self._meta.app_label, self._meta.module_name, self.id)
279 def __unicode__(self):
280 return unicode(self.username) + u" (" + unicode(self.get_full_name()) + u")"
282 def HTSUserInsertID(sender, instance, **kwargs):
284 Force addition of HTSUsers when someone just modifies the auth_user object
286 u = HTSUser.objects.filter(pk=instance.id)
288 cursor = connection.cursor()
289 cursor.execute('INSERT INTO samples_htsuser (user_ptr_id) VALUES (%s);' % (instance.id,))
292 post_save.connect(HTSUserInsertID, sender=User)