Example #1
0
/**
 * 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);
}
Example #7
0
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");
  }
Example #11
0
/**
 * 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;
}
Example #12
0
/**
 * 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);
}
Example #13
0
/**
 * 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;
}
Example #14
0
/**
 * 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");
}
Example #15
0
  /**
   * 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;
}
Example #18
0
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();
}
Example #19
0
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;
}