/** * Calls Gaussian1D as a child algorithm to fit the offset peak in a spectrum * @param mosaic * @param rcrystallite * @param inname * @param corrOption * @param pointOption * @param tofParams * @return */ double OptimizeExtinctionParameters::fitMosaic( double mosaic, double rcrystallite, std::string inname, std::string corrOption, std::string pointOption, std::string tofParams) { PeaksWorkspace_sptr inputW = boost::dynamic_pointer_cast<PeaksWorkspace>( AnalysisDataService::Instance().retrieve(inname)); std::vector<double> tofParam = Kernel::VectorHelper::splitStringIntoVector<double>(tofParams); if (mosaic < 0.0 || rcrystallite < 0.0) return 1e300; API::IAlgorithm_sptr tofextinction = createChildAlgorithm("TOFExtinction", 0.0, 0.2); tofextinction->setProperty("InputWorkspace", inputW); tofextinction->setProperty("OutputWorkspace", "tmp"); tofextinction->setProperty("ExtinctionCorrectionType", corrOption); tofextinction->setProperty<double>("Mosaic", mosaic); tofextinction->setProperty<double>("Cell", tofParam[0]); tofextinction->setProperty<double>("RCrystallite", rcrystallite); tofextinction->executeAsChildAlg(); PeaksWorkspace_sptr peaksW = tofextinction->getProperty("OutputWorkspace"); API::IAlgorithm_sptr sorthkl = createChildAlgorithm("SortHKL", 0.0, 0.2); sorthkl->setProperty("InputWorkspace", peaksW); sorthkl->setProperty("OutputWorkspace", peaksW); sorthkl->setProperty("PointGroup", pointOption); sorthkl->executeAsChildAlg(); double Chisq = sorthkl->getProperty("OutputChi2"); std::cout << mosaic << " " << rcrystallite << " " << Chisq << "\n"; return Chisq; }
/** * Execute the algorithm. */ void FitResolutionConvolvedModel::exec() { API::IAlgorithm_sptr fit = createFittingAlgorithm(); fit->setPropertyValue("Function", createFunctionString()); fit->setProperty("InputWorkspace", getPropertyValue(INPUT_WS_NAME)); fit->setProperty("DomainType", "Simple"); // Parallel not quite giving correct answers fit->setProperty("Minimizer", "Levenberg-MarquardtMD"); const int maxIter = niterations(); fit->setProperty("MaxIterations", maxIter); fit->setProperty("CreateOutput", true); fit->setPropertyValue("Output", getPropertyValue(SIMULATED_NAME)); try { fit->execute(); } catch (std::exception &exc) { throw std::runtime_error( std::string("FitResolutionConvolvedModel - Error running Fit: ") + exc.what()); } // Pass on the relevant properties IMDEventWorkspace_sptr simulatedData = fit->getProperty("OutputWorkspace"); this->setProperty(SIMULATED_NAME, simulatedData); if (this->existsProperty(OUTPUT_PARS)) { ITableWorkspace_sptr outputPars = fit->getProperty("OutputParameters"); setProperty(OUTPUT_PARS, outputPars); } if (this->existsProperty(OUTPUTCOV_MATRIX)) { ITableWorkspace_sptr covarianceMatrix = fit->getProperty("OutputNormalisedCovarianceMatrix"); setProperty(OUTPUTCOV_MATRIX, covarianceMatrix); } }
/** Fit function * Minimizer: "Levenberg-MarquardtMD"/"Simplex" */ bool RefinePowderInstrumentParameters2::doFitFunction(IFunction_sptr function, Workspace2D_sptr dataws, int wsindex, string minimizer, int numiters, double& chi2, string& fitstatus) { // 0. Debug output stringstream outss; outss << "Fit function: " << m_positionFunc->asString() << endl << "Data To Fit: \n"; for (size_t i = 0; i < dataws->readX(0).size(); ++i) outss << dataws->readX(wsindex)[i] << "\t\t" << dataws->readY(wsindex)[i] << "\t\t" << dataws->readE(wsindex)[i] << "\n"; g_log.information() << outss.str(); // 1. Create and setup fit algorithm API::IAlgorithm_sptr fitalg = createChildAlgorithm("Fit", 0.0, 0.2, true); fitalg->initialize(); fitalg->setProperty("Function", function); fitalg->setProperty("InputWorkspace", dataws); fitalg->setProperty("WorkspaceIndex", wsindex); fitalg->setProperty("Minimizer", minimizer); fitalg->setProperty("CostFunction", "Least squares"); fitalg->setProperty("MaxIterations", numiters); fitalg->setProperty("CalcErrors", true); // 2. Fit bool successfulfit = fitalg->execute(); if (!fitalg->isExecuted() || ! successfulfit) { // Early return due to bad fit g_log.warning("Fitting to instrument geometry function failed. "); chi2 = DBL_MAX; fitstatus = "Minimizer throws exception."; return false; } // 3. Understand solution chi2 = fitalg->getProperty("OutputChi2overDoF"); string tempfitstatus = fitalg->getProperty("OutputStatus"); fitstatus = tempfitstatus; bool goodfit = fitstatus.compare("success") == 0; stringstream dbss; dbss << "Fit Result (GSL): Chi^2 = " << chi2 << "; Fit Status = " << fitstatus << ", Return Bool = " << goodfit << std::endl; vector<string> funcparnames = function->getParameterNames(); for (size_t i = 0; i < funcparnames.size(); ++i) dbss << funcparnames[i] << " = " << setw(20) << function->getParameter(funcparnames[i]) << " +/- " << function->getError(i) << "\n"; g_log.debug() << dbss.str(); return goodfit; }
/** Call edit instrument geometry */ API::MatrixWorkspace_sptr AlignAndFocusPowder::editInstrument( API::MatrixWorkspace_sptr ws, std::vector<double> polars, std::vector<specnum_t> specids, std::vector<double> l2s, std::vector<double> phis) { g_log.information() << "running EditInstrumentGeometry started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr editAlg = createChildAlgorithm("EditInstrumentGeometry"); editAlg->setProperty("Workspace", ws); if (m_l1 > 0.) editAlg->setProperty("PrimaryFlightPath", m_l1); if (!polars.empty()) editAlg->setProperty("Polar", polars); if (!specids.empty()) editAlg->setProperty("SpectrumIDs", specids); if (!l2s.empty()) editAlg->setProperty("L2", l2s); if (!phis.empty()) editAlg->setProperty("Azimuthal", phis); editAlg->executeAsChildAlg(); ws = editAlg->getProperty("Workspace"); return ws; }
/** * Removes exponential decay from a workspace * @param wsInput :: [input] Workspace to work on * @return :: Workspace with decay removed */ API::MatrixWorkspace_sptr CalMuonDetectorPhases::removeExpDecay( const API::MatrixWorkspace_sptr &wsInput) { API::IAlgorithm_sptr remove = createChildAlgorithm("RemoveExpDecay"); remove->setProperty("InputWorkspace", wsInput); remove->executeAsChildAlg(); API::MatrixWorkspace_sptr wsRem = remove->getProperty("OutputWorkspace"); return wsRem; }
/** Group detectors in the workspace. * @param ws :: A local workspace * @param spectraList :: A list of spectra to group. */ void PlotAsymmetryByLogValue::groupDetectors(API::MatrixWorkspace_sptr& ws,const std::vector<int>& spectraList) { API::IAlgorithm_sptr group = createChildAlgorithm("GroupDetectors"); group->setProperty("InputWorkspace",ws); group->setProperty("SpectraList",spectraList); group->setProperty("KeepUngroupedSpectra",true); group->execute(); ws = group->getProperty("OutputWorkspace"); }
/** * Return an output workspace property dealing with the lack of connection * between of * WorkspaceProperty types * @param propName :: The name of the property * @param loader :: The loader algorithm * @returns A pointer to the OutputWorkspace property of the Child Algorithm */ API::Workspace_sptr Load::getOutputWorkspace(const std::string &propName, const API::IAlgorithm_sptr &loader) const { // @todo Need to try and find a better way using the getValue methods try { return loader->getProperty(propName); } catch (std::runtime_error &) { } // Try a MatrixWorkspace try { MatrixWorkspace_sptr childWS = loader->getProperty(propName); return childWS; } catch (std::runtime_error &) { } // EventWorkspace try { IEventWorkspace_sptr childWS = loader->getProperty(propName); return childWS; } catch (std::runtime_error &) { } // IMDEventWorkspace try { IMDEventWorkspace_sptr childWS = loader->getProperty(propName); return childWS; } catch (std::runtime_error &) { } // General IMDWorkspace try { IMDWorkspace_sptr childWS = loader->getProperty(propName); return childWS; } catch (std::runtime_error &) { } // ITableWorkspace? try { ITableWorkspace_sptr childWS = loader->getProperty(propName); return childWS; } catch (std::runtime_error &) { } // Just workspace? try { Workspace_sptr childWS = loader->getProperty(propName); return childWS; } catch (std::runtime_error &) { } g_log.debug() << "Workspace property " << propName << " did not return to MatrixWorkspace, EventWorkspace, " "IMDEventWorkspace, IMDWorkspace\n"; return Workspace_sptr(); }
/** Perform SortHKL on the output workspaces * * @param ws :: any PeaksWorkspace * @param runName :: string to put in statistics table */ void StatisticsOfPeaksWorkspace::doSortHKL(Mantid::API::Workspace_sptr ws, std::string runName) { std::string pointGroup = getPropertyValue("PointGroup"); std::string latticeCentering = getPropertyValue("LatticeCentering"); std::string wkspName = getPropertyValue("OutputWorkspace"); std::string tableName = getPropertyValue("StatisticsTable"); API::IAlgorithm_sptr statsAlg = createChildAlgorithm("SortHKL"); statsAlg->setProperty("InputWorkspace", ws); statsAlg->setPropertyValue("OutputWorkspace", wkspName); statsAlg->setPropertyValue("StatisticsTable", tableName); statsAlg->setProperty("PointGroup", pointGroup); statsAlg->setProperty("LatticeCentering", latticeCentering); statsAlg->setProperty("RowName", runName); if (runName.compare("Overall") != 0) statsAlg->setProperty("Append", true); statsAlg->executeAsChildAlg(); PeaksWorkspace_sptr statsWksp = statsAlg->getProperty("OutputWorkspace"); ITableWorkspace_sptr tablews = statsAlg->getProperty("StatisticsTable"); if (runName.compare("Overall") == 0) setProperty("OutputWorkspace", statsWksp); setProperty("StatisticsTable", tablews); }
/** Extracts relevant data from a workspace * @param startTime :: [input] First X value to consider * @param endTime :: [input] Last X value to consider * @return :: Pre-processed workspace to fit */ API::MatrixWorkspace_sptr CalMuonDetectorPhases::extractDataFromWorkspace(double startTime, double endTime) { // Extract counts from startTime to endTime API::IAlgorithm_sptr crop = createChildAlgorithm("CropWorkspace"); crop->setProperty("InputWorkspace", m_inputWS); crop->setProperty("XMin", startTime); crop->setProperty("XMax", endTime); crop->executeAsChildAlg(); boost::shared_ptr<API::MatrixWorkspace> wsCrop = crop->getProperty("OutputWorkspace"); return wsCrop; }
/// Run ConvertUnits as a sub-algorithm to convert to dSpacing MatrixWorkspace_sptr DiffractionFocussing::convertUnitsToDSpacing(const API::MatrixWorkspace_sptr& workspace) { const std::string CONVERSION_UNIT = "dSpacing"; Unit_const_sptr xUnit = workspace->getAxis(0)->unit(); g_log.information() << "Converting units from "<< xUnit->label() << " to " << CONVERSION_UNIT<<".\n"; API::IAlgorithm_sptr childAlg = createSubAlgorithm("ConvertUnits", 0.34, 0.66); childAlg->setProperty("InputWorkspace", workspace); childAlg->setPropertyValue("Target",CONVERSION_UNIT); childAlg->executeAsSubAlg(); return childAlg->getProperty("OutputWorkspace"); }
/** Rebin */ API::MatrixWorkspace_sptr AlignAndFocusPowder::rebin(API::MatrixWorkspace_sptr matrixws) { if (m_resampleX != 0) { // ResampleX g_log.information() << "running ResampleX(NumberBins=" << abs(m_resampleX) << ", LogBinning=" << (m_resampleX < 0) << ", dMin(" << m_dmins.size() << "), dmax(" << m_dmaxs.size() << ")) started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr alg = createChildAlgorithm("ResampleX"); alg->setProperty("InputWorkspace", matrixws); alg->setProperty("OutputWorkspace", matrixws); if ((!m_dmins.empty()) && (!m_dmaxs.empty())) { size_t numHist = m_outputW->getNumberHistograms(); if ((numHist == m_dmins.size()) && (numHist == m_dmaxs.size())) { alg->setProperty("XMin", m_dmins); alg->setProperty("XMax", m_dmaxs); } else { g_log.information() << "Number of dmin and dmax values don't match the " << "number of workspace indices. Ignoring the parameters.\n"; } } alg->setProperty("NumberBins", abs(m_resampleX)); alg->setProperty("LogBinning", (m_resampleX < 0)); alg->executeAsChildAlg(); matrixws = alg->getProperty("OutputWorkspace"); return matrixws; } else { g_log.information() << "running Rebin( "; for (double param : m_params) g_log.information() << param << " "; g_log.information() << ") started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr rebin3Alg = createChildAlgorithm("Rebin"); rebin3Alg->setProperty("InputWorkspace", matrixws); rebin3Alg->setProperty("OutputWorkspace", matrixws); rebin3Alg->setProperty("Params", m_params); rebin3Alg->executeAsChildAlg(); matrixws = rebin3Alg->getProperty("OutputWorkspace"); return matrixws; } }
/** * Set the output workspace(s) if the load's return workspace has type * API::Workspace * @param loader :: Shared pointer to load algorithm */ void LoadNexus::setOutputWorkspace(const API::IAlgorithm_sptr &loader) { // Go through each OutputWorkspace property and check whether we need to make // a counterpart here const std::vector<Property *> &loaderProps = loader->getProperties(); const size_t count = loader->propertyCount(); for (size_t i = 0; i < count; ++i) { Property *prop = loaderProps[i]; if (dynamic_cast<IWorkspaceProperty *>(prop) && prop->direction() == Direction::Output) { const std::string &name = prop->name(); if (!this->existsProperty(name)) { declareProperty(new WorkspaceProperty<Workspace>( name, loader->getPropertyValue(name), Direction::Output)); } Workspace_sptr wkspace = loader->getProperty(name); setProperty(name, wkspace); } } }
/** Call diffraction focus to a matrix workspace. */ API::MatrixWorkspace_sptr AlignAndFocusPowder::diffractionFocus(API::MatrixWorkspace_sptr ws) { if (!m_groupWS) { g_log.information() << "not focussing data\n"; return ws; } g_log.information() << "running DiffractionFocussing. \n"; API::IAlgorithm_sptr focusAlg = createChildAlgorithm("DiffractionFocussing"); focusAlg->setProperty("InputWorkspace", ws); focusAlg->setProperty("OutputWorkspace", ws); focusAlg->setProperty("GroupingWorkspace", m_groupWS); focusAlg->setProperty("PreserveEvents", m_preserveEvents); focusAlg->executeAsChildAlg(); ws = focusAlg->getProperty("OutputWorkspace"); return ws; }
/// Run Rebin as a Child Algorithm to harmonise the bin boundaries void DiffractionFocussing::RebinWorkspace( API::MatrixWorkspace_sptr &workspace) { double min = 0; double max = 0; double step = 0; calculateRebinParams(workspace, min, max, step); std::vector<double> paramArray{min, -step, max}; g_log.information() << "Rebinning from " << min << " to " << max << " in " << step << " logaritmic steps.\n"; API::IAlgorithm_sptr childAlg = createChildAlgorithm("Rebin"); childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", workspace); childAlg->setProperty<std::vector<double>>("Params", paramArray); childAlg->executeAsChildAlg(); workspace = childAlg->getProperty("OutputWorkspace"); }
/** Fit background function */ void ProcessBackground::fitBackgroundFunction(std::string bkgdfunctiontype) { // Get background type and create bakground function BackgroundFunction_sptr bkgdfunction = createBackgroundFunction(bkgdfunctiontype); int bkgdorder = getProperty("OutputBackgroundOrder"); bkgdfunction->setAttributeValue("n", bkgdorder); if (bkgdfunctiontype == "Chebyshev") { double xmin = m_outputWS->readX(0).front(); double xmax = m_outputWS->readX(0).back(); g_log.information() << "Chebyshev Fit range: " << xmin << ", " << xmax << "\n"; bkgdfunction->setAttributeValue("StartX", xmin); bkgdfunction->setAttributeValue("EndX", xmax); } g_log.information() << "Fit selected background " << bkgdfunctiontype << " to data workspace with " << m_outputWS->getNumberHistograms() << " spectra." << "\n"; // Fit input (a few) background pionts to get initial guess API::IAlgorithm_sptr fit; try { fit = this->createChildAlgorithm("Fit", 0.9, 1.0, true); } catch (Exception::NotFoundError &) { g_log.error() << "Requires CurveFitting library." << std::endl; throw; } g_log.information() << "Fitting background function: " << bkgdfunction->asString() << "\n"; double startx = m_lowerBound; double endx = m_upperBound; fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(bkgdfunction)); fit->setProperty("InputWorkspace", m_outputWS); fit->setProperty("WorkspaceIndex", 0); fit->setProperty("MaxIterations", 500); fit->setProperty("StartX", startx); fit->setProperty("EndX", endx); fit->setProperty("Minimizer", "Levenberg-MarquardtMD"); fit->setProperty("CostFunction", "Least squares"); fit->executeAsChildAlg(); // Get fit status and chi^2 std::string fitStatus = fit->getProperty("OutputStatus"); bool allowedfailure = (fitStatus.find("cannot") < fitStatus.size()) && (fitStatus.find("tolerance") < fitStatus.size()); if (fitStatus.compare("success") != 0 && !allowedfailure) { g_log.error() << "ProcessBackground: Fit Status = " << fitStatus << ". Not to update fit result" << std::endl; throw std::runtime_error("Bad Fit"); } const double chi2 = fit->getProperty("OutputChi2overDoF"); g_log.information() << "Fit background: Fit Status = " << fitStatus << ", chi2 = " << chi2 << "\n"; // Get out the parameter names API::IFunction_sptr funcout = fit->getProperty("Function"); TableWorkspace_sptr outbkgdparws = boost::make_shared<TableWorkspace>(); outbkgdparws->addColumn("str", "Name"); outbkgdparws->addColumn("double", "Value"); TableRow typerow = outbkgdparws->appendRow(); typerow << bkgdfunctiontype << 0.; vector<string> parnames = funcout->getParameterNames(); size_t nparam = funcout->nParams(); for (size_t i = 0; i < nparam; ++i) { TableRow newrow = outbkgdparws->appendRow(); newrow << parnames[i] << funcout->getParameter(i); } TableRow chi2row = outbkgdparws->appendRow(); chi2row << "Chi-square" << chi2; g_log.information() << "Set table workspace (#row = " << outbkgdparws->rowCount() << ") to OutputBackgroundParameterTable. " << "\n"; setProperty("OutputBackgroundParameterWorkspace", outbkgdparws); // Set output workspace const MantidVec &vecX = m_outputWS->readX(0); const MantidVec &vecY = m_outputWS->readY(0); FunctionDomain1DVector domain(vecX); FunctionValues values(domain); funcout->function(domain, values); MantidVec &dataModel = m_outputWS->dataY(1); MantidVec &dataDiff = m_outputWS->dataY(2); for (size_t i = 0; i < dataModel.size(); ++i) { dataModel[i] = values[i]; dataDiff[i] = vecY[i] - dataModel[i]; } return; }
/** Select background automatically */ DataObjects::Workspace2D_sptr ProcessBackground::autoBackgroundSelection(Workspace2D_sptr bkgdWS) { // Get background type and create bakground function BackgroundFunction_sptr bkgdfunction = createBackgroundFunction(m_bkgdType); int bkgdorder = getProperty("BackgroundOrder"); if (bkgdorder == 0) g_log.warning("(Input) background function order is 0. It might not be " "able to give a good estimation."); bkgdfunction->setAttributeValue("n", bkgdorder); bkgdfunction->initialize(); g_log.information() << "Input background points has " << bkgdWS->readX(0).size() << " data points for fit " << bkgdorder << "-th order " << bkgdfunction->name() << " (background) function" << bkgdfunction->asString() << "\n"; // Fit input (a few) background pionts to get initial guess API::IAlgorithm_sptr fit; try { fit = this->createChildAlgorithm("Fit", 0.0, 0.2, true); } catch (Exception::NotFoundError &) { g_log.error() << "Requires CurveFitting library." << std::endl; throw; } double startx = m_lowerBound; double endx = m_upperBound; fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(bkgdfunction)); fit->setProperty("InputWorkspace", bkgdWS); fit->setProperty("WorkspaceIndex", 0); fit->setProperty("MaxIterations", 500); fit->setProperty("StartX", startx); fit->setProperty("EndX", endx); fit->setProperty("Minimizer", "Levenberg-Marquardt"); fit->setProperty("CostFunction", "Least squares"); fit->executeAsChildAlg(); // Get fit result // a) Status std::string fitStatus = fit->getProperty("OutputStatus"); bool allowedfailure = (fitStatus.find("cannot") < fitStatus.size()) && (fitStatus.find("tolerance") < fitStatus.size()); if (fitStatus.compare("success") != 0 && !allowedfailure) { g_log.error() << "ProcessBackground: Fit Status = " << fitStatus << ". Not to update fit result" << std::endl; throw std::runtime_error("Bad Fit"); } // b) check that chi2 got better const double chi2 = fit->getProperty("OutputChi2overDoF"); g_log.information() << "Fit background: Fit Status = " << fitStatus << ", chi2 = " << chi2 << "\n"; // Filter and construct for the output workspace Workspace2D_sptr outws = filterForBackground(bkgdfunction); return outws; } // END OF FUNCTION
void GetDetOffsetsMultiPeaks::fitSpectra(const int64_t s, MatrixWorkspace_sptr inputW, const std::vector<double> &peakPositions, const std::vector<double> &fitWindows, size_t &nparams, double &minD, double &maxD, std::vector<double>&peakPosToFit, std::vector<double>&peakPosFitted, std::vector<double> &chisq) { const MantidVec & X = inputW->readX(s); minD = X.front(); maxD = X.back(); bool useFitWindows = (!fitWindows.empty()); std::vector<double> fitWindowsToUse; for (int i = 0; i < static_cast<int>(peakPositions.size()); ++i) { if((peakPositions[i] > minD) && (peakPositions[i] < maxD)) { peakPosToFit.push_back(peakPositions[i]); if (useFitWindows) { fitWindowsToUse.push_back(std::max(fitWindows[2*i], minD)); fitWindowsToUse.push_back(std::min(fitWindows[2*i+1], maxD)); } } } API::IAlgorithm_sptr findpeaks = createChildAlgorithm("FindPeaks", -1, -1, false); findpeaks->setProperty("InputWorkspace", inputW); findpeaks->setProperty<int>("FWHM",7); findpeaks->setProperty<int>("Tolerance",4); // FindPeaks will do the checking on the validity of WorkspaceIndex findpeaks->setProperty("WorkspaceIndex",static_cast<int>(s)); //Get the specified peak positions, which is optional findpeaks->setProperty("PeakPositions", peakPosToFit); if (useFitWindows) findpeaks->setProperty("FitWindows", fitWindowsToUse); findpeaks->setProperty<std::string>("PeakFunction", m_peakType); findpeaks->setProperty<std::string>("BackgroundType", m_backType); findpeaks->setProperty<bool>("HighBackground", this->getProperty("HighBackground")); findpeaks->setProperty<int>("MinGuessedPeakWidth",4); findpeaks->setProperty<int>("MaxGuessedPeakWidth",4); findpeaks->executeAsChildAlg(); ITableWorkspace_sptr peakslist = findpeaks->getProperty("PeaksList"); std::vector<size_t> banned; std::vector<double> peakWidFitted; std::vector<double> peakHighFitted; std::vector<double> peakBackground; for (size_t i = 0; i < peakslist->rowCount(); ++i) { // peak value double centre = peakslist->getRef<double>("centre",i); double width = peakslist->getRef<double>("width",i); double height = peakslist->getRef<double>("height", i); // background value double back_intercept = peakslist->getRef<double>("backgroundintercept", i); double back_slope = peakslist->getRef<double>("backgroundslope", i); double back_quad = peakslist->getRef<double>("A2", i); double background = back_intercept + back_slope * centre + back_quad * centre * centre; // goodness of fit double chi2 = peakslist->getRef<double>("chi2",i); // Get references to the data peakPosFitted.push_back(centre); peakWidFitted.push_back(width); peakHighFitted.push_back(height); peakBackground.push_back(background); chisq.push_back(chi2); } // first remove things that just didn't fit (center outside of window, bad chisq, ...) for (size_t i = 0; i < peakslist->rowCount(); ++i) { if (peakPosFitted[i] <= minD || peakPosFitted[i] >= maxD) { banned.push_back(i); continue; } else if (useFitWindows) // be more restrictive if fit windows were specified { if (peakPosFitted[i] <= fitWindowsToUse[2*i] || peakPosFitted[i] >= fitWindowsToUse[2*i+1]) { banned.push_back(i); continue; } } if (chisq[i] > m_maxChiSq) { banned.push_back(i); continue; } } // delete banned peaks g_log.debug() << "Deleting " << banned.size() << " of " << peakPosFitted.size() << " peaks in wkspindex = " << s << "\n"; deletePeaks(banned, peakPosToFit, peakPosFitted, peakWidFitted, peakHighFitted, peakBackground, chisq); // ban peaks that are low intensity compared to their widths for (size_t i = 0; i < peakWidFitted.size(); ++i) { if (peakHighFitted[i] * FWHM_TO_SIGMA / peakWidFitted[i] < 5.) { g_log.debug() << "Banning peak at " << peakPosFitted[i] << " in wkspindex = " << s << " I/sigma = " << (peakHighFitted[i] * FWHM_TO_SIGMA / peakWidFitted[i]) << "\n"; banned.push_back(i); continue; } } // delete banned peaks g_log.debug() << "Deleting " << banned.size() << " of " << peakPosFitted.size() << " peaks in wkspindex = " << s << "\n"; deletePeaks(banned, peakPosToFit, peakPosFitted, peakWidFitted, peakHighFitted, peakBackground, chisq); // determine the (z-value) for constant "width" - (delta d)/d std::vector<double> widthDivPos(peakWidFitted.size(), 0.); // DELETEME for (size_t i = 0; i < peakWidFitted.size(); ++i) { widthDivPos[i] = peakWidFitted[i] / peakPosFitted[i]; // DELETEME } std::vector<double> Zscore = getZscore(widthDivPos); for (size_t i = 0; i < peakWidFitted.size(); ++i) { if (Zscore[i] > 2.0) { g_log.debug() << "Banning peak at " << peakPosFitted[i] << " in wkspindex = " << s << " sigma/d = " << widthDivPos[i] << "\n"; banned.push_back(i); continue; } } // delete banned peaks g_log.debug() << "Deleting " << banned.size() << " of " << peakPosFitted.size() << " peaks in wkspindex = " << s << "\n"; deletePeaks(banned, peakPosToFit, peakPosFitted, peakWidFitted, peakHighFitted, peakBackground, chisq); // ban peaks that are not outside of error bars for the background for (size_t i = 0; i < peakWidFitted.size(); ++i) { if (peakHighFitted[i] < 0.5 * std::sqrt(peakHighFitted[i] + peakBackground[i])) { g_log.debug() << "Banning peak at " << peakPosFitted[i] << " in wkspindex = " << s << " " << peakHighFitted[i] << " < " << 0.5 * std::sqrt(peakHighFitted[i] + peakBackground[i]) << "\n"; banned.push_back(i); continue; } } // delete banned peaks g_log.debug() << "Deleting " << banned.size() << " of " << peakPosFitted.size() << " peaks in wkspindex = " << s << "\n"; deletePeaks(banned, peakPosToFit, peakPosFitted, peakWidFitted, peakHighFitted, peakBackground, chisq); nparams = peakPosFitted.size(); return; }
/** Executes the algorithm * @throw Exception::FileError If the grouping file cannot be opened or read * successfully * @throw runtime_error If unable to run one of the Child Algorithms * successfully */ void AlignAndFocusPowder::exec() { // retrieve the properties m_inputW = getProperty("InputWorkspace"); m_inputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_inputW); m_instName = m_inputW->getInstrument()->getName(); m_instName = Kernel::ConfigService::Instance().getInstrument(m_instName).shortName(); std::string calFilename = getPropertyValue("CalFileName"); std::string groupFilename = getPropertyValue("GroupFilename"); m_calibrationWS = getProperty("CalibrationWorkspace"); m_maskWS = getProperty("MaskWorkspace"); m_groupWS = getProperty("GroupingWorkspace"); DataObjects::TableWorkspace_sptr maskBinTableWS = getProperty("MaskBinTable"); m_l1 = getProperty("PrimaryFlightPath"); specids = getProperty("SpectrumIDs"); l2s = getProperty("L2"); tths = getProperty("Polar"); phis = getProperty("Azimuthal"); m_params = getProperty("Params"); dspace = getProperty("DSpacing"); auto dmin = getVecPropertyFromPmOrSelf("DMin", m_dmins); auto dmax = getVecPropertyFromPmOrSelf("DMax", m_dmaxs); LRef = getProperty("UnwrapRef"); DIFCref = getProperty("LowResRef"); minwl = getProperty("CropWavelengthMin"); maxwl = getProperty("CropWavelengthMax"); if (maxwl == 0.) maxwl = EMPTY_DBL(); // python can only specify 0 for unused tmin = getProperty("TMin"); tmax = getProperty("TMax"); m_preserveEvents = getProperty("PreserveEvents"); m_resampleX = getProperty("ResampleX"); // determine some bits about d-space and binning if (m_resampleX != 0) { m_params.clear(); // ignore the normal rebin parameters } else if (m_params.size() == 1) { if (dmax > 0.) dspace = true; else dspace = false; } if (dspace) { if (m_params.size() == 1 && dmax > 0) { double step = m_params[0]; m_params.clear(); if (step > 0 || dmin > 0) { m_params.push_back(dmin); m_params.push_back(step); m_params.push_back(dmax); g_log.information() << "d-Spacing Binning: " << m_params[0] << " " << m_params[1] << " " << m_params[2] << "\n"; } } } else { if (m_params.size() == 1 && tmax > 0) { double step = m_params[0]; if (step > 0 || tmin > 0) { m_params[0] = tmin; m_params.push_back(step); m_params.push_back(tmax); g_log.information() << "TOF Binning: " << m_params[0] << " " << m_params[1] << " " << m_params[2] << "\n"; } } } xmin = 0.; xmax = 0.; if (tmin > 0.) { xmin = tmin; } if (tmax > 0.) { xmax = tmax; } if (!dspace && m_params.size() == 3) { xmin = m_params[0]; xmax = m_params[2]; } // Low resolution int lowresoffset = getProperty("LowResSpectrumOffset"); if (lowresoffset < 0) { m_processLowResTOF = false; } else { m_processLowResTOF = true; m_lowResSpecOffset = static_cast<size_t>(lowresoffset); } loadCalFile(calFilename, groupFilename); // Now setup the output workspace m_outputW = getProperty("OutputWorkspace"); if (m_inputEW) { if (m_outputW != m_inputW) { m_outputEW = m_inputEW->clone(); } m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); } else { if (m_outputW != m_inputW) { m_outputW = WorkspaceFactory::Instance().create(m_inputW); } } if (m_processLowResTOF) { if (!m_inputEW) { throw std::runtime_error( "Input workspace is not EventWorkspace. It is not supported now."); } else { // Make a brand new EventWorkspace m_lowResEW = boost::dynamic_pointer_cast<EventWorkspace>( WorkspaceFactory::Instance().create( "EventWorkspace", m_inputEW->getNumberHistograms(), 2, 1)); // Cast to the matrixOutputWS and save it m_lowResW = boost::dynamic_pointer_cast<MatrixWorkspace>(m_lowResEW); // m_lowResW->setName(lowreswsname); } } // set up a progress bar with the "correct" number of steps m_progress = new Progress(this, 0., 1., 22); if (m_inputEW) { double tolerance = getProperty("CompressTolerance"); if (tolerance > 0.) { g_log.information() << "running CompressEvents(Tolerance=" << tolerance << ") started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr compressAlg = createChildAlgorithm("CompressEvents"); compressAlg->setProperty("InputWorkspace", m_outputEW); compressAlg->setProperty("OutputWorkspace", m_outputEW); compressAlg->setProperty("OutputWorkspace", m_outputEW); compressAlg->setProperty("Tolerance", tolerance); compressAlg->executeAsChildAlg(); m_outputEW = compressAlg->getProperty("OutputWorkspace"); m_outputW = boost::dynamic_pointer_cast<MatrixWorkspace>(m_outputEW); } else { g_log.information() << "Not compressing event list\n"; doSortEvents(m_outputW); // still sort to help some thing out } } m_progress->report(); if (xmin > 0. || xmax > 0.) { double tempmin; double tempmax; m_outputW->getXMinMax(tempmin, tempmax); g_log.information() << "running CropWorkspace(TOFmin=" << xmin << ", TOFmax=" << xmax << ") started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr cropAlg = createChildAlgorithm("CropWorkspace"); cropAlg->setProperty("InputWorkspace", m_outputW); cropAlg->setProperty("OutputWorkspace", m_outputW); if ((xmin > 0.) && (xmin > tempmin)) cropAlg->setProperty("Xmin", xmin); if ((xmax > 0.) && (xmax < tempmax)) cropAlg->setProperty("Xmax", xmax); cropAlg->executeAsChildAlg(); m_outputW = cropAlg->getProperty("OutputWorkspace"); m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); } m_progress->report(); // filter the input events if appropriate double removePromptPulseWidth = getProperty("RemovePromptPulseWidth"); if (removePromptPulseWidth > 0.) { m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); if (m_outputEW->getNumberEvents() > 0) { g_log.information() << "running RemovePromptPulse(Width=" << removePromptPulseWidth << ") started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr filterPAlg = createChildAlgorithm("RemovePromptPulse"); filterPAlg->setProperty("InputWorkspace", m_outputW); filterPAlg->setProperty("OutputWorkspace", m_outputW); filterPAlg->setProperty("Width", removePromptPulseWidth); filterPAlg->executeAsChildAlg(); m_outputW = filterPAlg->getProperty("OutputWorkspace"); m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); } else { g_log.information("skipping RemovePromptPulse on empty EventWorkspace"); } } m_progress->report(); if (maskBinTableWS) { g_log.information() << "running MaskBinsFromTable started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr alg = createChildAlgorithm("MaskBinsFromTable"); alg->setProperty("InputWorkspace", m_outputW); alg->setProperty("OutputWorkspace", m_outputW); alg->setProperty("MaskingInformation", maskBinTableWS); alg->executeAsChildAlg(); m_outputW = alg->getProperty("OutputWorkspace"); m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); } m_progress->report(); if (m_maskWS) { g_log.information() << "running MaskDetectors started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr maskAlg = createChildAlgorithm("MaskDetectors"); maskAlg->setProperty("Workspace", m_outputW); maskAlg->setProperty("MaskedWorkspace", m_maskWS); maskAlg->executeAsChildAlg(); Workspace_sptr tmpW = maskAlg->getProperty("Workspace"); m_outputW = boost::dynamic_pointer_cast<MatrixWorkspace>(tmpW); m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); } m_progress->report(); if (!dspace) m_outputW = rebin(m_outputW); m_progress->report(); if (m_calibrationWS) { g_log.information() << "running AlignDetectors started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr alignAlg = createChildAlgorithm("AlignDetectors"); alignAlg->setProperty("InputWorkspace", m_outputW); alignAlg->setProperty("OutputWorkspace", m_outputW); alignAlg->setProperty("CalibrationWorkspace", m_calibrationWS); alignAlg->executeAsChildAlg(); m_outputW = alignAlg->getProperty("OutputWorkspace"); } else { m_outputW = convertUnits(m_outputW, "dSpacing"); } m_progress->report(); if (LRef > 0. || minwl > 0. || DIFCref > 0. || (!isEmpty(maxwl))) { m_outputW = convertUnits(m_outputW, "TOF"); } m_progress->report(); // Beyond this point, low resolution TOF workspace is considered. if (LRef > 0.) { g_log.information() << "running UnwrapSNS(LRef=" << LRef << ",Tmin=" << tmin << ",Tmax=" << tmax << ") started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr removeAlg = createChildAlgorithm("UnwrapSNS"); removeAlg->setProperty("InputWorkspace", m_outputW); removeAlg->setProperty("OutputWorkspace", m_outputW); removeAlg->setProperty("LRef", LRef); if (tmin > 0.) removeAlg->setProperty("Tmin", tmin); if (tmax > tmin) removeAlg->setProperty("Tmax", tmax); removeAlg->executeAsChildAlg(); m_outputW = removeAlg->getProperty("OutputWorkspace"); } m_progress->report(); if (minwl > 0. || (!isEmpty(maxwl))) { // just crop the worksapce // turn off the low res stuff m_processLowResTOF = false; EventWorkspace_sptr ews = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); if (ews) g_log.information() << "Number of events = " << ews->getNumberEvents() << ". "; g_log.information("\n"); m_outputW = convertUnits(m_outputW, "Wavelength"); g_log.information() << "running CropWorkspace(WavelengthMin=" << minwl; if (!isEmpty(maxwl)) g_log.information() << ", WavelengthMax=" << maxwl; g_log.information() << ") started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr removeAlg = createChildAlgorithm("CropWorkspace"); removeAlg->setProperty("InputWorkspace", m_outputW); removeAlg->setProperty("OutputWorkspace", m_outputW); removeAlg->setProperty("XMin", minwl); removeAlg->setProperty("XMax", maxwl); removeAlg->executeAsChildAlg(); m_outputW = removeAlg->getProperty("OutputWorkspace"); if (ews) g_log.information() << "Number of events = " << ews->getNumberEvents() << ".\n"; } else if (DIFCref > 0.) { g_log.information() << "running RemoveLowResTof(RefDIFC=" << DIFCref << ",K=3.22) started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; EventWorkspace_sptr ews = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); if (ews) g_log.information() << "Number of events = " << ews->getNumberEvents() << ". "; g_log.information("\n"); API::IAlgorithm_sptr removeAlg = createChildAlgorithm("RemoveLowResTOF"); removeAlg->setProperty("InputWorkspace", m_outputW); removeAlg->setProperty("OutputWorkspace", m_outputW); removeAlg->setProperty("ReferenceDIFC", DIFCref); removeAlg->setProperty("K", 3.22); if (tmin > 0.) removeAlg->setProperty("Tmin", tmin); if (m_processLowResTOF) removeAlg->setProperty("LowResTOFWorkspace", m_lowResW); removeAlg->executeAsChildAlg(); m_outputW = removeAlg->getProperty("OutputWorkspace"); if (m_processLowResTOF) m_lowResW = removeAlg->getProperty("LowResTOFWorkspace"); } m_progress->report(); EventWorkspace_sptr ews = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); if (ews) { size_t numhighevents = ews->getNumberEvents(); if (m_processLowResTOF) { EventWorkspace_sptr lowes = boost::dynamic_pointer_cast<EventWorkspace>(m_lowResW); size_t numlowevents = lowes->getNumberEvents(); g_log.information() << "Number of high TOF events = " << numhighevents << "; " << "Number of low TOF events = " << numlowevents << ".\n"; } } m_progress->report(); // Convert units if (LRef > 0. || minwl > 0. || DIFCref > 0. || (!isEmpty(maxwl))) { m_outputW = convertUnits(m_outputW, "dSpacing"); if (m_processLowResTOF) m_lowResW = convertUnits(m_lowResW, "dSpacing"); } m_progress->report(); if (dspace) { m_outputW = rebin(m_outputW); if (m_processLowResTOF) m_lowResW = rebin(m_lowResW); } m_progress->report(); doSortEvents(m_outputW); if (m_processLowResTOF) doSortEvents(m_lowResW); m_progress->report(); // Diffraction focus m_outputW = diffractionFocus(m_outputW); if (m_processLowResTOF) m_lowResW = diffractionFocus(m_lowResW); m_progress->report(); doSortEvents(m_outputW); if (m_processLowResTOF) doSortEvents(m_lowResW); m_progress->report(); // this next call should probably be in for rebin as well // but it changes the system tests if (dspace && m_resampleX != 0) { m_outputW = rebin(m_outputW); if (m_processLowResTOF) m_lowResW = rebin(m_lowResW); } m_progress->report(); // edit the instrument geometry if (m_groupWS && (m_l1 > 0 || !tths.empty() || !l2s.empty() || !phis.empty())) { size_t numreg = m_outputW->getNumberHistograms(); try { // set up the vectors for doing everything auto specidsSplit = splitVectors(specids, numreg, "specids"); auto tthsSplit = splitVectors(tths, numreg, "two-theta"); auto l2sSplit = splitVectors(l2s, numreg, "L2"); auto phisSplit = splitVectors(phis, numreg, "phi"); // Edit instrument m_outputW = editInstrument(m_outputW, tthsSplit.reg, specidsSplit.reg, l2sSplit.reg, phisSplit.reg); if (m_processLowResTOF) { m_lowResW = editInstrument(m_lowResW, tthsSplit.low, specidsSplit.low, l2sSplit.low, phisSplit.low); } } catch (std::runtime_error &e) { g_log.warning("Not editing instrument geometry:"); g_log.warning(e.what()); } } m_progress->report(); // Conjoin 2 workspaces if there is low resolution if (m_processLowResTOF) { m_outputW = conjoinWorkspaces(m_outputW, m_lowResW, m_lowResSpecOffset); } m_progress->report(); // Convert units to TOF m_outputW = convertUnits(m_outputW, "TOF"); m_progress->report(); // compress again if appropriate double tolerance = getProperty("CompressTolerance"); m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW); if ((m_outputEW) && (tolerance > 0.)) { g_log.information() << "running CompressEvents(Tolerance=" << tolerance << ") started at " << Kernel::DateAndTime::getCurrentTime() << "\n"; API::IAlgorithm_sptr compressAlg = createChildAlgorithm("CompressEvents"); compressAlg->setProperty("InputWorkspace", m_outputEW); compressAlg->setProperty("OutputWorkspace", m_outputEW); compressAlg->setProperty("OutputWorkspace", m_outputEW); compressAlg->setProperty("Tolerance", tolerance); compressAlg->executeAsChildAlg(); m_outputEW = compressAlg->getProperty("OutputWorkspace"); m_outputW = boost::dynamic_pointer_cast<MatrixWorkspace>(m_outputEW); } m_progress->report(); if ((!m_params.empty()) && (m_params.size() != 1)) { m_params.erase(m_params.begin()); m_params.pop_back(); } if (!m_dmins.empty()) m_dmins.clear(); if (!m_dmaxs.empty()) m_dmaxs.clear(); m_outputW = rebin(m_outputW); m_progress->report(); // return the output workspace setProperty("OutputWorkspace", m_outputW); }
/// Execute the algorithm void SassenaFFT::exec() { const std::string gwsName = this->getPropertyValue("InputWorkspace"); API::WorkspaceGroup_sptr gws = this->getProperty("InputWorkspace"); const std::string ftqReName = gwsName + "_fqt.Re"; const std::string ftqImName = gwsName + "_fqt.Im"; // Make sure the intermediate structure factor is there if(!gws->contains(ftqReName) ) { const std::string errMessg = "workspace "+gwsName+" does not contain an intermediate structure factor"; this->g_log.error(errMessg); throw Kernel::Exception::NotFoundError("group workspace does not contain",ftqReName); } // Retrieve the real and imaginary parts of the intermediate scattering function DataObjects::Workspace2D_sptr fqtRe = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( gws->getItem( ftqReName ) ); DataObjects::Workspace2D_sptr fqtIm = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( gws->getItem( ftqImName ) ); // Calculate the FFT for all spectra, retaining only the real part since F(q,-t) = F*(q,t) int part=3; // extract the real part of the transform, assuming I(Q,t) is real const std::string sqwName = gwsName + "_sqw"; API::IAlgorithm_sptr fft = this->createChildAlgorithm("ExtractFFTSpectrum"); fft->setProperty<DataObjects::Workspace2D_sptr>("InputWorkspace", fqtRe); if( !this->getProperty("FFTonlyRealPart") ) { part=0; // extract the real part of the transform, assuming I(Q,t) is complex fft->setProperty<DataObjects::Workspace2D_sptr>("InputImagWorkspace", fqtIm); } fft->setPropertyValue("OutputWorkspace", sqwName ); fft->setProperty<int>("FFTPart",part); // extract the real part fft->executeAsChildAlg(); API::MatrixWorkspace_sptr sqw0 = fft->getProperty("OutputWorkspace"); DataObjects::Workspace2D_sptr sqw = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( sqw0 ); API::AnalysisDataService::Instance().addOrReplace( sqwName, sqw ); // Transform the X-axis to appropriate dimensions // We assume the units of the intermediate scattering function are in picoseconds // The resulting frequency unit is in mili-eV, thus use m_ps2meV API::IAlgorithm_sptr scaleX = this->createChildAlgorithm("ScaleX"); scaleX->setProperty<DataObjects::Workspace2D_sptr>("InputWorkspace",sqw); scaleX->setProperty<double>("Factor", m_ps2meV); scaleX->setProperty<DataObjects::Workspace2D_sptr>("OutputWorkspace", sqw); scaleX->executeAsChildAlg(); //Do we apply the detailed balance condition exp(E/(2*kT)) ? if( this->getProperty("DetailedBalance") ) { double T = this->getProperty("Temp"); // The ExponentialCorrection algorithm assumes the form C0*exp(-C1*x). Note the explicit minus in the exponent API::IAlgorithm_sptr ec = this->createChildAlgorithm("ExponentialCorrection"); ec->setProperty<DataObjects::Workspace2D_sptr>("InputWorkspace", sqw); ec->setProperty<DataObjects::Workspace2D_sptr>("OutputWorkspace", sqw); ec->setProperty<double>("C0",1.0); ec->setProperty<double>("C1",-1.0/(2.0*T*m_T2ueV)); // Temperature in units of ueV ec->setPropertyValue("Operation","Multiply"); ec->executeAsChildAlg(); } // Set the Energy unit for the X-axis sqw->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("DeltaE"); // Add to group workspace, except if we are replacing the workspace. In this case, the group workspace // is already notified of the changes by the analysis data service. if(!gws->contains(sqwName)) { gws->add( sqwName ); } else { this->g_log.information("Workspace "+sqwName+" replaced with new contents"); } }
/** * Gaussian fit to determine peak position if no user position given. * * @return :: detector position of the peak: Gaussian fit and position * of the maximum (serves as start value for the optimization) */ double LoadILLReflectometry::reflectometryPeak() { if (!isDefault("BeamCentre")) { return getProperty("BeamCentre"); } size_t startIndex; size_t endIndex; std::tie(startIndex, endIndex) = fitIntegrationWSIndexRange(*m_localWorkspace); IAlgorithm_sptr integration = createChildAlgorithm("Integration"); integration->initialize(); integration->setProperty("InputWorkspace", m_localWorkspace); integration->setProperty("OutputWorkspace", "__unused_for_child"); integration->setProperty("StartWorkspaceIndex", static_cast<int>(startIndex)); integration->setProperty("EndWorkspaceIndex", static_cast<int>(endIndex)); integration->execute(); MatrixWorkspace_sptr integralWS = integration->getProperty("OutputWorkspace"); IAlgorithm_sptr transpose = createChildAlgorithm("Transpose"); transpose->initialize(); transpose->setProperty("InputWorkspace", integralWS); transpose->setProperty("OutputWorkspace", "__unused_for_child"); transpose->execute(); integralWS = transpose->getProperty("OutputWorkspace"); rebinIntegralWorkspace(*integralWS); // determine initial height: maximum value const auto maxValueIt = std::max_element(integralWS->y(0).cbegin(), integralWS->y(0).cend()); const double height = *maxValueIt; // determine initial centre: index of the maximum value const size_t maxIndex = std::distance(integralWS->y(0).cbegin(), maxValueIt); const double centreByMax = static_cast<double>(maxIndex); g_log.debug() << "Peak maximum position: " << centreByMax << '\n'; // determine sigma const auto &ys = integralWS->y(0); auto lessThanHalfMax = [height](const double x) { return x < 0.5 * height; }; using IterType = HistogramData::HistogramY::const_iterator; std::reverse_iterator<IterType> revMaxValueIt{maxValueIt}; auto revMinFwhmIt = std::find_if(revMaxValueIt, ys.crend(), lessThanHalfMax); auto maxFwhmIt = std::find_if(maxValueIt, ys.cend(), lessThanHalfMax); std::reverse_iterator<IterType> revMaxFwhmIt{maxFwhmIt}; if (revMinFwhmIt == ys.crend() || maxFwhmIt == ys.cend()) { g_log.warning() << "Couldn't determine fwhm of beam, using position of max " "value as beam center.\n"; return centreByMax; } const double fwhm = static_cast<double>(std::distance(revMaxFwhmIt, revMinFwhmIt) + 1); g_log.debug() << "Initial fwhm (full width at half maximum): " << fwhm << '\n'; // generate Gaussian auto func = API::FunctionFactory::Instance().createFunction("CompositeFunction"); auto sum = boost::dynamic_pointer_cast<API::CompositeFunction>(func); func = API::FunctionFactory::Instance().createFunction("Gaussian"); auto gaussian = boost::dynamic_pointer_cast<API::IPeakFunction>(func); gaussian->setHeight(height); gaussian->setCentre(centreByMax); gaussian->setFwhm(fwhm); sum->addFunction(gaussian); func = API::FunctionFactory::Instance().createFunction("LinearBackground"); func->setParameter("A0", 0.); func->setParameter("A1", 0.); sum->addFunction(func); // call Fit child algorithm API::IAlgorithm_sptr fit = createChildAlgorithm("Fit"); fit->initialize(); fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(sum)); fit->setProperty("InputWorkspace", integralWS); fit->setProperty("StartX", centreByMax - 3 * fwhm); fit->setProperty("EndX", centreByMax + 3 * fwhm); fit->execute(); const std::string fitStatus = fit->getProperty("OutputStatus"); if (fitStatus != "success") { g_log.warning("Fit not successful, using position of max value.\n"); return centreByMax; } const auto centre = gaussian->centre(); g_log.debug() << "Sigma: " << gaussian->fwhm() << '\n'; g_log.debug() << "Estimated peak position: " << centre << '\n'; return centre; }
/** Calls Gaussian1D as a child algorithm to fit the offset peak in a spectrum * * @param wi :: The Workspace Index to fit. * @param inputW :: Input workspace. * @param peakPositions :: Peak positions. * @param fitWindows :: Fit windows. * @param nparams :: Number of parameters. * @param minD :: Min distance. * @param maxD :: Max distance. * @param peakPosToFit :: Actual peak positions to fit (output). * @param peakPosFitted :: Actual peak positions fitted (output). * @param chisq :: chisq. * @param peakHeights :: vector for fitted heights of peaks * @param i_highestpeak:: index of the highest peak among all peaks * @param resolution :: spectrum's resolution delta(d)/d * @param dev_resolution :: standard deviation resolution * @return The number of peaks in range */ int GetDetOffsetsMultiPeaks::fitSpectra( const int64_t wi, MatrixWorkspace_sptr inputW, const std::vector<double> &peakPositions, const std::vector<double> &fitWindows, size_t &nparams, double &minD, double &maxD, std::vector<double> &peakPosToFit, std::vector<double> &peakPosFitted, std::vector<double> &chisq, std::vector<double> &peakHeights, int &i_highestpeak, double &resolution, double &dev_resolution) { // Default overall fit range is the whole spectrum const MantidVec &X = inputW->readX(wi); minD = X.front(); maxD = X.back(); // Trim in the edges based on where the data turns off of zero const MantidVec &Y = inputW->readY(wi); size_t minDindex = 0; for (; minDindex < Y.size(); ++minDindex) { if (Y[minDindex] > 0.) { minD = X[minDindex]; break; } } if (minD >= maxD) { // throw if minD >= maxD std::stringstream ess; ess << "Stuff went wrong with wkspIndex=" << wi << " specIndex=" << inputW->getSpectrum(wi)->getSpectrumNo(); throw std::runtime_error(ess.str()); } size_t maxDindex = Y.size() - 1; for (; maxDindex > minDindex; --maxDindex) { if (Y[maxDindex] > 0.) { maxD = X[maxDindex]; break; } } std::stringstream dbss; dbss << "D-RANGE[" << inputW->getSpectrum(wi)->getSpectrumNo() << "]: " << minD << " -> " << maxD; g_log.debug(dbss.str()); // Setup the fit windows bool useFitWindows = (!fitWindows.empty()); std::vector<double> fitWindowsToUse; for (int i = 0; i < static_cast<int>(peakPositions.size()); ++i) { if ((peakPositions[i] > minD) && (peakPositions[i] < maxD)) { if (m_useFitWindowTable) { fitWindowsToUse.push_back(std::max(m_vecFitWindow[wi][2 * i], minD)); fitWindowsToUse.push_back( std::min(m_vecFitWindow[wi][2 * i + 1], maxD)); } else if (useFitWindows) { fitWindowsToUse.push_back(std::max(fitWindows[2 * i], minD)); fitWindowsToUse.push_back(std::min(fitWindows[2 * i + 1], maxD)); } peakPosToFit.push_back(peakPositions[i]); } } int numPeaksInRange = static_cast<int>(peakPosToFit.size()); if (numPeaksInRange == 0) { std::stringstream outss; outss << "Spectrum " << wi << " has no peak in range (" << minD << ", " << maxD << ")"; g_log.information(outss.str()); return 0; } // Fit peaks API::IAlgorithm_sptr findpeaks = createChildAlgorithm("FindPeaks", -1, -1, false); findpeaks->setProperty("InputWorkspace", inputW); findpeaks->setProperty<int>("FWHM", 7); findpeaks->setProperty<int>("Tolerance", 4); // FindPeaks will do the checking on the validity of WorkspaceIndex findpeaks->setProperty("WorkspaceIndex", static_cast<int>(wi)); // Get the specified peak positions, which is optional findpeaks->setProperty("PeakPositions", peakPosToFit); if (useFitWindows) findpeaks->setProperty("FitWindows", fitWindowsToUse); findpeaks->setProperty<std::string>("PeakFunction", m_peakType); findpeaks->setProperty<std::string>("BackgroundType", m_backType); findpeaks->setProperty<bool>("HighBackground", this->getProperty("HighBackground")); findpeaks->setProperty<int>("MinGuessedPeakWidth", 4); findpeaks->setProperty<int>("MaxGuessedPeakWidth", 4); findpeaks->setProperty<double>("MinimumPeakHeight", m_minPeakHeight); findpeaks->setProperty("StartFromObservedPeakCentre", true); findpeaks->executeAsChildAlg(); // Collect fitting resutl of all peaks ITableWorkspace_sptr peakslist = findpeaks->getProperty("PeaksList"); // use tmpPeakPosToFit to shuffle the vectors std::vector<double> tmpPeakPosToFit; generatePeaksList(peakslist, static_cast<int>(wi), peakPosToFit, tmpPeakPosToFit, peakPosFitted, peakHeights, chisq, (useFitWindows || m_useFitWindowTable), fitWindowsToUse, minD, maxD, resolution, dev_resolution); peakPosToFit = tmpPeakPosToFit; nparams = peakPosFitted.size(); // Find the highest peak i_highestpeak = -1; double maxheight = 0; for (int i = 0; i < static_cast<int>(peakPosFitted.size()); ++i) { double tmpheight = peakHeights[i]; if (tmpheight > maxheight) { maxheight = tmpheight; i_highestpeak = i; } } return numPeaksInRange; }
void MaskBinsFromTable::exec() { MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); DataObjects::TableWorkspace_sptr paramWS = getProperty("MaskingInformation"); // 1. Check input table workspace and column order g_log.debug() << "Lines of parameters workspace = " << paramWS->rowCount() << std::endl; bool colname_specx = false; if (!paramWS) { throw std::invalid_argument("Input table workspace is not accepted."); } else { std::vector<std::string> colnames = paramWS->getColumnNames(); // check colum name order if (colnames.size() < 3) { g_log.error() << "Input MaskingInformation table workspace has fewer than 3 columns. " << colnames.size() << " columns indeed" << std::endl; throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns."); } if (colnames[0].compare("XMin") == 0) { // 1. Style XMin, XMax, SpectraList. Check rest if (colnames[1].compare("XMax") != 0 || colnames[2].compare("SpectraList") != 0) { g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl; throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns."); } } else if (colnames[0].compare("SpectraList") == 0) { // 2. Style SpectraList, XMin, XMax colname_specx = true; if (colnames[1].compare("XMin") != 0 || colnames[2].compare("XMax") != 0) { g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl; throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns."); } } else { g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl; throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns."); } } // 2. Loop over all rows bool firstloop = true; API::MatrixWorkspace_sptr outputws = this->getProperty("OutputWorkspace"); for (size_t ib = 0; ib < paramWS->rowCount(); ++ib) { API::TableRow therow = paramWS->getRow(ib); double xmin, xmax; std::string speclist; if (colname_specx) { therow >> speclist >> xmin >> xmax; } else { therow >> xmin >> xmax >> speclist; } g_log.debug() << "Row " << ib << " XMin = " << xmin << " XMax = " << xmax << " SpectraList = " << speclist << std::endl; API::IAlgorithm_sptr maskbins = this->createChildAlgorithm("MaskBins", 0, 0.3, true); maskbins->initialize(); if (firstloop) { maskbins->setProperty("InputWorkspace", inputWS); firstloop = false; } else { maskbins->setProperty("InputWorkspace", outputws); } maskbins->setProperty("OutputWorkspace", outputws); maskbins->setPropertyValue("SpectraList", speclist); maskbins->setProperty("XMin", xmin); maskbins->setProperty("XMax", xmax); bool isexec = maskbins->execute(); if (!isexec) { g_log.error() << "MaskBins() is not executed for row " << ib << std::endl; throw std::runtime_error("MaskBins() is not executed"); } outputws = maskbins->getProperty("OutputWorkspace"); if (!outputws) { g_log.error() << "OutputWorkspace is not retrieved for row " << ib << ". " << std::endl; throw std::runtime_error("OutputWorkspace is not got from MaskBins"); } }
/** Get a workspace identified by an InputData structure. * @param data :: InputData with name and either spec or i fields defined. * @return InputData structure with the ws field set if everything was OK. */ PlotPeakByLogValue::InputData PlotPeakByLogValue::getWorkspace(const InputData& data) { InputData out(data); if (API::AnalysisDataService::Instance().doesExist(data.name)) { DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( API::AnalysisDataService::Instance().retrieve(data.name)); if (ws) { out.ws = ws; } else { return data; } } else { std::ifstream fil(data.name.c_str()); if (!fil) { g_log.warning() << "File "<<data.name<<" does not exist\n"; return data; } fil.close(); std::string::size_type i = data.name.find_last_of('.'); if (i == std::string::npos) { g_log.warning() << "Cannot open file "<<data.name<<"\n"; return data; } std::string ext = data.name.substr(i); try { API::IAlgorithm_sptr load = createSubAlgorithm("Load"); load->initialize(); load->setPropertyValue("FileName",data.name); load->execute(); if (load->isExecuted()) { API::Workspace_sptr rws = load->getProperty("OutputWorkspace"); if (rws) { DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(rws); if (ws) { out.ws = ws; } else { API::WorkspaceGroup_sptr gws = boost::dynamic_pointer_cast<API::WorkspaceGroup>(rws); if (gws) { std::vector<std::string> wsNames = gws->getNames(); std::string propName = "OUTPUTWORKSPACE_" + boost::lexical_cast<std::string>(data.period); if (load->existsProperty(propName)) { Workspace_sptr rws1 = load->getProperty(propName); out.ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(rws1); } } } } } } catch(std::exception& e) { g_log.error(e.what()); return data; } } if (!out.ws) return data; API::Axis* axis = out.ws->getAxis(1); if (axis->isSpectra()) {// spectra axis if (out.spec < 0) { if (out.i >= 0) { out.spec = axis->spectraNo(out.i); } else {// i < 0 && spec < 0 => use start and end for(size_t i=0;i<axis->length();++i) { double s = double(axis->spectraNo(i)); if (s >= out.start && s <= out.end) { out.indx.push_back(static_cast<int>(i)); } } } } else { for(size_t i=0;i<axis->length();++i) { int j = axis->spectraNo(i); if (j == out.spec) { out.i = static_cast<int>(i); break; } } } if (out.i < 0 && out.indx.empty()) { return data; } } else {// numeric axis out.spec = -1; if (out.i >= 0) { out.indx.clear(); } else { if (out.i < -1) { out.start = (*axis)(0); out.end = (*axis)(axis->length()-1); } for(size_t i=0;i<axis->length();++i) { double s = (*axis)(i); if (s >= out.start && s <= out.end) { out.indx.push_back(static_cast<int>(i)); } } } } return out; }
/** * Executes the algorithm */ void PlotPeakByLogValue::exec() { // Create a list of the input workspace const std::vector<InputData> wsNames = makeNames(); std::string fun = getPropertyValue("Function"); //int wi = getProperty("WorkspaceIndex"); std::string logName = getProperty("LogValue"); bool sequential = getPropertyValue("FitType") == "Sequential"; bool isDataName = false; // if true first output column is of type string and is the data source name ITableWorkspace_sptr result = WorkspaceFactory::Instance().createTable("TableWorkspace"); if (logName == "SourceName") { result->addColumn("str","Source name"); isDataName = true; } else if (logName.empty()) { result->addColumn("double","axis-1"); } else { result->addColumn("double",logName); } // Create an instance of the fitting function to obtain the names of fitting parameters IFitFunction* ifun = FunctionFactory::Instance().createInitialized(fun); if (!ifun) { throw std::invalid_argument("Fitting function failed to initialize"); } for(size_t iPar=0;iPar<ifun->nParams();++iPar) { result->addColumn("double",ifun->parameterName(iPar)); result->addColumn("double",ifun->parameterName(iPar)+"_Err"); } result->addColumn("double","Chi_squared"); delete ifun; setProperty("OutputWorkspace",result); double dProg = 1./static_cast<double>(wsNames.size()); double Prog = 0.; for(int i=0;i<static_cast<int>(wsNames.size());++i) { InputData data = getWorkspace(wsNames[i]); if (!data.ws) { g_log.warning() << "Cannot access workspace " << wsNames[i].name << '\n'; continue; } if (data.i < 0 && data.indx.empty()) { g_log.warning() << "Zero spectra selected for fitting in workspace " << wsNames[i].name << '\n'; continue; } int j,jend; if (data.i >= 0) { j = data.i; jend = j + 1; } else {// no need to check data.indx.empty() j = data.indx.front(); jend = data.indx.back() + 1; } dProg /= abs(jend - j); for(;j < jend;++j) { // Find the log value: it is either a log-file value or simply the workspace number double logValue; if (logName.empty()) { API::Axis* axis = data.ws->getAxis(1); logValue = (*axis)(j); } else if (logName != "SourceName") { Kernel::Property* prop = data.ws->run().getLogData(logName); if (!prop) { throw std::invalid_argument("Log value "+logName+" does not exist"); } TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(prop); logValue = logp->lastValue(); } std::string resFun = fun; std::vector<double> errors; double chi2; try { // Fit the function API::IAlgorithm_sptr fit = createSubAlgorithm("Fit"); fit->initialize(); fit->setProperty("InputWorkspace",data.ws); //fit->setPropertyValue("InputWorkspace",data.ws->getName()); fit->setProperty("WorkspaceIndex",j); fit->setPropertyValue("Function",fun); fit->setPropertyValue("StartX",getPropertyValue("StartX")); fit->setPropertyValue("EndX",getPropertyValue("EndX")); fit->setPropertyValue("Minimizer",getPropertyValue("Minimizer")); fit->setPropertyValue("CostFunction",getPropertyValue("CostFunction")); fit->execute(); resFun = fit->getPropertyValue("Function"); errors = fit->getProperty("Errors"); chi2 = fit->getProperty("OutputChi2overDoF"); } catch(...) { g_log.error("Error in Fit subalgorithm"); throw; } if (sequential) { fun = resFun; } // Extract the fitted parameters and put them into the result table TableRow row = result->appendRow(); if (isDataName) { row << wsNames[i].name; } else { row << logValue; } ifun = FunctionFactory::Instance().createInitialized(resFun); for(size_t iPar=0;iPar<ifun->nParams();++iPar) { row << ifun->getParameter(iPar) << errors[iPar]; } row << chi2; delete ifun; Prog += dProg; progress(Prog); interruption_point(); } // for(;j < jend;++j) } }
/** Select background automatically */ DataObjects::Workspace2D_sptr ProcessBackground::autoBackgroundSelection(Workspace2D_sptr bkgdWS) { // Get background type and create bakground function BackgroundFunction_sptr bkgdfunction = createBackgroundFunction(m_bkgdType); int bkgdorder = getProperty("BackgroundOrder"); bkgdfunction->setAttributeValue("n", bkgdorder); g_log.debug() << "DBx622 Background Workspace has " << bkgdWS->readX(0).size() << " data points." << std::endl; // Fit input (a few) background pionts to get initial guess API::IAlgorithm_sptr fit; try { fit = this->createChildAlgorithm("Fit", 0.0, 0.2, true); } catch (Exception::NotFoundError &) { g_log.error() << "Requires CurveFitting library." << std::endl; throw; } double startx = m_lowerBound; double endx = m_upperBound; fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(bkgdfunction)); fit->setProperty("InputWorkspace", bkgdWS); fit->setProperty("WorkspaceIndex", 0); fit->setProperty("MaxIterations", 500); fit->setProperty("StartX", startx); fit->setProperty("EndX", endx); fit->setProperty("Minimizer", "Levenberg-Marquardt"); fit->setProperty("CostFunction", "Least squares"); fit->executeAsChildAlg(); // Get fit result // a) Status std::string fitStatus = fit->getProperty("OutputStatus"); bool allowedfailure = (fitStatus.find("cannot") < fitStatus.size()) && (fitStatus.find("tolerance") < fitStatus.size()); if (fitStatus.compare("success") != 0 && !allowedfailure) { g_log.error() << "ProcessBackground: Fit Status = " << fitStatus << ". Not to update fit result" << std::endl; throw std::runtime_error("Bad Fit"); } // b) check that chi2 got better const double chi2 = fit->getProperty("OutputChi2overDoF"); g_log.information() << "Fit background: Fit Status = " << fitStatus << ", chi2 = " << chi2 << "\n"; // c) get out the parameter names API::IFunction_sptr func = fit->getProperty("Function"); /* Comment out as not being used std::vector<std::string> parnames = func->getParameterNames(); std::map<std::string, double> parvalues; for (size_t iname = 0; iname < parnames.size(); ++iname) { double value = func->getParameter(parnames[iname]); parvalues.insert(std::make_pair(parnames[iname], value)); } DataObject::Workspace2D_const_sptr theorybackground = AnalysisDataService::Instance().retrieve(wsname); */ // Filter and construct for the output workspace Workspace2D_sptr outws = filterForBackground(bkgdfunction); return outws; } // END OF FUNCTION
/** Executes the algorithm * * @throw Exception::FileError If the grouping file cannot be opened or read successfully * @throw runtime_error If unable to run one of the sub-algorithms successfully */ void DiffractionFocussing::exec() { // retrieve the properties std::string groupingFileName=getProperty("GroupingFileName"); // Get the input workspace MatrixWorkspace_sptr inputW = getProperty("InputWorkspace"); bool dist = inputW->isDistribution(); //do this first to check that a valid file is available before doing any work std::multimap<int64_t,int64_t> detectorGroups;// <group, UDET> if (!readGroupingFile(groupingFileName, detectorGroups)) { throw Exception::FileError("Error reading .cal file",groupingFileName); } //Convert to d-spacing units API::MatrixWorkspace_sptr tmpW = convertUnitsToDSpacing(inputW); //Rebin to a common set of bins RebinWorkspace(tmpW); std::set<int64_t> groupNumbers; for(std::multimap<int64_t,int64_t>::const_iterator d = detectorGroups.begin();d!=detectorGroups.end();d++) { if (groupNumbers.find(d->first) == groupNumbers.end()) { groupNumbers.insert(d->first); } } int iprogress = 0; int iprogress_count = static_cast<int>(groupNumbers.size()); int iprogress_step = iprogress_count / 100; if (iprogress_step == 0) iprogress_step = 1; std::vector<int64_t> resultIndeces; for(std::set<int64_t>::const_iterator g = groupNumbers.begin();g!=groupNumbers.end();g++) { if (iprogress++ % iprogress_step == 0) { progress(0.68 + double(iprogress)/iprogress_count/3); } std::multimap<int64_t,int64_t>::const_iterator from = detectorGroups.lower_bound(*g); std::multimap<int64_t,int64_t>::const_iterator to = detectorGroups.upper_bound(*g); std::vector<detid_t> detectorList; for(std::multimap<int64_t,int64_t>::const_iterator d = from;d!=to;d++) detectorList.push_back(static_cast<detid_t>(d->second)); // Want version 1 of GroupDetectors here API::IAlgorithm_sptr childAlg = createSubAlgorithm("GroupDetectors",-1.0,-1.0,true,1); childAlg->setProperty("Workspace", tmpW); childAlg->setProperty< std::vector<detid_t> >("DetectorList",detectorList); childAlg->executeAsSubAlg(); try { // get the index of the combined spectrum int ri = childAlg->getProperty("ResultIndex"); if (ri >= 0) { resultIndeces.push_back(ri); } } catch(...) { throw std::runtime_error("Unable to get Properties from GroupDetectors sub-algorithm"); } } // Discard left-over spectra, but print warning message giving number discarded int discarded = 0; const int64_t oldHistNumber = tmpW->getNumberHistograms(); API::Axis *spectraAxis = tmpW->getAxis(1); for(int64_t i=0; i < oldHistNumber; i++) if ( spectraAxis->spectraNo(i) >= 0 && find(resultIndeces.begin(),resultIndeces.end(),i) == resultIndeces.end()) { ++discarded; } g_log.warning() << "Discarded " << discarded << " spectra that were not assigned to any group" << std::endl; // Running GroupDetectors leads to a load of redundant spectra // Create a new workspace that's the right size for the meaningful spectra and copy them in int64_t newSize = tmpW->blocksize(); API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(tmpW,resultIndeces.size(),newSize+1,newSize); // Copy units outputW->getAxis(0)->unit() = tmpW->getAxis(0)->unit(); outputW->getAxis(1)->unit() = tmpW->getAxis(1)->unit(); API::Axis *spectraAxisNew = outputW->getAxis(1); for(int64_t hist=0; hist < static_cast<int64_t>(resultIndeces.size()); hist++) { int64_t i = resultIndeces[hist]; double spNo = static_cast<double>(spectraAxis->spectraNo(i)); MantidVec &tmpE = tmpW->dataE(i); MantidVec &outE = outputW->dataE(hist); MantidVec &tmpY = tmpW->dataY(i); MantidVec &outY = outputW->dataY(hist); MantidVec &tmpX = tmpW->dataX(i); MantidVec &outX = outputW->dataX(hist); outE.assign(tmpE.begin(),tmpE.end()); outY.assign(tmpY.begin(),tmpY.end()); outX.assign(tmpX.begin(),tmpX.end()); spectraAxisNew->setValue(hist,spNo); spectraAxis->setValue(i,-1); } progress(1.); outputW->isDistribution(dist); // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); return; }