/** Creates the output workspace, setting the axes according to the input binning parameters * @param[in] inputWorkspace The input workspace * @param[in] binParams The bin parameters from the user * @param[out] newAxis The 'vertical' axis defined by the given parameters * @return A pointer to the newly-created workspace */ RebinnedOutput_sptr SofQW3::setUpOutputWorkspace(API::MatrixWorkspace_const_sptr inputWorkspace, const std::vector<double> & binParams, std::vector<double>& newAxis) { // Create vector to hold the new X axis values MantidVecPtr xAxis; xAxis.access() = inputWorkspace->readX(0); const int xLength = static_cast<int>(xAxis->size()); // Create a vector to temporarily hold the vertical ('y') axis and populate that const int yLength = static_cast<int>(VectorHelper::createAxisFromRebinParams(binParams,newAxis)); // Create the output workspace MatrixWorkspace_sptr temp = WorkspaceFactory::Instance().create("RebinnedOutput", yLength - 1, xLength, xLength - 1); RebinnedOutput_sptr outputWorkspace = boost::static_pointer_cast<RebinnedOutput>(temp); WorkspaceFactory::Instance().initializeFromParent(inputWorkspace, outputWorkspace, true); // Create a numeric axis to replace the default vertical one Axis* const verticalAxis = new NumericAxis(yLength); outputWorkspace->replaceAxis(1, verticalAxis); // Now set the axis values for (int i = 0; i < yLength - 1; ++i) { outputWorkspace->setX(i, xAxis); verticalAxis->setValue(i, newAxis[i]); } // One more to set on the 'y' axis verticalAxis->setValue(yLength - 1, newAxis[yLength - 1]); // Set the axis units verticalAxis->unit() = UnitFactory::Instance().create("MomentumTransfer"); verticalAxis->title() = "|Q|"; // Set the X axis title (for conversion to MD) outputWorkspace->getAxis(0)->title() = "Energy transfer"; return outputWorkspace; }
/** * Execution path for NormalisedPolygon Rebinning * @param inputWS : Workspace to be rebinned * @param vertexes : TableWorkspace for debugging purposes * @param dumpVertexes : determines whether vertexes will be written to for * debugging purposes or not * @param outputDimensions : used for the column headings for Dump Vertexes */ MatrixWorkspace_sptr ReflectometryTransform::executeNormPoly( MatrixWorkspace_const_sptr inputWS, boost::shared_ptr<Mantid::DataObjects::TableWorkspace> &vertexes, bool dumpVertexes, std::string outputDimensions) const { MatrixWorkspace_sptr temp = WorkspaceFactory::Instance().create( "RebinnedOutput", m_d1NumBins, m_d0NumBins, m_d0NumBins); RebinnedOutput_sptr outWS = boost::static_pointer_cast<RebinnedOutput>(temp); const double widthD0 = (m_d0Max - m_d0Min) / double(m_d0NumBins); const double widthD1 = (m_d1Max - m_d1Min) / double(m_d1NumBins); std::vector<double> xBinsVec; std::vector<double> zBinsVec; VectorHelper::createAxisFromRebinParams({m_d1Min, widthD1, m_d1Max}, zBinsVec); VectorHelper::createAxisFromRebinParams({m_d0Min, widthD0, m_d0Max}, xBinsVec); // Put the correct bin boundaries into the workspace auto verticalAxis = new BinEdgeAxis(zBinsVec); outWS->replaceAxis(1, verticalAxis); for (size_t i = 0; i < zBinsVec.size() - 1; ++i) outWS->setX(i, xBinsVec); verticalAxis->title() = m_d1Label; // Prepare the required theta values DetectorAngularCache cache = initAngularCaches(inputWS.get()); m_theta = cache.thetas; m_thetaWidths = cache.thetaWidths; const size_t nHistos = inputWS->getNumberHistograms(); const size_t nBins = inputWS->blocksize(); // Holds the spectrum-detector mapping std::vector<specnum_t> specNumberMapping; std::vector<detid_t> detIDMapping; // Create a table for the output if we want to debug vertex positioning addColumnHeadings(vertexes, outputDimensions); for (size_t i = 0; i < nHistos; ++i) { IDetector_const_sptr detector = inputWS->getDetector(i); if (!detector || detector->isMasked() || detector->isMonitor()) { continue; } // Compute polygon points const double theta = m_theta[i]; const double thetaWidth = m_thetaWidths[i]; const double thetaHalfWidth = 0.5 * thetaWidth; const double thetaLower = theta - thetaHalfWidth; const double thetaUpper = theta + thetaHalfWidth; const MantidVec &X = inputWS->readX(i); const MantidVec &Y = inputWS->readY(i); const MantidVec &E = inputWS->readE(i); for (size_t j = 0; j < nBins; ++j) { const double lamLower = X[j]; const double lamUpper = X[j + 1]; const double signal = Y[j]; const double error = E[j]; auto inputQ = m_calculator->createQuad(lamUpper, lamLower, thetaUpper, thetaLower); FractionalRebinning::rebinToFractionalOutput(inputQ, inputWS, i, j, outWS, zBinsVec); // Find which qy bin this point lies in const auto qIndex = std::upper_bound(zBinsVec.begin(), zBinsVec.end(), inputQ[0].Y()) - zBinsVec.begin(); if (qIndex != 0 && qIndex < static_cast<int>(zBinsVec.size())) { // Add this spectra-detector pair to the mapping specNumberMapping.push_back( outWS->getSpectrum(qIndex - 1).getSpectrumNo()); detIDMapping.push_back(detector->getID()); } // Debugging if (dumpVertexes) { writeRow(vertexes, inputQ[0], i, j, signal, error); writeRow(vertexes, inputQ[1], i, j, signal, error); writeRow(vertexes, inputQ[2], i, j, signal, error); writeRow(vertexes, inputQ[3], i, j, signal, error); } } } outWS->finalize(); FractionalRebinning::normaliseOutput(outWS, inputWS); // Set the output spectrum-detector mapping SpectrumDetectorMapping outputDetectorMap(specNumberMapping, detIDMapping); outWS->updateSpectraUsing(outputDetectorMap); outWS->getAxis(0)->title() = m_d0Label; outWS->setYUnit(""); outWS->setYUnitLabel("Intensity"); return outWS; }