small html change
[htsworkflow.git] / htswfrontend / htswfrontend / exp_track / models.py
1 from django.db import models
2 from htswfrontend.fctracker.models import *
3 from django.core.exceptions import ObjectDoesNotExist
4
5 class FlowCell(models.Model):
6   
7   flowcell_id = models.CharField(max_length=20, unique=True, db_index=True, core=True)
8   run_date = models.DateTimeField(core=True)
9   advanced_run = models.BooleanField(default=False)
10   read_length = models.IntegerField(default=32) #Stanford is currenlty 25
11   
12   lane_1_library = models.ForeignKey(Library, related_name="lane_1_library")
13   lane_2_library = models.ForeignKey(Library, related_name="lane_2_library")
14   lane_3_library = models.ForeignKey(Library, related_name="lane_3_library")
15   lane_4_library = models.ForeignKey(Library, related_name="lane_4_library")
16   lane_5_library = models.ForeignKey(Library, related_name="lane_5_library")
17   lane_6_library = models.ForeignKey(Library, related_name="lane_6_library")
18   lane_7_library = models.ForeignKey(Library, related_name="lane_7_library")
19   lane_8_library = models.ForeignKey(Library, related_name="lane_8_library")
20
21   lane_1_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5)
22   lane_2_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5)
23   lane_3_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5)
24   lane_4_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5)
25   lane_5_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5)
26   lane_6_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5)
27   lane_7_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5)
28   lane_8_pM = models.DecimalField(max_digits=5, decimal_places=2,blank=False, null=False,default=2.5)
29   
30   lane_1_cluster_estimate = models.IntegerField(blank=True, null=True)
31   lane_2_cluster_estimate = models.IntegerField(blank=True, null=True)
32   lane_3_cluster_estimate = models.IntegerField(blank=True, null=True)
33   lane_4_cluster_estimate = models.IntegerField(blank=True, null=True)
34   lane_5_cluster_estimate = models.IntegerField(blank=True, null=True)
35   lane_6_cluster_estimate = models.IntegerField(blank=True, null=True)
36   lane_7_cluster_estimate = models.IntegerField(blank=True, null=True)
37   lane_8_cluster_estimate = models.IntegerField(blank=True, null=True)
38  
39   # lane_1_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_1_primer")
40   # lane_2_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_2_primer")
41   # lane_3_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_3_primer")
42   # lane_4_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_4_primer")
43   # lane_5_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_5_primer")
44   # lane_6_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_6_primer")
45   # lane_7_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_7_primer")
46   # lane_8_primer = models.ForeignKey(Primer,blank=True,null=True,related_name="lane_8_primer")
47
48   #Machine Names
49   CLUSTER_MAC = (
50       ('M304','Cardinal'),
51       ('R349','R349'),
52       ('Tinkerbell','Tinkerbell'),
53       ('BitBit','BitBit'),
54     )
55   
56   SEQ_MAC = (
57       ('EAS149','Stanford'),
58       ('EAS46','EAS46'),
59       ('EAS45','Paris'),
60       ('Britney','Britney'),
61       ('EAS614','LiLo'),
62     )
63
64   cluster_mac_id = models.CharField(max_length=50, choices=CLUSTER_MAC, default='BitBit')
65   seq_mac_id = models.CharField(max_length=50, choices=SEQ_MAC, verbose_name = 'Sequencer', default='Britney')
66   
67   is_paired_end = models.BooleanField(default=False)
68
69   notes = models.TextField(blank=True)
70
71   def __str__(self):
72     #return '%s (%s)' % (self.flowcell_id, self.run_date) 
73     return '%s' % (self.flowcell_id) 
74
75   def Create_LOG(self):
76     str = ''
77     str +='<a target=_balnk href="/exp_track/'+self.flowcell_id+'" title="Create XLS like sheet for this Flowcell ..." ">Create LOG</a>'
78     try:
79       t = DataRun.objects.get(fcid=self.id)
80       str +='<br/><br/><a target=_self href="/admin/exp_track/datarun/?q='+self.flowcell_id+'" title="Check Data Runs ..." "><b>DataRun</b> ..</a>'
81     except ObjectDoesNotExist:
82       str += '<br/><span style="color:red">not sequenced</span>'
83
84     if self.is_paired_end:
85       str += '<div><b>Paired End</b></div>'
86
87     return str
88   Create_LOG.allow_tags = True 
89
90   def Lanes(self):
91     #return '<div><span style="margin-right:10px">1)%s</span><span style="margin-right:10px">2)%s</span><span style="margin-right:10px">3)%s</span><span style="margin-right:10px">4)%s</span><span style="margin-right:10px">5)%s</span><span style="margin-right:10px">6)%s</span><span style="margin-right:10px">7)%s</span><span style="margin-right:10px">8)%s</span></div>' % (self.lane_1_library,self.lane_2_library,self.lane_3_library,self.lane_4_library,self.lane_5_library,self.lane_6_library,self.lane_7_library,self.lane_8_library)
92      return '<div>1)%s</div><div>2)%s</div><div>3)%s</div><div>4)%s</div><div>5)%s</div><div>6)%s</div><div>7)%s</div><div>8)%s</div>' % (self.lane_1_library,self.lane_2_library,self.lane_3_library,self.lane_4_library,self.lane_5_library,self.lane_6_library,self.lane_7_library,self.lane_8_library)
93   Lanes.allow_tags = True
94
95   class Meta:
96     ordering = ["-run_date"]
97   
98   class Admin:
99     save_on_top = True
100     date_hierarchy = "run_date"
101     save_on_top = True
102     search_fields = ['flowcell_id','seq_mac_id','cluster_mac_id','=lane_1_library__library_id','=lane_2_library__library_id','=lane_3_library__library_id','=lane_4_library__library_id','=lane_5_library__library_id','=lane_6_library__library_id','=lane_7_library__library_id','=lane_8_library__library_id']
103     list_display = ('flowcell_id','seq_mac_id','run_date', 'Create_LOG','Lanes','notes')
104     list_filter = ('seq_mac_id','cluster_mac_id')
105     fields = (
106         (None, {
107             'fields': ('run_date', ('flowcell_id','cluster_mac_id','seq_mac_id','is_paired_end'), ('read_length'),)
108         }),
109         ('Lanes:', {
110             ##'fields' : (('lane_1_library', 'lane_1_pM', 'lane_1_cluster_estimate', 'lane_1_primer'), ('lane_2_library', 'lane_2_pM', 'lane_2_cluster_estimate', 'lane_2_primer'), ('lane_3_library', 'lane_3_pM', 'lane_3_cluster_estimate', 'lane_3_primer'), ('lane_4_library', 'lane_4_pM', 'lane_4_cluster_estimate', 'lane_4_primer'), ('lane_5_library', 'lane_5_pM', 'lane_5_cluster_estimate', 'lane_5_primer'), ('lane_6_library', 'lane_6_pM', 'lane_6_cluster_estimate', 'lane_6_primer'), ('lane_7_library', 'lane_7_pM', 'lane_7_cluster_estimate', 'lane_7_primer'), ('lane_8_library', 'lane_8_pM', 'lane_8_cluster_estimate', 'lane_8_primer'),)
111            'fields' : (('lane_1_library', 'lane_1_pM', 'lane_1_cluster_estimate'), ('lane_2_library', 'lane_2_pM', 'lane_2_cluster_estimate'), ('lane_3_library', 'lane_3_pM', 'lane_3_cluster_estimate'), ('lane_4_library', 'lane_4_pM', 'lane_4_cluster_estimate'), ('lane_5_library', 'lane_5_pM', 'lane_5_cluster_estimate'), ('lane_6_library', 'lane_6_pM', 'lane_6_cluster_estimate'), ('lane_7_library', 'lane_7_pM', 'lane_7_cluster_estimate'), ('lane_8_library', 'lane_8_pM', 'lane_8_cluster_estimate'),)
112         }),
113         (None, {
114             'fields' : ('notes',)
115         }),
116     )
117
118
119 ### -----------------------
120
121 #Global Util vars
122 Dict_SEQ_MAC = dict((row[0], row[1]) for row in FlowCell.SEQ_MAC)
123 Dict_CLUSTER_MAC = dict((row[0], row[1]) for row in FlowCell.CLUSTER_MAC)
124
125
126 class DataRun(models.Model):
127   ConfTemplate = "CONFIG PARAMS WILL BE GENERATED BY THE PIPELINE SCRIPT.\nYOU'LL BE ABLE TO EDIT AFTER IF NEEDED."
128   run_folder = models.CharField(max_length=50,unique=True, db_index=True)
129   fcid = models.ForeignKey(FlowCell,verbose_name="Flowcell Id")
130   config_params = models.TextField(default=ConfTemplate)
131   run_start_time = models.DateTimeField(core=True)
132   RUN_STATUS_CHOICES = (
133       (0, 'Sequencer running'), ##Solexa Data Pipeline Not Yet Started'),
134       (1, 'Data Pipeline Started'),
135       (2, 'Data Pipeline Interrupted'),
136       (3, 'Data Pipeline Finished'),
137       (4, 'CollectReads Started'),
138       (5, 'CollectReads Finished'),
139       (6, 'QC Finished'),
140       (7, 'DONE'),
141     )
142   run_status = models.IntegerField(choices=RUN_STATUS_CHOICES, default=0)
143   run_note = models.TextField(blank=True)
144
145
146   # Global var
147   lrc = []
148   
149   def main_status(self):
150     str = '<div'
151     if self.run_status >= 5:
152       str += ' style="color:green">'
153       str += '<b>'+self.RUN_STATUS_CHOICES[self.run_status][1]+'</b>'
154       str +='<div style="margin-top:10px"><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></div>'
155     else:
156       str += '>'+self.RUN_STATUS_CHOICES[self.run_status][1]
157     str += '</div>'
158
159     ## Check Analysis Server Report 
160     str += '<div style="margin-top:10px">Data:<br/>'
161     res = getLibReads(self.fcid.flowcell_id.__str__(),'ByFC')
162                                                                                                                                                                                                                                                                       
163     if res[3] != 'OK':
164       str += '<div style="margin-top:10px;border:solid red 2px">'+res[3]+'</div>'
165     else:
166       lc = res[0]
167       if(lc>0):
168         rc = "%1.2f" % (res[1]/1000000.0)
169         lrc = ''
170         L = 1
171         for c in res[2]: 
172           lrc += '<div>['+L.__str__()+']: '+ "%1.2f" % (c/1000000.0)+'</div>'  
173           L += 1
174         str += '<div style="color:green"><b>'+lc.__str__()+'</b> lanes<br/><b>'+rc.__str__()+'</b> M reads</div>'
175         str += '<div style="color:#666666"><b>'+lrc+'</b></div>'        
176       else:
177         str += '<div style="color:red">no data yet</div>'
178
179     str += '</div>'
180   
181     return str
182   main_status.allow_tags = True
183
184   ## Util
185   #Dict_SEQ_MAC = dict((row[0], row[1]) for row in FlowCell.SEQ_MAC)
186   
187   def Flowcell_Info(self):
188     str = '<b>'+self.fcid.__str__()+'</b>'
189     str += '  (c: '+Dict_CLUSTER_MAC[self.fcid.cluster_mac_id]+',  s: '+Dict_SEQ_MAC[self.fcid.seq_mac_id]+')'
190     if self.fcid.is_paired_end:
191       str += '<span style="margin-left:10px"><b>Paired End</b></span>'
192     str += '<div style="margin-top:5px;">'    
193     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>'
194     str += '<div id="LanesOf'+self.fcid.__str__()+'" style="display:block;border:solid #cccccc 1px;width:350px">'
195     LanesList = '<div style="'+('background-color:#cccccc;' if 'Bad library' in self.fcid.lane_1_library.libtags() else '')+'">1: '+self.fcid.lane_1_library.__str__()+' ('+self.fcid.lane_1_library.library_species.use_genome_build+')</div> '
196     LanesList += '<div style="'+('background-color:#cccccc;' if 'Bad library' in self.fcid.lane_2_library.libtags() else '')+'">2: '+self.fcid.lane_2_library.__str__()+' ('+self.fcid.lane_2_library.library_species.use_genome_build+')</div>'
197     LanesList += '<div style="'+('background-color:#cccccc;' if 'Bad library' in self.fcid.lane_3_library.libtags() else '')+'">3: '+self.fcid.lane_3_library.__str__()+' ('+self.fcid.lane_3_library.library_species.use_genome_build+')</div>'
198     LanesList += '<div style="'+('background-color:#cccccc;' if 'Bad library' in self.fcid.lane_4_library.libtags() else '')+'">4: '+self.fcid.lane_4_library.__str__()+' ('+self.fcid.lane_4_library.library_species.use_genome_build+')</div>'
199     LanesList += '<div style="'+('background-color:#cccccc;' if 'Bad library' in self.fcid.lane_5_library.libtags() else '')+'">5: '+self.fcid.lane_5_library.__str__()+' ('+self.fcid.lane_5_library.library_species.use_genome_build+')</div>'
200     LanesList += '<div style="'+('background-color:#cccccc;' if 'Bad library' in self.fcid.lane_6_library.libtags() else '')+'">6: '+self.fcid.lane_6_library.__str__()+' ('+self.fcid.lane_6_library.library_species.use_genome_build+')</div>'
201     LanesList += '<div style="'+('background-color:#cccccc;' if 'Bad library' in self.fcid.lane_7_library.libtags() else '')+'">7: '+self.fcid.lane_7_library.__str__()+' ('+self.fcid.lane_7_library.library_species.use_genome_build+')</div>'
202     LanesList += '<div style="'+('background-color:#cccccc;' if 'Bad library' in self.fcid.lane_8_library.libtags() else '')+'">8: '+self.fcid.lane_8_library.__str__()+' ('+self.fcid.lane_8_library.library_species.use_genome_build+')</div>'
203     str += LanesList ## self.fcid.Lanes()
204     str += '</div>'
205     str += '<div><a title="open Flowcell record" href="/admin/exp_track/flowcell/'+self.fcid.id.__str__()+'/" target=_self>Edit Flowcell record</a>'
206     #str += '<span style="color:red;font-size:80%;margin-left:15px;margin-right:3px">New!</span>'
207     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>'
208     str += '</div>'
209     str += '</div>'    
210     return str
211   Flowcell_Info.allow_tags = True
212
213   class Admin:
214     search_fields = ['run_folder','run_note','config_params','=fcid__lane_1_library__library_id','=fcid__lane_2_library__library_id','=fcid__lane_3_library__library_id','=fcid__lane_4_library__library_id','=fcid__lane_5_library__library_id','=fcid__lane_6_library__library_id','=fcid__lane_7_library__library_id','=fcid__lane_8_library__library_id']
215
216     list_display = ('run_folder','Flowcell_Info','run_start_time','main_status','run_note')
217     list_filter = ('run_status','run_start_time')