/** Compares the properties of the input workspace with the reference
 * @param ws : the testee workspace
 * @param checkNumberHistograms : whether to check also the number of histograms
 * @return : empty if compatible, error message otherwises
 */
std::string
RunCombinationHelper::checkCompatibility(MatrixWorkspace_sptr ws,
                                         bool checkNumberHistograms) {
  std::string errors;
  if (ws->getNumberHistograms() != m_numberSpectra && checkNumberHistograms)
    errors += "different number of histograms; ";
  if (ws->getAxis(0)->unit()->unitID() != m_xUnit)
    errors += "different X units; ";
  if (ws->getAxis(1)->unit()->unitID() != m_spectrumAxisUnit)
    errors += "different spectrum axis units; ";
  if (ws->YUnit() != m_yUnit)
    errors += "different Y units; ";
  if (ws->isHistogramData() != m_isHistogramData)
    errors += "different distribution or histogram type; ";
  if (ws->detectorInfo().isScanning() != m_isScanning)
    errors += "a mix of workspaces with and without detector scans; ";
  if (m_isScanning && ws->detectorInfo().size() != m_numberDetectors)
    errors += "workspaces with detectors scans have different number of "
              "detectors; ";
  if (ws->getInstrument()->getName() != m_instrumentName)
    errors += "different instrument names; ";
  if (ws->getNumberHistograms() == m_numberSpectra) {
    if (!m_hasDx.empty()) {
      for (unsigned int i = 0; i < m_numberSpectra; ++i) {
        if (m_hasDx[i] != ws->hasDx(i)) {
          errors += "spectra must have either Dx values or not; ";
          break;
        }
      }
    }
  }
  return errors;
}
/** Sets the properties of the reference (usually first) workspace,
 * to later check the compatibility of the others with the reference
 * @param ref : the reference workspace
 */
void RunCombinationHelper::setReferenceProperties(MatrixWorkspace_sptr ref) {
  m_numberSpectra = ref->getNumberHistograms();
  m_numberDetectors = ref->detectorInfo().size();
  m_xUnit = ref->getAxis(0)->unit()->unitID();
  m_spectrumAxisUnit = ref->getAxis(1)->unit()->unitID();
  m_yUnit = ref->YUnit();
  m_isHistogramData = ref->isHistogramData();
  m_isScanning = ref->detectorInfo().isScanning();
  m_instrumentName = ref->getInstrument()->getName();
  if (m_numberSpectra) {
    m_hasDx.reserve(m_numberSpectra);
    for (unsigned int i = 0; i < m_numberSpectra; ++i)
      m_hasDx.push_back(ref->hasDx(i));
  }
}
Example #3
0
/** Makes sure that the input properties are set correctly
 *  @param inputWorkspace The input workspace
 */
void NormaliseToMonitor::checkProperties(
    const MatrixWorkspace_sptr &inputWorkspace) {

  // Check where the monitor spectrum should come from
  Property *monSpec = getProperty("MonitorSpectrum");
  MatrixWorkspace_sptr monWS = getProperty("MonitorWorkspace");
  Property *monID = getProperty("MonitorID");
  // Is the monitor spectrum within the main input workspace
  const bool inWS = !monSpec->isDefault();
  m_scanInput = inputWorkspace->detectorInfo().isScanning();
  // Or is it in a separate workspace
  bool sepWS{monWS};
  if (m_scanInput && sepWS)
    throw std::runtime_error("Can not currently use a separate monitor "
                             "workspace with a detector scan input workspace.");
  // or monitor ID
  bool monIDs = !monID->isDefault();
  // something has to be set
  // One and only one of these properties should have been set
  // input from separate workspace is overwritten by monitor spectrum
  if (inWS && sepWS) {
    g_log.information("Both input workspace MonitorSpectrum number and monitor "
                      "workspace are specified. Ignoring Monitor Workspace");
    sepWS = false;
  }
  // input from detector ID is rejected in favor of monitor sp
  if (inWS && monIDs) {
    g_log.information("Both input workspace MonitorSpectrum number and "
                      "detector ID are specified. Ignoring Detector ID");
    monIDs = false;
  }
  // separate ws takes over detectorID (this logic is duplicated within
  // getInWSMonitorSpectrum)
  if (sepWS && monIDs) {
    g_log.information("Both input MonitorWorkspace and detector ID are "
                      "specified. Ignoring Detector ID");
  }

  // Do a check for common binning and store
  m_commonBins = inputWorkspace->isCommonBins();

  // Check the monitor spectrum or workspace and extract into new workspace
  m_monitor = sepWS ? getMonitorWorkspace(inputWorkspace)
                    : getInWSMonitorSpectrum(inputWorkspace);

  // Check that the 'monitor' spectrum actually relates to a monitor - warn if
  // not
  try {
    const auto &monitorSpecInfo = m_monitor->spectrumInfo();
    for (const auto workspaceIndex : m_workspaceIndexes)
      if (!monitorSpecInfo.isMonitor(workspaceIndex))
        g_log.warning() << "The spectrum N: " << workspaceIndex
                        << " in MonitorWorkspace does not refer to a monitor.\n"
                        << "Continuing with normalization regardless.";
  } catch (Kernel::Exception::NotFoundError &e) {
    g_log.warning("Unable to check if the spectrum provided relates to a "
                  "monitor - the instrument is not fully specified.\n "
                  "Continuing with normalization regardless.");
    g_log.warning() << "Error was: " << e.what() << "\n";
    if (m_scanInput)
      throw std::runtime_error("Can not continue, spectrum can not be obtained "
                               "for monitor workspace, but the input workspace "
                               "has a detector scan.");
  }
}