Example #1
0
/**
 * Redraws mini plots when user changes previw range or spectrum.
 *
 * @param prop QtProperty that was changed
 * @param value Value it was changed to
 */
void IndirectSymmetrise::replotNewSpectrum(QtProperty *prop, double value) {
  // Validate the preview spectra
  if (prop == m_properties["PreviewSpec"]) {
    // Get the range of possible spectra numbers
    QString workspaceName = m_uiForm.dsInput->getCurrentDataName();
    MatrixWorkspace_sptr sampleWS =
        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
            workspaceName.toStdString());
    int minSpectrumRange = sampleWS->getSpectrum(0).getSpectrumNo();
    int maxSpectrumRange =
        sampleWS->getSpectrum(sampleWS->getNumberHistograms() - 1)
            .getSpectrumNo();

    // If entered value is lower then set spectra number to lowest valid value
    if (value < minSpectrumRange) {
      m_dblManager->setValue(m_properties["PreviewSpec"], minSpectrumRange);
      return;
    }

    // If entered value is higer then set spectra number to highest valid value
    if (value > maxSpectrumRange) {
      m_dblManager->setValue(m_properties["PreviewSpec"], maxSpectrumRange);
      return;
    }
  }

  // If we get this far then properties are valid so update mini plots
  if (prop == m_properties["PreviewSpec"])
    updateMiniPlots();
}
Example #2
0
  /**
   * Determine the min and max x-values for each spectrum and error check the pairs.
   *
   * @param inputWS The workspace to check the numbers for.
   * @param xmins The input/output that will hold the x-mins.
   * @param xmaxs The input/output that will hold the x-maxs.
   *
   * @return Any error messages generated during the execution. If empty everything
   * went according to plan.
   */
  string determineXMinMax(MatrixWorkspace_sptr inputWS,
                          vector<double>& xmins, vector<double>& xmaxs)
  {
    bool updateXMins = xmins.empty(); // they weren't set
    bool updateXMaxs = xmaxs.empty(); // they weren't set

    stringstream msg;

    size_t numSpectra = inputWS->getNumberHistograms();
    for (size_t i=0; i < numSpectra; ++i)
    {
      // determine ranges if necessary
      if (updateXMins || updateXMaxs) {
        const MantidVec& xvalues = inputWS->getSpectrum(i)->dataX();
        if (updateXMins)
          xmins.push_back(xvalues.front());
        if (updateXMaxs)
          xmaxs.push_back(xvalues.back());
      }

      // error check the ranges
      if (xmins[i] >= xmaxs[i])
      {
        if (!msg.str().empty())
          msg << ", ";
        msg << "at wksp_index=" << i << " XMin >= XMax ("
            << xmins[i] << " >= " << xmaxs[i] << ")";
      }
    }

    return msg.str(); // empty string means nothing went wrong
  }
MatrixWorkspace_sptr
ImggFormatsConvertViewQtWidget::loadImg(const std::string &inputName,
                                        const std::string &inFormat) const {

  QImage img = loadImgFile(inputName, inFormat);
  int width = img.width();
  int height = img.height();

  MatrixWorkspace_sptr imgWks = boost::dynamic_pointer_cast<MatrixWorkspace>(
      WorkspaceFactory::Instance().create("Workspace2D", height, width + 1,
                                          width));
  imgWks->setTitle(inputName);
  const double scaleFactor = std::numeric_limits<unsigned char>::max();
  for (int yi = 0; yi < static_cast<int>(width); ++yi) {
    auto &row = imgWks->getSpectrum(yi);
    auto &dataY = row.dataY();
    auto &dataX = row.dataX();
    std::fill(dataX.begin(), dataX.end(), static_cast<double>(yi));
    for (int xi = 0; xi < static_cast<int>(width); ++xi) {
      QRgb vRgb = img.pixel(xi, yi);
      dataY[xi] = scaleFactor * qGray(vRgb);
    }
  }

  return imgWks;
}
Example #4
0
/**
 * Plots a new workspace in the mini plot when it is loaded form the data
 *selector.
 *
 * @param workspaceName Name of the workspace that has been laoded
 */
void IndirectSymmetrise::plotRawInput(const QString &workspaceName) {
  // Set the preview spectrum number to the first spectrum in the workspace
  MatrixWorkspace_sptr sampleWS =
      AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
          workspaceName.toStdString());
  int minSpectrumRange = sampleWS->getSpectrum(0).getSpectrumNo();
  m_dblManager->setValue(m_properties["PreviewSpec"],
                         static_cast<double>(minSpectrumRange));

  updateMiniPlots();

  // Set the preview range to the maximum absolute X value
  QPair<double, double> axisRange = m_uiForm.ppRawPlot->getCurveRange("Raw");
  double symmRange = std::max(fabs(axisRange.first), fabs(axisRange.second));

  // Set valid range for range selectors
  m_uiForm.ppRawPlot->getRangeSelector("NegativeE")->setRange(-symmRange, 0);
  m_uiForm.ppRawPlot->getRangeSelector("PositiveE")->setRange(0, symmRange);

  // Set some default (and valid) values for E range
  m_dblManager->setValue(m_properties["EMax"], axisRange.second);
  m_dblManager->setValue(m_properties["EMin"], axisRange.second / 10);

  updateMiniPlots();
}
Example #5
0
/** Converts an EventWorkspace to an equivalent Workspace2D
 * @param inputMatrixW :: input event workspace
 * @return a MatrixWorkspace_sptr
 */
MatrixWorkspace_sptr
EventWorkspaceHelpers::convertEventTo2D(MatrixWorkspace_sptr inputMatrixW) {
  EventWorkspace_sptr inputW =
      boost::dynamic_pointer_cast<EventWorkspace>(inputMatrixW);
  if (!inputW)
    throw std::invalid_argument("EventWorkspaceHelpers::convertEventTo2D(): "
                                "Input workspace is not an EventWorkspace.");

  size_t numBins = inputW->blocksize();

  // Make a workspace 2D version of it
  MatrixWorkspace_sptr outputW;
  outputW = WorkspaceFactory::Instance().create(
      "Workspace2D", inputW->getNumberHistograms(), numBins + 1, numBins);
  WorkspaceFactory::Instance().initializeFromParent(inputW, outputW, false);

  // Now let's set all the X bins and values
  for (size_t i = 0; i < inputW->getNumberHistograms(); i++) {
    outputW->getSpectrum(i).copyInfoFrom(inputW->getSpectrum(i));
    outputW->setX(i, inputW->refX(i));

    MantidVec &Yout = outputW->dataY(i);
    const MantidVec &Yin = inputW->readY(i);
    for (size_t j = 0; j < numBins; j++)
      Yout[j] = Yin[j];

    MantidVec &Eout = outputW->dataE(i);
    const MantidVec &Ein = inputW->readE(i);
    for (size_t j = 0; j < numBins; j++)
      Eout[j] = Ein[j];
  }

  return outputW;
}
Example #6
0
    /**
     * Execute the algorithm
     */
    void ExtractMasking::exec()
    {
      MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");

      const int nHist = static_cast<int>(inputWS->getNumberHistograms());
      const int xLength(1), yLength(1);
      // Create a new workspace for the results, copy from the input to ensure that we copy over the instrument and current masking
      MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(inputWS, nHist, xLength, yLength);

      Progress prog(this,0.0,1.0,nHist);
      MantidVecPtr xValues;
      xValues.access() = MantidVec(1, 0.0);

      PARALLEL_FOR2(inputWS, outputWS)
      for( int i = 0; i < nHist; ++i )
      {
        PARALLEL_START_INTERUPT_REGION
        // Spectrum in the output workspace
        ISpectrum * outSpec = outputWS->getSpectrum(i);
        // Spectrum in the input workspace
        const ISpectrum * inSpec = inputWS->getSpectrum(i);

        // Copy X, spectrum number and detector IDs
        outSpec->setX(xValues);
        outSpec->copyInfoFrom(*inSpec);

        IDetector_const_sptr inputDet;
        bool inputIsMasked(false);
        try
        {
          inputDet = inputWS->getDetector(i);
          if( inputDet->isMasked() )
          {
            inputIsMasked = true;
          }
        }
        catch(Kernel::Exception::NotFoundError &)
        {
          inputIsMasked = false;
        }

        if( inputIsMasked )
        {
          outSpec->dataY()[0] = 0.0;
          outSpec->dataE()[0] = 0.0;
        }
        else
        {
          outSpec->dataY()[0] = 1.0;
          outSpec->dataE()[0] = 1.0;
        }
        prog.report();

        PARALLEL_END_INTERUPT_REGION
      }
      PARALLEL_CHECK_INTERUPT_REGION

      setProperty("OutputWorkspace", outputWS);
    }
Example #7
0
/** Initialise a workspace from its parent
 * This sets values such as title, instrument, units, sample, spectramap.
 * This does NOT copy any data.
 *
 * @param parent :: the parent workspace
 * @param child :: the child workspace
 * @param differentSize :: A flag to indicate if the two workspace will be different sizes
 */
void WorkspaceFactoryImpl::initializeFromParent(const MatrixWorkspace_const_sptr parent,
  const MatrixWorkspace_sptr child, const bool differentSize) const
{
  child->setTitle(parent->getTitle());
  child->setComment(parent->getComment());
  child->setInstrument(parent->getInstrument());  // This call also copies the SHARED POINTER to the parameter map
  // This call will (should) perform a COPY of the parameter map.
  child->instrumentParameters();
  child->m_sample = parent->m_sample;
  child->m_run = parent->m_run;
  child->setYUnit(parent->m_YUnit);
  child->setYUnitLabel(parent->m_YUnitLabel);
  child->isDistribution(parent->isDistribution());

  // Only copy the axes over if new sizes are not given
  if ( !differentSize )
  {
    // Only copy mask map if same size for now. Later will need to check continued validity.
    child->m_masks = parent->m_masks;
  }

  // Same number of histograms = copy over the spectra data
  if (parent->getNumberHistograms() == child->getNumberHistograms())
  {
    for (size_t wi=0; wi<parent->getNumberHistograms(); wi++)
    {
      ISpectrum * childSpec = child->getSpectrum(wi);
      const ISpectrum * parentSpec = parent->getSpectrum(wi);
      // Copy spectrum number and detector IDs
      childSpec->copyInfoFrom(*parentSpec);
    }
  }

  // deal with axis
  for (size_t i = 0; i < parent->m_axes.size(); ++i)
  {
    const size_t newAxisLength = child->getAxis(i)->length();
    const size_t oldAxisLength = parent->getAxis(i)->length();

    if ( !differentSize || newAxisLength == oldAxisLength )
    {
      // Need to delete the existing axis created in init above
      delete child->m_axes[i];
      // Now set to a copy of the parent workspace's axis
      child->m_axes[i] = parent->m_axes[i]->clone(child.get());
    }
    else
    {
      if (! parent->getAxis(i)->isSpectra()) // WHY???
      {
        delete child->m_axes[i];
        // Call the 'different length' clone variant
        child->m_axes[i] = parent->m_axes[i]->clone(newAxisLength,child.get());
      }
    }
  }

  return;
}
Example #8
0
/** Creates the output workspace, its size, units, etc.
*  @param binParams the bin boundary specification using the same same syntax as param the Rebin algorithm
*  @return A pointer to the newly-created workspace
*/
API::MatrixWorkspace_sptr Q1D2::setUpOutputWorkspace(const std::vector<double> & binParams) const
{
  // Calculate the output binning
  MantidVecPtr XOut;
  size_t sizeOut = static_cast<size_t>(
    VectorHelper::createAxisFromRebinParams(binParams, XOut.access()));

  // Now create the output workspace
  MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(m_dataWS,1,sizeOut,sizeOut-1);
  outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("MomentumTransfer");
  outputWS->setYUnitLabel("1/cm");

  // Set the X vector for the output workspace
  outputWS->setX(0, XOut);
  outputWS->isDistribution(true);

  outputWS->getSpectrum(0)->clearDetectorIDs();
  outputWS->getSpectrum(0)->setSpectrumNo(1);

  return outputWS;
}
Example #9
0
/**
 * Groups the workspace according to grouping provided.
 *
 * @param ws :: Workspace to group
 * @param  g :: The grouping information
 * @return Sptr to created grouped workspace
 */
