Example #1
0
/**
 * Creates the output workspace for this algorithm
 * @param inputWorkspace A parent workspace to initialize from.
 * @return A pointer to the output workspace.
 */
API::MatrixWorkspace_sptr Transpose::createOutputWorkspace(
    API::MatrixWorkspace_const_sptr inputWorkspace) {
  Mantid::API::Axis *yAxis = getVerticalAxis(inputWorkspace);
  const size_t oldNhist = inputWorkspace->getNumberHistograms();
  const auto &inX = inputWorkspace->x(0);
  const size_t oldYlength = inputWorkspace->blocksize();
  const size_t oldVerticalAxislength = yAxis->length();

  // The input Y axis may be binned so the new X data should be too
  size_t newNhist(oldYlength), newXsize(oldVerticalAxislength),
      newYsize(oldNhist);
  MatrixWorkspace_sptr outputWorkspace = inputWorkspace->cloneEmpty();
  outputWorkspace->initialize(newNhist, newXsize, newYsize);
  outputWorkspace->setTitle(inputWorkspace->getTitle());
  outputWorkspace->setComment(inputWorkspace->getComment());
  outputWorkspace->copyExperimentInfoFrom(inputWorkspace.get());
  outputWorkspace->setYUnit(inputWorkspace->YUnit());
  outputWorkspace->setYUnitLabel(inputWorkspace->YUnitLabel());
  outputWorkspace->setDistribution(inputWorkspace->isDistribution());

  // Create a new numeric axis for Y the same length as the old X array
  // Values come from input X
  API::NumericAxis *newYAxis(nullptr);
  if (inputWorkspace->isHistogramData()) {
    newYAxis = new API::BinEdgeAxis(inX.rawData());
  } else {
    newYAxis = new API::NumericAxis(inX.rawData());
  }

  newYAxis->unit() = inputWorkspace->getAxis(0)->unit();
  outputWorkspace->getAxis(0)->unit() = inputWorkspace->getAxis(1)->unit();
  outputWorkspace->replaceAxis(1, newYAxis);
  setProperty("OutputWorkspace", outputWorkspace);
  return outputWorkspace;
}
Example #2
0
/**
 * Creates the output workspace for this algorithm
 * @param inputWorkspace A parent workspace to initialize from.
 * @return A pointer to the output workspace.
 */
API::MatrixWorkspace_sptr Transpose::createOutputWorkspace(
    API::MatrixWorkspace_const_sptr inputWorkspace) {
  Mantid::API::Axis *yAxis = getVerticalAxis(inputWorkspace);
  const size_t oldNhist = inputWorkspace->getNumberHistograms();
  const MantidVec &inX = inputWorkspace->readX(0);
  const size_t oldYlength = inputWorkspace->blocksize();
  const size_t oldVerticalAxislength = yAxis->length();

  // The input Y axis may be binned so the new X data should be too
  size_t newNhist(oldYlength), newXsize(oldVerticalAxislength),
      newYsize(oldNhist);
  MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
      inputWorkspace, newNhist, newXsize, newYsize);

  // Create a new numeric axis for Y the same length as the old X array
  // Values come from input X
  API::NumericAxis *newYAxis(nullptr);
  if (inputWorkspace->isHistogramData()) {
    newYAxis = new API::BinEdgeAxis(inX);
  } else {
    newYAxis = new API::NumericAxis(inX);
  }

  newYAxis->unit() = inputWorkspace->getAxis(0)->unit();
  outputWorkspace->getAxis(0)->unit() = inputWorkspace->getAxis(1)->unit();
  outputWorkspace->replaceAxis(1, newYAxis);
  setProperty("OutputWorkspace", outputWorkspace);
  return outputWorkspace;
}
Example #3
0
/** Creates the output workspace, setting the axes according to the input
 * binning parameters
 *  @param[in]  inputWorkspace The input workspace
 *  @param[in]  binParams The bin parameters from the user
 *  @param[out] newAxis        The 'vertical' axis defined by the given
 * parameters
 *  @return A pointer to the newly-created workspace
 */
API::MatrixWorkspace_sptr SofQWCentre::setUpOutputWorkspace(
    API::MatrixWorkspace_const_sptr inputWorkspace,
    const std::vector<double> &binParams, std::vector<double> &newAxis) {
  // Create vector to hold the new X axis values
  HistogramData::BinEdges xAxis(inputWorkspace->sharedX(0));
  const int xLength = static_cast<int>(xAxis.size());
  // Create a vector to temporarily hold the vertical ('y') axis and populate
  // that
  const int yLength = static_cast<int>(
      VectorHelper::createAxisFromRebinParams(binParams, newAxis));

  // Create the output workspace
  MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
      inputWorkspace, yLength - 1, xLength, xLength - 1);
  // Create a numeric axis to replace the default vertical one
  Axis *const verticalAxis = new BinEdgeAxis(newAxis);
  outputWorkspace->replaceAxis(1, verticalAxis);

  // Now set the axis values
  for (int i = 0; i < yLength - 1; ++i) {
    outputWorkspace->setBinEdges(i, xAxis);
  }

  // Set the axis units
  verticalAxis->unit() = UnitFactory::Instance().create("MomentumTransfer");
  verticalAxis->title() = "|Q|";

  // Set the X axis title (for conversion to MD)
  outputWorkspace->getAxis(0)->title() = "Energy transfer";

  outputWorkspace->setYUnit("");
  outputWorkspace->setYUnitLabel("Intensity");

  return outputWorkspace;
}
Example #4
0
/** Creates the output workspace, setting the X vector to the bins boundaries in
 * Qx.
 *  @return A pointer to the newly-created workspace
 */
API::MatrixWorkspace_sptr
Qxy::setUpOutputWorkspace(API::MatrixWorkspace_const_sptr inputWorkspace) {
  const double max = getProperty("MaxQxy");
  const double delta = getProperty("DeltaQ");

  int bins = static_cast<int>(max / delta);
  if (bins * delta != max)
    ++bins; // Stop at first boundary past MaxQxy if max is not a multiple of
            // delta
  const double startVal = -1.0 * delta * bins;
  bins *= 2; // go from -max to +max
  bins += 1; // Add 1 - this is a histogram

  // Create an output workspace with the same meta-data as the input
  MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
      inputWorkspace, bins - 1, bins, bins - 1);
  // ... but clear the masking from the parameter map as we don't want to carry
  // that over since this is essentially
  // a 2D rebin
  ParameterMap &pmap = outputWorkspace->instrumentParameters();
  pmap.clearParametersByName("masked");

  // Create a numeric axis to replace the vertical one
  Axis *verticalAxis = new BinEdgeAxis(bins);
  outputWorkspace->replaceAxis(1, verticalAxis);

  // Build up the X values
  Kernel::cow_ptr<MantidVec> axis;
  MantidVec &horizontalAxisRef = axis.access();
  horizontalAxisRef.resize(bins);
  for (int i = 0; i < bins; ++i) {
    const double currentVal = startVal + i * delta;
    // Set the X value
    horizontalAxisRef[i] = currentVal;
    // Set the Y value on the axis
    verticalAxis->setValue(i, currentVal);
  }

  // Fill the X vectors in the output workspace
  for (int i = 0; i < bins - 1; ++i) {
    outputWorkspace->setX(i, axis);
    for (int j = 0; j < bins - j; ++j) {
      outputWorkspace->dataY(i)[j] = std::numeric_limits<double>::quiet_NaN();
      outputWorkspace->dataE(i)[j] = std::numeric_limits<double>::quiet_NaN();
    }
  }

  // Set the axis units
  outputWorkspace->getAxis(1)->unit() = outputWorkspace->getAxis(0)->unit() =
      UnitFactory::Instance().create("MomentumTransfer");
  // Set the 'Y' unit (gets confusing here...this is probably a Z axis in this
  // case)
  outputWorkspace->setYUnitLabel("Cross Section (1/cm)");

  setProperty("OutputWorkspace", outputWorkspace);
  return outputWorkspace;
}
Example #5
0
/**Copy the meta data for the input workspace to an output workspace and create
 *it with the desired number of spectra.
 * Also labels the axis of each spectra with Yi, where i is the index
 *
 * @param inws :: The input workspace as a shared pointer
 * @param size :: The number of spectra the workspace should be created with
 * @return The pointer to the newly created workspace
 */
