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)
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.AutoField(primary_key=True)
132 library_id = models.CharField(max_length=30, db_index=True, unique=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 cell_line = models.ForeignKey(Cellline, blank=True, null=True, verbose_name="Background")
138 condition = models.ForeignKey(Condition, blank=True, null=True)
139 antibody = models.ForeignKey(Antibody,blank=True,null=True)
140 # New field Aug/25/08. SQL: alter table fctracker_library add column "lib_affiliation" varchar(256) NULL;
141 affiliations = models.ManyToManyField(Affiliation,related_name='library_affiliations',null=True)
142 # new field Nov/14/08
143 tags = models.ManyToManyField(Tag,related_name='library_tags',blank=True,null=True)
144 # New field Aug/19/08
145 # SQL to add column: alter table fctracker_library add column "replicate" smallint unsigned NULL;
146 REPLICATE_NUM = ((1,1),(2,2),(3,3),(4,4))
147 replicate = models.PositiveSmallIntegerField(choices=REPLICATE_NUM,default=1)
148 experiment_type = models.ForeignKey(ExperimentType)
149 library_type = models.ForeignKey(LibraryType, blank=True, null=True)
150 creation_date = models.DateField(blank=True, null=True)
151 made_for = models.CharField(max_length=50, blank=True,
152 verbose_name='ChIP/DNA/RNA Made By')
153 made_by = models.CharField(max_length=50, blank=True, default="Lorian")
155 PROTOCOL_END_POINTS = (
157 ('Sample', 'Raw sample'),
158 ('Progress', 'In progress'),
159 ('1A', 'Ligation, then gel'),
160 ('PCR', 'Ligation, then PCR'),
161 ('1Ab', 'Ligation, PCR, then gel'),
162 ('1Aa', 'Ligation, gel, then PCR'),
163 ('2A', 'Ligation, PCR, gel, PCR'),
164 ('Done', 'Completed'),
166 stopping_point = models.CharField(max_length=25, choices=PROTOCOL_END_POINTS, default='Done')
167 amplified_from_sample = models.ForeignKey('self', blank=True, null=True, related_name='amplified_into_sample')
169 undiluted_concentration = models.DecimalField("Concentration",
170 max_digits=5, decimal_places=2, blank=True, null=True,
171 help_text=u"Undiluted concentration (ng/\u00b5l)")
172 # note \u00b5 is the micro symbol in unicode
173 successful_pM = models.DecimalField(max_digits=9, decimal_places=1, blank=True, null=True)
174 ten_nM_dilution = models.BooleanField()
175 avg_lib_size = models.IntegerField(default=225, blank=True, null=True)
176 notes = models.TextField(blank=True)
178 def __unicode__(self):
179 return u'#%s: %s' % (self.library_id, self.library_name)
182 verbose_name_plural = "libraries"
183 #ordering = ["-creation_date"]
184 ordering = ["-library_id"]
186 def antibody_name(self):
187 str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>'
189 antibody_name.allow_tags = True
192 return self.library_species.common_name
194 def affiliation(self):
195 affs = self.affiliations.all().order_by('name')
199 ar.append(t.__unicode__())
200 return '%s' % (", ".join(ar))
202 def is_archived(self):
204 returns True if archived else False
206 if self.longtermstorage_set.count() > 0:
212 affs = self.tags.all().order_by('tag_name')
215 ar.append(t.__unicode__())
216 return u'%s' % ( ", ".join(ar))
219 str ='<a target=_self href="/admin/experiments/datarun/?q='+self.library_id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>'
221 DataRun.allow_tags = True
223 def aligned_m_reads(self):
224 return getLibReads(self.library_id)
226 def aligned_reads(self):
227 res = getLibReads(self.library_id)
231 return u'<div style="border:solid red 2px">'+res[2]+'</div>'
233 rc = "%1.2f" % (res[1]/1000000.0)
234 # 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
236 bgcolor = '#ff3300' # Red
237 rc_thr = [10000000,5000000,3000000]
238 if self.experiment_type == 'RNA-seq':
239 rc_thr = [20000000,10000000,6000000]
241 if res[1] > rc_thr[0]:
242 bgcolor = '#66ff66' # Green
244 if res[1] > rc_thr[1]:
245 bgcolor ='#00ccff' # Blue
247 if res[1] > rc_thr[2]:
248 bgcolor ='#ffcc33' # Orange
249 tstr = '<div style="background-color:'+bgcolor+';color:black">'
250 tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
252 else: tstr = 'not processed yet'
254 aligned_reads.allow_tags = True
258 summary_url = self.get_absolute_url()
259 return '<a href="%s">S</a>' % (summary_url,)
260 public.allow_tags = True
263 def get_absolute_url(self):
264 return ('htsworkflow.frontend.samples.views.library_to_flowcells', [str(self.library_id)])
268 Provide some site-specific customization for the django user class
270 #objects = UserManager()
273 ordering = ['username']
276 return '/admin/%s/%s/%d' % (self._meta.app_label, self._meta.module_name, self.id)
278 def HTSUserInsertID(sender, instance, **kwargs):
280 Force addition of HTSUsers when someone just modifies the auth_user object
282 u = HTSUser.objects.filter(pk=instance.id)
284 cursor = connection.cursor()
285 cursor.execute('INSERT INTO samples_htsuser (user_ptr_id) VALUES (%s);' % (instance.id,))
288 post_save.connect(HTSUserInsertID, sender=User)