MatrixWorkspace_sptr groupWorkspace(MatrixWorkspace_const_sptr ws, const Grouping& g)
{
  // As I couldn't specify multiple groups for GroupDetectors, I am going down quite a complicated
  // route - for every group distinct grouped workspace is created using GroupDetectors. These
  // workspaces are then merged into the output workspace.

  // Create output workspace
  MatrixWorkspace_sptr outWs =
    WorkspaceFactory::Instance().create(ws, g.groups.size(), ws->readX(0).size(), ws->blocksize());

  for(size_t gi = 0; gi < g.groups.size(); gi++)
  {
    Mantid::API::IAlgorithm_sptr alg = AlgorithmManager::Instance().create("GroupDetectors");
    alg->setChild(true); // So Output workspace is not added to the ADS
    alg->initialize();
    alg->setProperty("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(ws));
    alg->setPropertyValue("SpectraList", g.groups[gi]);
    alg->setPropertyValue("OutputWorkspace", "grouped"); // Is not actually used, just to make validators happy
    alg->execute();

    MatrixWorkspace_sptr grouped = alg->getProperty("OutputWorkspace");

    // Copy the spectrum
    *(outWs->getSpectrum(gi)) = *(grouped->getSpectrum(0));

    // Update spectrum number
    outWs->getSpectrum(gi)->setSpectrumNo(static_cast<specid_t>(gi));

    // Copy to the output workspace
    outWs->dataY(gi) = grouped->readY(0);
    outWs->dataX(gi) = grouped->readX(0);
    outWs->dataE(gi) = grouped->readE(0);
  }

  return outWs;
}
Example #10
0
MatrixWorkspace_sptr
CreateFloodWorkspace::scaleToCentralPixel(MatrixWorkspace_sptr ws) {
  int const centralSpectrum = getProperty(Prop::CENTRAL_PIXEL);
  auto const nHisto = static_cast<int>(ws->getNumberHistograms());
  if (centralSpectrum >= nHisto) {
    throw std::invalid_argument(
        "Spectrum index " + std::to_string(centralSpectrum) +
        " passed to property " + Prop::CENTRAL_PIXEL +
        " is outside the range 0-" + std::to_string(nHisto - 1));
  }
  auto const spectraMap = ws->getSpectrumToWorkspaceIndexMap();
  auto const centralIndex = spectraMap.at(centralSpectrum);
  auto const scaleFactor = ws->y(centralIndex).front();
  g_log.information() << "Scale to central pixel, factor = " << scaleFactor
                      << '\n';
  if (scaleFactor <= 0.0) {
    throw std::runtime_error("Scale factor muhst be > 0, found " +
                             std::to_string(scaleFactor));
  }
  auto const axis = ws->getAxis(1);
  auto const sa = dynamic_cast<const SpectraAxis *>(axis);
  double const startX =
      isDefault(Prop::START_X) ? sa->getMin() : getProperty(Prop::START_X);
  double const endX =
      isDefault(Prop::END_X) ? sa->getMax() : getProperty(Prop::END_X);
  PARALLEL_FOR_IF(Kernel::threadSafe(*ws))
  for (int i = 0; i < nHisto; ++i) {
    PARALLEL_START_INTERUPT_REGION
    auto const spec = ws->getSpectrum(i).getSpectrumNo();
    if (isExcludedSpectrum(spec)) {
      ws->mutableY(i)[0] = VERY_BIG_VALUE;
      ws->mutableE(i)[0] = 0.0;
    } else if (spec >= startX && spec <= endX) {
      ws->mutableY(i)[0] /= scaleFactor;
      ws->mutableE(i)[0] /= scaleFactor;
    } else {
      ws->mutableY(i)[0] = 1.0;
      ws->mutableE(i)[0] = 0.0;
    }
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION
  return ws;
}
void ConvertToMatrixWorkspace::exec()
{
  MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
  // Let's see if we have to do anything first. Basically we want to avoid the data copy if we can
  DataObjects::EventWorkspace_const_sptr eventW = 
    boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>(inputWorkspace);
  MatrixWorkspace_sptr outputWorkspace;
  if( eventW )
  {
    g_log.information() << "Converting EventWorkspace to Workspace2D.\n";

    const size_t numHists = inputWorkspace->getNumberHistograms();
    Progress prog(this,0.0,1.0,numHists*2);

    // Sort the input workspace in-place by TOF. This can be faster if there are few event lists.
    eventW->sortAll(TOF_SORT, &prog);

    // Create the output workspace. This will copy many aspects fron the input one.
    outputWorkspace = WorkspaceFactory::Instance().create(inputWorkspace);

    // ...but not the data, so do that here.
    PARALLEL_FOR2(inputWorkspace,outputWorkspace)
    for (int64_t i = 0; i < (int64_t)numHists; ++i)
    {
      PARALLEL_START_INTERUPT_REGION
      const ISpectrum * inSpec = inputWorkspace->getSpectrum(i);
      ISpectrum * outSpec = outputWorkspace->getSpectrum(i);

      outSpec->copyInfoFrom(*inSpec);
      outSpec->setX(inSpec->ptrX());
      outSpec->dataY() = inSpec->dataY();
      outSpec->dataE() = inSpec->dataE();
      
      prog.report("Binning");

      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    outputWorkspace->generateSpectraMap();
  }
  else
  {
Example #12
0
/** Create the final output workspace after converting the X axis
* @returns the final output workspace
*
* @param progress :: Progress indicator
* @param targetUnit :: Target conversion unit
* @param inputWS :: Input workspace
* @param nHist :: Stores the number of histograms
*/
MatrixWorkspace_sptr ConvertSpectrumAxis2::createOutputWorkspace(
    API::Progress &progress, const std::string &targetUnit,
    API::MatrixWorkspace_sptr &inputWS, size_t nHist) {
  // Create the output workspace. Can not re-use the input one because the
  // spectra are re-ordered.
  MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
      inputWS, m_indexMap.size(), inputWS->x(0).size(), inputWS->y(0).size());

  // Now set up a new numeric axis holding the theta values corresponding to
  // each spectrum.
  auto const newAxis = new NumericAxis(m_indexMap.size());
  outputWorkspace->replaceAxis(1, newAxis);

  progress.setNumSteps(nHist + m_indexMap.size());

  // Set the units of the axis.
  if (targetUnit == "theta" || targetUnit == "Theta" ||
      targetUnit == "signed_theta" || targetUnit == "SignedTheta") {
    newAxis->unit() = boost::make_shared<Units::Degrees>();
  } else if (targetUnit == "ElasticQ") {
    newAxis->unit() = UnitFactory::Instance().create("MomentumTransfer");
  } else if (targetUnit == "ElasticQSquared") {
    newAxis->unit() = UnitFactory::Instance().create("QSquared");
  }

  std::multimap<double, size_t>::const_iterator it;
  size_t currentIndex = 0;
  for (it = m_indexMap.begin(); it != m_indexMap.end(); ++it) {
    // Set the axis value.
    newAxis->setValue(currentIndex, it->first);
    // Copy over the data.
    outputWorkspace->setHistogram(currentIndex, inputWS->histogram(it->second));
    // We can keep the spectrum numbers etc.
    outputWorkspace->getSpectrum(currentIndex)
        .copyInfoFrom(inputWS->getSpectrum(it->second));
    ++currentIndex;

    progress.report("Creating output workspace...");
  }
  return outputWorkspace;
}
/**
 * Construct an "empty" output workspace in virtual-lambda for summation in Q.
 * The workspace will have the same x values as the input workspace but the y
 * values will all be zero.
 *
 * @return : a 1D workspace where y values are all zero
 */
MatrixWorkspace_sptr
ReflectometryReductionOne2::constructIvsLamWS(MatrixWorkspace_sptr detectorWS) {

  // There is one output spectrum for each detector group
  const size_t numGroups = detectorGroups().size();
  // Calculate the number of bins based on the min/max wavelength, using
  // the same bin width as the input workspace
  const double binWidth = (detectorWS->x(0).back() - detectorWS->x(0).front()) /
                          static_cast<double>(detectorWS->blocksize());
  const int numBins = static_cast<int>(
      std::ceil((wavelengthMax() - wavelengthMin()) / binWidth));
  // Construct the histogram with these X values. Y and E values are zero.
  const BinEdges xValues(numBins, LinearGenerator(wavelengthMin(), binWidth));
  // Create the output workspace
  MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(
      detectorWS, numGroups, numBins, numBins - 1);

  // Loop through each detector group in the input
  for (size_t groupIdx = 0; groupIdx < numGroups; ++groupIdx) {
    // Get the detectors in this group
    auto &detectors = detectorGroups()[groupIdx];
    // Set the x values for this spectrum
    outputWS->setBinEdges(groupIdx, xValues);
    // Set the detector ID from the twoThetaR detector.
    const size_t twoThetaRIdx = twoThetaRDetectorIdx(detectors);
    auto &outSpec = outputWS->getSpectrum(groupIdx);
    const detid_t twoThetaRDetID =
        m_spectrumInfo->detector(twoThetaRIdx).getID();
    outSpec.clearDetectorIDs();
    outSpec.addDetectorID(twoThetaRDetID);
    // Set the spectrum number from the twoThetaR detector
    SpectrumNumber specNum =
        detectorWS->indexInfo().spectrumNumber(twoThetaRIdx);
    auto indexInf = outputWS->indexInfo();
    indexInf.setSpectrumNumbers(specNum, specNum);
    outputWS->setIndexInfo(indexInf);
  }

  return outputWS;
}
/**
 * Performs asymmetry calculation on the given workspace using indices 0,1.
 * @param inputWS :: [input] Workspace to calculate asymmetry from (will use
 * workspace indices 0,1).
 * @returns MatrixWorkspace containing result of the calculation.
 */
MatrixWorkspace_sptr
MuonPairingAsymmetry::pairAsymmetryCalc(MatrixWorkspace_sptr inputWS,
                                        const double &alpha) {
  MatrixWorkspace_sptr outWS;

  // Ensure our specified spectra definitely point to the data
  inputWS->getSpectrum(0).setSpectrumNo(0);
  inputWS->getSpectrum(1).setSpectrumNo(1);
  const std::vector<int> fwdSpectra = {0};
  const std::vector<int> bwdSpectra = {1};

  IAlgorithm_sptr alg = this->createChildAlgorithm("AsymmetryCalc");
  alg->setProperty("InputWorkspace", inputWS);
  alg->setProperty("ForwardSpectra", fwdSpectra);
  alg->setProperty("BackwardSpectra", bwdSpectra);
  alg->setProperty("Alpha", alpha);
  alg->setProperty("OutputWorkspace", "__NotUsed__");
  alg->execute();
  outWS = alg->getProperty("OutputWorkspace");

  return outWS;
}
Example #15
0
/** Build the instrument/detector setup in workspace
 */
void SmoothNeighbours::setupNewInstrument(MatrixWorkspace_sptr outws) {
  // Copy geometry over.
  API::WorkspaceFactory::Instance().initializeFromParent(*inWS, *outws, false);

  // Go through all the output workspace
  size_t numberOfSpectra = outws->getNumberHistograms();

  for (int outWIi = 0; outWIi < int(numberOfSpectra); outWIi++) {
    auto &outSpec = outws->getSpectrum(outWIi);

    // Reset detectors
    outSpec.clearDetectorIDs();

    // Which are the neighbours?
    for (const auto &neighbor : m_neighbours[outWIi]) {
      const auto &inSpec = inWS->getSpectrum(neighbor.first);
      outSpec.addDetectorIDs(inSpec.getDetectorIDs());
    }
  }

  return;
}
Example #16
0
/**
 * Sets a new preview spectrum for the mini plot.
 *
 * @param value workspace index
 */
void ResNorm::previewSpecChanged(int value) {
  m_previewSpec = value;

  // Update vanadium plot
  if (m_uiForm.dsVanadium->isValid())
    m_uiForm.ppPlot->addSpectrum(
        "Vanadium", m_uiForm.dsVanadium->getCurrentDataName(), m_previewSpec);

  // Update fit plot
  std::string fitWsGroupName(m_pythonExportWsName + "_Fit_Workspaces");
  std::string fitParamsName(m_pythonExportWsName + "_Fit");
  if (AnalysisDataService::Instance().doesExist(fitWsGroupName)) {
    WorkspaceGroup_sptr fitWorkspaces =
        AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
            fitWsGroupName);
    ITableWorkspace_sptr fitParams =
        AnalysisDataService::Instance().retrieveWS<ITableWorkspace>(
            fitParamsName);
    if (fitWorkspaces && fitParams) {
      Column_const_sptr scaleFactors = fitParams->getColumn("Scaling");
      std::string fitWsName(fitWorkspaces->getItem(m_previewSpec)->name());
      MatrixWorkspace_const_sptr fitWs =
          AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
              fitWsName);

      MatrixWorkspace_sptr fit = WorkspaceFactory::Instance().create(fitWs, 1);
      fit->setX(0, fitWs->readX(1));
      fit->getSpectrum(0)->setData(fitWs->readY(1), fitWs->readE(1));

      for (size_t i = 0; i < fit->blocksize(); i++)
        fit->dataY(0)[i] /= scaleFactors->cell<double>(m_previewSpec);

      m_uiForm.ppPlot->addSpectrum("Fit", fit, 0, Qt::red);
    }
  }
}
Example #17
0
/** Executes the algorithm
 *  @throw Exception::FileError If the calibration file cannot be opened and read successfully
 *  @throw Exception::InstrumentDefinitionError If unable to obtain the source-sample distance
 */
void AlignDetectors::exec()
{
    // Get the input workspace
    MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");

    // Read in the calibration data
    const std::string calFileName = getProperty("CalibrationFile");
    OffsetsWorkspace_sptr offsetsWS = getProperty("OffsetsWorkspace");

    progress(0.0,"Reading calibration file");
    if (offsetsWS && !calFileName.empty())
        throw std::invalid_argument("You must specify either CalibrationFile or OffsetsWorkspace but not both.");
    if (!offsetsWS && calFileName.empty())
        throw std::invalid_argument("You must specify either CalibrationFile or OffsetsWorkspace.");

    if (!calFileName.empty())
    {
        // Load the .cal file
        IAlgorithm_sptr alg = createChildAlgorithm("LoadCalFile");
        alg->setPropertyValue("CalFilename", calFileName);
        alg->setProperty("InputWorkspace", inputWS);
        alg->setProperty<bool>("MakeGroupingWorkspace", false);
        alg->setProperty<bool>("MakeOffsetsWorkspace", true);
        alg->setProperty<bool>("MakeMaskWorkspace", false);
        alg->setPropertyValue("WorkspaceName", "temp");
        alg->executeAsChildAlg();
        offsetsWS = alg->getProperty("OutputOffsetsWorkspace");
    }

    const int64_t numberOfSpectra = inputWS->getNumberHistograms();

    // generate map of the tof->d conversion factors
    this->tofToDmap = calcTofToD_ConversionMap(inputWS, offsetsWS);

    //Check if its an event workspace
    EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
    if (eventW != NULL)
    {
        this->execEvent();
        return;
    }

    API::MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
    // If input and output workspaces are not the same, create a new workspace for the output
    if (outputWS != inputWS )
    {
        outputWS = WorkspaceFactory::Instance().create(inputWS);
        setProperty("OutputWorkspace",outputWS);
    }

    // Set the final unit that our output workspace will have
    outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("dSpacing");

    // Initialise the progress reporting object
    Progress progress(this,0.0,1.0,numberOfSpectra);

    // Loop over the histograms (detector spectra)
    PARALLEL_FOR2(inputWS,outputWS)
    for (int64_t i = 0; i < int64_t(numberOfSpectra); ++i)
    {
        PARALLEL_START_INTERUPT_REGION
        try {
            // Get the input spectrum number at this workspace index
            const ISpectrum * inSpec = inputWS->getSpectrum(size_t(i));
            const double factor = calcConversionFromMap(this->tofToDmap, inSpec->getDetectorIDs());

            // Get references to the x data
            MantidVec& xOut = outputWS->dataX(i);

            // Make sure reference to input X vector is obtained after output one because in the case
            // where the input & output workspaces are the same, it might move if the vectors were shared.
            const MantidVec& xIn = inSpec->readX();

            //std::transform( xIn.begin(), xIn.end(), xOut.begin(), std::bind2nd(std::multiplies<double>(), factor) );
            // the above transform creates wrong output in parallel in debug in Visual Studio
            for(size_t k = 0; k < xOut.size(); ++k)
            {
                xOut[k] = xIn[k] * factor;
            }

            // Copy the Y&E data
            outputWS->dataY(i) = inSpec->readY();
            outputWS->dataE(i) = inSpec->readE();

        } catch (Exception::NotFoundError &) {
            // Zero the data in this case
            outputWS->dataX(i).assign(outputWS->readX(i).size(),0.0);
            outputWS->dataY(i).assign(outputWS->readY(i).size(),0.0);
            outputWS->dataE(i).assign(outputWS->readE(i).size(),0.0);
        }
        progress.report();
        PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

}
Example #18
0
/** Executes the algorithm
 *
 *  @throw runtime_error Thrown if algorithm cannot execute
 */
void MaxMin::exec()
{
  // Try and retrieve the optional properties
  m_MinRange = getProperty("RangeLower");
  m_MaxRange = getProperty("RangeUpper");
  m_MinSpec = getProperty("StartWorkspaceIndex");
  m_MaxSpec = getProperty("EndWorkspaceIndex");
  showMin = getProperty("ShowMin");

  // Get the input workspace
  MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");

  const int numberOfSpectra = static_cast<int>(localworkspace->getNumberHistograms());

  // Check 'StartSpectrum' is in range 0-numberOfSpectra
  if ( m_MinSpec > numberOfSpectra )
  {
    g_log.warning("StartSpectrum out of range! Set to 0.");
    m_MinSpec = 0;
  }
  if ( isEmpty(m_MaxSpec) ) m_MaxSpec = numberOfSpectra-1;
  if ( m_MaxSpec > numberOfSpectra-1 || m_MaxSpec < m_MinSpec )
  {
    g_log.warning("EndSpectrum out of range! Set to max detector number");
    m_MaxSpec = numberOfSpectra;
  }
  if ( m_MinRange > m_MaxRange )
  {
    g_log.warning("Range_upper is less than Range_lower. Will integrate up to frame maximum.");
    m_MaxRange = 0.0;
  }

  // Create the 1D workspace for the output
  MatrixWorkspace_sptr outputWorkspace = API::WorkspaceFactory::Instance().create(localworkspace,m_MaxSpec-m_MinSpec+1,2,1);


  Progress progress(this,0,1,(m_MaxSpec-m_MinSpec+1));
  PARALLEL_FOR2(localworkspace,outputWorkspace)
  // Loop over spectra
  for (int i = m_MinSpec; i <= m_MaxSpec; ++i)
  {
    PARALLEL_START_INTERUPT_REGION
    int newindex=i-m_MinSpec;
    // Copy over spectrum and detector number info
    outputWorkspace->getSpectrum(newindex)->copyInfoFrom(*localworkspace->getSpectrum(i));

    // Retrieve the spectrum into a vector
    const MantidVec& X = localworkspace->readX(i);
    const MantidVec& Y = localworkspace->readY(i);

    // Find the range [min,max]
    MantidVec::const_iterator lowit, highit;
    if (m_MinRange == EMPTY_DBL()) lowit=X.begin();
    else lowit=std::lower_bound(X.begin(),X.end(),m_MinRange);

    if (m_MaxRange == EMPTY_DBL()) highit=X.end();
    else highit=std::find_if(lowit,X.end(),std::bind2nd(std::greater<double>(),m_MaxRange));

    // If range specified doesn't overlap with this spectrum then bail out
    if ( lowit == X.end() || highit == X.begin() ) continue;

    --highit; // Upper limit is the bin before, i.e. the last value smaller than MaxRange

    MantidVec::difference_type distmin=std::distance(X.begin(),lowit);
    MantidVec::difference_type distmax=std::distance(X.begin(),highit);

    MantidVec::const_iterator maxY;
    // Find the max/min element
    if (showMin==true)
    {
      maxY=std::min_element(Y.begin()+distmin,Y.begin()+distmax);
    }
    else
    {
      maxY=std::max_element(Y.begin()+distmin,Y.begin()+distmax);
    }
    MantidVec::difference_type d=std::distance(Y.begin(),maxY);
    // X boundaries for the max/min element
    outputWorkspace->dataX(newindex)[0]=*(X.begin()+d);
    outputWorkspace->dataX(newindex)[1]=*(X.begin()+d+1); //This is safe since X is of dimension Y+1
    outputWorkspace->dataY(newindex)[0]=*maxY;
    progress.report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  // Assign it to the output workspace property
  setProperty("OutputWorkspace",outputWorkspace);

  return;
}
Example #19
0
void SofQWCentre::exec() {
  using namespace Geometry;

  MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");

  // Do the full check for common binning
  if (!WorkspaceHelpers::commonBoundaries(*inputWorkspace)) {
    g_log.error(
        "The input workspace must have common binning across all spectra");
    throw std::invalid_argument(
        "The input workspace must have common binning across all spectra");
  }

  std::vector<double> verticalAxis;
  MatrixWorkspace_sptr outputWorkspace = setUpOutputWorkspace(
      inputWorkspace, getProperty("QAxisBinning"), verticalAxis);
  setProperty("OutputWorkspace", outputWorkspace);

  // Holds the spectrum-detector mapping
  std::vector<specnum_t> specNumberMapping;
  std::vector<detid_t> detIDMapping;

  m_EmodeProperties.initCachedValues(*inputWorkspace, this);
  int emode = m_EmodeProperties.m_emode;

  // Get a pointer to the instrument contained in the workspace
  Instrument_const_sptr instrument = inputWorkspace->getInstrument();

  // Get the distance between the source and the sample (assume in metres)
  IComponent_const_sptr source = instrument->getSource();
  IComponent_const_sptr sample = instrument->getSample();
  V3D beamDir = sample->getPos() - source->getPos();
  beamDir.normalize();

  try {
    double l1 = source->getDistance(*sample);
    g_log.debug() << "Source-sample distance: " << l1 << '\n';
  } catch (Exception::NotFoundError &) {
    g_log.error("Unable to calculate source-sample distance");
    throw Exception::InstrumentDefinitionError(
        "Unable to calculate source-sample distance",
        inputWorkspace->getTitle());
  }

  // Conversion constant for E->k. k(A^-1) = sqrt(energyToK*E(meV))
  const double energyToK = 8.0 * M_PI * M_PI * PhysicalConstants::NeutronMass *
                           PhysicalConstants::meV * 1e-20 /
                           (PhysicalConstants::h * PhysicalConstants::h);

  // Loop over input workspace bins, reassigning data to correct bin in output
  // qw workspace
  const size_t numHists = inputWorkspace->getNumberHistograms();
  const size_t numBins = inputWorkspace->blocksize();
  Progress prog(this, 0.0, 1.0, numHists);
  for (int64_t i = 0; i < int64_t(numHists); ++i) {
    try {
      // Now get the detector object for this histogram
      IDetector_const_sptr spectrumDet = inputWorkspace->getDetector(i);
      if (spectrumDet->isMonitor())
        continue;

      const double efixed = m_EmodeProperties.getEFixed(*spectrumDet);

      // For inelastic scattering the simple relationship q=4*pi*sinTheta/lambda
      // does not hold. In order to
      // be completely general we must calculate the momentum transfer by
      // calculating the incident and final
      // wave vectors and then use |q| = sqrt[(ki - kf)*(ki - kf)]
      DetectorGroup_const_sptr detGroup =
          boost::dynamic_pointer_cast<const DetectorGroup>(spectrumDet);
      std::vector<IDetector_const_sptr> detectors;
      if (detGroup) {
        detectors = detGroup->getDetectors();
      } else {
        detectors.push_back(spectrumDet);
      }

      const size_t numDets = detectors.size();
      // cache to reduce number of static casts
      const double numDets_d = static_cast<double>(numDets);
      const auto &Y = inputWorkspace->y(i);
      const auto &E = inputWorkspace->e(i);
      const auto &X = inputWorkspace->x(i);

      // Loop over the detectors and for each bin calculate Q
      for (size_t idet = 0; idet < numDets; ++idet) {
        IDetector_const_sptr det = detectors[idet];
        // Calculate kf vector direction and then Q for each energy bin
        V3D scatterDir = (det->getPos() - sample->getPos());
        scatterDir.normalize();
        for (size_t j = 0; j < numBins; ++j) {
          const double deltaE = 0.5 * (X[j] + X[j + 1]);
          // Compute ki and kf wave vectors and therefore q = ki - kf
          double ei(0.0), ef(0.0);
          if (emode == 1) {
            ei = efixed;
            ef = efixed - deltaE;
            if (ef < 0) {
              std::string mess =
                  "Energy transfer requested in Direct mode exceeds incident "
                  "energy.\n Found for det ID: " +
                  std::to_string(idet) + " bin No " + std::to_string(j) +
                  " with Ei=" + boost::lexical_cast<std::string>(efixed) +
                  " and energy transfer: " +
                  boost::lexical_cast<std::string>(deltaE);
              throw std::runtime_error(mess);
            }
          } else {
            ei = efixed + deltaE;
            ef = efixed;
            if (ef < 0) {
              std::string mess =
                  "Incident energy of a neutron is negative. Are you trying to "
                  "process Direct data in Indirect mode?\n Found for det ID: " +
                  std::to_string(idet) + " bin No " + std::to_string(j) +
                  " with efied=" + boost::lexical_cast<std::string>(efixed) +
                  " and energy transfer: " +
                  boost::lexical_cast<std::string>(deltaE);
              throw std::runtime_error(mess);
            }
          }

          if (ei < 0)
            throw std::runtime_error(
                "Negative incident energy. Check binning.");

          const V3D ki = beamDir * sqrt(energyToK * ei);
          const V3D kf = scatterDir * (sqrt(energyToK * (ef)));
          const double q = (ki - kf).norm();

          // Test whether it's in range of the Q axis
          if (q < verticalAxis.front() || q > verticalAxis.back())
            continue;
          // Find which q bin this point lies in
          const MantidVec::difference_type qIndex =
              std::upper_bound(verticalAxis.begin(), verticalAxis.end(), q) -
              verticalAxis.begin() - 1;

          // Add this spectra-detector pair to the mapping
          specNumberMapping.push_back(
              outputWorkspace->getSpectrum(qIndex).getSpectrumNo());
          detIDMapping.push_back(det->getID());

          // And add the data and it's error to that bin, taking into account
          // the number of detectors contributing to this bin
          outputWorkspace->mutableY(qIndex)[j] += Y[j] / numDets_d;
          // Standard error on the average
          outputWorkspace->mutableE(qIndex)[j] =
              sqrt((pow(outputWorkspace->e(qIndex)[j], 2) + pow(E[j], 2)) /
                   numDets_d);
        }
      }

    } catch (Exception::NotFoundError &) {
      // Get to here if exception thrown when calculating distance to detector
      // Presumably, if we get to here the spectrum will be all zeroes anyway
      // (from conversion to E)
      continue;
    }
    prog.report();
  }

  // If the input workspace was a distribution, need to divide by q bin width
  if (inputWorkspace->isDistribution())
    this->makeDistribution(outputWorkspace, verticalAxis);

  // Set the output spectrum-detector mapping
  SpectrumDetectorMapping outputDetectorMap(specNumberMapping, detIDMapping);
  outputWorkspace->updateSpectraUsing(outputDetectorMap);

  // Replace any NaNs in outputWorkspace with zeroes
  if (this->getProperty("ReplaceNaNs")) {
    auto replaceNans = this->createChildAlgorithm("ReplaceSpecialValues");
    replaceNans->setChild(true);
    replaceNans->initialize();
    replaceNans->setProperty("InputWorkspace", outputWorkspace);
    replaceNans->setProperty("OutputWorkspace", outputWorkspace);
    replaceNans->setProperty("NaNValue", 0.0);
    replaceNans->setProperty("InfinityValue", 0.0);
    replaceNans->setProperty("BigNumberThreshold", DBL_MAX);
    replaceNans->execute();
  }
}
/** Calls Gaussian1D as a child algorithm to fit the offset peak in a spectrum
  *
  * @param wi :: The Workspace Index to fit.
  * @param inputW :: Input workspace.
  * @param peakPositions :: Peak positions.
  * @param fitWindows :: Fit windows.
  * @param nparams :: Number of parameters.
  * @param minD :: Min distance.
  * @param maxD :: Max distance.
  * @param peakPosToFit :: Actual peak positions to fit (output).
  * @param peakPosFitted :: Actual peak positions fitted (output).
  * @param chisq :: chisq.
  * @param peakHeights :: vector for fitted heights of peaks
  * @param i_highestpeak:: index of the highest peak among all peaks
  * @param resolution :: spectrum's resolution delta(d)/d
  * @param dev_resolution :: standard deviation resolution
  * @return The number of peaks in range
  */
int GetDetOffsetsMultiPeaks::fitSpectra(
    const int64_t wi, MatrixWorkspace_sptr inputW,
    const std::vector<double> &peakPositions,
    const std::vector<double> &fitWindows, size_t &nparams, double &minD,
    double &maxD, std::vector<double> &peakPosToFit,
    std::vector<double> &peakPosFitted, std::vector<double> &chisq,
    std::vector<double> &peakHeights, int &i_highestpeak, double &resolution,
    double &dev_resolution) {
  // Default overall fit range is the whole spectrum
  const MantidVec &X = inputW->readX(wi);
  minD = X.front();
  maxD = X.back();

  // Trim in the edges based on where the data turns off of zero
  const MantidVec &Y = inputW->readY(wi);
  size_t minDindex = 0;
  for (; minDindex < Y.size(); ++minDindex) {
    if (Y[minDindex] > 0.) {
      minD = X[minDindex];
      break;
    }
  }
  if (minD >= maxD) {
    // throw if minD >= maxD
    std::stringstream ess;
    ess << "Stuff went wrong with wkspIndex=" << wi
        << " specIndex=" << inputW->getSpectrum(wi)->getSpectrumNo();
    throw std::runtime_error(ess.str());
  }

  size_t maxDindex = Y.size() - 1;
  for (; maxDindex > minDindex; --maxDindex) {
    if (Y[maxDindex] > 0.) {
      maxD = X[maxDindex];
      break;
    }
  }
  std::stringstream dbss;
  dbss << "D-RANGE[" << inputW->getSpectrum(wi)->getSpectrumNo()
       << "]: " << minD << " -> " << maxD;
  g_log.debug(dbss.str());

  // Setup the fit windows
  bool useFitWindows = (!fitWindows.empty());
  std::vector<double> fitWindowsToUse;
  for (int i = 0; i < static_cast<int>(peakPositions.size()); ++i) {
    if ((peakPositions[i] > minD) && (peakPositions[i] < maxD)) {
      if (m_useFitWindowTable) {
        fitWindowsToUse.push_back(std::max(m_vecFitWindow[wi][2 * i], minD));
        fitWindowsToUse.push_back(
            std::min(m_vecFitWindow[wi][2 * i + 1], maxD));
      } else if (useFitWindows) {
        fitWindowsToUse.push_back(std::max(fitWindows[2 * i], minD));
        fitWindowsToUse.push_back(std::min(fitWindows[2 * i + 1], maxD));
      }
      peakPosToFit.push_back(peakPositions[i]);
    }
  }
  int numPeaksInRange = static_cast<int>(peakPosToFit.size());
  if (numPeaksInRange == 0) {
    std::stringstream outss;
    outss << "Spectrum " << wi << " has no peak in range (" << minD << ", "
          << maxD << ")";
    g_log.information(outss.str());
    return 0;
  }

  // Fit peaks
  API::IAlgorithm_sptr findpeaks =
      createChildAlgorithm("FindPeaks", -1, -1, false);
  findpeaks->setProperty("InputWorkspace", inputW);
  findpeaks->setProperty<int>("FWHM", 7);
  findpeaks->setProperty<int>("Tolerance", 4);
  // FindPeaks will do the checking on the validity of WorkspaceIndex
  findpeaks->setProperty("WorkspaceIndex", static_cast<int>(wi));

  // Get the specified peak positions, which is optional
  findpeaks->setProperty("PeakPositions", peakPosToFit);
  if (useFitWindows)
    findpeaks->setProperty("FitWindows", fitWindowsToUse);
  findpeaks->setProperty<std::string>("PeakFunction", m_peakType);
  findpeaks->setProperty<std::string>("BackgroundType", m_backType);
  findpeaks->setProperty<bool>("HighBackground",
                               this->getProperty("HighBackground"));
  findpeaks->setProperty<int>("MinGuessedPeakWidth", 4);
  findpeaks->setProperty<int>("MaxGuessedPeakWidth", 4);
  findpeaks->setProperty<double>("MinimumPeakHeight", m_minPeakHeight);
  findpeaks->setProperty("StartFromObservedPeakCentre", true);
  findpeaks->executeAsChildAlg();

  // Collect fitting resutl of all peaks
  ITableWorkspace_sptr peakslist = findpeaks->getProperty("PeaksList");

  // use tmpPeakPosToFit to shuffle the vectors
  std::vector<double> tmpPeakPosToFit;
  generatePeaksList(peakslist, static_cast<int>(wi), peakPosToFit,
                    tmpPeakPosToFit, peakPosFitted, peakHeights, chisq,
                    (useFitWindows || m_useFitWindowTable), fitWindowsToUse,
                    minD, maxD, resolution, dev_resolution);
  peakPosToFit = tmpPeakPosToFit;

  nparams = peakPosFitted.size();

  // Find the highest peak
  i_highestpeak = -1;
  double maxheight = 0;
  for (int i = 0; i < static_cast<int>(peakPosFitted.size()); ++i) {
    double tmpheight = peakHeights[i];
    if (tmpheight > maxheight) {
      maxheight = tmpheight;
      i_highestpeak = i;
    }
  }

  return numPeaksInRange;
}
Example #21
0
  /** Create a Workspace2D (MatrixWorkspace) with given spectra and bin parameters
   */
  MatrixWorkspace_sptr GeneratePeaks::createDataWorkspace(std::vector<double> binparameters)
  {
    // Check validity
    if (m_spectraSet.size() == 0)
      throw std::invalid_argument("Input spectra list is empty. Unable to generate a new workspace.");

    if (binparameters.size() < 3)
    {
      std::stringstream errss;
      errss << "Number of input binning parameters are not enough (" << binparameters.size() << "). "
            << "Binning parameters should be 3 (x0, step, xf).";
      g_log.error(errss.str());
      throw std::invalid_argument(errss.str());
    }

    double x0 = binparameters[0];
    double dx = binparameters[1];
    double xf = binparameters[2];
    if (x0 >= xf || (xf - x0) < dx || dx == 0.)
    {
      std::stringstream errss;
      errss << "Order of input binning parameters is not correct.  It is not logical to have "
            << "x0 = " << x0 << ", xf = " << xf << ", dx = " << dx;
      g_log.error(errss.str());
      throw std::invalid_argument(errss.str());
    }

    // Determine number of x values
    std::vector<double> xarray;
    double xvalue = x0;
    while (xvalue <= xf)
    {
      // Push current value to vector
      xarray.push_back(xvalue);

      // Calculate next value, linear or logarithmic
      if (dx > 0)
        xvalue += dx;
      else
        xvalue += fabs(dx)*xvalue;
    }
    size_t numxvalue = xarray.size();

    // Create new workspace
    MatrixWorkspace_sptr ws = API::WorkspaceFactory::Instance().create("Workspace2D", m_spectraSet.size(),
                                                                       numxvalue, numxvalue-1);
    for (size_t ip = 0; ip < m_spectraSet.size(); ip ++)
      std::copy(xarray.begin(), xarray.end(), ws->dataX(ip).begin());

    // Set spectrum numbers
    std::map<specid_t, specid_t>::iterator spiter;
    for (spiter = m_SpectrumMap.begin(); spiter != m_SpectrumMap.end(); ++spiter)
    {
      specid_t specid = spiter->first;
      specid_t wsindex = spiter->second;
      g_log.debug() << "Build WorkspaceIndex-Spectrum  " << wsindex << " , " << specid << "\n";
      ws->getSpectrum(wsindex)->setSpectrumNo(specid);
    }

    return ws;
  }
Example #22
0
/**
 * This function handles the logic for summing RebinnedOutput workspaces.
 * @param outputWorkspace the workspace to hold the summed input
 * @param progress the progress indicator
 * @param numSpectra
 * @param numMasked
 * @param numZeros
 */
void SumSpectra::doRebinnedOutput(MatrixWorkspace_sptr outputWorkspace,
                                  Progress &progress, size_t &numSpectra,
                                  size_t &numMasked, size_t &numZeros) {
  // Get a copy of the input workspace
  MatrixWorkspace_sptr temp = getProperty("InputWorkspace");

  // First, we need to clean the input workspace for nan's and inf's in order
  // to treat the data correctly later. This will create a new private
  // workspace that will be retrieved as mutable.
  IAlgorithm_sptr alg = this->createChildAlgorithm("ReplaceSpecialValues");
  alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", temp);
  std::string outName = "_" + temp->getName() + "_clean";
  alg->setProperty("OutputWorkspace", outName);
  alg->setProperty("NaNValue", 0.0);
  alg->setProperty("NaNError", 0.0);
  alg->setProperty("InfinityValue", 0.0);
  alg->setProperty("InfinityError", 0.0);
  alg->executeAsChildAlg();
  MatrixWorkspace_sptr localworkspace = alg->getProperty("OutputWorkspace");

  // Transform to real workspace types
  RebinnedOutput_sptr inWS =
      boost::dynamic_pointer_cast<RebinnedOutput>(localworkspace);
  RebinnedOutput_sptr outWS =
      boost::dynamic_pointer_cast<RebinnedOutput>(outputWorkspace);

  // Get references to the output workspaces's data vectors
  ISpectrum *outSpec = outputWorkspace->getSpectrum(0);
  MantidVec &YSum = outSpec->dataY();
  MantidVec &YError = outSpec->dataE();
  MantidVec &FracSum = outWS->dataF(0);
  MantidVec Weight;
  std::vector<size_t> nZeros;
  if (m_calculateWeightedSum) {
    Weight.assign(YSum.size(), 0);
    nZeros.assign(YSum.size(), 0);
  }
  numSpectra = 0;
  numMasked = 0;
  numZeros = 0;

  // Loop over spectra
  std::set<int>::iterator it;
  // for (int i = m_minSpec; i <= m_maxSpec; ++i)
  for (it = m_indices.begin(); it != m_indices.end(); ++it) {
    int i = *it;
    // Don't go outside the range.
    if ((i >= m_numberOfSpectra) || (i < 0)) {
      g_log.error() << "Invalid index " << i
                    << " was specified. Sum was aborted.\n";
      break;
    }

    try {
      // Get the detector object for this spectrum
      Geometry::IDetector_const_sptr det = localworkspace->getDetector(i);
      // Skip monitors, if the property is set to do so
      if (!m_keepMonitors && det->isMonitor())
        continue;
      // Skip masked detectors
      if (det->isMasked()) {
        numMasked++;
        continue;
      }
    } catch (...) {
      // if the detector not found just carry on
    }
    numSpectra++;

    // Retrieve the spectrum into a vector
    const MantidVec &YValues = localworkspace->readY(i);
    const MantidVec &YErrors = localworkspace->readE(i);
    const MantidVec &FracArea = inWS->readF(i);

    if (m_calculateWeightedSum) {
      for (int k = 0; k < this->m_yLength; ++k) {
        if (YErrors[k] != 0) {
          double errsq = YErrors[k] * YErrors[k] * FracArea[k] * FracArea[k];
          YError[k] += errsq;
          Weight[k] += 1. / errsq;
          YSum[k] += YValues[k] * FracArea[k] / errsq;
          FracSum[k] += FracArea[k];
        } else {
          nZeros[k]++;
          FracSum[k] += FracArea[k];
        }
      }
    } else {
      for (int k = 0; k < this->m_yLength; ++k) {
        YSum[k] += YValues[k] * FracArea[k];
        YError[k] += YErrors[k] * YErrors[k] * FracArea[k] * FracArea[k];
        FracSum[k] += FracArea[k];
      }
    }

    // Map all the detectors onto the spectrum of the output
    outSpec->addDetectorIDs(localworkspace->getSpectrum(i)->getDetectorIDs());

    progress.report();
  }

  if (m_calculateWeightedSum) {
    numZeros = 0;
    for (size_t i = 0; i < Weight.size(); i++) {
      if (nZeros[i] == 0)
        YSum[i] *= double(numSpectra) / Weight[i];
      else
        numZeros += nZeros[i];
    }
  }

  // Create the correct representation
  outWS->finalize();
}
Example #23
0
    /**
    * Reads the data from the file. It is assumed that the provided file stream has its position
    * set such that the first call to getline will be give the first line of data
    * @param file :: A reference to a file stream
    * @returns A pointer to a new workspace
    */
    API::Workspace_sptr LoadAscii::readData(std::ifstream & file) const
    {
      // Get the first line and find the number of spectra from the number of columns
      std::string line;
      getline(file,line);
      boost::trim(line);

      std::list<std::string> columns;
      const int numCols = splitIntoColumns(columns, line);
      if( numCols < 2 ) 
      {
        g_log.error() << "Invalid data format found in file \"" << getPropertyValue("Filename") << "\"\n";
        throw std::runtime_error("Invalid data format. Fewer than 2 columns found.");
      }
      size_t numSpectra(0);
      bool haveErrors(false);
      bool haveXErrors(false);
      // Assume single data set with no errors
      if( numCols == 2 )
      {
        numSpectra = numCols/2;
      }
      // Data with errors
      else if( (numCols-1) % 2 == 0 )
      {
        numSpectra = (numCols - 1)/2;
        haveErrors = true;
      }
      // Data with errors on both X and Y (4-column file)
      else if( numCols == 4 )
      {
        numSpectra = 1;
        haveErrors = true;
        haveXErrors = true;
      }
      else
      {
        g_log.error() << "Invalid data format found in file \"" << getPropertyValue("Filename") << "\"\n";
        g_log.error() << "LoadAscii requires the number of columns to be an even multiple of either 2 or 3.";
        throw std::runtime_error("Invalid data format.");
      }

      // A quick check at the number of lines won't be accurate enough as potentially there
      // could be blank lines and comment lines
      int numBins(0), lineNo(0);
      std::vector<DataObjects::Histogram1D> spectra(numSpectra);
      std::vector<double> values(numCols, 0.);
      do
      {
        ++lineNo;
        boost::trim(line);
        if( this->skipLine(line) ) continue;
        columns.clear();
        int lineCols = this->splitIntoColumns(columns, line); 
        if( lineCols != numCols )
        {
          std::ostringstream ostr;
          ostr << "Number of columns changed at line " << lineNo;
          throw std::runtime_error(ostr.str());
        }

        try
        {
          fillInputValues(values, columns); //ignores nans and replaces them with 0
        }
        catch(boost::bad_lexical_cast&)
        {
          g_log.error() << "Invalid value on line " << lineNo << " of \""
            << getPropertyValue("Filename") << "\"\n";
          throw std::runtime_error("Invalid value encountered.");
        }

        for (size_t i = 0; i < numSpectra; ++i)
        {
          spectra[i].dataX().push_back(values[0]);
          spectra[i].dataY().push_back(values[i*2+1]);
          if( haveErrors )
          {
            spectra[i].dataE().push_back(values[i*2+2]);
          }
          if( haveXErrors )
          {
            // Note: we only have X errors with 4-column files.
            // We are only here when i=0.
            spectra[i].dataDx().push_back(values[3]);
          }
        }
        ++numBins;
      }
      while(getline(file,line));

      MatrixWorkspace_sptr localWorkspace = boost::dynamic_pointer_cast<MatrixWorkspace>
        (WorkspaceFactory::Instance().create("Workspace2D",numSpectra,numBins,numBins));
      try 
      {
        localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create(getProperty("Unit"));
      } 
      catch (Exception::NotFoundError&) 
      {
        // Asked for dimensionless workspace (obviously not in unit factory)
      }

      for (size_t i = 0; i < numSpectra; ++i)
      {
        localWorkspace->dataX(i) = spectra[i].dataX();
        localWorkspace->dataY(i) = spectra[i].dataY();
        /* If Y or E errors are not there, DON'T copy across as the 'spectra' vectors
           have not been filled above. The workspace will by default have vectors of
           the right length filled with zeroes. */
        if ( haveErrors ) localWorkspace->dataE(i) = spectra[i].dataE();
        if ( haveXErrors ) localWorkspace->dataDx(i) = spectra[i].dataDx();
        // Just have spectrum number start at 1 and count up
        localWorkspace->getSpectrum(i)->setSpectrumNo(static_cast<specid_t>(i)+1);
      }
      return localWorkspace;
    }
/** Executes the algorithm
 *  @throw Exception::FileError If the calibration file cannot be opened and
 * read successfully
 *  @throw Exception::InstrumentDefinitionError If unable to obtain the
 * source-sample distance
 */
void AlignDetectors::exec() {
  // Get the input workspace
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");

  this->getCalibrationWS(inputWS);

  // Initialise the progress reporting object
  m_numberOfSpectra = static_cast<int64_t>(inputWS->getNumberHistograms());

  // Check if its an event workspace
  EventWorkspace_const_sptr eventW =
      boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
  if (eventW != nullptr) {
    this->execEvent();
    return;
  }

  API::MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
  // If input and output workspaces are not the same, create a new workspace for
  // the output
  if (outputWS != inputWS) {
    outputWS = WorkspaceFactory::Instance().create(inputWS);
    setProperty("OutputWorkspace", outputWS);
  }

  // Set the final unit that our output workspace will have
  setXAxisUnits(outputWS);

  ConversionFactors converter = ConversionFactors(m_calibrationWS);

  Progress progress(this, 0.0, 1.0, m_numberOfSpectra);

  // Loop over the histograms (detector spectra)
  PARALLEL_FOR2(inputWS, outputWS)
  for (int64_t i = 0; i < m_numberOfSpectra; ++i) {
    PARALLEL_START_INTERUPT_REGION
    try {
      // Get the input spectrum number at this workspace index
      auto inSpec = inputWS->getSpectrum(size_t(i));
      auto toDspacing = converter.getConversionFunc(inSpec->getDetectorIDs());

      // Get references to the x data
      MantidVec &xOut = outputWS->dataX(i);

      // Make sure reference to input X vector is obtained after output one
      // because in the case
      // where the input & output workspaces are the same, it might move if the
      // vectors were shared.
      const MantidVec &xIn = inSpec->readX();

      std::transform(xIn.begin(), xIn.end(), xOut.begin(), toDspacing);

      // Copy the Y&E data
      outputWS->dataY(i) = inSpec->readY();
      outputWS->dataE(i) = inSpec->readE();

    } catch (Exception::NotFoundError &) {
      // Zero the data in this case
      outputWS->dataX(i).assign(outputWS->readX(i).size(), 0.0);
      outputWS->dataY(i).assign(outputWS->readY(i).size(), 0.0);
      outputWS->dataE(i).assign(outputWS->readE(i).size(), 0.0);
    }
    progress.report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION
}
Example #25
0
void GatherWorkspaces::exec() {
  // Every process in an MPI job must hit this next line or everything hangs!
  mpi::communicator world; // The communicator containing all processes

  inputWorkspace = getProperty("InputWorkspace");

  // Create a new communicator that includes only those processes that have an
  // input workspace
  const int haveWorkspace(inputWorkspace ? 1 : 0);
  included = world.split(haveWorkspace);

  // If the present process doesn't have an input workspace then its work is
  // done
  if (!haveWorkspace) {
    g_log.information("No input workspace on this process, so nothing to do.");
    return;
  }

  // Get the number of bins in each workspace and check they're all the same
  numBins = inputWorkspace->blocksize();
  std::vector<std::size_t> all_numBins;
  all_gather(included, numBins, all_numBins);
  if (std::count(all_numBins.begin(), all_numBins.end(), numBins) !=
      (int)all_numBins.size()) {
    // All the processes will error out if all the workspaces don't have the
    // same number of bins
    throw Exception::MisMatch<std::size_t>(
        numBins, 0, "All input workspaces must have the same number of bins");
  }
  // Also check that all workspaces are either histogram or not
  // N.B. boost mpi doesn't seem to like me using booleans in the all_gather
  hist = inputWorkspace->isHistogramData();
  std::vector<int> all_hist;
  all_gather(included, hist, all_hist);
  if (std::count(all_hist.begin(), all_hist.end(), hist) !=
      (int)all_hist.size()) {
    // All the processes will error out if we don't have either all histogram or
    // all point-data workspaces
    throw Exception::MisMatch<int>(
        hist, 0,
        "The input workspaces must be all histogram or all point data");
  }

  // How do we accumulate the data?
  std::string accum = this->getPropertyValue("AccumulationMethod");
  // Get the total number of spectra in the combined inputs
  totalSpec = inputWorkspace->getNumberHistograms();
  sumSpec = totalSpec;
  if (accum == "Append") {
    reduce(included, totalSpec, sumSpec, std::plus<std::size_t>(), 0);
  } else if (accum == "Add") {
    // barrier only helps when memory is too low for communication
    // included.barrier();
  }

  eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWorkspace);
  if (eventW != NULL) {
    if (getProperty("PreserveEvents")) {
      // Input workspace is an event workspace. Use the other exec method
      this->execEvent();
      return;
    }
  }

  // The root process needs to create a workspace of the appropriate size
  MatrixWorkspace_sptr outputWorkspace;
  if (included.rank() == 0) {
    g_log.debug() << "Total number of spectra is " << sumSpec << "\n";
    // Create the workspace for the output
    outputWorkspace = WorkspaceFactory::Instance().create(
        inputWorkspace, sumSpec, numBins + hist, numBins);
    setProperty("OutputWorkspace", outputWorkspace);
    ExperimentInfo_sptr inWS = inputWorkspace;
    outputWorkspace->copyExperimentInfoFrom(inWS.get());
  }

  for (size_t wi = 0; wi < totalSpec; wi++) {
    if (included.rank() == 0) {
      const ISpectrum *inSpec = inputWorkspace->getSpectrum(wi);
      if (accum == "Add") {
        outputWorkspace->dataX(wi) = inputWorkspace->readX(wi);
        reduce(included, inputWorkspace->readY(wi), outputWorkspace->dataY(wi),
               vplus(), 0);
        reduce(included, inputWorkspace->readE(wi), outputWorkspace->dataE(wi),
               eplus(), 0);
      } else if (accum == "Append") {
        // Copy over data from own input workspace
        outputWorkspace->dataX(wi) = inputWorkspace->readX(wi);
        outputWorkspace->dataY(wi) = inputWorkspace->readY(wi);
        outputWorkspace->dataE(wi) = inputWorkspace->readE(wi);

        const int numReqs(3 * (included.size() - 1));
        mpi::request reqs[numReqs];
        int j(0);

        // Receive data from all the other processes
        // This works because the process ranks are ordered the same in
        // 'included' as
        // they are in 'world', but in general this is not guaranteed. TODO:
        // robustify
        for (int i = 1; i < included.size(); ++i) {
          size_t index = wi + i * totalSpec;
          reqs[j++] = included.irecv(i, 0, outputWorkspace->dataX(index));
          reqs[j++] = included.irecv(i, 1, outputWorkspace->dataY(index));
          reqs[j++] = included.irecv(i, 2, outputWorkspace->dataE(index));
          ISpectrum *outSpec = outputWorkspace->getSpectrum(index);
          outSpec->clearDetectorIDs();
          outSpec->addDetectorIDs(inSpec->getDetectorIDs());
        }

        // Make sure everything's been received before exiting the algorithm
        mpi::wait_all(reqs, reqs + numReqs);
      }
      ISpectrum *outSpec = outputWorkspace->getSpectrum(wi);
      outSpec->clearDetectorIDs();
      outSpec->addDetectorIDs(inSpec->getDetectorIDs());
    } else {
      if (accum == "Add") {
        reduce(included, inputWorkspace->readY(wi), vplus(), 0);
        reduce(included, inputWorkspace->readE(wi), eplus(), 0);
      } else if (accum == "Append") {
        mpi::request reqs[3];

        // Send the spectrum to the root process
        reqs[0] = included.isend(0, 0, inputWorkspace->readX(0));
        reqs[1] = included.isend(0, 1, inputWorkspace->readY(0));
        reqs[2] = included.isend(0, 2, inputWorkspace->readE(0));

        // Make sure the sends have completed before exiting the algorithm
        mpi::wait_all(reqs, reqs + 3);
      }
    }
  }
}
Example #26
0
/** Read a data file that contains only one spectrum into a workspace
*  @return the new workspace
*/
const API::MatrixWorkspace_sptr LoadRKH::read1D() {
  g_log.information()
      << "file appears to contain 1D information, reading in 1D data mode\n";

  // The 3rd line contains information regarding the number of points in the
  // file and
  // start and end reading points
  int totalPoints(0), readStart(0), readEnd(0), buried(0);
  std::string fileline;

  getline(m_fileIn, fileline);
  std::istringstream is(fileline);
  // Get data information
  for (int counter = 1; counter < 8; ++counter) {
    switch (counter) {
    case 1:
      is >> totalPoints;
      break;
    case 5:
      is >> readStart;
      break;
    case 6:
      is >> readEnd;
      break;
    default:
      is >> buried;
      break;
    }
  }

  g_log.information()
      << "Total number of data points declared to be in the data file: "
      << totalPoints << "\n";

  // What are we reading?
  std::string firstColVal = getProperty("FirstColumnValue");
  bool colIsUnit(true);
  if (m_RKHKeys.find(firstColVal) != m_RKHKeys.end()) {
    colIsUnit = false;
    readStart = 1;
    readEnd = totalPoints;
  }

  if (readStart < 1 || readEnd < 1 || readEnd < readStart ||
      readStart > totalPoints || readEnd > totalPoints) {
    g_log.error("Invalid data range specfied.");
    m_fileIn.close();
    throw std::invalid_argument("Invalid data range specfied.");
  }

  g_log.information() << "Reading started on data line: " << readStart << "\n";
  g_log.information() << "Reading finished on data line: " << readEnd << "\n";

  // The 4th and 5th line do not contain useful information either
  skipLines(m_fileIn, 2);

  int pointsToRead = readEnd - readStart + 1;
  // Now stream sits at the first line of data
  std::vector<double> columnOne, ydata, errdata, xError;
  columnOne.reserve(readEnd);
  ydata.reserve(readEnd);
  errdata.reserve(readEnd);

  auto hasXError = hasXerror(m_fileIn);

  Progress prog(this, 0.0, 1.0, readEnd);

  if (hasXError) {
    xError.reserve(readEnd);
    readLinesWithXErrorForRKH1D(m_fileIn, readStart, readEnd, columnOne, ydata,
                                errdata, xError, prog);
  } else {
    readLinesForRKH1D(m_fileIn, readStart, readEnd, columnOne, ydata, errdata,
                      prog);
  }
  m_fileIn.close();

  assert(pointsToRead == static_cast<int>(columnOne.size()));
  assert(pointsToRead == static_cast<int>(ydata.size()));
  assert(pointsToRead == static_cast<int>(errdata.size()));

  if (hasXError) {
    assert(pointsToRead == static_cast<int>(xError.size()));
  }

  if (colIsUnit) {
    MatrixWorkspace_sptr localworkspace = WorkspaceFactory::Instance().create(
        "Workspace2D", 1, pointsToRead, pointsToRead);
    localworkspace->getAxis(0)->unit() =
        UnitFactory::Instance().create(firstColVal);
    localworkspace->dataX(0) = columnOne;
    localworkspace->dataY(0) = ydata;
    localworkspace->dataE(0) = errdata;
    if (hasXError) {
      localworkspace->dataDx(0) = xError;
    }
    return localworkspace;
  } else {
    MatrixWorkspace_sptr localworkspace =
        WorkspaceFactory::Instance().create("Workspace2D", pointsToRead, 1, 1);
    // Set the appropriate values
    for (int index = 0; index < pointsToRead; ++index) {
      localworkspace->getSpectrum(index)
          .setSpectrumNo(static_cast<int>(columnOne[index]));
      localworkspace->dataY(index)[0] = ydata[index];
      localworkspace->dataE(index)[0] = errdata[index];
    }

    if (hasXError) {
      for (int index = 0; index < pointsToRead; ++index) {
        localworkspace->dataDx(index)[0] = xError[index];
      }
    }
    return localworkspace;
  }
}
Example #27
0
/**
  @ throw invalid_argument if the workspaces are not mututially compatible
*/
void Q1D2::exec()
{
  m_dataWS = getProperty("DetBankWorkspace");
  MatrixWorkspace_const_sptr waveAdj = getProperty("WavelengthAdj");
  MatrixWorkspace_const_sptr pixelAdj = getProperty("PixelAdj");
  MatrixWorkspace_const_sptr wavePixelAdj = getProperty("WavePixelAdj");
  const bool doGravity = getProperty("AccountForGravity");
  m_doSolidAngle = getProperty("SolidAngleWeighting");

  //throws if we don't have common binning or another incompatibility
  Qhelper helper;
  helper.examineInput(m_dataWS, waveAdj, pixelAdj);
  // FIXME: how to examine the wavePixelAdj? 
  g_log.debug() << "All input workspaces were found to be valid\n";
  // normalization as a function of wavelength (i.e. centers of x-value bins)
  double const * const binNorms = waveAdj ? &(waveAdj->readY(0)[0]) : NULL;
  // error on the wavelength normalization
  double const * const binNormEs = waveAdj ? &(waveAdj->readE(0)[0]) : NULL;

  //define the (large number of) data objects that are going to be used in all iterations of the loop below

  // this will become the output workspace from this algorithm
  MatrixWorkspace_sptr outputWS = setUpOutputWorkspace(getProperty("OutputBinning"));

  const MantidVec & QOut = outputWS->readX(0);
  MantidVec & YOut = outputWS->dataY(0);
  MantidVec & EOutTo2 = outputWS->dataE(0);
  // normalisation that is applied to counts in each Q bin
  MantidVec normSum(YOut.size(), 0.0);
  // the error on the normalisation
  MantidVec normError2(YOut.size(), 0.0);

  const int numSpec = static_cast<int>(m_dataWS->getNumberHistograms());
  Progress progress(this, 0.05, 1.0, numSpec+1);

  PARALLEL_FOR3(m_dataWS, outputWS, pixelAdj)
  for (int i = 0; i < numSpec; ++i)
  {
    PARALLEL_START_INTERUPT_REGION
    // Get the pixel relating to this spectrum
    IDetector_const_sptr det;
    try {
      det = m_dataWS->getDetector(i);
    } catch (Exception::NotFoundError&) {
      g_log.warning() << "Workspace index " << i << " (SpectrumIndex = " << m_dataWS->getSpectrum(i)->getSpectrumNo() << ") has no detector assigned to it - discarding" << std::endl;
      // 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 or if detector is masked shouldn't be included skip onto the next spectrum
    if ( !det || det->isMonitor() || det->isMasked() )
    {
      continue;
    }

    //get the bins that are included inside the RadiusCut/WaveCutcut off, those to calculate for
    //const size_t wavStart = waveLengthCutOff(i);
    const size_t wavStart = helper.waveLengthCutOff(m_dataWS, getProperty("RadiusCut"), getProperty("WaveCut"), i);
    if (wavStart >=  m_dataWS->readY(i).size())
    {
      // all the spectra in this detector are out of range
      continue;
    }
    
    const size_t numWavbins = m_dataWS->readY(i).size()-wavStart;
    // make just one call to new to reduce CPU overhead on each thread, access to these 
    // three "arrays" is via iterators
    MantidVec _noDirectUseStorage_(3*numWavbins);
    //normalization term
    MantidVec::iterator norms = _noDirectUseStorage_.begin();
    // the error on these weights, it contributes to the error calculation on the output workspace
    MantidVec::iterator normETo2s = norms + numWavbins;
    // the Q values calculated from input wavelength workspace
    MantidVec::iterator QIn = normETo2s + numWavbins;

    // the weighting for this input spectrum that is added to the normalization
    calculateNormalization(wavStart, i, pixelAdj, wavePixelAdj, binNorms, binNormEs, norms, normETo2s);

    // now read the data from the input workspace, calculate Q for each bin
    convertWavetoQ(i, doGravity, wavStart, QIn);

    // Pointers to the counts data and it's error
    MantidVec::const_iterator YIn = m_dataWS->readY(i).begin()+wavStart;
    MantidVec::const_iterator EIn = m_dataWS->readE(i).begin()+wavStart;

    //when finding the output Q bin remember that the input Q bins (from the convert to wavelength) start high and reduce
    MantidVec::const_iterator loc = QOut.end();
    // sum the Q contributions from each individual spectrum into the output array
    const MantidVec::const_iterator end = m_dataWS->readY(i).end();
    for( ; YIn != end; ++YIn, ++EIn, ++QIn, ++norms, ++normETo2s)
    {
      //find the output bin that each input y-value will fall into, remembering there is one more bin boundary than bins
      getQBinPlus1(QOut, *QIn, loc);
      // ignore counts that are out of the output range
      if ( (loc != QOut.begin()) && (loc != QOut.end()) )
      {
        // the actual Q-bin to add something to
        const size_t bin = loc - QOut.begin() - 1;
        PARALLEL_CRITICAL(q1d_counts_sum)
        {
          YOut[bin] += *YIn;
          normSum[bin] += *norms;
          //these are the errors squared which will be summed and square rooted at the end
          EOutTo2[bin] += (*EIn)*(*EIn);
          normError2[bin] += *normETo2s;
        }
      }
    }
    
    PARALLEL_CRITICAL(q1d_spectra_map)
    {
      progress.report("Computing I(Q)");

      // Add up the detector IDs in the output spectrum at workspace index 0
      const ISpectrum * inSpec = m_dataWS->getSpectrum(i);
      ISpectrum * outSpec = outputWS->getSpectrum(0);
      outSpec->addDetectorIDs( inSpec->getDetectorIDs() );
    }

    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  bool doOutputParts = getProperty("OutputParts");
  if (doOutputParts)
  {
      MatrixWorkspace_sptr ws_sumOfCounts = WorkspaceFactory::Instance().create(outputWS);
      ws_sumOfCounts->dataX(0) = outputWS->dataX(0);
      ws_sumOfCounts->dataY(0) = outputWS->dataY(0);
      for (size_t i = 0; i < outputWS->dataE(0).size(); i++)
      {
        ws_sumOfCounts->dataE(0)[i] = sqrt(outputWS->dataE(0)[i]);
      }      

      MatrixWorkspace_sptr ws_sumOfNormFactors = WorkspaceFactory::Instance().create(outputWS);
      ws_sumOfNormFactors->dataX(0) = outputWS->dataX(0);
      for (size_t i = 0; i < ws_sumOfNormFactors->dataY(0).size(); i++)
      {
        ws_sumOfNormFactors->dataY(0)[i] = normSum[i];
        ws_sumOfNormFactors->dataE(0)[i] = sqrt(normError2[i]);
      }

      helper.outputParts(this, ws_sumOfCounts, ws_sumOfNormFactors);
  }


  progress.report("Normalizing I(Q)");
  //finally divide the number of counts in each output Q bin by its weighting
  normalize(normSum, normError2, YOut, EOutTo2);

  outputWS->updateSpectraUsingMap();

  setProperty("OutputWorkspace",outputWS);
}
Example #28
0
/** Executes the algorithm
 *  @throw std::invalid_argument If the input workspaces do not meet the requirements of this algorithm
 */
void ConjoinWorkspaces::exec()
{
  // Retrieve the input workspaces
  MatrixWorkspace_const_sptr ws1 = getProperty("InputWorkspace1");
  MatrixWorkspace_const_sptr ws2 = getProperty("InputWorkspace2");
  event_ws1 = boost::dynamic_pointer_cast<const EventWorkspace>(ws1);
  event_ws2 = boost::dynamic_pointer_cast<const EventWorkspace>(ws2);

  //Make sure that we are not mis-matching EventWorkspaces and other types of workspaces
  if (((event_ws1) && (!event_ws2)) || ((!event_ws1) && (event_ws2)))
  {
    const std::string message("Only one of the input workspaces are of type EventWorkspace; please use matching workspace types (both EventWorkspace's or both Workspace2D's).");
    g_log.error(message);
    throw std::invalid_argument(message);
  }

  if (event_ws1 && event_ws2)
  {
    //Both are event workspaces. Use the special method
    this->execEvent();
    return;
  }

  // Check that the input workspaces meet the requirements for this algorithm
  this->validateInputs(ws1,ws2);

  // Create the output workspace
  const size_t totalHists = ws1->getNumberHistograms() + ws2->getNumberHistograms();
  MatrixWorkspace_sptr output = WorkspaceFactory::Instance().create("Workspace2D",totalHists,ws1->readX(0).size(),
                                                                             ws1->readY(0).size());
  // Copy over stuff from first input workspace
  WorkspaceFactory::Instance().initializeFromParent(ws1,output,true);

  // Create the X values inside a cow pointer - they will be shared in the output workspace
  cow_ptr<MantidVec> XValues;
  XValues.access() = ws1->readX(0);

  // Initialize the progress reporting object
  m_progress = new API::Progress(this, 0.0, 1.0, totalHists);

  // Loop over the input workspaces in turn copying the data into the output one
  const int64_t& nhist1 = ws1->getNumberHistograms();
  PARALLEL_FOR2(ws1, output)
  for (int64_t i = 0; i < nhist1; ++i)
  {
    PARALLEL_START_INTERUPT_REGION
    ISpectrum * outSpec = output->getSpectrum(i);
    const ISpectrum * inSpec = ws1->getSpectrum(i);

    // Copy X,Y,E
    outSpec->setX(XValues);
    outSpec->setData(inSpec->dataY(), inSpec->dataE());
    // Copy the spectrum number/detector IDs
    outSpec->copyInfoFrom(*inSpec);

    // Propagate masking, if needed
    if ( ws1->hasMaskedBins(i) )
    {
      const MatrixWorkspace::MaskList& inputMasks = ws1->maskedBins(i);
      MatrixWorkspace::MaskList::const_iterator it;
      for (it = inputMasks.begin(); it != inputMasks.end(); ++it)
      {
        output->flagMasked(i,(*it).first,(*it).second);
      }
    }    
    m_progress->report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION


  //For second loop we use the offset from the first
  const int64_t& nhist2 = ws2->getNumberHistograms();

  PARALLEL_FOR2(ws2, output)
  for (int64_t j = 0; j < nhist2; ++j)
  {
    PARALLEL_START_INTERUPT_REGION
    // The spectrum in the output workspace
    ISpectrum * outSpec = output->getSpectrum(nhist1 + j);
    // Spectrum in the second workspace
    const ISpectrum * inSpec = ws2->getSpectrum(j);

    // Copy X,Y,E
    outSpec->setX(XValues);
    outSpec->setData(inSpec->dataY(), inSpec->dataE());
    // Copy the spectrum number/detector IDs
    outSpec->copyInfoFrom(*inSpec);

    // Propagate masking, if needed
    if ( ws2->hasMaskedBins(j) )
    {
      const MatrixWorkspace::MaskList& inputMasks = ws2->maskedBins(j);
      MatrixWorkspace::MaskList::const_iterator it;
      for (it = inputMasks.begin(); it != inputMasks.end(); ++it)
      {
        output->flagMasked(nhist1 + j,(*it).first,(*it).second);
      }
    }
    m_progress->report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  this->fixSpectrumNumbers(ws1,ws2, output);

  // Delete the second input workspace from the ADS
  AnalysisDataService::Instance().remove(getPropertyValue("InputWorkspace2"));
  // Set the result workspace to the first input
  setProperty("InputWorkspace1",output);
}
Example #29
0
/** Execute the algorithm.
 */
void EditInstrumentGeometry::exec() {
  // Lots of things have to do with the input workspace
  MatrixWorkspace_sptr workspace = getProperty("Workspace");
  Geometry::Instrument_const_sptr originstrument = workspace->getInstrument();

  // Get and check the primary flight path
  double l1 = this->getProperty("PrimaryFlightPath");
  if (isEmpty(l1)) {
    // Use the original L1
    if (!originstrument) {
      std::string errmsg(
          "It is not supported that L1 is not given, ",
          "while there is no instrument associated to input workspace.");
      g_log.error(errmsg);
      throw std::runtime_error(errmsg);
    }
    Geometry::IComponent_const_sptr source = originstrument->getSource();
    Geometry::IComponent_const_sptr sample = originstrument->getSample();
    l1 = source->getDistance(*sample);
    g_log.information() << "Retrieve L1 from input data workspace. \n";
  }
  g_log.information() << "Using L1 = " << l1 << "\n";

  // Get spectra number in case they are in a funny order
  std::vector<int32_t> specids = this->getProperty("SpectrumIDs");
  if (specids.empty()) // they are using the order of the input workspace
  {
    size_t numHist = workspace->getNumberHistograms();
    for (size_t i = 0; i < numHist; ++i) {
      specids.push_back(workspace->getSpectrum(i).getSpectrumNo());
      g_log.information() << "Add spectrum "
                          << workspace->getSpectrum(i).getSpectrumNo() << ".\n";
    }
  }

  // Get the detector ids - empsy means ignore it
  const vector<int> vec_detids = getProperty("DetectorIDs");
  const bool renameDetID(!vec_detids.empty());

  // Get individual detector geometries ordered by input spectrum Numbers
  const std::vector<double> l2s = this->getProperty("L2");
  const std::vector<double> tths = this->getProperty("Polar");
  std::vector<double> phis = this->getProperty("Azimuthal");

  // empty list of L2 and 2-theta is not allowed
  if (l2s.empty()) {
    throw std::runtime_error("User must specify L2 for all spectra. ");
  }
  if (tths.empty()) {
    throw std::runtime_error("User must specify 2theta for all spectra.");
  }

  // empty list of phi means that they are all zero
  if (phis.empty()) {
    phis.assign(l2s.size(), 0.);
  }

  // Validate
  for (size_t ib = 0; ib < l2s.size(); ib++) {
    g_log.information() << "Detector " << specids[ib] << "  L2 = " << l2s[ib]
                        << "  2Theta = " << tths[ib] << '\n';
    if (specids[ib] < 0) {
      // Invalid spectrum Number : less than 0.
      stringstream errmsgss;
      errmsgss << "Detector ID = " << specids[ib] << " cannot be less than 0.";
      throw std::invalid_argument(errmsgss.str());
    }
    if (l2s[ib] <= 0.0) {
      throw std::invalid_argument("L2 cannot be less or equal to 0");
    }
  }

  // Keep original instrument and set the new instrument, if necessary
  const auto spec2indexmap = workspace->getSpectrumToWorkspaceIndexMap();

  // ??? Condition: spectrum has 1 and only 1 detector
  size_t nspec = workspace->getNumberHistograms();

  // Initialize another set of L2/2-theta/Phi/DetectorIDs vector ordered by
  // workspace index
  std::vector<double> storL2s(nspec, 0.);
  std::vector<double> stor2Thetas(nspec, 0.);
  std::vector<double> storPhis(nspec, 0.);
  vector<int> storDetIDs(nspec, 0);

  // Map the properties from spectrum Number to workspace index
  for (size_t i = 0; i < specids.size(); i++) {
    // Find spectrum's workspace index
    auto it = spec2indexmap.find(specids[i]);
    if (it == spec2indexmap.end()) {
      stringstream errss;
      errss << "Spectrum Number " << specids[i] << " is not found. "
            << "Instrument won't be edited for this spectrum. \n";
      g_log.error(errss.str());
      throw std::runtime_error(errss.str());
    }

    // Store and set value
    size_t workspaceindex = it->second;

    storL2s[workspaceindex] = l2s[i];
    stor2Thetas[workspaceindex] = tths[i];
    storPhis[workspaceindex] = phis[i];
    if (renameDetID)
      storDetIDs[workspaceindex] = vec_detids[i];

    g_log.debug() << "workspace index = " << workspaceindex
                  << " is for Spectrum " << specids[i] << '\n';
  }

  // Generate a new instrument
  // Name of the new instrument
  std::string name = std::string(getProperty("InstrumentName"));
  if (name.empty()) {
    // Use the original L1
    if (!originstrument) {
      std::string errmsg(
          "It is not supported that InstrumentName is not given, ",
          "while there is no instrument associated to input workspace.");
      g_log.error(errmsg);
      throw std::runtime_error(errmsg);
    }
    name = originstrument->getName();
  }

  // Create a new instrument from scratch any way.
  auto instrument = boost::make_shared<Geometry::Instrument>(name);
  if (!bool(instrument)) {
    stringstream errss;
    errss << "Trying to use a Parametrized Instrument as an Instrument.";
    g_log.error(errss.str());
    throw std::runtime_error(errss.str());
  }

  // Set up source and sample information
  Geometry::ObjComponent *samplepos =
      new Geometry::ObjComponent("Sample", instrument.get());
  instrument->add(samplepos);
  instrument->markAsSamplePos(samplepos);
  samplepos->setPos(0.0, 0.0, 0.0);

  Geometry::ObjComponent *source =
      new Geometry::ObjComponent("Source", instrument.get());
  instrument->add(source);
  instrument->markAsSource(source);
  source->setPos(0.0, 0.0, -1.0 * l1);

  // Add/copy detector information
  auto indexInfo = workspace->indexInfo();
  std::vector<detid_t> detIDs;
  for (size_t i = 0; i < workspace->getNumberHistograms(); i++) {
    // Create a new detector.
    //    (Instrument will take ownership of pointer so no need to delete.)
    detid_t newdetid;
    if (renameDetID)
      newdetid = storDetIDs[i];
    else
      newdetid = detid_t(i) + 100;
    Geometry::Detector *detector =
        new Geometry::Detector("det", newdetid, samplepos);

    // Set up new detector parameters related to new instrument
    double l2 = storL2s[i];
    double tth = stor2Thetas[i];
    double phi = storPhis[i];

    Kernel::V3D pos;
    pos.spherical(l2, tth, phi);
    detector->setPos(pos);

    // Add new detector to spectrum and instrument
    // Good and do some debug output
    g_log.debug() << "Orignal spectrum " << indexInfo.spectrumNumber(i)
                  << "has " << indexInfo.detectorIDs(i).size()
                  << " detectors. \n";

    detIDs.push_back(newdetid);
    instrument->add(detector);
    instrument->markAsDetector(detector);

  } // ENDFOR workspace index
  indexInfo.setDetectorIDs(std::move(detIDs));
  workspace->setIndexInfo(indexInfo);

  // Add the new instrument
  workspace->setInstrument(instrument);
}
Example #30
0
    /**
    *   Executes the algorithm.
    */
    void LoadSpec::exec()
    {
      std::string filename = getProperty("Filename");
      //std::string separator = " "; //separator can be 1 or more spaces
      std::ifstream file(filename.c_str());

      file.seekg (0, std::ios::end);
      Progress progress(this,0,1,static_cast<int>(file.tellg()));
      file.seekg (0, std::ios::beg);

      std::string str;

      std::vector<DataObjects::Histogram1D> spectra;


      int nBins = 0; //number of rows


      //bool numeric = true;
      std::vector<double> input;

      //determine the number of lines starting by #L
      //as there is one per set of data
      int spectra_nbr = 0;
      while(getline(file,str))
      {
        if (str[0] == '#' && str[1] == 'L')
        {
          spectra_nbr++;
        }
      }

      spectra.resize(spectra_nbr);
      file.clear(); //end of file has been reached so we need to clear file state
      file.seekg (0, std::ios::beg); //go back to beginning of file

      int working_with_spectrum_nbr = -1; //spectrum number
      while(getline(file,str))
      {
        progress.report(static_cast<int>(file.tellg()));

        //line with data, need to be parsed by white spaces
        if (!str.empty() && str[0] != '#')
        {
          typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
          boost::char_separator<char> sep(" ");
          tokenizer tok(str, sep);
          for (tokenizer::iterator beg=tok.begin(); beg!=tok.end(); ++beg)
          {
            std::stringstream ss;
            ss << *beg;
            double d;
            ss >> d;
            input.push_back(d);
          }
        }

        if (str.empty())
        {
          if (working_with_spectrum_nbr != -1)
          {
            for(int j=0; j<static_cast<int>(input.size()-1); j++)
            {
              spectra[working_with_spectrum_nbr].dataX().push_back(input[j]);
              j++;
              spectra[working_with_spectrum_nbr].dataY().push_back(input[j]);
              j++;
              spectra[working_with_spectrum_nbr].dataE().push_back(input[j]);
              nBins = j/3;
            }
          }
          working_with_spectrum_nbr++;
          input.clear();
        }

      } //end of read file

      try
      {
        if (spectra_nbr == 0)
          throw "Undefined number of spectra";

        if (working_with_spectrum_nbr == (spectra_nbr-1))
        {
          for(int j=0; j<static_cast<int>(input.size()-1); j++)
          {
            spectra[working_with_spectrum_nbr].dataX().push_back(input[j]);
            j++;
            spectra[working_with_spectrum_nbr].dataY().push_back(input[j]);
            j++;
            spectra[working_with_spectrum_nbr].dataE().push_back(input[j]);
            nBins = j/3;
          }
        }
      }
      catch (...)
      {
      }

      try
      {
        int nSpectra = spectra_nbr;
        MatrixWorkspace_sptr localWorkspace = boost::dynamic_pointer_cast<MatrixWorkspace>
          (WorkspaceFactory::Instance().create("Workspace2D",nSpectra,nBins,nBins));

        localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create(getProperty("Unit"));

        for(int i=0;i<nSpectra;i++)
        {
          localWorkspace->dataX(i) = spectra[i].dataX();
          localWorkspace->dataY(i) = spectra[i].dataY();
          localWorkspace->dataE(i) = spectra[i].dataE();
          // Just have spectrum number start at 1 and count up
          localWorkspace->getSpectrum(i)->setSpectrumNo(i+1);
        }

        setProperty("OutputWorkspace",localWorkspace);
      }
      catch (Exception::NotFoundError&)
      {
        // Asked for dimensionless workspace (obviously not in unit factory)
      }

    }