API::MatrixWorkspace_sptr
SplineSmoothing::setupOutputWorkspace(const MatrixWorkspace_sptr &inws,
                                      const int size) const {
    // Must pass a shared pointer instead of a reference as the
    // workspace factory will not accept raw pointers.
    MatrixWorkspace_sptr outputWorkspace =
        WorkspaceFactory::Instance().create(inws, size);

    // create labels for output workspace
    auto tAxis = new API::TextAxis(size);
    for (int i = 0; i < size; ++i) {
        const std::string index = std::to_string(i);
        tAxis->setLabel(i, "Y" + index);
    }
    outputWorkspace->replaceAxis(1, tAxis);

    return outputWorkspace;
}
/// Create the efficiency workspace by combining single spectra workspaces into
/// one.
/// @param labels :: Axis labels for each workspace.
/// @param workspaces :: Workspaces to put together.
MatrixWorkspace_sptr JoinISISPolarizationEfficiencies::createEfficiencies(
    std::vector<std::string> const &labels,
    std::vector<MatrixWorkspace_sptr> const &workspaces) {
  auto interpolatedWorkspaces = interpolateWorkspaces(workspaces);

  auto const &inWS = interpolatedWorkspaces.front();
  MatrixWorkspace_sptr outWS = DataObjects::create<Workspace2D>(
      *inWS, labels.size(), inWS->histogram(0));
  auto axis1 = new TextAxis(labels.size());
  outWS->replaceAxis(1, axis1);
  outWS->getAxis(0)->setUnit("Wavelength");

  for (size_t i = 0; i < interpolatedWorkspaces.size(); ++i) {
    auto &ws = interpolatedWorkspaces[i];
    outWS->setHistogram(i, ws->histogram(0));
    axis1->setLabel(i, labels[i]);
  }

  return outWS;
}
Example #7
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;
}
Example #8
0
/**  Populate output workspace with results
*   @param outWS :: [input/output] Output workspace to populate
*   @param nplots :: [input] Number of histograms
*/
void PlotAsymmetryByLogValue::populateOutputWorkspace(
    MatrixWorkspace_sptr &outWS, int nplots) {

  auto tAxis = new TextAxis(nplots);
  if (nplots == 1) {
    size_t i = 0;
    for (auto &value : m_logValue) {
      outWS->dataX(0)[i] = value.second;
      outWS->dataY(0)[i] = m_redY[value.first];
      outWS->dataE(0)[i] = m_redE[value.first];
      i++;
    }
    tAxis->setLabel(0, "Asymmetry");

  } else {
    size_t i = 0;
    for (auto &value : m_logValue) {
      outWS->dataX(0)[i] = value.second;
      outWS->dataY(0)[i] = m_diffY[value.first];
      outWS->dataE(0)[i] = m_diffE[value.first];
      outWS->dataX(1)[i] = value.second;
      outWS->dataY(1)[i] = m_redY[value.first];
      outWS->dataE(1)[i] = m_redE[value.first];
      outWS->dataX(2)[i] = value.second;
      outWS->dataY(2)[i] = m_greenY[value.first];
      outWS->dataE(2)[i] = m_greenE[value.first];
      outWS->dataX(3)[i] = value.second;
      outWS->dataY(3)[i] = m_sumY[value.first];
      outWS->dataE(3)[i] = m_sumE[value.first];
      i++;
    }
    tAxis->setLabel(0, "Red-Green");
    tAxis->setLabel(1, "Red");
    tAxis->setLabel(2, "Green");
    tAxis->setLabel(3, "Red+Green");
  }
  outWS->replaceAxis(1, tAxis);
  outWS->getAxis(0)->title() = m_logName;
  outWS->setYUnitLabel("Asymmetry");
}
Example #9
0
/**
 * Setup the output workspace
 * @param parent :: A pointer to the input workspace
 * @param newXBins [out] :: An output vector to be filled with the new X bin boundaries
 * @param newYBins [out] :: An output vector to be filled with the new Y bin boundaries
 * @return A pointer to the output workspace
 */
MatrixWorkspace_sptr Rebin2D::createOutputWorkspace(MatrixWorkspace_const_sptr parent,
        MantidVec & newXBins,
        MantidVec & newYBins) const
{
    using Kernel::VectorHelper::createAxisFromRebinParams;
    // First create the two sets of bin boundaries
    const int newXSize = createAxisFromRebinParams(getProperty("Axis1Binning"), newXBins);
    const int newYSize = createAxisFromRebinParams(getProperty("Axis2Binning"), newYBins);
    // and now the workspace
    MatrixWorkspace_sptr outputWS;
    if (!this->useFractionalArea)
    {
        outputWS = WorkspaceFactory::Instance().create(parent,newYSize-1,newXSize,newXSize-1);
    }
    else
    {
        outputWS = WorkspaceFactory::Instance().create("RebinnedOutput", newYSize-1, newXSize, newXSize-1);
        WorkspaceFactory::Instance().initializeFromParent(parent, outputWS, true);
    }
    Axis* const verticalAxis = new NumericAxis(newYSize);
    // Meta data
    verticalAxis->unit() = parent->getAxis(1)->unit();
    verticalAxis->title() = parent->getAxis(1)->title();
    outputWS->replaceAxis(1,verticalAxis);

    // Now set the axis values
    for (size_t i=0; i < static_cast<size_t>(newYSize-1); ++i)
    {
        outputWS->setX(i,newXBins);
        verticalAxis->setValue(i,newYBins[i]);
    }
    // One more to set on the 'y' axis
    verticalAxis->setValue(newYSize-1,newYBins[newYSize-1]);

    return outputWS;
}
Example #10
0
/** Execute the algorithm.
 */
