/*********************************************************************** * Turn a given motif into its own reverse complement. ***********************************************************************/ void reverse_complement_motif (MOTIF_T* a_motif) { ALPH_SIZE_T size; int i, temp_trim; ARRAY_T* left_freqs; ARRAY_T* right_freqs; ARRAY_T* temp_freqs; // Temporary space during swap. assert(a_motif->alph == DNA_ALPH); // Allocate space. size = (a_motif->flags & MOTIF_HAS_AMBIGS ? ALL_SIZE : ALPH_SIZE); temp_freqs = allocate_array(alph_size(a_motif->alph, size)); // Consider each row (position) in the motif. for (i = 0; i < (int)((a_motif->length + 1) / 2); i++) { left_freqs = get_matrix_row(i, a_motif->freqs); right_freqs = get_matrix_row(a_motif->length - (i + 1), a_motif->freqs); // Make a temporary copy of one row. copy_array(left_freqs, temp_freqs); // Compute reverse complements in both directions. complement_dna_freqs(right_freqs, left_freqs); complement_dna_freqs(temp_freqs, right_freqs); } free_array(temp_freqs); if (a_motif->scores) { // Allocate space. temp_freqs = allocate_array(alph_size(a_motif->alph, ALPH_SIZE)); // Consider each row (position) in the motif. for (i = 0; i < (int)((a_motif->length + 1) / 2); i++) { left_freqs = get_matrix_row(i, a_motif->scores); right_freqs = get_matrix_row(a_motif->length - (i + 1), a_motif->scores); // Make a temporary copy of one row. copy_array(left_freqs, temp_freqs); // Compute reverse complements in both directions. complement_dna_freqs(right_freqs, left_freqs); complement_dna_freqs(temp_freqs, right_freqs); } free_array(temp_freqs); } //swap the trimming variables temp_trim = a_motif->trim_left; a_motif->trim_left = a_motif->trim_right; a_motif->trim_right = temp_trim; //swap the strand indicator //this assumes a ? is equalivant to + if (get_motif_strand(a_motif) == '-') { set_motif_strand('+', a_motif); } else { set_motif_strand('-', a_motif); } }
void dxml_start_motif(void *ctx, char *id, char *seq, int length, long num_sites, long p_hits, long n_hits, double pvalue, double evalue, double uevalue) { CTX_T *data; MOTIF_T *motif; data = (CTX_T*)ctx; data->motif = (MOTIF_T*)mm_malloc(sizeof(MOTIF_T)); motif = data->motif; memset(motif, 0, sizeof(MOTIF_T)); set_motif_id(seq, strlen(seq), motif); set_motif_id2("", 0, motif); set_motif_strand('+', motif); motif->length = length; motif->num_sites = num_sites; motif->evalue = evalue; // both DNA and RNA have 4 letters motif->alph = data->fscope.alphabet; motif->flags = MOTIF_BOTH_STRANDS; // DREME does not support the concept of single strand scanning (yet) // allocate the matrix motif->freqs = allocate_matrix(motif->length, alph_size(motif->alph, ALPH_SIZE)); motif->scores = NULL; // no scores in DREME xml // no url in DREME motif->url = strdup(""); // set by postprocessing motif->complexity = -1; motif->trim_left = 0; motif->trim_right = 0; }
/***************************************************************************** * MEME > motifs > motif * Construct the skeleton of a motif. ****************************************************************************/ void mxml_start_motif(void *ctx, char *id, char *name, char *alt, int width, double sites, double llr, double ic, double re, double bayes_threshold, double log10_evalue, double elapsed_time, char *url) { CTX_T *data; MOTIF_T *motif; data = (CTX_T*)ctx; data->mscope.motif = mm_malloc(sizeof(MOTIF_T)); motif = data->mscope.motif; memset(motif, 0, sizeof(MOTIF_T)); set_motif_id(name, strlen(name), motif); set_motif_id2(alt, sizeof(alt), motif); set_motif_strand('+', motif); motif->length = width; motif->num_sites = sites; motif->url = strdup(url); motif->log_evalue = log10_evalue; motif->evalue = pow(10.0, log10_evalue); // calculate alphabet size motif->alph = alph_hold(data->alph); motif->flags = (data->fscope.strands == 2 ? MOTIF_BOTH_STRANDS : 0); // allocate matricies motif->freqs = allocate_matrix(motif->length, alph_size_core(motif->alph)); init_matrix(-1, motif->freqs); motif->scores = allocate_matrix(motif->length, alph_size_core(motif->alph)); init_matrix(NO_SCORE, motif->scores); // should be set by a post processing method motif->complexity = -1; motif->trim_left = 0; motif->trim_right = 0; // cache motif position if (data->options & SCANNED_SITES) { rbtree_put(data->motif_lookup, id, &(data->current_motif)); } }
/*********************************************************************** * Create two copies of each motif. The new IDs are preceded by "+" * and "-", and the "-" version is the reverse complement of the "+" * version. * * The reverse complement is always listed directly after the original. ***********************************************************************/ void add_reverse_complements (ARRAYLST_T* motifs) { int i, count; char motif_id[MAX_MOTIF_ID_LENGTH + 1]; // Name of the current motif; count = arraylst_size(motifs); //double the array size arraylst_preallocate(count*2, motifs); arraylst_add_n(count, NULL, motifs); //move and reverse complement the original motifs for (i = count-1; i >= 0; --i) { //move the motif to its new position arraylst_swap(i, 2*i, motifs); //get the motif and the one that will become the reverse complement MOTIF_T *orig = arraylst_get(2*i, motifs); if (get_motif_strand(orig) == '?') set_motif_strand('+', orig); //copy and reverse complement the motif to the position after MOTIF_T *rc = dup_rc_motif(orig); arraylst_set(2*i + 1, rc, motifs); } assert(arraylst_size(motifs) == (2 * count)); }