/** * 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; }
MatrixWorkspace_sptr ImggFormatsConvertViewQtWidget::loadImg(const std::string &inputName, const std::string &inFormat) const { QImage img = loadImgFile(inputName, inFormat); int width = img.width(); int height = img.height(); MatrixWorkspace_sptr imgWks = boost::dynamic_pointer_cast<MatrixWorkspace>( WorkspaceFactory::Instance().create("Workspace2D", height, width + 1, width)); imgWks->setTitle(inputName); const double scaleFactor = std::numeric_limits<unsigned char>::max(); for (int yi = 0; yi < static_cast<int>(width); ++yi) { auto &row = imgWks->getSpectrum(yi); auto &dataY = row.dataY(); auto &dataX = row.dataX(); std::fill(dataX.begin(), dataX.end(), static_cast<double>(yi)); for (int xi = 0; xi < static_cast<int>(width); ++xi) { QRgb vRgb = img.pixel(xi, yi); dataY[xi] = scaleFactor * qGray(vRgb); } } return imgWks; }
/** Initialise a workspace from its parent * This sets values such as title, instrument, units, sample, spectramap. * This does NOT copy any data. * * @param parent :: the parent workspace * @param child :: the child workspace * @param differentSize :: A flag to indicate if the two workspace will be different sizes */ void WorkspaceFactoryImpl::initializeFromParent(const MatrixWorkspace_const_sptr parent, const MatrixWorkspace_sptr child, const bool differentSize) const { child->setTitle(parent->getTitle()); child->setComment(parent->getComment()); child->setInstrument(parent->getInstrument()); // This call also copies the SHARED POINTER to the parameter map // This call will (should) perform a COPY of the parameter map. child->instrumentParameters(); child->m_sample = parent->m_sample; child->m_run = parent->m_run; child->setYUnit(parent->m_YUnit); child->setYUnitLabel(parent->m_YUnitLabel); child->isDistribution(parent->isDistribution()); // Only copy the axes over if new sizes are not given if ( !differentSize ) { // Only copy mask map if same size for now. Later will need to check continued validity. child->m_masks = parent->m_masks; } // Same number of histograms = copy over the spectra data if (parent->getNumberHistograms() == child->getNumberHistograms()) { for (size_t wi=0; wi<parent->getNumberHistograms(); wi++) { ISpectrum * childSpec = child->getSpectrum(wi); const ISpectrum * parentSpec = parent->getSpectrum(wi); // Copy spectrum number and detector IDs childSpec->copyInfoFrom(*parentSpec); } } // deal with axis for (size_t i = 0; i < parent->m_axes.size(); ++i) { const size_t newAxisLength = child->getAxis(i)->length(); const size_t oldAxisLength = parent->getAxis(i)->length(); if ( !differentSize || newAxisLength == oldAxisLength ) { // Need to delete the existing axis created in init above delete child->m_axes[i]; // Now set to a copy of the parent workspace's axis child->m_axes[i] = parent->m_axes[i]->clone(child.get()); } else { if (! parent->getAxis(i)->isSpectra()) // WHY??? { delete child->m_axes[i]; // Call the 'different length' clone variant child->m_axes[i] = parent->m_axes[i]->clone(newAxisLength,child.get()); } } } return; }
/** Populate output workspace with results * @param outWS :: [input/output] Output workspace to populate * @param nplots :: [input] Number of histograms */ void PlotAsymmetryByLogValue::saveResultsToADS(MatrixWorkspace_sptr &outWS, int nplots) { if (nplots == 2) { size_t i = 0; for (auto &value : m_logValue) { size_t run = value.first; outWS->dataX(0)[i] = static_cast<double>(run); // run number outWS->dataY(0)[i] = value.second; // log value outWS->dataY(1)[i] = m_redY[run]; // redY outWS->dataE(1)[i] = m_redE[run]; // redE i++; } } else { size_t i = 0; for (auto &value : m_logValue) { size_t run = value.first; outWS->dataX(0)[i] = static_cast<double>(run); // run number outWS->dataY(0)[i] = value.second; // log value outWS->dataY(1)[i] = m_diffY[run]; // diffY outWS->dataE(1)[i] = m_diffE[run]; // diffE outWS->dataY(2)[i] = m_redY[run]; // redY outWS->dataE(2)[i] = m_redE[run]; // redE outWS->dataY(3)[i] = m_greenY[run]; // greenY outWS->dataE(3)[i] = m_greenE[run]; // greenE outWS->dataY(4)[i] = m_sumY[run]; // sumY outWS->dataE(4)[i] = m_sumE[run]; // sumE i++; } } // Set the title! outWS->setTitle(m_allProperties); // Save results to ADS // We can't set an output property to store the results as this algorithm // is executed as a child algorithm in the Muon ALC interface // If current results were saved as a property we couln't used // the functionality to re-use previous results in ALC AnalysisDataService::Instance().addOrReplace(m_currResName, outWS); }
/** 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; }
WorkspaceGroup_sptr PolarizationCorrection::execPA(WorkspaceGroup_sptr inWS) { if (isPropertyDefault(cAlphaLabel())) { throw std::invalid_argument("Must provide as input for PA: " + cAlphaLabel()); } if (isPropertyDefault(cApLabel())) { throw std::invalid_argument("Must provide as input for PA: " + cApLabel()); } size_t itemIndex = 0; MatrixWorkspace_sptr Ipp = boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++)); MatrixWorkspace_sptr Ipa = boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++)); MatrixWorkspace_sptr Iap = boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++)); MatrixWorkspace_sptr Iaa = boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++)); Ipp->setTitle("Ipp"); Iaa->setTitle("Iaa"); Ipa->setTitle("Ipa"); Iap->setTitle("Iap"); auto cropAlg = this->createChildAlgorithm("CropWorkspace"); cropAlg->initialize(); cropAlg->setProperty("InputWorkspace", Ipp); cropAlg->setProperty("EndWorkspaceIndex", 0); cropAlg->execute(); MatrixWorkspace_sptr croppedIpp = cropAlg->getProperty("OutputWorkspace"); MatrixWorkspace_sptr ones = copyShapeAndFill(croppedIpp, 1.0); // The ones workspace is now identical to the input workspaces in x, but has 1 // as y values. It can therefore be used to build real polynomial functions. const VecDouble c_rho = getProperty(crhoLabel()); const VecDouble c_alpha = getProperty(cAlphaLabel()); const VecDouble c_pp = getProperty(cppLabel()); const VecDouble c_ap = getProperty(cApLabel()); const auto rho = this->execPolynomialCorrection( ones, c_rho); // Execute polynomial expression const auto pp = this->execPolynomialCorrection( ones, c_pp); // Execute polynomial expression const auto alpha = this->execPolynomialCorrection( ones, c_alpha); // Execute polynomial expression const auto ap = this->execPolynomialCorrection( ones, c_ap); // Execute polynomial expression const auto A0 = (Iaa * pp * ap) + (ap * Ipa * rho * pp) + (ap * Iap * alpha * pp) + (Ipp * ap * alpha * rho * pp); const auto A1 = pp * Iaa; const auto A2 = pp * Iap; const auto A3 = ap * Iaa; const auto A4 = ap * Ipa; const auto A5 = ap * alpha * Ipp; const auto A6 = ap * alpha * Iap; const auto A7 = pp * rho * Ipp; const auto A8 = pp * rho * Ipa; const auto D = pp * ap * (rho + alpha + 1.0 + (rho * alpha)); const auto nIpp = (A0 - A1 + A2 - A3 + A4 + A5 - A6 + A7 - A8 + Ipp + Iaa - Ipa - Iap) / D; const auto nIaa = (A0 + A1 - A2 + A3 - A4 - A5 + A6 - A7 + A8 + Ipp + Iaa - Ipa - Iap) / D; const auto nIpa = (A0 - A1 + A2 + A3 - A4 - A5 + A6 + A7 - A8 - Ipp - Iaa + Ipa + Iap) / D; const auto nIap = (A0 + A1 - A2 - A3 + A4 + A5 - A6 - A7 + A8 - Ipp - Iaa + Ipa + Iap) / D; WorkspaceGroup_sptr dataOut = boost::make_shared<WorkspaceGroup>(); dataOut->addWorkspace(nIpp); dataOut->addWorkspace(nIpa); dataOut->addWorkspace(nIap); dataOut->addWorkspace(nIaa); size_t totalGroupEntries(dataOut->getNumberOfEntries()); for (size_t i = 1; i < totalGroupEntries; i++) { auto alg = this->createChildAlgorithm("ReplaceSpecialValues"); alg->setProperty("InputWorkspace", dataOut->getItem(i)); alg->setProperty("OutputWorkspace", "dataOut_" + std::to_string(i)); alg->setProperty("NaNValue", 0.0); alg->setProperty("NaNError", 0.0); alg->setProperty("InfinityValue", 0.0); alg->setProperty("InfinityError", 0.0); alg->execute(); } // Preserve the history of the inside workspaces nIpp->history().addHistory(Ipp->getHistory()); nIaa->history().addHistory(Iaa->getHistory()); nIpa->history().addHistory(Ipa->getHistory()); nIap->history().addHistory(Iap->getHistory()); return dataOut; }
/** Load an individual "<SASentry>" element into a new workspace. It extends the *LoadCanSAS1D * in the direction of loading the SAStransmission_spectrum as well. (which was *introduced in version 1.1) * * @param[in] workspaceData points to a "<SASentry>" element * @param[out] runName the name this workspace should take * @return dataWS this workspace will be filled with data * @throw NotFoundError if any expected elements couldn't be read * @throw NotImplementedError if the entry doesn't contain exactly one run */ MatrixWorkspace_sptr LoadCanSAS1D2::loadEntry(Poco::XML::Node *const workspaceData, std::string &runName) { MatrixWorkspace_sptr main_out = LoadCanSAS1D::loadEntry(workspaceData, runName); bool loadTrans = getProperty("LoadTransmission"); if (!loadTrans) return main_out; // all done. It is not to load the transmission, nor check // if it exists. Element *workspaceElem = dynamic_cast<Element *>(workspaceData); // check(workspaceElem, "<SASentry>"); // already done at // LoadCanSAS1D::loadEntry Poco::AutoPtr<NodeList> sasTransList = workspaceElem->getElementsByTagName("SAStransmission_spectrum"); if (!sasTransList->length()) { g_log.warning() << "There is no transmission data for this file " << getPropertyValue("Filename") << std::endl; return main_out; } for (unsigned short trans_index = 0; trans_index < sasTransList->length(); trans_index++) { // foreach SAStransmission_spectrum Node *idataElem = sasTransList->item(trans_index); Element *sasTrasElem = dynamic_cast<Element *>(idataElem); if (!sasTrasElem) continue; std::vector<API::MatrixWorkspace_sptr> &group = (sasTrasElem->getAttribute("name") == "sample") ? trans_gp : trans_can_gp; // getting number of Tdata elements in the xml file Poco::AutoPtr<NodeList> tdataElemList = sasTrasElem->getElementsByTagName("Tdata"); size_t nBins = tdataElemList->length(); MatrixWorkspace_sptr dataWS = WorkspaceFactory::Instance().create("Workspace2D", 1, nBins, nBins); createLogs(workspaceElem, dataWS); std::string title = main_out->getTitle(); title += ":trans"; title += sasTrasElem->getAttribute("name"); dataWS->setTitle(title); dataWS->isDistribution(true); dataWS->setYUnit(""); // load workspace data MantidVec &X = dataWS->dataX(0); MantidVec &Y = dataWS->dataY(0); MantidVec &E = dataWS->dataE(0); int vecindex = 0; // iterate through each Tdata element and get the values of "Lambda", //"T" and "Tdev" text nodes and fill X,Y,E vectors for (unsigned long index = 0; index < nBins; ++index) { Node *idataElem = tdataElemList->item(index); Element *elem = dynamic_cast<Element *>(idataElem); if (elem) { // setting X vector std::string nodeVal; Element *qElem = elem->getChildElement("Lambda"); check(qElem, "Lambda"); nodeVal = qElem->innerText(); std::stringstream x(nodeVal); double d; x >> d; X[vecindex] = d; // setting Y vector Element *iElem = elem->getChildElement("T"); check(qElem, "T"); nodeVal = iElem->innerText(); std::stringstream y(nodeVal); y >> d; Y[vecindex] = d; // setting the error vector Element *idevElem = elem->getChildElement("Tdev"); check(qElem, "Tdev"); nodeVal = idevElem->innerText(); std::stringstream e(nodeVal); e >> d; E[vecindex] = d; ++vecindex; } } runLoadInstrument(main_out->getInstrument()->getName(), dataWS); dataWS->getAxis(0)->setUnit("Wavelength"); // add to group group.push_back(dataWS); } return main_out; }
/** * 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
WorkspaceGroup_sptr PolarizationCorrectionFredrikze::execPA(WorkspaceGroup_sptr inWS) { size_t itemIndex = 0; MatrixWorkspace_sptr Ipp = boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++)); MatrixWorkspace_sptr Ipa = boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++)); MatrixWorkspace_sptr Iap = boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++)); MatrixWorkspace_sptr Iaa = boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++)); Ipp->setTitle("Ipp"); Iaa->setTitle("Iaa"); Ipa->setTitle("Ipa"); Iap->setTitle("Iap"); const auto rho = this->getEfficiencyWorkspace(crhoLabel); const auto pp = this->getEfficiencyWorkspace(cppLabel); const auto alpha = this->getEfficiencyWorkspace(cAlphaLabel); const auto ap = this->getEfficiencyWorkspace(cApLabel); const auto A0 = (Iaa * pp * ap) + (Ipa * ap * rho * pp) + (Iap * ap * alpha * pp) + (Ipp * ap * alpha * rho * pp); const auto A1 = Iaa * pp; const auto A2 = Iap * pp; const auto A3 = Iaa * ap; const auto A4 = Ipa * ap; const auto A5 = Ipp * ap * alpha; const auto A6 = Iap * ap * alpha; const auto A7 = Ipp * pp * rho; const auto A8 = Ipa * pp * rho; const auto D = pp * ap * (rho + alpha + 1.0 + (rho * alpha)); const auto nIpp = (A0 - A1 + A2 - A3 + A4 + A5 - A6 + A7 - A8 + Ipp + Iaa - Ipa - Iap) / D; const auto nIaa = (A0 + A1 - A2 + A3 - A4 - A5 + A6 - A7 + A8 + Ipp + Iaa - Ipa - Iap) / D; const auto nIap = (A0 - A1 + A2 + A3 - A4 - A5 + A6 + A7 - A8 - Ipp - Iaa + Ipa + Iap) / D; const auto nIpa = (A0 + A1 - A2 - A3 + A4 + A5 - A6 - A7 + A8 - Ipp - Iaa + Ipa + Iap) / D; WorkspaceGroup_sptr dataOut = boost::make_shared<WorkspaceGroup>(); dataOut->addWorkspace(nIpp); dataOut->addWorkspace(nIpa); dataOut->addWorkspace(nIap); dataOut->addWorkspace(nIaa); size_t totalGroupEntries(dataOut->getNumberOfEntries()); for (size_t i = 1; i < totalGroupEntries; i++) { auto alg = this->createChildAlgorithm("ReplaceSpecialValues"); alg->setProperty("InputWorkspace", dataOut->getItem(i)); alg->setProperty("OutputWorkspace", "dataOut_" + std::to_string(i)); alg->setProperty("NaNValue", 0.0); alg->setProperty("NaNError", 0.0); alg->setProperty("InfinityValue", 0.0); alg->setProperty("InfinityError", 0.0); alg->execute(); } // Preserve the history of the inside workspaces nIpp->history().addHistory(Ipp->getHistory()); nIaa->history().addHistory(Iaa->getHistory()); nIpa->history().addHistory(Ipa->getHistory()); nIap->history().addHistory(Iap->getHistory()); return dataOut; }
/// 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); }