void ResampleX::exec() {
  // generically having access to the input workspace is a good idea
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
  bool inPlace = (inputWS == outputWS); // Rebinning in-place
  m_isDistribution = inputWS->isDistribution();
  m_isHistogram = inputWS->isHistogramData();
  const int numSpectra = static_cast<int>(inputWS->getNumberHistograms());

  // the easy parameters
  m_useLogBinning = getProperty("LogBinning");
  m_numBins = getProperty("NumberBins");
  m_preserveEvents = getProperty("PreserveEvents");

  // determine the xmin/xmax for the workspace
  vector<double> xmins = getProperty("XMin");
  vector<double> xmaxs = getProperty("XMax");
  string error = determineXMinMax(inputWS, xmins, xmaxs);
  if (!error.empty())
    throw std::runtime_error(error);

  bool common_limits = true;
  {
    double xmin_common = xmins[0];
    double xmax_common = xmaxs[0];
    for (size_t i = 1; i < xmins.size(); ++i) {
      if (xmins[i] != xmin_common) {
        common_limits = false;
        break;
      }
      if (xmaxs[i] != xmax_common) {
        common_limits = false;
        break;
      }
    }
  }
  if (common_limits) {
    g_log.debug() << "Common limits between all spectra\n";
  } else {
    g_log.debug() << "Does not have common limits between all spectra\n";
  }

  // start doing actual work
  EventWorkspace_const_sptr inputEventWS =
      boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
  if (inputEventWS != nullptr) {
    if (m_preserveEvents) {
      if (inPlace) {
        g_log.debug() << "Rebinning event workspace in place\n";
      } else {
        g_log.debug() << "Rebinning event workspace out of place\n";
        outputWS = inputWS->clone();
      }
      auto outputEventWS =
          boost::dynamic_pointer_cast<EventWorkspace>(outputWS);

      if (common_limits) {
        // get the delta from the first since they are all the same
        BinEdges xValues(0);
        const double delta = this->determineBinning(xValues.mutableRawData(),
                                                    xmins[0], xmaxs[0]);
        g_log.debug() << "delta = " << delta << "\n";
        outputEventWS->setAllX(xValues);
      } else {
        // initialize progress reporting.
        Progress prog(this, 0.0, 1.0, numSpectra);

        // do the rebinning
        PARALLEL_FOR_IF(Kernel::threadSafe(*inputEventWS, *outputWS))
        for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) {
          PARALLEL_START_INTERUPT_REGION
          BinEdges xValues(0);
          const double delta = this->determineBinning(
              xValues.mutableRawData(), xmins[wkspIndex], xmaxs[wkspIndex]);
          g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta
                        << " xmin=" << xmins[wkspIndex]
                        << " xmax=" << xmaxs[wkspIndex] << "\n";
          outputEventWS->setHistogram(wkspIndex, xValues);
          prog.report(name()); // Report progress
          PARALLEL_END_INTERUPT_REGION
        }
        PARALLEL_CHECK_INTERUPT_REGION
      }
    }    // end if (m_preserveEvents)
    else // event workspace -> matrix workspace
    {
      //--------- Different output, OR you're inplace but not preserving Events
      g_log.information() << "Creating a Workspace2D from the EventWorkspace "
                          << inputEventWS->getName() << ".\n";
      outputWS = create<DataObjects::Workspace2D>(
          *inputWS, numSpectra, HistogramData::BinEdges(m_numBins + 1));

      // Initialize progress reporting.
      Progress prog(this, 0.0, 1.0, numSpectra);

      // Go through all the histograms and set the data
      PARALLEL_FOR_IF(Kernel::threadSafe(*inputEventWS, *outputWS))
      for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) {
        PARALLEL_START_INTERUPT_REGION

        // Set the X axis for each output histogram
        MantidVec xValues;
        const double delta =
            this->determineBinning(xValues, xmins[wkspIndex], xmaxs[wkspIndex]);
        g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta
                      << "\n";
        outputWS->setBinEdges(wkspIndex, xValues);

        // Get a const event list reference. inputEventWS->dataY() doesn't work.
        const EventList &el = inputEventWS->getSpectrum(wkspIndex);
        MantidVec y_data, e_data;
        // The EventList takes care of histogramming.
        el.generateHistogram(xValues, y_data, e_data);

        // Copy the data over.
        outputWS->mutableY(wkspIndex) = std::move(y_data);
        outputWS->mutableE(wkspIndex) = std::move(e_data);

        // Report progress
        prog.report(name());
        PARALLEL_END_INTERUPT_REGION
      }
      PARALLEL_CHECK_INTERUPT_REGION

      // Copy all the axes
      for (int i = 1; i < inputWS->axes(); i++) {
        outputWS->replaceAxis(i, inputWS->getAxis(i)->clone(outputWS.get()));
        outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
      }

      // Copy the units over too.
      for (int i = 0; i < outputWS->axes(); ++i) {
        outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
      }
      outputWS->setYUnit(inputEventWS->YUnit());
      outputWS->setYUnitLabel(inputEventWS->YUnitLabel());
    }
    // Assign it to the output workspace property
    setProperty("OutputWorkspace", outputWS);
    return;
  } else // (inputeventWS != NULL)
Example #11
0
/** Reads the header information from a file containing 2D data
*  @param[in] initalLine the second line in the file
*  @param[out] outWrksp the workspace that the data will be writen to
*  @param[out] axis0Data x-values for the workspace
*  @return a progress bar object
*  @throw NotFoundError if there is compulsulary data is missing from the file
*  @throw invalid_argument if there is an inconsistency in the header information
*/
Progress LoadRKH::read2DHeader(const std::string & initalLine, MatrixWorkspace_sptr & outWrksp, MantidVec & axis0Data)
{
    const std::string XUnit(readUnit(initalLine));

    std::string fileLine;
    std::getline(m_fileIn, fileLine);
    const std::string YUnit(readUnit(fileLine));

    std::getline(m_fileIn, fileLine);
    const std::string intensityUnit(readUnit(fileLine));

    // the next line should contain just "1", but I'm not enforcing that
    std::getline(m_fileIn, fileLine);
    std::string title;
    std::getline(m_fileIn, title);

    std::getline(m_fileIn, fileLine);
    boost::trim(fileLine);
    const int nAxis0Boundaries = boost::lexical_cast<int>(fileLine);
    axis0Data.resize(nAxis0Boundaries);
    readNumEntrys(nAxis0Boundaries, axis0Data);

    std::getline(m_fileIn, fileLine);
    boost::trim(fileLine);
    int nAxis1Boundaries;
    try
    {
        nAxis1Boundaries = boost::lexical_cast<int>(fileLine);
    }
    catch(boost::bad_lexical_cast &)
    {
        // using readNumEntrys() above broke the sequence of getline()s and so try again in case we just read the end of a line
        std::getline(m_fileIn, fileLine);
        boost::trim(fileLine);
        nAxis1Boundaries = boost::lexical_cast<int>(fileLine);
    }
    MantidVec axis1Data(nAxis1Boundaries);
    readNumEntrys(nAxis1Boundaries, axis1Data);

    std::getline(m_fileIn, fileLine);
    // check for the file pointer being left at the end of a line
    if ( fileLine.size() < 5 )
    {
        std::getline(m_fileIn, fileLine);
    }
    Poco::StringTokenizer wsDimensions(fileLine, " ",
                                       Poco::StringTokenizer::TOK_TRIM);
    if ( wsDimensions.count() < 2 )
    {
        throw Exception::NotFoundError("Input file", "dimensions");
    }
    const int nAxis0Values = boost::lexical_cast<int>(wsDimensions[0]);
    const int nAxis1Values = boost::lexical_cast<int>(wsDimensions[1]);

    Progress prog(this, 0.05, 1.0, 2*nAxis1Values);

    // we now have all the data we need to create the output workspace
    outWrksp = WorkspaceFactory::Instance().create(
                   "Workspace2D", nAxis1Values, nAxis0Boundaries, nAxis0Values);
    outWrksp->getAxis(0)->unit() = UnitFactory::Instance().create(XUnit);
    outWrksp->setYUnitLabel(intensityUnit);

    NumericAxis* const axis1 = new Mantid::API::NumericAxis(nAxis1Boundaries);
    axis1->unit() = Mantid::Kernel::UnitFactory::Instance().create(YUnit);
    outWrksp->replaceAxis(1, axis1);
    for ( int i = 0; i < nAxis1Boundaries; ++i )
    {
        axis1->setValue(i, axis1Data[i]);
    }


    outWrksp->setTitle(title);
    // move over the next line which is there to help with loading from Fortran routines
    std::getline(m_fileIn, fileLine);

    return prog;
}
Example #12
0
/**
 * Execute the algorithm.
 */
