Change default picomolarity to 5, and allow overriding the default
[htsworkflow.git] / htsworkflow / frontend / experiments / models.py
1 from django.db import models
2 from htsworkflow.frontend.samples.models import *
3 from htsworkflow.frontend.settings import options
4 from django.core.exceptions import ObjectDoesNotExist
5 import logging
6
7 class ClusterStation(models.Model):
8   name = models.CharField(max_length=50, unique=True)
9
10   def __unicode__(self):
11     return unicode(self.name)
12
13 class Sequencer(models.Model):
14   name = models.CharField(max_length=50, unique=True)
15
16   def __unicode__(self):
17     return unicode(self.name)
18
19 default_pM = 5
20 try:
21   default_pM = int(options.get('frontend', 'default_pm'))
22 except ValueError,e:
23   logging.error("invalid value for frontend.default_pm")
24
25 class FlowCell(models.Model):
26   
27   flowcell_id = models.CharField(max_length=20, unique=True, db_index=True)
28   run_date = models.DateTimeField()
29   advanced_run = models.BooleanField(default=False)
30   paired_end = models.BooleanField(default=False)
31   read_length = models.IntegerField(default=32) #Stanford is currenlty 25
32   
33   lane_1_library = models.ForeignKey(Library, related_name="lane_1_library")
34   lane_2_library = models.ForeignKey(Library, related_name="lane_2_library")
35   lane_3_library = models.ForeignKey(Library, related_name="lane_3_library")
36   lane_4_library = models.ForeignKey(Library, related_name="lane_4_library")
37   lane_5_library = models.ForeignKey(Library, related_name="lane_5_library")
38   lane_6_library = models.ForeignKey(Library, related_name="lane_6_library")
39   lane_7_library = models.ForeignKey(Library, related_name="lane_7_library")
40   lane_8_library = models.ForeignKey(Library, related_name="lane_8_library")
41
42   lane_1_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
43   lane_2_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
44   lane_3_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
45   lane_4_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
46   lane_5_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
47   lane_6_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
48   lane_7_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
49   lane_8_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
50   
51   lane_1_cluster_estimate = models.IntegerField(blank=True, null=True)
52   lane_2_cluster_estimate = models.IntegerField(blank=True, null=True)
53   lane_3_cluster_estimate = models.IntegerField(blank=True, null=True)
54   lane_4_cluster_estimate = models.IntegerField(blank=True, null=True)
55   lane_5_cluster_estimate = models.IntegerField(blank=True, null=True)
56   lane_6_cluster_estimate = models.IntegerField(blank=True, null=True)
57   lane_7_cluster_estimate = models.IntegerField(blank=True, null=True)
58   lane_8_cluster_estimate = models.IntegerField(blank=True, null=True)
59  
60   # lane_1_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_1_primer")
61   # lane_2_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_2_primer")
62   # lane_3_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_3_primer")
63   # lane_4_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_4_primer")
64   # lane_5_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_5_primer")
65   # lane_6_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_6_primer")
66   # lane_7_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_7_primer")
67   # lane_8_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_8_primer")
68
69   #cluster_mac_id = models.CharField(max_length=50, choices=CLUSTER_MAC, default='BitBit')
70   #seq_mac_id = models.CharField(max_length=50, choices=SEQ_MAC, verbose_name = 'Sequencer', default='Britney')
71   cluster_station = models.ForeignKey(ClusterStation)
72   sequencer = models.ForeignKey(Sequencer)
73   
74   notes = models.TextField(blank=True)
75
76   def __unicode__(self):
77       return unicode(self.flowcell_id) 
78
79   def Create_LOG(self):
80     str = ''
81     str +='<a target=_balnk href="/experiments/'+self.flowcell_id+'" title="Create XLS like sheet for this Flowcell ..." ">Create LOG</a>'
82     try:
83       t = DataRun.objects.get(fcid=self.id)
84       str +='<br/><a target=_self href="/admin/experiments/datarun/?q='+self.flowcell_id+'" title="Check Data Runs ..." ">DataRun ..</a>'
85     except ObjectDoesNotExist:
86       str += '<br/><span style="color:red">not sequenced</span>'
87     return str
88   Create_LOG.allow_tags = True 
89
90   def Lanes(self):
91     library_url = '/admin/samples/library/%s' 
92     html = ['<ol>']
93     for i in range(1,9):
94         library_id = getattr(self, 'lane_%d_library_id' % i)
95         library = getattr(self, 'lane_%d_library' % i)
96         element = '<li><a href="%s">%s</a></li>'
97         html.append(element % (library_url % library_id, library))
98     html.append('</ol>')
99     return "\n".join(html)
100   Lanes.allow_tags = True
101
102   class Meta:
103     ordering = ["-run_date"]
104   
105 ### -----------------------
106 class DataRun(models.Model):
107   ConfTemplate = "CONFIG PARAMS WILL BE GENERATED BY THE PIPELINE SCRIPT.\nYOU'LL BE ABLE TO EDIT AFTER IF NEEDED."
108   run_folder = models.CharField(max_length=50,unique=True, db_index=True)
109   fcid = models.ForeignKey(FlowCell,verbose_name="Flowcell Id")
110   config_params = models.TextField(default=ConfTemplate)
111   run_start_time = models.DateTimeField()
112   RUN_STATUS_CHOICES = (
113       (0, 'Sequencer running'), ##Solexa Data Pipeline Not Yet Started'),
114       (1, 'Data Pipeline Started'),
115       (2, 'Data Pipeline Interrupted'),
116       (3, 'Data Pipeline Finished'),
117       (4, 'CollectReads Started'),
118       (5, 'CollectReads Finished'),
119       (6, 'QC Finished'),
120       (7, 'DONE'),
121     )
122   run_status = models.IntegerField(choices=RUN_STATUS_CHOICES, default=0)
123   run_note = models.TextField(blank=True)
124
125
126   def main_status(self):
127     str = '<div'
128     if self.run_status >= 5:
129       str += ' style="color:green">'
130       str += '<b>'+self.RUN_STATUS_CHOICES[self.run_status][1]+'</b>'
131       str += '<br/><br/>' #<span style="color:red;font-size:80%;">New!</span>'
132       str +='<br/><a target=_balnk href="'+settings.TASKS_PROJS_SERVER+'/Flowcells/'+self.fcid.flowcell_id+'/'+self.fcid.flowcell_id+'_QC_Summary.html" title="View QC Summaries of this run ..." ">View QC Page</a>'
133     else:
134       str += '>'+self.RUN_STATUS_CHOICES[self.run_status][1]
135
136     str += '</div>'
137     return str
138   main_status.allow_tags = True
139
140   main_status.allow_tags = True
141   
142   def Flowcell_Info(self):
143     str = '<b>'+self.fcid.__str__()+'</b>'
144     str += '  (c: '+self.fcid.cluster_mac_id+',  s: '+self.fcid.seq_mac_id+')'
145     str += '<div style="margin-top:5px;">'    
146     str +='<a title="View Lane List here ..."  onClick="el = document.getElementById(\'LanesOf'+self.fcid.__str__()+'\');if(el) (el.style.display==\'none\'?el.style.display=\'block\':el.style.display=\'none\')" style="cursor:pointer;color: #5b80b2;">View/hide lanes</a>'
147     str += '<div id="LanesOf'+self.fcid.__str__()+'" style="display:block;border:solid #cccccc 1px;width:350px">'
148     LanesList = '1: '+self.fcid.lane_1_library.__str__()+' ('+self.fcid.lane_1_library.library_species.use_genome_build+')<br/>2: '+self.fcid.lane_2_library.__str__()+' ('+self.fcid.lane_2_library.library_species.use_genome_build+')<br/>3: '+self.fcid.lane_3_library.__str__()+' ('+self.fcid.lane_3_library.library_species.use_genome_build+')<br/>4: '+self.fcid.lane_4_library.__str__()+' ('+self.fcid.lane_4_library.library_species.use_genome_build+')<br/>5: '+self.fcid.lane_5_library.__str__()+' ('+self.fcid.lane_5_library.library_species.use_genome_build+')<br/>6: '+self.fcid.lane_6_library.__str__()+' ('+self.fcid.lane_6_library.library_species.use_genome_build+')<br/>7: '+self.fcid.lane_7_library.__str__()+' ('+self.fcid.lane_7_library.library_species.use_genome_build+')<br/>8: '+self.fcid.lane_8_library.__str__()+' ('+self.fcid.lane_8_library.library_species.use_genome_build+')'
149     str += LanesList ## self.fcid.Lanes()
150     str += '</div>'
151     str += '<div><a title="open Flowcell record" href="/admin/exp_track/flowcell/'+self.fcid.id.__str__()+'/" target=_self>Edit Flowcell record</a>'
152     #str += '<span style="color:red;font-size:80%;margin-left:15px;margin-right:3px">New!</span>'
153     str +='<a style="margin-left:15px;" target=_balnk href="/exp_track/'+self.fcid.flowcell_id+'" title="View XLS like sheet for this Flowcell LOG ..." ">GA LOG Page</a>'
154     str += '</div>'
155     str += '</div>'    
156     return str
157   Flowcell_Info.allow_tags = True