Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
static int
select_range(expression_type range_type,
             expression_type parent_type,
             struct selection *selection,
             const freesasa_structure *structure,
             const expression *left,
             const expression *right)
{
    int lower, upper, i, j;

    assert(range_type == E_RANGE || range_type == E_RANGE_OPEN_L || range_type == E_RANGE_OPEN_R);
    assert(parent_type == E_RESI || parent_type == E_CHAIN);

    if (parent_type == E_RESI) { /* residues have integer numbering */
        if (( left &&  left->type != E_NUMBER) ||
            (right && right->type != E_NUMBER)) {
            return freesasa_warn("select: %s: range '%s-%s' invalid, needs to be two numbers, "
                                 "will be ignored",e_str(parent_type), left->value, right->value);
        }
    } else { /* chains can be numbered by both letters (common) and numbers (uncommon) */
        if (left->type != right->type ||
            (left->type == E_ID && (strlen(left->value) > 1 || strlen(right->value) > 1)))
            return freesasa_warn("select: %s: range '%s-%s' invalid, should be two letters (A-C) or numbers (1-5), "
                                 "will be ignored", e_str(parent_type), left->value, right->value);
    }
    if (range_type == E_RANGE_OPEN_L) {
        lower = atoi(freesasa_structure_atom_res_number(structure, 0));
        upper = atoi(right->value);
    } else if (range_type == E_RANGE_OPEN_R) {
        lower = atoi(left->value);
        upper = atoi(freesasa_structure_atom_res_number(structure, freesasa_structure_n(structure) - 1));
    } else if (left->type == E_NUMBER) {
        lower = atoi(left->value);
        upper = atoi(right->value);
    } else {
        lower = (int)left->value[0];
        upper = (int)right->value[0];
    }
    for (i = 0; i < selection->size; ++i) {
        if (parent_type == E_RESI) j = atoi(freesasa_structure_atom_res_number(structure,i));
        else j = (int)freesasa_structure_atom_chain(structure,i);
        if (j >= lower && j <= upper)
            selection->atom[i] = 1;
    }
    return FREESASA_SUCCESS;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
static int
select_list(expression_type parent_type,
            struct selection *selection,
            const freesasa_structure *structure,
            const expression *expr)
{
    int resr, resl;
    expression *left, *right;

    if (expr == NULL)
        return fail_msg("NULL expression");

    left = expr->left;
    right = expr->right;

    switch(expr->type) {
    case E_PLUS:
        if (left == NULL || right == NULL)
            return fail_msg("NULL expression");
        resl = select_list(parent_type, selection, structure, left);
        resr = select_list(parent_type, selection, structure, right);
        if (resl == FREESASA_WARN || resr == FREESASA_WARN)
            return FREESASA_WARN;
        break;
    case E_RANGE:
        if (left == NULL || right == NULL)
            return fail_msg("NULL expression");
        return select_range(E_RANGE, parent_type, selection, structure, left, right);
    case E_RANGE_OPEN_L:
        if (left != NULL || right == NULL)
            return fail_msg("NULL expression");
        return select_range(E_RANGE_OPEN_L, parent_type, selection, structure, left, right);
    case E_RANGE_OPEN_R:
        if (left == NULL || right != NULL)
            return fail_msg("NULL expression");
        return select_range(E_RANGE_OPEN_R, parent_type, selection, structure, left, right);
    case E_ID:
    case E_NUMBER:
        if (is_valid_id(parent_type, expr) == FREESASA_SUCCESS)
            select_id(parent_type, selection, structure, expr->value);
        else return freesasa_warn("select: %s: '%s' invalid %s",
                                  e_str(parent_type), expr->value, e_str(expr->type));
        break;
    default:
        return freesasa_fail("select: parse error (expression: '%s %s')",
                             e_str(parent_type), e_str(expr->type));
    }
    return FREESASA_SUCCESS;
}
Ejemplo n.º 5
0
/**
    Add type. Returns the index of the new type on success,
    FREESASA_FAIL if realloc/strdup fails, FREESASA_WARN if type
    already known (ignore duplicates).
 */
static int
add_type(struct classifier_types *types,
         const char *type_name,
         const char *class_name, 
         double r)
{
    int the_class, n = types->n_types + 1;
    char **tn = types->name;
    double *tr = types->type_radius;
    int *tc = types->type_class;
    
    if (find_string(types->name, type_name, types->n_types) >= 0)
        return freesasa_warn("Ignoring duplicate entry for '%s'.", type_name);
    
    the_class = add_class(types,class_name);
    if (the_class == FREESASA_FAIL) {
        return mem_fail();
    }
    
    if ((types->name = realloc(tn, sizeof(char*)*n)) == NULL) {
        types->name = tn;
        return mem_fail();
    }
    
    if ((types->type_radius = realloc(tr, sizeof(double)*n)) == NULL) {
        types->type_radius = tr;
        return mem_fail();
    }
    
    if ((types->type_class = realloc(tc, sizeof(int) * n)) == NULL) {
        types->type_class = tc;
        return mem_fail();
    }
    
    if ((types->name[n-1] = strdup(type_name)) == NULL) {
        return mem_fail();
    }
        
    types->n_types++;
    types->type_radius[types->n_types-1] = r;
    types->type_class[types->n_types-1] = the_class;
    return types->n_types-1;
}
Ejemplo n.º 6
0
static void
select_id(expression_type parent_type,
          struct selection *selection,
          const freesasa_structure *structure,
          const char *id)
{
    int count = 0, match, i;

    assert(id);

    for (i = 0; i < selection->size; ++i) {
        match = 0;
        switch(parent_type) {
        case E_NAME:
            match = match_name(structure, id, i);
            break;
        case E_SYMBOL:
            match = match_symbol(structure, id, i);
            break;
        case E_RESN:
            match = match_resn(structure, id, i);
            break;
        case E_RESI:
            match = match_resi(structure, id, i);
            break;
        case E_CHAIN:
            match = match_chain(structure, id, i);
            break;
        default:
            assert(0);
            break;
        }
        if (match) selection->atom[i] = 1;
        count += match;
    }
    if (count == 0) freesasa_warn("Found no matches to %s '%s', typo?",
                                  e_str(parent_type),id);
}
Ejemplo n.º 7
0
/**
    Add atom to residue. Returns index of the new atom on
    success. FREESASA_FAIL if memory allocation fails. FREESASA_WARN
    if the atom has already been added.
 */
static int
add_atom(struct classifier_residue *res,
         const char *name,
         double radius,
         int the_class)
{
    int n;
    char **an = res->atom_name;
    double *ar = res->atom_radius;
    int *ac = res->atom_class;

    if (find_string(res->atom_name, name, res->n_atoms) >= 0)
        return freesasa_warn("in %s(): Ignoring duplicate entry for atom '%s %s'", 
                             __func__, res->name, name);
    n = res->n_atoms+1;

    if ((res->atom_name = realloc(res->atom_name,sizeof(char*)*n)) == NULL) {
        res->atom_name = an;
        return mem_fail();
    }
    if ((res->atom_radius = realloc(res->atom_radius,sizeof(double)*n)) == NULL) {
        res->atom_radius = ar;
        return mem_fail();
    }
    if ((res->atom_class = realloc(res->atom_class,sizeof(int)*n)) == NULL) {
        res->atom_class = ac;
        return mem_fail();
    }
    if ((res->atom_name[n-1] = strdup(name)) == NULL) 
        return mem_fail();

    ++res->n_atoms;
    res->atom_radius[n-1] = radius;
    res->atom_class[n-1] = the_class;

    return n-1;
}
Ejemplo n.º 8
0
static int
select_area_impl(const char *command,
                 char *name,
                 double *area,
                 const freesasa_structure *structure,
                 const freesasa_result *result)
{
    struct selection *selection = NULL;
    struct expression *expression = NULL;
    const int maxlen = FREESASA_MAX_SELECTION_NAME;
    double sasa = 0;
    int err = 0, warn = 0, n_atoms = 0, j, len;

    assert(name); assert(area);
    assert(command); assert(structure); assert(result);
    assert(freesasa_structure_n(structure) == result->n_atoms);

    *area = 0;
    name[0] = '\0';

    expression = get_expression(command);
    selection = selection_new(result->n_atoms);

    if (selection == NULL) {
        return fail_msg("");
    }

    if (expression != NULL && selection != NULL) {
        switch (select_atoms(selection, expression, structure)) {
        case FREESASA_FAIL:
            err = 1;
            break;
        case FREESASA_WARN:
            warn = 1; /* proceed with calculation, print warning later */
        case FREESASA_SUCCESS: {
            for (j = 0; j < selection->size; ++j) {
                ++n_atoms;
                sasa += selection->atom[j]*result->sasa[j];
            }

            *area = sasa;
            len = strlen(selection->name);
            if (len > maxlen) {
                strncpy(name,selection->name,maxlen);
                name[maxlen] = '\0';
            }
            else {
                strncpy(name,selection->name,len);
                name[len] = '\0';
            }

            break;
        }
        default:
            assert(0);
        }
    } else {
        err = 1;
    }
    selection_free(selection);
    expression_free(expression);

    if (err)
        return fail_msg("problems parsing expression '%s'",command);
    if (warn)
        return freesasa_warn("in %s(): There were warnings",__func__);
    return n_atoms;
}
Ejemplo n.º 9
0
static int
is_valid_id(int parent_type,
            const expression *expr)
{
    int type, n, warn, i;
    const char* val;

    assert(expr->type == E_NUMBER || expr->type == E_ID);

    type = expr->type;
    val = expr->value;

    switch(parent_type) {
    case E_NAME:
        if (strlen(val) > PDB_ATOM_NAME_STRL)
            return freesasa_warn("select: %s: atom name '%s' invalid (string too long), "
                                 "will be ignored", e_str(parent_type), val);
        break;
    case E_SYMBOL:
        if (type != E_ID)
            return freesasa_warn("select: %s: '%s' invalid (should be 1 or 2 letters, 'C', 'N', 'SE', etc), "
                                 "will be ignored", e_str(parent_type), val);
        if (strlen(val) > 2)
            return freesasa_warn("select: %s: '%s' invalid (element names have 1 or 2 characters), "
                                 "will be ignored", e_str(parent_type), val);
        break;
    case E_RESN:
        if (strlen(val) > PDB_ATOM_RES_NAME_STRL)
            return freesasa_warn("select: %s: '%s' invalid (string too long), "
                                 "will be ignored", e_str(parent_type), val);
        break;
    case E_RESI:
        if (type == E_ID) {
            /* these should have format 1, 2, 345, etc or 12A, 12B, etc. */
            n = strlen(val);
            if (n > PDB_ATOM_RES_NUMBER_STRL) {
                return freesasa_warn("select: %s: '%s' invalid (string too long), "
                                     "will be ignored", e_str(parent_type), val);
            } else {
                warn = 0;
                if (n == 1) ++warn;
                if (!warn && (toupper(val[n - 1]) < 'A' || toupper(val[n - 1]) > 'Z')) {
                    ++warn;
                }
                for (i = 0; !warn && i < n - 1; ++i) {
                    if (val[i] < '0' || val[i] > '9') {
                        ++warn;
                    }
                }
                if (warn) {
                    return freesasa_warn("select: %s: '%s' invalid, should either be "
                                         "number (1, 2, 3) or number with insertion code (1A, 1B, ...), "
                                         "will be ignored", e_str(parent_type), val);
                }
            }
        } else if (type != E_NUMBER) {
            return freesasa_warn("select: %s: '%s' invalid, will be ignored",
                                 e_str(parent_type), val);
        }
        break;
    case E_CHAIN:
        if (strlen(val) > 1)
            return freesasa_warn("select: %s: '%s' invalid (string too long), "
                                 "will be ignored", e_str(parent_type), val);
        break;
    default:
        assert(0);
        break;
    }
    return FREESASA_SUCCESS;
}