/** Read a line specifying an atom, store it in the config. Use supplied types to add assign radius and class. Returns FREESASA_WARN for duplicates. Returns FREESASA_FAIL for syntax errors or memory allocation errors. FREESASA_SUCCESS else. */ static int read_atoms_line(struct classifier_config *config, const struct classifier_types *types, const char* line) { size_t blen=100; char buf1[blen], buf2[blen], buf3[blen]; int res, type, atom; if (sscanf(line,"%s %s %s",buf1,buf2,buf3) == 3) { type = find_string(types->name, buf3, types->n_types); if (type < 0) return freesasa_fail("Unknown atom type '%s' in line '%s'",buf3,line); res = add_residue(config,buf1); if (res == FREESASA_FAIL) return fail_msg(""); atom = add_atom(config->residue[res], buf2, types->type_radius[type], types->type_class[type]); if (atom == FREESASA_FAIL) return fail_msg(""); if (atom == FREESASA_WARN) return FREESASA_WARN; } else { return freesasa_fail("in %s(): Could not parse line '%s', expecting triplet of type " "'RESIDUE ATOM CLASS', for example 'ALA CB C_ALI'.", __func__, line); } return FREESASA_SUCCESS; }
int freesasa_selection_parse_error(expression *e, yyscan_t scanner, const char *msg) { if (freesasa_get_verbosity() == FREESASA_V_DEBUG) print_expr(stderr, e, 0); if (freesasa_get_verbosity() == FREESASA_V_NORMAL) fprintf(stderr, "\n"); return freesasa_fail(msg); }
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; }
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; }
/** Read a line specifying a type, store it in the config. Returns warning for duplicates, failures for syntax errors or memory allocation errors. */ static int read_types_line(struct classifier_types *types, const char* line) { size_t blen=101; char buf1[blen], buf2[blen]; int the_type; double r; if (sscanf(line,"%s %lf %s",buf1,&r,buf2) == 3) { the_type = add_type(types, buf1, buf2, r); if (the_type == FREESASA_FAIL) return fail_msg(""); if (the_type == FREESASA_WARN) return FREESASA_WARN; } else { return freesasa_fail("in %s(): Could not parse line '%s', expecting triplet of type " "'TYPE [RADIUS] CLASS' for example 'C_ALI 2.00 apolar'", __func__, line); } return FREESASA_SUCCESS; }
//! check if array of strings has a string that matches key, ignores trailing and leading whitespace static int find_string(char **array, const char *key, int array_size) { assert(key); if (array == NULL || array_size == 0) return -1; int n = strlen(key); char key_trimmed[n+1]; // remove trailing and leading whitespace sscanf(key,"%s",key_trimmed); for (int i = 0; i < array_size; ++i) { if (array[i] == NULL) {freesasa_fail("%d %d %s %s",i,array_size,key,key_trimmed);} assert(array[i]); if (strcmp(array[i],key_trimmed) == 0) return i; } return FREESASA_FAIL; }
/** Checks that input file has the required fields and locates the 'types' and 'atoms' sections. No syntax checking. Return FREESASA_SUCCESS if file seems ok, FREESASA_FILE if either/both of the sections are missing. */ static int check_file(FILE *input, struct file_range *types, struct file_range *atoms) { assert(input); assert(types); assert(atoms); long last_tell; char buf[200]; struct file_range *last_range = NULL; last_tell = ftell(input); types->begin = atoms->begin = -1; while (fscanf(input,"%s",buf) > 0) { if (strcmp(buf,"types:") == 0) { types->begin = last_tell; if (last_range) last_range->end = last_tell; last_range = types; } if (strcmp(buf,"atoms:") == 0) { atoms->begin = last_tell; if (last_range) last_range->end = last_tell; last_range = atoms; } last_tell = ftell(input); } if (last_range != NULL) { last_range->end = last_tell; } rewind(input); if ((types->begin == -1) || (atoms->begin == -1)) { return freesasa_fail("in %s(): Input configuration lacks (at least) one of " "the entries 'types:' or " "'atoms:'.", __func__); } return FREESASA_SUCCESS; }