/*********************************************************************** * A helper function to normalize a subarray. ***********************************************************************/ void normalize_subarray( int start_index, int length, double tolerance, ARRAY_T* array ) { ATYPE total; int i; /* Compute the total. */ total = 0.0; for (i = start_index; i < start_index + length; i++) { total += get_array_item(i, array); } assert(total != 0.0); /* Don't bother if we're close enough. */ if (almost_equal(1.0, total, tolerance)) { return; } /* Divide each element by the total. */ for (i = start_index; i < start_index + length; i++) { set_array_item(i, get_array_item(i, array) / total, array); } }
/************************************************************************** * Get pseudocount frequencies. * * The target_freq matrix only has values for the basic alphabet. * Fill in the ambiguous character pseudocounts afterwards using * the average of pseudocounts for letters matching the ambiguous ones. **************************************************************************/ ARRAY_T *get_pseudocount_freqs( ALPH_T alph, ARRAY_T * f, /* Foreground distribution. */ ARRAY_T * b, /* Background distribution. */ MATRIX_T * target_freq /* Target frequency matrix. */ ) { int i, j; int asize = alph_size(alph, ALPH_SIZE); // excludes ambigs ARRAY_T *g = allocate_array(alph_size(alph, ALL_SIZE));// includes ambigs /* Create pseudocount frequencies. */ for (i = 0; i < asize; i++) { /* non-ambiguous freqs */ double gi = 0; for (j= 0; j < asize; j++) { /* non-ambiguous freqs */ double qij = get_matrix_cell(i, j, target_freq); double fj = get_array_item(j, f); double bj = get_array_item(j, b); gi += (fj/bj) * qij; } /* j */ set_array_item(i, gi, g); if (SUBST_MATRIX_DEBUG) printf("%g %g, ", get_array_item(i, f), gi); } /* i */ calc_ambigs(alph, FALSE, g); /* takes the average pseudocount */ if (SUBST_MATRIX_DEBUG) printf("\n"); return(g); /* return the pseudocounts */ } /* get_pseudocount_freqs */
/*********************************************************************** * Make all the elements of an array positive by adding a constant to * each. ***********************************************************************/ void all_positive (ARRAY_T* array) { int i_item; int num_items; ATYPE min; check_null_array(array); /* Find the minimum value. */ min = get_array_item(0, array); num_items = get_array_length(array); for (i_item = 0; i_item < num_items; i_item++) { if (get_array_item(i_item, array) < min) { min = get_array_item(i_item, array); } } /* If there are negative elements ... */ if (min < 0.0) { /* ... then subtract the minimum from all elements. */ for (i_item = 0; i_item < num_items; i_item++) { incr_array_item(i_item, -min, array); } } }
/***************************************************************************** * MEME > model > /background_frequencies ****************************************************************************/ void mxml_end_background(void *ctx) { CTX_T *data; int i; bool error; double sum, delta; data = (CTX_T*)ctx; sum = 0; error = false; for (i = 0; i < get_array_length(data->nums); i++) { if (get_array_item(i, data->nums) == -1) { local_error(data, "Background frequency was not provided for letter %c.\n", alph_char(data->alph, i)); error = true; } else { sum += get_array_item(i, data->nums); } } delta = sum - 1.0; if (delta < 0) delta = -delta; if (delta > 0.01) { local_error(data, "The background frequencies summed to %f but they should sum to 1.0.\n", sum); error = true; } if (error) { free_array(data->nums); } else { data->fscope.background = data->nums; data->nums = NULL; } }
/*********************************************************************** * Determine whether two arrays are equal, within a given bound. ***********************************************************************/ BOOLEAN_T equal_arrays (ATYPE close_enough, ARRAY_T* array1, ARRAY_T* array2) { int i_item; int num_items; check_null_array(array1); check_null_array(array2); /* Verify that the arrays are of the same length. */ if (!check_array_dimensions(FALSE, array1, array2)) { return(FALSE); } /* Check to be sure that each value is the same. */ num_items = get_array_length(array1); for (i_item = 0; i_item < num_items; i_item++) { if (!almost_equal(get_array_item(i_item, array1) - get_array_item(i_item, array2), 0.0, close_enough)) { return(FALSE); } } return(TRUE); }
/*********************************************************************** * Mix two arrays in log space. ***********************************************************************/ void mix_log_arrays (float mixing, /* Percent of array2 that will be retained. */ ARRAY_T* array1, ARRAY_T* array2) { int i_item; int num_items; ATYPE mixed_value; check_null_array(array1); check_null_array(array2); /* Verify that the arrays are of the same length. */ check_array_dimensions(TRUE, array1, array2); /* Verify that we've got a reasonable mixing parameter. */ if ((mixing > 1.0) || (mixing < 0.0)) { die("Invalid mixing parameter (%g).\n", mixing); } num_items = get_array_length(array1); for (i_item = 0; i_item < num_items; i_item++) { mixed_value = LOG_SUM(my_log2(1.0 - mixing) + get_array_item(i_item, array1), my_log2(mixing) + get_array_item(i_item, array2)); set_array_item(i_item, mixed_value, array2); } }
/*********************************************************************** * Compute the complexity of a motif as a number between 0 and 1. * * Motif complexity is the average K-L distance between the "motif * background distribution" and each column of the motif. The motif * background is just the average distribution of all the columns. The * K-L distance, which measures the difference between two * distributions, is the same as the information content: * * \sum_i p_i log(p_i/f_i) * * This value increases with increasing complexity. ***********************************************************************/ double compute_motif_complexity (MOTIF_T* a_motif) { double return_value; ARRAY_T* motif_background; // Mean emission distribution. int num_rows; int i_row; int num_cols; int i_col; num_cols = get_alph_size(ALPH_SIZE); num_rows = get_num_rows(a_motif->freqs); // Compute the mean emission distribution. motif_background = get_matrix_col_sums(a_motif->freqs); scalar_mult(1.0 / (double)num_rows, motif_background); // Compute the K-L distance w.r.t. the background. return_value = 0; for (i_row = 0; i_row < num_rows; i_row++) { ARRAY_T* this_emission = get_matrix_row(i_row, a_motif->freqs); for (i_col = 0; i_col < num_cols; i_col++) { ATYPE this_item = get_array_item(i_col, this_emission); ATYPE background_item = get_array_item(i_col, motif_background); // Use two logs to avoid handling divide-by-zero as a special case. return_value += this_item * (my_log(this_item) - my_log(background_item)); } } free_array(motif_background); return(return_value / (double)num_rows); }
/*********************************************************************** * Discard motifs that are not connected. ***********************************************************************/ static void throw_out_unused_motifs (MATRIX_T* transp_freq, MATRIX_T* spacer_ave, int* num_motifs, MOTIF_T* motifs) { int i_motif, j_motif; ARRAY_T* row_sums; ARRAY_T* col_sums; // Extract the margins of the transition matrix. row_sums = get_matrix_row_sums(transp_freq); col_sums = get_matrix_col_sums(transp_freq); for (i_motif = 0; i_motif < *num_motifs; i_motif++) { // Is this row or column empty? if ((get_array_item(i_motif + 1, row_sums) == 0.0) || (get_array_item(i_motif + 1, col_sums) == 0.0)) { if (verbosity >= NORMAL_VERBOSE) { fprintf(stderr, "Removing unused motif %s. No occurrences of this motif were found.\n", get_motif_id(&(motifs[i_motif]))); } // Remove the row and column from the transition matrix. remove_matrix_row(i_motif + 1, transp_freq); remove_matrix_col(i_motif + 1, transp_freq); assert(get_num_rows(transp_freq) == get_num_cols(transp_freq)); remove_matrix_row(i_motif + 1, spacer_ave); remove_matrix_col(i_motif + 1, spacer_ave); assert(get_num_rows(spacer_ave) == get_num_cols(spacer_ave)); // Remove the motif from the array. for (j_motif = i_motif + 1; j_motif < *num_motifs; j_motif++) { free_motif(&(motifs[j_motif - 1])); copy_motif(&(motifs[j_motif]), &(motifs[j_motif - 1])); } free_motif(&(motifs[j_motif - 1])); (*num_motifs)--; i_motif--; // Recalculate the row and column sums. free_array(row_sums); free_array(col_sums); row_sums = get_matrix_row_sums(transp_freq); col_sums = get_matrix_col_sums(transp_freq); } } free_array(row_sums); free_array(col_sums); }
KARLIN_INPUT_T *make_karlin_input( MATRIX_T *matrix, /* scoring matrix */ ARRAY_T *probs /* letter freq distribution */ ) { int i, j; double escore; long lowest, highest; ARRAY_T *score_probs; int nscores; int alen = get_num_rows(matrix); /* size of alphabet */ KARLIN_INPUT_T *karlin_input; /* data to return */ /* find the highest and lowest scores in the scoring matrix */ lowest = 1; highest = -1; for (i=0; i<alen; i++) { for (j=0; j<alen; j++) { double s = get_matrix_cell(i, j, matrix); if (s < lowest) lowest = s; if (s > highest) highest = s; } } if (lowest >= 0) die("Lowest score in scoring matrix must be negative, is %f.", (double)lowest); if (highest<= 0) die("Highest score in scoring matrix must be positve, is %f.", (double)highest); /* allocate the array of score probabilities and set to 0 */ nscores = highest - lowest + 1; score_probs = allocate_array(nscores); init_array(0, score_probs); /* compute the probabilities of different scores */ escore = 0; for (i=0; i<alen; i++) { for (j=0; j<alen; j++) { int s = get_matrix_cell(i, j, matrix); double pi = get_array_item(i, probs); double pj = get_array_item(j, probs); double sp = get_array_item(s-lowest, score_probs); set_array_item(s-lowest, sp + pi*pj, score_probs); /* cumulative prob. of score */ escore += pi*pj*s; /*printf("i %d j %d s %d pi %f pj %f sp %f escore %f\n",i,j,s, pi, pj, sp, escore);*/ } } karlin_input = (KARLIN_INPUT_T *)mm_malloc(sizeof(KARLIN_INPUT_T)); karlin_input->low = lowest; karlin_input->high = highest; karlin_input->escore = escore; karlin_input->prob = score_probs; return(karlin_input); } /* make_karlin_input */
/*********************************************************************** * Convert array by compute the average of complementary dna frequencies. * * Assumes DNA alphabet in order ACGT. ***********************************************************************/ void balance_complementary_dna_freqs (ARRAY_T* source) { double at = (get_array_item(0, source)+get_array_item(3, source))/2.0; double cg = (get_array_item(1, source)+get_array_item(2, source))/2.0; set_array_item(0, at, source); // A -> T set_array_item(1, cg, source); // C -> G set_array_item(2, cg, source); // G -> C set_array_item(3, at, source); // T -> A fill_in_ambiguous_chars(FALSE, source); }
/*********************************************************************** * Convert array by compute the average of complementary dna frequencies. * * Apparently no-one uses this. * * Assumes DNA alphabet in order ACGT. ***********************************************************************/ void balance_complementary_dna_freqs (ARRAY_T* source) { double at = (get_array_item(0, source)+get_array_item(3, source))/2.0; double cg = (get_array_item(1, source)+get_array_item(2, source))/2.0; set_array_item(0, at, source); // A -> T set_array_item(1, cg, source); // C -> G set_array_item(2, cg, source); // G -> C set_array_item(3, at, source); // T -> A calc_ambigs(DNA_ALPH, FALSE, source); }
/************************************************************************** * get_scaled_lo_prior_dist * * Takes a scaled distribution of priors and creates a scaled distribution of * log odds priors. The parameters for the scaling of the input priors are * in the PRIOR_DIST_T data structure. The output distribution of log odss * priors are scaled to be in the same range as the PSSM log odds using * the input parameters pssm_range, pssm_scale, and pssm_offset. * * Special handling is required for a uniform distribution of priors. * In that case the max_prior == min_prior, and the distribution only * contains one bin. * * Returns a new array containing the scaled log odds priors **************************************************************************/ ARRAY_T *get_scaled_lo_prior_dist( PRIOR_DIST_T *prior_dist, double alpha, int pssm_range, double pssm_scale, double pssm_offset ) { assert(prior_dist != NULL); // Alocate enought space for elements in [0 ... pssm_range] ARRAY_T *scaled_lo_prior_dist = allocate_array(pssm_range + 1); if (prior_dist != NULL) { ARRAY_T *dist_array = get_prior_dist_array(prior_dist); int len_prior_dist = get_array_length(dist_array); double max_prior = get_prior_dist_maximum(prior_dist); double min_prior = get_prior_dist_minimum(prior_dist); double prior_dist_scale = get_prior_dist_scale(prior_dist); double prior_dist_offset = get_prior_dist_offset(prior_dist); init_array(0.0L, scaled_lo_prior_dist); if (max_prior == min_prior) { // Special case for uniform priors double value = 1.0; double lo_prior = my_log2(alpha * max_prior / (1.0L - (alpha * max_prior))); // Convert lo_prior to PSSM scale int scaled_index = raw_to_scaled(lo_prior, 1.0L, pssm_scale, pssm_offset); set_array_item(scaled_index, value, scaled_lo_prior_dist); } else { int prior_index = 0; for (prior_index = 0; prior_index < len_prior_dist; ++prior_index) { double value = get_array_item(prior_index, dist_array); // Convert index giving scaled prior to raw prior. double scaled_prior = ((double) prior_index) + 0.5L; double prior \ = scaled_to_raw(scaled_prior, 1, prior_dist_scale, prior_dist_offset); double lo_prior = my_log2(alpha * prior / (1.0L - (alpha * prior))); // Scale raw lo_prior using parameters from PSSM. int scaled_index = raw_to_scaled(lo_prior, 1.0L, pssm_scale, pssm_offset); if (scaled_index < pssm_range) { double old_value = get_array_item(scaled_index, scaled_lo_prior_dist); set_array_item(scaled_index, value + old_value, scaled_lo_prior_dist); } } } } return scaled_lo_prior_dist; }
/*********************************************************************** * Compute the reverse complement of one DNA frequency distribution. * * Assumes DNA alphabet in order ACGT. ***********************************************************************/ void complement_dna_freqs (ARRAY_T* source, ARRAY_T* dest) { set_array_item(0, get_array_item(3, source), dest); // A -> T set_array_item(1, get_array_item(2, source), dest); // C -> G set_array_item(2, get_array_item(1, source), dest); // G -> C set_array_item(3, get_array_item(0, source), dest); // T -> A //check if the frequencies have ambiguous characters //for example meme does not use ambiguous characters if (get_array_length(source) > 4) { fill_in_ambiguous_chars(FALSE, dest); } }
/*********************************************************************** * Apply a pseudocount to the motif pspm. ***********************************************************************/ void apply_pseudocount_to_motif (MOTIF_T* motif, ARRAY_T *background, double pseudocount) { int pos, letter, len, asize, sites; double prob, count, total; ARRAY_T *temp; // no point in doing work when it makes no difference if (pseudocount == 0) return; assert(pseudocount > 0); // motif dimensions asize = alph_size(motif->alph, ALPH_SIZE); len = motif->length; // create a uniform background if none is given temp = NULL; if (background == NULL) { temp = allocate_array(asize); get_uniform_frequencies(motif->alph, temp); background = temp; } // calculate the counts sites = (motif->num_sites > 0 ? motif->num_sites : DEFAULT_SITE_COUNT); total = sites + pseudocount; for (pos = 0; pos < len; ++pos) { for (letter = 0; letter < asize; ++letter) { prob = get_matrix_cell(pos, letter, motif->freqs); count = (prob * sites) + (pseudocount * get_array_item(letter, background)); prob = count / total; set_matrix_cell(pos, letter, prob, motif->freqs); } } if (temp) free_array(temp); }
/*********************************************************************** * Normalize an array in log space. ***********************************************************************/ void log_normalize (ATYPE close_enough, ARRAY_T* array) { int i_item; int num_items; ATYPE total; ATYPE this_value; /* Get the sum of the elements. */ total = log_array_total(array); /* If the array already sums to zero, don't bother. */ if (almost_equal(total, 0.0, close_enough)) { return; } /* If there's nothing in the array, then return all zeroes. */ if (total < LOG_SMALL) { init_array(LOG_ZERO, array); return; } num_items = get_array_length(array); for (i_item = 0; i_item < num_items; i_item++) { this_value = get_array_item(i_item, array) - total; /* If this value is small enough, just make it zero. */ if (this_value < LOG_SMALL) { set_array_item(i_item, LOG_ZERO, array); } else { set_array_item(i_item, this_value, array); } } }
/************************************************************************** * get_min_pvalue * * Return the minimum p-value for a given pssm. * **************************************************************************/ static double get_min_pvalue( PSSM_T *pssm // The PSSM. ) { int i, j; int max_score; int r = pssm->w; int c = pssm->alphsize; double min_p_value; // Get the largest score in each row and sum them. max_score = 0; for (i=0; i<r; i++) { double large = -BIG; for (j=0; j<c; j++) { double x = get_matrix_cell(i, j, pssm->matrix); large = MAX(large, x); } max_score += large; } min_p_value = get_array_item(max_score, pssm->pv); return(min_p_value); } /* get_min_pvalue */
/*********************************************************************** * Divide corresponding elements in two arrays. ***********************************************************************/ void dot_divide (ARRAY_T* array1, ARRAY_T* array2) { int i_item; int num_items; check_null_array(array1); check_null_array(array2); check_array_dimensions(TRUE, array1, array2); num_items = get_array_length(array1); for (i_item = 0; i_item < num_items; i_item++) { set_array_item(i_item, get_array_item(i_item, array1) / get_array_item(i_item, array2), array2); } }
/*********************************************************************** * Compute the dot product of two arrays. ***********************************************************************/ double dot_product (ARRAY_T* array1, ARRAY_T* array2) { int i_item; int num_items; double return_value; check_array_dimensions(TRUE, array1, array2); num_items = get_array_length(array1); return_value = 0.0; for (i_item = 0; i_item < num_items; i_item++) { return_value += get_array_item(i_item, array1) * get_array_item(i_item, array2); } return(return_value); }
/*********************************************************************** * Compute the sum of the squares of the differences between two arrays. ***********************************************************************/ ATYPE sum_of_square_diffs (ARRAY_T* array1, ARRAY_T* array2) { int i_item; int num_items; ATYPE diff; /* The difference between two corresponding array values. */ ATYPE total = 0; /* The sum of the squares. */ check_null_array(array1); check_null_array(array2); check_array_dimensions(TRUE, array1, array2); num_items = get_array_length(array1); for (i_item = 0; i_item < num_items; i_item++) { diff = get_array_item(i_item, array1) - get_array_item(i_item, array2); total += diff * diff; } return(total); }
ATYPE get_array_maximum (ARRAY_T* array) { check_null_array(array); int num_items = get_array_length(array); if (num_items == 0) { die("Attempted to retrieve maximum value from an empty array.\n"); } ATYPE return_value = get_array_item(0, array); int i_item; for (i_item = 1; i_item < num_items; i_item++) { ATYPE item = get_array_item(i_item, array); if (item > return_value) { return_value = item; } } return(return_value); }
/* * Replace the elements an array of frequences with the average * over complementary bases. */ void average_freq_with_complement(ALPH_T alph, ARRAY_T *freqs) { int a_index, t_index, g_index, c_index; double at_freq, gc_freq; assert(alph == DNA_ALPH); a_index = alph_index(alph, 'A'); t_index = alph_index(alph, 'T'); g_index = alph_index(alph, 'G'); c_index = alph_index(alph, 'C'); at_freq = (get_array_item(a_index, freqs) + get_array_item(t_index, freqs)) / 2.0; gc_freq = (get_array_item(g_index, freqs) + get_array_item(c_index, freqs)) / 2.0; set_array_item(a_index, at_freq, freqs); set_array_item(t_index, at_freq, freqs); set_array_item(g_index, gc_freq, freqs); set_array_item(c_index, gc_freq, freqs); }
/* * Take the counts from an ambiguous character and evenly distribute * them among the corresponding concrete characters. * * This function operates in log space. */ static void dist_ambig(ALPH_T alph, char ambig, char *concrete_chars, ARRAY_T* freqs) { PROB_T ambig_count, concrete_count; int ambig_index, num_concretes, i, concrete_index; // Get the count to be distributed. ambig_index = alph_index(alph, ambig); ambig_count = get_array_item(ambig_index, freqs); // Divide it by the number of corresponding concrete characters. num_concretes = strlen(concrete_chars); ambig_count -= my_log2((PROB_T)num_concretes); // Distribute it in equal portions to the given concrete characters. for (i = 0; i < num_concretes; i++) { concrete_index = alph_index(alph, concrete_chars[i]); concrete_count = get_array_item(concrete_index, freqs); // Add the ambiguous counts. concrete_count = LOG_SUM(concrete_count, ambig_count); set_array_item(concrete_index, concrete_count, freqs); } // Set the ambiguous count to zero. set_array_item(ambig_index, LOG_ZERO, freqs); }
/************************************************************************* * Test whether a given array is already sorted. *************************************************************************/ BOOLEAN_T is_sorted (BOOLEAN_T good_score_is_low, ARRAY_T* my_array) { ATYPE prev_value = get_array_item(0, my_array); int index = 0; int length = get_array_length(my_array); for (index = 1; index < length; index++) { ATYPE this_value = get_array_item(index, my_array); if (good_score_is_low) { if (this_value < prev_value) { return(FALSE); } } else { if (this_value > prev_value) { return(FALSE); } } prev_value = this_value; } return(TRUE); }
/***************************************************************************** * MEME > motifs > motif > probabilities > alphabet_matrix > /alphabet_array * Check that all letters have a probability and update the current matrix row. ****************************************************************************/ void mxml_end_probability_pos(void *ctx) { CTX_T *data; ARRAY_T *pos; int i; data = (CTX_T*)ctx; pos = get_matrix_row(data->current_pos, data->mscope.motif->freqs); for (i = 0; i < get_array_length(pos); i++) { if (get_array_item(i, pos) == -1) { local_error(data, "Probability for letter %c in position %d is missing.\n", alph_char(data->alph, i), i + 1); } } data->current_pos++; }
void unlog_array (ARRAY_T* array) { int i_item; int num_items; check_null_array(array); num_items = get_array_length(array); for (i_item = 0; i_item < num_items; i_item++) { set_array_item(i_item, EXP2(get_array_item(i_item, array)), array); } }
/*********************************************************************** * Multiply each element of an array by a scalar value. ***********************************************************************/ void scalar_mult (ATYPE value, ARRAY_T* array) { int i_item; int num_items; check_null_array(array); num_items = get_array_length(array); for (i_item = 0; i_item < num_items; i_item++) { set_array_item(i_item, get_array_item(i_item, array) * value, array); } }
/************************************************************************** * Convert a given array to or from logs. **************************************************************************/ void convert_to_from_log_array (BOOLEAN_T to_log, ARRAY_T* source_array, ARRAY_T* target_array) { int num_items; int i_item; ATYPE new_value; // If the source is null, just return. if (source_array == NULL) return; num_items = get_array_length(source_array); for (i_item = 0; i_item < num_items; i_item++) { if (to_log) { new_value = my_log2(get_array_item(i_item, source_array)); } else { new_value = EXP2(get_array_item(i_item, source_array)); } set_array_item(i_item, new_value, target_array); } }
/************************************************************************* * Converts the motif frequency matrix into a odds matrix: taken from old ama-scan.c *************************************************************************/ void convert_to_odds_matrix(MOTIF_T* motif, ARRAY_T* bg_freqs){ const int asize = alph_size(get_motif_alph(motif), ALPH_SIZE); int motif_position_index,alph_index; MATRIX_T *freqs; freqs = get_motif_freqs(motif); const int num_motif_positions = get_num_rows(freqs); for (alph_index=0;alph_index<asize;++alph_index){ double bg_likelihood = get_array_item(alph_index, bg_freqs); for (motif_position_index=0;motif_position_index<num_motif_positions;++motif_position_index){ freqs->rows[motif_position_index]->items[alph_index] /= bg_likelihood; } } }
MATRIX_T *convert_score_to_target( MATRIX_T *score, /* score matrix */ ARRAY_T *prob /* letter frequencies */ ) { int i, j; KARLIN_INPUT_T *karlin_input; double lambda, K, H; MATRIX_T *target; /* target freq. matrix */ int alen = get_num_rows(score); /* alphabet length */ /* make input for karlin() */ karlin_input = make_karlin_input(score, prob); /* get lambda */ karlin(karlin_input->low, karlin_input->high, karlin_input->prob->items, &lambda, &K, &H); /*printf("lambda %f K %f H %f\n", lambda, K, H);*/ /* calculate target frequencies */ target = allocate_matrix(alen, alen); for (i=0; i<alen; i++) { for (j=0; j<alen; j++) { double pi = get_array_item(i, prob); double pj = get_array_item(j, prob); double sij = get_matrix_cell(i, j, score); double f = pi * pj * exp(lambda * sij); set_matrix_cell(i, j, f, target); } } // Free local dynamic memory. free_array(karlin_input->prob); myfree(karlin_input); return(target); } /* convert_score_to_target */
/************************************************************************* * Copies the motif frequency matrix and converts it into a odds matrix *************************************************************************/ MATRIX_T* create_odds_matrix(MOTIF_T *motif, ARRAY_T* bg_freqs){ const int asize = alph_size(get_motif_alph(motif), ALPH_SIZE); int pos, aidx; MATRIX_T *odds; odds = duplicate_matrix(get_motif_freqs(motif)); const int num_pos = get_num_rows(odds); for (aidx = 0; aidx < asize; ++aidx) { double bg_likelihood = get_array_item(aidx, bg_freqs); for (pos = 0; pos < num_pos; ++pos) { odds->rows[pos]->items[aidx] /= bg_likelihood; } } return odds; }