def run(sample): assay_names = [] for a in [sample.dna, sample.protein]: if a is not None: assay_names.append(a.name) assay_type, clicked, assay_args = render(sample, assay_names) first_pass_preprocess(sample, assay_args) if assay_type == DNA_ASSAY: preprocess_dna(sample, clicked, *assay_args) elif assay_type == PROTEIN_ASSAY: preprocess_protein(sample, clicked, *assay_args) if clicked: interface.rerun() available_assays = [] for a in [sample.dna, sample.protein]: if a is not None: available_assays.append(a) if a.name == assay_type: current_assay = a interface.subheader( f'Analysing {assay_type} | {current_assay.shape[0]} cells | {current_assay.shape[1]} ids | {len(set(current_assay.get_labels()))} clusters' ) return current_assay, available_assays
def run(sample, name, should_save): for assay, og_assay in zip( [sample.dna, sample.protein], [sample._original_dna, sample._original_protein]): if assay is not None: for key in assay.metadata: og_assay.add_metadata(key, assay.metadata[key]) for key in assay.row_attrs: og_assay.add_row_attr(key, assay.row_attrs[key]) if should_save: interface.status('Saving h5 file.') if name == '': interface.error('Please provide a name to save by.') elif name[-3:] == '.h5': name = name[:-3] try: os.remove(DFT.ROOT / f'h5/analyzed/{name}.h5') except FileNotFoundError: pass samp = sample[:] set_defaults(samp) mio.save(samp, DFT.ROOT / f'h5/analyzed/{name}.h5') interface.status('Saved.') interface.rerun()
def customize_labels(assay, lab_map, pal): old_labs = set(assay.get_labels()) old_pal = assay.get_palette() assay.rename_labels(lab_map) assay.set_palette(pal) new_labs = set(assay.get_labels()) if new_labs != old_labs or old_pal != pal: interface.rerun()
def run(assay, available_assays): clicked, method, description, cluster_kwargs, info = render(assay) first_pass_cluster(available_assays) if clicked: cluster(assay, method, description, **cluster_kwargs) interface.rerun() interface.info( f'Currently clustered using {assay.metadata[DFT.CLUSTER_DESCRIPTION]}', info)
def run(assay, available_assays): clicked, scale_attribute, pca_attribute, umap_attribute, pca_comps, info = render( assay) first_pass_prepare(available_assays) if clicked: prepare(assay, scale_attribute, pca_attribute, umap_attribute, pca_comps) interface.rerun() interface.info( f'Current transformations are:<br>' f'Scale on {assay.metadata[DFT.SCALE_ATTR]}<br>' f'PCA on {assay.metadata[DFT.PCA_ATTR]}<br>' f'UMAP on {assay.metadata[DFT.UMAP_ATTR]}', info)
def run(sample, name): interface.status('Saving h5 file.') if name == '': interface.error('Please provide a name to save by.') elif name[-3:] == '.h5': name = name[:-3] try: os.remove(DFT.ROOT / f'h5/analyzed/{name}.h5') except FileNotFoundError: pass samp = sample[:] set_defaults(samp) mio.save(samp, DFT.ROOT / f'h5/analyzed/{name}.h5') interface.status('Saved.') interface.rerun()
def render(sample, assay): interface.status('Creating visuals.') category, kind = assay.metadata[DFT.VISUAL_TYPE] options = DFT.VISUALS[category][1] column_sizes = DFT.VISUALS[category][0] columns = st.beta_columns(column_sizes) with columns[0]: new_category = st.selectbox("", list(DFT.VISUALS.keys())) if new_category != category: assay.add_metadata(DFT.VISUAL_TYPE, [new_category, DFT.VISUALS[new_category][1][0]]) interface.rerun() for i in range(len(options)): with columns[i + 1]: st.markdown(f"<p style='margin-bottom:33px'></p>", unsafe_allow_html=True) clicked = st.button(options[i], key=f'visual-{options[i]}') if clicked: kind = options[i] assay.add_metadata(DFT.VISUAL_TYPE, [category, kind]) if kind in DFT.LAYOUT: columns = st.beta_columns(DFT.LAYOUT[kind]) args_conatiner = columns[0] plot_columns = columns[1:] else: columns = st.beta_columns([0.75, 0.1, 2]) args_conatiner = columns[0] plot_columns = columns[2] with args_conatiner: kwargs = {} analyte_map = {'protein': 'Protein', 'dna': 'DNA'} if kind == DFT.SIGNATURES: kwargs['layer'] = st.selectbox('Layer', DFT.LAYERS[assay.name]) kwargs['attribute'] = st.selectbox( 'Signature', ['Median', 'Standard deviation', 'p-value']) elif kind == DFT.HEATMAP: kwargs['attribute'] = st.selectbox('Attribute', DFT.LAYERS[assay.name], key='Visualization Attribute') kwargs['splitby'] = st.selectbox('Split by', DFT.SPLITBY[assay.name]) kwargs['orderby'] = st.selectbox('Order by', DFT.LAYERS[assay.name], key='Visualization Orderby') kwargs['cluster'] = st.checkbox('Cluster within labels', True) kwargs['convolve'] = st.slider('Smoothing', 0, 100) elif kind == DFT.SCATTERPLOT: kwargs['attribute'] = st.selectbox('Attribute', DFT.ATTRS_2D) kwargs['colorby'] = st.selectbox('Color by', DFT.COLORBY[assay.name]) if kwargs['colorby'] not in DFT.SPLITBY[assay.name] + ['density']: features = st.multiselect( 'Features', list(assay.ids()), list(assay.ids())[:min(len(assay.ids()), 4)]) if len(features) != 0: kwargs['features'] = features elif kind == DFT.FEATURE_SCATTER: kwargs['layer'] = st.selectbox('Layer', DFT.LAYERS[assay.name]) feature1 = st.selectbox('Feature 1', list(assay.ids()), index=0) feature2 = st.selectbox('Feature 1', list(assay.ids()), index=2) kwargs['ids'] = [feature1, feature2] kwargs['colorby'] = st.selectbox('Color by', DFT.COLORBY[assay.name]) elif kind == DFT.VIOLINPLOT: kwargs['attribute'] = st.selectbox('Attribute', DFT.LAYERS[assay.name]) kwargs['splitby'] = st.selectbox('Split by', DFT.SPLITBY[assay.name]) kwargs['points'] = st.checkbox('Box and points', False) features = st.multiselect( 'Features', list(assay.ids()), list(assay.ids())[:min(len(assay.ids()), 4)]) if len(features) != 0: kwargs['features'] = features elif kind == DFT.RIDGEPLOT: kwargs['attribute'] = st.selectbox('Attribute', DFT.LAYERS[assay.name]) kwargs['splitby'] = st.selectbox('Split by', DFT.SPLITBY[assay.name]) features = st.multiselect( 'Features', list(assay.ids()), list(assay.ids())[:min(len(assay.ids()), 4)]) if len(features) != 0: kwargs['features'] = features elif kind == DFT.STRIPPLOT: kwargs['attribute'] = st.selectbox('Attribute', DFT.LAYERS[assay.name]) kwargs['colorby'] = st.selectbox('Colorby', DFT.LAYERS[assay.name]) features = st.multiselect( 'Features', list(assay.ids()), list(assay.ids())[:min(len(assay.ids()), 4)]) if len(features) != 0: kwargs['features'] = features elif kind == DFT.DNA_PROTEIN_PLOT: kwargs['analyte'] = st.selectbox( 'Analyte', ['protein'], format_func=lambda a: analyte_map[a]) kwargs['dna_features'] = st.multiselect('DNA features', list(sample.dna.ids()), sample.dna.ids()[:4]) kwargs['protein_features'] = st.multiselect( 'Protein features', list(sample.protein.ids()), sample.protein.ids()[:4]) elif kind == DFT.DNA_PROTEIN_HEATMAP: kwargs['clusterby'] = st.selectbox( 'Cluster by', ['dna', 'protein'], format_func=lambda a: analyte_map[a]) kwargs['sortby'] = st.selectbox( 'Sort by', ['dna', 'protein'], format_func=lambda a: analyte_map[a]) kwargs['dna_features'] = st.multiselect('DNA features', list(sample.dna.ids()), sample.dna.ids()) kwargs['protein_features'] = st.multiselect( 'Protein features', list(sample.protein.ids()), sample.protein.ids()) elif kind == DFT.METRICS: st.header('') interface.info( '<b>Some values might be missing in case the raw<br> files are not loaded.</b> These metrics can be<br> pasted into the metrics sheet as is.' ) elif kind == DFT.READ_DEPTH: if assay.name == PROTEIN_ASSAY: kwargs['layer'] = st.selectbox('Layer', DFT.LAYERS[assay.name]) kwargs['colorby'] = st.selectbox('Color by', ['density', None]) kwargs['features'] = st.multiselect( 'Features', list(assay.ids()), list(assay.ids())[:min(len(assay.ids()), 4)]) else: st.header('') interface.info('<b>Only applicable for the protein assay</b>') elif kind == DFT.ASSAY_SCATTER: kwargs['draw'] = sample.protein_raw is not None if not kwargs['draw']: interface.info('<b>Raw files needed for this plot.</b>') elif kind == DFT.DOWNLOAD: kwargs['item'] = st.selectbox('Object to Download', DFT.DOWNLOAD_ITEMS) kwargs['download'] = st.button('Download', key='download_button') return plot_columns, kind, kwargs
def render(): with st.sidebar.beta_expander('Files', expanded=True): interface.info('Load or download a file from s3') info = st.empty() col1, col2 = st.beta_columns([0.3, 1]) with col1: st.markdown(f"<sup><p style='margin-bottom:22px'></p></sup>", unsafe_allow_html=True) load_raw = st.checkbox('Raw') with col2: st.markdown(f"<sup><p style='margin-bottom:22px'></p></sup>", unsafe_allow_html=True) apply_filter = st.checkbox('Filter', False) link = st.text_input('Load from s3', value='') if not os.path.exists(DFT.ROOT / 'h5'): os.mkdir(DFT.ROOT / 'h5') if not os.path.exists(DFT.ROOT / 'h5/downloads'): os.mkdir(DFT.ROOT / 'h5/downloads/') if not os.path.exists(DFT.ROOT / 'h5/analyzed'): os.mkdir(DFT.ROOT / 'h5/analyzed/') downloaded_files = np.array(os.listdir(DFT.ROOT / 'h5/downloads/')) analyzed_files = np.array(os.listdir(DFT.ROOT / 'h5/analyzed/')) filenames = list(analyzed_files[analyzed_files.argsort()]) + list( downloaded_files[downloaded_files.argsort()]) filenames = [None] + [f for f in filenames if f[-3:] == '.h5'] def shownames(name): nonlocal analyzed_files if name in analyzed_files: return '* ' + name else: return name kind = None selector = st.empty() file = selector.selectbox('Load existing file', filenames, format_func=shownames) if link != '': kind = DFT.S3 file = link elif file is not None: if file in downloaded_files: file = DFT.ROOT / f'h5/downloads/{file}' else: file = DFT.ROOT / f'h5/analyzed/{file}' kind = DFT.LOCAL typed_name = st.text_input('Save, download or delete the given file', value='') def _get_file_from_name(typed_name): if typed_name[-3:] == '.h5': typed_name = typed_name[:-3] if typed_name + '.h5' in analyzed_files: typed_name = DFT.ROOT / f'h5/analyzed/{typed_name}.h5' elif typed_name + '.h5' in downloaded_files: typed_name = DFT.ROOT / f'h5/downloads/{typed_name}.h5' else: interface.error( f'Cannot find "{typed_name}" in the available files') return typed_name col1, col2, col3 = st.beta_columns([0.25, 0.4, 0.4]) with col1: st.markdown('') should_save = st.button('Save') with col2: st.markdown('') if st.button('Download'): download_path = _get_file_from_name(typed_name) interface.download(download_path) with col3: st.markdown('') if st.button('Delete'): typed_name = _get_file_from_name(typed_name) if file is not None and typed_name == file: interface.error( 'Cannot delete the file used in the current analysis.') os.remove(typed_name) interface.rerun() return file, load_raw, apply_filter, kind, should_save, typed_name, info