1 # Create your views here.
2 from htsworkflow.frontend.experiments.models import FlowCell
3 from htsworkflow.frontend.samples.changelist import ChangeList
4 from htsworkflow.frontend.samples.models import Library
5 from htsworkflow.frontend.samples.results import get_flowcell_result_dict, parse_flowcell_id
6 from htsworkflow.frontend.bcmagic.forms import BarcodeMagicForm
7 from htsworkflow.pipelines.runfolder import load_pipeline_run_xml
8 from htsworkflow.pipelines import runfolder
9 from htsworkflow.pipelines.eland import ResultLane
10 from htsworkflow.frontend import settings
11 from htsworkflow.util import makebed
12 from htsworkflow.util import opener
14 from django.core.exceptions import ObjectDoesNotExist
15 from django.http import HttpResponse, HttpResponseRedirect
16 from django.shortcuts import render_to_response
17 from django.template import RequestContext
18 from django.template.loader import get_template
19 from django.contrib.auth.decorators import login_required
25 LANE_LIST = [1,2,3,4,5,6,7,8]
26 SAMPLES_CONTEXT_DEFAULTS = {
27 'app_name': 'Flowcell/Library Tracker',
28 'bcmagic': BarcodeMagicForm()
31 def create_library_context(cl):
33 Create a list of libraries that includes how many lanes were run
36 #for lib in library_items.object_list:
37 for lib in cl.result_list:
39 summary['library_id'] = lib.library_id
40 summary['library_name'] = lib.library_name
41 summary['species_name' ] = lib.library_species.scientific_name
42 if lib.amplified_from_sample is not None:
43 summary['amplified_from'] = lib.amplified_from_sample.library_id
45 summary['amplified_from'] = ''
47 #for lane_id in LANE_LIST:
48 # lane = getattr(lib, 'lane_%d_library' % (lane_id,))
49 # lanes_run += len( lane.all() )
50 lanes_run = lib.lane_set.count()
51 summary['lanes_run'] = lanes_run
52 summary['is_archived'] = lib.is_archived()
53 records.append(summary)
54 cl.result_count = unicode(cl.paginator._count) + u" libraries"
55 return {'library_list': records }
59 fcl = ChangeList(request, Library,
60 list_filter=['affiliations', 'library_species'],
61 search_fields=['library_id', 'library_name', 'amplified_from_sample__library_id'],
63 queryset=Library.objects.filter(hidden__exact=0)
66 context = { 'cl': fcl, 'title': 'Library Index'}
67 context.update(create_library_context(fcl))
68 t = get_template('samples/library_index.html')
69 c = RequestContext(request, context)
72 'page_name': 'Library Index',
73 'east_region_config_div': 'changelist-filter',
76 app_context.update(SAMPLES_CONTEXT_DEFAULTS)
78 app_t = get_template('flowcell_libraries_app.html')
79 app_c = RequestContext(request, app_context)
80 return HttpResponse( app_t.render(app_c) )
82 def library_to_flowcells(request, lib_id):
84 Display information about all the flowcells a library has been run on.
88 lib = Library.objects.get(library_id=lib_id)
90 return HttpResponse("Library %s does not exist" % (lib_id))
93 interesting_flowcells = {} # aka flowcells we're looking at
94 #for lane in LANE_LIST:
95 for lane in lib.lane_set.all():
96 #lane_library = getattr(lib, 'lane_%d_library' % (lane,))
97 #for fc in lane_library.all():
99 flowcell_id, id = parse_flowcell_id(fc.flowcell_id)
100 if flowcell_id not in interesting_flowcells:
101 interesting_flowcells[flowcell_id] = get_flowcell_result_dict(flowcell_id)
102 flowcell_list.append((fc.flowcell_id, lane.lane_number))
106 lane_summary_list = []
108 for fc, lane_number in flowcell_list:
109 lane_summary, err_list = _summary_stats(fc, lane_number)
111 eland_results.extend(_make_eland_results(fc, lane_number, interesting_flowcells))
112 lane_summary_list.extend(lane_summary)
115 'page_name': 'Library Details',
117 'eland_results': eland_results,
118 'lane_summary_list': lane_summary_list,
120 context.update(SAMPLES_CONTEXT_DEFAULTS)
122 return render_to_response(
123 'samples/library_detail.html',
125 context_instance = RequestContext(request))
127 def summaryhtm_fc_cnm(request, flowcell_id, cnm):
129 returns a Summary.htm file if it exists.
131 fc_id, status = parse_flowcell_id(flowcell_id)
132 d = get_flowcell_result_dict(fc_id)
135 return HttpResponse('<b>Results for Flowcell %s not found.</b>' % (fc_id))
138 return HttpResponse('<b>Results for Flowcell %s; %s not found.</b>' % (fc_id, cnm))
140 summary_filepath = d[cnm]['summary']
142 if summary_filepath is None:
143 return HttpResponse('<b>Summary.htm for Flowcell %s; %s not found.</b>' % (fc_id, cnm))
145 f = open(summary_filepath, 'r')
147 return HttpResponse(f)
150 def result_fc_cnm_eland_lane(request, flowcell_id, cnm, lane):
152 returns an eland_file upon calling.
154 fc_id, status = parse_flowcell_id(flowcell_id)
155 d = get_flowcell_result_dict(fc_id)
158 return HttpResponse('<b>Results for Flowcell %s not found.</b>' % (fc_id))
161 return HttpResponse('<b>Results for Flowcell %s; %s not found.</b>' % (fc_id, cnm))
163 erd = d[cnm]['eland_results']
167 return HttpResponse('<b>Results for Flowcell %s; %s; lane %s not found.</b>' % (fc_id, cnm, lane))
171 #f = opener.autoopen(filepath, 'r')
172 # return HttpResponse(f, mimetype="application/x-elandresult")
174 f = open(filepath, 'r')
175 return HttpResponse(f, mimetype='application/x-bzip2')
179 def bedfile_fc_cnm_eland_lane_ucsc(request, fc_id, cnm, lane):
181 returns a bed file for a given flowcell, CN-M (i.e. C1-33), and lane (ucsc compatible)
183 return bedfile_fc_cnm_eland_lane(request, fc_id, cnm, lane, ucsc_compatible=True)
186 def bedfile_fc_cnm_eland_lane(request, flowcell_id, cnm, lane, ucsc_compatible=False):
188 returns a bed file for a given flowcell, CN-M (i.e. C1-33), and lane
190 fc_id, status = parse_flowcell_id(flowcell_id)
191 d = get_flowcell_result_dict(fc_id)
194 return HttpResponse('<b>Results for Flowcell %s not found.</b>' % (fc_id))
197 return HttpResponse('<b>Results for Flowcell %s; %s not found.</b>' % (fc_id, cnm))
199 erd = d[cnm]['eland_results']
203 return HttpResponse('<b>Results for Flowcell %s; %s; lane %s not found.</b>' % (fc_id, cnm, lane))
208 fi = opener.autoopen(filepath, 'r')
211 name, description = makebed.make_description( fc_id, lane )
213 bedgen = makebed.make_bed_from_eland_generator(fi, name, description)
216 return HttpResponse(bedgen)
218 return HttpResponse(bedgen, mimetype="application/x-bedfile")
221 def _summary_stats(flowcell_id, lane_id):
223 Return the summary statistics for a given flowcell, lane, and end.
225 fc_id, status = parse_flowcell_id(flowcell_id)
226 fc_result_dict = get_flowcell_result_dict(fc_id)
231 if fc_result_dict is None:
232 err_list.append('Results for Flowcell %s not found.' % (fc_id))
233 return (summary_list, err_list)
235 for cycle_width in fc_result_dict:
236 xmlpath = fc_result_dict[cycle_width]['run_xml']
239 err_list.append('Run xml for Flowcell %s(%s) not found.' % (fc_id, cycle_width))
242 run = load_pipeline_run_xml(xmlpath)
243 gerald_summary = run.gerald.summary.lane_results
244 for end in range(len(gerald_summary)):
245 end_summary = run.gerald.eland_results.results[end]
246 if end_summary.has_key(lane_id):
247 eland_summary = run.gerald.eland_results.results[end][lane_id]
249 eland_summary = ResultLane(lane_id=lane_id, end=end)
250 # add information to lane_summary
251 eland_summary.flowcell_id = flowcell_id
252 eland_summary.clusters = gerald_summary[end][lane_id].cluster
253 eland_summary.cycle_width = cycle_width
254 if hasattr(eland_summary, 'genome_map'):
255 eland_summary.summarized_reads = runfolder.summarize_mapped_reads(
256 eland_summary.genome_map,
257 eland_summary.mapped_reads)
259 # grab some more information out of the flowcell db
260 flowcell = FlowCell.objects.get(flowcell_id=flowcell_id)
261 pm_field = 'lane_%d_pM' % (lane_id)
262 eland_summary.successful_pm = getattr(flowcell, pm_field)
264 summary_list.append(eland_summary)
266 #except Exception, e:
267 # summary_list.append("Summary report needs to be updated.")
268 # logging.error("Exception: " + str(e))
270 return (summary_list, err_list)
272 def _summary_stats_old(flowcell_id, lane):
274 return a dictionary of summary stats for a given flowcell_id & lane.
276 fc_id, status = parse_flowcell_id(flowcell_id)
277 fc_result_dict = get_flowcell_result_dict(fc_id)
283 if fc_result_dict is None:
284 err_list.append('Results for Flowcell %s not found.' % (fc_id))
285 return (dict_list, err_list, summary_list)
287 for cnm in fc_result_dict:
289 xmlpath = fc_result_dict[cnm]['run_xml']
292 err_list.append('Run xml for Flowcell %s(%s) not found.' % (fc_id, cnm))
295 tree = ElementTree.parse(xmlpath).getroot()
296 results = runfolder.PipelineRun(pathname='', xml=tree)
298 lane_report = runfolder.summarize_lane(results.gerald, lane)
299 summary_list.append(os.linesep.join(lane_report))
301 summary_list.append("Summary report needs to be updated.")
302 logging.error("Exception: " + str(e))
304 print "----------------------------------"
305 print "-- DOES NOT SUPPORT PAIRED END ---"
306 print "----------------------------------"
307 lane_results = results.gerald.summary[0][lane]
312 d['average_alignment_score'] = lrs.average_alignment_score
313 d['average_first_cycle_intensity'] = lrs.average_first_cycle_intensity
314 d['cluster'] = lrs.cluster
316 d['flowcell'] = flowcell_id
318 d['percent_error_rate'] = lrs.percent_error_rate
319 d['percent_intensity_after_20_cycles'] = lrs.percent_intensity_after_20_cycles
320 d['percent_pass_filter_align'] = lrs.percent_pass_filter_align
321 d['percent_pass_filter_clusters'] = lrs.percent_pass_filter_clusters
323 #FIXME: function finished, but need to take advantage of
324 # may need to take in a list of lanes so we only have to
325 # load the xml file once per flowcell rather than once
329 return (dict_list, err_list, summary_list)
332 def get_eland_result_type(pathname):
334 Guess the eland result file type from the filename
336 path, filename = os.path.split(pathname)
337 if 'extended' in filename:
339 elif 'multi' in filename:
341 elif 'result' in filename:
346 def _make_eland_results(flowcell_id, lane, interesting_flowcells):
347 fc_id, status = parse_flowcell_id(flowcell_id)
348 cur_fc = interesting_flowcells.get(fc_id, None)
352 flowcell = FlowCell.objects.get(flowcell_id=flowcell_id)
353 # Loop throw storage devices if a result has been archived
355 if cur_fc is not None:
356 for lts in flowcell.longtermstorage_set.all():
357 for sd in lts.storage_devices.all():
358 # Use barcode_id if it exists
359 if sd.barcode_id is not None and sd.barcode_id != '':
360 storage_id_list.append(sd.barcode_id)
363 storage_id_list.append(sd.uuid)
365 # Formatting for template use
366 if len(storage_id_list) == 0:
369 storage_ids = ', '.join([ '<a href="/inventory/%s/">%s</a>' % (s,s) for s in storage_id_list ])
372 for cycle in cur_fc.keys():
373 result_path = cur_fc[cycle]['eland_results'].get(lane, None)
374 result_link = make_result_link(fc_id, cycle, lane, result_path)
375 results.append({'flowcell_id': fc_id,
378 'summary_url': make_summary_url(flowcell_id, cycle),
379 'result_url': result_link[0],
380 'result_label': result_link[1],
381 'bed_url': result_link[2],
382 'storage_ids': storage_ids
386 def make_summary_url(flowcell_id, cycle_name):
387 url = '/results/%s/%s/summary/' % (flowcell_id, cycle_name)
390 def make_result_link(flowcell_id, cycle_name, lane, eland_result_path):
391 if eland_result_path is None:
394 result_type = get_eland_result_type(eland_result_path)
395 result_url = '/results/%s/%s/eland_result/%s' % (flowcell_id, cycle_name, lane)
396 result_label = 'eland %s' % (result_type,)
398 if result_type == 'result':
399 bed_url_pattern = '/results/%s/%s/bedfile/%s'
400 bed_url = bed_url_pattern % (flowcell_id, cycle_name, lane)
402 return (result_url, result_label, bed_url)
404 def _files(flowcell_id, lane):
406 Sets up available files for download
410 flowcell_id, id = parse_flowcell_id(flowcell_id)
411 d = get_flowcell_result_dict(flowcell_id)
418 # c_name == 'CN-M' (i.e. C1-33)
421 if d[c_name]['summary'] is not None:
422 output.append('<a href="/results/%s/%s/summary/">summary(%s)</a>' \
423 % (flowcell_id, c_name, c_name))
425 erd = d[c_name]['eland_results']
427 result_type = get_eland_result_type(erd[lane])
428 result_url_pattern = '<a href="/results/%s/%s/eland_result/%s">eland %s(%s)</a>'
429 output.append(result_url_pattern % (flowcell_id, c_name, lane, result_type, c_name))
430 if result_type == 'result':
431 bed_url_pattern = '<a href="/results/%s/%s/bedfile/%s">bedfile(%s)</a>'
432 output.append(bed_url_pattern % (flowcell_id, c_name, lane, c_name))
437 return '(' + '|'.join(output) + ')'
439 def library_id_to_admin_url(request, lib_id):
440 lib = Library.objects.get(library_id=lib_id)
441 return HttpResponseRedirect('/admin/samples/library/%s' % (lib.id,))
444 def user_profile(request):
446 Information about the user
449 'page_name': 'User Profile',
451 #'bcmagic': BarcodeMagicForm(),
452 #'select': 'settings',
454 context.update(SAMPLES_CONTEXT_DEFAULTS)
455 return render_to_response('registration/profile.html', context,
456 context_instance=RequestContext(request))