/************************************************************************** * 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; }
/************************************************************************** * scale_pssm * * Scale and round the scores in a PSSM so that the score of a word * is in the range [0..w*range]. * * Returns the scaled PSSM. * **************************************************************************/ void scale_pssm( PSSM_T *pssm, // The PSSM. (IN/OUT) PRIOR_DIST_T *prior_dist, // Distribution of priors (IN) double alpha, // Fraction of all TFBS that are the TFBS of interest int range // The desired range. (IN) ) { int i, j; MATRIX_T* matrix = pssm->matrix; int r = pssm->w; int c = pssm->alphsize; double small = BIG; double large = -BIG; double scale, offset; // Get the largest and smallest scores in the PSSM. for (i=0; i<r; i++) { for (j=0; j<c; j++) { double x = get_matrix_cell(i, j, matrix); small = MIN(small, x); large = MAX(large, x); } } // Get the smallest and largest prior log-odds from the prior distribution // and use them to adjust small and large. if (prior_dist != NULL) { double min_lo_prior = get_min_lo_prior(prior_dist, alpha); double max_lo_prior = get_max_lo_prior(prior_dist, alpha); small = MIN(small, min_lo_prior); large = MAX(large, max_lo_prior); } // Find offset and scale factors so that PSSM scores for words is in the // range: [0..w*range] // To make LO=0 map back to 0, need offset*scale to be an integer. // So we make offset and scale integers. (TLB 31 May 2013) if (large == small) { small = large - 1; } // In case all motif entries are the same. offset = small = floor(small); // Make offset an integer. scale = floor(range/(large-small)); // Ensure scaled scores are <= range. // Scale and round the PSSM entries. for (i=0; i<r; i++) { for (j=0; j<c; j++) { double x = raw_to_scaled(get_matrix_cell(i, j, matrix), 1, scale, offset); set_matrix_cell(i, j, x, matrix); } } // return scale and offset of scores pssm->scale = scale; pssm->offset = offset; pssm->range = range; } // scale_pssm
/************************************************************************** * * get_scaled_pssm_score * **************************************************************************/ double get_scaled_pssm_score( double score, PSSM_T* pssm ) { return raw_to_scaled( score, get_pssm_w(pssm), get_pssm_scale(pssm), get_pssm_offset(pssm) ); }
/** * @brief Get event threshold value * * @param hal Address of an initialized sensor hardware descriptor. * @param threshold Address of threshold descriptor. * @return bool true if the call succeeds, else false is returned. */ static bool bma250_get_threshold (sensor_hal_t *hal, sensor_threshold_desc_t *threshold) { switch (threshold->type) { /* Invalid/unsupported threshold type - do nothing, return false */ default: return false; /* any-motion threshold */ case SENSOR_THRESHOLD_MOTION: case SENSOR_THRESHOLD_TILT: threshold->value = raw_to_scaled(hal, sensor_bus_get(hal, BMA250_SLOPE_THRESHOLD)); break; /* tap/double-tap threshold */ case SENSOR_THRESHOLD_TAP: { uint8_t const mask = BMA250_TAP_TH_FIELD; threshold->value = raw_to_scaled(hal, sensor_reg_fieldget(hal, BMA250_TAP_CONFIG, mask)); } break; /* low-G threshold */ case SENSOR_THRESHOLD_LOW_G: threshold->value = raw_to_scaled(hal, sensor_bus_get(hal, BMA250_LOW_G_THRESHOLD)); break; /* high-G threshold */ case SENSOR_THRESHOLD_HIGH_G: threshold->value = raw_to_scaled(hal, sensor_bus_get(hal, BMA250_HIGH_G_THRESHOLD)); break; } return true; }
/** * @brief Format Bosch 3-axis accelerometer data samples * * This routine formats Bosch 3-axis accelerometer data using tunable * configuration parameters controlling device orientation and flags that * indicate whether or not axis data should be scaled in engineering units. * * @param hal Address of an initialized sensor hardware descriptor. * @param acc Bosch accelerometer axis data samples. * @param data Address of sensor_data_t structure to return values. * @return Nothing */ static void format_axis_data(const sensor_hal_t *hal, const bma_axis_t acc[], sensor_data_t *data) { /* Get axis values based based on device orientation configuration. */ int32_t const acc_x = hal->orientation.x.sign * bma_axis_val(acc[hal->orientation.x.axis]); int32_t const acc_y = hal->orientation.y.sign * bma_axis_val(acc[hal->orientation.y.axis]); int32_t const acc_z = hal->orientation.z.sign * bma_axis_val(acc[hal->orientation.z.axis]); /* Convert raw sensor sample to engineering units if requested. */ if (data->scaled) { data->axis.x = raw_to_scaled(hal, acc_x); data->axis.y = raw_to_scaled(hal, acc_y); data->axis.z = raw_to_scaled(hal, acc_z); } else { data->axis.x = acc_x; data->axis.y = acc_y; data->axis.z = acc_z; } }
/******************************************************************** * This program reads a MEME PSP file and computes the binned * distribution of priors. The distribution is writen to stdout. ********************************************************************/ int main(int argc, char *argv[]) { char *usage = "compute-prior-dist <num-bins> <psp-file>"; if (argc != 3) { fprintf(stderr, "Usage: %s\n", usage); return -1; } int num_bins = atoi(argv[1]); if (num_bins <= 0) { fprintf(stderr, "Usage: %s\n", usage); return -1; } const char *filename = argv[2]; // Read each prior, find max and min of distribution. DATA_BLOCK_READER_T *psp_reader = NULL; psp_reader = new_prior_reader_from_psp(FALSE /* Don't try to parse genomic coord.*/, filename); DATA_BLOCK_T *psp_block = new_prior_block(); int prior_array_size = 100; ARRAY_T *raw_priors = allocate_array(prior_array_size); int num_priors = 0; while (psp_reader->go_to_next_sequence(psp_reader) != FALSE) { while (psp_reader->get_next_block(psp_reader, psp_block) != FALSE) { double prior = get_prior_from_data_block(psp_block); if (prior == 0.0) { // Skip priors that are exactly 0.0 continue; } if (num_priors == INT_MAX) { die("Number of priors exceeded maximum allowed value of %d", INT_MAX); } set_array_item(num_priors, prior, raw_priors); ++num_priors; if (num_priors >= prior_array_size) { resize_array(raw_priors, 2 * prior_array_size); prior_array_size = 2 * prior_array_size; } } } free_data_block(psp_block); free_data_block_reader(psp_reader); ARRAY_T *priors = extract_subarray(raw_priors, 0, num_priors); free_array(raw_priors); double median_prior = compute_median(priors); double min_prior = get_array_item(0, priors); double max_prior = get_array_item(num_priors - 1, priors); // Print min, max, and median printf("#min %6.5f\n", min_prior); printf("#max %6.5f\n", max_prior); printf("#median %6.5f\n", median_prior); // Special case if priors are exactly uniform. if (min_prior == max_prior) { printf("%6.5f\n", 1.0); return 0; } // Create the array of bins, intialized to 0. double *prior_dist = mm_calloc(num_bins, sizeof(double)); double scale = (num_bins - 1) / (max_prior - min_prior); double offset = min_prior; int dist_index = 0; int i; for (i = 0; i < num_priors; ++i) { double prior = get_array_item(i, priors); dist_index = raw_to_scaled(prior, 1, scale, offset); ++prior_dist[dist_index]; } for (dist_index = 0; dist_index < num_bins; ++dist_index) { // Print normalized bin counts prior_dist[dist_index] /= num_priors; printf("%6.5f\n", prior_dist[dist_index]); } return 0; }