예제 #1
0
int UnwrapSNS::unwrapX(const MantidVec &datain, MantidVec &dataout,
                       const double &Ld) {
  MantidVec tempX_L; // lower half - to be frame wrapped
  tempX_L.reserve(m_XSize);
  tempX_L.clear();
  MantidVec tempX_U; // upper half - to not be frame wrapped
  tempX_U.reserve(m_XSize);
  tempX_U.clear();

  double filterVal = m_Tmin * Ld / m_LRef;
  dataout.clear();
  int specialBin = 0;
  for (int bin = 0; bin < m_XSize; ++bin) {
    // This is the time-of-flight value under consideration in the current
    // iteration of the loop
    const double tof = datain[bin];
    if (tof < filterVal) {
      tempX_L.push_back(tof + m_frameWidth);
      // Record the bins that fall in this range for copying over the data &
      // errors
      if (specialBin < bin)
        specialBin = bin;
    } else {
      tempX_U.push_back(tof);
    }
  } // loop over X values

  // now put it back into the vector supplied
  dataout.clear();
  dataout.insert(dataout.begin(), tempX_U.begin(), tempX_U.end());
  dataout.insert(dataout.end(), tempX_L.begin(), tempX_L.end());
  assert(datain.size() == dataout.size());

  return specialBin;
}
예제 #2
0
/**
 * Use the binning information to generate a x-axis.
 *
 * @param xValues The new x-axis.
 * @param xmin The x-min to be used.
 * @param xmax The x-max to be used.
 *
 * @return The final delta value (absolute value).
 */
double ResampleX::determineBinning(MantidVec &xValues, const double xmin,
                                   const double xmax) {
  xValues.clear(); // clear out the x-values

  int numBoundaries(0);
  int reqNumBoundaries(m_numBins);
  int expNumBoundaries(m_numBins);
  if (m_isDistribution)
    reqNumBoundaries -= 1; // to get the VectorHelper to do the right thing
  else
    expNumBoundaries += 1; // should be one more bin boundary for histograms

  vector<double> params; // xmin, delta, xmax
  params.push_back(xmin);
  params.push_back(0.); // dummy delta value
  params.push_back(xmax);

  // constant binning is easy
  if (m_useLogBinning) {
    if (xmin == 0)
      throw std::invalid_argument("Cannot calculate log of xmin=0");
    if (xmax == 0)
      throw std::invalid_argument("Cannot calculate log of xmax=0");

    const int MAX_ITER(100); // things went wrong if we get this far

    // starting delta value assuming everything happens exactly
    double delta = (log(xmax) - log(xmin)) / static_cast<double>(m_numBins);
    double shift = .1;
    int sign = 0;
    for (int numIter = 0; numIter < MAX_ITER; ++numIter) {
      params[1] = -1. * delta;
      if (!m_isDistribution)
        params[2] = xmax + delta;
      numBoundaries =
          VectorHelper::createAxisFromRebinParams(params, xValues, true);

      if (numBoundaries == expNumBoundaries) {
        double diff = (xmax - xValues.back());
        if (diff != 0.) {
          g_log.debug()
              << "Didn't get the exact xmax value: [xmax - xValues.back()="
              << diff << "] [relative diff = " << fabs(100. * diff / xmax)
              << "%]\n";
          g_log.debug() << "Resetting final x-value to xmax\n";
          *(xValues.rbegin()) = xmax;
        }
        break;
      } else if (numBoundaries > expNumBoundaries) // too few points
      {
        delta *= (1. + shift);
        if (sign < 0)
          shift *= .9;
        sign = 1;
      } else // too many points
      {
        delta *= (1. - shift);
        if (sign > 0)
          shift *= .9;
        sign = -1;
      }
    }
  } else {
    params[1] = (xmax - xmin) / static_cast<double>(reqNumBoundaries);
    numBoundaries =
        VectorHelper::createAxisFromRebinParams(params, xValues, true);
  }

  if (numBoundaries != expNumBoundaries) {
    g_log.warning()
        << "Did not generate the requested number of bins: generated "
        << numBoundaries << " requested " << expNumBoundaries << "\n";
  }

  // return the delta value so the caller can do debug printing
  return params[1];
}
예제 #3
0
/**
 * Get a data array covering the specified range of data, at the specified
 * resolution.  NOTE: The calling code is responsible for deleting the
 * DataArray that is constructed in and returned by this method.
 *
 * @param xMin    Left edge of region to be covered.
 * @param xMax    Right edge of region to be covered.
 * @param yMin    Bottom edge of region to be covered.
 * @param yMax    Top edge of region to be covered.
 * @param numRows Number of rows to return. If the number of rows is less
 *                than the actual number of data rows in [yMin,yMax], the
 *                data will be subsampled, and only the specified number
 *                of rows will be returned.
 * @param numCols The specrum data will be rebinned using the specified
 *                number of colums.
 * @param isLogX  Flag indicating whether or not the data should be
 *                binned logarithmically.
 */
DataArray_const_sptr MatrixWSDataSource::getDataArray( double xMin,    double  xMax,
                                                       double yMin,    double  yMax,
                                                       size_t numRows, size_t  numCols,
                                                       bool   isLogX )
{
  /* Since we're rebinning, the columns can be arbitrary */
  /* but rows must be aligned to get whole spectra */
  size_t first_row;
  SVUtils::CalculateInterval( m_totalYMin, m_totalYMax, m_totalRows,
                              first_row, yMin, yMax, numRows );

  std::vector<float> newData(numRows * numCols);

  MantidVec xScale;
  xScale.resize(numCols + 1);
  if ( isLogX )
  {
    for ( size_t i = 0; i < numCols+1; i++ )
    {
      xScale[i] = xMin * exp ( (double)i / (double)numCols * log(xMax/xMin) );
    }
  }
  else
  {
    double dx = (xMax - xMin) / ((double)numCols + 1.0);
    for ( size_t i = 0; i < numCols+1; i++ )
    {
      xScale[i] = xMin + (double)i * dx;
    }
  }

  // Choose spectra from required range of spectrum indexes
  double yStep = (yMax - yMin) / (double)numRows;
  double dYIndex;

  MantidVec yVals;
  MantidVec err;
  yVals.resize(numCols);
  err.resize(numCols);
  size_t index = 0;
  for ( size_t i = 0; i < numRows; i++ )
  {
    double midY = yMin + ((double)i + 0.5) * yStep;
    SVUtils::Interpolate( m_totalYMin, m_totalYMax,         midY,
                          0.0,         (double)m_totalRows, dYIndex );
    size_t sourceRow = (size_t)dYIndex;
    yVals.clear();
    err.clear();
    yVals.resize(numCols, 0);
    err.resize(numCols, 0);

    m_matWs->generateHistogram( sourceRow, xScale, yVals, err, true );
    for ( size_t col = 0; col < numCols; col++ )
    {
      newData[index] = (float)yVals[col];
      index++;
    }
  }

  // The calling code is responsible for deleting the DataArray when it is done with it
  DataArray_const_sptr newDataArray( new DataArray( xMin, xMax, yMin, yMax,
                                                    isLogX,
                                                    numRows, numCols,
                                                    newData) );

  return newDataArray;
}