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
93 def get_absolute_url(self):
94 return ('htsworkflow.frontend.experiments.views.flowcell_detail',
95 [str(self.flowcell_id)])
97 ### -----------------------
98 class DataRun(models.Model):
99 ConfTemplate = "CONFIG PARAMS WILL BE GENERATED BY THE PIPELINE SCRIPT.\nYOU'LL BE ABLE TO EDIT AFTER IF NEEDED."
100 run_folder = models.CharField(max_length=50,unique=True, db_index=True)
101 fcid = models.ForeignKey(FlowCell,verbose_name="Flowcell Id")
102 config_params = models.TextField(default=ConfTemplate)
103 run_start_time = models.DateTimeField()
104 RUN_STATUS_CHOICES = (
105 (0, 'Sequencer running'), ##Solexa Data Pipeline Not Yet Started'),
106 (1, 'Data Pipeline Started'),
107 (2, 'Data Pipeline Interrupted'),
108 (3, 'Data Pipeline Finished'),
109 (4, 'CollectReads Started'),
110 (5, 'CollectReads Finished'),
114 run_status = models.IntegerField(choices=RUN_STATUS_CHOICES, default=0)
115 run_note = models.TextField(blank=True)
118 def main_status(self):
120 if self.run_status >= 5:
121 str += ' style="color:green">'
122 str += '<b>'+self.RUN_STATUS_CHOICES[self.run_status][1]+'</b>'
123 str += '<br/><br/>' #<span style="color:red;font-size:80%;">New!</span>'
124 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>'
126 str += '>'+self.RUN_STATUS_CHOICES[self.run_status][1]
130 main_status.allow_tags = True
132 main_status.allow_tags = True
134 def Flowcell_Info(self):
135 str = '<b>'+self.fcid.__str__()+'</b>'
136 str += ' (c: '+self.fcid.cluster_mac_id+', s: '+self.fcid.seq_mac_id+')'
137 str += '<div style="margin-top:5px;">'
138 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>'
139 str += '<div id="LanesOf'+self.fcid.__str__()+'" style="display:block;border:solid #cccccc 1px;width:350px">'
140 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+')'
141 str += LanesList ## self.fcid.Lanes()
143 str += '<div><a title="open Flowcell record" href="/admin/exp_track/flowcell/'+self.fcid.id.__str__()+'/" target=_self>Edit Flowcell record</a>'
144 #str += '<span style="color:red;font-size:80%;margin-left:15px;margin-right:3px">New!</span>'
145 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>'
149 Flowcell_Info.allow_tags = True
151 LANE_STATUS_CODES = [(0, 'Failed'),
154 LANE_STATUS_MAP = dict((int(k),v) for k,v in LANE_STATUS_CODES )
155 LANE_STATUS_MAP[None] = "Unknown"
157 class Lane(models.Model):
158 flowcell = models.ForeignKey(FlowCell)
159 lane_number = models.IntegerField(choices=[(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8)])
160 library = models.ForeignKey(Library)
161 pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=default_pM)
162 cluster_estimate = models.IntegerField(blank=True, null=True)
163 status = models.IntegerField(choices=LANE_STATUS_CODES, null=True, blank=True)
164 comment = models.TextField(null=True, blank=True)
167 def get_absolute_url(self):
168 return ('htsworkflow.frontend.experiments.views.flowcell_lane_detail',
169 [str(self.flowcell.flowcell_id), str(self.lane_number)])