def download_dip_rates(request, dataset_id): try: dataset = HTSDataset.objects.get(pk=dataset_id, deleted_date=None) except HTSDataset.DoesNotExist: raise Http404() _assert_has_perm(request, dataset, 'download_data') if not license_accepted(request, dataset): return _plain_response('You must accept the dataset license to ' 'download this file') try: full_path = _generate_dip_rates(dataset) except NoDataException: return _plain_response('No data found for this request') output_filename = '{}_dip_rates.tsv'.format(dataset.name) return serve_file(request, full_path, rename_to=output_filename, content_type='text/tab-separated-values')
def download_fit_params(request, dataset_id, stat_type): file_type = 'fit_params_{}_tsv'.format(stat_type) file_name = 'fit_params_{}_{}.tsv'.format(stat_type, dataset_id) file_type_protocol = 1 param_names = { 'dip': ('aa', 'aa_obs', 'emax', 'emax_rel', 'emax_obs', 'emax_obs_rel', 'einf', 'ec50', 'ic50', 'hill'), 'viability': ('aa', 'aa_obs', 'emax', 'emax_obs', 'einf', 'ec50', 'ic50', 'hill') } try: dataset = HTSDataset.objects.get(pk=dataset_id, deleted_date=None) except (HTSDataset.DoesNotExist, ValueError): return _plain_response('This dataset does not exist, or you do not ' 'have permission to access it.') _assert_has_perm(request, dataset, 'download_data') if not license_accepted(request, dataset): return _plain_response('You must accept the dataset license to ' 'download this file') mod_date = timezone.now() file = _cached_file(dataset, file_type, file_type_protocol) # Additional cache invalidation: curve fits were generated after the # cached file if file: if file.creation_date < CurveFitSet.objects.get( dataset_id=dataset_id, stat_type=stat_type).calculation_end: file = None if file: full_path = file.file.name else: try: # Fetch the DIP rates from the DB base_params = df_curve_fits(dataset.id, stat_type, drug_ids=None, cell_line_ids=None) except NoDataException: return _plain_response( 'The requested parameter set does not exist for the ' 'specified dataset') # Fit Hill curves and compute parameters fp = fit_params_from_base(base_params, custom_ic_concentrations={50}, custom_ec_concentrations={50}, include_auc=False, include_aa=True, include_hill=True, include_emax=True, include_einf=True, include_response_values=False) fp.reset_index('dataset_id', drop=True, inplace=True) # Remove -ve AA values fp.loc[fp['aa'] < 0.0, 'aa'] = np.nan # Filter for the default list of parameters only fp = fp.filter(items=param_names[stat_type]) full_path = os.path.join(settings.DOWNLOADS_ROOT, file_name) fp.to_csv(full_path, sep='\t') df, created = HTSDatasetFile.objects.get_or_create( dataset=dataset, file_type=file_type, defaults={ 'file_type_protocol': file_type_protocol, 'file': full_path }) if not created: df.file_type_protocol = file_type_protocol df.file = full_path df.creation_date = mod_date df.save() output_filename = '{}_{}_params.tsv'.format(dataset.name, stat_type) return serve_file(request, full_path, rename_to=output_filename, content_type='text/tab-separated-values')
def ajax_get_plot(request, file_type='json'): if file_type == 'csv': permission_required = 'download_data' else: permission_required = 'view_plots' try: plot_type = request.GET['plotType'] template = request.GET.get('theme', default_plotly_template) if template not in ALLOWED_TEMPLATES: return HttpResponse('Please select an allowed template', status=400) dataset_id = int(request.GET['datasetId']) dataset2_id = request.GET.get('dataset2Id', None) if dataset2_id == "": dataset2_id = None if dataset2_id is not None: dataset2_id = int(dataset2_id) cell_line_id = request.GET.getlist('c') drug_id = request.GET.getlist('d') cell_line_id = [int(cl) for cl in cell_line_id] drug_ids = [] for dr in drug_id: try: drug_ids.append(int(dr)) except ValueError: drug_ids.append([int(d) for d in dr.split(",")]) drug_id = drug_ids assay = request.GET.get('assayId') yaxis = request.GET.get('logTransform', 'None') except (KeyError, ValueError): raise Http404() try: dataset = HTSDataset.objects.get(pk=dataset_id) except HTSDataset.DoesNotExist: raise Http404() _assert_has_perm(request, dataset, permission_required) if not license_accepted(request, dataset): return HttpResponse(LICENSE_UNSIGNED.format(dataset.name), status=400) if plot_type == 'tc': if len(drug_id) != 1 or len(cell_line_id) != 1: return HttpResponse( 'Please select exactly one cell line and ' 'drug for time course plot', status=400) try: df_data = df_doses_assays_controls(dataset=dataset, drug_id=drug_id, cell_line_id=cell_line_id, assay=assay) except NoDataException: return HttpResponse( 'No data found for this request. This ' 'drug/cell line/assay combination may not ' 'exist.', status=400) if assay is None: assay = df_data.assays.index.get_level_values('assay')[0] overlay_dip_fit = request.GET.get('overlayDipFit', 'false') == 'true' if overlay_dip_fit and assay != df_data.dip_assay_name: return HttpResponse( 'Can only overlay DIP rate on cell ' 'proliferation assays', status=400) plot_fig = plot_time_course(df_data, log_yaxis=yaxis == 'log2', assay_name=assay, show_dip_fit=overlay_dip_fit, subtitle=dataset.name, template=template) elif plot_type in ('drc', 'drpar'): if all(isinstance(d, int) for d in drug_id): plot_fig = _dose_response_plot(request, dataset, dataset2_id, permission_required, drug_id, cell_line_id, plot_type, template) else: if dataset2_id is not None: return HttpResponse( 'Please select a single dataset at a time to view drug ' 'combination heat plots', status=400) plot_fig = _drug_combination_heatmap(request, dataset, drug_id, cell_line_id, template) if isinstance(plot_fig, HttpResponse): return plot_fig elif plot_type == 'qc': qc_view = request.GET.get('qcView', None) if qc_view == 'ctrldipbox': ctrl_dip_data = df_ctrl_dip_rates(dataset_id) if ctrl_dip_data is None: return HttpResponse( 'No control wells with DIP rates ' 'available were detected in this ' 'dataset.', status=400) plot_fig = plot_ctrl_dip_by_plate(ctrl_dip_data, template=template) elif qc_view == 'ctrlcellbox': # Try to fetch from cache cache_key = f'dataset_{dataset_id}_plot_ctrlcellbox' cur_plotver = 1 plot_cached = cache.get(cache_key) if plot_cached: plot_fig = plot_cached['plot_fig'] if plot_cached is None or plot_cached['dataset_last_modified'] < dataset.modified_date or \ plot_cached['plot_version'] < cur_plotver: # Create plot groupings = dataset_groupings(dataset) if not groupings['singleTimepoint']: return HttpResponse( 'This plot type is only available for ' 'single time-point datasets', status=400) try: df_data = df_control_wells(dataset_id=dataset, assay=assay) except NoDataException: return HttpResponse('No data found for this request.', status=400) if (df_data['value'] == 100.0).all(): return HttpResponse( 'The raw data for this dataset is given as relative viability, so no control ' 'wells are available', status=400) plot_fig = plot_ctrl_cell_counts_by_plate( df_data, subtitle=dataset.name, template=template) # Push to cache cache.set( cache_key, { 'dataset_last_modified': dataset.modified_date, 'plot_version': cur_plotver, 'plot_fig': plot_fig }) elif qc_view == 'dipplatemap': plate_id = request.GET.get('plateId', None) try: plate_id = int(plate_id) except ValueError: return HttpResponse('Integer plateId required', status=400) pl_data = ajax_load_plate(request, plate_id, return_as_platedata=True, use_names=True) plot_fig = plot_plate_map(pl_data, color_by='dip_rates', template=template) else: return HttpResponse('Unimplemented QC view: {}'.format(qc_view), status=400) else: return HttpResponse('Unimplemented plot type: %s' % plot_type, status=400) as_attachment = request.GET.get('download', '0') == '1' if file_type == 'json': j = json.dumps(plot_fig, cls=PlotlyJSONEncoder) response = HttpResponse(j, content_type='application/json') elif file_type == 'csv': response = HttpResponse(plotly_to_dataframe(plot_fig).to_csv(), content_type='text/csv') elif file_type == 'html': template = 'plotly_plot{}.html'.format( '_standalone' if as_attachment else '') context = { 'data': json.dumps(plot_fig, cls=PlotlyJSONEncoder), 'page_title': strip_tags(plot_fig['layout']['title']['text']) } if as_attachment: context['plotlyjs'] = get_plotlyjs() response = render(request, template, context) else: return HttpResponse('Unknown file type: %s' % file_type, status=400) if as_attachment: try: title = plot_fig['layout']['title']['text'] except KeyError: title = 'Plot' response['Content-Disposition'] = \ 'attachment; filename="{}.{}"'.format(strip_tags(title), file_type) return response
def ajax_load_plate(request, plate_id, extra_return_args=None, return_as_platedata=False, use_names=False): if not request.user.is_authenticated and settings.LOGIN_REQUIRED: return JsonResponse({}, status=401) try: p = Plate.objects.filter(id=plate_id).select_related('dataset').get() except Plate.DoesNotExist: raise Http404() _assert_has_perm(request, p.dataset, 'view_plate_layout') if not license_accepted(request, p.dataset): return HttpResponse(LICENSE_UNSIGNED.format(p.dataset.name), status=400) field_ext = '__name' if use_names else '_id' # Blank well data wells = [] for cl in range(p.num_wells): wells.append({ 'cellLine': None, 'drugs': AutoExtendList(), 'doses': AutoExtendList(), 'dipRate': None }) # Populate cell lines cl_query = Well.objects.filter(plate_id=plate_id).values( 'well_num', 'cell_line' + field_ext) for w in cl_query: wells[w['well_num']]['cellLine'] = w['cell_line' + field_ext] # Populate drugs drugs = WellDrug.objects.filter(well__plate_id=plate_id).values( 'well__well_num', 'drug' + field_ext, 'order', 'dose') for dr in drugs: # prefetched above wells[dr['well__well_num']]['drugs'][dr['order']] = dr['drug' + field_ext] wells[dr['well__well_num']]['doses'][dr['order']] = dr['dose'] # Populate DIP rates for ws in WellStatistic.objects.filter(well__plate_id=plate_id, stat_name='dip_rate').values( 'well__well_num', 'value'): # Need to remove NaNs for proper JSON support wells[ws['well__well_num']]['dipRate'] = ws['value'] if \ ws['value'] is not None and not math.isnan(ws['value']) else None plate = { 'datasetName': p.dataset.name, 'plateId': p.id, 'plateName': p.name, 'numCols': p.width, 'numRows': p.height, 'wells': wells } if return_as_platedata: return PlateData.from_dict(plate) return_dict = {'success': True, 'plateMap': plate} if extra_return_args is not None: return_dict.update(extra_return_args) return JsonResponse(return_dict)