void RebinByTimeBase::exec() {
  using Mantid::DataObjects::EventWorkspace;
  IEventWorkspace_sptr inWS = getProperty("InputWorkspace");

  if (!boost::dynamic_pointer_cast<EventWorkspace>(inWS)) {
    const std::string algName = this->name();
    throw std::invalid_argument(
        algName + " Algorithm requires an EventWorkspace as an input.");
  }

  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");

  // retrieve the properties
  const std::vector<double> inParams = getProperty("Params");
  std::vector<double> rebinningParams;

  // workspace independent determination of length
  const int histnumber = static_cast<int>(inWS->getNumberHistograms());

  const uint64_t nanoSecondsInASecond = static_cast<uint64_t>(1e9);
  const DateAndTime runStartTime = inWS->run().startTime();
  // The validator only passes parameters with size 1, or 3xn.

  double tStep = 0;
  if (inParams.size() >= 3) {
    // Use the start of the run to offset the times provided by the user. pulse
    // time of the events are absolute.
    const DateAndTime startTime = runStartTime + inParams[0];
    const DateAndTime endTime = runStartTime + inParams[2];
    // Rebinning params in nanoseconds.
    rebinningParams.push_back(
        static_cast<double>(startTime.totalNanoseconds()));
    tStep = inParams[1] * nanoSecondsInASecond;
    rebinningParams.push_back(tStep);
    rebinningParams.push_back(static_cast<double>(endTime.totalNanoseconds()));
  } else if (inParams.size() == 1) {
    const uint64_t xmin = getMinX(inWS);
    const uint64_t xmax = getMaxX(inWS);

    rebinningParams.push_back(static_cast<double>(xmin));
    tStep = inParams[0] * nanoSecondsInASecond;
    rebinningParams.push_back(tStep);
    rebinningParams.push_back(static_cast<double>(xmax));
  }

  // Validate the timestep.
  if (tStep <= 0) {
    throw std::invalid_argument(
        "Cannot have a timestep less than or equal to zero.");
  }

  // Initialize progress reporting.
  Progress prog(this, 0.0, 1.0, histnumber);

  MantidVecPtr XValues_new;
  // create new X axis, with absolute times in seconds.
  const int ntcnew = VectorHelper::createAxisFromRebinParams(
      rebinningParams, XValues_new.access());

  ConvertToRelativeTime transformToRelativeT(runStartTime);

  // Transform the output into relative times in seconds.
  MantidVec OutXValues_scaled(XValues_new->size());
  std::transform(XValues_new->begin(), XValues_new->end(),
                 OutXValues_scaled.begin(), transformToRelativeT);

  outputWS = WorkspaceFactory::Instance().create("Workspace2D", histnumber,
                                                 ntcnew, ntcnew - 1);
  WorkspaceFactory::Instance().initializeFromParent(inWS, outputWS, true);

  // Copy all the axes
  for (int i = 1; i < inWS->axes(); i++) {
    outputWS->replaceAxis(i, inWS->getAxis(i)->clone(outputWS.get()));
    outputWS->getAxis(i)->unit() = inWS->getAxis(i)->unit();
  }

  // X-unit is relative time since the start of the run.
  outputWS->getAxis(0)->unit() = boost::make_shared<Units::Time>();

  // Copy the units over too.
  for (int i = 1; i < outputWS->axes(); ++i) {
    outputWS->getAxis(i)->unit() = inWS->getAxis(i)->unit();
  }
  outputWS->setYUnit(inWS->YUnit());
  outputWS->setYUnitLabel(inWS->YUnitLabel());

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

  // Go through all the histograms and set the data
  doHistogramming(inWS, outputWS, XValues_new, OutXValues_scaled, prog);
}
Example #13
0
/** Execute the algorithm.
 */
void ResampleX::exec() {
  // generically having access to the input workspace is a good idea
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
  bool inPlace = (inputWS == outputWS); // Rebinning in-place
  m_isDistribution = inputWS->isDistribution();
  m_isHistogram = inputWS->isHistogramData();
  int numSpectra = static_cast<int>(inputWS->getNumberHistograms());

  // the easy parameters
  m_useLogBinning = getProperty("LogBinning");
  m_numBins = getProperty("NumberBins");
  m_preserveEvents = getProperty("PreserveEvents");

  // determine the xmin/xmax for the workspace
  vector<double> xmins = getProperty("XMin");
  vector<double> xmaxs = getProperty("XMax");
  string error = determineXMinMax(inputWS, xmins, xmaxs);
  if (!error.empty())
    throw std::runtime_error(error);

  bool common_limits = true;
  {
    double xmin_common = xmins[0];
    double xmax_common = xmaxs[0];
    for (size_t i = 1; i < xmins.size(); ++i) {
      if (xmins[i] != xmin_common) {
        common_limits = false;
        break;
      }
      if (xmaxs[i] != xmax_common) {
        common_limits = false;
        break;
      }
    }
  }
  if (common_limits) {
    g_log.debug() << "Common limits between all spectra\n";
  } else {
    g_log.debug() << "Does not have common limits between all spectra\n";
  }

  // start doing actual work
  EventWorkspace_const_sptr inputEventWS =
      boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
  if (inputEventWS != NULL) {
    if (m_preserveEvents) {
      EventWorkspace_sptr outputEventWS =
          boost::dynamic_pointer_cast<EventWorkspace>(outputWS);
      if (inPlace) {
        g_log.debug() << "Rebinning event workspace in place\n";
      } else {
        g_log.debug() << "Rebinning event workspace out of place\n";

        // copy the event workspace to a new EventWorkspace
        outputEventWS = boost::dynamic_pointer_cast<EventWorkspace>(
            API::WorkspaceFactory::Instance().create(
                "EventWorkspace", inputWS->getNumberHistograms(), 2, 1));
        // copy geometry over.
        API::WorkspaceFactory::Instance().initializeFromParent(
            inputEventWS, outputEventWS, false);
        // copy over the data as well.
        outputEventWS->copyDataFrom((*inputEventWS));
      }

      if (common_limits) {
        // get the delta from the first since they are all the same
        MantidVecPtr xValues;
        double delta =
            this->determineBinning(xValues.access(), xmins[0], xmaxs[0]);
        g_log.debug() << "delta = " << delta << "\n";
        outputEventWS->setAllX(xValues);
      } else {
        // initialize progress reporting.
        Progress prog(this, 0.0, 1.0, numSpectra);

        // do the rebinning
        PARALLEL_FOR2(inputEventWS, outputWS)
        for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) {
          PARALLEL_START_INTERUPT_REGION
          MantidVec xValues;
          double delta = this->determineBinning(xValues, xmins[wkspIndex],
                                                xmaxs[wkspIndex]);
          g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta
                        << " xmin=" << xmins[wkspIndex]
                        << " xmax=" << xmaxs[wkspIndex] << "\n";
          outputEventWS->getSpectrum(wkspIndex)->setX(xValues);
          prog.report(name()); // Report progress
          PARALLEL_END_INTERUPT_REGION
        }
        PARALLEL_CHECK_INTERUPT_REGION
      }

      this->setProperty(
          "OutputWorkspace",
          boost::dynamic_pointer_cast<MatrixWorkspace>(outputEventWS));
    }    // end if (m_preserveEvents)
    else // event workspace -> matrix workspace
    {
      //--------- Different output, OR you're inplace but not preserving Events
      //--- create a Workspace2D -------
      g_log.information() << "Creating a Workspace2D from the EventWorkspace "
                          << inputEventWS->getName() << ".\n";

      // Create a Workspace2D
      // This creates a new Workspace2D through a torturous route using the
      // WorkspaceFactory.
      // The Workspace2D is created with an EMPTY CONSTRUCTOR
      outputWS = WorkspaceFactory::Instance().create("Workspace2D", numSpectra,
                                                     m_numBins, m_numBins - 1);
      WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS,
                                                        true);
      // Initialize progress reporting.
      Progress prog(this, 0.0, 1.0, numSpectra);

      // Go through all the histograms and set the data
      PARALLEL_FOR2(inputEventWS, outputWS)
      for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) {
        PARALLEL_START_INTERUPT_REGION

        // Set the X axis for each output histogram
        MantidVec xValues;
        double delta =
            this->determineBinning(xValues, xmins[wkspIndex], xmaxs[wkspIndex]);
        g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta
                      << "\n";
        outputWS->setX(wkspIndex, xValues);

        // Get a const event list reference. inputEventWS->dataY() doesn't work.
        const EventList &el = inputEventWS->getEventList(wkspIndex);
        MantidVec y_data, e_data;
        // The EventList takes care of histogramming.
        el.generateHistogram(xValues, y_data, e_data);

        // Copy the data over.
        outputWS->dataY(wkspIndex).assign(y_data.begin(), y_data.end());
        outputWS->dataE(wkspIndex).assign(e_data.begin(), e_data.end());

        // Report progress
        prog.report(name());
        PARALLEL_END_INTERUPT_REGION
      }
      PARALLEL_CHECK_INTERUPT_REGION

      // Copy all the axes
      for (int i = 1; i < inputWS->axes(); i++) {
        outputWS->replaceAxis(i, inputWS->getAxis(i)->clone(outputWS.get()));
        outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
      }

      // Copy the units over too.
      for (int i = 0; i < outputWS->axes(); ++i)
        outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
      outputWS->setYUnit(inputEventWS->YUnit());
      outputWS->setYUnitLabel(inputEventWS->YUnitLabel());

      // Assign it to the output workspace property
      setProperty("OutputWorkspace", outputWS);
    }
    return;
  } else // (inputeventWS != NULL)
