/**
 * @brief Handle setting fit workspace.
 *
 * Creates a list of Q values from each spectrum to be used with WorkspaceIndex
 * attribute.
 *
 * @param ws Pointer to workspace
 */
void InelasticDiffSphere::setWorkspace(
    boost::shared_ptr<const API::Workspace> ws) {
  m_qValueCache.clear();

  auto workspace = boost::dynamic_pointer_cast<const API::MatrixWorkspace>(ws);
  if (!workspace)
    return;

  size_t numHist = workspace->getNumberHistograms();
  for (size_t idx = 0; idx < numHist; idx++) {
    Mantid::Geometry::IDetector_const_sptr det;
    try {
      det = workspace->getDetector(idx);
    } catch (Kernel::Exception::NotFoundError &) {
      m_qValueCache.clear();
      g_log.information("Cannot populate Q values from workspace");
      break;
    }

    try {
      double efixed = workspace->getEFixed(det);
      double usignTheta = 0.5 * workspace->detectorTwoTheta(*det);

      double q = Mantid::Kernel::UnitConversion::run(usignTheta, efixed);

      m_qValueCache.push_back(q);
    } catch (std::runtime_error &) {
      m_qValueCache.clear();
      g_log.information("Cannot populate Q values from workspace");
      return;
    }
  }
}
Beispiel #2
0
  /**
   * A map detector ID and Q ranges
   * This method looks unnecessary as it could be calculated on the fly but
   * the parallelization means that lazy instantation slows it down due to the
   * necessary CRITICAL sections required to update the cache. The Q range
   * values are required very frequently so the total time is more than
   * offset by this precaching step
   */
  void SofQW3::initThetaCache(API::MatrixWorkspace_const_sptr workspace)
  {
    const size_t nhist = workspace->getNumberHistograms();
    this->m_theta = std::vector<double>(nhist);
    size_t ndets(0);
    double minTheta(DBL_MAX), maxTheta(-DBL_MAX);

    for(int64_t i = 0 ; i < (int64_t)nhist; ++i) //signed for OpenMP
    {

      m_progress->report("Calculating detector angles");
      IDetector_const_sptr det;
      try
      {
        det = workspace->getDetector(i);
        // Check to see if there is an EFixed, if not skip it
        try
        {
          getEFixed(det);
        }
        catch(std::runtime_error&)
        {
          det.reset();
        }
      }
      catch(Kernel::Exception::NotFoundError&)
      {
        // Catch if no detector. Next line tests whether this happened - test placed
        // outside here because Mac Intel compiler doesn't like 'continue' in a catch
        // in an openmp block.
      }
      // If no detector found, skip onto the next spectrum
      if( !det || det->isMonitor() )
      {
        this->m_theta[i] = -1.0; // Indicates a detector to skip
      }
      else
      {
        ++ndets;
        const double theta = workspace->detectorTwoTheta(det);
        this->m_theta[i] = theta;
        if( theta < minTheta )
        {
          minTheta = theta;
        }
        else if( theta > maxTheta )
        {
          maxTheta = theta;
        }
      }
    }

    this->m_thetaWidth = (maxTheta - minTheta)/static_cast<double>(ndets);
    g_log.information() << "Calculated detector width in theta=" << (m_thetaWidth*180.0/M_PI) << " degrees.\n";
  }