Exemple #1
0
/**
 * Execute the algorithm.
 */
void LoadSassena::exec() {
  // auto
  // gws=boost::dynamic_pointer_cast<API::WorkspaceGroup>(getProperty("OutputWorkspace"));
  // API::WorkspaceGroup_sptr gws=getProperty("OutputWorkspace");
  API::Workspace_sptr ows = getProperty("OutputWorkspace");

  API::WorkspaceGroup_sptr gws =
      boost::dynamic_pointer_cast<API::WorkspaceGroup>(ows);
  if (gws && API::AnalysisDataService::Instance().doesExist(gws->name())) {
    // gws->deepRemoveAll(); // remove workspace members
    API::AnalysisDataService::Instance().deepRemoveGroup(gws->name());
  } else {
    gws = boost::make_shared<API::WorkspaceGroup>();
    setProperty("OutputWorkspace",
                boost::dynamic_pointer_cast<API::Workspace>(gws));
  }

  // populate m_validSets
  int nvalidSets = 4;
  const char *validSets[] = {"fq", "fq0", "fq2", "fqt"};
  for (int iSet = 0; iSet < nvalidSets; iSet++)
    this->m_validSets.push_back(validSets[iSet]);

  // open the HDF5 file for reading
  m_filename = this->getPropertyValue("Filename");
  hid_t h5file = H5Fopen(m_filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
  if (h5file < 0) {
    this->g_log.error("Cannot open " + m_filename);
    throw Kernel::Exception::FileError("Unable to open:", m_filename);
  }

  // find out the sassena version used
  char cversion[16];
  if (H5LTget_attribute_string(h5file, "/", "sassena_version", cversion) < 0) {
    this->g_log.error("Unable to read Sassena version");
  }
  // const std::string version(cversion);
  // determine which loader protocol to use based on the version
  // to be done at a later time, maybe implement a Version class
  std::vector<int> sorting_indexes;
  const MantidVec qvmod = this->loadQvectors(h5file, gws, sorting_indexes);
  // iterate over the valid sets
  std::string setName;
  for (std::vector<std::string>::const_iterator it = this->m_validSets.begin();
       it != this->m_validSets.end(); ++it) {
    setName = *it;
    if (H5LTfind_dataset(h5file, setName.c_str()) == 1) {
      if (setName == "fq" || setName == "fq0" || setName == "fq2")
        this->loadFQ(h5file, gws, setName, qvmod, sorting_indexes);
      else if (setName == "fqt")
        this->loadFQT(h5file, gws, setName, qvmod, sorting_indexes);
    } else
      this->g_log.information("Dataset " + setName + " not present in file");
  } // end of iterate over the valid sets

  H5Fclose(h5file);
} // end of LoadSassena::exec()
/**
 * Create the output workspace group.
 * @param baseName :: The base name for the output workspace. Suffix "Workspace"
 * will be added to it.
 * @param function :: A function to calculate the values. Must be of the
 * MultiDomainFunction type.
 * @param domain :: Domain created earlier with this creator (unused)
 * @param values :: Values created earlier with this creator (unused)
 * @param outputWorkspacePropertyName :: Name for the property to hold the
 * output workspace. If
 *    empty the property won't be created.
 * @return A shared pointer to the created workspace.
 */
boost::shared_ptr<API::Workspace> MultiDomainCreator::createOutputWorkspace(
    const std::string &baseName, API::IFunction_sptr function,
    boost::shared_ptr<API::FunctionDomain> domain,
    boost::shared_ptr<API::FunctionValues> values,
    const std::string &outputWorkspacePropertyName) {
  UNUSED_ARG(domain);
  UNUSED_ARG(values);

  auto mdFunction =
      boost::dynamic_pointer_cast<API::MultiDomainFunction>(function);
  if (!mdFunction) {
    throw std::runtime_error("A MultiDomainFunction is expected to be used "
                             "with MultiDomainCreator.");
  }

  // split the function into independent parts
  std::vector<API::IFunction_sptr> functions =
      mdFunction->createEquivalentFunctions();
  // there must be as many parts as there are domains
  if (functions.size() != m_creators.size()) {
    throw std::runtime_error("Number of functions and domains don't match");
  }

  API::WorkspaceGroup_sptr outWS =
      API::WorkspaceGroup_sptr(new API::WorkspaceGroup());

  for (size_t i = 0; i < functions.size(); ++i) {
    std::string localName =
        baseName + "Workspace_" + boost::lexical_cast<std::string>(i);
    auto fun = functions[i];
    auto creator = m_creators[i];
    boost::shared_ptr<API::FunctionDomain> localDomain;
    boost::shared_ptr<API::FunctionValues> localValues;
    fun->setUpForFit();
    creator->createDomain(localDomain, localValues);
    creator->initFunction(fun);
    auto ws = creator->createOutputWorkspace(localName, fun, localDomain,
                                             localValues, "");
    API::AnalysisDataService::Instance().addOrReplace(localName, ws);
    outWS->addWorkspace(ws);
  }

  if (!outputWorkspacePropertyName.empty()) {
    declareProperty(
        new API::WorkspaceProperty<API::WorkspaceGroup>(
            outputWorkspacePropertyName, "", Kernel::Direction::Output),
        "Name of the output Workspace holding resulting simulated spectrum");
    m_manager->setPropertyValue(outputWorkspacePropertyName,
                                baseName + "Workspaces");
    m_manager->setProperty(outputWorkspacePropertyName, outWS);
  }

  return outWS;
}
Exemple #3
0
/**
 * Register a workspace in the Analysis Data Service and add it to the
 * groupWorkspace
 * @param gws pointer to WorkspaceGroup being filled
 * @param wsName name of workspace to be added and registered
 * @param ws pointer to workspace to be added and registered
 * @param description
 */
void LoadSassena::registerWorkspace(API::WorkspaceGroup_sptr gws,
                                    const std::string wsName,
                                    DataObjects::Workspace2D_sptr ws,
                                    const std::string &description) {
  UNUSED_ARG(description);
  API::AnalysisDataService::Instance().add(wsName, ws);
  gws->addWorkspace(ws);
}
/** Fits each spectrum in the workspace to f(x) = A * sin( w * x + p)
* @param ws :: [input] The workspace to fit
* @param freq :: [input] Hint for the frequency (w)
* @param groupName :: [input] The name of the output workspace group
* @param resTab :: [output] Table workspace storing the asymmetries and phases
* @param resGroup :: [output] Workspace group storing the fitting results
*/
void CalMuonDetectorPhases::fitWorkspace(const API::MatrixWorkspace_sptr &ws,
                                         double freq, std::string groupName,
                                         API::ITableWorkspace_sptr &resTab,
                                         API::WorkspaceGroup_sptr &resGroup) {

  int nhist = static_cast<int>(ws->getNumberHistograms());

  // Create the fitting function f(x) = A * sin ( w * x + p )
  // The same function and initial parameters are used for each fit
  std::string funcStr = createFittingFunction(freq, true);

  // Set up results table
  resTab->addColumn("int", "Spectrum number");
  resTab->addColumn("double", "Asymmetry");
  resTab->addColumn("double", "Phase");

  // Loop through fitting all spectra individually
  const static std::string success = "success";
  for (int wsIndex = 0; wsIndex < nhist; wsIndex++) {
    reportProgress(wsIndex, nhist);
    auto fit = createChildAlgorithm("Fit");
    fit->initialize();
    fit->setPropertyValue("Function", funcStr);
    fit->setProperty("InputWorkspace", ws);
    fit->setProperty("WorkspaceIndex", wsIndex);
    fit->setProperty("CreateOutput", true);
    fit->setPropertyValue("Output", groupName);
    fit->execute();

    std::string status = fit->getProperty("OutputStatus");
    if (!fit->isExecuted() || status != success) {
      std::ostringstream error;
      error << "Fit failed for spectrum at workspace index " << wsIndex;
      error << ": " << status;
      throw std::runtime_error(error.str());
    }

    API::MatrixWorkspace_sptr fitOut = fit->getProperty("OutputWorkspace");
    resGroup->addWorkspace(fitOut);
    API::ITableWorkspace_sptr tab = fit->getProperty("OutputParameters");
    // Now we have our fitting results stored in tab
    // but we need to extract the relevant information, i.e.
    // the detector phases (parameter 'p') and asymmetries ('A')
    const auto &spectrum = ws->getSpectrum(static_cast<size_t>(wsIndex));
    extractDetectorInfo(tab, resTab, spectrum.getSpectrumNo());
  }
}
Exemple #5
0
void Load::loadMultipleFiles() {
  // allFilenames contains "rows" of filenames. If the row has more than 1 file
  // in it
  // then that row is to be summed across each file in the row
  const std::vector<std::vector<std::string>> allFilenames =
      getProperty("Filename");
  std::string outputWsName = getProperty("OutputWorkspace");

  std::vector<std::string> wsNames(allFilenames.size());
  std::transform(allFilenames.begin(), allFilenames.end(), wsNames.begin(),
                 generateWsNameFromFileNames);

  auto wsName = wsNames.cbegin();
  assert(allFilenames.size() == wsNames.size());

  std::vector<API::Workspace_sptr> loadedWsList;
  loadedWsList.reserve(allFilenames.size());

  Workspace_sptr tempWs;

  // Cycle through the filenames and wsNames.
  for (auto filenames = allFilenames.cbegin(); filenames != allFilenames.cend();
       ++filenames, ++wsName) {
    auto filename = filenames->cbegin();
    Workspace_sptr sumWS = loadFileToWs(*filename, *wsName);

    ++filename;
    for (; filename != filenames->cend(); ++filename) {
      tempWs = loadFileToWs(*filename, "__@loadsum_temp@");
      sumWS = plusWs(sumWS, tempWs);
    }

    API::WorkspaceGroup_sptr group =
        boost::dynamic_pointer_cast<WorkspaceGroup>(sumWS);
    if (group) {
      std::vector<std::string> childWsNames = group->getNames();
      auto childWsName = childWsNames.begin();
      size_t count = 1;
      for (; childWsName != childWsNames.end(); ++childWsName, ++count) {
        Workspace_sptr childWs = group->getItem(*childWsName);
        const std::string childName =
            group->getName() + "_" + std::to_string(count);
        API::AnalysisDataService::Instance().addOrReplace(childName, childWs);
        // childWs->setName(group->getName() + "_" +
        // boost::lexical_cast<std::string>(count));
      }
    }
    // Add the sum to the list of loaded workspace names.
    loadedWsList.push_back(sumWS);
  }

  // If we only have one loaded ws, set it as the output.
  if (loadedWsList.size() == 1) {
    setProperty("OutputWorkspace", loadedWsList[0]);
    AnalysisDataService::Instance().rename(loadedWsList[0]->getName(),
                                           outputWsName);
  }
  // Else we have multiple loaded workspaces - group them and set the group as
  // output.
  else {
    API::WorkspaceGroup_sptr group = groupWsList(loadedWsList);
    setProperty("OutputWorkspace", group);

    std::vector<std::string> childWsNames = group->getNames();
    size_t count = 1;
    for (auto &childWsName : childWsNames) {
      if (childWsName == outputWsName) {
        Mantid::API::Workspace_sptr child = group->getItem(childWsName);
        // child->setName(child->getName() + "_" +
        // boost::lexical_cast<std::string>(count));
        const std::string childName =
            child->getName() + "_" + std::to_string(count);
        API::AnalysisDataService::Instance().addOrReplace(childName, child);
        count++;
      }
    }

    childWsNames = group->getNames();
    count = 1;
    for (auto &childWsName : childWsNames) {
      Workspace_sptr childWs = group->getItem(childWsName);
      std::string outWsPropName = "OutputWorkspace_" + std::to_string(count);
      ++count;
      declareProperty(Kernel::make_unique<WorkspaceProperty<Workspace>>(
          outWsPropName, childWsName, Direction::Output));
      setProperty(outWsPropName, childWs);
    }
  }

  // Clean up.
  if (tempWs) {
    Algorithm_sptr alg =
        AlgorithmManager::Instance().createUnmanaged("DeleteWorkspace");
    alg->initialize();
    alg->setChild(true);
    alg->setProperty("Workspace", tempWs);
    alg->execute();
  }
}
/** Fits each spectrum in the workspace to f(x) = A * sin( w * x + p)
 * @param ws :: [input] The workspace to fit
 * @param freq :: [input] Hint for the frequency (w)
 * @param groupName :: [input] The name of the output workspace group
 * @param resTab :: [output] Table workspace storing the asymmetries and phases
 * @param resGroup :: [output] Workspace group storing the fitting results
 */
void CalMuonDetectorPhases::fitWorkspace(const API::MatrixWorkspace_sptr &ws,
                                         double freq, std::string groupName,
                                         API::ITableWorkspace_sptr resTab,
                                         API::WorkspaceGroup_sptr &resGroup) {

  int nhist = static_cast<int>(ws->getNumberHistograms());

  // Create the fitting function f(x) = A * sin ( w * x + p )
  // The same function and initial parameters are used for each fit
  std::string funcStr = createFittingFunction(freq, true);

  // Set up results table
  resTab->addColumn("int", "Spectrum number");
  resTab->addColumn("double", "Asymmetry");
  resTab->addColumn("double", "Phase");

  const auto &indexInfo = ws->indexInfo();

  // Loop through fitting all spectra individually
  const static std::string success = "success";
  for (int wsIndex = 0; wsIndex < nhist; wsIndex++) {
    reportProgress(wsIndex, nhist);
    const auto &yValues = ws->y(wsIndex);
    auto emptySpectrum = std::all_of(yValues.begin(), yValues.end(),
                                     [](double value) { return value == 0.; });
    if (emptySpectrum) {
      g_log.warning("Spectrum " + std::to_string(wsIndex) + " is empty");
      TableWorkspace_sptr tab = boost::make_shared<TableWorkspace>();
      tab->addColumn("str", "Name");
      tab->addColumn("double", "Value");
      tab->addColumn("double", "Error");
      for (int j = 0; j < 4; j++) {
        API::TableRow row = tab->appendRow();
        if (j == PHASE_ROW) {
          row << "dummy" << 0.0 << 0.0;
        } else {
          row << "dummy" << ASYMM_ERROR << 0.0;
        }
      }

      extractDetectorInfo(*tab, *resTab, indexInfo.spectrumNumber(wsIndex));

    } else {
      auto fit = createChildAlgorithm("Fit");
      fit->initialize();
      fit->setPropertyValue("Function", funcStr);
      fit->setProperty("InputWorkspace", ws);
      fit->setProperty("WorkspaceIndex", wsIndex);
      fit->setProperty("CreateOutput", true);
      fit->setPropertyValue("Output", groupName);
      fit->execute();

      std::string status = fit->getProperty("OutputStatus");
      if (!fit->isExecuted()) {
        std::ostringstream error;
        error << "Fit failed for spectrum at workspace index " << wsIndex;
        error << ": " << status;
        throw std::runtime_error(error.str());
      } else if (status != success) {
        g_log.warning("Fit failed for spectrum at workspace index " +
                      std::to_string(wsIndex) + ": " + status);
      }

      API::MatrixWorkspace_sptr fitOut = fit->getProperty("OutputWorkspace");
      resGroup->addWorkspace(fitOut);
      API::ITableWorkspace_sptr tab = fit->getProperty("OutputParameters");
      // Now we have our fitting results stored in tab
      // but we need to extract the relevant information, i.e.
      // the detector phases (parameter 'p') and asymmetries ('A')
      extractDetectorInfo(*tab, *resTab, indexInfo.spectrumNumber(wsIndex));
    }
  }
}
    /// Create a list of input workspace names
    std::vector<PlotPeakByLogValue::InputData> PlotPeakByLogValue::makeNames()const
    {
      std::vector<InputData> nameList;
      std::string inputList = getPropertyValue("Input");
      int default_wi = getProperty("WorkspaceIndex");
      int default_spec = getProperty("Spectrum");
      double start = 0;
      double end = 0;

      typedef Poco::StringTokenizer tokenizer;
      tokenizer names(inputList, ";", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
      for (tokenizer::Iterator it = names.begin(); it != names.end(); ++it)
      {
        tokenizer params(*it, ",", tokenizer::TOK_TRIM);
        std::string name = params[0];
        int wi = default_wi;
        int spec = default_spec;
        if (params.count() > 1)
        {
          std::string index = params[1]; // spectrum or workspace index with a prefix
          if (index.size() > 2 && index.substr(0,2) == "sp")
          {// spectrum number
            spec = boost::lexical_cast<int>(index.substr(2));
            wi = -1; // undefined yet
          }
          else if (index.size() > 1 && index[0] == 'i')
          {// workspace index
            wi = boost::lexical_cast<int>(index.substr(1));
            spec = -1; // undefined yet
          }
          else if (index.size() > 0 && index[0] == 'v')
          {
            if (index.size() > 1)
            {// there is some text after 'v'
              tokenizer range(index.substr(1), ":", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
              if (range.count() < 1)
              {
                wi = -2; // means use the whole range
              }
              else if (range.count() == 1)
              {
                start = boost::lexical_cast<double>(range[0]);
                end = start;
                wi = -1;
                spec = -1;
              }
              else if (range.count() > 1)
              {
                start = boost::lexical_cast<double>(range[0]);
                end = boost::lexical_cast<double>(range[1]);
                if (start > end) std::swap(start,end);
                wi = -1;
                spec = -1;
              }
            }
            else
            {
              wi = -2;
            }
          }
          else
          {// error
            //throw std::invalid_argument("Malformed spectrum identifier ("+index+"). "
            //  "It must be either \"sp\" followed by a number for a spectrum number or"
            //  "\"i\" followed by a number for a workspace index.");
            wi = default_wi;
          }
          
        }
        int period = (params.count() > 2)? boost::lexical_cast<int>(params[2]) : 1;
        if (API::AnalysisDataService::Instance().doesExist(name))
        {
          API::Workspace_sptr ws = API::AnalysisDataService::Instance().retrieve(name);
          API::WorkspaceGroup_sptr wsg = boost::dynamic_pointer_cast<API::WorkspaceGroup>(ws);
          if (wsg)
          {
            std::vector<std::string> wsNames = wsg->getNames();
            for(std::vector<std::string>::iterator i=wsNames.begin();i!=wsNames.end();++i)
            {
             nameList.push_back(InputData(*i,wi,-1,period,start,end));
            }
            continue;
          }
        }
        nameList.push_back(InputData(name,wi,spec,period,start,end));
      }
      return nameList;
    }
Exemple #8
0
    /** Get a workspace identified by an InputData structure. 
      * @param data :: InputData with name and either spec or i fields defined. 
      * @return InputData structure with the ws field set if everything was OK.
      */
    PlotPeakByLogValue::InputData PlotPeakByLogValue::getWorkspace(const InputData& data)
    {
      InputData out(data);
      if (API::AnalysisDataService::Instance().doesExist(data.name))
      {
        DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
          API::AnalysisDataService::Instance().retrieve(data.name));
        if (ws)
        {
          out.ws = ws;
        }
        else
        {
          return data;
        }
      }
      else
      {
        std::ifstream fil(data.name.c_str());
        if (!fil)
        {
          g_log.warning() << "File "<<data.name<<" does not exist\n";
          return data;
        }
        fil.close();
        std::string::size_type i = data.name.find_last_of('.');
        if (i == std::string::npos)
        {
          g_log.warning() << "Cannot open file "<<data.name<<"\n";
          return data;
        }
        std::string ext = data.name.substr(i);
        try
        {
          API::IAlgorithm_sptr load = createSubAlgorithm("Load");
          load->initialize();
          load->setPropertyValue("FileName",data.name);
          load->execute();
          if (load->isExecuted())
          {
            API::Workspace_sptr rws = load->getProperty("OutputWorkspace");
            if (rws)
            {
              DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(rws);
              if (ws) 
              {
                out.ws = ws;
              }
              else
              {
                API::WorkspaceGroup_sptr gws = boost::dynamic_pointer_cast<API::WorkspaceGroup>(rws);
                if (gws)
                {
                  std::vector<std::string> wsNames = gws->getNames();
                  std::string propName = "OUTPUTWORKSPACE_" + boost::lexical_cast<std::string>(data.period);
                  if (load->existsProperty(propName))
                  {
                    Workspace_sptr rws1 = load->getProperty(propName);
                    out.ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(rws1);
                  }
                }
              }
            }
          }
        }
        catch(std::exception& e)
        {
          g_log.error(e.what());
          return data;
        }
      }

      if (!out.ws) return data;

      API::Axis* axis = out.ws->getAxis(1);
      if (axis->isSpectra())
      {// spectra axis
        if (out.spec < 0)
        {
          if (out.i >= 0)
          {
            out.spec = axis->spectraNo(out.i);
          }
          else
          {// i < 0 && spec < 0 => use start and end
            for(size_t i=0;i<axis->length();++i)
            {
              double s = double(axis->spectraNo(i));
              if (s >= out.start && s <= out.end)
              {
                out.indx.push_back(static_cast<int>(i));
              }
            }
          }
        }
        else
        {
          for(size_t i=0;i<axis->length();++i)
          {
            int j = axis->spectraNo(i);
            if (j == out.spec)
            {
              out.i = static_cast<int>(i);
              break;
            }
          }
        }
        if (out.i < 0 && out.indx.empty())
        {
          return data;
        }
      }
      else
      {// numeric axis
        out.spec = -1;
        if (out.i >= 0)
        {
          out.indx.clear();
        }
        else
        {
          if (out.i < -1)
          {
            out.start = (*axis)(0);
            out.end = (*axis)(axis->length()-1);
          }
          for(size_t i=0;i<axis->length();++i)
          {
            double s = (*axis)(i);
            if (s >= out.start && s <= out.end)
            {
              out.indx.push_back(static_cast<int>(i));
            }
          }
        }
      }

      return out;
    }
Exemple #9
0
/// Execute the algorithm
void SassenaFFT::exec()
{
  const std::string gwsName = this->getPropertyValue("InputWorkspace");
  API::WorkspaceGroup_sptr gws = this->getProperty("InputWorkspace");

  const std::string ftqReName = gwsName + "_fqt.Re";
  const std::string ftqImName = gwsName + "_fqt.Im";

  // Make sure the intermediate structure factor is there
  if(!gws->contains(ftqReName) )
  {
    const std::string errMessg = "workspace "+gwsName+" does not contain an intermediate structure factor";
    this->g_log.error(errMessg);
    throw Kernel::Exception::NotFoundError("group workspace does not contain",ftqReName);
  }

  // Retrieve the real and imaginary parts of the intermediate scattering function
  DataObjects::Workspace2D_sptr fqtRe = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( gws->getItem( ftqReName ) );
  DataObjects::Workspace2D_sptr fqtIm = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( gws->getItem( ftqImName ) );

  // Calculate the FFT for all spectra, retaining only the real part since F(q,-t) = F*(q,t)
  int part=3; // extract the real part of the transform, assuming I(Q,t) is real
  const std::string sqwName = gwsName + "_sqw";
  API::IAlgorithm_sptr fft = this->createChildAlgorithm("ExtractFFTSpectrum");
  fft->setProperty<DataObjects::Workspace2D_sptr>("InputWorkspace", fqtRe);
  if( !this->getProperty("FFTonlyRealPart") )
  {
    part=0; // extract the real part of the transform, assuming I(Q,t) is complex
    fft->setProperty<DataObjects::Workspace2D_sptr>("InputImagWorkspace", fqtIm);
  }
  fft->setPropertyValue("OutputWorkspace", sqwName );
  fft->setProperty<int>("FFTPart",part); // extract the real part
  fft->executeAsChildAlg();
  API::MatrixWorkspace_sptr sqw0 = fft->getProperty("OutputWorkspace");
  DataObjects::Workspace2D_sptr sqw = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( sqw0 );
  API::AnalysisDataService::Instance().addOrReplace( sqwName, sqw );

  // Transform the X-axis to appropriate dimensions
  // We assume the units of the intermediate scattering function are in picoseconds
  // The resulting frequency unit is in mili-eV, thus use m_ps2meV
  API::IAlgorithm_sptr scaleX = this->createChildAlgorithm("ScaleX");
  scaleX->setProperty<DataObjects::Workspace2D_sptr>("InputWorkspace",sqw);
  scaleX->setProperty<double>("Factor", m_ps2meV);
  scaleX->setProperty<DataObjects::Workspace2D_sptr>("OutputWorkspace", sqw);
  scaleX->executeAsChildAlg();

  //Do we apply the detailed balance condition exp(E/(2*kT)) ?
  if( this->getProperty("DetailedBalance") )
  {
    double T = this->getProperty("Temp");
    // The ExponentialCorrection algorithm assumes the form C0*exp(-C1*x). Note the explicit minus in the exponent
    API::IAlgorithm_sptr ec = this->createChildAlgorithm("ExponentialCorrection");
    ec->setProperty<DataObjects::Workspace2D_sptr>("InputWorkspace", sqw);
    ec->setProperty<DataObjects::Workspace2D_sptr>("OutputWorkspace", sqw);
    ec->setProperty<double>("C0",1.0);
    ec->setProperty<double>("C1",-1.0/(2.0*T*m_T2ueV)); // Temperature in units of ueV
    ec->setPropertyValue("Operation","Multiply");
    ec->executeAsChildAlg();
  }

  // Set the Energy unit for the X-axis
  sqw->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("DeltaE");

  // Add to group workspace, except if we are replacing the workspace. In this case, the group workspace
  // is already notified of the changes by the analysis data service.
  if(!gws->contains(sqwName))
  {
    gws->add( sqwName );
  }
  else
  {
    this->g_log.information("Workspace "+sqwName+" replaced with new contents");
  }

}