/** Calculates the rebin parameters in the case where the bins of the two * workspaces intersect. * 'Intersect' is used in the sense of two intersecting sets. * @param X1 :: The bin boundaries from the first workspace * @param i :: Indicates the index in X1 immediately before the overlap * region starts * @param X2 :: The bin boundaries from the second workspace * @param params :: A reference to the vector of rebinning parameters */ void MergeRuns::intersectionParams(const HistogramX &X1, int64_t &i, const HistogramX &X2, std::vector<double> ¶ms) const { // First calculate the number of bins in each workspace that are in the // overlap region int64_t overlapbins1, overlapbins2; overlapbins1 = X1.size() - i; for (overlapbins2 = 0; X2[overlapbins2] < X1.back(); ++overlapbins2) { } // We want to use whichever one has the larger bins (on average) if (overlapbins1 < overlapbins2) { // In this case we want the rest of the bins from the first workspace..... for (; i < static_cast<int64_t>(X1.size()); ++i) { params.push_back(X1[i] - X1[i - 1]); params.push_back(X1[i]); } // Now remove the last bin & boundary params.pop_back(); params.pop_back(); // ....and then the non-overlap ones from the second workspace for (size_t j = overlapbins2; j < X2.size(); ++j) { params.push_back(X2[j] - params.back()); params.push_back(X2[j]); } } else { // In this case we just have to add all the bins from the second workspace for (size_t j = 1; j < X2.size(); ++j) { params.push_back(X2[j] - params.back()); params.push_back(X2[j]); } } }
/** Calculates the rebin parameters in the case where the range of the second * workspace is * entirely within that of the first workspace. * 'Inclusion' is used in the sense of a set being included in anothre. * @param X1 :: The bin boundaries from the first workspace * @param i :: Indicates the index in X1 immediately before the overlap * region starts * @param X2 :: The bin boundaries from the second workspace * @param params :: A reference to the vector of rebinning parameters */ void MergeRuns::inclusionParams(const HistogramX &X1, int64_t &i, const HistogramX &X2, std::vector<double> ¶ms) const { // First calculate the number of bins in each workspace that are in the // overlap region int64_t overlapbins1, overlapbins2; for (overlapbins1 = 1; X1[i + overlapbins1] < X2.back(); ++overlapbins1) { } //++overlapbins1; overlapbins2 = X2.size() - 1; // In the overlap region, we want to use whichever one has the larger bins (on // average) if (overlapbins1 + 1 <= overlapbins2) { // In the case where the first workspace has larger bins it's easy // - just add the rest of X1's bins for (; i < static_cast<int64_t>(X1.size()); ++i) { params.push_back(X1[i] - X1[i - 1]); params.push_back(X1[i]); } } else { // In this case we want all of X2's bins first (without the first and last // boundaries) for (size_t j = 1; j < X2.size() - 1; ++j) { params.push_back(X2[j] - params.back()); params.push_back(X2[j]); } // And now those from X1 that lie above the overlap region i += overlapbins1; for (; i < static_cast<int64_t>(X1.size()); ++i) { params.push_back(X1[i] - params.back()); params.push_back(X1[i]); } } }
/** 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; } }
/** Calculates the rebin paramters in the case where the two input workspaces do * not overlap at all. * @param X1 :: The bin boundaries from the first workspace * @param X2 :: The bin boundaries from the second workspace * @param params :: A reference to the vector of rebinning parameters */ void MergeRuns::noOverlapParams(const HistogramX &X1, const HistogramX &X2, std::vector<double> ¶ms) const { // Add all the bins from the first workspace for (size_t i = 1; i < X1.size(); ++i) { params.push_back(X1[i - 1]); params.push_back(X1[i] - X1[i - 1]); } // Put a single bin in the 'gap' (but check first the 'gap' isn't zero) if (X1.back() < X2.front()) { params.push_back(X1.back()); params.push_back(X2.front() - X1.back()); } // Now add all the bins from the second workspace for (size_t j = 1; j < X2.size(); ++j) { params.push_back(X2[j - 1]); params.push_back(X2[j] - X2[j - 1]); } params.push_back(X2.back()); }