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; }
/** * 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]; }
/** * 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; }