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 if len(gerald_summary) > end and gerald_summary[end].has_key(lane_id):
253 eland_summary.clusters = gerald_summary[end][lane_id].cluster
255 eland_summary.clusters = None
256 eland_summary.cycle_width = cycle_width
257 if hasattr(eland_summary, 'genome_map'):
258 eland_summary.summarized_reads = runfolder.summarize_mapped_reads(
259 eland_summary.genome_map,
260 eland_summary.mapped_reads)
262 # grab some more information out of the flowcell db
263 flowcell = FlowCell.objects.get(flowcell_id=flowcell_id)
264 #pm_field = 'lane_%d_pM' % (lane_id)
265 lane_obj = flowcell.lane_set.get(lane_number=lane_id)
266 eland_summary.successful_pm = lane_obj.pM
268 summary_list.append(eland_summary)
270 #except Exception, e:
271 # summary_list.append("Summary report needs to be updated.")
272 # logging.error("Exception: " + str(e))
274 return (summary_list, err_list)
276 def _summary_stats_old(flowcell_id, lane):
278 return a dictionary of summary stats for a given flowcell_id & lane.
280 fc_id, status = parse_flowcell_id(flowcell_id)
281 fc_result_dict = get_flowcell_result_dict(fc_id)
287 if fc_result_dict is None:
288 err_list.append('Results for Flowcell %s not found.' % (fc_id))
289 return (dict_list, err_list, summary_list)
291 for cnm in fc_result_dict:
293 xmlpath = fc_result_dict[cnm]['run_xml']
296 err_list.append('Run xml for Flowcell %s(%s) not found.' % (fc_id, cnm))
299 tree = ElementTree.parse(xmlpath).getroot()
300 results = runfolder.PipelineRun(pathname='', xml=tree)
302 lane_report = runfolder.summarize_lane(results.gerald, lane)
303 summary_list.append(os.linesep.join(lane_report))
305 summary_list.append("Summary report needs to be updated.")
306 logging.error("Exception: " + str(e))
308 print "----------------------------------"
309 print "-- DOES NOT SUPPORT PAIRED END ---"
310 print "----------------------------------"
311 lane_results = results.gerald.summary[0][lane]
316 d['average_alignment_score'] = lrs.average_alignment_score
317 d['average_first_cycle_intensity'] = lrs.average_first_cycle_intensity
318 d['cluster'] = lrs.cluster
320 d['flowcell'] = flowcell_id
322 d['percent_error_rate'] = lrs.percent_error_rate
323 d['percent_intensity_after_20_cycles'] = lrs.percent_intensity_after_20_cycles
324 d['percent_pass_filter_align'] = lrs.percent_pass_filter_align
325 d['percent_pass_filter_clusters'] = lrs.percent_pass_filter_clusters
327 #FIXME: function finished, but need to take advantage of
328 # may need to take in a list of lanes so we only have to
329 # load the xml file once per flowcell rather than once
333 return (dict_list, err_list, summary_list)
336 def get_eland_result_type(pathname):
338 Guess the eland result file type from the filename
340 path, filename = os.path.split(pathname)
341 if 'extended' in filename:
343 elif 'multi' in filename:
345 elif 'result' in filename:
350 def _make_eland_results(flowcell_id, lane, interesting_flowcells):
351 fc_id, status = parse_flowcell_id(flowcell_id)
352 cur_fc = interesting_flowcells.get(fc_id, None)
356 flowcell = FlowCell.objects.get(flowcell_id=flowcell_id)
357 # Loop throw storage devices if a result has been archived
359 if cur_fc is not None:
360 for lts in flowcell.longtermstorage_set.all():
361 for sd in lts.storage_devices.all():
362 # Use barcode_id if it exists
363 if sd.barcode_id is not None and sd.barcode_id != '':
364 storage_id_list.append(sd.barcode_id)
367 storage_id_list.append(sd.uuid)
369 # Formatting for template use
370 if len(storage_id_list) == 0:
373 storage_ids = ', '.join([ '<a href="/inventory/%s/">%s</a>' % (s,s) for s in storage_id_list ])
376 for cycle in cur_fc.keys():
377 result_path = cur_fc[cycle]['eland_results'].get(lane, None)
378 result_link = make_result_link(fc_id, cycle, lane, result_path)
379 results.append({'flowcell_id': fc_id,
382 'summary_url': make_summary_url(flowcell_id, cycle),
383 'result_url': result_link[0],
384 'result_label': result_link[1],
385 'bed_url': result_link[2],
386 'storage_ids': storage_ids
390 def make_summary_url(flowcell_id, cycle_name):
391 url = '/results/%s/%s/summary/' % (flowcell_id, cycle_name)
394 def make_result_link(flowcell_id, cycle_name, lane, eland_result_path):
395 if eland_result_path is None:
398 result_type = get_eland_result_type(eland_result_path)
399 result_url = '/results/%s/%s/eland_result/%s' % (flowcell_id, cycle_name, lane)
400 result_label = 'eland %s' % (result_type,)
402 if result_type == 'result':
403 bed_url_pattern = '/results/%s/%s/bedfile/%s'
404 bed_url = bed_url_pattern % (flowcell_id, cycle_name, lane)
406 return (result_url, result_label, bed_url)
408 def _files(flowcell_id, lane):
410 Sets up available files for download
414 flowcell_id, id = parse_flowcell_id(flowcell_id)
415 d = get_flowcell_result_dict(flowcell_id)
422 # c_name == 'CN-M' (i.e. C1-33)
425 if d[c_name]['summary'] is not None:
426 output.append('<a href="/results/%s/%s/summary/">summary(%s)</a>' \
427 % (flowcell_id, c_name, c_name))
429 erd = d[c_name]['eland_results']
431 result_type = get_eland_result_type(erd[lane])
432 result_url_pattern = '<a href="/results/%s/%s/eland_result/%s">eland %s(%s)</a>'
433 output.append(result_url_pattern % (flowcell_id, c_name, lane, result_type, c_name))
434 if result_type == 'result':
435 bed_url_pattern = '<a href="/results/%s/%s/bedfile/%s">bedfile(%s)</a>'
436 output.append(bed_url_pattern % (flowcell_id, c_name, lane, c_name))
441 return '(' + '|'.join(output) + ')'
443 def library_id_to_admin_url(request, lib_id):
444 lib = Library.objects.get(library_id=lib_id)
445 return HttpResponseRedirect('/admin/samples/library/%s' % (lib.id,))
448 def user_profile(request):
450 Information about the user
453 'page_name': 'User Profile',
455 #'bcmagic': BarcodeMagicForm(),
456 #'select': 'settings',
458 context.update(SAMPLES_CONTEXT_DEFAULTS)
459 return render_to_response('registration/profile.html', context,
460 context_instance=RequestContext(request))