/** * Disable points in the workpsace in the way that points which are not included in any of specified * sections are not used when fitting given workspace * @param ws :: Workspace to disable points in * @param sections :: Section we want to use for fitting */ void ALCBaselineModellingModel::disableUnwantedPoints(MatrixWorkspace_sptr ws, const std::vector<IALCBaselineModellingModel::Section>& sections) { // Whether point with particular index should be disabled std::vector<bool> toDisable(ws->blocksize(), true); // Find points which are in at least one section, and exclude them from disable list for (size_t i = 0; i < ws->blocksize(); ++i) { for (auto it = sections.begin(); it != sections.end(); ++it) { if ( ws->dataX(0)[i] >= it->first && ws->dataX(0)[i] <= it->second ) { toDisable[i] = false; break; // No need to check other sections } } } // XXX: Points are disabled by settings their errors to very high value. This makes those // points to have very low weights during the fitting, effectively disabling them. const double DISABLED_ERR = std::numeric_limits<double>::max(); // Disable chosen points for (size_t i = 0; i < ws->blocksize(); ++i) { if (toDisable[i]) { ws->dataE(0)[i] = DISABLED_ERR; } } }
/** * Computes the square root of the errors and if the input was a distribution * this divides by the new bin-width * @param outputWS The workspace containing the output data * @param inputWS The input workspace used for testing distribution state */ void Rebin2D::normaliseOutput(MatrixWorkspace_sptr outputWS, MatrixWorkspace_const_sptr inputWS) { //PARALLEL_FOR1(outputWS) for(int64_t i = 0; i < static_cast<int64_t>(outputWS->getNumberHistograms()); ++i) { PARALLEL_START_INTERUPT_REGION MantidVec & outputY = outputWS->dataY(i); MantidVec & outputE = outputWS->dataE(i); for(size_t j = 0; j < outputWS->blocksize(); ++j) { m_progress->report("Calculating errors"); const double binWidth = (outputWS->readX(i)[j+1] - outputWS->readX(i)[j]); double eValue = std::sqrt(outputE[j]); // Don't do this for a RebinnedOutput workspace. The fractions // take care of such things. if( inputWS->isDistribution() && inputWS->id() != "RebinnedOutput") { outputY[j] /= binWidth; eValue /= binWidth; } outputE[j] = eValue; } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputWS->isDistribution(inputWS->isDistribution()); }
MatrixWorkspace_sptr CalculateIqt::removeInvalidData(MatrixWorkspace_sptr workspace) { auto binning = (workspace->blocksize() + 1) / 2; auto binV = workspace->x(0)[binning]; workspace = cropWorkspace(workspace, binV); return replaceSpecialValues(workspace); }
/** Create an output workspace of the appropriate (histogram or event) type * and * copy over the data * @param inputWS The input workspace */ API::MatrixWorkspace_sptr ConvertUnits::setupOutputWorkspace( const API::MatrixWorkspace_const_sptr inputWS) { MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); // If input and output workspaces are NOT the same, create a new workspace // for // the output if (outputWS != inputWS) { outputWS = inputWS->clone(); } if (!m_inputEvents && m_distribution) { // Loop over the histograms (detector spectra) Progress prog(this, 0.0, 0.2, m_numberOfSpectra); PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS)) for (int64_t i = 0; i < static_cast<int64_t>(m_numberOfSpectra); ++i) { PARALLEL_START_INTERUPT_REGION // Take the bin width dependency out of the Y & E data auto &X = outputWS->x(i); auto &Y = outputWS->mutableY(i); auto &E = outputWS->mutableE(i); for (size_t j = 0; j < outputWS->blocksize(); ++j) { const double width = std::abs(X[j + 1] - X[j]); Y[j] *= width; E[j] *= width; } prog.report("Convert to " + m_outputUnit->unitID()); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION }
/** Return the to-be axis of the workspace dependent on the log entry * @param ws : the input workspace * @return : the x-axis to use for the output workspace */ std::vector<double> ConjoinXRuns::getXAxis(MatrixWorkspace_sptr ws) const { std::vector<double> axis; axis.reserve(ws->blocksize()); auto &run = ws->run(); // try time series first TimeSeriesProperty<double> *timeSeriesDouble(nullptr); timeSeriesDouble = dynamic_cast<TimeSeriesProperty<double> *>(run.getLogData(m_logEntry)); if (timeSeriesDouble) { // try double series axis = timeSeriesDouble->filteredValuesAsVector(); } else { // try int series next TimeSeriesProperty<int> *timeSeriesInt(nullptr); timeSeriesInt = dynamic_cast<TimeSeriesProperty<int> *>(run.getLogData(m_logEntry)); if (timeSeriesInt) { std::vector<int> intAxis = timeSeriesInt->filteredValuesAsVector(); axis = std::vector<double>(intAxis.begin(), intAxis.end()); } else { // then scalar axis.push_back(run.getPropertyAsSingleValue(m_logEntry)); } } return axis; }
/** * Checks the input workspace's X data structure is logical. * @param inputWS pointer to input workspace * @returns True if the X structure of the given input is what we expect, i.e. NX=NY+1 */ bool ConvertToPointData::isWorkspaceLogical(const MatrixWorkspace_sptr inputWS) const { const size_t numBins = inputWS->blocksize(); const size_t numBoundaries = inputWS->readX(0).size(); if( numBoundaries != (numBins + 1) ) { g_log.error() << "The number of bin boundaries must be one greater than the number of bins. " << "Found nbins=" << numBins << " and nBoundaries=" << numBoundaries << "\n"; return false; } return true; }
void IQTransform::exec() { MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); // Print a warning if the input workspace has more than one spectrum if ( inputWS->getNumberHistograms() > 1 ) { g_log.warning("This algorithm is intended for use on single-spectrum workspaces.\n" "Only the first spectrum will be transformed."); } // Do background subtraction from a workspace first because it doesn't like // potential conversion to point data that follows. Requires a temporary workspace. MatrixWorkspace_sptr tmpWS; MatrixWorkspace_sptr backgroundWS = getProperty("BackgroundWorkspace"); if ( backgroundWS ) tmpWS = subtractBackgroundWS(inputWS,backgroundWS); else tmpWS = inputWS; // Create the output workspace const size_t length = tmpWS->blocksize(); MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(inputWS,1,length,length); m_label->setLabel(""); outputWS->setYUnit(""); // Copy the data over. Assume single spectrum input (output will be). // Take the mid-point of histogram bins if ( tmpWS->isHistogramData() ) { VectorHelper::convertToBinCentre(tmpWS->readX(0),outputWS->dataX(0)); } else { outputWS->setX(0,tmpWS->refX(0)); } MantidVec& Y = outputWS->dataY(0) = tmpWS->dataY(0); outputWS->dataE(0) = tmpWS->dataE(0); // Subtract a constant background if requested const double background = getProperty("BackgroundValue"); if ( background > 0.0 ) subtractBackgroundValue(Y,background); // Select the desired transformation function and call it TransformFunc f = m_transforms.find(getProperty("TransformType"))->second; (this->*f)(outputWS); // Need the generic label unit on this (unless the unit on the X axis hasn't changed) if ( ! m_label->caption().empty() ) outputWS->getAxis(0)->unit() = m_label; setProperty("OutputWorkspace",outputWS); }
void ImggFormatsConvertViewQtWidget::writeImg( MatrixWorkspace_sptr inWks, const std::string &outputName, const std::string &outFormat) const { if (!inWks) return; auto width = inWks->getNumberHistograms(); if (0 == width) return; auto height = inWks->blocksize(); QImage img(QSize(static_cast<int>(width), static_cast<int>(height)), QImage::Format_Indexed8); int tableSize = 256; QVector<QRgb> grayscale(tableSize); for (int i = 0; i < grayscale.size(); i++) { int level = i; // would be equivalent: qGray(i, i, i); grayscale[i] = qRgb(level, level, level); } img.setColorTable(grayscale); // only 16 to 8 bits color map supported with current libraries const double scaleFactor = std::numeric_limits<unsigned short int>::max() / std::numeric_limits<unsigned char>::max(); for (int yi = 0; yi < static_cast<int>(width); ++yi) { const auto &row = inWks->readY(yi); for (int xi = 0; xi < static_cast<int>(width); ++xi) { int scaled = static_cast<int>(row[xi] / scaleFactor); // Images not from IMAT, just crop. This needs much improvement when // we have proper Load/SaveImage algorithms if (scaled > 255) scaled = 255; if (scaled < 0) scaled = 0; img.setPixel(xi, yi, scaled); } } writeImgFile(img, outputName, outFormat); }
/** * Construct an "empty" output workspace in virtual-lambda for summation in Q. * The workspace will have the same x values as the input workspace but the y * values will all be zero. * * @return : a 1D workspace where y values are all zero */ MatrixWorkspace_sptr ReflectometryReductionOne2::constructIvsLamWS(MatrixWorkspace_sptr detectorWS) { // There is one output spectrum for each detector group const size_t numGroups = detectorGroups().size(); // Calculate the number of bins based on the min/max wavelength, using // the same bin width as the input workspace const double binWidth = (detectorWS->x(0).back() - detectorWS->x(0).front()) / static_cast<double>(detectorWS->blocksize()); const int numBins = static_cast<int>( std::ceil((wavelengthMax() - wavelengthMin()) / binWidth)); // Construct the histogram with these X values. Y and E values are zero. const BinEdges xValues(numBins, LinearGenerator(wavelengthMin(), binWidth)); // Create the output workspace MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create( detectorWS, numGroups, numBins, numBins - 1); // Loop through each detector group in the input for (size_t groupIdx = 0; groupIdx < numGroups; ++groupIdx) { // Get the detectors in this group auto &detectors = detectorGroups()[groupIdx]; // Set the x values for this spectrum outputWS->setBinEdges(groupIdx, xValues); // Set the detector ID from the twoThetaR detector. const size_t twoThetaRIdx = twoThetaRDetectorIdx(detectors); auto &outSpec = outputWS->getSpectrum(groupIdx); const detid_t twoThetaRDetID = m_spectrumInfo->detector(twoThetaRIdx).getID(); outSpec.clearDetectorIDs(); outSpec.addDetectorID(twoThetaRDetID); // Set the spectrum number from the twoThetaR detector SpectrumNumber specNum = detectorWS->indexInfo().spectrumNumber(twoThetaRIdx); auto indexInf = outputWS->indexInfo(); indexInf.setSpectrumNumbers(specNum, specNum); outputWS->setIndexInfo(indexInf); } return outputWS; }
void NormaliseToMonitor::exec() { // Get the input workspace const MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); // First check the inputs checkProperties(inputWS); bool isSingleCountWorkspace = false; try { isSingleCountWorkspace = (!inputWS->isHistogramData()) && (inputWS->blocksize() == 1); } catch (std::length_error &) { // inconsistent bin size, not a single count workspace isSingleCountWorkspace = false; } // See if the normalization with integration properties are set. const bool integrate = setIntegrationProps(isSingleCountWorkspace); if (integrate) normaliseByIntegratedCount(inputWS, outputWS, isSingleCountWorkspace); else normaliseBinByBin(inputWS, outputWS); setProperty("OutputWorkspace", outputWS); std::string norm_ws_name = getPropertyValue("NormFactorWS"); if (!norm_ws_name.empty()) { std::string out_name = getPropertyValue("OutputWorkspace"); if (out_name == norm_ws_name) { // if the normalization factor workspace name coincides with output // workspace name, add _normFactor suffix to this name norm_ws_name = norm_ws_name + "_normFactor"; auto pProp = (this->getPointerToProperty("NormFactorWS")); pProp->setValue(norm_ws_name); } if (!integrate) m_monitor = extractMonitorSpectra(m_monitor, m_workspaceIndexes); setProperty("NormFactorWS", m_monitor); } }
/** * Sets a new preview spectrum for the mini plot. * * @param value workspace index */ void ResNorm::previewSpecChanged(int value) { m_previewSpec = value; // Update vanadium plot if (m_uiForm.dsVanadium->isValid()) m_uiForm.ppPlot->addSpectrum( "Vanadium", m_uiForm.dsVanadium->getCurrentDataName(), m_previewSpec); // Update fit plot std::string fitWsGroupName(m_pythonExportWsName + "_Fit_Workspaces"); std::string fitParamsName(m_pythonExportWsName + "_Fit"); if (AnalysisDataService::Instance().doesExist(fitWsGroupName)) { WorkspaceGroup_sptr fitWorkspaces = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( fitWsGroupName); ITableWorkspace_sptr fitParams = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>( fitParamsName); if (fitWorkspaces && fitParams) { Column_const_sptr scaleFactors = fitParams->getColumn("Scaling"); std::string fitWsName(fitWorkspaces->getItem(m_previewSpec)->name()); MatrixWorkspace_const_sptr fitWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( fitWsName); MatrixWorkspace_sptr fit = WorkspaceFactory::Instance().create(fitWs, 1); fit->setX(0, fitWs->readX(1)); fit->getSpectrum(0)->setData(fitWs->readY(1), fitWs->readE(1)); for (size_t i = 0; i < fit->blocksize(); i++) fit->dataY(0)[i] /= scaleFactors->cell<double>(m_previewSpec); m_uiForm.ppPlot->addSpectrum("Fit", fit, 0, Qt::red); } } }
void ApplyPaalmanPings::run() { // Create / Initialize algorithm API::BatchAlgorithmRunner::AlgorithmRuntimeProps absCorProps; IAlgorithm_sptr applyCorrAlg = AlgorithmManager::Instance().create("ApplyPaalmanPingsCorrection"); applyCorrAlg->initialize(); // get Sample Workspace MatrixWorkspace_sptr sampleWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( m_sampleWorkspaceName); m_originalSampleUnits = sampleWs->getAxis(0)->unit()->unitID(); // If not in wavelength then do conversion if (m_originalSampleUnits != "Wavelength") { g_log.information( "Sample workspace not in wavelength, need to convert to continue."); absCorProps["SampleWorkspace"] = addConvertUnitsStep(sampleWs, "Wavelength"); } else { absCorProps["SampleWorkspace"] = m_sampleWorkspaceName; } const bool useCan = m_uiForm.ckUseCan->isChecked(); const bool useCorrections = m_uiForm.ckUseCorrections->isChecked(); // Get Can and Clone MatrixWorkspace_sptr canClone; if (useCan) { const auto canName = m_uiForm.dsContainer->getCurrentDataName().toStdString(); const auto cloneName = "__algorithm_can"; IAlgorithm_sptr clone = AlgorithmManager::Instance().create("CloneWorkspace"); clone->initialize(); clone->setProperty("InputWorkspace", canName); clone->setProperty("Outputworkspace", cloneName); clone->execute(); const bool useShift = m_uiForm.ckShiftCan->isChecked(); if (useShift) { IAlgorithm_sptr scaleX = AlgorithmManager::Instance().create("ScaleX"); scaleX->initialize(); scaleX->setLogging(false); scaleX->setProperty("InputWorkspace", cloneName); scaleX->setProperty("OutputWorkspace", cloneName); scaleX->setProperty("Factor", m_uiForm.spCanShift->value()); scaleX->setProperty("Operation", "Add"); scaleX->execute(); IAlgorithm_sptr rebin = AlgorithmManager::Instance().create("RebinToWorkspace"); rebin->initialize(); rebin->setLogging(false); rebin->setProperty("WorkspaceToRebin", cloneName); rebin->setProperty("WorkspaceToMatch", m_sampleWorkspaceName); rebin->setProperty("OutputWorkspace", cloneName); rebin->execute(); } canClone = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(cloneName); // Check for same binning across sample and container if (!checkWorkspaceBinningMatches(sampleWs, canClone)) { const char *text = "Binning on sample and container does not match." "Would you like to rebin the container to match the sample?"; int result = QMessageBox::question(NULL, tr("Rebin sample?"), tr(text), QMessageBox::Yes, QMessageBox::No, QMessageBox::NoButton); if (result == QMessageBox::Yes) { addRebinStep(QString::fromStdString(canName), QString::fromStdString(m_sampleWorkspaceName)); } else { m_batchAlgoRunner->clearQueue(); g_log.error("Cannot apply absorption corrections " "using a sample and " "container with different binning."); return; } } // If not in wavelength then do conversion std::string originalCanUnits = canClone->getAxis(0)->unit()->unitID(); if (originalCanUnits != "Wavelength") { g_log.information("Container workspace not in wavelength, need to " "convert to continue."); absCorProps["CanWorkspace"] = addConvertUnitsStep(canClone, "Wavelength"); } else { absCorProps["CanWorkspace"] = cloneName; } const bool useCanScale = m_uiForm.ckScaleCan->isChecked(); if (useCanScale) { const double canScaleFactor = m_uiForm.spCanScale->value(); applyCorrAlg->setProperty("CanScaleFactor", canScaleFactor); } } if (useCorrections) { QString correctionsWsName = m_uiForm.dsCorrections->getCurrentDataName(); WorkspaceGroup_sptr corrections = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( correctionsWsName.toStdString()); bool interpolateAll = false; for (size_t i = 0; i < corrections->size(); i++) { MatrixWorkspace_sptr factorWs = boost::dynamic_pointer_cast<MatrixWorkspace>(corrections->getItem(i)); // Check for matching binning if (sampleWs && (sampleWs->blocksize() != factorWs->blocksize())) { int result; if (interpolateAll) { result = QMessageBox::Yes; } else { std::string text = "Number of bins on sample and " + factorWs->name() + " workspace does not match.\n" + "Would you like to interpolate this workspace to " "match the sample?"; result = QMessageBox::question( NULL, tr("Interpolate corrections?"), tr(text.c_str()), QMessageBox::YesToAll, QMessageBox::Yes, QMessageBox::No); } switch (result) { case QMessageBox::YesToAll: interpolateAll = true; // fall through case QMessageBox::Yes: addInterpolationStep(factorWs, absCorProps["SampleWorkspace"]); break; default: m_batchAlgoRunner->clearQueue(); g_log.error("ApplyPaalmanPings cannot run with corrections that do " "not match sample binning."); return; } } } applyCorrAlg->setProperty("CorrectionsWorkspace", correctionsWsName.toStdString()); } // Generate output workspace name auto QStrSampleWsName = QString::fromStdString(m_sampleWorkspaceName); int nameCutIndex = QStrSampleWsName.lastIndexOf("_"); if (nameCutIndex == -1) nameCutIndex = QStrSampleWsName.length(); QString correctionType; switch (m_uiForm.cbGeometry->currentIndex()) { case 0: correctionType = "flt"; break; case 1: correctionType = "cyl"; break; case 2: correctionType = "anl"; break; } QString outputWsName = QStrSampleWsName.left(nameCutIndex); // Using corrections if (m_uiForm.ckUseCorrections->isChecked()) { outputWsName += "_" + correctionType + "_Corrected"; } else { outputWsName += "_Subtracted"; } // Using container if (m_uiForm.ckUseCan->isChecked()) { const auto canName = m_uiForm.dsContainer->getCurrentDataName().toStdString(); MatrixWorkspace_sptr containerWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(canName); auto run = containerWs->run(); if (run.hasProperty("run_number")) { outputWsName += "_" + QString::fromStdString(run.getProperty("run_number")->value()); } else { auto canCutIndex = QString::fromStdString(canName).indexOf("_"); outputWsName += "_" + QString::fromStdString(canName).left(canCutIndex); } } outputWsName += "_red"; applyCorrAlg->setProperty("OutputWorkspace", outputWsName.toStdString()); // Add corrections algorithm to queue m_batchAlgoRunner->addAlgorithm(applyCorrAlg, absCorProps); // Run algorithm queue connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(absCorComplete(bool))); m_batchAlgoRunner->executeBatchAsync(); // Set the result workspace for Python script export m_pythonExportWsName = outputWsName.toStdString(); // m_containerWorkspaceName = m_uiForm.dsContainer->getCurrentDataName(); // updateContainer(); }
double DiffractionEventCalibrateDetectors::intensity( double x, double y, double z, double rotx, double roty, double rotz, std::string detname, std::string inname, std::string outname, std::string peakOpt, std::string rb_param, std::string groupWSName) { EventWorkspace_sptr inputW = boost::dynamic_pointer_cast<EventWorkspace>( AnalysisDataService::Instance().retrieve(inname)); bool debug = true; CPUTimer tim; movedetector(x, y, z, rotx, roty, rotz, detname, inputW); if (debug) std::cout << tim << " to movedetector()\n"; IAlgorithm_sptr alg3 = createChildAlgorithm("ConvertUnits"); alg3->setProperty<EventWorkspace_sptr>("InputWorkspace", inputW); alg3->setPropertyValue("OutputWorkspace", outname); alg3->setPropertyValue("Target", "dSpacing"); alg3->executeAsChildAlg(); MatrixWorkspace_sptr outputW = alg3->getProperty("OutputWorkspace"); if (debug) std::cout << tim << " to ConvertUnits\n"; IAlgorithm_sptr alg4 = createChildAlgorithm("DiffractionFocussing"); alg4->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputW); alg4->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputW); alg4->setPropertyValue("GroupingFileName", ""); alg4->setPropertyValue("GroupingWorkspace", groupWSName); alg4->executeAsChildAlg(); outputW = alg4->getProperty("OutputWorkspace"); // Remove file if (debug) std::cout << tim << " to DiffractionFocussing\n"; IAlgorithm_sptr alg5 = createChildAlgorithm("Rebin"); alg5->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputW); alg5->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputW); alg5->setPropertyValue("Params", rb_param); alg5->executeAsChildAlg(); outputW = alg5->getProperty("OutputWorkspace"); if (debug) std::cout << tim << " to Rebin\n"; // Find point of peak centre const MantidVec &yValues = outputW->readY(0); auto it = std::max_element(yValues.begin(), yValues.end()); double peakHeight = *it; if (peakHeight == 0) return -0.000; double peakLoc = outputW->readX(0)[it - yValues.begin()]; IAlgorithm_sptr fit_alg; try { // set the ChildAlgorithm no to log as this will be run once per spectra fit_alg = createChildAlgorithm("Fit", -1, -1, false); } catch (Exception::NotFoundError &) { g_log.error("Can't locate Fit algorithm"); throw; } std::ostringstream fun_str; fun_str << "name=Gaussian,Height=" << peakHeight << ",Sigma=0.01,PeakCentre=" << peakLoc; fit_alg->setProperty("Function", fun_str.str()); fit_alg->setProperty("InputWorkspace", outputW); fit_alg->setProperty("WorkspaceIndex", 0); fit_alg->setProperty("StartX", outputW->readX(0)[0]); fit_alg->setProperty("EndX", outputW->readX(0)[outputW->blocksize()]); fit_alg->setProperty("MaxIterations", 200); fit_alg->setProperty("Output", "fit"); fit_alg->executeAsChildAlg(); if (debug) std::cout << tim << " to Fit\n"; std::vector<double> params; // = fit_alg->getProperty("Parameters"); Mantid::API::IFunction_sptr fun_res = fit_alg->getProperty("Function"); for (size_t i = 0; i < fun_res->nParams(); ++i) { params.push_back(fun_res->getParameter(i)); } peakHeight = params[0]; peakLoc = params[1]; movedetector(-x, -y, -z, -rotx, -roty, -rotz, detname, inputW); if (debug) std::cout << tim << " to movedetector()\n"; // Optimize C/peakheight + |peakLoc-peakOpt| where C is scaled by number of // events EventWorkspace_const_sptr inputE = boost::dynamic_pointer_cast<const EventWorkspace>(inputW); return (static_cast<int>(inputE->getNumberEvents()) / 1.e6) / peakHeight + std::fabs(peakLoc - boost::lexical_cast<double>(peakOpt)); }
/** Checks input properties and compares them to previous values * @param is :: [output] Number of the first run * @param ie :: [output] Number of the last run */ void PlotAsymmetryByLogValue::checkProperties(size_t &is, size_t &ie) { // Log Value m_logName = getPropertyValue("LogValue"); // Get function to apply to logValue m_logFunc = getPropertyValue("Function"); // Get type of computation m_int = (getPropertyValue("Type") == "Integral"); // Get grouping properties m_forward_list = getProperty("ForwardSpectra"); m_backward_list = getProperty("BackwardSpectra"); // Get green and red periods m_red = getProperty("Red"); m_green = getProperty("Green"); // Get time min and time max m_minTime = getProperty("TimeMin"); m_maxTime = getProperty("TimeMax"); // Get type of dead-time corrections m_dtcType = getPropertyValue("DeadTimeCorrType"); m_dtcFile = getPropertyValue("DeadTimeCorrFile"); // Get runs std::string firstFN = getProperty("FirstRun"); std::string lastFN = getProperty("LastRun"); // Parse run names and get the number of runs parseRunNames(firstFN, lastFN, m_filenameBase, m_filenameExt, m_filenameZeros); is = atoi(firstFN.c_str()); // starting run number ie = atoi(lastFN.c_str()); // last run number if (ie < is) { throw std::runtime_error( "First run number is greater than last run number"); } // Create a string holding all the properties std::ostringstream ss; ss << m_filenameBase << "," << m_filenameExt << "," << m_filenameZeros << ","; ss << m_dtcType << "," << m_dtcFile << ","; ss << getPropertyValue("ForwardSpectra") << "," << getPropertyValue("BackwardSpectra") << ","; ss << m_int << "," << m_minTime << "," << m_maxTime << ","; ss << m_red << "," << m_green << ","; ss << m_logName << ", " << m_logFunc; m_allProperties = ss.str(); // Check if we can re-use results from previous run // We can reuse results if: // 1. There is a ws in the ADS with name m_currResName // 2. It is a MatrixWorkspace // 3. It has a title equatl to m_allProperties // This ws stores previous results as described below if (AnalysisDataService::Instance().doesExist(m_currResName)) { MatrixWorkspace_sptr prevResults = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( m_currResName); if (prevResults) { if (m_allProperties == prevResults->getTitle()) { // We can re-use results size_t nPoints = prevResults->blocksize(); size_t nHisto = prevResults->getNumberHistograms(); if (nHisto == 2) { // Only 'red' data for (size_t i = 0; i < nPoints; i++) { // The first spectrum contains: X -> run number, Y -> log value // The second spectrum contains: Y -> redY, E -> redE size_t run = static_cast<size_t>(prevResults->readX(0)[i]); if ((run >= is) && (run <= ie)) { m_logValue[run] = prevResults->readY(0)[i]; m_redY[run] = prevResults->readY(1)[i]; m_redE[run] = prevResults->readE(1)[i]; } } } else { // 'Red' and 'Green' data for (size_t i = 0; i < nPoints; i++) { // The first spectrum contains: X -> run number, Y -> log value // The second spectrum contains: Y -> diffY, E -> diffE // The third spectrum contains: Y -> redY, E -> redE // The fourth spectrum contains: Y -> greenY, E -> greeE // The fifth spectrum contains: Y -> sumY, E -> sumE size_t run = static_cast<size_t>(prevResults->readX(0)[i]); if ((run >= is) && (run <= ie)) { m_logValue[run] = prevResults->readY(0)[i]; m_diffY[run] = prevResults->readY(1)[i]; m_diffE[run] = prevResults->readE(1)[i]; m_redY[run] = prevResults->readY(2)[i]; m_redE[run] = prevResults->readE(2)[i]; m_greenY[run] = prevResults->readY(3)[i]; m_greenE[run] = prevResults->readE(3)[i]; m_sumY[run] = prevResults->readY(4)[i]; m_sumE[run] = prevResults->readE(4)[i]; } } } } } } }
/** Carries out the bin-by-bin normalization * @param inputWorkspace The input workspace * @param outputWorkspace The result workspace */ void NormaliseToMonitor::normaliseBinByBin( const MatrixWorkspace_sptr &inputWorkspace, MatrixWorkspace_sptr &outputWorkspace) { EventWorkspace_sptr inputEvent = boost::dynamic_pointer_cast<EventWorkspace>(inputWorkspace); // Only create output workspace if different to input one if (outputWorkspace != inputWorkspace) { if (inputEvent) { outputWorkspace = inputWorkspace->clone(); } else outputWorkspace = create<MatrixWorkspace>(*inputWorkspace); } auto outputEvent = boost::dynamic_pointer_cast<EventWorkspace>(outputWorkspace); const auto &inputSpecInfo = inputWorkspace->spectrumInfo(); const auto &monitorSpecInfo = m_monitor->spectrumInfo(); const auto specLength = inputWorkspace->blocksize(); for (auto &workspaceIndex : m_workspaceIndexes) { // Get hold of the monitor spectrum const auto &monX = m_monitor->binEdges(workspaceIndex); auto monY = m_monitor->counts(workspaceIndex); auto monE = m_monitor->countStandardDeviations(workspaceIndex); size_t timeIndex = 0; if (m_scanInput) timeIndex = monitorSpecInfo.spectrumDefinition(workspaceIndex)[0].second; // Calculate the overall normalization just the once if bins are all // matching if (m_commonBins) this->normalisationFactor(monX, monY, monE); const size_t numHists = inputWorkspace->getNumberHistograms(); // Flag set when a division by 0 is found bool hasZeroDivision = false; Progress prog(this, 0.0, 1.0, numHists); // Loop over spectra PARALLEL_FOR_IF( Kernel::threadSafe(*inputWorkspace, *outputWorkspace, *m_monitor)) for (int64_t i = 0; i < int64_t(numHists); ++i) { PARALLEL_START_INTERUPT_REGION prog.report(); const auto &specDef = inputSpecInfo.spectrumDefinition(i); if (!spectrumDefinitionsMatchTimeIndex(specDef, timeIndex)) continue; const auto &X = inputWorkspace->binEdges(i); // If not rebinning, just point to our monitor spectra, otherwise create // new vectors auto Y = (m_commonBins ? monY : Counts(specLength)); auto E = (m_commonBins ? monE : CountStandardDeviations(specLength)); if (!m_commonBins) { // ConvertUnits can give X vectors of all zeros - skip these, they // cause // problems if (X.back() == 0.0 && X.front() == 0.0) continue; // Rebin the monitor spectrum to match the binning of the current data // spectrum VectorHelper::rebinHistogram( monX.rawData(), monY.mutableRawData(), monE.mutableRawData(), X.rawData(), Y.mutableRawData(), E.mutableRawData(), false); // Recalculate the overall normalization factor this->normalisationFactor(X, Y, E); } if (inputEvent) { // --- EventWorkspace --- EventList &outEL = outputEvent->getSpectrum(i); outEL.divide(X.rawData(), Y.mutableRawData(), E.mutableRawData()); } else { // --- Workspace2D --- auto &YOut = outputWorkspace->mutableY(i); auto &EOut = outputWorkspace->mutableE(i); const auto &inY = inputWorkspace->y(i); const auto &inE = inputWorkspace->e(i); outputWorkspace->setSharedX(i, inputWorkspace->sharedX(i)); // The code below comes more or less straight out of Divide.cpp for (size_t k = 0; k < specLength; ++k) { // Get the input Y's const double leftY = inY[k]; const double rightY = Y[k]; if (rightY == 0.0) { hasZeroDivision = true; } // Calculate result and store in local variable to avoid overwriting // original data if output workspace is same as one of the input // ones const double newY = leftY / rightY; if (fabs(rightY) > 1.0e-12 && fabs(newY) > 1.0e-12) { const double lhsFactor = (inE[k] < 1.0e-12 || fabs(leftY) < 1.0e-12) ? 0.0 : pow((inE[k] / leftY), 2); const double rhsFactor = E[k] < 1.0e-12 ? 0.0 : pow((E[k] / rightY), 2); EOut[k] = std::abs(newY) * sqrt(lhsFactor + rhsFactor); } // Now store the result YOut[k] = newY; } // end Workspace2D case } // end loop over current spectrum PARALLEL_END_INTERUPT_REGION } // end loop over spectra PARALLEL_CHECK_INTERUPT_REGION if (hasZeroDivision) { g_log.warning() << "Division by zero in some of the bins.\n"; } if (inputEvent) outputEvent->clearMRU(); } }
void GroupDetectors::exec() { // Get the input workspace const MatrixWorkspace_sptr WS = getProperty("Workspace"); std::vector<size_t> indexList = getProperty("WorkspaceIndexList"); std::vector<specid_t> spectraList = getProperty("SpectraList"); const std::vector<detid_t> detectorList = getProperty("DetectorList"); // Could create a Validator to replace the below if ( indexList.empty() && spectraList.empty() && detectorList.empty() ) { g_log.information(name() + ": WorkspaceIndexList, SpectraList, and DetectorList properties are all empty, no grouping done"); return; } // Bin boundaries need to be the same, so check if they actually are if (!API::WorkspaceHelpers::commonBoundaries(WS)) { g_log.error("Can only group if the histograms have common bin boundaries"); throw std::runtime_error("Can only group if the histograms have common bin boundaries"); } // If the spectraList property has been set, need to loop over the workspace looking for the // appropriate spectra number and adding the indices they are linked to the list to be processed if ( ! spectraList.empty() ) { WS->getIndicesFromSpectra(spectraList,indexList); }// End dealing with spectraList else if ( ! detectorList.empty() ) { // Dealing with DetectorList //convert from detectors to workspace indices WS->getIndicesFromDetectorIDs(detectorList, indexList); } if ( indexList.empty() ) { g_log.warning("Nothing to group"); return; } const size_t vectorSize = WS->blocksize(); const specid_t firstIndex = static_cast<specid_t>(indexList[0]); ISpectrum * firstSpectrum = WS->getSpectrum(firstIndex); setProperty("ResultIndex",firstIndex); // loop over the spectra to group Progress progress(this, 0.0, 1.0, static_cast<int>(indexList.size()-1)); for (size_t i = 0; i < indexList.size()-1; ++i) { // The current spectrum const size_t currentIndex = indexList[i+1]; ISpectrum * spec = WS->getSpectrum(currentIndex); // Add the current detector to belong to the first spectrum firstSpectrum->addDetectorIDs(spec->getDetectorIDs()); // Add up all the Y spectra and store the result in the first one // Need to keep the next 3 lines inside loop for now until ManagedWorkspace mru-list works properly MantidVec &firstY = WS->dataY(firstIndex); MantidVec::iterator fYit; MantidVec::iterator fEit = firstSpectrum->dataE().begin(); MantidVec::iterator Yit = spec->dataY().begin(); MantidVec::iterator Eit = spec->dataE().begin(); for (fYit = firstY.begin(); fYit != firstY.end(); ++fYit, ++fEit, ++Yit, ++Eit) { *fYit += *Yit; // Assume 'normal' (i.e. Gaussian) combination of errors *fEit = sqrt( (*fEit)*(*fEit) + (*Eit)*(*Eit) ); } // Now zero the now redundant spectrum and set its spectraNo to indicate this (using -1) // N.B. Deleting spectra would cause issues for ManagedWorkspace2D, hence the the approach taken here spec->dataY().assign(vectorSize,0.0); spec->dataE().assign(vectorSize,0.0); spec->setSpectrumNo(-1); spec->clearDetectorIDs(); progress.report(); } }
/** * Returns the size of the new X vector * @param inputWS pointer to input workspace * @returns An integer giving the size of the new X vector */ size_t ConvertToPointData::getNewXSize(const MatrixWorkspace_sptr inputWS) const { return static_cast<int>(inputWS->blocksize()); }
/** * Execute the algorithm. */ void SofQW3::exec() { MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); // Do the full check for common binning if( !WorkspaceHelpers::commonBoundaries(inputWS) ) { throw std::invalid_argument("The input workspace must have common binning across all spectra"); } RebinnedOutput_sptr outputWS = this->setUpOutputWorkspace(inputWS, getProperty("QAxisBinning"), m_Qout); g_log.debug() << "Workspace type: " << outputWS->id() << std::endl; setProperty("OutputWorkspace", outputWS); const size_t nEnergyBins = inputWS->blocksize(); const size_t nHistos = inputWS->getNumberHistograms(); // Progress reports & cancellation const size_t nreports(nHistos * nEnergyBins); m_progress = boost::shared_ptr<API::Progress>(new API::Progress(this, 0.0, 1.0, nreports)); // Compute input caches this->initCachedValues(inputWS); std::vector<double> par = inputWS->getInstrument()->getNumberParameter("detector-neighbour-offset"); if (par.empty()) { // Index theta cache this->initThetaCache(inputWS); } else { g_log.debug() << "Offset: " << par[0] << std::endl; this->m_detNeighbourOffset = static_cast<int>(par[0]); this->getValuesAndWidths(inputWS); } const MantidVec & X = inputWS->readX(0); PARALLEL_FOR2(inputWS, outputWS) for (int64_t i = 0; i < static_cast<int64_t>(nHistos); ++i) // signed for openmp { PARALLEL_START_INTERUPT_REGION DetConstPtr detector = inputWS->getDetector(i); if (detector->isMasked() || detector->isMonitor()) { continue; } double theta = this->m_theta[i]; double phi = 0.0; double thetaWidth = 0.0; double phiWidth = 0.0; // Non-PSD mode if (par.empty()) { thetaWidth = this->m_thetaWidth; } // PSD mode else { phi = this->m_phi[i]; thetaWidth = this->m_thetaWidths[i]; phiWidth = this->m_phiWidths[i]; } double thetaHalfWidth = 0.5 * thetaWidth; double phiHalfWidth = 0.5 * phiWidth; const double thetaLower = theta - thetaHalfWidth; const double thetaUpper = theta + thetaHalfWidth; const double phiLower = phi - phiHalfWidth; const double phiUpper = phi + phiHalfWidth; const double efixed = this->getEFixed(detector); for(size_t j = 0; j < nEnergyBins; ++j) { m_progress->report("Computing polygon intersections"); // For each input polygon test where it intersects with // the output grid and assign the appropriate weights of Y/E const double dE_j = X[j]; const double dE_jp1 = X[j+1]; const V2D ll(dE_j, this->calculateQ(efixed, dE_j, thetaLower, phiLower)); const V2D lr(dE_jp1, this->calculateQ(efixed, dE_jp1, thetaLower, phiLower)); const V2D ur(dE_jp1, this->calculateQ(efixed, dE_jp1, thetaUpper, phiUpper)); const V2D ul(dE_j, this->calculateQ(efixed, dE_j, thetaUpper, phiUpper)); Quadrilateral inputQ = Quadrilateral(ll, lr, ur, ul); this->rebinToFractionalOutput(inputQ, inputWS, i, j, outputWS, m_Qout); } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputWS->finalize(); this->normaliseOutput(outputWS, inputWS); }
/** Execute the algorithm. */ void MaxEnt::exec() { // MaxEnt parameters // Complex data? bool complex = getProperty("ComplexData"); // Image must be positive? bool positiveImage = getProperty("PositiveImage"); // Autoshift bool autoShift = getProperty("AutoShift"); // Increase the number of points in the image by this factor size_t densityFactor = getProperty("DensityFactor"); // Background (default level, sky background, etc) double background = getProperty("A"); // Chi target double chiTarget = getProperty("ChiTarget"); // Required precision for Chi arget double chiEps = getProperty("ChiEps"); // Maximum degree of non-parallelism between S and C double angle = getProperty("MaxAngle"); // Distance penalty for current image double distEps = getProperty("DistancePenalty"); // Maximum number of iterations size_t niter = getProperty("MaxIterations"); // Maximum number of iterations in alpha chop size_t alphaIter = getProperty("AlphaChopIterations"); // Number of spectra and datapoints // Read input workspace MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); // Number of spectra size_t nspec = inWS->getNumberHistograms(); // Number of data points size_t npoints = inWS->blocksize() * densityFactor; // Number of X bins size_t npointsX = inWS->isHistogramData() ? npoints + 1 : npoints; // The type of entropy we are going to use (depends on the type of image, // positive only, or positive and/or negative) MaxentData_sptr maxentData; if (positiveImage) { maxentData = boost::make_shared<MaxentData>( boost::make_shared<MaxentEntropyPositiveValues>()); } else { maxentData = boost::make_shared<MaxentData>( boost::make_shared<MaxentEntropyNegativeValues>()); } // Output workspaces MatrixWorkspace_sptr outImageWS; MatrixWorkspace_sptr outDataWS; MatrixWorkspace_sptr outEvolChi; MatrixWorkspace_sptr outEvolTest; nspec = complex ? nspec / 2 : nspec; outImageWS = WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints); outDataWS = WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints); outEvolChi = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter); outEvolTest = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter); npoints *= 2; for (size_t s = 0; s < nspec; s++) { // Start distribution (flat background) std::vector<double> image(npoints, background); if (complex) { auto dataRe = inWS->readY(s); auto dataIm = inWS->readY(s + nspec); auto errorsRe = inWS->readE(s); auto errorsIm = inWS->readE(s + nspec); maxentData->loadComplex(dataRe, dataIm, errorsRe, errorsIm, image, background); } else { auto data = inWS->readY(s); auto error = inWS->readE(s); maxentData->loadReal(data, error, image, background); } // To record the algorithm's progress std::vector<double> evolChi(niter, 0.); std::vector<double> evolTest(niter, 0.); // Progress Progress progress(this, 0, 1, niter); // Run maxent algorithm for (size_t it = 0; it < niter; it++) { // Calculate quadratic model coefficients // (SB eq. 21 and 24) maxentData->calculateQuadraticCoefficients(); double currAngle = maxentData->getAngle(); double currChisq = maxentData->getChisq(); auto coeffs = maxentData->getQuadraticCoefficients(); // Calculate delta to construct new image (SB eq. 25) auto delta = move(coeffs, chiTarget / currChisq, chiEps, alphaIter); // Apply distance penalty (SB eq. 33) image = maxentData->getImage(); delta = applyDistancePenalty(delta, coeffs, image, background, distEps); // Update image according to 'delta' and calculate the new Chi-square maxentData->updateImage(delta); currChisq = maxentData->getChisq(); // Record the evolution of Chi-square and angle(S,C) evolChi[it] = currChisq; evolTest[it] = currAngle; // Stop condition, solution found if ((std::abs(currChisq / chiTarget - 1.) < chiEps) && (currAngle < angle)) { break; } // Check for canceling the algorithm if (!(it % 1000)) { interruption_point(); } progress.report(); } // iterations // Get calculated data auto solData = maxentData->getReconstructedData(); auto solImage = maxentData->getImage(); // Populate the output workspaces populateDataWS(inWS, s, nspec, solData, outDataWS); populateImageWS(inWS, s, nspec, solImage, outImageWS, autoShift); // Populate workspaces recording the evolution of Chi and Test // X values for (size_t it = 0; it < niter; it++) { outEvolChi->dataX(s)[it] = static_cast<double>(it); outEvolTest->dataX(s)[it] = static_cast<double>(it); } // Y values outEvolChi->dataY(s).assign(evolChi.begin(), evolChi.end()); outEvolTest->dataY(s).assign(evolTest.begin(), evolTest.end()); // No errors } // Next spectrum setProperty("EvolChi", outEvolChi); setProperty("EvolAngle", outEvolTest); setProperty("ReconstructedImage", outImageWS); setProperty("ReconstructedData", outDataWS); }
/** Populates the output workspaces * @param inWS :: [input] The input workspace * @param spec :: [input] The current spectrum being analyzed * @param nspec :: [input] The total number of histograms in the input workspace * @param result :: [input] The result to be written in the output workspace * @param outWS :: [input] The output workspace to populate * @param autoShift :: [input] Whether or not to correct the phase shift */ void MaxEnt::populateImageWS(const MatrixWorkspace_sptr &inWS, size_t spec, size_t nspec, const std::vector<double> &result, MatrixWorkspace_sptr &outWS, bool autoShift) { if (result.size() % 2) throw std::invalid_argument("Cannot write results to output workspaces"); int npoints = static_cast<int>(result.size() / 2); int npointsX = inWS->isHistogramData() ? npoints + 1 : npoints; MantidVec X(npointsX); MantidVec YR(npoints); MantidVec YI(npoints); MantidVec E(npoints, 0.); double x0 = inWS->readX(spec)[0]; double dx = inWS->readX(spec)[1] - x0; double delta = 1. / dx / npoints; int isOdd = (inWS->blocksize() % 2) ? 1 : 0; double shift = x0 * 2 * M_PI; if (!autoShift) shift = 0; for (int i = 0; i < npoints; i++) { int j = (npoints / 2 + i + isOdd) % npoints; X[i] = delta * (-npoints / 2 + i); double xShift = X[i] * shift; double c = cos(xShift); double s = sin(xShift); YR[i] = result[2 * j] * c - result[2 * j + 1] * s; YI[i] = result[2 * j] * s + result[2 * j + 1] * c; YR[i] *= dx; YI[i] *= dx; } if (npointsX == npoints + 1) X[npoints] = X[npoints - 1] + delta; // Caption & label auto inputUnit = inWS->getAxis(0)->unit(); if (inputUnit) { boost::shared_ptr<Kernel::Units::Label> lblUnit = boost::dynamic_pointer_cast<Kernel::Units::Label>( UnitFactory::Instance().create("Label")); if (lblUnit) { lblUnit->setLabel( inverseCaption[inWS->getAxis(0)->unit()->caption()], inverseLabel[inWS->getAxis(0)->unit()->label().ascii()]); outWS->getAxis(0)->unit() = lblUnit; } } outWS->dataX(spec).assign(X.begin(), X.end()); outWS->dataY(spec).assign(YR.begin(), YR.end()); outWS->dataE(spec).assign(E.begin(), E.end()); outWS->dataX(nspec + spec).assign(X.begin(), X.end()); outWS->dataY(nspec + spec).assign(YI.begin(), YI.end()); outWS->dataE(nspec + spec).assign(E.begin(), E.end()); }
/** * Plots raw time data from .raw file before any data conversion has been * performed. */ void ISISEnergyTransfer::plotRaw() { using Mantid::specnum_t; using MantidQt::API::BatchAlgorithmRunner; if (!m_uiForm.dsRunFiles->isValid()) { emit showMessageBox("You must select a run file."); return; } int detectorMin = m_uiForm.spPlotTimeSpecMin->value(); int detectorMax = m_uiForm.spPlotTimeSpecMax->value(); if (detectorMin > detectorMax) { emit showMessageBox( "Minimum spectra must be less than or equal to maximum spectra."); return; } const int startBack = m_uiForm.spBackgroundStart->value(); const int endBack = m_uiForm.spBackgroundEnd->value(); if (m_uiForm.ckBackgroundRemoval->isChecked() == true) { if (startBack > endBack) { emit showMessageBox("Background Start must be less than Background End"); return; } } QString rawFile = m_uiForm.dsRunFiles->getFirstFilename(); auto pos = rawFile.lastIndexOf("."); auto extension = rawFile.right(rawFile.length() - pos); QFileInfo rawFileInfo(rawFile); std::string name = rawFileInfo.baseName().toStdString(); IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("Load"); loadAlg->initialize(); loadAlg->setProperty("Filename", rawFile.toStdString()); loadAlg->setProperty("OutputWorkspace", name); loadAlg->setProperty("LoadLogFiles", false); if (extension.compare(".nxs") == 0) { int64_t detectorMin = static_cast<int64_t>(m_uiForm.spPlotTimeSpecMin->value()); int64_t detectorMax = static_cast<int64_t>(m_uiForm.spPlotTimeSpecMax->value()); loadAlg->setProperty("SpectrumMin", detectorMin); loadAlg->setProperty("SpectrumMax", detectorMax); } else { loadAlg->setProperty("SpectrumMin", detectorMin); loadAlg->setProperty("SpectrumMax", detectorMax); } loadAlg->execute(); if (m_uiForm.ckBackgroundRemoval->isChecked()) { MatrixWorkspace_sptr tempWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(name); const double minBack = tempWs->readX(0)[0]; const double maxBack = tempWs->readX(0)[tempWs->blocksize()]; if (startBack < minBack) { emit showMessageBox("The Start of Background Removal is less than the " "minimum of the data range"); return; } if (endBack > maxBack) { emit showMessageBox("The End of Background Removal is more than the " "maximum of the data range"); return; } } // Rebin the workspace to its self to ensure constant binning BatchAlgorithmRunner::AlgorithmRuntimeProps inputToRebin; inputToRebin["WorkspaceToMatch"] = name; inputToRebin["WorkspaceToRebin"] = name; inputToRebin["OutputWorkspace"] = name; IAlgorithm_sptr rebinAlg = AlgorithmManager::Instance().create("RebinToWorkspace"); rebinAlg->initialize(); m_batchAlgoRunner->addAlgorithm(rebinAlg, inputToRebin); BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromRebin; inputFromRebin["InputWorkspace"] = name; std::vector<specnum_t> detectorList; for (specnum_t i = detectorMin; i <= detectorMax; i++) detectorList.push_back(i); if (m_uiForm.ckBackgroundRemoval->isChecked()) { std::vector<double> range; range.push_back(m_uiForm.spBackgroundStart->value()); range.push_back(m_uiForm.spBackgroundEnd->value()); IAlgorithm_sptr calcBackAlg = AlgorithmManager::Instance().create("CalculateFlatBackground"); calcBackAlg->initialize(); calcBackAlg->setProperty("OutputWorkspace", name + "_bg"); calcBackAlg->setProperty("Mode", "Mean"); calcBackAlg->setProperty("StartX", range[0]); calcBackAlg->setProperty("EndX", range[1]); m_batchAlgoRunner->addAlgorithm(calcBackAlg, inputFromRebin); BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromCalcBG; inputFromCalcBG["InputWorkspace"] = name + "_bg"; IAlgorithm_sptr groupAlg = AlgorithmManager::Instance().create("GroupDetectors"); groupAlg->initialize(); groupAlg->setProperty("OutputWorkspace", name + "_grp"); groupAlg->setProperty("DetectorList", detectorList); m_batchAlgoRunner->addAlgorithm(groupAlg, inputFromCalcBG); IAlgorithm_sptr rawGroupAlg = AlgorithmManager::Instance().create("GroupDetectors"); rawGroupAlg->initialize(); rawGroupAlg->setProperty("OutputWorkspace", name + "_grp_raw"); rawGroupAlg->setProperty("DetectorList", detectorList); m_batchAlgoRunner->addAlgorithm(rawGroupAlg, inputFromRebin); } else { IAlgorithm_sptr rawGroupAlg = AlgorithmManager::Instance().create("GroupDetectors"); rawGroupAlg->initialize(); rawGroupAlg->setProperty("OutputWorkspace", name + "_grp"); rawGroupAlg->setProperty("DetectorList", detectorList); m_batchAlgoRunner->addAlgorithm(rawGroupAlg, inputFromRebin); } disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(plotRawComplete(bool))); m_batchAlgoRunner->executeBatchAsync(); }
void ImageROIViewQtWidget::showProjectionImage( const Mantid::API::WorkspaceGroup_sptr &wsg, size_t idx) { MatrixWorkspace_sptr ws; try { ws = boost::dynamic_pointer_cast<MatrixWorkspace>(wsg->getItem(idx)); if (!ws) return; } catch (std::exception &e) { QMessageBox::warning( this, "Cannot load image", "There was a problem while trying to find the image data: " + QString::fromStdString(e.what())); } const size_t MAXDIM = 2048 * 16; size_t width; try { width = boost::lexical_cast<size_t>(ws->run().getLogData("Axis1")->value()); // TODO: add a settings option for this (like max mem allocation for // images)? if (width >= MAXDIM) width = MAXDIM; } catch (std::exception &e) { QMessageBox::critical(this, "Cannot load image", "There was a problem while trying to " "find the width of the image: " + QString::fromStdString(e.what())); return; } size_t height; try { height = boost::lexical_cast<size_t>(ws->run().getLogData("Axis2")->value()); if (height >= MAXDIM) height = MAXDIM; } catch (std::exception &e) { QMessageBox::critical(this, "Cannot load image", "There was a problem while trying to " "find the height of the image: " + QString::fromStdString(e.what())); return; } // images are loaded as 1 histogram == 1 pixel (1 bin per histogram): if (height != ws->getNumberHistograms() || width != ws->blocksize()) { QMessageBox::critical( this, "Image dimensions do not match in the input image workspace", "Could not load the expected " "number of rows and columns."); return; } // find min and max to scale pixel values double min = std::numeric_limits<double>::max(), max = std::numeric_limits<double>::min(); for (size_t i = 0; i < ws->getNumberHistograms(); ++i) { for (size_t j = 0; j < ws->blocksize(); ++j) { const double &v = ws->readY(i)[j]; if (v < min) min = v; if (v > max) max = v; } } if (min >= max) { QMessageBox::warning( this, "Empty image!", "The image could be loaded but it contains " "effectively no information, all pixels have the same value."); // black picture QPixmap pix(static_cast<int>(width), static_cast<int>(height)); pix.fill(QColor(0, 0, 0)); m_ui.label_img->setPixmap(pix); m_ui.label_img->show(); m_basePixmap.reset(new QPixmap(pix)); return; } // load / transfer image into a QImage QImage rawImg(QSize(static_cast<int>(width), static_cast<int>(height)), QImage::Format_RGB32); const double max_min = max - min; const double scaleFactor = 255.0 / max_min; for (size_t yi = 0; yi < width; ++yi) { for (size_t xi = 0; xi < width; ++xi) { const double &v = ws->readY(yi)[xi]; // color the range min-max in gray scale. To apply different color // maps you'd need to use rawImg.setColorTable() or similar. const int scaled = static_cast<int>(scaleFactor * (v - min)); QRgb vRgb = qRgb(scaled, scaled, scaled); rawImg.setPixel(static_cast<int>(xi), static_cast<int>(yi), vRgb); } } // paint and show image // direct from image QPixmap pix = QPixmap::fromImage(rawImg); m_ui.label_img->setPixmap(pix); m_ui.label_img->show(); m_basePixmap.reset(new QPixmap(pix)); // Alternative, drawing with a painter: // QPixmap pix(static_cast<int>(width), static_cast<int>(height)); // QPainter painter; // painter.begin(&pix); // painter.drawImage(0, 0, rawImg); // painter.end(); // m_ui.label_img->setPixmap(pix); // m_ui.label_img->show(); // m_basePixmap.reset(new QPixmap(pix)); }