示例#1
0
/** Rebunches histogram data data according to n_bunch input
*
* @param xold :: old x data
* @param yold :: old y data
* @param eold :: old e data
* @param xnew :: new x data
* @param ynew :: new y data
* @param enew :: new e data
* @param n_bunch :: number of data points to bunch together for each new point
* @throw runtime_error Thrown if algorithm cannot execute
* @throw invalid_argument Thrown if input to function is incorrect
**/
void Rebunch::rebunch_hist_frequencies(const HistogramX &xold,
                                       const HistogramY &yold,
                                       const HistogramE &eold, HistogramX &xnew,
                                       HistogramY &ynew, HistogramE &enew,
                                       const size_t n_bunch) {
  double width;
  size_t size_x = xold.size();
  size_t size_y = yold.size();

  double ysum, esum;
  size_t hi_index = size_x - 1;
  size_t wbins = size_y / n_bunch;
  size_t rem = size_y % n_bunch;

  size_t i, j;
  int i_in = 0;
  j = 0;
  while (j < wbins) {
    ysum = 0.0;
    esum = 0.0;
    for (i = 1; i <= n_bunch; i++) {
      width = xold[i_in + 1] - xold[i_in];
      ysum += yold[i_in] * width;
      esum += eold[i_in] * eold[i_in] * width * width;
      i_in++;
    }
    // average contributing x values
    ynew[j] = ysum;
    enew[j] = sqrt(esum);
    j++;
  }
  if (rem != 0) {
    ysum = 0.0;
    esum = 0.0;
    for (i = 1; i <= rem; i++) {
      width = xold[i_in + 1] - xold[i_in];
      ysum += yold[i_in] * width;
      esum += eold[i_in] * eold[i_in] * width * width;
      i_in++;
    }
    ynew[j] = ysum;
    enew[j] = sqrt(esum);
  }

  j = 0;
  xnew[j] = xold[0];
  j++;
  for (i = n_bunch; i < hi_index; i += n_bunch) {
    xnew[j] = xold[i];
    j++;
  }
  xnew[j] = xold[hi_index];

  for (i = 0; i < ynew.size(); i++) {
    width = xnew[i + 1] - xnew[i];
    ynew[i] = ynew[i] / width;
    enew[i] = enew[i] / width;
  }
}
void CalculateCarpenterSampleCorrection::calculate_ms_correction(
    const double angle_deg, const double radius, const double coeff1,
    const double coeff2, const double coeff3, const Points &wavelength,
    HistogramY &y_val) {

  const size_t NUM_Y = y_val.size();
  bool is_histogram = false;
  if (wavelength.size() == NUM_Y + 1)
    is_histogram = true;
  else if (wavelength.size() == NUM_Y)
    is_histogram = false;
  else
    throw std::runtime_error("Data is neither historgram or density");

  // initialize Z array for this angle
  vector<double> Z = createZ(angle_deg);

  const double Q2 = coeff1 * coeff2;
  const double sigsct = coeff2 * coeff3;

  for (size_t j = 0; j < NUM_Y; j++) {
    double wl_val = wavelength[j];
    if (is_histogram) // average with next value
      wl_val = .5 * (wl_val + wavelength[j + 1]);

    y_val[j] = calculate_ms_factor(radius, Q2, sigsct, Z, wl_val);
  }
}
示例#3
0
/** Rebunches point data data according to n_bunch input
 *
 * @param xold :: old x data
 * @param yold :: old y data
 * @param eold :: old e data
 * @param xnew :: new x data
 * @param ynew :: new y data
 * @param enew :: new e data
 * @param n_bunch :: number of data points to bunch together for each new point
 * @throw runtime_error Thrown if algorithm cannot execute
 * @throw invalid_argument Thrown if input to function is incorrect
 **/
void Rebunch::rebunch_point(const HistogramX &xold, const HistogramY &yold,
                            const HistogramE &eold, HistogramX &xnew,
                            HistogramY &ynew, HistogramE &enew,
                            const size_t n_bunch) {

  size_t size_y = yold.size();
  double xsum, ysum, esum;
  size_t wbins = size_y / n_bunch;
  size_t rem = size_y % n_bunch;

  size_t i, j;
  int i_in = 0;
  j = 0;
  while (j < wbins) {
    xsum = 0.0;
    ysum = 0.0;
    esum = 0.0;
    for (i = 1; i <= n_bunch; i++) {
      xsum += xold[i_in];
      ysum += yold[i_in];
      esum += eold[i_in] * eold[i_in];
      i_in++;
    }
    // average contributing x values
    xnew[j] = xsum / static_cast<double>(n_bunch);
    ynew[j] = ysum / static_cast<double>(n_bunch);
    enew[j] = sqrt(esum) / static_cast<double>(n_bunch);
    j++;
  }
  if (rem != 0) {
    xsum = 0.0;
    ysum = 0.0;
    esum = 0.0;
    for (i = 1; i <= rem; i++) {
      xsum += xold[i_in];
      ysum += yold[i_in];
      esum += eold[i_in] * eold[i_in];
      i_in++;
    }
    xnew[j] = xsum / static_cast<double>(rem);
    ynew[j] = ysum / static_cast<double>(rem);
    enew[j] = sqrt(esum) / static_cast<double>(rem);
  }
}
示例#4
0
/** A Fourier transform of a derivative of order `n` has a factor of `i^n` where
 * `i` is the imaginary unit. This code multiplies the Fourier transform of the
 * input function `(re[j], im[j])` by `(2*pi*nu)^n` without using
 * `std::complex`.
 * @param nu :: complete real X of input histogram
 * @param &re :: complete real Y  of input histogram
 * @param &im :: complete imaginary Y of input histogram
*/
void FFTDerivative::multiplyTransform(HistogramX &nu, HistogramY &re,
                                      HistogramY &im) {
    int dn = getProperty("Order");
    bool swap_re_im = dn % 2 != 0;
    int sign_re = 1;
    int sign_im = -1;
    switch (dn % 4) {
    case 1:
        sign_re = 1;
        sign_im = -1;
        break;
    case 2:
        sign_re = -1;
        sign_im = -1;
        break;
    case 3:
        sign_re = -1;
        sign_im = 1;
        break;
    }
    // Multiply the transform by (2*pi*i*w)**dn
    for (size_t j = 0; j < re.size(); ++j) {
        double w = 2 * M_PI * nu[j];
        double ww = w;
        for (int k = dn; k > 1; --k) {
            ww *= w;
        }
        double a = sign_re * re[j] * ww;
        double b = sign_im * im[j] * ww;
        if (swap_re_im) {
            re[j] = b;
            im[j] = a;
        } else {
            re[j] = a;
            im[j] = b;
        }
    }
}