/** * Creates the output workspace for this algorithm * @param inputWorkspace A parent workspace to initialize from. * @return A pointer to the output workspace. */ API::MatrixWorkspace_sptr Transpose::createOutputWorkspace( API::MatrixWorkspace_const_sptr inputWorkspace) { Mantid::API::Axis *yAxis = getVerticalAxis(inputWorkspace); const size_t oldNhist = inputWorkspace->getNumberHistograms(); const auto &inX = inputWorkspace->x(0); const size_t oldYlength = inputWorkspace->blocksize(); const size_t oldVerticalAxislength = yAxis->length(); // The input Y axis may be binned so the new X data should be too size_t newNhist(oldYlength), newXsize(oldVerticalAxislength), newYsize(oldNhist); MatrixWorkspace_sptr outputWorkspace = inputWorkspace->cloneEmpty(); outputWorkspace->initialize(newNhist, newXsize, newYsize); outputWorkspace->setTitle(inputWorkspace->getTitle()); outputWorkspace->setComment(inputWorkspace->getComment()); outputWorkspace->copyExperimentInfoFrom(inputWorkspace.get()); outputWorkspace->setYUnit(inputWorkspace->YUnit()); outputWorkspace->setYUnitLabel(inputWorkspace->YUnitLabel()); outputWorkspace->setDistribution(inputWorkspace->isDistribution()); // Create a new numeric axis for Y the same length as the old X array // Values come from input X API::NumericAxis *newYAxis(nullptr); if (inputWorkspace->isHistogramData()) { newYAxis = new API::BinEdgeAxis(inX.rawData()); } else { newYAxis = new API::NumericAxis(inX.rawData()); } newYAxis->unit() = inputWorkspace->getAxis(0)->unit(); outputWorkspace->getAxis(0)->unit() = inputWorkspace->getAxis(1)->unit(); outputWorkspace->replaceAxis(1, newYAxis); setProperty("OutputWorkspace", outputWorkspace); return outputWorkspace; }
/** * Creates the output workspace for this algorithm * @param inputWorkspace A parent workspace to initialize from. * @return A pointer to the output workspace. */ API::MatrixWorkspace_sptr Transpose::createOutputWorkspace( API::MatrixWorkspace_const_sptr inputWorkspace) { Mantid::API::Axis *yAxis = getVerticalAxis(inputWorkspace); const size_t oldNhist = inputWorkspace->getNumberHistograms(); const MantidVec &inX = inputWorkspace->readX(0); const size_t oldYlength = inputWorkspace->blocksize(); const size_t oldVerticalAxislength = yAxis->length(); // The input Y axis may be binned so the new X data should be too size_t newNhist(oldYlength), newXsize(oldVerticalAxislength), newYsize(oldNhist); MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create( inputWorkspace, newNhist, newXsize, newYsize); // Create a new numeric axis for Y the same length as the old X array // Values come from input X API::NumericAxis *newYAxis(nullptr); if (inputWorkspace->isHistogramData()) { newYAxis = new API::BinEdgeAxis(inX); } else { newYAxis = new API::NumericAxis(inX); } newYAxis->unit() = inputWorkspace->getAxis(0)->unit(); outputWorkspace->getAxis(0)->unit() = inputWorkspace->getAxis(1)->unit(); outputWorkspace->replaceAxis(1, newYAxis); setProperty("OutputWorkspace", outputWorkspace); return outputWorkspace; }
/** 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 */ API::MatrixWorkspace_sptr SofQWCentre::setUpOutputWorkspace( API::MatrixWorkspace_const_sptr inputWorkspace, const std::vector<double> &binParams, std::vector<double> &newAxis) { // Create vector to hold the new X axis values HistogramData::BinEdges xAxis(inputWorkspace->sharedX(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 outputWorkspace = WorkspaceFactory::Instance().create( inputWorkspace, yLength - 1, xLength, xLength - 1); // Create a numeric axis to replace the default vertical one Axis *const verticalAxis = new BinEdgeAxis(newAxis); outputWorkspace->replaceAxis(1, verticalAxis); // Now set the axis values for (int i = 0; i < yLength - 1; ++i) { outputWorkspace->setBinEdges(i, xAxis); } // 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"; outputWorkspace->setYUnit(""); outputWorkspace->setYUnitLabel("Intensity"); return outputWorkspace; }
/** Creates the output workspace, setting the X vector to the bins boundaries in * Qx. * @return A pointer to the newly-created workspace */ API::MatrixWorkspace_sptr Qxy::setUpOutputWorkspace(API::MatrixWorkspace_const_sptr inputWorkspace) { const double max = getProperty("MaxQxy"); const double delta = getProperty("DeltaQ"); int bins = static_cast<int>(max / delta); if (bins * delta != max) ++bins; // Stop at first boundary past MaxQxy if max is not a multiple of // delta const double startVal = -1.0 * delta * bins; bins *= 2; // go from -max to +max bins += 1; // Add 1 - this is a histogram // Create an output workspace with the same meta-data as the input MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create( inputWorkspace, bins - 1, bins, bins - 1); // ... but clear the masking from the parameter map as we don't want to carry // that over since this is essentially // a 2D rebin ParameterMap &pmap = outputWorkspace->instrumentParameters(); pmap.clearParametersByName("masked"); // Create a numeric axis to replace the vertical one Axis *verticalAxis = new BinEdgeAxis(bins); outputWorkspace->replaceAxis(1, verticalAxis); // Build up the X values Kernel::cow_ptr<MantidVec> axis; MantidVec &horizontalAxisRef = axis.access(); horizontalAxisRef.resize(bins); for (int i = 0; i < bins; ++i) { const double currentVal = startVal + i * delta; // Set the X value horizontalAxisRef[i] = currentVal; // Set the Y value on the axis verticalAxis->setValue(i, currentVal); } // Fill the X vectors in the output workspace for (int i = 0; i < bins - 1; ++i) { outputWorkspace->setX(i, axis); for (int j = 0; j < bins - j; ++j) { outputWorkspace->dataY(i)[j] = std::numeric_limits<double>::quiet_NaN(); outputWorkspace->dataE(i)[j] = std::numeric_limits<double>::quiet_NaN(); } } // Set the axis units outputWorkspace->getAxis(1)->unit() = outputWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create("MomentumTransfer"); // Set the 'Y' unit (gets confusing here...this is probably a Z axis in this // case) outputWorkspace->setYUnitLabel("Cross Section (1/cm)"); setProperty("OutputWorkspace", outputWorkspace); return outputWorkspace; }
/**Copy the meta data for the input workspace to an output workspace and create *it with the desired number of spectra. * Also labels the axis of each spectra with Yi, where i is the index * * @param inws :: The input workspace as a shared pointer * @param size :: The number of spectra the workspace should be created with * @return The pointer to the newly created workspace */ API::MatrixWorkspace_sptr SplineSmoothing::setupOutputWorkspace(const MatrixWorkspace_sptr &inws, const int size) const { // Must pass a shared pointer instead of a reference as the // workspace factory will not accept raw pointers. MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(inws, size); // create labels for output workspace auto tAxis = new API::TextAxis(size); for (int i = 0; i < size; ++i) { const std::string index = std::to_string(i); tAxis->setLabel(i, "Y" + index); } outputWorkspace->replaceAxis(1, tAxis); return outputWorkspace; }
/// Create the efficiency workspace by combining single spectra workspaces into /// one. /// @param labels :: Axis labels for each workspace. /// @param workspaces :: Workspaces to put together. MatrixWorkspace_sptr JoinISISPolarizationEfficiencies::createEfficiencies( std::vector<std::string> const &labels, std::vector<MatrixWorkspace_sptr> const &workspaces) { auto interpolatedWorkspaces = interpolateWorkspaces(workspaces); auto const &inWS = interpolatedWorkspaces.front(); MatrixWorkspace_sptr outWS = DataObjects::create<Workspace2D>( *inWS, labels.size(), inWS->histogram(0)); auto axis1 = new TextAxis(labels.size()); outWS->replaceAxis(1, axis1); outWS->getAxis(0)->setUnit("Wavelength"); for (size_t i = 0; i < interpolatedWorkspaces.size(); ++i) { auto &ws = interpolatedWorkspaces[i]; outWS->setHistogram(i, ws->histogram(0)); axis1->setLabel(i, labels[i]); } return outWS; }
/** Create the final output workspace after converting the X axis * @returns the final output workspace * * @param progress :: Progress indicator * @param targetUnit :: Target conversion unit * @param inputWS :: Input workspace * @param nHist :: Stores the number of histograms */ MatrixWorkspace_sptr ConvertSpectrumAxis2::createOutputWorkspace( API::Progress &progress, const std::string &targetUnit, API::MatrixWorkspace_sptr &inputWS, size_t nHist) { // Create the output workspace. Can not re-use the input one because the // spectra are re-ordered. MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create( inputWS, m_indexMap.size(), inputWS->x(0).size(), inputWS->y(0).size()); // Now set up a new numeric axis holding the theta values corresponding to // each spectrum. auto const newAxis = new NumericAxis(m_indexMap.size()); outputWorkspace->replaceAxis(1, newAxis); progress.setNumSteps(nHist + m_indexMap.size()); // Set the units of the axis. if (targetUnit == "theta" || targetUnit == "Theta" || targetUnit == "signed_theta" || targetUnit == "SignedTheta") { newAxis->unit() = boost::make_shared<Units::Degrees>(); } else if (targetUnit == "ElasticQ") { newAxis->unit() = UnitFactory::Instance().create("MomentumTransfer"); } else if (targetUnit == "ElasticQSquared") { newAxis->unit() = UnitFactory::Instance().create("QSquared"); } std::multimap<double, size_t>::const_iterator it; size_t currentIndex = 0; for (it = m_indexMap.begin(); it != m_indexMap.end(); ++it) { // Set the axis value. newAxis->setValue(currentIndex, it->first); // Copy over the data. outputWorkspace->setHistogram(currentIndex, inputWS->histogram(it->second)); // We can keep the spectrum numbers etc. outputWorkspace->getSpectrum(currentIndex) .copyInfoFrom(inputWS->getSpectrum(it->second)); ++currentIndex; progress.report("Creating output workspace..."); } return outputWorkspace; }
/** Populate output workspace with results * @param outWS :: [input/output] Output workspace to populate * @param nplots :: [input] Number of histograms */ void PlotAsymmetryByLogValue::populateOutputWorkspace( MatrixWorkspace_sptr &outWS, int nplots) { auto tAxis = new TextAxis(nplots); if (nplots == 1) { size_t i = 0; for (auto &value : m_logValue) { outWS->dataX(0)[i] = value.second; outWS->dataY(0)[i] = m_redY[value.first]; outWS->dataE(0)[i] = m_redE[value.first]; i++; } tAxis->setLabel(0, "Asymmetry"); } else { size_t i = 0; for (auto &value : m_logValue) { outWS->dataX(0)[i] = value.second; outWS->dataY(0)[i] = m_diffY[value.first]; outWS->dataE(0)[i] = m_diffE[value.first]; outWS->dataX(1)[i] = value.second; outWS->dataY(1)[i] = m_redY[value.first]; outWS->dataE(1)[i] = m_redE[value.first]; outWS->dataX(2)[i] = value.second; outWS->dataY(2)[i] = m_greenY[value.first]; outWS->dataE(2)[i] = m_greenE[value.first]; outWS->dataX(3)[i] = value.second; outWS->dataY(3)[i] = m_sumY[value.first]; outWS->dataE(3)[i] = m_sumE[value.first]; i++; } tAxis->setLabel(0, "Red-Green"); tAxis->setLabel(1, "Red"); tAxis->setLabel(2, "Green"); tAxis->setLabel(3, "Red+Green"); } outWS->replaceAxis(1, tAxis); outWS->getAxis(0)->title() = m_logName; outWS->setYUnitLabel("Asymmetry"); }
/** * Setup the output workspace * @param parent :: A pointer to the input workspace * @param newXBins [out] :: An output vector to be filled with the new X bin boundaries * @param newYBins [out] :: An output vector to be filled with the new Y bin boundaries * @return A pointer to the output workspace */ MatrixWorkspace_sptr Rebin2D::createOutputWorkspace(MatrixWorkspace_const_sptr parent, MantidVec & newXBins, MantidVec & newYBins) const { using Kernel::VectorHelper::createAxisFromRebinParams; // First create the two sets of bin boundaries const int newXSize = createAxisFromRebinParams(getProperty("Axis1Binning"), newXBins); const int newYSize = createAxisFromRebinParams(getProperty("Axis2Binning"), newYBins); // and now the workspace MatrixWorkspace_sptr outputWS; if (!this->useFractionalArea) { outputWS = WorkspaceFactory::Instance().create(parent,newYSize-1,newXSize,newXSize-1); } else { outputWS = WorkspaceFactory::Instance().create("RebinnedOutput", newYSize-1, newXSize, newXSize-1); WorkspaceFactory::Instance().initializeFromParent(parent, outputWS, true); } Axis* const verticalAxis = new NumericAxis(newYSize); // Meta data verticalAxis->unit() = parent->getAxis(1)->unit(); verticalAxis->title() = parent->getAxis(1)->title(); outputWS->replaceAxis(1,verticalAxis); // Now set the axis values for (size_t i=0; i < static_cast<size_t>(newYSize-1); ++i) { outputWS->setX(i,newXBins); verticalAxis->setValue(i,newYBins[i]); } // One more to set on the 'y' axis verticalAxis->setValue(newYSize-1,newYBins[newYSize-1]); return outputWS; }
/** Execute the algorithm. */ void ResampleX::exec() { // generically having access to the input workspace is a good idea MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); bool inPlace = (inputWS == outputWS); // Rebinning in-place m_isDistribution = inputWS->isDistribution(); m_isHistogram = inputWS->isHistogramData(); const int numSpectra = static_cast<int>(inputWS->getNumberHistograms()); // the easy parameters m_useLogBinning = getProperty("LogBinning"); m_numBins = getProperty("NumberBins"); m_preserveEvents = getProperty("PreserveEvents"); // determine the xmin/xmax for the workspace vector<double> xmins = getProperty("XMin"); vector<double> xmaxs = getProperty("XMax"); string error = determineXMinMax(inputWS, xmins, xmaxs); if (!error.empty()) throw std::runtime_error(error); bool common_limits = true; { double xmin_common = xmins[0]; double xmax_common = xmaxs[0]; for (size_t i = 1; i < xmins.size(); ++i) { if (xmins[i] != xmin_common) { common_limits = false; break; } if (xmaxs[i] != xmax_common) { common_limits = false; break; } } } if (common_limits) { g_log.debug() << "Common limits between all spectra\n"; } else { g_log.debug() << "Does not have common limits between all spectra\n"; } // start doing actual work EventWorkspace_const_sptr inputEventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); if (inputEventWS != nullptr) { if (m_preserveEvents) { if (inPlace) { g_log.debug() << "Rebinning event workspace in place\n"; } else { g_log.debug() << "Rebinning event workspace out of place\n"; outputWS = inputWS->clone(); } auto outputEventWS = boost::dynamic_pointer_cast<EventWorkspace>(outputWS); if (common_limits) { // get the delta from the first since they are all the same BinEdges xValues(0); const double delta = this->determineBinning(xValues.mutableRawData(), xmins[0], xmaxs[0]); g_log.debug() << "delta = " << delta << "\n"; outputEventWS->setAllX(xValues); } else { // initialize progress reporting. Progress prog(this, 0.0, 1.0, numSpectra); // do the rebinning PARALLEL_FOR_IF(Kernel::threadSafe(*inputEventWS, *outputWS)) for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) { PARALLEL_START_INTERUPT_REGION BinEdges xValues(0); const double delta = this->determineBinning( xValues.mutableRawData(), xmins[wkspIndex], xmaxs[wkspIndex]); g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta << " xmin=" << xmins[wkspIndex] << " xmax=" << xmaxs[wkspIndex] << "\n"; outputEventWS->setHistogram(wkspIndex, xValues); prog.report(name()); // Report progress PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION } } // end if (m_preserveEvents) else // event workspace -> matrix workspace { //--------- Different output, OR you're inplace but not preserving Events g_log.information() << "Creating a Workspace2D from the EventWorkspace " << inputEventWS->getName() << ".\n"; outputWS = create<DataObjects::Workspace2D>( *inputWS, numSpectra, HistogramData::BinEdges(m_numBins + 1)); // Initialize progress reporting. Progress prog(this, 0.0, 1.0, numSpectra); // Go through all the histograms and set the data PARALLEL_FOR_IF(Kernel::threadSafe(*inputEventWS, *outputWS)) for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) { PARALLEL_START_INTERUPT_REGION // Set the X axis for each output histogram MantidVec xValues; const double delta = this->determineBinning(xValues, xmins[wkspIndex], xmaxs[wkspIndex]); g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta << "\n"; outputWS->setBinEdges(wkspIndex, xValues); // Get a const event list reference. inputEventWS->dataY() doesn't work. const EventList &el = inputEventWS->getSpectrum(wkspIndex); MantidVec y_data, e_data; // The EventList takes care of histogramming. el.generateHistogram(xValues, y_data, e_data); // Copy the data over. outputWS->mutableY(wkspIndex) = std::move(y_data); outputWS->mutableE(wkspIndex) = std::move(e_data); // Report progress prog.report(name()); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Copy all the axes for (int i = 1; i < inputWS->axes(); i++) { outputWS->replaceAxis(i, inputWS->getAxis(i)->clone(outputWS.get())); outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit(); } // Copy the units over too. for (int i = 0; i < outputWS->axes(); ++i) { outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit(); } outputWS->setYUnit(inputEventWS->YUnit()); outputWS->setYUnitLabel(inputEventWS->YUnitLabel()); } // Assign it to the output workspace property setProperty("OutputWorkspace", outputWS); return; } else // (inputeventWS != NULL)
/** Reads the header information from a file containing 2D data * @param[in] initalLine the second line in the file * @param[out] outWrksp the workspace that the data will be writen to * @param[out] axis0Data x-values for the workspace * @return a progress bar object * @throw NotFoundError if there is compulsulary data is missing from the file * @throw invalid_argument if there is an inconsistency in the header information */ Progress LoadRKH::read2DHeader(const std::string & initalLine, MatrixWorkspace_sptr & outWrksp, MantidVec & axis0Data) { const std::string XUnit(readUnit(initalLine)); std::string fileLine; std::getline(m_fileIn, fileLine); const std::string YUnit(readUnit(fileLine)); std::getline(m_fileIn, fileLine); const std::string intensityUnit(readUnit(fileLine)); // the next line should contain just "1", but I'm not enforcing that std::getline(m_fileIn, fileLine); std::string title; std::getline(m_fileIn, title); std::getline(m_fileIn, fileLine); boost::trim(fileLine); const int nAxis0Boundaries = boost::lexical_cast<int>(fileLine); axis0Data.resize(nAxis0Boundaries); readNumEntrys(nAxis0Boundaries, axis0Data); std::getline(m_fileIn, fileLine); boost::trim(fileLine); int nAxis1Boundaries; try { nAxis1Boundaries = boost::lexical_cast<int>(fileLine); } catch(boost::bad_lexical_cast &) { // using readNumEntrys() above broke the sequence of getline()s and so try again in case we just read the end of a line std::getline(m_fileIn, fileLine); boost::trim(fileLine); nAxis1Boundaries = boost::lexical_cast<int>(fileLine); } MantidVec axis1Data(nAxis1Boundaries); readNumEntrys(nAxis1Boundaries, axis1Data); std::getline(m_fileIn, fileLine); // check for the file pointer being left at the end of a line if ( fileLine.size() < 5 ) { std::getline(m_fileIn, fileLine); } Poco::StringTokenizer wsDimensions(fileLine, " ", Poco::StringTokenizer::TOK_TRIM); if ( wsDimensions.count() < 2 ) { throw Exception::NotFoundError("Input file", "dimensions"); } const int nAxis0Values = boost::lexical_cast<int>(wsDimensions[0]); const int nAxis1Values = boost::lexical_cast<int>(wsDimensions[1]); Progress prog(this, 0.05, 1.0, 2*nAxis1Values); // we now have all the data we need to create the output workspace outWrksp = WorkspaceFactory::Instance().create( "Workspace2D", nAxis1Values, nAxis0Boundaries, nAxis0Values); outWrksp->getAxis(0)->unit() = UnitFactory::Instance().create(XUnit); outWrksp->setYUnitLabel(intensityUnit); NumericAxis* const axis1 = new Mantid::API::NumericAxis(nAxis1Boundaries); axis1->unit() = Mantid::Kernel::UnitFactory::Instance().create(YUnit); outWrksp->replaceAxis(1, axis1); for ( int i = 0; i < nAxis1Boundaries; ++i ) { axis1->setValue(i, axis1Data[i]); } outWrksp->setTitle(title); // move over the next line which is there to help with loading from Fortran routines std::getline(m_fileIn, fileLine); return prog; }
/** * Execute the algorithm. */ void RebinByTimeBase::exec() { using Mantid::DataObjects::EventWorkspace; IEventWorkspace_sptr inWS = getProperty("InputWorkspace"); if (!boost::dynamic_pointer_cast<EventWorkspace>(inWS)) { const std::string algName = this->name(); throw std::invalid_argument( algName + " Algorithm requires an EventWorkspace as an input."); } MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); // retrieve the properties const std::vector<double> inParams = getProperty("Params"); std::vector<double> rebinningParams; // workspace independent determination of length const int histnumber = static_cast<int>(inWS->getNumberHistograms()); const uint64_t nanoSecondsInASecond = static_cast<uint64_t>(1e9); const DateAndTime runStartTime = inWS->run().startTime(); // The validator only passes parameters with size 1, or 3xn. double tStep = 0; if (inParams.size() >= 3) { // Use the start of the run to offset the times provided by the user. pulse // time of the events are absolute. const DateAndTime startTime = runStartTime + inParams[0]; const DateAndTime endTime = runStartTime + inParams[2]; // Rebinning params in nanoseconds. rebinningParams.push_back( static_cast<double>(startTime.totalNanoseconds())); tStep = inParams[1] * nanoSecondsInASecond; rebinningParams.push_back(tStep); rebinningParams.push_back(static_cast<double>(endTime.totalNanoseconds())); } else if (inParams.size() == 1) { const uint64_t xmin = getMinX(inWS); const uint64_t xmax = getMaxX(inWS); rebinningParams.push_back(static_cast<double>(xmin)); tStep = inParams[0] * nanoSecondsInASecond; rebinningParams.push_back(tStep); rebinningParams.push_back(static_cast<double>(xmax)); } // Validate the timestep. if (tStep <= 0) { throw std::invalid_argument( "Cannot have a timestep less than or equal to zero."); } // Initialize progress reporting. Progress prog(this, 0.0, 1.0, histnumber); MantidVecPtr XValues_new; // create new X axis, with absolute times in seconds. const int ntcnew = VectorHelper::createAxisFromRebinParams( rebinningParams, XValues_new.access()); ConvertToRelativeTime transformToRelativeT(runStartTime); // Transform the output into relative times in seconds. MantidVec OutXValues_scaled(XValues_new->size()); std::transform(XValues_new->begin(), XValues_new->end(), OutXValues_scaled.begin(), transformToRelativeT); outputWS = WorkspaceFactory::Instance().create("Workspace2D", histnumber, ntcnew, ntcnew - 1); WorkspaceFactory::Instance().initializeFromParent(inWS, outputWS, true); // Copy all the axes for (int i = 1; i < inWS->axes(); i++) { outputWS->replaceAxis(i, inWS->getAxis(i)->clone(outputWS.get())); outputWS->getAxis(i)->unit() = inWS->getAxis(i)->unit(); } // X-unit is relative time since the start of the run. outputWS->getAxis(0)->unit() = boost::make_shared<Units::Time>(); // Copy the units over too. for (int i = 1; i < outputWS->axes(); ++i) { outputWS->getAxis(i)->unit() = inWS->getAxis(i)->unit(); } outputWS->setYUnit(inWS->YUnit()); outputWS->setYUnitLabel(inWS->YUnitLabel()); // Assign it to the output workspace property setProperty("OutputWorkspace", outputWS); // Go through all the histograms and set the data doHistogramming(inWS, outputWS, XValues_new, OutXValues_scaled, prog); }
/** Execute the algorithm. */ void ResampleX::exec() { // generically having access to the input workspace is a good idea MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); bool inPlace = (inputWS == outputWS); // Rebinning in-place m_isDistribution = inputWS->isDistribution(); m_isHistogram = inputWS->isHistogramData(); int numSpectra = static_cast<int>(inputWS->getNumberHistograms()); // the easy parameters m_useLogBinning = getProperty("LogBinning"); m_numBins = getProperty("NumberBins"); m_preserveEvents = getProperty("PreserveEvents"); // determine the xmin/xmax for the workspace vector<double> xmins = getProperty("XMin"); vector<double> xmaxs = getProperty("XMax"); string error = determineXMinMax(inputWS, xmins, xmaxs); if (!error.empty()) throw std::runtime_error(error); bool common_limits = true; { double xmin_common = xmins[0]; double xmax_common = xmaxs[0]; for (size_t i = 1; i < xmins.size(); ++i) { if (xmins[i] != xmin_common) { common_limits = false; break; } if (xmaxs[i] != xmax_common) { common_limits = false; break; } } } if (common_limits) { g_log.debug() << "Common limits between all spectra\n"; } else { g_log.debug() << "Does not have common limits between all spectra\n"; } // start doing actual work EventWorkspace_const_sptr inputEventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); if (inputEventWS != NULL) { if (m_preserveEvents) { EventWorkspace_sptr outputEventWS = boost::dynamic_pointer_cast<EventWorkspace>(outputWS); if (inPlace) { g_log.debug() << "Rebinning event workspace in place\n"; } else { g_log.debug() << "Rebinning event workspace out of place\n"; // copy the event workspace to a new EventWorkspace outputEventWS = boost::dynamic_pointer_cast<EventWorkspace>( API::WorkspaceFactory::Instance().create( "EventWorkspace", inputWS->getNumberHistograms(), 2, 1)); // copy geometry over. API::WorkspaceFactory::Instance().initializeFromParent( inputEventWS, outputEventWS, false); // copy over the data as well. outputEventWS->copyDataFrom((*inputEventWS)); } if (common_limits) { // get the delta from the first since they are all the same MantidVecPtr xValues; double delta = this->determineBinning(xValues.access(), xmins[0], xmaxs[0]); g_log.debug() << "delta = " << delta << "\n"; outputEventWS->setAllX(xValues); } else { // initialize progress reporting. Progress prog(this, 0.0, 1.0, numSpectra); // do the rebinning PARALLEL_FOR2(inputEventWS, outputWS) for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) { PARALLEL_START_INTERUPT_REGION MantidVec xValues; double delta = this->determineBinning(xValues, xmins[wkspIndex], xmaxs[wkspIndex]); g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta << " xmin=" << xmins[wkspIndex] << " xmax=" << xmaxs[wkspIndex] << "\n"; outputEventWS->getSpectrum(wkspIndex)->setX(xValues); prog.report(name()); // Report progress PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION } this->setProperty( "OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(outputEventWS)); } // end if (m_preserveEvents) else // event workspace -> matrix workspace { //--------- Different output, OR you're inplace but not preserving Events //--- create a Workspace2D ------- g_log.information() << "Creating a Workspace2D from the EventWorkspace " << inputEventWS->getName() << ".\n"; // Create a Workspace2D // This creates a new Workspace2D through a torturous route using the // WorkspaceFactory. // The Workspace2D is created with an EMPTY CONSTRUCTOR outputWS = WorkspaceFactory::Instance().create("Workspace2D", numSpectra, m_numBins, m_numBins - 1); WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, true); // Initialize progress reporting. Progress prog(this, 0.0, 1.0, numSpectra); // Go through all the histograms and set the data PARALLEL_FOR2(inputEventWS, outputWS) for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) { PARALLEL_START_INTERUPT_REGION // Set the X axis for each output histogram MantidVec xValues; double delta = this->determineBinning(xValues, xmins[wkspIndex], xmaxs[wkspIndex]); g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta << "\n"; outputWS->setX(wkspIndex, xValues); // Get a const event list reference. inputEventWS->dataY() doesn't work. const EventList &el = inputEventWS->getEventList(wkspIndex); MantidVec y_data, e_data; // The EventList takes care of histogramming. el.generateHistogram(xValues, y_data, e_data); // Copy the data over. outputWS->dataY(wkspIndex).assign(y_data.begin(), y_data.end()); outputWS->dataE(wkspIndex).assign(e_data.begin(), e_data.end()); // Report progress prog.report(name()); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Copy all the axes for (int i = 1; i < inputWS->axes(); i++) { outputWS->replaceAxis(i, inputWS->getAxis(i)->clone(outputWS.get())); outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit(); } // Copy the units over too. for (int i = 0; i < outputWS->axes(); ++i) outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit(); outputWS->setYUnit(inputEventWS->YUnit()); outputWS->setYUnitLabel(inputEventWS->YUnitLabel()); // Assign it to the output workspace property setProperty("OutputWorkspace", outputWS); } return; } else // (inputeventWS != NULL)
/** * Make 2D MatrixWorkspace */ void ConvertMDHistoToMatrixWorkspace::make2DWorkspace() { // get the input workspace IMDHistoWorkspace_sptr inputWorkspace = getProperty("InputWorkspace"); // find the non-integrated dimensions Mantid::Geometry::VecIMDDimension_const_sptr nonIntegDims = inputWorkspace->getNonIntegratedDimensions(); auto xDim = nonIntegDims[0]; auto yDim = nonIntegDims[1]; size_t nx = xDim->getNBins(); size_t ny = yDim->getNBins(); size_t xDimIndex = inputWorkspace->getDimensionIndexById(xDim->getDimensionId()); size_t xStride = calcStride(*inputWorkspace, xDimIndex); size_t yDimIndex = inputWorkspace->getDimensionIndexById(yDim->getDimensionId()); size_t yStride = calcStride(*inputWorkspace, yDimIndex); // get the normalization of the output std::string normProp = getPropertyValue("Normalization"); Mantid::API::MDNormalization normalization; if (normProp == "NoNormalization") { normalization = NoNormalization; } else if (normProp == "VolumeNormalization") { normalization = VolumeNormalization; } else if (normProp == "NumEventsNormalization") { normalization = NumEventsNormalization; } else { normalization = NoNormalization; } signal_t inverseVolume = static_cast<signal_t>(inputWorkspace->getInverseVolume()); // create the output workspace MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create("Workspace2D", ny, nx + 1, nx); // set the x-values Mantid::MantidVec &X = outputWorkspace->dataX(0); double dx = xDim->getBinWidth(); double x = xDim->getMinimum(); for (auto ix = X.begin(); ix != X.end(); ++ix, x += dx) { *ix = x; } // set the y-values and errors for (size_t i = 0; i < ny; ++i) { if (i > 0) outputWorkspace->setX(i, X); auto &Y = outputWorkspace->dataY(i); auto &E = outputWorkspace->dataE(i); size_t yOffset = i * yStride; for (size_t j = 0; j < nx; ++j) { size_t linearIndex = yOffset + j * xStride; signal_t signal = inputWorkspace->getSignalArray()[linearIndex]; signal_t error = inputWorkspace->getErrorSquaredArray()[linearIndex]; // apply normalization if (normalization != NoNormalization) { if (normalization == VolumeNormalization) { signal *= inverseVolume; error *= inverseVolume; } else // normalization == NumEventsNormalization { signal_t factor = inputWorkspace->getNumEventsArray()[linearIndex]; factor = factor != 0.0 ? 1.0 / factor : 1.0; signal *= factor; error *= factor; } } Y[j] = signal; E[j] = sqrt(error); } } // set the first axis auto labelX = boost::dynamic_pointer_cast<Kernel::Units::Label>( Kernel::UnitFactory::Instance().create("Label")); labelX->setLabel(xDim->getName()); outputWorkspace->getAxis(0)->unit() = labelX; // set the second axis auto yAxis = new NumericAxis(ny); for (size_t i = 0; i < ny; ++i) { yAxis->setValue(i, yDim->getX(i)); } auto labelY = boost::dynamic_pointer_cast<Kernel::Units::Label>( Kernel::UnitFactory::Instance().create("Label")); labelY->setLabel(yDim->getName()); yAxis->unit() = labelY; outputWorkspace->replaceAxis(1, yAxis); // set the "units" for the y values outputWorkspace->setYUnitLabel("Signal"); // done setProperty("OutputWorkspace", outputWorkspace); }
/** Executes the rebin algorithm * * @throw runtime_error Thrown if the bin range does not intersect the range of *the input workspace */ void Rebin::exec() { // Get the input workspace MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); // Are we preserving event workspace-iness? bool PreserveEvents = getProperty("PreserveEvents"); // Rebinning in-place bool inPlace = (inputWS == outputWS); std::vector<double> rbParams = rebinParamsFromInput(getProperty("Params"), *inputWS, g_log); const bool dist = inputWS->isDistribution(); const bool isHist = inputWS->isHistogramData(); // workspace independent determination of length const int histnumber = static_cast<int>(inputWS->getNumberHistograms()); //------------------------------------------------------- bool fullBinsOnly = getProperty("FullBinsOnly"); MantidVecPtr XValues_new; // create new output X axis const int ntcnew = VectorHelper::createAxisFromRebinParams( rbParams, XValues_new.access(), true, fullBinsOnly); //--------------------------------------------------------------------------------- // Now, determine if the input workspace is actually an EventWorkspace EventWorkspace_const_sptr eventInputWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); if (eventInputWS != NULL) { //------- EventWorkspace as input ------------------------------------- EventWorkspace_sptr eventOutputWS = boost::dynamic_pointer_cast<EventWorkspace>(outputWS); if (inPlace && PreserveEvents) { // -------------Rebin in-place, preserving events // ---------------------------------------------- // This only sets the X axis. Actual rebinning will be done upon data // access. eventOutputWS->setAllX(XValues_new); this->setProperty( "OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(eventOutputWS)); } else if (!inPlace && PreserveEvents) { // -------- NOT in-place, but you want to keep events for some reason. // ---------------------- // Must copy the event workspace to a new EventWorkspace (and bin that). // Make a brand new EventWorkspace eventOutputWS = boost::dynamic_pointer_cast<EventWorkspace>( API::WorkspaceFactory::Instance().create( "EventWorkspace", inputWS->getNumberHistograms(), 2, 1)); // Copy geometry over. API::WorkspaceFactory::Instance().initializeFromParent( inputWS, eventOutputWS, false); // You need to copy over the data as well. eventOutputWS->copyDataFrom((*eventInputWS)); // This only sets the X axis. Actual rebinning will be done upon data // access. eventOutputWS->setAllX(XValues_new); // Cast to the matrixOutputWS and save it this->setProperty( "OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(eventOutputWS)); } else { //--------- Different output, OR you're inplace but not preserving Events //--- create a Workspace2D ------- g_log.information() << "Creating a Workspace2D from the EventWorkspace " << eventInputWS->getName() << ".\n"; // Create a Workspace2D // This creates a new Workspace2D through a torturous route using the // WorkspaceFactory. // The Workspace2D is created with an EMPTY CONSTRUCTOR outputWS = WorkspaceFactory::Instance().create("Workspace2D", histnumber, ntcnew, ntcnew - 1); WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, true); // Initialize progress reporting. Progress prog(this, 0.0, 1.0, histnumber); // Go through all the histograms and set the data PARALLEL_FOR3(inputWS, eventInputWS, outputWS) for (int i = 0; i < histnumber; ++i) { PARALLEL_START_INTERUPT_REGION // Set the X axis for each output histogram outputWS->setX(i, XValues_new); // Get a const event list reference. eventInputWS->dataY() doesn't work. const EventList &el = eventInputWS->getEventList(i); MantidVec y_data, e_data; // The EventList takes care of histogramming. el.generateHistogram(*XValues_new, y_data, e_data); // Copy the data over. outputWS->dataY(i).assign(y_data.begin(), y_data.end()); outputWS->dataE(i).assign(e_data.begin(), e_data.end()); // Report progress prog.report(name()); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Copy all the axes for (int i = 1; i < inputWS->axes(); i++) { outputWS->replaceAxis(i, inputWS->getAxis(i)->clone(outputWS.get())); outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit(); } // Copy the units over too. for (int i = 0; i < outputWS->axes(); ++i) outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit(); outputWS->setYUnit(eventInputWS->YUnit()); outputWS->setYUnitLabel(eventInputWS->YUnitLabel()); // Assign it to the output workspace property setProperty("OutputWorkspace", outputWS); } } // END ---- EventWorkspace
/** * Executes the algorithm */ void PlotAsymmetryByLogValue::exec() { m_forward_list = getProperty("ForwardSpectra"); m_backward_list = getProperty("BackwardSpectra"); m_autogroup = ( m_forward_list.size() == 0 && m_backward_list.size() == 0); //double alpha = getProperty("Alpha"); std::string logName = getProperty("LogValue"); int red = getProperty("Red"); int green = getProperty("Green"); std::string stype = getProperty("Type"); m_int = stype == "Integral"; std::string firstFN = getProperty("FirstRun"); std::string lastFN = getProperty("LastRun"); std::string ext = firstFN.substr(firstFN.find_last_of(".")); firstFN.erase(firstFN.size()-4); lastFN.erase(lastFN.size()-4); std::string fnBase = firstFN; size_t i = fnBase.size()-1; while(isdigit(fnBase[i])) i--; if (i == fnBase.size()-1) { g_log.error("File name must end with a number."); throw Exception::FileError("File name must end with a number.",firstFN); } fnBase.erase(i+1); firstFN.erase(0,fnBase.size()); lastFN.erase(0,fnBase.size()); size_t is = atoi(firstFN.c_str()); // starting run number size_t ie = atoi(lastFN.c_str()); // last run number int w = static_cast<int>(firstFN.size()); // The number of runs size_t npoints = ie - is + 1; // Create the 2D workspace for the output int nplots = green != EMPTY_INT() ? 4 : 1; MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create("Workspace2D", nplots, // the number of plots npoints, // the number of data points on a plot npoints // it's not a histogram ); TextAxis* tAxis = new TextAxis(nplots); if (nplots == 1) { tAxis->setLabel(0,"Asymmetry"); } else { tAxis->setLabel(0,"Red-Green"); tAxis->setLabel(1,"Red"); tAxis->setLabel(2,"Green"); tAxis->setLabel(3,"Red+Green"); } outWS->replaceAxis(1,tAxis); Progress progress(this,0,1,ie-is+2); for(size_t i=is; i<=ie; i++) { std::ostringstream fn,fnn; fnn << std::setw(w) << std::setfill('0') << i ; fn << fnBase << fnn.str() << ext; // Load a muon nexus file with auto_group set to true IAlgorithm_sptr loadNexus = createChildAlgorithm("LoadMuonNexus"); loadNexus->setPropertyValue("Filename", fn.str()); loadNexus->setPropertyValue("OutputWorkspace","tmp"+fnn.str()); if (m_autogroup) loadNexus->setPropertyValue("AutoGroup","1"); loadNexus->execute(); std::string wsProp = "OutputWorkspace"; DataObjects::Workspace2D_sptr ws_red; DataObjects::Workspace2D_sptr ws_green; // Run through the periods of the loaded file and do calculations on the selected ones Workspace_sptr tmp = loadNexus->getProperty(wsProp); WorkspaceGroup_sptr wsGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(tmp); if (!wsGroup) { ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmp); TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName)); if (!logp) { throw std::invalid_argument("Log "+logName+" does not exist or not a double type"); } double Y,E; calcIntAsymmetry(ws_red,Y,E); outWS->dataY(0)[i-is] = Y; outWS->dataX(0)[i-is] = logp->lastValue(); outWS->dataE(0)[i-is] = E; } else { for( int period = 1; period <= wsGroup->getNumberOfEntries(); ++period ) { std::stringstream suffix; suffix << period; wsProp = "OutputWorkspace_" + suffix.str();// form the property name for higher periods // Do only one period if (green == EMPTY_INT() && period == red) { Workspace_sptr tmpff = loadNexus->getProperty(wsProp); ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmpff); TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName)); if (!logp) { throw std::invalid_argument("Log "+logName+" does not exist or not a double type"); } double Y,E; calcIntAsymmetry(ws_red,Y,E); outWS->dataY(0)[i-is] = Y; outWS->dataX(0)[i-is] = logp->lastValue(); outWS->dataE(0)[i-is] = E; } else // red & green { if (period == red) { Workspace_sptr temp = loadNexus->getProperty(wsProp); ws_red = boost::dynamic_pointer_cast<Workspace2D>(temp); } if (period == green) { Workspace_sptr temp = loadNexus->getProperty(wsProp); ws_green = boost::dynamic_pointer_cast<Workspace2D>(temp); } } } // red & green claculation if (green != EMPTY_INT()) { if (!ws_red || !ws_green) throw std::invalid_argument("Red or green period is out of range"); TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName)); if (!logp) { throw std::invalid_argument("Log "+logName+" does not exist or not a double type"); } double Y,E; double Y1,E1; calcIntAsymmetry(ws_red,Y,E); calcIntAsymmetry(ws_green,Y1,E1); outWS->dataY(1)[i-is] = Y; outWS->dataX(1)[i-is] = logp->lastValue(); outWS->dataE(1)[i-is] = E; outWS->dataY(2)[i-is] = Y1; outWS->dataX(2)[i-is] = logp->lastValue(); outWS->dataE(2)[i-is] = E1; outWS->dataY(3)[i-is] = Y + Y1; outWS->dataX(3)[i-is] = logp->lastValue(); outWS->dataE(3)[i-is] = sqrt(E*E+E1*E1); // move to last for safety since some grouping takes place in the // calcIntAsymmetry call below calcIntAsymmetry(ws_red,ws_green,Y,E); outWS->dataY(0)[i-is] = Y; outWS->dataX(0)[i-is] = logp->lastValue(); outWS->dataE(0)[i-is] = E; } else if (!ws_red) throw std::invalid_argument("Red period is out of range"); } progress.report(); } outWS->getAxis(0)->title() = logName; outWS->setYUnitLabel("Asymmetry"); // Assign the result to the output workspace property setProperty("OutputWorkspace", outWS); }
/// Exec function void CreateWorkspace::exec() { // Contortions to get at the vector in the property without copying it const Property * const dataXprop = getProperty("DataX"); const Property * const dataYprop = getProperty("DataY"); const Property * const dataEprop = getProperty("DataE"); const std::vector<double>& dataX = *dynamic_cast<const ArrayProperty<double>*>(dataXprop); const std::vector<double>& dataY = *dynamic_cast<const ArrayProperty<double>*>(dataYprop); const std::vector<double>& dataE = *dynamic_cast<const ArrayProperty<double>*>(dataEprop); const int nSpec = getProperty("NSpec"); const std::string xUnit = getProperty("UnitX"); const std::string vUnit = getProperty("VerticalAxisUnit"); const std::vector<std::string> vAxis = getProperty("VerticalAxisValues"); std::string parentWorkspace = getPropertyValue("ParentWorkspace"); if ( ( vUnit != "SpectraNumber" ) && ( static_cast<int>(vAxis.size()) != nSpec ) ) { throw std::invalid_argument("Number of y-axis labels must match number of histograms."); } // Verify length of vectors makes sense with NSpec if ( ( dataY.size() % nSpec ) != 0 ) { throw std::invalid_argument("Length of DataY must be divisible by NSpec"); } const std::size_t ySize = dataY.size() / nSpec; // Check whether the X values provided are to be re-used for (are common to) every spectrum const bool commonX( dataX.size() == ySize || dataX.size() == ySize+1 ); std::size_t xSize; MantidVecPtr XValues; if ( commonX ) { xSize = dataX.size(); XValues.access() = dataX; } else { if ( dataX.size() % nSpec != 0 ) { throw std::invalid_argument("Length of DataX must be divisible by NSpec"); } xSize = static_cast<int>(dataX.size()) / nSpec; if ( xSize < ySize || xSize > ySize + 1 ) { throw std::runtime_error("DataX width must be as DataY or +1"); } } const bool dataE_provided = !dataE.empty(); if ( dataE_provided && dataY.size() != dataE.size() ) { throw std::runtime_error("DataE (if provided) must be the same size as DataY"); } MatrixWorkspace_sptr parentWS; if (!parentWorkspace.empty()) { try { parentWS = boost::dynamic_pointer_cast<MatrixWorkspace>( AnalysisDataService::Instance().retrieve(parentWorkspace) ); } catch(...) { g_log.warning("Parent workspace not found"); // ignore parent workspace } } // Create the OutputWorkspace MatrixWorkspace_sptr outputWS; if (parentWS) { // if parent is defined use it to initialise the workspace outputWS = WorkspaceFactory::Instance().create(parentWS, nSpec, xSize, ySize); } else { // otherwise create a blank workspace outputWS = WorkspaceFactory::Instance().create("Workspace2D", nSpec, xSize, ySize); } Progress progress(this,0,1,nSpec); PARALLEL_FOR1(outputWS) for ( int i = 0; i < nSpec; i++ ) { PARALLEL_START_INTERUPT_REGION const std::vector<double>::difference_type xStart = i*xSize; const std::vector<double>::difference_type xEnd = xStart + xSize; const std::vector<double>::difference_type yStart = i*ySize; const std::vector<double>::difference_type yEnd = yStart + ySize; // Just set the pointer if common X bins. Otherwise, copy in the right chunk (as we do for Y). if ( commonX ) { outputWS->setX(i,XValues); } else { outputWS->dataX(i).assign(dataX.begin()+xStart,dataX.begin()+xEnd); } outputWS->dataY(i).assign(dataY.begin()+yStart,dataY.begin()+yEnd); if ( dataE_provided) outputWS->dataE(i).assign(dataE.begin()+yStart,dataE.begin()+yEnd); progress.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Set the Unit of the X Axis try { outputWS->getAxis(0)->unit() = UnitFactory::Instance().create(xUnit); } catch ( Exception::NotFoundError & ) { outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("Label"); Unit_sptr unit = outputWS->getAxis(0)->unit(); boost::shared_ptr<Units::Label> label = boost::dynamic_pointer_cast<Units::Label>(unit); label->setLabel(xUnit, xUnit); } // Populate the VerticalAxis. A spectra one is there by default with a 1->N mapping if ( vUnit != "SpectraNumber" ) { if ( vUnit == "Text" ) { TextAxis* const newAxis = new TextAxis(vAxis.size()); outputWS->replaceAxis(1, newAxis); for ( size_t i = 0; i < vAxis.size(); i++ ) { newAxis->setLabel(i, vAxis[i]); } } else { NumericAxis* const newAxis = new NumericAxis(vAxis.size()); newAxis->unit() = UnitFactory::Instance().create(vUnit); outputWS->replaceAxis(1, newAxis); for ( size_t i = 0; i < vAxis.size(); i++ ) { try { newAxis->setValue(i, boost::lexical_cast<double, std::string>(vAxis[i]) ); } catch ( boost::bad_lexical_cast & ) { throw std::invalid_argument("CreateWorkspace - YAxisValues property could not be converted to a double."); } } } } // Set distribution flag outputWS->isDistribution(getProperty("Distribution")); // Set Y Unit label if (!parentWS || !getPropertyValue("YUnitLabel").empty()) { outputWS->setYUnitLabel(getProperty("YUnitLabel")); } // Set Workspace Title if (!parentWS || !getPropertyValue("WorkspaceTitle").empty()) { outputWS->setTitle(getProperty("WorkspaceTitle")); } // Set OutputWorkspace property setProperty("OutputWorkspace", outputWS); }
/** * Read histogram data * @param histogramEntries map of the file entries that have histogram * @param outputGroup pointer to the workspace group * @param nxFile Reads data from inside first first top entry */ void LoadMcStas::readHistogramData( const std::map<std::string, std::string> &histogramEntries, WorkspaceGroup_sptr &outputGroup, ::NeXus::File &nxFile) { std::string nameAttrValueYLABEL; for (const auto &histogramEntry : histogramEntries) { const std::string &dataName = histogramEntry.first; const std::string &dataType = histogramEntry.second; // open second level entry nxFile.openGroup(dataName, dataType); // grap title to use to e.g. create workspace name std::string nameAttrValueTITLE; nxFile.getAttr("filename", nameAttrValueTITLE); if (nxFile.hasAttr("ylabel")) { nxFile.getAttr("ylabel", nameAttrValueYLABEL); } // Find the axis names auto nxdataEntries = nxFile.getEntries(); std::string axis1Name, axis2Name; for (auto &nxdataEntry : nxdataEntries) { if (nxdataEntry.second == "NXparameters") continue; if (nxdataEntry.first == "ncount") continue; nxFile.openData(nxdataEntry.first); if (nxFile.hasAttr("axis")) { int axisNo(0); nxFile.getAttr("axis", axisNo); if (axisNo == 1) axis1Name = nxdataEntry.first; else if (axisNo == 2) axis2Name = nxdataEntry.first; else throw std::invalid_argument("Unknown axis number"); } nxFile.closeData(); } std::vector<double> axis1Values, axis2Values; nxFile.readData<double>(axis1Name, axis1Values); if (axis2Name.length() == 0) { axis2Name = nameAttrValueYLABEL; axis2Values.push_back(0.0); } else { nxFile.readData<double>(axis2Name, axis2Values); } const size_t axis1Length = axis1Values.size(); const size_t axis2Length = axis2Values.size(); g_log.debug() << "Axis lengths=" << axis1Length << " " << axis2Length << '\n'; // Require "data" field std::vector<double> data; nxFile.readData<double>("data", data); // Optional errors field std::vector<double> errors; try { nxFile.readData<double>("errors", errors); } catch (::NeXus::Exception &) { g_log.information() << "Field " << dataName << " contains no error information.\n"; } // close second level entry nxFile.closeGroup(); MatrixWorkspace_sptr ws = WorkspaceFactory::Instance().create( "Workspace2D", axis2Length, axis1Length, axis1Length); Axis *axis1 = ws->getAxis(0); axis1->title() = axis1Name; // Set caption auto lblUnit = boost::make_shared<Units::Label>(); lblUnit->setLabel(axis1Name, ""); axis1->unit() = lblUnit; Axis *axis2 = new NumericAxis(axis2Length); axis2->title() = axis2Name; // Set caption lblUnit = boost::make_shared<Units::Label>(); lblUnit->setLabel(axis2Name, ""); axis2->unit() = lblUnit; ws->setYUnit(axis2Name); ws->replaceAxis(1, axis2); for (size_t wsIndex = 0; wsIndex < axis2Length; ++wsIndex) { auto &dataY = ws->dataY(wsIndex); auto &dataE = ws->dataE(wsIndex); auto &dataX = ws->dataX(wsIndex); for (size_t j = 0; j < axis1Length; ++j) { // Data is stored in column-major order so we are translating to // row major for Mantid const size_t fileDataIndex = j * axis2Length + wsIndex; dataY[j] = data[fileDataIndex]; dataX[j] = axis1Values[j]; if (!errors.empty()) dataE[j] = errors[fileDataIndex]; } axis2->setValue(wsIndex, axis2Values[wsIndex]); } // set the workspace title ws->setTitle(nameAttrValueTITLE); // use the workspace title to create the workspace name std::replace(nameAttrValueTITLE.begin(), nameAttrValueTITLE.end(), ' ', '_'); // ensure that specified name is given to workspace (eventWS) when added to // outputGroup std::string nameOfGroupWS = getProperty("OutputWorkspace"); std::string nameUserSee = nameAttrValueTITLE + "_" + nameOfGroupWS; std::string extraProperty = "Outputworkspace_dummy_" + std::to_string(m_countNumWorkspaceAdded); declareProperty(Kernel::make_unique<WorkspaceProperty<Workspace>>( extraProperty, nameUserSee, Direction::Output)); setProperty(extraProperty, boost::static_pointer_cast<Workspace>(ws)); m_countNumWorkspaceAdded++; // need to increment to ensure extraProperty are // unique // Make Mantid store the workspace in the group outputGroup->addWorkspace(ws); } nxFile.closeGroup(); } // finish