int freesasa_shrake_rupley(double *sasa, const coord_t *xyz, const double *r, const freesasa_parameters *param) { assert(sasa); assert(xyz); assert(r); if (param == NULL) param = &freesasa_default_parameters; int n_atoms = freesasa_coord_n(xyz), n_threads = param->n_threads, resolution = param->shrake_rupley_n_points, return_value = FREESASA_SUCCESS; double probe_radius = param->probe_radius; sr_data sr; if (resolution <= 0) return freesasa_fail("in %s(): n_slices_per_atom = %f is invalid, must be > 0\n", __func__, resolution); if (n_atoms == 0) return freesasa_warn("%s(): empty coordinates", __func__); if (n_threads > n_atoms) { n_threads = n_atoms; freesasa_warn("No sense in having more threads than atoms, only using %d threads.", n_threads); } if (init_sr(&sr, sasa, xyz, r, probe_radius, resolution)) return FREESASA_FAIL; //calculate SASA if (n_threads > 1) { #if USE_THREADS return_value = sr_do_threads(n_threads, &sr); #else return_value = freesasa_warn("%s: program compiled for single-threaded use, " "but multiple threads were requested. Will " "proceed in single-threaded mode.\n", __func__); n_threads = 1; #endif } if (n_threads == 1) { // don't want the overhead of generating threads if only one is used for (int i = 0; i < n_atoms; ++i) { sasa[i] = sr_atom_area(i, &sr); } } release_sr(&sr); return return_value; }
int init_sr(sr_data *sr, double *sasa, const coord_t *xyz, const double *r, double probe_radius, int n_points) { int n_atoms = freesasa_coord_n(xyz); coord_t *srp = test_points(n_points); if (srp == NULL) return fail_msg("Failed to initialize test points."); //store parameters and reference arrays sr->n_atoms = n_atoms; sr->n_points = n_points; sr->probe_radius = probe_radius; sr->xyz = xyz; sr->srp = srp; sr->sasa = sasa; sr->nb = NULL; sr->r = malloc(sizeof(double)*n_atoms); sr->r2 = malloc(sizeof(double)*n_atoms); if (sr->r == NULL || sr->r2 == NULL) goto cleanup; for (int i = 0; i < n_atoms; ++i) { double ri = r[i] + probe_radius; sr->r[i] = ri; sr->r2[i] = ri * ri; } //calculate distances sr->nb = freesasa_nb_new(xyz, sr->r); if (sr->nb == NULL) goto cleanup; return FREESASA_SUCCESS; cleanup: release_sr(sr); return mem_fail(); }
int freesasa_shrake_rupley(double *sasa, const coord_t *xyz, const double *r, double probe_radius, int n_points, int n_threads) { assert(sasa); assert(xyz); assert(r); assert(n_threads > 0); int n_atoms = freesasa_coord_n(xyz); int return_value = FREESASA_SUCCESS; sr_data sr; if (n_atoms == 0) return freesasa_warn("%s(): empty coordinates", __func__); if (init_sr(&sr,sasa,xyz,r,probe_radius,n_points)) return mem_fail(); //calculate SASA if (n_threads > 1) { #if USE_THREADS sr_do_threads(n_threads, sr); #else return_value = freesasa_warn("%s: program compiled for single-threaded use, " "but multiple threads were requested. Will " "proceed in single-threaded mode.\n", __func__); n_threads = 1; #endif } if (n_threads == 1) { // don't want the overhead of generating threads if only one is used for (int i = 0; i < n_atoms; ++i) { sasa[i] = sr_atom_area(i,sr); } } release_sr(sr); return return_value; }