/**
  * Make 2D MatrixWorkspace
  */
void ConvertMDHistoToMatrixWorkspace::make2DWorkspace() {
  // get the input workspace
  IMDHistoWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");

  // find the non-integrated dimensions
  Mantid::Geometry::VecIMDDimension_const_sptr nonIntegDims =
      inputWorkspace->getNonIntegratedDimensions();

  auto xDim = nonIntegDims[0];
  auto yDim = nonIntegDims[1];

  size_t nx = xDim->getNBins();
  size_t ny = yDim->getNBins();

  size_t xDimIndex =
      inputWorkspace->getDimensionIndexById(xDim->getDimensionId());
  size_t xStride = calcStride(*inputWorkspace, xDimIndex);

  size_t yDimIndex =
      inputWorkspace->getDimensionIndexById(yDim->getDimensionId());
  size_t yStride = calcStride(*inputWorkspace, yDimIndex);

  // get the normalization of the output
  std::string normProp = getPropertyValue("Normalization");
  Mantid::API::MDNormalization normalization;
  if (normProp == "NoNormalization") {
    normalization = NoNormalization;
  } else if (normProp == "VolumeNormalization") {
    normalization = VolumeNormalization;
  } else if (normProp == "NumEventsNormalization") {
    normalization = NumEventsNormalization;
  } else {
    normalization = NoNormalization;
  }
  signal_t inverseVolume =
      static_cast<signal_t>(inputWorkspace->getInverseVolume());

  // create the output workspace
  MatrixWorkspace_sptr outputWorkspace =
      WorkspaceFactory::Instance().create("Workspace2D", ny, nx + 1, nx);

  // set the x-values
  Mantid::MantidVec &X = outputWorkspace->dataX(0);
  double dx = xDim->getBinWidth();
  double x = xDim->getMinimum();
  for (auto ix = X.begin(); ix != X.end(); ++ix, x += dx) {
    *ix = x;
  }

  // set the y-values and errors
  for (size_t i = 0; i < ny; ++i) {
    if (i > 0)
      outputWorkspace->setX(i, X);
    auto &Y = outputWorkspace->dataY(i);
    auto &E = outputWorkspace->dataE(i);

    size_t yOffset = i * yStride;
    for (size_t j = 0; j < nx; ++j) {
      size_t linearIndex = yOffset + j * xStride;
      signal_t signal = inputWorkspace->getSignalArray()[linearIndex];
      signal_t error = inputWorkspace->getErrorSquaredArray()[linearIndex];
      // apply normalization
      if (normalization != NoNormalization) {
        if (normalization == VolumeNormalization) {
          signal *= inverseVolume;
          error *= inverseVolume;
        } else // normalization == NumEventsNormalization
        {
          signal_t factor = inputWorkspace->getNumEventsArray()[linearIndex];
          factor = factor != 0.0 ? 1.0 / factor : 1.0;
          signal *= factor;
          error *= factor;
        }
      }
      Y[j] = signal;
      E[j] = sqrt(error);
    }
  }

  // set the first axis
  auto labelX = boost::dynamic_pointer_cast<Kernel::Units::Label>(
      Kernel::UnitFactory::Instance().create("Label"));
  labelX->setLabel(xDim->getName());
  outputWorkspace->getAxis(0)->unit() = labelX;

  // set the second axis
  auto yAxis = new NumericAxis(ny);
  for (size_t i = 0; i < ny; ++i) {
    yAxis->setValue(i, yDim->getX(i));
  }
  auto labelY = boost::dynamic_pointer_cast<Kernel::Units::Label>(
      Kernel::UnitFactory::Instance().create("Label"));
  labelY->setLabel(yDim->getName());
  yAxis->unit() = labelY;
  outputWorkspace->replaceAxis(1, yAxis);

  // set the "units" for the y values
  outputWorkspace->setYUnitLabel("Signal");

  // done
  setProperty("OutputWorkspace", outputWorkspace);
}
Example #15
0
/** Executes the rebin algorithm
*
*  @throw runtime_error Thrown if the bin range does not intersect the range of
*the input workspace
*/
void Rebin::exec() {
  // Get the input workspace
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");

  // Are we preserving event workspace-iness?
  bool PreserveEvents = getProperty("PreserveEvents");

  // Rebinning in-place
  bool inPlace = (inputWS == outputWS);

  std::vector<double> rbParams =
      rebinParamsFromInput(getProperty("Params"), *inputWS, g_log);

  const bool dist = inputWS->isDistribution();
  const bool isHist = inputWS->isHistogramData();

  // workspace independent determination of length
  const int histnumber = static_cast<int>(inputWS->getNumberHistograms());

  //-------------------------------------------------------

  bool fullBinsOnly = getProperty("FullBinsOnly");

  MantidVecPtr XValues_new;
  // create new output X axis
  const int ntcnew = VectorHelper::createAxisFromRebinParams(
      rbParams, XValues_new.access(), true, fullBinsOnly);

  //---------------------------------------------------------------------------------
  // Now, determine if the input workspace is actually an EventWorkspace
  EventWorkspace_const_sptr eventInputWS =
      boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);

  if (eventInputWS != NULL) {
    //------- EventWorkspace as input -------------------------------------
    EventWorkspace_sptr eventOutputWS =
        boost::dynamic_pointer_cast<EventWorkspace>(outputWS);

    if (inPlace && PreserveEvents) {
      // -------------Rebin in-place, preserving events
      // ----------------------------------------------
      // This only sets the X axis. Actual rebinning will be done upon data
      // access.
      eventOutputWS->setAllX(XValues_new);
      this->setProperty(
          "OutputWorkspace",
          boost::dynamic_pointer_cast<MatrixWorkspace>(eventOutputWS));
    } else if (!inPlace && PreserveEvents) {
      // -------- NOT in-place, but you want to keep events for some reason.
      // ----------------------
      // Must copy the event workspace to a new EventWorkspace (and bin that).

      // Make a brand new EventWorkspace
      eventOutputWS = boost::dynamic_pointer_cast<EventWorkspace>(
          API::WorkspaceFactory::Instance().create(
              "EventWorkspace", inputWS->getNumberHistograms(), 2, 1));
      // Copy geometry over.
      API::WorkspaceFactory::Instance().initializeFromParent(
          inputWS, eventOutputWS, false);
      // You need to copy over the data as well.
      eventOutputWS->copyDataFrom((*eventInputWS));

      // This only sets the X axis. Actual rebinning will be done upon data
      // access.
      eventOutputWS->setAllX(XValues_new);

      // Cast to the matrixOutputWS and save it
      this->setProperty(
          "OutputWorkspace",
          boost::dynamic_pointer_cast<MatrixWorkspace>(eventOutputWS));
    } else {
      //--------- Different output, OR you're inplace but not preserving Events
      //--- create a Workspace2D -------
      g_log.information() << "Creating a Workspace2D from the EventWorkspace "
                          << eventInputWS->getName() << ".\n";

      // Create a Workspace2D
      // This creates a new Workspace2D through a torturous route using the
      // WorkspaceFactory.
      // The Workspace2D is created with an EMPTY CONSTRUCTOR
      outputWS = WorkspaceFactory::Instance().create("Workspace2D", histnumber,
                                                     ntcnew, ntcnew - 1);
      WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS,
                                                        true);

      // Initialize progress reporting.
      Progress prog(this, 0.0, 1.0, histnumber);

      // Go through all the histograms and set the data
      PARALLEL_FOR3(inputWS, eventInputWS, outputWS)
      for (int i = 0; i < histnumber; ++i) {
        PARALLEL_START_INTERUPT_REGION

        // Set the X axis for each output histogram
        outputWS->setX(i, XValues_new);

        // Get a const event list reference. eventInputWS->dataY() doesn't work.
        const EventList &el = eventInputWS->getEventList(i);
        MantidVec y_data, e_data;
        // The EventList takes care of histogramming.
        el.generateHistogram(*XValues_new, y_data, e_data);

        // Copy the data over.
        outputWS->dataY(i).assign(y_data.begin(), y_data.end());
        outputWS->dataE(i).assign(e_data.begin(), e_data.end());

        // Report progress
        prog.report(name());
        PARALLEL_END_INTERUPT_REGION
      }
      PARALLEL_CHECK_INTERUPT_REGION

      // Copy all the axes
      for (int i = 1; i < inputWS->axes(); i++) {
        outputWS->replaceAxis(i, inputWS->getAxis(i)->clone(outputWS.get()));
        outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
      }

      // Copy the units over too.
      for (int i = 0; i < outputWS->axes(); ++i)
        outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
      outputWS->setYUnit(eventInputWS->YUnit());
      outputWS->setYUnitLabel(eventInputWS->YUnitLabel());

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

  } // END ---- EventWorkspace
