/** Write data in SLOG format */ void SaveGSS::writeSLOGdata(const int bank, const bool MultiplyByBinWidth, std::stringstream &out, const MantidVec &X, const MantidVec &Y, const MantidVec &E) const { const size_t datasize = Y.size(); double bc1 = X.front(); // minimum TOF in microseconds if (bc1 <= 0.) { throw std::runtime_error( "Cannot write out logarithmic data starting at zero"); } double bc2 = 0.5 * (*(X.rbegin()) + *(X.rbegin() + 1)); // maximum TOF (in microseconds?) double bc3 = (*(X.begin() + 1) - bc1) / bc1; // deltaT/T g_log.debug() << "SaveGSS(): Min TOF = " << bc1 << std::endl; writeBankLine(out, "SLOG", bank, datasize); out << std::fixed << " " << std::setprecision(0) << std::setw(10) << bc1 << std::fixed << " " << std::setprecision(0) << std::setw(10) << bc2 << std::fixed << " " << std::setprecision(7) << std::setw(10) << bc3 << std::fixed << " 0 FXYE" << std::endl; for (size_t i = 0; i < datasize; i++) { double y = Y[i]; double e = E[i]; if (MultiplyByBinWidth) { // Multiple by bin width as double delta = X[i + 1] - X[i]; y *= delta; e *= delta; } e = fixErrorValue(e); out << " " << std::fixed << std::setprecision(9) << std::setw(20) << 0.5 * (X[i] + X[i + 1]) << " " << std::fixed << std::setprecision(9) << std::setw(20) << y << " " << std::fixed << std::setprecision(9) << std::setw(20) << e << std::setw(12) << " " << "\n"; // let it flush its own buffer } out << std::flush; return; }
/** * 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]; }