3 from django.core.exceptions import ObjectDoesNotExist
4 from django.core import urlresolvers
5 from django.db import models
7 from htsworkflow.frontend.samples.models import *
8 from htsworkflow.frontend.settings import options
10 class ClusterStation(models.Model):
11 name = models.CharField(max_length=50, unique=True)
13 def __unicode__(self):
14 return unicode(self.name)
16 class Sequencer(models.Model):
17 name = models.CharField(max_length=50, unique=True)
19 def __unicode__(self):
20 return unicode(self.name)
24 default_pM = int(options.get('frontend', 'default_pm'))
26 logging.error("invalid value for frontend.default_pm")
28 class FlowCell(models.Model):
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),(0,'All Lanes')], null=True)
37 cluster_station = models.ForeignKey(ClusterStation, default=3)
38 sequencer = models.ForeignKey(Sequencer, default=1)
40 notes = models.TextField(blank=True)
42 def __unicode__(self):
43 return unicode(self.flowcell_id)
47 str +='<a target=_balnk href="/experiments/'+self.flowcell_id+'" title="Create XLS like sheet for this Flowcell ..." ">Create LOG</a>'
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>'
54 Create_LOG.allow_tags = True
57 library_url = '/admin/samples/library/%s'
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), )
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
76 ordering = ["-run_date"]
78 def get_admin_url(self):
79 # that's the django way... except it didn't work
80 #return urlresolvers.reverse('admin_experiments_FlowCell_change', args=(self.id,))
81 return '/admin/experiments/flowcell/%s/' % (self.id,)
83 def flowcell_type(self):
85 Convert our boolean 'is paired' flag to a name
92 ### -----------------------
93 class DataRun(models.Model):
94 ConfTemplate = "CONFIG PARAMS WILL BE GENERATED BY THE PIPELINE SCRIPT.\nYOU'LL BE ABLE TO EDIT AFTER IF NEEDED."
95 run_folder = models.CharField(max_length=50,unique=True, db_index=True)
96 fcid = models.ForeignKey(FlowCell,verbose_name="Flowcell Id")
97 config_params = models.TextField(default=ConfTemplate)
98 run_start_time = models.DateTimeField()
99 RUN_STATUS_CHOICES = (
100 (0, 'Sequencer running'), ##Solexa Data Pipeline Not Yet Started'),
101 (1, 'Data Pipeline Started'),
102 (2, 'Data Pipeline Interrupted'),
103 (3, 'Data Pipeline Finished'),
104 (4, 'CollectReads Started'),
105 (5, 'CollectReads Finished'),
109 run_status = models.IntegerField(choices=RUN_STATUS_CHOICES, default=0)
110 run_note = models.TextField(blank=True)
113 def main_status(self):
115 if self.run_status >= 5:
116 str += ' style="color:green">'
117 str += '<b>'+self.RUN_STATUS_CHOICES[self.run_status][1]+'</b>'
118 str += '<br/><br/>' #<span style="color:red;font-size:80%;">New!</span>'
119 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>'
121 str += '>'+self.RUN_STATUS_CHOICES[self.run_status][1]
125 main_status.allow_tags = True
127 main_status.allow_tags = True
129 def Flowcell_Info(self):
130 str = '<b>'+self.fcid.__str__()+'</b>'
131 str += ' (c: '+self.fcid.cluster_mac_id+', s: '+self.fcid.seq_mac_id+')'
132 str += '<div style="margin-top:5px;">'
133 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>'
134 str += '<div id="LanesOf'+self.fcid.__str__()+'" style="display:block;border:solid #cccccc 1px;width:350px">'
135 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+')'
136 str += LanesList ## self.fcid.Lanes()
138 str += '<div><a title="open Flowcell record" href="/admin/exp_track/flowcell/'+self.fcid.id.__str__()+'/" target=_self>Edit Flowcell record</a>'
139 #str += '<span style="color:red;font-size:80%;margin-left:15px;margin-right:3px">New!</span>'
140 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>'
144 Flowcell_Info.allow_tags = True
146 LANE_STATUS_CODES = [(0, 'Failed'),
149 LANE_STATUS_MAP = dict((int(k),v) for k,v in LANE_STATUS_CODES )
150 LANE_STATUS_MAP[None] = "Unknown"
152 class Lane(models.Model):
153 flowcell = models.ForeignKey(FlowCell)
154 lane_number = models.IntegerField(choices=[(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8)])
155 library = models.ForeignKey(Library)
156 pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
157 cluster_estimate = models.IntegerField(blank=True, null=True)
158 status = models.IntegerField(choices=LANE_STATUS_CODES, null=True, blank=True)
159 comment = models.TextField(null=True, blank=True)