/**
*   Executes the algorithm
*/
void PlotAsymmetryByLogValue::exec()
{
    m_forward_list = getProperty("ForwardSpectra");
    m_backward_list = getProperty("BackwardSpectra");
    m_autogroup = ( m_forward_list.size() == 0 && m_backward_list.size() == 0);

    //double alpha = getProperty("Alpha");

    std::string logName = getProperty("LogValue");

    int red = getProperty("Red");
    int green = getProperty("Green");

    std::string stype = getProperty("Type");
    m_int = stype == "Integral";

    std::string firstFN = getProperty("FirstRun");
    std::string lastFN = getProperty("LastRun");

    std::string ext = firstFN.substr(firstFN.find_last_of("."));

    firstFN.erase(firstFN.size()-4);
    lastFN.erase(lastFN.size()-4);

    std::string fnBase = firstFN;
    size_t i = fnBase.size()-1;
    while(isdigit(fnBase[i]))  i--;
    if (i == fnBase.size()-1)
    {
        g_log.error("File name must end with a number.");
        throw Exception::FileError("File name must end with a number.",firstFN);
    }
    fnBase.erase(i+1);

    firstFN.erase(0,fnBase.size());
    lastFN.erase(0,fnBase.size());

    size_t is = atoi(firstFN.c_str());  // starting run number
    size_t ie = atoi(lastFN.c_str());   // last run number
    int w  = static_cast<int>(firstFN.size());

    // The number of runs
    size_t npoints = ie - is + 1;

    // Create the 2D workspace for the output
    int nplots = green != EMPTY_INT() ? 4 : 1;
    MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create("Workspace2D",
                                 nplots,          //  the number of plots
                                 npoints,    //  the number of data points on a plot
                                 npoints     //  it's not a histogram
                                                                    );
    TextAxis* tAxis = new TextAxis(nplots);
    if (nplots == 1)
    {
        tAxis->setLabel(0,"Asymmetry");
    }
    else
    {
        tAxis->setLabel(0,"Red-Green");
        tAxis->setLabel(1,"Red");
        tAxis->setLabel(2,"Green");
        tAxis->setLabel(3,"Red+Green");
    }
    outWS->replaceAxis(1,tAxis);

    Progress progress(this,0,1,ie-is+2);
    for(size_t i=is; i<=ie; i++)
    {
        std::ostringstream fn,fnn;
        fnn << std::setw(w) << std::setfill('0') << i ;
        fn << fnBase << fnn.str() << ext;

        // Load a muon nexus file with auto_group set to true
        IAlgorithm_sptr loadNexus = createChildAlgorithm("LoadMuonNexus");
        loadNexus->setPropertyValue("Filename", fn.str());
        loadNexus->setPropertyValue("OutputWorkspace","tmp"+fnn.str());
        if (m_autogroup)
            loadNexus->setPropertyValue("AutoGroup","1");
        loadNexus->execute();

        std::string wsProp = "OutputWorkspace";

        DataObjects::Workspace2D_sptr ws_red;
        DataObjects::Workspace2D_sptr ws_green;

        // Run through the periods of the loaded file and do calculations on the selected ones
        Workspace_sptr tmp = loadNexus->getProperty(wsProp);
        WorkspaceGroup_sptr wsGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(tmp);
        if (!wsGroup)
        {
            ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmp);
            TimeSeriesProperty<double>* logp =
                dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName));
            if (!logp)
            {
                throw std::invalid_argument("Log "+logName+" does not exist or not a double type");
            }
            double Y,E;
            calcIntAsymmetry(ws_red,Y,E);
            outWS->dataY(0)[i-is] = Y;
            outWS->dataX(0)[i-is] = logp->lastValue();
            outWS->dataE(0)[i-is] = E;
        }
        else
        {

            for( int period = 1; period <= wsGroup->getNumberOfEntries(); ++period )
            {
                std::stringstream suffix;
                suffix << period;
                wsProp = "OutputWorkspace_" + suffix.str();// form the property name for higher periods
                // Do only one period
                if (green == EMPTY_INT() && period == red)
                {
                    Workspace_sptr tmpff = loadNexus->getProperty(wsProp);
                    ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmpff);
                    TimeSeriesProperty<double>* logp =
                        dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName));
                    if (!logp)
                    {
                        throw std::invalid_argument("Log "+logName+" does not exist or not a double type");
                    }
                    double Y,E;
                    calcIntAsymmetry(ws_red,Y,E);
                    outWS->dataY(0)[i-is] = Y;
                    outWS->dataX(0)[i-is] = logp->lastValue();
                    outWS->dataE(0)[i-is] = E;
                }
                else // red & green
                {
                    if (period == red)
                    {
                        Workspace_sptr temp = loadNexus->getProperty(wsProp);
                        ws_red = boost::dynamic_pointer_cast<Workspace2D>(temp);
                    }
                    if (period == green)
                    {
                        Workspace_sptr temp = loadNexus->getProperty(wsProp);
                        ws_green = boost::dynamic_pointer_cast<Workspace2D>(temp);
                    }
                }

            }
            // red & green claculation
            if (green != EMPTY_INT())
            {
                if (!ws_red || !ws_green)
                    throw std::invalid_argument("Red or green period is out of range");
                TimeSeriesProperty<double>* logp =
                    dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName));
                if (!logp)
                {
                    throw std::invalid_argument("Log "+logName+" does not exist or not a double type");
                }
                double Y,E;
                double Y1,E1;
                calcIntAsymmetry(ws_red,Y,E);
                calcIntAsymmetry(ws_green,Y1,E1);
                outWS->dataY(1)[i-is] = Y;
                outWS->dataX(1)[i-is] = logp->lastValue();
                outWS->dataE(1)[i-is] = E;

                outWS->dataY(2)[i-is] = Y1;
                outWS->dataX(2)[i-is] = logp->lastValue();
                outWS->dataE(2)[i-is] = E1;

                outWS->dataY(3)[i-is] = Y + Y1;
                outWS->dataX(3)[i-is] = logp->lastValue();
                outWS->dataE(3)[i-is] = sqrt(E*E+E1*E1);

                // move to last for safety since some grouping takes place in the
                // calcIntAsymmetry call below
                calcIntAsymmetry(ws_red,ws_green,Y,E);
                outWS->dataY(0)[i-is] = Y;
                outWS->dataX(0)[i-is] = logp->lastValue();
                outWS->dataE(0)[i-is] = E;
            }
            else if (!ws_red)
                throw std::invalid_argument("Red period is out of range");

        }
        progress.report();
    }

    outWS->getAxis(0)->title() = logName;
    outWS->setYUnitLabel("Asymmetry");

    // Assign the result to the output workspace property
    setProperty("OutputWorkspace", outWS);

}
Example #17
0
/// Exec function
void CreateWorkspace::exec()
{
    // Contortions to get at the vector in the property without copying it
    const Property * const dataXprop = getProperty("DataX");
    const Property * const dataYprop = getProperty("DataY");
    const Property * const dataEprop = getProperty("DataE");
    const std::vector<double>& dataX = *dynamic_cast<const ArrayProperty<double>*>(dataXprop);
    const std::vector<double>& dataY = *dynamic_cast<const ArrayProperty<double>*>(dataYprop);
    const std::vector<double>& dataE = *dynamic_cast<const ArrayProperty<double>*>(dataEprop);

    const int nSpec = getProperty("NSpec");
    const std::string xUnit = getProperty("UnitX");
    const std::string vUnit = getProperty("VerticalAxisUnit");
    const std::vector<std::string> vAxis = getProperty("VerticalAxisValues");
    std::string parentWorkspace = getPropertyValue("ParentWorkspace");

    if ( ( vUnit != "SpectraNumber" ) && ( static_cast<int>(vAxis.size()) != nSpec ) )
    {
        throw std::invalid_argument("Number of y-axis labels must match number of histograms.");
    }

    // Verify length of vectors makes sense with NSpec
    if ( ( dataY.size() % nSpec ) != 0 )
    {
        throw std::invalid_argument("Length of DataY must be divisible by NSpec");
    }
    const std::size_t ySize = dataY.size() / nSpec;

    // Check whether the X values provided are to be re-used for (are common to) every spectrum
    const bool commonX( dataX.size() == ySize || dataX.size() == ySize+1 );

    std::size_t xSize;
    MantidVecPtr XValues;
    if ( commonX )
    {
        xSize = dataX.size();
        XValues.access() = dataX;
    }
    else
    {
        if ( dataX.size() % nSpec != 0 )
        {
            throw std::invalid_argument("Length of DataX must be divisible by NSpec");
        }

        xSize = static_cast<int>(dataX.size()) / nSpec;
        if ( xSize < ySize || xSize > ySize + 1 )
        {
            throw std::runtime_error("DataX width must be as DataY or +1");
        }

    }

    const bool dataE_provided = !dataE.empty();
    if ( dataE_provided && dataY.size() != dataE.size() )
    {
        throw std::runtime_error("DataE (if provided) must be the same size as DataY");
    }

    MatrixWorkspace_sptr parentWS;
    if (!parentWorkspace.empty())
    {
        try
        {
            parentWS = boost::dynamic_pointer_cast<MatrixWorkspace>( AnalysisDataService::Instance().retrieve(parentWorkspace) );
        }
        catch(...)
        {
            g_log.warning("Parent workspace not found");
            // ignore parent workspace
        }
    }

    // Create the OutputWorkspace
    MatrixWorkspace_sptr outputWS;
    if (parentWS)
    {
        // if parent is defined use it to initialise the workspace
        outputWS = WorkspaceFactory::Instance().create(parentWS, nSpec, xSize, ySize);
    }
    else
    {
        // otherwise create a blank workspace
        outputWS = WorkspaceFactory::Instance().create("Workspace2D", nSpec, xSize, ySize);
    }

    Progress progress(this,0,1,nSpec);

    PARALLEL_FOR1(outputWS)
    for ( int i = 0; i < nSpec; i++ )
    {
        PARALLEL_START_INTERUPT_REGION

        const std::vector<double>::difference_type xStart = i*xSize;
        const std::vector<double>::difference_type xEnd = xStart + xSize;
        const std::vector<double>::difference_type yStart = i*ySize;
        const std::vector<double>::difference_type yEnd = yStart + ySize;

        // Just set the pointer if common X bins. Otherwise, copy in the right chunk (as we do for Y).
        if ( commonX )
        {
            outputWS->setX(i,XValues);
        }
        else
        {
            outputWS->dataX(i).assign(dataX.begin()+xStart,dataX.begin()+xEnd);
        }

        outputWS->dataY(i).assign(dataY.begin()+yStart,dataY.begin()+yEnd);

        if ( dataE_provided) outputWS->dataE(i).assign(dataE.begin()+yStart,dataE.begin()+yEnd);

        progress.report();
        PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    // Set the Unit of the X Axis
    try
    {
        outputWS->getAxis(0)->unit() = UnitFactory::Instance().create(xUnit);
    }
    catch ( Exception::NotFoundError & )
    {
        outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("Label");
        Unit_sptr unit = outputWS->getAxis(0)->unit();
        boost::shared_ptr<Units::Label> label = boost::dynamic_pointer_cast<Units::Label>(unit);
        label->setLabel(xUnit, xUnit);
    }

    // Populate the VerticalAxis. A spectra one is there by default with a 1->N mapping
    if ( vUnit != "SpectraNumber" )
    {
        if ( vUnit == "Text" )
        {
            TextAxis* const newAxis = new TextAxis(vAxis.size());
            outputWS->replaceAxis(1, newAxis);
            for ( size_t i = 0; i < vAxis.size(); i++ )
            {
                newAxis->setLabel(i, vAxis[i]);
            }
        }
        else
        {
            NumericAxis* const newAxis = new NumericAxis(vAxis.size());
            newAxis->unit() = UnitFactory::Instance().create(vUnit);
            outputWS->replaceAxis(1, newAxis);
            for ( size_t i = 0; i < vAxis.size(); i++ )
            {
                try
                {
                    newAxis->setValue(i, boost::lexical_cast<double, std::string>(vAxis[i]) );
                }
                catch ( boost::bad_lexical_cast & )
                {
                    throw std::invalid_argument("CreateWorkspace - YAxisValues property could not be converted to a double.");
                }
            }
        }
    }

    // Set distribution flag
    outputWS->isDistribution(getProperty("Distribution"));

    // Set Y Unit label
    if (!parentWS || !getPropertyValue("YUnitLabel").empty())
    {
        outputWS->setYUnitLabel(getProperty("YUnitLabel"));
    }

    // Set Workspace Title
    if (!parentWS || !getPropertyValue("WorkspaceTitle").empty())
    {
        outputWS->setTitle(getProperty("WorkspaceTitle"));
    }

    // Set OutputWorkspace property
    setProperty("OutputWorkspace", outputWS);
}
Example #18
0
/**
 * Read histogram data
 * @param histogramEntries map of the file entries that have histogram
 * @param outputGroup pointer to the workspace group
 * @param nxFile Reads data from inside first first top entry
 */
void LoadMcStas::readHistogramData(
    const std::map<std::string, std::string> &histogramEntries,
    WorkspaceGroup_sptr &outputGroup, ::NeXus::File &nxFile) {

  std::string nameAttrValueYLABEL;

  for (const auto &histogramEntry : histogramEntries) {
    const std::string &dataName = histogramEntry.first;
    const std::string &dataType = histogramEntry.second;

    // open second level entry
    nxFile.openGroup(dataName, dataType);

    // grap title to use to e.g. create workspace name
    std::string nameAttrValueTITLE;
    nxFile.getAttr("filename", nameAttrValueTITLE);

    if (nxFile.hasAttr("ylabel")) {
      nxFile.getAttr("ylabel", nameAttrValueYLABEL);
    }

    // Find the axis names
    auto nxdataEntries = nxFile.getEntries();
    std::string axis1Name, axis2Name;
    for (auto &nxdataEntry : nxdataEntries) {
      if (nxdataEntry.second == "NXparameters")
        continue;
      if (nxdataEntry.first == "ncount")
        continue;
      nxFile.openData(nxdataEntry.first);

      if (nxFile.hasAttr("axis")) {
        int axisNo(0);
        nxFile.getAttr("axis", axisNo);
        if (axisNo == 1)
          axis1Name = nxdataEntry.first;
        else if (axisNo == 2)
          axis2Name = nxdataEntry.first;
        else
          throw std::invalid_argument("Unknown axis number");
      }
      nxFile.closeData();
    }

    std::vector<double> axis1Values, axis2Values;
    nxFile.readData<double>(axis1Name, axis1Values);
    if (axis2Name.length() == 0) {
      axis2Name = nameAttrValueYLABEL;
      axis2Values.push_back(0.0);
    } else {
      nxFile.readData<double>(axis2Name, axis2Values);
    }

    const size_t axis1Length = axis1Values.size();
    const size_t axis2Length = axis2Values.size();
    g_log.debug() << "Axis lengths=" << axis1Length << " " << axis2Length
                  << '\n';

    // Require "data" field
    std::vector<double> data;
    nxFile.readData<double>("data", data);

    // Optional errors field
    std::vector<double> errors;
    try {
      nxFile.readData<double>("errors", errors);
    } catch (::NeXus::Exception &) {
      g_log.information() << "Field " << dataName
                          << " contains no error information.\n";
    }

    // close second level entry
    nxFile.closeGroup();

    MatrixWorkspace_sptr ws = WorkspaceFactory::Instance().create(
        "Workspace2D", axis2Length, axis1Length, axis1Length);
    Axis *axis1 = ws->getAxis(0);
    axis1->title() = axis1Name;
    // Set caption
    auto lblUnit = boost::make_shared<Units::Label>();
    lblUnit->setLabel(axis1Name, "");
    axis1->unit() = lblUnit;

    Axis *axis2 = new NumericAxis(axis2Length);
    axis2->title() = axis2Name;
    // Set caption
    lblUnit = boost::make_shared<Units::Label>();
    lblUnit->setLabel(axis2Name, "");
    axis2->unit() = lblUnit;

    ws->setYUnit(axis2Name);
    ws->replaceAxis(1, axis2);

    for (size_t wsIndex = 0; wsIndex < axis2Length; ++wsIndex) {
      auto &dataY = ws->dataY(wsIndex);
      auto &dataE = ws->dataE(wsIndex);
      auto &dataX = ws->dataX(wsIndex);

      for (size_t j = 0; j < axis1Length; ++j) {
        // Data is stored in column-major order so we are translating to
        // row major for Mantid
        const size_t fileDataIndex = j * axis2Length + wsIndex;

        dataY[j] = data[fileDataIndex];
        dataX[j] = axis1Values[j];
        if (!errors.empty())
          dataE[j] = errors[fileDataIndex];
      }
      axis2->setValue(wsIndex, axis2Values[wsIndex]);
    }

    // set the workspace title
    ws->setTitle(nameAttrValueTITLE);

    // use the workspace title to create the workspace name
    std::replace(nameAttrValueTITLE.begin(), nameAttrValueTITLE.end(), ' ',
                 '_');

    // ensure that specified name is given to workspace (eventWS) when added to
    // outputGroup
    std::string nameOfGroupWS = getProperty("OutputWorkspace");
    std::string nameUserSee = nameAttrValueTITLE + "_" + nameOfGroupWS;
    std::string extraProperty =
        "Outputworkspace_dummy_" + std::to_string(m_countNumWorkspaceAdded);
    declareProperty(Kernel::make_unique<WorkspaceProperty<Workspace>>(
        extraProperty, nameUserSee, Direction::Output));
    setProperty(extraProperty, boost::static_pointer_cast<Workspace>(ws));
    m_countNumWorkspaceAdded++; // need to increment to ensure extraProperty are
                                // unique

    // Make Mantid store the workspace in the group
    outputGroup->addWorkspace(ws);
  }
  nxFile.closeGroup();

} // finish