int main() { /* * default flags */ rbtree_t rbt; rbtree_create(&rbt, sizeof(int)); int n = 1; rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); print_rbt(rbt.root, 0); rbtree_destroy( &rbt ); /* * right leaning flag */ rbtree_create(&rbt, sizeof(int)); rbtree_set_flags(&rbt, rbt.flags & ~G_RB_LEFT_LEANING); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); print_rbt(rbt.root, 0); rbtree_destroy( &rbt ); /* * override flag */ rbtree_create(&rbt, sizeof(int)); rbtree_set_flags(&rbt, G_RB_EQUAL_OVERRIDE); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); rbtree_add(&rbt, &n); print_rbt(rbt.root, 0); rbtree_destroy( &rbt ); return 0; }
/* * 销毁红黑树 */ static void rbtree_destroy(RBTree tree) { if (tree==NULL) return ; if (tree->left != NULL) rbtree_destroy(tree->left); if (tree->right != NULL) rbtree_destroy(tree->right); free(tree); }
static void rbtree_destroy(struct rbtree_node_t* node) { struct rbitem_t* item; item = rbtree_entry(node, struct rbitem_t, link); if (node->left) rbtree_destroy(node->left); if (node->right) rbtree_destroy(node->right); node_release(item->node); free(item); }
void router_destroy(struct router_t* router) { if (router->rbtree.node) rbtree_destroy(router->rbtree.node); locker_destroy(&router->locker); free(router); }
void destroy_rbtree(RBRoot *root) { if (root != NULL) rbtree_destroy(root->node); free(root); }
/***************************************************************************** * Destroys a JSON reader. ****************************************************************************/ void jsonrd_destroy(JSONRD_T *jsonrd) { str_destroy(jsonrd->token.value_string, false); free(jsonrd->stack.states); str_destroy(jsonrd->buf, false); bmstr_destroy(jsonrd->landmark); rbtree_destroy(jsonrd->prior_states); memset(jsonrd, 0, sizeof(JSONRD_T)); free(jsonrd); }
/***************************************************************************** * Destroys the data used by the SAX parser ****************************************************************************/ void destroy_dreme_io_xml_sax_context(void *ctx) { PS_T *ps = (PS_T*)ctx; if (ps->motif_id) free(ps->motif_id); if (ps->freqs) free(ps->freqs); rbtree_destroy(ps->alph_ids); free(ps->characters.buffer); attrbuf_free(&(ps->attrbuf)); linklst_destroy_all(ps->expected_stack, free); free(ps); }
/***************************************************************************** * Destroy the parser along with any motifs which weren't retrieved. ****************************************************************************/ static void destroy_parser_data(CTX_T *data) { if (data->fscope.scanned_sites) { if (!(data->fscope.options_returned & SCANNED_SITES)) { arraylst_destroy(sseq_destroy, data->fscope.scanned_sites); } } if (data->fscope.background) { free_array(data->fscope.background); } if (data->fscope.release) { free(data->fscope.release); } if (data->sequence_lookup) rbtree_destroy(data->sequence_lookup); linklst_destroy_all(data->warnings, free); linklst_destroy_all(data->errors, free); linklst_destroy_all(data->motif_queue, destroy_motif); rbtree_destroy(data->letter_lookup); if (data->alph) alph_release(data->alph); if (data->alph_rdr) alph_reader_destroy(data->alph_rdr); memset(data, 0, sizeof(CTX_T)); free(data); }
/************************************************************************* * Entry point for ama *************************************************************************/ int main(int argc, char **argv) { AMA_OPTIONS_T options; ARRAYLST_T *motifs; clock_t c0, c1; // measuring cpu_time MOTIF_AND_PSSM_T *combo; CISML_T *cisml; PATTERN_T** patterns; PATTERN_T *pattern; FILE *fasta_file, *text_output, *cisml_output; int i, seq_loading_num, seq_counter, unique_seqs, seq_len, scan_len, x1, x2, y1, y2; char *seq_name, *path; bool need_postprocessing, created; SEQ_T *sequence; RBTREE_T *seq_ids; RBNODE_T *seq_node; double *logcumback; ALPH_T *alph; // process the command process_command_line(argc, argv, &options); // load DNA motifs motifs = load_motifs(&options); // get the alphabet if (arraylst_size(motifs) > 0) { combo = (MOTIF_AND_PSSM_T*)arraylst_get(0, motifs); alph = alph_hold(get_motif_alph(combo->motif)); } else { alph = alph_dna(); } // pick columns for GC operations x1 = -1; x2 = -1; y1 = -1; y2 = -1; if (alph_size_core(alph) == 4 && alph_size_pairs(alph) == 2) { x1 = 0; // A x2 = alph_complement(alph, x1); // T y1 = (x2 == 1 ? 2 : 1); // C y2 = alph_complement(alph, y1); // G assert(x1 != x2 && y1 != y2 && x1 != y1 && x2 != y2 && x1 != y2 && x2 != y1); } // record starting time c0 = clock(); // Create cisml data structure for recording results cisml = allocate_cisml(PROGRAM_NAME, options.command_line, options.motif_filename, options.fasta_filename); set_cisml_background_file(cisml, options.bg_filename); // make a CISML pattern to hold scores for each motif for (i = 0; i < arraylst_size(motifs); i++) { combo = (MOTIF_AND_PSSM_T*)arraylst_get(i, motifs); add_cisml_pattern(cisml, allocate_pattern(get_motif_id(combo->motif), "")); } // Open the FASTA file for reading. fasta_file = NULL; if (!open_file(options.fasta_filename, "r", false, "FASTA", "sequences", &fasta_file)) { die("Couldn't open the file %s.\n", options.fasta_filename); } if (verbosity >= NORMAL_VERBOSE) { if (options.last == 0) { fprintf(stderr, "Using entire sequence\n"); } else { fprintf(stderr, "Limiting sequence to last %d positions.\n", options.last); } } // // Read in all sequences and score with all motifs // seq_loading_num = 0; // keeps track on the number of sequences read in total seq_counter = 0; // holds the index to the seq in the pattern unique_seqs = 0; // keeps track on the number of unique sequences need_postprocessing = false; sequence = NULL; logcumback = NULL; seq_ids = rbtree_create(rbtree_strcasecmp,rbtree_strcpy,free,rbtree_intcpy,free); while (read_one_fasta(alph, fasta_file, options.max_seq_length, &sequence)) { ++seq_loading_num; seq_name = get_seq_name(sequence); seq_len = get_seq_length(sequence); scan_len = (options.last != 0 ? options.last : seq_len); // red-black trees are only required if duplicates should be combined if (options.combine_duplicates){ //lookup seq id and create new entry if required, return sequence index seq_node = rbtree_lookup(seq_ids, get_seq_name(sequence), true, &created); if (created) { // assign it a loading number rbtree_set(seq_ids, seq_node, &unique_seqs); seq_counter = unique_seqs; ++unique_seqs; } else { seq_counter = *((int*)rbnode_get(seq_node)); } } // // Set up sequence-dependent background model and compute // log cumulative probability of sequence. // This needs the sequence in raw format. // if (options.sdbg_order >= 0) logcumback = log_cumulative_background(alph, options.sdbg_order, sequence); // Index the sequence, throwing away the raw format and ambiguous characters index_sequence(sequence, alph, SEQ_NOAMBIG); // Get the GC content of the sequence if binning p-values by GC // and store it in the sequence object. if (options.num_gc_bins > 1) { ARRAY_T *freqs = get_sequence_freqs(sequence, alph); set_total_gc_sequence(sequence, get_array_item(y1, freqs) + get_array_item(y2, freqs)); // f(C) + f(G) free_array(freqs); // clean up } else { set_total_gc_sequence(sequence, -1); // flag ignore } // Scan with motifs. for (i = 0; i < arraylst_size(motifs); i++) { pattern = get_cisml_patterns(cisml)[i]; combo = (MOTIF_AND_PSSM_T*)arraylst_get(i, motifs); if (verbosity >= HIGHER_VERBOSE) { fprintf(stderr, "Scanning %s sequence with length %d " "abbreviated to %d with motif %s with length %d.\n", seq_name, seq_len, scan_len, get_motif_id(combo->motif), get_motif_length(combo->motif)); } SCANNED_SEQUENCE_T* scanned_seq = NULL; if (!options.combine_duplicates || get_pattern_num_scanned_sequences(pattern) <= seq_counter) { // Create a scanned_sequence record and save it in the pattern. scanned_seq = allocate_scanned_sequence(seq_name, seq_name, pattern); set_scanned_sequence_length(scanned_seq, scan_len); } else { // get existing sequence record scanned_seq = get_pattern_scanned_sequences(pattern)[seq_counter]; set_scanned_sequence_length(scanned_seq, max(scan_len, get_scanned_sequence_length(scanned_seq))); } // check if scanned component of sequence has sufficient length for the motif if (scan_len < get_motif_length(combo->motif)) { // set score to zero and p-value to 1 if not set yet if(!has_scanned_sequence_score(scanned_seq)){ set_scanned_sequence_score(scanned_seq, 0.0); } if(options.pvalues && !has_scanned_sequence_pvalue(scanned_seq)){ set_scanned_sequence_pvalue(scanned_seq, 1.0); } add_scanned_sequence_scanned_position(scanned_seq); if (get_scanned_sequence_num_scanned_positions(scanned_seq) > 0L) { need_postprocessing = true; } if (verbosity >= HIGH_VERBOSE) { fprintf(stderr, "%s too short for motif %s. Score set to 0.\n", seq_name, get_motif_id(combo->motif)); } } else { // scan the sequence using average/maximum motif affinity ama_sequence_scan(alph, sequence, logcumback, combo->pssm_pair, options.scoring, options.pvalues, options.last, scanned_seq, &need_postprocessing); } } // All motifs scanned free_seq(sequence); if (options.sdbg_order >= 0) myfree(logcumback); } // read sequences fclose(fasta_file); if (verbosity >= HIGH_VERBOSE) fprintf(stderr, "(%d) sequences read in.\n", seq_loading_num); if (verbosity >= NORMAL_VERBOSE) fprintf(stderr, "Finished \n"); // if any sequence identifier was multiple times in the sequence set then // postprocess of the data is required if (need_postprocessing || options.normalize_scores) { post_process(cisml, motifs, options.normalize_scores); } // output results if (options.output_format == DIRECTORY_FORMAT) { if (create_output_directory(options.out_dir, options.clobber, verbosity > QUIET_VERBOSE)) { // only warn in higher verbose modes fprintf(stderr, "failed to create output directory `%s' or already exists\n", options.out_dir); exit(1); } path = make_path_to_file(options.out_dir, text_filename); //FIXME check for errors: MEME doesn't either and we at least know we have a good directory text_output = fopen(path, "w"); free(path); path = make_path_to_file(options.out_dir, cisml_filename); //FIXME check for errors cisml_output = fopen(path, "w"); free(path); print_cisml(cisml_output, cisml, true, NULL, false); print_score(cisml, text_output); fclose(cisml_output); fclose(text_output); } else if (options.output_format == GFF_FORMAT) { print_score(cisml, stdout); } else if (options.output_format == CISML_FORMAT) { print_cisml(stdout, cisml, true, NULL, false); } else { die("Output format invalid!\n"); } // // Clean up. // rbtree_destroy(seq_ids); arraylst_destroy(motif_and_pssm_destroy, motifs); free_cisml(cisml); rbtree_destroy(options.selected_motifs); alph_release(alph); // measure time if (verbosity >= NORMAL_VERBOSE) { // starting time c1 = clock(); fprintf(stderr, "cycles (CPU); %ld cycles\n", (long) c1); fprintf(stderr, "elapsed CPU time: %f seconds\n", (float) (c1-c0) / CLOCKS_PER_SEC); } return 0; }
static int check_reg_size(struct globals *globals, int minsize, int row, int col) { int rown, coln, n; int neighbors[8][2]; int this_id; int ngbr_id; LARGEINT reg_size; struct RB_TREE *visited; struct rc next, ngbr_rc; struct rclist rilist; int no_check; if (!(FLAG_GET(globals->candidate_flag, row, col))) return minsize; FLAG_UNSET(globals->candidate_flag, row, col); visited = rbtree_create(cmp_rc, sizeof(struct rc)); ngbr_rc.row = row; ngbr_rc.col = col; rbtree_insert(visited, &ngbr_rc); /* get this ID */ Segment_get(&globals->rid_seg, (void *) &this_id, row, col); /* breadth-first search */ next.row = row; next.col = col; rclist_init(&rilist); reg_size = 1; do { globals->find_neighbors(next.row, next.col, neighbors); n = globals->nn - 1; do { rown = neighbors[n][0]; coln = neighbors[n][1]; no_check = 0; if (rown < globals->row_min || rown >= globals->row_max || coln < globals->col_min || coln >= globals->col_max) no_check = 1; if (!no_check && (FLAG_GET(globals->null_flag, rown, coln))) no_check = 1; ngbr_rc.row = rown; ngbr_rc.col = coln; if (!no_check && !rbtree_find(visited, &ngbr_rc)) { rbtree_insert(visited, &ngbr_rc); /* get neighbour ID */ Segment_get(&globals->rid_seg, (void *) &ngbr_id, rown, coln); /* same neighbour */ if (ngbr_id == this_id) { reg_size++; rclist_add(&rilist, rown, coln); FLAG_UNSET(globals->candidate_flag, rown, coln); } } } while (n--); /* end do loop - next neighbor */ } while (rclist_drop(&rilist, &next)); /* while there are cells to check */ rclist_destroy(&rilist); rbtree_destroy(visited); return reg_size; }
static int find_best_neighbour(struct globals *globals, int row, int col, int this_id, struct NB_TREE *nbtree, int *reg_size, struct ngbr_stats **Rbest, int *best_n_row, int *best_n_col) { int rown, coln, n, count; int neighbors[8][2]; struct rc next, ngbr_rc; struct rclist rilist; int no_check; int ngbr_id; struct RB_TREE *visited; struct ngbr_stats Ri, Rk, *Rfound; double sim, best_sim; int best_n_id; int have_Ri; Ri.mean = G_malloc(globals->datasize); Rk.mean = G_malloc(globals->datasize); nbtree_clear(nbtree); FLAG_UNSET(globals->candidate_flag, row, col); visited = rbtree_create(cmp_rc, sizeof(struct rc)); ngbr_rc.row = row; ngbr_rc.col = col; rbtree_insert(visited, &ngbr_rc); /* breadth-first search */ next.row = row; next.col = col; rclist_init(&rilist); count = 1; best_n_id = -1; best_sim = 2; do { have_Ri = 0; globals->find_neighbors(next.row, next.col, neighbors); n = globals->nn - 1; do { rown = neighbors[n][0]; coln = neighbors[n][1]; no_check = 0; if (rown < globals->row_min || rown >= globals->row_max || coln < globals->col_min || coln >= globals->col_max) no_check = 1; if (!no_check && (FLAG_GET(globals->null_flag, rown, coln))) no_check = 1; ngbr_rc.row = rown; ngbr_rc.col = coln; if (!no_check && !rbtree_find(visited, &ngbr_rc)) { rbtree_insert(visited, &ngbr_rc); /* get neighbor ID */ Segment_get(&globals->rid_seg, (void *) &ngbr_id, rown, coln); /* same neighbour */ if (ngbr_id == this_id) { count++; rclist_add(&rilist, rown, coln); FLAG_UNSET(globals->candidate_flag, rown, coln); } else { /* different neighbour */ /* compare to this cell next.row, next.col */ if (!have_Ri) { Segment_get(globals->bands_out, (void *) Ri.mean, next.row, next.col); have_Ri = 1; } Segment_get(globals->bands_out, (void *) Rk.mean, rown, coln); sim = globals->calculate_similarity(&Ri, &Rk, globals); if (best_sim > sim) { best_sim = sim; best_n_id = ngbr_id; *best_n_row = rown; *best_n_col = coln; } /* find in neighbor tree */ Rk.id = ngbr_id; if ((Rfound = nbtree_find(nbtree, &Rk))) { Rfound->count++; if (*Rbest && (*Rbest)->count < Rfound->count) *Rbest = Rfound; } else { Rk.count = 1; Rk.row = rown; Rk.col = coln; nbtree_insert(nbtree, &Rk); if (!(*Rbest)) *Rbest = nbtree_find(nbtree, &Rk); } } } } while (n--); /* end do loop - next neighbor */ } while (rclist_drop(&rilist, &next)); /* while there are cells to check */ rclist_destroy(&rilist); rbtree_destroy(visited); G_free(Ri.mean); G_free(Rk.mean); *reg_size = count; return best_n_id; }
/* break polygons using a memory-based search index */ void Vect_break_polygons_mem(struct Map_info *Map, int type, struct Map_info *Err) { struct line_pnts *BPoints, *Points; struct line_cats *Cats, *ErrCats; int i, j, k, ret, ltype, broken, last, nlines; int nbreaks; struct RB_TREE *RBTree; int npoints, nallpoints, nmarks; XPNT *XPnt_found, XPnt_search; double dx, dy, a1 = 0, a2 = 0; int closed, last_point, cross; G_debug(1, "Memory-based version of Vect_break_polygons()"); RBTree = rbtree_create(compare_xpnts, sizeof(XPNT)); BPoints = Vect_new_line_struct(); Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); ErrCats = Vect_new_cats_struct(); nlines = Vect_get_num_lines(Map); G_debug(3, "nlines = %d", nlines); /* Go through all lines in vector, and add each point to structure of points, * if such point already exists check angles of segments and if differ mark for break */ nmarks = 0; npoints = 0; nallpoints = 0; XPnt_search.used = 0; G_message(_("Breaking polygons (pass 1: select break points)...")); for (i = 1; i <= nlines; i++) { G_percent(i, nlines, 1); G_debug(3, "i = %d", i); if (!Vect_line_alive(Map, i)) continue; ltype = Vect_read_line(Map, Points, Cats, i); if (!(ltype & type)) continue; /* This would be confused by duplicate coordinates (angle cannot be calculated) -> * prune line first */ Vect_line_prune(Points); /* If first and last point are identical it is close polygon, we don't need to register last point * and we can calculate angle for first. * If first and last point are not identical we have to mark for break both */ last_point = Points->n_points - 1; if (Points->x[0] == Points->x[last_point] && Points->y[0] == Points->y[last_point]) closed = 1; else closed = 0; for (j = 0; j < Points->n_points; j++) { G_debug(3, "j = %d", j); nallpoints++; if (j == last_point && closed) continue; /* do not register last of close polygon */ XPnt_search.x = Points->x[j]; XPnt_search.y = Points->y[j]; /* Already in DB? */ XPnt_found = rbtree_find(RBTree, &XPnt_search); if (Points->n_points <= 2 || (!closed && (j == 0 || j == last_point))) { cross = 1; /* mark for cross in any case */ } else { /* calculate angles */ cross = 0; if (j == 0 && closed) { /* closed polygon */ dx = Points->x[last_point] - Points->x[0]; dy = Points->y[last_point] - Points->y[0]; a1 = atan2(dy, dx); dx = Points->x[1] - Points->x[0]; dy = Points->y[1] - Points->y[0]; a2 = atan2(dy, dx); } else { dx = Points->x[j - 1] - Points->x[j]; dy = Points->y[j - 1] - Points->y[j]; a1 = atan2(dy, dx); dx = Points->x[j + 1] - Points->x[j]; dy = Points->y[j + 1] - Points->y[j]; a2 = atan2(dy, dx); } } if (XPnt_found) { /* found */ if (XPnt_found->cross == 1) continue; /* already marked */ /* check angles */ if (cross) { XPnt_found->cross = 1; nmarks++; } else { G_debug(3, "a1 = %f xa1 = %f a2 = %f xa2 = %f", a1, XPnt_found->a1, a2, XPnt_found->a2); if ((a1 == XPnt_found->a1 && a2 == XPnt_found->a2) || (a1 == XPnt_found->a2 && a2 == XPnt_found->a1)) { /* identical */ } else { XPnt_found->cross = 1; nmarks++; } } } else { if (j == 0 || j == (Points->n_points - 1) || Points->n_points < 3) { XPnt_search.a1 = 0; XPnt_search.a2 = 0; XPnt_search.cross = 1; nmarks++; } else { XPnt_search.a1 = a1; XPnt_search.a2 = a2; XPnt_search.cross = 0; } /* Add to tree */ rbtree_insert(RBTree, &XPnt_search); npoints++; } } } nbreaks = 0; nallpoints = 0; G_debug(2, "Break polygons: unique vertices: %ld", (long int)RBTree->count); /* uncomment to check if search tree is healthy */ /* if (rbtree_debug(RBTree, RBTree->root) == 0) G_warning("Break polygons: RBTree not ok"); */ /* Second loop through lines (existing when loop is started, no need to process lines written again) * and break at points marked for break */ G_message(_("Breaking polygons (pass 2: break at selected points)...")); for (i = 1; i <= nlines; i++) { int n_orig_points; G_percent(i, nlines, 1); G_debug(3, "i = %d", i); if (!Vect_line_alive(Map, i)) continue; ltype = Vect_read_line(Map, Points, Cats, i); if (!(ltype & type)) continue; if (!(ltype & GV_LINES)) continue; /* Nonsense to break points */ /* Duplicates would result in zero length lines -> prune line first */ n_orig_points = Points->n_points; Vect_line_prune(Points); broken = 0; last = 0; G_debug(3, "n_points = %d", Points->n_points); for (j = 1; j < Points->n_points; j++) { G_debug(3, "j = %d", j); nallpoints++; if (Points->n_points <= 1 || (j == (Points->n_points - 1) && !broken)) break; /* One point only or * last point and line is not broken, do nothing */ XPnt_search.x = Points->x[j]; XPnt_search.y = Points->y[j]; XPnt_found = rbtree_find(RBTree, &XPnt_search); /* all points must be in the search tree, without duplicates */ if (XPnt_found == NULL) G_fatal_error(_("Point not in search tree!")); /* break or write last segment of broken line */ if ((j == (Points->n_points - 1) && broken) || XPnt_found->cross) { Vect_reset_line(BPoints); for (k = last; k <= j; k++) { Vect_append_point(BPoints, Points->x[k], Points->y[k], Points->z[k]); } /* Result may collapse to one point */ Vect_line_prune(BPoints); if (BPoints->n_points > 1) { ret = Vect_write_line(Map, ltype, BPoints, Cats); G_debug(3, "Line %d written j = %d n_points(orig,pruned) = %d n_points(new) = %d", ret, j, Points->n_points, BPoints->n_points); } if (!broken) Vect_delete_line(Map, i); /* not yet deleted */ /* Write points on breaks */ if (Err) { if (XPnt_found->cross && !XPnt_found->used) { Vect_reset_line(BPoints); Vect_append_point(BPoints, Points->x[j], Points->y[j], 0); Vect_write_line(Err, GV_POINT, BPoints, ErrCats); } XPnt_found->used = 1; } last = j; broken = 1; nbreaks++; } } if (!broken && n_orig_points > Points->n_points) { /* was pruned before -> rewrite */ if (Points->n_points > 1) { Vect_rewrite_line(Map, i, ltype, Points, Cats); G_debug(3, "Line %d pruned, npoints = %d", i, Points->n_points); } else { Vect_delete_line(Map, i); G_debug(3, "Line %d was deleted", i); } } else { G_debug(3, "Line %d was not changed", i); } } rbtree_destroy(RBTree); Vect_destroy_line_struct(Points); Vect_destroy_line_struct(BPoints); Vect_destroy_cats_struct(Cats); G_verbose_message(_("Breaks: %d"), nbreaks); }
/* * Load background file frequencies into the array. */ ARRAY_T* get_file_frequencies(ALPH_T *alph, char *bg_filename, ARRAY_T *freqs) { regmatch_t matches[4]; STR_T *line; char chunk[BG_CHUNK_SIZE+1], letter[2], *key; int size, terminate, offset, i; FILE *fp; regex_t bgfreq; double freq; RBTREE_T *letters; RBNODE_T *node; regcomp_or_die("bg freq", &bgfreq, BGFREQ_RE, REG_EXTENDED); letters = rbtree_create(rbtree_strcasecmp, rbtree_strcpy, free, rbtree_dblcpy, free); line = str_create(100); if (!(fp = fopen(bg_filename, "r"))) { die("Unable to open background file \"%s\" for reading.\n", bg_filename); } terminate = feof(fp); while (!terminate) { size = fread(chunk, sizeof(char), BG_CHUNK_SIZE, fp); chunk[size] = '\0'; terminate = feof(fp); offset = 0; while (offset < size) { // skip mac newline if (str_len(line) == 0 && chunk[offset] == '\r') { offset++; continue; } // find next new line for (i = offset; i < size; ++i) { if (chunk[i] == '\n') break; } // append portion up to the new line or end of chunk str_append(line, chunk+offset, i - offset); // read more if we didn't find a new line if (i == size && !terminate) break; // move the offset past the new line offset = i + 1; // handle windows new line if (str_char(line, -1) == '\r') str_truncate(line, -1); // remove everything to the right of a comment character for (i = 0; i < str_len(line); ++i) { if (str_char(line, i) == '#') { str_truncate(line, i); break; } } // check the line for a single letter followed by a number if (regexec_or_die("bg freq", &bgfreq, str_internal(line), 4, matches, 0)) { // parse the letter and frequency value regex_strncpy(matches+1, str_internal(line), letter, 2); freq = regex_dbl(matches+2, str_internal(line)); // check the frequency is acceptable if (freq < 0 || freq > 1) { die("The background file lists the illegal probability %g for " "the letter %s.\n", freq, letter); } else if (freq == 0) { die("The background file lists a probability of zero for the " "letter %s\n", letter); } if (freq >= 0 && freq <= 1) rbtree_put(letters, letter, &freq); } str_clear(line); } } // finished with the file so clean up file parsing stuff fclose(fp); str_destroy(line, FALSE); regfree(&bgfreq); // guess the alphabet if (*alph == INVALID_ALPH) { switch (rbtree_size(letters)) { case PROTEIN_ASIZE: *alph = PROTEIN_ALPH; break; case DNA_ASIZE: *alph = DNA_ALPH; break; default: die("Number of single character entries in background does not match " "an alphabet.\n"); } } // make the background if (freqs == NULL) freqs = allocate_array(alph_size(*alph, ALL_SIZE)); assert(get_array_length(freqs) >= alph_size(*alph, ALL_SIZE)); init_array(-1, freqs); for (node = rbtree_first(letters); node != NULL; node = rbtree_next(node)) { key = (char*)rbtree_key(node); i = alph_index(*alph, key[0]); freq = *((double*)rbtree_value(node)); if (i == -1) { die("Background contains letter %s which is not in the %s alphabet.\n", key, alph_name(*alph)); } if (get_array_item(i, freqs) != -1) { die("Background contains letter %s which has the same meaning as an " "already listed letter.\n", key); } set_array_item(i, freq, freqs); } // check that all items were set for (i = 0; i < alph_size(*alph, ALPH_SIZE); i++) { if (get_array_item(i, freqs) == -1) { die("Background is missing letter %c.\n", alph_char(*alph, i)); } } // disabled for backwards compatability (AMA test was failing) //normalize_subarray(0, ALPH_ASIZE[*alph], 0.0, freqs); // calculate the values of the ambiguous letters from the concrete ones calc_ambigs(*alph, FALSE, freqs); // cleanup rbtree_destroy(letters); // return result return freqs; }
/* * return 0 if nothing was modidied * return 1 if elevation was modified */ int do_flatarea(int index, CELL ele, CELL *alt_org, CELL *alt_new) { int upr, upc, r, c, ct_dir; CELL is_in_list, is_worked, this_in_list; int index_doer, index_up; int n_flat_cells = 0, counter; CELL ele_nbr, min_ele_diff; int uphill_order, downhill_order, max_uphill_order, max_downhill_order; int last_order; struct pq *up_pq = pq_create(); struct pq *down_pq = pq_create(); struct orders inc_order, *order_found, *nbr_order_found; struct RB_TREE *order_tree = rbtree_create(cmp_orders, sizeof(struct orders)); pq_add(index, down_pq); pq_add(index, up_pq); inc_order.downhill = -1; inc_order.uphill = 0; inc_order.index = index; inc_order.flag = 0; rbtree_insert(order_tree, &inc_order); n_flat_cells = 1; min_ele_diff = INT_MAX; max_uphill_order = max_downhill_order = 0; /* get uphill start points */ G_debug(2, "get uphill start points"); counter = 0; while (down_pq->size) { if ((index_doer = pq_drop(down_pq)) == -1) G_fatal_error("get start points: no more points in down queue"); seg_index_rc(alt_seg, index_doer, &r, &c); FLAG_SET(flat_done, r, c); /* check all neighbours, breadth first search */ for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (upr, upc) for this neighbour */ upr = r + nextdr[ct_dir]; upc = c + nextdc[ct_dir]; /* check if r, c are within region */ if (upr >= 0 && upr < nrows && upc >= 0 && upc < ncols) { index_up = SEG_INDEX(alt_seg, upr, upc); is_in_list = FLAG_GET(in_list, upr, upc); is_worked = FLAG_GET(worked, upr, upc); ele_nbr = alt_org[index_up]; if (ele_nbr == ele && !is_worked) { inc_order.downhill = -1; inc_order.uphill = -1; inc_order.index = index_up; inc_order.flag = 0; /* not yet added to queue */ if ((order_found = rbtree_find(order_tree, &inc_order)) == NULL) { n_flat_cells++; /* add to down queue if not yet in there */ pq_add(index_up, down_pq); /* add to up queue if not yet in there */ if (is_in_list) { pq_add(index_up, up_pq); /* set uphill order to 0 */ inc_order.uphill = 0; counter++; } rbtree_insert(order_tree, &inc_order); } } } } } /* flat area too small, not worth the effort */ if (n_flat_cells < 5) { /* clean up */ pq_destroy(up_pq); pq_destroy(down_pq); rbtree_destroy(order_tree); return 0; } G_debug(2, "%d flat cells, %d cells in tree, %d start cells", n_flat_cells, (int)order_tree->count, counter); pq_destroy(down_pq); down_pq = pq_create(); /* got uphill start points, do uphill correction */ G_debug(2, "got uphill start points, do uphill correction"); counter = 0; uphill_order = 1; while (up_pq->size) { int is_in_down_queue = 0; if ((index_doer = pq_drop(up_pq)) == -1) G_fatal_error("uphill order: no more points in up queue"); seg_index_rc(alt_seg, index_doer, &r, &c); this_in_list = FLAG_GET(in_list, r, c); /* get uphill order for this point */ inc_order.index = index_doer; if ((order_found = rbtree_find(order_tree, &inc_order)) == NULL) G_fatal_error(_("flat cell escaped for uphill correction")); last_order = uphill_order - 1; uphill_order = order_found->uphill; if (last_order > uphill_order) G_warning(_("queue error: last uphill order %d > current uphill order %d"), last_order, uphill_order); /* debug */ if (uphill_order == -1) G_fatal_error(_("uphill order not set")); if (max_uphill_order < uphill_order) max_uphill_order = uphill_order; uphill_order++; counter++; /* check all neighbours, breadth first search */ for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (upr, upc) for this neighbour */ upr = r + nextdr[ct_dir]; upc = c + nextdc[ct_dir]; /* check if r, c are within region */ if (upr >= 0 && upr < nrows && upc >= 0 && upc < ncols) { index_up = SEG_INDEX(alt_seg, upr, upc); is_in_list = FLAG_GET(in_list, upr, upc); is_worked = FLAG_GET(worked, upr, upc); ele_nbr = alt_org[index_up]; /* all cells that are in_list should have been added * previously as uphill start points */ if (ele_nbr == ele && !is_worked) { inc_order.index = index_up; if ((nbr_order_found = rbtree_find(order_tree, &inc_order)) == NULL) { G_fatal_error(_("flat cell escaped in uphill correction")); } /* not yet added to queue */ if (nbr_order_found->uphill == -1) { if (is_in_list) G_warning("cell should be in queue"); /* add to up queue */ pq_add(index_up, up_pq); /* set nbr uphill order = current uphill order + 1 */ nbr_order_found->uphill = uphill_order; } } /* add focus cell to down queue */ if (!this_in_list && !is_in_down_queue && ele_nbr != ele && !is_in_list && !is_worked) { pq_add(index_doer, down_pq); /* set downhill order to 0 */ order_found->downhill = 0; is_in_down_queue = 1; } if (ele_nbr > ele && min_ele_diff > ele_nbr - ele) min_ele_diff = ele_nbr - ele; } } } /* debug: all flags should be set to 0 */ pq_destroy(up_pq); up_pq = pq_create(); /* got downhill start points, do downhill correction */ G_debug(2, "got downhill start points, do downhill correction"); downhill_order = 1; while (down_pq->size) { if ((index_doer = pq_drop(down_pq)) == -1) G_fatal_error(_("downhill order: no more points in down queue")); seg_index_rc(alt_seg, index_doer, &r, &c); this_in_list = FLAG_GET(in_list, r, c); /* get downhill order for this point */ inc_order.index = index_doer; if ((order_found = rbtree_find(order_tree, &inc_order)) == NULL) G_fatal_error(_("flat cell escaped for downhill correction")); last_order = downhill_order - 1; downhill_order = order_found->downhill; if (last_order > downhill_order) G_warning(_("queue error: last downhill order %d > current downhill order %d"), last_order, downhill_order); /* debug */ if (downhill_order == -1) G_fatal_error(_("downhill order: downhill order not set")); if (max_downhill_order < downhill_order) max_downhill_order = downhill_order; downhill_order++; /* check all neighbours, breadth first search */ for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (upr, upc) for this neighbour */ upr = r + nextdr[ct_dir]; upc = c + nextdc[ct_dir]; /* check if r, c are within region */ if (upr >= 0 && upr < nrows && upc >= 0 && upc < ncols) { index_up = SEG_INDEX(alt_seg, upr, upc); is_in_list = FLAG_GET(in_list, upr, upc); is_worked = FLAG_GET(worked, upr, upc); ele_nbr = alt_org[index_up]; if (ele_nbr == ele && !is_worked) { inc_order.index = index_up; if ((nbr_order_found = rbtree_find(order_tree, &inc_order)) == NULL) G_fatal_error(_("flat cell escaped in downhill correction")); /* not yet added to queue */ if (nbr_order_found->downhill == -1) { /* add to down queue */ pq_add(index_up, down_pq); /* set nbr downhill order = current downhill order + 1 */ nbr_order_found->downhill = downhill_order; /* add to up queue */ if (is_in_list) { pq_add(index_up, up_pq); /* set flag */ nbr_order_found->flag = 1; } } } } } } /* got uphill and downhill order, adjust ele */ /* increment: ele += uphill_order + max_downhill_order - downhill_order */ /* decrement: ele += uphill_order - max_uphill_order - downhill_order */ G_debug(2, "adjust ele"); while (up_pq->size) { if ((index_doer = pq_drop(up_pq)) == -1) G_fatal_error("no more points in up queue"); seg_index_rc(alt_seg, index_doer, &r, &c); this_in_list = FLAG_GET(in_list, r, c); /* get uphill and downhill order for this point */ inc_order.index = index_doer; if ((order_found = rbtree_find(order_tree, &inc_order)) == NULL) G_fatal_error(_("flat cell escaped for adjustment")); uphill_order = order_found->uphill; downhill_order = order_found->downhill; /* debug */ if (uphill_order == -1) G_fatal_error(_("adjustment: uphill order not set")); if (!this_in_list && downhill_order == -1) G_fatal_error(_("adjustment: downhill order not set")); /* increment */ if (this_in_list) { downhill_order = max_downhill_order; uphill_order = 0; } alt_new[index_doer] += (uphill_order + (double)(max_downhill_order - downhill_order) / 2.0 + 0.5) / 2.0 + 0.5; /* check all neighbours, breadth first search */ for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (upr, upc) for this neighbour */ upr = r + nextdr[ct_dir]; upc = c + nextdc[ct_dir]; /* check if r, c are within region */ if (upr >= 0 && upr < nrows && upc >= 0 && upc < ncols) { index_up = SEG_INDEX(alt_seg, upr, upc); is_in_list = FLAG_GET(in_list, upr, upc); is_worked = FLAG_GET(worked, upr, upc); ele_nbr = alt_org[index_up]; if (ele_nbr == ele && !is_worked) { inc_order.index = index_up; if ((nbr_order_found = rbtree_find(order_tree, &inc_order)) == NULL) G_fatal_error(_("flat cell escaped in adjustment")); /* not yet added to queue */ if (nbr_order_found->flag == 0) { if (is_in_list) G_warning("adjustment: in_list cell should be in queue"); /* add to up queue */ pq_add(index_up, up_pq); nbr_order_found->flag = 1; } } } } } /* clean up */ pq_destroy(up_pq); pq_destroy(down_pq); rbtree_destroy(order_tree); return 1; }
/*********************************************************************** Free memory allocated in options processing ***********************************************************************/ static void cleanup_options(CENTRIMO_OPTIONS_T *options) { rbtree_destroy(options->selected_motifs); }