|
#if HAVE_CONFIG_H |
|
# include <config.h> |
|
#endif |
|
#include <assert.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <errno.h> |
|
#include <math.h> |
|
|
|
#include "pdb.h" |
|
#include "freesasa_internal.h" |
|
#include "classifier.h" |
|
|
|
void |
|
freesasa_residue_rel_nodearea(freesasa_nodearea *rel, |
|
const freesasa_nodearea *abs, |
|
const freesasa_nodearea *ref) |
|
{ |
|
rel->total = 100. * abs->total / ref->total; |
|
rel->side_chain = 100. * abs->side_chain / ref->side_chain; |
|
rel->main_chain = 100. * abs->main_chain / ref->main_chain; |
|
rel->polar = 100. * abs->polar / ref->polar; |
|
rel->apolar = 100. * abs->apolar / ref->apolar; |
|
rel->name = abs->name; |
|
} |
|
|
|
static void |
|
rsa_print_header(FILE *output, |
|
const char *config_name, |
|
const char *protein_name, |
|
const char *chains, |
|
const freesasa_parameters *parameters, |
|
int options) |
|
{ |
|
freesasa_algorithm alg = parameters->alg; |
|
#ifdef PACKAGE_VERSION |
|
fprintf(output, "REM FreeSASA " PACKAGE_VERSION "\n"); |
|
#else |
|
fprintf(output, "REM FreeSASA\n"); |
|
#endif |
|
fprintf(output, "REM Absolute and relative SASAs for %s\n", protein_name); |
|
if (!(options & FREESASA_OUTPUT_SKIP_REL)) |
|
fprintf(output, "REM Atomic radii and reference values for relative SASA: %s\n", config_name); |
|
else |
|
fprintf(output, "REM No reference values available to calculate relative SASA\n"); |
|
fprintf(output, "REM Chains: %s\n", chains); |
|
fprintf(output, "REM Algorithm: %s\n", freesasa_alg_name(alg)); |
|
fprintf(output, "REM Probe-radius: %.2f\n", parameters->probe_radius); |
|
if (alg == FREESASA_LEE_RICHARDS) { |
|
fprintf(output, "REM Slices: %d\n", parameters->lee_richards_n_slices); |
|
} else if (alg == FREESASA_SHRAKE_RUPLEY) { |
|
fprintf(output, "REM Test-points: %d\n", parameters->shrake_rupley_n_points); |
|
} |
|
fprintf(output, "REM RES _ NUM All-atoms Total-Side Main-Chain Non-polar All polar\n"); |
|
fprintf(output, "REM ABS REL ABS REL ABS REL ABS REL ABS REL\n"); |
|
} |
|
|
|
static inline void |
|
rsa_print_abs_rel(FILE*output, |
|
double abs, |
|
double rel) |
|
{ |
|
fprintf(output, "%7.2f", abs); |
|
if (isfinite(rel)) fprintf(output, "%6.1f", rel); |
|
else fprintf(output, " N/A"); |
|
} |
|
|
|
static inline void |
|
rsa_print_abs_only(FILE *output, |
|
double abs) |
|
{ |
|
fprintf(output, "%7.2f", abs); |
|
fprintf(output, " N/A"); |
|
} |
|
|
|
static int |
|
rsa_print_residue(FILE *output, |
|
int iaa, |
|
const freesasa_nodearea *abs, |
|
const freesasa_nodearea *rel, |
|
freesasa_node *residue) |
|
{ |
|
const char *resi_str; |
|
char chain; |
|
|
|
resi_str = freesasa_node_residue_number(residue); |
|
chain = freesasa_node_name(freesasa_node_parent(residue))[0]; |
|
|
|
fprintf(output, "RES %s %c%s ", abs->name, chain, resi_str); |
|
if (rel->name != NULL) { |
|
rsa_print_abs_rel(output, abs->total, rel->total); |
|
rsa_print_abs_rel(output, abs->side_chain, rel->side_chain); |
|
rsa_print_abs_rel(output, abs->main_chain, rel->main_chain); |
|
rsa_print_abs_rel(output, abs->apolar, rel->apolar); |
|
rsa_print_abs_rel(output, abs->polar, rel->polar); |
|
} else { |
|
rsa_print_abs_only(output, abs->total); |
|
rsa_print_abs_only(output, abs->side_chain); |
|
rsa_print_abs_only(output, abs->main_chain); |
|
rsa_print_abs_only(output, abs->apolar); |
|
rsa_print_abs_only(output, abs->polar); |
|
} |
|
fprintf(output, "\n"); |
|
return FREESASA_SUCCESS; |
|
} |
|
|
|
int |
|
freesasa_write_rsa(FILE *output, |
|
freesasa_node *tree, |
|
int options) |
|
{ |
|
assert(output); |
|
assert(tree); |
|
|
|
freesasa_node *residue, *chain, *structure_node, |
|
*result_node = freesasa_node_children(tree); |
|
|
|
const freesasa_nodearea *abs, *reference; |
|
freesasa_nodearea rel; |
|
int res_index, chain_index; |
|
const freesasa_parameters *parameters; |
|
|
|
parameters = freesasa_node_result_parameters(result_node); |
|
structure_node = freesasa_node_children(result_node); |
|
chain = freesasa_node_children(structure_node); |
|
|
|
rsa_print_header(output, freesasa_node_classified_by(result_node), |
|
freesasa_node_name(result_node), freesasa_node_name(structure_node), parameters, options); |
|
|
|
res_index = chain_index = 0; |
|
while(chain) { |
|
residue = freesasa_node_children(chain); |
|
while (residue) { |
|
abs = freesasa_node_area(residue); |
|
reference = freesasa_node_residue_reference(residue); |
|
if (reference && !(options & FREESASA_OUTPUT_SKIP_REL)) { |
|
freesasa_residue_rel_nodearea(&rel, abs, reference); |
|
} else { |
|
rel = freesasa_nodearea_null; |
|
} |
|
rsa_print_residue(output, res_index, abs, &rel, residue); |
|
++res_index; |
|
residue = freesasa_node_next(residue); |
|
} |
|
chain = freesasa_node_next(chain); |
|
} |
|
|
|
fprintf(output, "END Absolute sums over single chains surface\n"); |
|
|
|
chain = freesasa_node_children(structure_node); |
|
chain_index = 0; |
|
while(chain) { |
|
const char *name = freesasa_node_name(chain); |
|
abs = freesasa_node_area(chain); |
|
|
|
fprintf(output,"CHAIN%3d %c %10.1f %10.1f %10.1f %10.1f %10.1f\n", |
|
chain_index+1, name[0], abs->total, abs->side_chain, |
|
abs->main_chain, abs->apolar, abs->polar); |
|
|
|
++chain_index; |
|
chain = freesasa_node_next(chain); |
|
} |
|
|
|
abs = freesasa_node_area(structure_node); |
|
fprintf(output, "END Absolute sums over all chains\n"); |
|
fprintf(output,"TOTAL %10.1f %10.1f %10.1f %10.1f %10.1f\n", |
|
abs->total, abs->side_chain, abs->main_chain, abs->apolar, abs->polar); |
|
|
|
fflush(output); |
|
if (ferror(output)) { |
|
return fail_msg(strerror(errno)); |
|
} |
|
|
|
return FREESASA_SUCCESS; |
|
} |
|
|