def download_pdb( pdb_download_button_clicked, sequence_alignment_data, caretta_class ): if pdb_download_button_clicked and sequence_alignment_data and caretta_class: sequence_alignment = app_helper.decompress_object( sequence_alignment_data, suite ) if not sequence_alignment: return "" msa_class = app_helper.decompress_object(caretta_class, suite) msa_class.write_files( write_pdb=True, write_fasta=False, write_class=False, write_features=False, ) output_filename = f"{msa_class.output_folder}/superposed_pdbs.zip" pdb_zip_file = ZipFile(output_filename, mode="w") for pdb_file in (Path(msa_class.output_folder) / "superposed_pdbs").glob( "*.pdb" ): pdb_zip_file.write( str(pdb_file), arcname=f"{pdb_file.stem}{pdb_file.suffix}" ) return app_layout.get_download_string(output_filename) else: return ""
def display_feature( display_feature_button_clicked, feature_selection_dropdown_value, feature_alignment_data, ): if (display_feature_button_clicked and feature_selection_dropdown_value and feature_alignment_data): feature_alignment_dict = app_helper.decompress_object( feature_alignment_data, suite) chosen_feature_data = feature_alignment_dict[ feature_selection_dropdown_value] feature_line_component = dcc.Graph( figure=app_helper.line(chosen_feature_data), id="feature-line-graph") feature_heatmap_component = dcc.Graph( figure=app_helper.heatmap(chosen_feature_data), id="feature-heatmap-graph", ) return feature_line_component, feature_heatmap_component else: return ( dcc.Graph( figure=app_helper.empty_dict(), id="feature-line-graph", style={"display": "none"}, ), dcc.Graph( figure=app_helper.empty_dict(), id="feature-heatmap-graph", style={"display": "none"}, ), )
def download_alignment(fasta_download_button_clicked, sequence_alignment_data, caretta_class): if fasta_download_button_clicked and sequence_alignment_data and caretta_class: sequence_alignment = app_helper.decompress_object( sequence_alignment_data, suite) if not sequence_alignment: return "" msa_class = app_helper.decompress_object(caretta_class, suite) msa_class.write_files( write_pdb=False, write_fasta=True, write_class=False, write_features=False, write_matrix=False, ) return app_layout.get_download_string( str(Path(msa_class.output_folder) / "result.fasta")) else: return ""
def download_features( export_feature_button_clicked, export_all_features_button_clicked, feature_selection_dropdown_value, feature_alignment_data, caretta_class, ): output_string = "" if feature_alignment_data and caretta_class: feature_alignment_dict = app_helper.decompress_object( feature_alignment_data, suite ) msa_class = app_helper.decompress_object(caretta_class, suite) protein_names = [s.name for s in msa_class.structures] if ( export_feature_button_clicked and feature_selection_dropdown_value ) and not export_all_features_button_clicked: output_filename = f"{msa_class.output_folder}/{'-'.join(feature_selection_dropdown_value.split())}.csv" app_helper.write_feature_as_tsv( feature_alignment_dict[feature_selection_dropdown_value], protein_names, output_filename, ) output_string = app_layout.get_download_string(output_filename) elif ( export_all_features_button_clicked and not export_feature_button_clicked ): output_filename = f"{msa_class.output_folder}/features.zip" features_zip_file = ZipFile(output_filename, mode="w") for feature in feature_alignment_dict: feature_file = ( f"{msa_class.output_folder}/{'-'.join(feature.split())}.csv" ) app_helper.write_feature_as_tsv( feature_alignment_dict[feature], protein_names, feature_file ) features_zip_file.write( str(feature_file), arcname=f"{'-'.join(feature.split())}.csv" ) output_string = app_layout.get_download_string(output_filename) return output_string, app_layout.get_export_feature_buttons()
def align_structures( align_button, user_input, proteins_selection_dropdown, gap_open_dropdown, gap_extend_dropdown, unique_id, ): if align_button and user_input and proteins_selection_dropdown: pdb_entries = [ app_helper.decompress_object(x, suite) for x in proteins_selection_dropdown ] if not gap_open_dropdown: gap_open_dropdown = 1 if not gap_extend_dropdown: gap_extend_dropdown = 0.01 pdb_files = [] for p in pdb_entries: try: pdb_files.append(p.get_pdb()[1]) except (OSError, AttributeError, pyparsing.ParseException): continue msa_class = multiple_alignment.StructureMultiple.from_pdb_files( pdb_files, multiple_alignment.DEFAULT_SUPERPOSITION_PARAMETERS, output_folder=f"static/results_{app_helper.decompress_object(unique_id, suite)}", ) if len(msa_class.structures) > 2: pw_matrix = msa_class.make_pairwise_shape_matrix() sequence_alignment = msa_class.align( pw_matrix, gap_open_penalty=gap_open_dropdown, gap_extend_penalty=gap_extend_dropdown, ) else: sequence_alignment = msa_class.align( pw_matrix=None, gap_open_penalty=gap_open_dropdown, gap_extend_penalty=gap_extend_dropdown, ) msa_class.superpose() fasta = app_helper.to_fasta_str(sequence_alignment) dssp_dir = msa_class.output_folder / ".caretta_tmp" if not dssp_dir.exists(): dssp_dir.mkdir() features = msa_class.get_aligned_features(dssp_dir, num_threads=4, only_dssp=False) caretta_class = app_helper.compress_object(msa_class, suite) sequence_alignment_data = app_helper.compress_object( sequence_alignment, suite ) feature_alignment_data = app_helper.compress_object(features, suite) sequence_alignment_component = dash_bio.AlignmentChart( id="sequence-alignment-graph", data=fasta, showconsensus=False, showconservation=False, overview=None, height=300, colorscale="hydrophobicity", ) structure_alignment_component = dcc.Graph( figure=app_helper.scatter3D( {s.name: s.coordinates for s in msa_class.structures} ), id="scatter-plot", ) feature_selection_dropdown = [{"label": x, "value": x} for x in features] loading_indicator_output = "" return ( caretta_class, sequence_alignment_data, feature_alignment_data, sequence_alignment_component, structure_alignment_component, feature_selection_dropdown, loading_indicator_output, ) else: return ( app_helper.empty_object(suite), app_helper.empty_object(suite), app_helper.empty_object(suite), "", "", [{"label": "no alignment present", "value": "no alignment"}], "", )
def update_interactive_panels( scatter_plot_clickdata, feature_line_clickdata, feature_line_graph, scatter_plot, structure_alignment_selected_residue, feature_alignment_selected_residue, sequence_alignment_data, ): if feature_line_graph and scatter_plot: changed = None clickdata = None if ( feature_line_clickdata and app_helper.compress_object( ( feature_line_clickdata["points"][0]["pointNumber"], feature_line_clickdata["points"][0]["curveNumber"], ), suite, ) != feature_alignment_selected_residue ): clickdata = feature_line_clickdata changed = "feature-panel" elif ( scatter_plot_clickdata and app_helper.compress_object( ( scatter_plot_clickdata["points"][0]["pointNumber"], scatter_plot_clickdata["points"][0]["curveNumber"], ), suite, ) != structure_alignment_selected_residue ): clickdata = scatter_plot_clickdata changed = "structure-panel" if changed is not None and clickdata is not None: # Save new clicked index aln_index = clickdata["points"][0]["pointNumber"] protein_index = clickdata["points"][0]["curveNumber"] if changed == "feature-panel": feature_alignment_selected_residue = app_helper.compress_object( (aln_index, protein_index), suite ) elif changed == "structure-panel": structure_alignment_selected_residue = app_helper.compress_object( (aln_index, protein_index), suite ) sequence_alignment = app_helper.decompress_object( sequence_alignment_data, suite ) number_of_structures = len(sequence_alignment) try: maxim, minim = ( np.max(feature_line_graph["data"][0]["y"]), np.min(feature_line_graph["data"][0]["y"]), ) except KeyError: return ( structure_alignment_selected_residue, feature_alignment_selected_residue, feature_line_graph, scatter_plot, ) if len(feature_line_graph["data"]) > 2: feature_line_graph["data"] = feature_line_graph["data"][:-1] if len(scatter_plot["data"]) > number_of_structures: scatter_plot["data"] = scatter_plot["data"][:-1] if changed == "feature-panel": aln_positions = app_helper.aln_index_to_protein( aln_index, sequence_alignment ) feature_line_graph["data"] += [ dict( y=[minim, maxim], x=[aln_index, aln_index], type="scatter", mode="lines", name="selected residue", ) ] to_add = [] for i in range(len(scatter_plot["data"])): p = aln_positions[scatter_plot["data"][i]["name"]] if p is not None: x, y, z = ( scatter_plot["data"][i]["x"][p], scatter_plot["data"][i]["y"][p], scatter_plot["data"][i]["z"][p], ) to_add.append((x, y, z)) else: continue scatter_plot["data"] += [ dict( x=[x[0] for x in to_add], y=[y[1] for y in to_add], z=[z[2] for z in to_add], type="scatter3d", mode="markers", name="selected residues", ) ] elif changed == "structure-panel": aligned_sequence = list(sequence_alignment.values())[protein_index] aln_index = app_helper.protein_to_aln_index( aln_index, aligned_sequence ) x, y, z = ( clickdata["points"][0]["x"], clickdata["points"][0]["y"], clickdata["points"][0]["z"], ) feature_line_graph["data"] += [ dict( y=[minim, maxim], x=[aln_index, aln_index], type="scatter", mode="lines", name="selected_residue", ) ] scatter_plot["data"] += [ dict( y=[y], x=[x], z=[z], type="scatter3d", mode="markers", name="selected residue", ) ] return ( structure_alignment_selected_residue, feature_alignment_selected_residue, feature_line_graph, scatter_plot, )