Ejemplo n.º 1
0
static coord_t *
test_points(int N) 
{
    // Golden section spiral on a sphere
    // from http://web.archive.org/web/20120421191837/http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere
    double dlong = M_PI*(3-sqrt(5)), dz = 2.0/N, longitude = 0, z = 1-dz/2, r;
    coord_t *coord = freesasa_coord_new();
    double *tp = malloc(3*N*sizeof(double));
    if (tp == NULL || coord == NULL) {
        freesasa_coord_free(coord);
        free(tp);
        mem_fail();
        return NULL;
    }

    for (double *p = tp; p-tp < 3*N; p += 3) {
        r = sqrt(1-z*z);
        p[0] = cos(longitude)*r;
        p[1] = sin(longitude)*r;
        p[2] = z;
        z -= dz;
        longitude += dlong;
    }

    if (freesasa_coord_append(coord,tp,N) == FREESASA_FAIL) {
        fail_msg("");
        freesasa_coord_free(coord);
        coord = NULL;
    }
    free(tp);

    return coord;
}
Ejemplo n.º 2
0
// free contents
void
release_sr(sr_data sr) 
{
    freesasa_coord_free(sr.srp);
    freesasa_nb_free(sr.nb);
    free(sr.r);
    free(sr.r2);
}
Ejemplo n.º 3
0
// free contents
void
release_sr(sr_data *sr)
{
    freesasa_coord_free(sr->srp);
    freesasa_nb_free(sr->nb);
    free(sr->r);
    free(sr->r2);
}
Ejemplo n.º 4
0
int
init_sr(sr_data* sr_p,
        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_data sr = {.n_atoms = n_atoms, .n_points = n_points,
                  .probe_radius = probe_radius,
                  .xyz = xyz, .srp = srp,
                  .sasa = sasa};

    sr.r = malloc(sizeof(double)*n_atoms);
    sr.r2 = malloc(sizeof(double)*n_atoms);
    if (sr.r == NULL || sr.r2 == NULL) {
        freesasa_coord_free(srp);
        free(sr.r);
        free(sr.r2);
        return mem_fail();
    }
    
    for (int i = 0; i < n_atoms; ++i) {
        sr.r[i] = r[i] + probe_radius;
        sr.r2[i] = sr.r[i]*sr.r[i];
    }

    //calculate distances
    sr.nb = freesasa_nb_new(xyz,sr.r);
    if (sr.nb == NULL) {
        freesasa_coord_free(srp);
        free(sr.r);
        free(sr.r2);
        return mem_fail();
    }
    *sr_p = sr;
    return FREESASA_SUCCESS;
}
Ejemplo n.º 5
0
static double
sr_atom_area(int i,
             const sr_data sr)
{
    const int n_points = sr.n_points;
    /* this array keeps track of which testpoints belonging to
       a certain atom do not overlap with any other atoms */
    int spcount[n_points];
    const int nni = sr.nb->nn[i];
    const int * restrict nbi = sr.nb->nb[i];
    const double ri = sr.r[i];
    const double * restrict r2 = sr.r2;
    const double * restrict v = freesasa_coord_all(sr.xyz);
    const double * restrict vi = v+3*i;
    const double * restrict tp;
    int n_surface = 0, current_nb, a;
    double dx, dy, dz;
    /* testpoints for this atom */
    coord_t * restrict tp_coord_ri = freesasa_coord_copy(sr.srp);

    freesasa_coord_scale(tp_coord_ri, ri);
    freesasa_coord_translate(tp_coord_ri, vi);
    tp = freesasa_coord_all(tp_coord_ri);

    // initialize with all surface points hidden
    memset(spcount,0,n_points*sizeof(int));

    /* Using the trick from NSOL to check points one by one for all
       atoms, start comparing with the first neighbor. If there is no
       overlap for a given test-point, try with other neighbors
       instead. Would probably work even better if test points were
       organized in patches and not spirals. */
    current_nb = 0;
    for (int j = 0; j < n_points; ++j) {
        //a is the index of the atom under consideration
        a = nbi[current_nb];
        dx = tp[j*3]   - v[a*3];
        dy = tp[j*3+1] - v[a*3+1];
        dz = tp[j*3+2] - v[a*3+2];
        if (dx*dx + dy*dy + dz*dz > r2[a]) {
            int k = 0;
            for (; k < nni; ++k) {
                a = nbi[k];
                dx = tp[j*3]   - v[a*3];
                dy = tp[j*3+1] - v[a*3+1];
                dz = tp[j*3+2] - v[a*3+2];
                if (dx*dx + dy*dy + dz*dz <= r2[a]) {
                    current_nb = k;
                    break;
                }
            }
            // we have gone through the whole list without overlap
            if (k == nni) spcount[j] = 1;
        }
    }
    for (int k = 0; k < n_points; ++k) {
        if (spcount[k]) ++n_surface;
    }
    freesasa_coord_free(tp_coord_ri);
    return (4.0*M_PI*ri*ri*n_surface)/n_points;
}