示例#1
0
文件: pssm.c 项目: a1aks/Haystack
/**************************************************************************
*	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;

}
示例#2
0
文件: pssm.c 项目: a1aks/Haystack
/**************************************************************************
*	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
示例#3
0
文件: pssm.c 项目: a1aks/Haystack
/**************************************************************************
*
*	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)
    );
}
示例#4
0
/**
 * @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;
}