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 lane_obj = flowcell.lane_set.get(lane_number=lane_id)
263 eland_summary.successful_pm = lane_obj.pM
265 summary_list.append(eland_summary)
267 #except Exception, e:
268 # summary_list.append("Summary report needs to be updated.")
269 # logging.error("Exception: " + str(e))
271 return (summary_list, err_list)
273 def _summary_stats_old(flowcell_id, lane):
275 return a dictionary of summary stats for a given flowcell_id & lane.
277 fc_id, status = parse_flowcell_id(flowcell_id)
278 fc_result_dict = get_flowcell_result_dict(fc_id)
284 if fc_result_dict is None:
285 err_list.append('Results for Flowcell %s not found.' % (fc_id))
286 return (dict_list, err_list, summary_list)
288 for cnm in fc_result_dict:
290 xmlpath = fc_result_dict[cnm]['run_xml']
293 err_list.append('Run xml for Flowcell %s(%s) not found.' % (fc_id, cnm))
296 tree = ElementTree.parse(xmlpath).getroot()
297 results = runfolder.PipelineRun(pathname='', xml=tree)
299 lane_report = runfolder.summarize_lane(results.gerald, lane)
300 summary_list.append(os.linesep.join(lane_report))
302 summary_list.append("Summary report needs to be updated.")
303 logging.error("Exception: " + str(e))
305 print "----------------------------------"
306 print "-- DOES NOT SUPPORT PAIRED END ---"
307 print "----------------------------------"
308 lane_results = results.gerald.summary[0][lane]
313 d['average_alignment_score'] = lrs.average_alignment_score
314 d['average_first_cycle_intensity'] = lrs.average_first_cycle_intensity
315 d['cluster'] = lrs.cluster
317 d['flowcell'] = flowcell_id
319 d['percent_error_rate'] = lrs.percent_error_rate
320 d['percent_intensity_after_20_cycles'] = lrs.percent_intensity_after_20_cycles
321 d['percent_pass_filter_align'] = lrs.percent_pass_filter_align
322 d['percent_pass_filter_clusters'] = lrs.percent_pass_filter_clusters
324 #FIXME: function finished, but need to take advantage of
325 # may need to take in a list of lanes so we only have to
326 # load the xml file once per flowcell rather than once
330 return (dict_list, err_list, summary_list)
333 def get_eland_result_type(pathname):
335 Guess the eland result file type from the filename
337 path, filename = os.path.split(pathname)
338 if 'extended' in filename:
340 elif 'multi' in filename:
342 elif 'result' in filename:
347 def _make_eland_results(flowcell_id, lane, interesting_flowcells):
348 fc_id, status = parse_flowcell_id(flowcell_id)
349 cur_fc = interesting_flowcells.get(fc_id, None)
353 flowcell = FlowCell.objects.get(flowcell_id=flowcell_id)
354 # Loop throw storage devices if a result has been archived
356 if cur_fc is not None:
357 for lts in flowcell.longtermstorage_set.all():
358 for sd in lts.storage_devices.all():
359 # Use barcode_id if it exists
360 if sd.barcode_id is not None and sd.barcode_id != '':
361 storage_id_list.append(sd.barcode_id)
364 storage_id_list.append(sd.uuid)
366 # Formatting for template use
367 if len(storage_id_list) == 0:
370 storage_ids = ', '.join([ '<a href="/inventory/%s/">%s</a>' % (s,s) for s in storage_id_list ])
373 for cycle in cur_fc.keys():
374 result_path = cur_fc[cycle]['eland_results'].get(lane, None)
375 result_link = make_result_link(fc_id, cycle, lane, result_path)
376 results.append({'flowcell_id': fc_id,
379 'summary_url': make_summary_url(flowcell_id, cycle),
380 'result_url': result_link[0],
381 'result_label': result_link[1],
382 'bed_url': result_link[2],
383 'storage_ids': storage_ids
387 def make_summary_url(flowcell_id, cycle_name):
388 url = '/results/%s/%s/summary/' % (flowcell_id, cycle_name)
391 def make_result_link(flowcell_id, cycle_name, lane, eland_result_path):
392 if eland_result_path is None:
395 result_type = get_eland_result_type(eland_result_path)
396 result_url = '/results/%s/%s/eland_result/%s' % (flowcell_id, cycle_name, lane)
397 result_label = 'eland %s' % (result_type,)
399 if result_type == 'result':
400 bed_url_pattern = '/results/%s/%s/bedfile/%s'
401 bed_url = bed_url_pattern % (flowcell_id, cycle_name, lane)
403 return (result_url, result_label, bed_url)
405 def _files(flowcell_id, lane):
407 Sets up available files for download
411 flowcell_id, id = parse_flowcell_id(flowcell_id)
412 d = get_flowcell_result_dict(flowcell_id)
419 # c_name == 'CN-M' (i.e. C1-33)
422 if d[c_name]['summary'] is not None:
423 output.append('<a href="/results/%s/%s/summary/">summary(%s)</a>' \
424 % (flowcell_id, c_name, c_name))
426 erd = d[c_name]['eland_results']
428 result_type = get_eland_result_type(erd[lane])
429 result_url_pattern = '<a href="/results/%s/%s/eland_result/%s">eland %s(%s)</a>'
430 output.append(result_url_pattern % (flowcell_id, c_name, lane, result_type, c_name))
431 if result_type == 'result':
432 bed_url_pattern = '<a href="/results/%s/%s/bedfile/%s">bedfile(%s)</a>'
433 output.append(bed_url_pattern % (flowcell_id, c_name, lane, c_name))
438 return '(' + '|'.join(output) + ')'
440 def library_id_to_admin_url(request, lib_id):
441 lib = Library.objects.get(library_id=lib_id)
442 return HttpResponseRedirect('/admin/samples/library/%s' % (lib.id,))
445 def user_profile(request):
447 Information about the user
450 'page_name': 'User Profile',
452 #'bcmagic': BarcodeMagicForm(),
453 #'select': 'settings',
455 context.update(SAMPLES_CONTEXT_DEFAULTS)
456 return render_to_response('registration/profile.html', context,
457 context_instance=RequestContext(request))