/** * Handles completion of the algorithm. * * @param error If the algorithm failed */ void ISISDiagnostics::algorithmComplete(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); if (error) return; WorkspaceGroup_sptr sliceOutputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( "IndirectDiagnostics_Workspaces"); if (sliceOutputGroup->size() == 0) { g_log.warning("No result workspaces, cannot plot preview."); return; } for (size_t i = 0; i < sliceOutputGroup->size(); i++) { QString wsName = QString::fromStdString(sliceOutputGroup->getItem(i)->name()); } // Enable plot and save buttons m_uiForm.pbSave->setEnabled(true); m_uiForm.pbPlot->setEnabled(true); // Update the preview plots sliceAlgDone(false); m_batchAlgoRunner->executeBatchAsync(); }
/** Execute the algorithm. */ void PolarizationCorrectionFredrikze::exec() { WorkspaceGroup_sptr inWS = getProperty("InputWorkspace"); const std::string analysisMode = getProperty("PolarizationAnalysis"); const size_t nWorkspaces = inWS->size(); validateInputWorkspace(inWS); WorkspaceGroup_sptr outWS; if (analysisMode == pALabel) { if (nWorkspaces != 4) { throw std::invalid_argument( "For PA analysis, input group must have 4 periods."); } g_log.notice("PA polarization correction"); outWS = execPA(inWS); } else if (analysisMode == pNRLabel) { if (nWorkspaces != 2) { throw std::invalid_argument( "For PNR analysis, input group must have 2 periods."); } outWS = execPNR(inWS); g_log.notice("PNR polarization correction"); } this->setProperty("OutputWorkspace", outWS); }
/** * Sum over transmission group workspaces to produce one * workspace. * @param transGroup : The transmission group to be processed * @return A workspace pointer containing the sum of transmission workspaces. */ Mantid::API::Workspace_sptr ReflectometryReductionOneAuto::sumOverTransmissionGroup( WorkspaceGroup_sptr &transGroup) { // Handle transmission runs // we clone the first member of transmission group as to // avoid addition in place which would affect the original // workspace member. // // We used .release because clone() will return a unique_ptr. // we need to release the ownership of the pointer so that it // can be cast into a shared_ptr of type Workspace. Workspace_sptr transmissionRunSum(transGroup->getItem(0)->clone().release()); // make a variable to store the overall total of the summation MatrixWorkspace_sptr total; // set up and initialize plus algorithm. auto plusAlg = this->createChildAlgorithm("Plus"); plusAlg->setChild(true); // plusAlg->setRethrows(true); plusAlg->initialize(); // now accumalate the group members for (size_t item = 1; item < transGroup->size(); ++item) { plusAlg->setProperty("LHSWorkspace", transmissionRunSum); plusAlg->setProperty("RHSWorkspace", transGroup->getItem(item)); plusAlg->setProperty("OutputWorkspace", transmissionRunSum); plusAlg->execute(); total = plusAlg->getProperty("OutputWorkspace"); } return total; }
/** * Handles completion of the algorithm. * * Sets result workspace for Python export and ungroups result WorkspaceGroup. * * @param error True if the algorithm was stopped due to error, false otherwise */ void ISISEnergyTransfer::algorithmComplete(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); if (error) return; WorkspaceGroup_sptr energyTransferOutputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( "IndirectEnergyTransfer_Workspaces"); if (energyTransferOutputGroup->size() == 0) return; // Set workspace for Python export as the first result workspace m_pythonExportWsName = energyTransferOutputGroup->getNames()[0]; m_outputWorkspaces = energyTransferOutputGroup->getNames(); // Ungroup the output workspace energyTransferOutputGroup->removeAll(); AnalysisDataService::Instance().remove("IndirectEnergyTransfer_Workspaces"); // Enable plotting and saving m_uiForm.pbPlot->setEnabled(true); m_uiForm.cbPlotType->setEnabled(true); m_uiForm.pbSave->setEnabled(true); m_uiForm.ckSaveAclimax->setEnabled(true); m_uiForm.ckSaveASCII->setEnabled(true); m_uiForm.ckSaveDaveGrp->setEnabled(true); m_uiForm.ckSaveNexus->setEnabled(true); m_uiForm.ckSaveNXSPE->setEnabled(true); m_uiForm.ckSaveSPE->setEnabled(true); }
/** * Replots the energy mini plot */ void ISISCalibration::calPlotEnergy() { if ( ! m_uiForm.leRunNo->isValid() ) { emit showMessageBox("Run number not valid."); return; } QString files = m_uiForm.leRunNo->getFilenames().join(","); QFileInfo fi(m_uiForm.leRunNo->getFirstFilename()); QString detRange = QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + "," + QString::number(m_dblManager->value(m_properties["ResSpecMax"])); IAlgorithm_sptr reductionAlg = AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer"); reductionAlg->initialize(); reductionAlg->setProperty("Instrument", getInstrumentConfiguration()->getInstrumentName().toStdString()); reductionAlg->setProperty("Analyser", getInstrumentConfiguration()->getAnalyserName().toStdString()); reductionAlg->setProperty("Reflection", getInstrumentConfiguration()->getReflectionName().toStdString()); reductionAlg->setProperty("InputFiles", files.toStdString()); reductionAlg->setProperty("OutputWorkspace", "__IndirectCalibration_reduction"); reductionAlg->setProperty("SpectraRange", detRange.toStdString()); reductionAlg->execute(); if(!reductionAlg->isExecuted()) { g_log.warning("Could not generate energy preview plot."); return; } WorkspaceGroup_sptr reductionOutputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>("__IndirectCalibration_reduction"); if(reductionOutputGroup->size() == 0) { g_log.warning("No result workspaces, cannot plot energy preview."); return; } MatrixWorkspace_sptr energyWs = boost::dynamic_pointer_cast<MatrixWorkspace>(reductionOutputGroup->getItem(0)); if(!energyWs) { g_log.warning("No result workspaces, cannot plot energy preview."); return; } const Mantid::MantidVec & dataX = energyWs->readX(0); QPair<double, double> range(dataX.front(), dataX.back()); auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground"); setPlotPropertyRange(resBackground, m_properties["ResStart"], m_properties["ResEnd"], range); m_uiForm.ppResolution->clear(); m_uiForm.ppResolution->addSpectrum("Energy", energyWs, 0); m_uiForm.ppResolution->resizeX(); calSetDefaultResolution(energyWs); m_uiForm.ppResolution->replot(); }
/** Execute the algorithm. */ void PolarizationCorrection::exec() { WorkspaceGroup_sptr inWS = getProperty("InputWorkspace"); const std::string analysisMode = getProperty("PolarizationAnalysis"); const size_t nWorkspaces = inWS->size(); validateInputWorkspace(inWS); Instrument_const_sptr instrument = fetchInstrument(inWS.get()); // Check if we need to fetch polarization parameters from the instrument's // parameters std::map<std::string, std::string> loadableProperties; loadableProperties[crhoLabel()] = "crho"; loadableProperties[cppLabel()] = "cPp"; // In PA mode, we also require cap and calpha if (analysisMode == pALabel()) { loadableProperties[cApLabel()] = "cAp"; loadableProperties[cAlphaLabel()] = "calpha"; } for (auto propName = loadableProperties.begin(); propName != loadableProperties.end(); ++propName) { Property *prop = getProperty(propName->first); if (!prop) continue; if (prop->isDefault()) { auto vals = instrument->getStringParameter(propName->second); if (vals.empty()) throw std::runtime_error( "Cannot find value for " + propName->first + " in parameter file. Please specify this property manually."); prop->setValue(vals[0]); } } WorkspaceGroup_sptr outWS; if (analysisMode == pALabel()) { if (nWorkspaces != 4) { throw std::invalid_argument( "For PA analysis, input group must have 4 periods."); } g_log.notice("PA polarization correction"); outWS = execPA(inWS); } else if (analysisMode == pNRLabel()) { if (nWorkspaces != 2) { throw std::invalid_argument( "For PNR analysis, input group must have 2 periods."); } outWS = execPNR(inWS); g_log.notice("PNR polarization correction"); } this->setProperty("OutputWorkspace", outWS); }
void IqtFit::updatePlot() { if (!m_ffInputWS) { g_log.error("No workspace loaded, cannot create preview plot."); return; } int specNo = m_uiForm.spPlotSpectrum->value(); m_uiForm.ppPlot->clear(); m_uiForm.ppPlot->addSpectrum("Sample", m_ffInputWS, specNo); try { const QPair<double, double> curveRange = m_uiForm.ppPlot->getCurveRange("Sample"); const std::pair<double, double> range(curveRange.first, curveRange.second); m_uiForm.ppPlot->getRangeSelector("FuryFitRange") ->setRange(range.first, range.second); m_ffRangeManager->setRange(m_properties["StartX"], range.first, range.second); m_ffRangeManager->setRange(m_properties["EndX"], range.first, range.second); setDefaultParameters("Exponential1"); setDefaultParameters("Exponential2"); setDefaultParameters("StretchedExp"); m_uiForm.ppPlot->resizeX(); m_uiForm.ppPlot->setAxisRange(qMakePair(0.0, 1.0), QwtPlot::yLeft); } catch (std::invalid_argument &exc) { showMessageBox(exc.what()); } // If there is a result plot then plot it if (AnalysisDataService::Instance().doesExist(m_pythonExportWsName)) { WorkspaceGroup_sptr outputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( m_pythonExportWsName); if (specNo >= static_cast<int>(outputGroup->size())) return; MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>( outputGroup->getItem(specNo)); if (ws) { if (m_uiForm.ckPlotGuess->isChecked()) { m_uiForm.ppPlot->removeSpectrum("Guess"); } m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); m_uiForm.ppPlot->addSpectrum("Diff", ws, 2, Qt::blue); } } }
/** * Validate the multiperiods workspace groups. Gives the opportunity to exit * processing if things don't look right. * @param vecMultiPeriodGroups : vector of multiperiod groups. */ void MultiPeriodGroupWorker::validateMultiPeriodGroupInputs( const VecWSGroupType &vecMultiPeriodGroups) const { const size_t multiPeriodGroupsSize = vecMultiPeriodGroups.size(); if (multiPeriodGroupsSize > 0) { const size_t benchMarkGroupSize = vecMultiPeriodGroups[0]->size(); for (size_t i = 0; i < multiPeriodGroupsSize; ++i) { WorkspaceGroup_sptr currentGroup = vecMultiPeriodGroups[i]; if (currentGroup->size() != benchMarkGroupSize) { throw std::runtime_error("Not all the input Multi-period-group input " "workspaces are the same size."); } for (size_t j = 0; j < currentGroup->size(); ++j) { MatrixWorkspace_const_sptr currentNestedWS = boost::dynamic_pointer_cast<const MatrixWorkspace>( currentGroup->getItem(j)); Property *nPeriodsProperty = currentNestedWS->run().getLogData("nperiods"); size_t nPeriods = std::stoul(nPeriodsProperty->value()); if (nPeriods != benchMarkGroupSize) { throw std::runtime_error("Missmatch between nperiods log and the " "number of workspaces in the input group: " + vecMultiPeriodGroups[i]->getName()); } Property *currentPeriodProperty = currentNestedWS->run().getLogData("current_period"); size_t currentPeriod = std::stoul(currentPeriodProperty->value()); if (currentPeriod != (j + 1)) { throw std::runtime_error("Multiperiod group workspaces must be " "ordered by current_period. Correct: " + currentNestedWS->getName()); } } } } }
/** * Handles completion of the correction algorithm. * * @param error True of the algorithm failed */ void CalculatePaalmanPings::absCorComplete(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(absCorComplete(bool))); if (error) { emit showMessageBox("Absorption correction calculation failed.\nSee " "Results Log for more details."); return; } // Convert the spectrum axis of correction factors to Q const auto sampleWsName = m_uiForm.dsSample->getCurrentDataName().toStdString(); MatrixWorkspace_sptr sampleWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(sampleWsName); WorkspaceGroup_sptr corrections = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( m_pythonExportWsName); for (size_t i = 0; i < corrections->size(); i++) { MatrixWorkspace_sptr factorWs = boost::dynamic_pointer_cast<MatrixWorkspace>(corrections->getItem(i)); if (!factorWs || !sampleWs) continue; if (getEMode(sampleWs) == "Indirect") { API::BatchAlgorithmRunner::AlgorithmRuntimeProps convertSpecProps; IAlgorithm_sptr convertSpecAlgo = AlgorithmManager::Instance().create("ConvertSpectrumAxis"); convertSpecAlgo->initialize(); convertSpecAlgo->setProperty("InputWorkspace", factorWs); convertSpecAlgo->setProperty("OutputWorkspace", factorWs->getName()); convertSpecAlgo->setProperty("Target", "ElasticQ"); convertSpecAlgo->setProperty("EMode", "Indirect"); try { convertSpecAlgo->setProperty("EFixed", getEFixed(factorWs)); } catch (std::runtime_error &) { } m_batchAlgoRunner->addAlgorithm(convertSpecAlgo); } } // Run algorithm queue connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(postProcessComplete(bool))); m_batchAlgoRunner->executeBatchAsync(); }
/** * Handles completion of the algorithm. * * Sets result workspace for Python export and ungroups result WorkspaceGroup. * * @param error True if the algorithm was stopped due to error, false otherwise */ void IndirectConvertToEnergy::algorithmComplete(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); if(error) return; WorkspaceGroup_sptr energyTransferOutputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>("IndirectEnergyTransfer_Workspaces"); if(energyTransferOutputGroup->size() == 0) return; // Set workspace for Python export as the first result workspace m_pythonExportWsName = energyTransferOutputGroup->getNames()[0]; // Ungroup the output workspace energyTransferOutputGroup->removeAll(); AnalysisDataService::Instance().remove("IndirectEnergyTransfer_Workspaces"); }
/** * Returns a workspace for the first period as specified using FirstPeriod * property. * @param group :: Loaded group of workspaces to use * @return Workspace for the period */ MatrixWorkspace_sptr MuonLoad::getFirstPeriodWS(WorkspaceGroup_sptr group) { int firstPeriod = getProperty("FirstPeriod"); MatrixWorkspace_sptr resultWS; if (firstPeriod < 0 || firstPeriod >= static_cast<int>(group->size())) throw std::invalid_argument( "Workspace doesn't contain specified first period"); resultWS = boost::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(firstPeriod)); if (!resultWS) throw std::invalid_argument( "First period workspace is not a MatrixWorkspace"); return resultWS; }
/** * Remove a workspace group and all its members from the ADS. * @param name :: A group to remove. */ void AnalysisDataServiceImpl::deepRemoveGroup(const std::string &name) { WorkspaceGroup_sptr group = retrieveWS<WorkspaceGroup>(name); if (!group) { throw std::runtime_error("Workspace " + name + " is not a workspace group."); } group->observeADSNotifications(false); for (size_t i = 0; i < group->size(); ++i) { auto ws = group->getItem(i); WorkspaceGroup_sptr gws = boost::dynamic_pointer_cast<WorkspaceGroup>(ws); if (gws) { // if a member is a group remove its items as well deepRemoveGroup(gws->name()); } else { remove(ws->name()); } } remove(name); }
/** * Returns a workspace for the second period as specified using SecondPeriod * property. * @param group :: Loaded group of workspaces to use * @return Workspace for the period */ MatrixWorkspace_sptr MuonLoad::getSecondPeriodWS(WorkspaceGroup_sptr group) { int secondPeriod = getProperty("SecondPeriod"); MatrixWorkspace_sptr resultWS; if (secondPeriod != EMPTY_INT()) { if (secondPeriod < 0 || secondPeriod >= static_cast<int>(group->size())) throw std::invalid_argument( "Workspace doesn't contain specified second period"); resultWS = boost::dynamic_pointer_cast<MatrixWorkspace>( group->getItem(secondPeriod)); if (!resultWS) throw std::invalid_argument( "Second period workspace is not a MatrixWorkspace"); } return resultWS; }
/** * Updates the preview plot when the algorithm is complete. * * @param error True if the algorithm was stopped due to error, false otherwise */ void ISISDiagnostics::sliceAlgDone(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(sliceAlgDone(bool))); if (error) return; QStringList filenames = m_uiForm.dsInputFiles->getFilenames(); if (filenames.size() < 1) return; WorkspaceGroup_sptr sliceOutputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( "IndirectDiagnostics_Workspaces"); if (sliceOutputGroup->size() == 0) { g_log.warning("No result workspaces, cannot plot preview."); return; } MatrixWorkspace_sptr sliceWs = boost::dynamic_pointer_cast<MatrixWorkspace>( sliceOutputGroup->getItem(0)); if (!sliceWs) { g_log.warning("No result workspaces, cannot plot preview."); return; } // Set workspace for Python export as the first result workspace m_pythonExportWsName = sliceWs->getName(); // Plot result spectrum m_uiForm.ppSlicePreview->clear(); m_uiForm.ppSlicePreview->addSpectrum("Slice", sliceWs, 0); m_uiForm.ppSlicePreview->resizeX(); // Ungroup the output workspace sliceOutputGroup->removeAll(); AnalysisDataService::Instance().remove("IndirectDiagnostics_Workspaces"); }
/** * Updates the preview plot when the algorithm is complete. * * @param error True if the algorithm was stopped due to error, false otherwise */ void IndirectDiagnostics::sliceAlgDone(bool error) { if(error) return; QStringList filenames = m_uiForm.dsInputFiles->getFilenames(); if(filenames.size() < 1) return; WorkspaceGroup_sptr sliceOutputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>("IndirectDiagnostics_Workspaces"); if(sliceOutputGroup->size() == 0) { g_log.warning("No result workspaces, cannot plot preview."); return; } MatrixWorkspace_sptr sliceWs = boost::dynamic_pointer_cast<MatrixWorkspace>(sliceOutputGroup->getItem(0)); if(!sliceWs) { g_log.warning("No result workspaces, cannot plot preview."); return; } // Set workspace for Python export as the first result workspace m_pythonExportWsName = sliceWs->getName(); // Plot result spectrum plotMiniPlot(sliceWs, 0, "SlicePreviewPlot", "SlicePreviewCurve"); // Set X range to data range setXAxisToCurve("SlicePreviewPlot", "SlicePreviewCurve"); m_plots["SlicePreviewPlot"]->replot(); // Ungroup the output workspace sliceOutputGroup->removeAll(); AnalysisDataService::Instance().remove("IndirectDiagnostics_Workspaces"); }
/** * Sum transmission workspaces that belong to a workspace group * @param transGroup : The transmission group containing the transmission runs * @return :: A workspace pointer containing the sum of transmission workspaces */ MatrixWorkspace_sptr ReflectometryReductionOneAuto2::sumTransmissionWorkspaces( WorkspaceGroup_sptr &transGroup) { const std::string transSum = "trans_sum"; Workspace_sptr sumWS = transGroup->getItem(0)->clone(); /// For this step to appear in the history of the output workspaces I need to /// set child to false and work with the ADS auto plusAlg = createChildAlgorithm("Plus"); plusAlg->setChild(false); plusAlg->initialize(); for (size_t item = 1; item < transGroup->size(); item++) { plusAlg->setProperty("LHSWorkspace", sumWS); plusAlg->setProperty("RHSWorkspace", transGroup->getItem(item)); plusAlg->setProperty("OutputWorkspace", transSum); plusAlg->execute(); sumWS = AnalysisDataService::Instance().retrieve(transSum); } MatrixWorkspace_sptr result = boost::dynamic_pointer_cast<MatrixWorkspace>(sumWS); AnalysisDataService::Instance().remove(transSum); return result; }
bool ReflectometryReductionOneAuto::processGroups() { auto group = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( getPropertyValue("InputWorkspace")); const std::string outputIvsQ = this->getPropertyValue("OutputWorkspace"); const std::string outputIvsLam = this->getPropertyValue("OutputWorkspaceWavelength"); // Create a copy of ourselves Algorithm_sptr alg = this->createChildAlgorithm( this->name(), -1, -1, this->isLogging(), this->version()); alg->setChild(false); alg->setRethrows(true); // Copy all the non-workspace properties over std::vector<Property *> props = this->getProperties(); for (auto prop = props.begin(); prop != props.end(); ++prop) { if (*prop) { IWorkspaceProperty *wsProp = dynamic_cast<IWorkspaceProperty *>(*prop); if (!wsProp) alg->setPropertyValue((*prop)->name(), (*prop)->value()); } } // Check if the transmission runs are groups or not const std::string firstTrans = this->getPropertyValue("FirstTransmissionRun"); WorkspaceGroup_sptr firstTransG; if (!firstTrans.empty()) { auto firstTransWS = AnalysisDataService::Instance().retrieveWS<Workspace>(firstTrans); firstTransG = boost::dynamic_pointer_cast<WorkspaceGroup>(firstTransWS); if (!firstTransG) alg->setProperty("FirstTransmissionRun", firstTrans); else if (group->size() != firstTransG->size()) throw std::runtime_error("FirstTransmissionRun WorkspaceGroup must be " "the same size as the InputWorkspace " "WorkspaceGroup"); } const std::string secondTrans = this->getPropertyValue("SecondTransmissionRun"); WorkspaceGroup_sptr secondTransG; if (!secondTrans.empty()) { auto secondTransWS = AnalysisDataService::Instance().retrieveWS<Workspace>(secondTrans); secondTransG = boost::dynamic_pointer_cast<WorkspaceGroup>(secondTransWS); if (!secondTransG) alg->setProperty("SecondTransmissionRun", secondTrans); else if (group->size() != secondTransG->size()) throw std::runtime_error("SecondTransmissionRun WorkspaceGroup must be " "the same size as the InputWorkspace " "WorkspaceGroup"); } std::vector<std::string> IvsQGroup, IvsLamGroup; // Execute algorithm over each group member (or period, if this is // multiperiod) size_t numMembers = group->size(); for (size_t i = 0; i < numMembers; ++i) { const std::string IvsQName = outputIvsQ + "_" + boost::lexical_cast<std::string>(i + 1); const std::string IvsLamName = outputIvsLam + "_" + boost::lexical_cast<std::string>(i + 1); alg->setProperty("InputWorkspace", group->getItem(i)->name()); alg->setProperty("OutputWorkspace", IvsQName); alg->setProperty("OutputWorkspaceWavelength", IvsLamName); // Handle transmission runs if (firstTransG) alg->setProperty("FirstTransmissionRun", firstTransG->getItem(i)->name()); if (secondTransG) alg->setProperty("SecondTransmissionRun", secondTransG->getItem(i)->name()); alg->execute(); IvsQGroup.push_back(IvsQName); IvsLamGroup.push_back(IvsLamName); // We use the first group member for our thetaout value if (i == 0) this->setPropertyValue("ThetaOut", alg->getPropertyValue("ThetaOut")); } // Group the IvsQ and IvsLam workspaces Algorithm_sptr groupAlg = this->createChildAlgorithm("GroupWorkspaces"); groupAlg->setChild(false); groupAlg->setRethrows(true); groupAlg->setProperty("InputWorkspaces", IvsLamGroup); groupAlg->setProperty("OutputWorkspace", outputIvsLam); groupAlg->execute(); groupAlg->setProperty("InputWorkspaces", IvsQGroup); groupAlg->setProperty("OutputWorkspace", outputIvsQ); groupAlg->execute(); // If this is a multiperiod workspace and we have polarization corrections // enabled if (this->getPropertyValue("PolarizationAnalysis") != noPolarizationCorrectionMode()) { if (group->isMultiperiod()) { // Perform polarization correction over the IvsLam group Algorithm_sptr polAlg = this->createChildAlgorithm("PolarizationCorrection"); polAlg->setChild(false); polAlg->setRethrows(true); polAlg->setProperty("InputWorkspace", outputIvsLam); polAlg->setProperty("OutputWorkspace", outputIvsLam); polAlg->setProperty("PolarizationAnalysis", this->getPropertyValue("PolarizationAnalysis")); polAlg->setProperty("CPp", this->getPropertyValue(cppLabel())); polAlg->setProperty("CRho", this->getPropertyValue(crhoLabel())); polAlg->setProperty("CAp", this->getPropertyValue(cApLabel())); polAlg->setProperty("CAlpha", this->getPropertyValue(cAlphaLabel())); polAlg->execute(); // Now we've overwritten the IvsLam workspaces, we'll need to recalculate // the IvsQ ones alg->setProperty("FirstTransmissionRun", ""); alg->setProperty("SecondTransmissionRun", ""); for (size_t i = 0; i < numMembers; ++i) { const std::string IvsQName = outputIvsQ + "_" + boost::lexical_cast<std::string>(i + 1); const std::string IvsLamName = outputIvsLam + "_" + boost::lexical_cast<std::string>(i + 1); alg->setProperty("InputWorkspace", IvsLamName); alg->setProperty("OutputWorkspace", IvsQName); alg->setProperty("OutputWorkspaceWavelength", IvsLamName); alg->execute(); } } else { g_log.warning("Polarization corrections can only be performed on " "multiperiod workspaces."); } } // We finished successfully this->setPropertyValue("OutputWorkspace", outputIvsQ); this->setPropertyValue("OutputWorkspaceWavelength", outputIvsLam); setExecuted(true); notificationCenter().postNotification( new FinishedNotification(this, isExecuted())); return true; }
bool ApplyPaalmanPings::validate() { UserInputValidator uiv; uiv.checkDataSelectorIsValid("Sample", m_uiForm.dsSample); MatrixWorkspace_sptr sampleWs; bool useCan = m_uiForm.ckUseCan->isChecked(); bool useCorrections = m_uiForm.ckUseCorrections->isChecked(); if (!(useCan || useCorrections)) uiv.addErrorMessage("Must use either container subtraction or corrections"); if (useCan) { uiv.checkDataSelectorIsValid("Container", m_uiForm.dsContainer); // Check can and sample workspaces are the same "type" (reduced or S(Q, w)) QString sample = m_uiForm.dsSample->getCurrentDataName(); QString sampleType = sample.right(sample.length() - sample.lastIndexOf("_")); QString container = m_uiForm.dsContainer->getCurrentDataName(); QString containerType = container.right(container.length() - container.lastIndexOf("_")); g_log.debug() << "Sample type is: " << sampleType.toStdString() << '\n'; g_log.debug() << "Can type is: " << containerType.toStdString() << '\n'; if (containerType != sampleType) uiv.addErrorMessage( "Sample and can workspaces must contain the same type of data."); } if (useCorrections) { if (m_uiForm.dsCorrections->getCurrentDataName().compare("") == 0) { uiv.addErrorMessage( "Use Correction must contain a corrections file or workspace."); } else { QString correctionsWsName = m_uiForm.dsCorrections->getCurrentDataName(); WorkspaceGroup_sptr corrections = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( correctionsWsName.toStdString()); for (size_t i = 0; i < corrections->size(); i++) { // Check it is a MatrixWorkspace MatrixWorkspace_sptr factorWs = boost::dynamic_pointer_cast<MatrixWorkspace>( corrections->getItem(i)); if (!factorWs) { QString msg = "Correction factor workspace " + QString::number(i) + " is not a MatrixWorkspace"; uiv.addErrorMessage(msg); continue; } // Check X unit is wavelength Mantid::Kernel::Unit_sptr xUnit = factorWs->getAxis(0)->unit(); if (xUnit->caption() != "Wavelength") { QString msg = "Correction factor workspace " + QString::fromStdString(factorWs->name()) + " is not in wavelength"; uiv.addErrorMessage(msg); } } } } // Show errors if there are any if (!uiv.isAllInputValid()) emit showMessageBox(uiv.generateErrorMessage()); return uiv.isAllInputValid(); }
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(); }
bool ReflectometryReductionOneAuto::processGroups() { // isPolarizationCorrectionOn is used to decide whether // we should process our Transmission WorkspaceGroup members // as individuals (not multiperiod) when PolarizationCorrection is off, // or sum over all of the workspaces in the group // and used that sum as our TransmissionWorkspace when PolarizationCorrection // is on. const bool isPolarizationCorrectionOn = this->getPropertyValue("PolarizationAnalysis") != noPolarizationCorrectionMode(); // Get our input workspace group auto group = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( getPropertyValue("InputWorkspace")); // Get name of IvsQ workspace const std::string outputIvsQ = this->getPropertyValue("OutputWorkspace"); // Get name of IvsLam workspace const std::string outputIvsLam = this->getPropertyValue("OutputWorkspaceWavelength"); // Create a copy of ourselves Algorithm_sptr alg = this->createChildAlgorithm( this->name(), -1, -1, this->isLogging(), this->version()); alg->setChild(false); alg->setRethrows(true); // Copy all the non-workspace properties over std::vector<Property *> props = this->getProperties(); for (auto &prop : props) { if (prop) { IWorkspaceProperty *wsProp = dynamic_cast<IWorkspaceProperty *>(prop); if (!wsProp) alg->setPropertyValue(prop->name(), prop->value()); } } // Check if the transmission runs are groups or not const std::string firstTrans = this->getPropertyValue("FirstTransmissionRun"); WorkspaceGroup_sptr firstTransG; if (!firstTrans.empty()) { auto firstTransWS = AnalysisDataService::Instance().retrieveWS<Workspace>(firstTrans); firstTransG = boost::dynamic_pointer_cast<WorkspaceGroup>(firstTransWS); if (!firstTransG) { // we only have one transmission workspace, so we use it as it is. alg->setProperty("FirstTransmissionRun", firstTrans); } else if (group->size() != firstTransG->size() && !isPolarizationCorrectionOn) { // if they are not the same size then we cannot associate a transmission // group workspace member with every input group workpspace member. throw std::runtime_error("FirstTransmissionRun WorkspaceGroup must be " "the same size as the InputWorkspace " "WorkspaceGroup"); } } const std::string secondTrans = this->getPropertyValue("SecondTransmissionRun"); WorkspaceGroup_sptr secondTransG; if (!secondTrans.empty()) { auto secondTransWS = AnalysisDataService::Instance().retrieveWS<Workspace>(secondTrans); secondTransG = boost::dynamic_pointer_cast<WorkspaceGroup>(secondTransWS); if (!secondTransG) // we only have one transmission workspace, so we use it as it is. alg->setProperty("SecondTransmissionRun", secondTrans); else if (group->size() != secondTransG->size() && !isPolarizationCorrectionOn) { // if they are not the same size then we cannot associate a transmission // group workspace member with every input group workpspace member. throw std::runtime_error("SecondTransmissionRun WorkspaceGroup must be " "the same size as the InputWorkspace " "WorkspaceGroup"); } } std::vector<std::string> IvsQGroup, IvsLamGroup; // Execute algorithm over each group member (or period, if this is // multiperiod) size_t numMembers = group->size(); for (size_t i = 0; i < numMembers; ++i) { const std::string IvsQName = outputIvsQ + "_" + boost::lexical_cast<std::string>(i + 1); const std::string IvsLamName = outputIvsLam + "_" + boost::lexical_cast<std::string>(i + 1); // If our transmission run is a group and PolarizationCorrection is on // then we sum our transmission group members. // // This is done inside of the for loop to avoid the wrong workspace being // used when these arguments are passed through to the exec() method. // If this is not set in the loop, exec() will fetch the first workspace // from the specified Transmission Group workspace that the user entered. if (firstTransG && isPolarizationCorrectionOn) { auto firstTransmissionSum = sumOverTransmissionGroup(firstTransG); alg->setProperty("FirstTransmissionRun", firstTransmissionSum); } if (secondTransG && isPolarizationCorrectionOn) { auto secondTransmissionSum = sumOverTransmissionGroup(secondTransG); alg->setProperty("SecondTransmissionRun", secondTransmissionSum); } // Otherwise, if polarization correction is off, we process them // using one transmission group member at a time. if (firstTransG && !isPolarizationCorrectionOn) // polarization off alg->setProperty("FirstTransmissionRun", firstTransG->getItem(i)->name()); if (secondTransG && !isPolarizationCorrectionOn) // polarization off alg->setProperty("SecondTransmissionRun", secondTransG->getItem(i)->name()); alg->setProperty("InputWorkspace", group->getItem(i)->name()); alg->setProperty("OutputWorkspace", IvsQName); alg->setProperty("OutputWorkspaceWavelength", IvsLamName); alg->execute(); MatrixWorkspace_sptr tempFirstTransWS = alg->getProperty("FirstTransmissionRun"); IvsQGroup.push_back(IvsQName); IvsLamGroup.push_back(IvsLamName); // We use the first group member for our thetaout value if (i == 0) this->setPropertyValue("ThetaOut", alg->getPropertyValue("ThetaOut")); } // Group the IvsQ and IvsLam workspaces Algorithm_sptr groupAlg = this->createChildAlgorithm("GroupWorkspaces"); groupAlg->setChild(false); groupAlg->setRethrows(true); groupAlg->setProperty("InputWorkspaces", IvsLamGroup); groupAlg->setProperty("OutputWorkspace", outputIvsLam); groupAlg->execute(); groupAlg->setProperty("InputWorkspaces", IvsQGroup); groupAlg->setProperty("OutputWorkspace", outputIvsQ); groupAlg->execute(); // If this is a multiperiod workspace and we have polarization corrections // enabled if (isPolarizationCorrectionOn) { if (group->isMultiperiod()) { // Perform polarization correction over the IvsLam group Algorithm_sptr polAlg = this->createChildAlgorithm("PolarizationCorrection"); polAlg->setChild(false); polAlg->setRethrows(true); polAlg->setProperty("InputWorkspace", outputIvsLam); polAlg->setProperty("OutputWorkspace", outputIvsLam); polAlg->setProperty("PolarizationAnalysis", this->getPropertyValue("PolarizationAnalysis")); polAlg->setProperty("CPp", this->getPropertyValue(cppLabel())); polAlg->setProperty("CRho", this->getPropertyValue(crhoLabel())); polAlg->setProperty("CAp", this->getPropertyValue(cApLabel())); polAlg->setProperty("CAlpha", this->getPropertyValue(cAlphaLabel())); polAlg->execute(); // Now we've overwritten the IvsLam workspaces, we'll need to recalculate // the IvsQ ones alg->setProperty("FirstTransmissionRun", ""); alg->setProperty("SecondTransmissionRun", ""); for (size_t i = 0; i < numMembers; ++i) { const std::string IvsQName = outputIvsQ + "_" + boost::lexical_cast<std::string>(i + 1); const std::string IvsLamName = outputIvsLam + "_" + boost::lexical_cast<std::string>(i + 1); alg->setProperty("InputWorkspace", IvsLamName); alg->setProperty("OutputWorkspace", IvsQName); alg->setProperty("CorrectionAlgorithm", "None"); alg->setProperty("OutputWorkspaceWavelength", IvsLamName); alg->execute(); } } else { g_log.warning("Polarization corrections can only be performed on " "multiperiod workspaces."); } } // We finished successfully this->setPropertyValue("OutputWorkspace", outputIvsQ); this->setPropertyValue("OutputWorkspaceWavelength", outputIvsLam); setExecuted(true); notificationCenter().postNotification( new FinishedNotification(this, isExecuted())); return true; }