Added control_lane column to Flowcell.
[htsworkflow.git] / htsworkflow / frontend / experiments / models.py
1 import logging
2
3 from django.core.exceptions import ObjectDoesNotExist
4 from django.core import urlresolvers
5 from django.db import models
6
7 from htsworkflow.frontend.samples.models import *
8 from htsworkflow.frontend.settings import options
9
10 class ClusterStation(models.Model):
11   name = models.CharField(max_length=50, unique=True)
12
13   def __unicode__(self):
14     return unicode(self.name)
15
16 class Sequencer(models.Model):
17   name = models.CharField(max_length=50, unique=True)
18
19   def __unicode__(self):
20     return unicode(self.name)
21
22 default_pM = 5
23 try:
24   default_pM = int(options.get('frontend', 'default_pm'))
25 except ValueError,e:
26   logging.error("invalid value for frontend.default_pm")
27
28 class FlowCell(models.Model):
29   
30   flowcell_id = models.CharField(max_length=20, unique=True, db_index=True)
31   run_date = models.DateTimeField()
32   advanced_run = models.BooleanField(default=False)
33   paired_end = models.BooleanField(default=False)
34   read_length = models.IntegerField(default=32) #Stanford is currenlty 25
35   control_lane = models.IntegerField(choices=[(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8)], null=True)
36
37   cluster_station = models.ForeignKey(ClusterStation, default=3)
38   sequencer = models.ForeignKey(Sequencer, default=1)
39   
40   notes = models.TextField(blank=True)
41
42   def __unicode__(self):
43       return unicode(self.flowcell_id) 
44
45   def Create_LOG(self):
46     str = ''
47     str +='<a target=_balnk href="/experiments/'+self.flowcell_id+'" title="Create XLS like sheet for this Flowcell ..." ">Create LOG</a>'
48     try:
49       t = DataRun.objects.get(fcid=self.id)
50       str +='<br/><a target=_self href="/admin/experiments/datarun/?q='+self.flowcell_id+'" title="Check Data Runs ..." ">DataRun ..</a>'
51     except ObjectDoesNotExist:
52       str += '<br/><span style="color:red">not sequenced</span>'
53     return str
54   Create_LOG.allow_tags = True 
55
56   def Lanes(self):
57     library_url = '/admin/samples/library/%s' 
58     html = ['<table>']
59     #for i in range(1,9):
60     for lane in self.lane_set.all():
61         cluster_estimate = lane.cluster_estimate
62         if cluster_estimate is not None:
63             cluster_estimate = "%s k" % ((int(cluster_estimate)/1000), )
64         else:
65             cluster_estimate = 'None'
66         library_id = lane.library_id
67         library = lane.library
68         element = '<tr><td>%d</td><td><a href="%s">%s</a></td><td>%s</td></tr>'
69         expanded_library_url = library_url %(library_id,)
70         html.append(element % (lane.lane_number, expanded_library_url, library, cluster_estimate))
71     html.append('</table>')
72     return "\n".join(html)
73   Lanes.allow_tags = True
74
75   class Meta:
76     ordering = ["-run_date"]
77   
78 ### -----------------------
79 class DataRun(models.Model):
80   ConfTemplate = "CONFIG PARAMS WILL BE GENERATED BY THE PIPELINE SCRIPT.\nYOU'LL BE ABLE TO EDIT AFTER IF NEEDED."
81   run_folder = models.CharField(max_length=50,unique=True, db_index=True)
82   fcid = models.ForeignKey(FlowCell,verbose_name="Flowcell Id")
83   config_params = models.TextField(default=ConfTemplate)
84   run_start_time = models.DateTimeField()
85   RUN_STATUS_CHOICES = (
86       (0, 'Sequencer running'), ##Solexa Data Pipeline Not Yet Started'),
87       (1, 'Data Pipeline Started'),
88       (2, 'Data Pipeline Interrupted'),
89       (3, 'Data Pipeline Finished'),
90       (4, 'CollectReads Started'),
91       (5, 'CollectReads Finished'),
92       (6, 'QC Finished'),
93       (7, 'DONE'),
94     )
95   run_status = models.IntegerField(choices=RUN_STATUS_CHOICES, default=0)
96   run_note = models.TextField(blank=True)
97
98
99   def main_status(self):
100     str = '<div'
101     if self.run_status >= 5:
102       str += ' style="color:green">'
103       str += '<b>'+self.RUN_STATUS_CHOICES[self.run_status][1]+'</b>'
104       str += '<br/><br/>' #<span style="color:red;font-size:80%;">New!</span>'
105       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>'
106     else:
107       str += '>'+self.RUN_STATUS_CHOICES[self.run_status][1]
108
109     str += '</div>'
110     return str
111   main_status.allow_tags = True
112
113   main_status.allow_tags = True
114   
115   def Flowcell_Info(self):
116     str = '<b>'+self.fcid.__str__()+'</b>'
117     str += '  (c: '+self.fcid.cluster_mac_id+',  s: '+self.fcid.seq_mac_id+')'
118     str += '<div style="margin-top:5px;">'    
119     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>'
120     str += '<div id="LanesOf'+self.fcid.__str__()+'" style="display:block;border:solid #cccccc 1px;width:350px">'
121     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+')'
122     str += LanesList ## self.fcid.Lanes()
123     str += '</div>'
124     str += '<div><a title="open Flowcell record" href="/admin/exp_track/flowcell/'+self.fcid.id.__str__()+'/" target=_self>Edit Flowcell record</a>'
125     #str += '<span style="color:red;font-size:80%;margin-left:15px;margin-right:3px">New!</span>'
126     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>'
127     str += '</div>'
128     str += '</div>'    
129     return str
130   Flowcell_Info.allow_tags = True
131
132
133 class Lane(models.Model):
134   flowcell = models.ForeignKey(FlowCell)
135   lane_number = models.IntegerField(choices=[(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8)])
136   library = models.ForeignKey(Library)
137   pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
138   cluster_estimate = models.IntegerField(blank=True, null=True)
139   comment = models.TextField(null=True, blank=True)