예제 #1
0
void ConvertEmptyToTof::setTofInWS(const std::vector<double> &tofAxis,
                                   API::MatrixWorkspace_sptr outputWS) {

  const size_t numberOfSpectra = m_inputWS->getNumberHistograms();
  int64_t numberOfSpectraInt64 =
      static_cast<int64_t>(numberOfSpectra); // cast to make openmp happy

  g_log.debug() << "Setting the TOF X Axis for numberOfSpectra="
                << numberOfSpectra << '\n';

  Progress prog(this, 0.0, 0.2, numberOfSpectra);
  PARALLEL_FOR2(m_inputWS, outputWS)
  for (int64_t i = 0; i < numberOfSpectraInt64; ++i) {
    PARALLEL_START_INTERUPT_REGION
    // Just copy over
    outputWS->dataY(i) = m_inputWS->readY(i);
    outputWS->dataE(i) = m_inputWS->readE(i);
    // copy
    outputWS->setX(i, tofAxis);

    prog.report();
    PARALLEL_END_INTERUPT_REGION
  } // end for i
  PARALLEL_CHECK_INTERUPT_REGION
  outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
}
예제 #2
0
/**
 * Converts the input workspaces to spectrum axis to ElasticQ and adds it to the
 * ADS to be used by PlotPeakBylogValue
 * @param inputWs - The MatrixWorkspace to be converted
 * @param wsName - The desired name of the output workspace
 */
void ConvolutionFitSequential::convertInputToElasticQ(
    API::MatrixWorkspace_sptr &inputWs, const std::string &wsName) {
  auto axis = inputWs->getAxis(1);
  if (axis->isSpectra()) {
    auto convSpec = createChildAlgorithm("ConvertSpectrumAxis");
    // Store in ADS to allow use by PlotPeakByLogValue
    convSpec->setAlwaysStoreInADS(true);
    convSpec->setProperty("InputWorkSpace", inputWs);
    convSpec->setProperty("OutputWorkSpace", wsName);
    convSpec->setProperty("Target", "ElasticQ");
    convSpec->setProperty("EMode", "Indirect");
    convSpec->executeAsChildAlg();
  } else if (axis->isNumeric()) {
    // Check that units are Momentum Transfer
    if (axis->unit()->unitID() != "MomentumTransfer") {
      throw std::runtime_error("Input must have axis values of Q");
    }
    auto cloneWs = createChildAlgorithm("CloneWorkspace");
    // Store in ADS to allow use by PlotPeakByLogValue
    cloneWs->setAlwaysStoreInADS(true);
    cloneWs->setProperty("InputWorkspace", inputWs);
    cloneWs->setProperty("OutputWorkspace", wsName);
    cloneWs->executeAsChildAlg();
  } else {
    throw std::runtime_error(
        "Input workspace must have either spectra or numeric axis.");
  }
}
예제 #3
0
/**
* Loads the information contained in non-Spectra (ie, Text or Numeric) axis in the Nexus
* file into the workspace.
* @param local_workspace :: pointer to workspace object
* @param data :: reference to the NeXuS data for the axis
*/
void LoadNexusProcessed::loadNonSpectraAxis(API::MatrixWorkspace_sptr local_workspace, NXData & data)
{
  Mantid::API::Axis* axis = local_workspace->getAxis(1);

  if ( axis->isNumeric() )
  {
    NXDouble axisData = data.openNXDouble("axis2");
    axisData.load();
    for ( int i = 0; i < static_cast<int>(axis->length()); i++ )
    {
      axis->setValue(i, axisData[i]);
    }
  }
  else if ( axis->isText() )
  {
    // We must cast the axis object to TextAxis so we may use ->setLabel
    Mantid::API::TextAxis* textAxis = dynamic_cast<Mantid::API::TextAxis*>(axis);
    NXChar axisData = data.openNXChar("axis2");
    axisData.load();
    std::string axisLabels = axisData();    
    // Use boost::tokenizer to split up the input
    boost::char_separator<char> sep("\n");
    boost::tokenizer<boost::char_separator<char> > tokenizer(axisLabels, sep);
    boost::tokenizer<boost::char_separator<char> >::iterator tokIter;
    int i = 0;
    for ( tokIter = tokenizer.begin(); tokIter != tokenizer.end(); ++tokIter )
    {
      textAxis->setLabel(i, *tokIter);
      ++i;
    }
  }
}
예제 #4
0
/** Checks and retrieves the monitor spectrum out of the input workspace
 *  @param inputWorkspace The input workspace.
 *  @param wsID The workspace ID.
 *  @returns A workspace containing the monitor spectrum only
 *  @throw std::runtime_error If the properties are invalid
 */
API::MatrixWorkspace_sptr NormaliseToMonitor::getMonitorWorkspace(API::MatrixWorkspace_sptr inputWorkspace,int &wsID)
{
  // Get the workspace from the ADS. Will throw if it's not there.
  MatrixWorkspace_sptr monitorWS = getProperty("MonitorWorkspace");
  wsID = getProperty("MonitorWorkspaceIndex");
  // Check that it's a single spectrum workspace
  if ( static_cast<int>(monitorWS->getNumberHistograms()) < wsID )
  {
    throw std::runtime_error("The MonitorWorkspace must contain the MonitorWorkspaceIndex");
  }
  // Check that the two workspace come from the same instrument
  if ( monitorWS->getInstrument()->getName() != inputWorkspace->getInstrument()->getName() )
  {
    throw std::runtime_error("The Input and Monitor workspaces must come from the same instrument");
  }
  // Check that they're in the same units
  if ( monitorWS->getAxis(0)->unit()->unitID() != inputWorkspace->getAxis(0)->unit()->unitID() )
  {
    throw std::runtime_error("The Input and Monitor workspaces must have the same unit");
  }

  // In this case we need to test whether the bins in the monitor workspace match
  m_commonBins = (m_commonBins &&
                  API::WorkspaceHelpers::matchingBins(inputWorkspace,monitorWS,true) );

  // If the workspace passes all these tests, make a local copy because it will get changed
  return this->extractMonitorSpectrum(monitorWS,wsID);
}
예제 #5
0
  void StripVanadiumPeaks2::exec(){

    // 1. Process input/output
    API::MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
    std::string outputWSName = getPropertyValue("OutputWorkspace");
    int singleIndex = getProperty("WorkspaceIndex");
    int param_fwhm = getProperty("FWHM");
    int param_tolerance = getProperty("Tolerance");

    bool singleSpectrum = !isEmpty(singleIndex);

    // 2. Call StripPeaks
    std::string peakpositions;
    std::string unit = inputWS->getAxis(0)->unit()->unitID();
    if (unit == "dSpacing")
    {
      peakpositions = "0.5044,0.5191,0.5350,0.5526,0.5936,0.6178,0.6453,0.6768,0.7134,0.7566,0.8089,0.8737,0.9571,1.0701,1.2356,1.5133,2.1401";
    }
    else if (unit == "MomentumTransfer")
    {
      g_log.error() << "Unit MomentumTransfer (Q-space) is NOT supported by StripVanadiumPeaks now.\n";
      throw std::invalid_argument("Q-space is not supported");
      // Comment out next line as it won't be reached.
      //peakpositions = "2.9359, 4.1520, 5.0851, 5.8716, 6.5648, 7.1915, 7.7676, 8.3045, 8.8074, 9.2837, 9.7368, 10.1703, 10.5849, 11.3702, 11.7443, 12.1040, 12.4568";

    } else {
      g_log.error() << "Unit " << unit << " Is NOT supported by StripVanadiumPeaks, which only supports d-spacing" << std::endl;
      throw std::invalid_argument("Not supported unit");
    }

    // Call StripPeak
    double pro0 = 0.0;
    double prof = 1.0;
    bool sublog = true;
    IAlgorithm_sptr stripPeaks = createChildAlgorithm("StripPeaks", pro0, prof, sublog);
    stripPeaks->setProperty("InputWorkspace", inputWS);
    stripPeaks->setPropertyValue("OutputWorkspace", outputWSName);
    stripPeaks->setProperty("FWHM", param_fwhm);
    stripPeaks->setProperty("Tolerance", param_tolerance);
    stripPeaks->setPropertyValue("PeakPositions", peakpositions);
    stripPeaks->setProperty<std::string>("BackgroundType", getProperty("BackgroundType"));
    stripPeaks->setProperty<bool>("HighBackground", getProperty("HighBackground"));
    if (singleSpectrum){
      stripPeaks->setProperty("WorkspaceIndex", singleIndex);
    }
    stripPeaks->setProperty<double>("PeakPositionTolerance", getProperty("PeakPositionTolerance"));

    stripPeaks->executeAsChildAlg();

    // 3. Get and set output workspace
    // API::MatrixWorkspace_sptr outputWS = AnalysisDataService::Instance().retrieveWS<API::MatrixWorkspace_sptr>(outputWSName);
    // boost::shared_ptr<API::Workspace> outputWS = AnalysisDataService::Instance().retrieve(outputWSName);
    API::MatrixWorkspace_sptr outputWS = stripPeaks->getProperty("OutputWorkspace");

    this->setProperty("OutputWorkspace", outputWS);

    return;
  }
예제 #6
0
/** Initialization method:
@param bkgWS    -- shared pointer to the workspace which contains background
@param sourceWS -- shared pointer to the workspace to remove background from
@param emode    -- energy conversion mode used during internal units conversion
(0 -- elastic, 1-direct, 2 indirect, as defined in Units conversion
@param pLog     -- pointer to the logger class which would report errors
@param nThreads -- number of threads to be used for background removal
@param inPlace  -- if the background removal occurs from the existing workspace
or target workspace has to be cloned.
*/
void BackgroundHelper::initialize(const API::MatrixWorkspace_const_sptr &bkgWS,
                                  const API::MatrixWorkspace_sptr &sourceWS,
                                  int emode, Kernel::Logger *pLog, int nThreads,
                                  bool inPlace) {
  m_bgWs = bkgWS;
  m_wkWS = sourceWS;
  m_Emode = emode;
  m_pgLog = pLog;
  m_inPlace = inPlace;

  std::string bgUnits = bkgWS->getAxis(0)->unit()->unitID();
  if (bgUnits != "TOF")
    throw std::invalid_argument(" Background Workspace: " + bkgWS->getName() +
                                " should be in the units of TOF");

  if (!(bkgWS->getNumberHistograms() == 1 ||
        sourceWS->getNumberHistograms() == bkgWS->getNumberHistograms()))
    throw std::invalid_argument(" Background Workspace: " + bkgWS->getName() +
                                " should have the same number of spectra as "
                                "source workspace or be a single histogram "
                                "workspace");

  auto WSUnit = sourceWS->getAxis(0)->unit();
  if (!WSUnit)
    throw std::invalid_argument(" Source Workspace: " + sourceWS->getName() +
                                " should have units");

  Geometry::IComponent_const_sptr source =
      sourceWS->getInstrument()->getSource();
  m_Sample = sourceWS->getInstrument()->getSample();
  if ((!source) || (!m_Sample))
    throw std::invalid_argument(
        "Instrument on Source workspace:" + sourceWS->getName() +
        "is not sufficiently defined: failed to get source and/or sample");
  m_L1 = source->getDistance(*m_Sample);

  // just in case.
  this->deleteUnitsConverters();
  // allocate the array of units converters to avoid units reallocation within a
  // loop
  m_WSUnit.assign(nThreads, NULL);
  for (int i = 0; i < nThreads; i++) {
    m_WSUnit[i] = WSUnit->clone();
  }

  m_singleValueBackground = false;
  if (bkgWS->getNumberHistograms() == 0)
    m_singleValueBackground = true;
  const MantidVec &dataX = bkgWS->dataX(0);
  const MantidVec &dataY = bkgWS->dataY(0);
  // const MantidVec& dataE = bkgWS->dataE(0);
  m_NBg = dataY[0];
  m_dtBg = dataX[1] - dataX[0];
  // m_ErrSq  = dataE[0]*dataE[0]; // needs further clarification

  m_Efix = this->getEi(sourceWS);
}
예제 #7
0
/**
 * Validation of the inputs of the RingProfile algorithm.
 *
 * Inside this method, the Workspace is considered a 2D Matrix, where each
 *spectrum is
 * the rows of the matrix and have the variation in axis0. The columns of the
 *matrix
 * is the position of dataX(0)
 *
 * The main validation are:
 *  - the centre of the ring is inside the image it self.
 *  - The minimum ring is smaller than the limits of the image to allow
 * @param inputWS: pointer to the input workspace
*/
void RingProfile::checkInputsForNumericWorkspace(
    const API::MatrixWorkspace_sptr inputWS) {
  g_log.notice() << "CheckingInputs For Numeric Workspace" << std::endl;

  // The Axis0 is defined by the values of readX inside the spectra of the
  // workspace.
  // The limits of this axis will be get by inspection of the readX vector
  // taking the first
  // and the last value.

  // check that centre is inside the range available for the instrument
  const MantidVec &refX = inputWS->readX(inputWS->getNumberHistograms() / 2);
  // get the limits of the axis 0 (X)
  double min_v_x, max_v_x;
  min_v_x = std::min(refX[0], refX[refX.size() - 1]);
  max_v_x = std::max(refX[0], refX[refX.size() - 1]);
  g_log.notice() << "Limits X = " << min_v_x << " " << max_v_x << std::endl;
  // check centre is inside the X domain
  if (centre_x < min_v_x || centre_x > max_v_x) {
    std::stringstream s;
    s << "The input value for centre (X=" << centre_x
      << ") is outside the limits of the instrument [" << min_v_x << ", "
      << max_v_x << "]";
    throw std::invalid_argument(s.str());
  }

  // The Axis1 is defined by the spectra inside the workspace. Its limits and
  // values are given by the
  // ws->getAxis(1)

  // get the limits of the axis1 (Y)
  API::NumericAxis *oldAxis2 =
      dynamic_cast<API::NumericAxis *>(inputWS->getAxis(1));
  // we cannot have the positions in Y direction without a NumericAxis
  if (!oldAxis2)
    throw std::invalid_argument("Vertical axis is not a numeric axis. If it is "
                                "a spectra axis try running "
                                "ConvertSpectrumAxis first.");
  double min_v_y = std::min(oldAxis2->getMin(), oldAxis2->getMax());
  double max_v_y = std::max(oldAxis2->getMin(), oldAxis2->getMax());
  g_log.notice() << "Limits Y = " << min_v_y << " " << max_v_y << std::endl;
  // check centre is inside the Y domain
  if (centre_y < min_v_y || centre_y > max_v_y) {
    std::stringstream s;
    s << "The input value for centre (Y=" << centre_y
      << ") is outside the limits of the instrument [" << min_v_y << ", "
      << max_v_y << "]";
    throw std::invalid_argument(s.str());
  }
  g_log.notice() << "Centre: " << centre_x << "  " << centre_y << std::endl;
  // check minradius is inside the limits of the region of the instrument
  if (centre_x - min_radius > max_v_x || centre_x + min_radius < min_v_x ||
      centre_y - min_radius > max_v_y || centre_y + min_radius < min_v_y)
    throw std::invalid_argument(
        "The minimun radius is outside the region of the instrument");
}
예제 #8
0
파일: RadiusSum.cpp 프로젝트: mcvine/mantid
double RadiusSum::getMinBinSizeForNumericImage(API::MatrixWorkspace_sptr inWS) {
  // The pixel dimensions:
  //  - width: image width/ number of pixels in one row
  //  - height: image height/ number of pixels in one column
  //  The minimum bin size is the smallest value between this two values.

  std::vector<double> boundaries = getBoundariesOfNumericImage(inWS);
  const MantidVec &refX = inWS->readX(inputWS->getNumberHistograms() / 2);
  int nX = static_cast<int>(refX.size());
  int nY = static_cast<int>(inWS->getAxis(1)->length());

  // remembering boundaries is defined as { xMin, xMax, yMin, yMax}
  return std::min(((boundaries[1] - boundaries[0]) / nX),
                  ((boundaries[3] - boundaries[2]) / nY));
}
예제 #9
0
/// Run ConvertUnits as a sub-algorithm to convert to dSpacing
MatrixWorkspace_sptr DiffractionFocussing::convertUnitsToDSpacing(const API::MatrixWorkspace_sptr& workspace)
{
  const std::string CONVERSION_UNIT = "dSpacing";

  Unit_const_sptr xUnit = workspace->getAxis(0)->unit();

  g_log.information() << "Converting units from "<< xUnit->label() << " to " << CONVERSION_UNIT<<".\n";

  API::IAlgorithm_sptr childAlg = createSubAlgorithm("ConvertUnits", 0.34, 0.66);
  childAlg->setProperty("InputWorkspace", workspace);
  childAlg->setPropertyValue("Target",CONVERSION_UNIT);
  childAlg->executeAsSubAlg();

  return childAlg->getProperty("OutputWorkspace");
}
예제 #10
0
파일: RadiusSum.cpp 프로젝트: mcvine/mantid
/** Assuming that the input workspace is a Numeric Image where the pixel
 *positions depend on their
 *  relative position inside the workspace, this function extracts the position
 *of the first and last
 *  pixel of the image.
 *
 *  It is important that the input workspace must be a numeric image, and not an
 *instrument related workspace.
 *  The function will raise exception (std::invalid_argument) if an invalid
 *input is give.
 *
 *  @see RadiusSum::inputWorkspaceHasInstrumentAssociated for reference.
 *
 *  @param inWS reference to the workspace
 *  @return a list of values that defines the limits of the image in this order:
 *Xmin, Xmax, Ymin, Ymax
 */
std::vector<double>
RadiusSum::getBoundariesOfNumericImage(API::MatrixWorkspace_sptr inWS) {

  // horizontal axis

  // get the pixel position in the horizontal axis from the middle of the image.
  const MantidVec &refX = inWS->readX(inWS->getNumberHistograms() / 2);

  double min_x, max_x;

  const double &first_x(refX[0]);
  const double &last_x(refX[refX.size() - 1]);
  if (first_x < last_x) {
    min_x = first_x;
    max_x = last_x;
  } else {
    min_x = last_x;
    max_x = first_x;
  }

  // vertical axis
  API::NumericAxis *verticalAxis =
      dynamic_cast<API::NumericAxis *>(inWS->getAxis(1));
  if (!verticalAxis)
    throw std::invalid_argument("Vertical axis is not a numeric axis. Can not "
                                "find the limits of the image.");

  double min_y, max_y;
  min_y = verticalAxis->getMin();
  max_y = verticalAxis->getMax();

  // check the assumption made that verticalAxis will provide the correct
  // answer.
  if (min_y > max_y) {
    throw std::logic_error("Failure to get the boundaries of this image. "
                           "Internal logic error. Please, inform MantidHelp");
  }

  std::vector<double> output(4); // output = {min_x, max_x, min_y, max_y}; not
                                 // supported in all compilers
  output[0] = min_x;
  output[1] = max_x;
  output[2] = min_y;
  output[3] = max_y;
  return output;
}
예제 #11
0
/**
 * Here is the main logic to perform the transformation, to calculate the bin
 *position in degree for each spectrum.
 *
 * The first part of the method is to check if the pixel position is inside the
 *ring defined as minRadio and maxRadio.
 *
 * To do this, it deducts the pixel position. This deduction follows the
 *followin assumption:
 *
 *  - the spectrum_index == row number
 *  - the position in the 'Y' direction is given by getAxis(1)[spectrum_index]
 *  - the position in the 'X' direction is the central point of the bin
 *(dataX[column] + dataX[column+1])/2
 *
 * Having the position of the pixel, as defined above, if the distance is
 *outside the ring defined by minRadio, maxRadio,
 * it defines the bin position as -1.
 *
 * If the pixel is inside the ring, it calculates the angle of the pixel and
 *calls fromAngleToBin to define the bin
 * position.
 * @param ws: pointer to the workspace
 * @param spectrum_index: index of the spectrum
 * @param bins_pos: bin positions (for each column inside the spectrum, the
 *correspondent bin_pos)
 */
void RingProfile::getBinForPixel(const API::MatrixWorkspace_sptr ws,
                                 int spectrum_index,
                                 std::vector<int> &bins_pos) {

  if (bins_pos.size() != ws->dataY(spectrum_index).size())
    throw std::runtime_error("Invalid bin positions vector");

  API::NumericAxis *oldAxis2 = dynamic_cast<API::NumericAxis *>(ws->getAxis(1));
  // assumption y position is the ws->getAxis(1)(spectrum_index)
  if (!oldAxis2) {
    throw std::logic_error("Failed to cast workspace axis to NumericAxis");
  }

  // calculate ypos, the difference of y - centre and  the square of this
  // difference
  double ypos = (*oldAxis2)(spectrum_index);
  double diffy = ypos - centre_y;
  double diffy_quad = pow(diffy, 2.0);

  // the reference to X bins (the limits for each pixel in the horizontal
  // direction)
  auto xvec = ws->dataX(spectrum_index);

  // for each pixel inside this row
  for (size_t i = 0; i < xvec.size() - 1; i++) {

    double xpos = (xvec[i] + xvec[i + 1]) /
                  2.0; // the x position is the centre of the bins boundaries
    double diffx = xpos - centre_x;
    // calculate the distance => norm of pixel position - centre
    double distance = sqrt(pow(diffx, 2.0) + diffy_quad);

    // check if the distance is inside the ring
    if (distance < min_radius || distance > max_radius || distance == 0) {
      bins_pos[i] = -1;
      continue;
    }

    double angle = atan2(diffy, diffx);

    // call fromAngleToBin (radians)
    bins_pos[i] = fromAngleToBin(angle, false);
  }
}
예제 #12
0
/** Checks and retrieves the requested spectrum out of the input workspace
 *  @param inputWorkspace The input workspace.
 *  @param spectra_num The spectra number.
 *  @returns A workspace containing the monitor spectrum only.
 *  @returns spectra number (WS ID) which is used to normalize by.
 *  @throw std::runtime_error If the properties are invalid
 */
API::MatrixWorkspace_sptr NormaliseToMonitor::getInWSMonitorSpectrum(
    const API::MatrixWorkspace_sptr &inputWorkspace, int &spectra_num) {
  // this is the index of the spectra within the workspace and we need to
  // identify it either from DetID or from SpecID
  // size_t spectra_num(-1);
  // try monitor spectrum. If it is specified, it overrides everything
  int monitorSpec = getProperty("MonitorSpectrum");
  if (monitorSpec < 0) {
    // Get hold of the monitor spectrum through detector ID
    int monitorID = getProperty("MonitorID");
    if (monitorID < 0) {
      throw std::runtime_error(
          "Both MonitorSpectrum and MonitorID can not be negative");
    }
    // set spectra of detector's ID of one selected monitor ID
    std::vector<detid_t> detID(1, monitorID);
    // got the index of correspondent spectra (should be only one).
    auto indexList = inputWorkspace->getIndicesFromDetectorIDs(detID);
    if (indexList.empty()) {
      throw std::runtime_error(
          "Can not find spectra, corresponding to the requested monitor ID");
    }
    if (indexList.size() > 1) {
      throw std::runtime_error("More then one spectra corresponds to the "
                               "requested monitor ID, which is unheard of");
    }
    spectra_num = static_cast<int>(indexList[0]);
  } else { // monitor spectrum is specified.
    const SpectraAxis *axis =
        dynamic_cast<const SpectraAxis *>(inputWorkspace->getAxis(1));
    if (!axis) {
      throw std::runtime_error("Cannot retrieve monitor spectrum - spectrum "
                               "numbers not attached to workspace");
    }
    auto specs = axis->getSpectraIndexMap();
    if (!specs.count(monitorSpec)) {
      throw std::runtime_error("Input workspace does not contain spectrum "
                               "number given for MonitorSpectrum");
    }
    spectra_num = static_cast<int>(specs[monitorSpec]);
  }
  return this->extractMonitorSpectrum(inputWorkspace, spectra_num);
}
예제 #13
0
void ConvertEmptyToTof::setTofInWS(const std::vector<double> &tofAxis,
                                   API::MatrixWorkspace_sptr outputWS) {

  const size_t numberOfSpectra = m_inputWS->getNumberHistograms();

  g_log.debug() << "Setting the TOF X Axis for numberOfSpectra="
                << numberOfSpectra << '\n';

  auto axisPtr = Kernel::make_cow<HistogramData::HistogramX>(tofAxis);
  HistogramData::BinEdges edges(tofAxis);
  Progress prog(this, 0.0, 0.2, numberOfSpectra);

  for (size_t i = 0; i < numberOfSpectra; ++i) {
    // Replace bin edges with tof axis
    outputWS->setBinEdges(i, edges);

    prog.report();
  } // end for i

  outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
}
예제 #14
0
void LoadDaveGrp::exec()
{
  const std::string filename = this->getProperty("Filename");

  int yLength = 0;

  MantidVec *xAxis = new MantidVec();
  MantidVec *yAxis = new MantidVec();

  std::vector<MantidVec *> data;
  std::vector<MantidVec *> errors;

  this->ifile.open(filename.c_str());
  if (this->ifile.is_open())
  {
    // Size of x axis
    this->getAxisLength(this->xLength);
    // Size of y axis
    this->getAxisLength(yLength);
    // This is also the number of groups (spectra)
    this->nGroups = yLength;
    // Read in the x axis values
    this->getAxisValues(xAxis, static_cast<std::size_t>(this->xLength));
    // Read in the y axis values
    this->getAxisValues(yAxis, static_cast<std::size_t>(yLength));
    // Read in the data
    this->getData(data, errors);
  }
  this->ifile.close();

  // Scale the x-axis if it is in micro-eV to get it to meV
  const bool isUeV = this->getProperty("IsMicroEV");
  if (isUeV)
  {
    MantidVec::iterator iter;
    for (iter = xAxis->begin(); iter != xAxis->end(); ++iter)
    {
      *iter /= 1000.0;
    }
  }

  // Create workspace
  API::MatrixWorkspace_sptr outputWorkspace = \
      boost::dynamic_pointer_cast<API::MatrixWorkspace>\
      (API::WorkspaceFactory::Instance().create("Workspace2D", this->nGroups,
      this->xLength, yLength));
  // Force the workspace to be a distribution
  outputWorkspace->isDistribution(true);

  // Set the x-axis units
  outputWorkspace->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create(this->getProperty("XAxisUnits"));

  API::Axis* const verticalAxis = new API::NumericAxis(yLength);
  // Set the y-axis units
  verticalAxis->unit() = Kernel::UnitFactory::Instance().create(this->getProperty("YAxisUnits"));

  outputWorkspace->replaceAxis(1, verticalAxis);

  for(int i = 0; i < this->nGroups; i++)
  {
    outputWorkspace->dataX(i) = *xAxis;
    outputWorkspace->dataY(i) = *data[i];
    outputWorkspace->dataE(i) = *errors[i];
    verticalAxis->setValue(i, yAxis->at(i));

    delete data[i];
    delete errors[i];
  }

  delete xAxis;
  delete yAxis;

  outputWorkspace->mutableRun().addProperty("Filename",filename);
  this->setProperty("OutputWorkspace", outputWorkspace);
}
예제 #15
0
/**
 * Executes the algorithm
 */
void ScaleX::exec()
{
  //Get input workspace and offset
  const MatrixWorkspace_sptr inputW = getProperty("InputWorkspace");
  m_algFactor = getProperty("Factor");
  m_parname = getPropertyValue("InstrumentParameter");
  m_combine = getProperty("Combine");
  if(m_combine && m_parname.empty())
  {
    throw std::invalid_argument("Combine behaviour requested but the InstrumentParameter argument is blank.");
  }

  const std::string op = getPropertyValue("Operation");
  API::MatrixWorkspace_sptr outputW = createOutputWS(inputW);
  //Get number of histograms
  int histnumber = static_cast<int>(inputW->getNumberHistograms());
  m_progress = new API::Progress(this, 0.0, 1.0, histnumber+1);
  m_progress->report("Scaling X");
  m_wi_min = 0;
  m_wi_max = histnumber-1;
  //check if workspace indexes have been set
  int tempwi_min = getProperty("IndexMin");
  int tempwi_max = getProperty("IndexMax");
  if ( tempwi_max != Mantid::EMPTY_INT() )
  {
    if ((m_wi_min <= tempwi_min) && (tempwi_min <= tempwi_max) && (tempwi_max <= m_wi_max))
    {
      m_wi_min = tempwi_min;
      m_wi_max = tempwi_max;
    }
    else
    {
      g_log.error("Invalid Workspace Index min/max properties");
      throw std::invalid_argument("Inconsistent properties defined");
    }
  }
  // Setup appropriate binary function
  const bool multiply = (op=="Multiply");
  if(multiply) m_binOp = std::multiplies<double>();
  else m_binOp = std::plus<double>();

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

  // do the shift in X
  PARALLEL_FOR2(inputW, outputW)
  for (int i = 0; i < histnumber; ++i)
  {
    PARALLEL_START_INTERUPT_REGION

    //Copy y and e data
    auto & outY = outputW->dataY(i);
    outY = inputW->dataY(i);
    auto & outE = outputW->dataE(i);
    outE = inputW->dataE(i);

    auto & outX = outputW->dataX(i);
    const auto & inX = inputW->readX(i);
    //Change bin value by offset
    if ((i >= m_wi_min) && (i <= m_wi_max))
    {
      double factor = getScaleFactor(inputW, i);
      // Do the offsetting
      std::transform(inX.begin(), inX.end(), outX.begin(), std::bind2nd(m_binOp, factor));
      // reverse the vector if multiplicative factor was negative
      if(multiply && factor < 0.0)
      {
        std::reverse( outX.begin(), outX.end() );
        std::reverse( outY.begin(), outY.end() );
        std::reverse( outE.begin(), outE.end() );
      }
    }
    else
    {
      outX = inX; //copy
    }
    m_progress->report("Scaling X");

    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  // Copy units
  if (outputW->getAxis(0)->unit().get())
    outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit();
  try
  {
    if (inputW->getAxis(1)->unit().get())
      outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit();
  }
  catch(Exception::IndexError &)
  {
    // OK, so this isn't a Workspace2D
  }
  // Assign it to the output workspace property
  setProperty("OutputWorkspace",outputW);
}
예제 #16
0
/**
 * Read the instrument group
 * @param mtd_entry :: The node for the current workspace
 * @param local_workspace :: The workspace to attach the instrument
 */
void LoadNexusProcessed::readInstrumentGroup(NXEntry & mtd_entry, API::MatrixWorkspace_sptr local_workspace)
{
  //Instrument information
  NXInstrument inst = mtd_entry.openNXInstrument("instrument");
  if ( ! inst.containsGroup("detector") )
  {
    g_log.information() << "Detector block not found. The workspace will not contain any detector information.\n";
    return;
  }

  //Populate the spectra-detector map
  NXDetector detgroup = inst.openNXDetector("detector");

  //Read necessary arrays from the file
  // Detector list contains a list of all of the detector numbers. If it not present then we can't update the spectra
  // map
  int ndets(-1);
  boost::shared_array<int> det_list(NULL);
  try
  {
    NXInt detlist_group = detgroup.openNXInt("detector_list");
    ndets = detlist_group.dim0();
    detlist_group.load();
    det_list.swap(detlist_group.sharedBuffer());
  }
  catch(std::runtime_error &)
  {
    g_log.information() << "detector_list block not found. The workspace will not contain any detector information."
        << std::endl;
    return;
  }

  //Detector count contains the number of detectors associated with each spectra
  NXInt det_count = detgroup.openNXInt("detector_count");
  det_count.load();
  //Detector index - contains the index of the detector in the workspace
  NXInt det_index = detgroup.openNXInt("detector_index");
  det_index.load();
  int nspectra = det_index.dim0();

  //Spectra block - Contains spectrum numbers for each workspace index
  // This might not exist so wrap and check. If it doesn't exist create a default mapping
  bool have_spectra(true);
  boost::shared_array<int> spectra(NULL);
  try
  {
    NXInt spectra_block = detgroup.openNXInt("spectra");
    spectra_block.load();
    spectra.swap(spectra_block.sharedBuffer());
  }
  catch(std::runtime_error &)
  {
    have_spectra = false;
  }

  //Now build the spectra list
  int *spectra_list = new int[ndets];
  API::Axis *axis1 = local_workspace->getAxis(1);
  int index=0;

  for(int i = 1; i <= nspectra; ++i)
  { 
      int spectrum(-1);
      if( have_spectra ) spectrum = spectra[i-1];
      else spectrum = i+1 ;

      if ((i >= m_spec_min && i < m_spec_max )||(m_list && find(m_spec_list.begin(), m_spec_list.end(),
        i) != m_spec_list.end()))
      {
        if( m_axis1vals.empty() )
        {
          axis1->spectraNo(index) = spectrum;
        }
        else
        {
          axis1->setValue(index, m_axis1vals[i-1]);
        }
        ++index;
      }

      int offset = det_index[i-1];
      int detcount = det_count[i-1];
      for(int j = 0; j < detcount; j++)
      {
        spectra_list[offset + j] = spectrum;
      }
     
  }
  local_workspace->replaceSpectraMap(new SpectraDetectorMap(spectra_list, det_list.get(), ndets));
  delete[] spectra_list;
}
예제 #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

}
예제 #18
0
void setXAxisUnits(API::MatrixWorkspace_sptr outputWS) {
  outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("dSpacing");
}
/** Convert the workspace units using TOF as an intermediate step in the
 * conversion
 * @param fromUnit :: The unit of the input workspace
 * @param outputWS :: The output workspace
 */
void ConvertUnitsUsingDetectorTable::convertViaTOF(
    Kernel::Unit_const_sptr fromUnit, API::MatrixWorkspace_sptr outputWS) {
  using namespace Geometry;

  // Let's see if we are using a TableWorkspace to override parameters
  TableWorkspace_sptr paramWS = getProperty("DetectorParameters");

  // See if we have supplied a DetectorParameters Workspace
  // TODO: Check if paramWS is NULL and if so throw an exception

  //      const std::string l1ColumnLabel("l1");

  // Let's check all the columns exist and are readable
  try {
    auto spectraColumnTmp = paramWS->getColumn("spectra");
    auto l1ColumnTmp = paramWS->getColumn("l1");
    auto l2ColumnTmp = paramWS->getColumn("l2");
    auto twoThetaColumnTmp = paramWS->getColumn("twotheta");
    auto efixedColumnTmp = paramWS->getColumn("efixed");
    auto emodeColumnTmp = paramWS->getColumn("emode");
  } catch (...) {
    throw Exception::InstrumentDefinitionError(
        "DetectorParameter TableWorkspace is not defined correctly.");
  }

  // Now let's read them into some vectors.
  auto l1Column = paramWS->getColVector<double>("l1");
  auto l2Column = paramWS->getColVector<double>("l2");
  auto twoThetaColumn = paramWS->getColVector<double>("twotheta");
  auto efixedColumn = paramWS->getColVector<double>("efixed");
  auto emodeColumn = paramWS->getColVector<int>("emode");
  auto spectraColumn = paramWS->getColVector<int>("spectra");

  EventWorkspace_sptr eventWS =
      boost::dynamic_pointer_cast<EventWorkspace>(outputWS);
  assert(static_cast<bool>(eventWS) == m_inputEvents); // Sanity check

  Progress prog(this, 0.2, 1.0, m_numberOfSpectra);
  int64_t numberOfSpectra_i =
      static_cast<int64_t>(m_numberOfSpectra); // cast to make openmp happy

  // Get the unit object for each workspace
  Kernel::Unit_const_sptr outputUnit = outputWS->getAxis(0)->unit();

  std::vector<double> emptyVec;
  int failedDetectorCount = 0;

  // ConstColumnVector<int> spectraNumber = paramWS->getVector("spectra");

  // TODO: Check why this parallel stuff breaks
  // Loop over the histograms (detector spectra)
  // PARALLEL_FOR1(outputWS)
  for (int64_t i = 0; i < numberOfSpectra_i; ++i) {

    // Lets find what row this spectrum ID appears in our detector table.

    // PARALLEL_START_INTERUPT_REGION

    std::size_t wsid = i;

    try {

      double deg2rad = M_PI / 180.;

      auto det = outputWS->getDetector(i);
      int specid = det->getID();

      // int spectraNumber = static_cast<int>(spectraColumn->toDouble(i));
      // wsid = outputWS->getIndexFromSpectrumNumber(spectraNumber);
      g_log.debug() << "###### Spectra #" << specid
                    << " ==> Workspace ID:" << wsid << std::endl;

      // Now we need to find the row that contains this spectrum
      std::vector<int>::iterator specIter;

      specIter = std::find(spectraColumn.begin(), spectraColumn.end(), specid);
      if (specIter != spectraColumn.end()) {
        size_t detectorRow = std::distance(spectraColumn.begin(), specIter);
        double l1 = l1Column[detectorRow];
        double l2 = l2Column[detectorRow];
        double twoTheta = twoThetaColumn[detectorRow] * deg2rad;
        double efixed = efixedColumn[detectorRow];
        int emode = emodeColumn[detectorRow];

        g_log.debug() << "specId from detector table = "
                      << spectraColumn[detectorRow] << std::endl;

        // l1 = l1Column->toDouble(detectorRow);
        // l2 = l2Column->toDouble(detectorRow);
        // twoTheta = deg2rad * twoThetaColumn->toDouble(detectorRow);
        // efixed = efixedColumn->toDouble(detectorRow);
        // emode = static_cast<int>(emodeColumn->toDouble(detectorRow));

        g_log.debug() << "###### Spectra #" << specid
                      << " ==> Det Table Row:" << detectorRow << std::endl;

        g_log.debug() << "\tL1=" << l1 << ",L2=" << l2 << ",TT=" << twoTheta
                      << ",EF=" << efixed << ",EM=" << emode << std::endl;

        // Make local copies of the units. This allows running the loop in
        // parallel
        Unit *localFromUnit = fromUnit->clone();
        Unit *localOutputUnit = outputUnit->clone();
        /// @todo Don't yet consider hold-off (delta)
        const double delta = 0.0;
        // Convert the input unit to time-of-flight
        localFromUnit->toTOF(outputWS->dataX(wsid), emptyVec, l1, l2, twoTheta,
                             emode, efixed, delta);
        // Convert from time-of-flight to the desired unit
        localOutputUnit->fromTOF(outputWS->dataX(wsid), emptyVec, l1, l2,
                                 twoTheta, emode, efixed, delta);
        // EventWorkspace part, modifying the EventLists.
        if (m_inputEvents) {
          eventWS->getEventList(wsid)
              .convertUnitsViaTof(localFromUnit, localOutputUnit);
        }
        // Clear unit memory
        delete localFromUnit;
        delete localOutputUnit;

      } else {
        // Not found
        g_log.debug() << "Spectrum " << specid << " not found!" << std::endl;
        failedDetectorCount++;
        outputWS->maskWorkspaceIndex(wsid);
      }

    } catch (Exception::NotFoundError &) {
      // Get to here if exception thrown when calculating distance to detector
      failedDetectorCount++;
      // Since you usually (always?) get to here when there's no attached
      // detectors, this call is
      // the same as just zeroing out the data (calling clearData on the
      // spectrum)
      outputWS->maskWorkspaceIndex(i);
    }

    prog.report("Convert to " + m_outputUnit->unitID());
    // PARALLEL_END_INTERUPT_REGION
  } // loop over spectra
  // PARALLEL_CHECK_INTERUPT_REGION

  if (failedDetectorCount != 0) {
    g_log.information() << "Something went wrong for " << failedDetectorCount
                        << " spectra. Masking spectrum." << std::endl;
  }
  if (m_inputEvents)
    eventWS->clearMRU();
}
예제 #20
0
/** Executes the algorithm
 *
 */
void SplineBackground::exec()
{

  API::MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
  int spec = getProperty("WorkspaceIndex");

  if (spec > static_cast<int>(inWS->getNumberHistograms()))
    throw std::out_of_range("WorkspaceIndex is out of range.");

  const MantidVec& X = inWS->readX(spec);
  const MantidVec& Y = inWS->readY(spec);
  const MantidVec& E = inWS->readE(spec);
  const bool isHistogram = inWS->isHistogramData();

  const int ncoeffs = getProperty("NCoeff");
  const int k = 4; // order of the spline + 1 (cubic)
  const int nbreak = ncoeffs - (k - 2);

  if (nbreak <= 0)
    throw std::out_of_range("Too low NCoeff");

  gsl_bspline_workspace *bw;
  gsl_vector *B;

  gsl_vector *c, *w, *x, *y;
  gsl_matrix *Z, *cov;
  gsl_multifit_linear_workspace *mw;
  double chisq;

  int n = static_cast<int>(Y.size());
  bool isMasked = inWS->hasMaskedBins(spec);
  std::vector<int> masked(Y.size());
  if (isMasked)
  {
    for(API::MatrixWorkspace::MaskList::const_iterator it=inWS->maskedBins(spec).begin();it!=inWS->maskedBins(spec).end();++it)
      masked[it->first] = 1;
    n -= static_cast<int>(inWS->maskedBins(spec).size());
  }

  if (n < ncoeffs)
  {
    g_log.error("Too many basis functions (NCoeff)");
    throw std::out_of_range("Too many basis functions (NCoeff)");
  }

  /* allocate a cubic bspline workspace (k = 4) */
  bw = gsl_bspline_alloc(k, nbreak);
  B = gsl_vector_alloc(ncoeffs);

  x = gsl_vector_alloc(n);
  y = gsl_vector_alloc(n);
  Z = gsl_matrix_alloc(n, ncoeffs);
  c = gsl_vector_alloc(ncoeffs);
  w = gsl_vector_alloc(n);
  cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
  mw = gsl_multifit_linear_alloc(n, ncoeffs);

  /* this is the data to be fitted */
  int j = 0;
  for (MantidVec::size_type i = 0; i < Y.size(); ++i)
  {
    if (isMasked && masked[i]) continue;
    gsl_vector_set(x, j, (isHistogram ? (0.5*(X[i]+X[i+1])) : X[i])); // Middle of the bins, if a histogram
    gsl_vector_set(y, j, Y[i]);
    gsl_vector_set(w, j, E[i]>0.?1./(E[i]*E[i]):0.);

    ++j;
  }

  if (n != j)
  {
    gsl_bspline_free(bw);
    gsl_vector_free(B);
    gsl_vector_free(x);
    gsl_vector_free(y);
    gsl_matrix_free(Z);
    gsl_vector_free(c);
    gsl_vector_free(w);
    gsl_matrix_free(cov);
    gsl_multifit_linear_free(mw);

    throw std::runtime_error("Assertion failed: n != j");
  }

  double xStart = X.front();
  double xEnd =   X.back();

  /* use uniform breakpoints */
  gsl_bspline_knots_uniform(xStart, xEnd, bw);

  /* construct the fit matrix X */
  for (int i = 0; i < n; ++i)
  {
    double xi=gsl_vector_get(x, i);

    /* compute B_j(xi) for all j */
    gsl_bspline_eval(xi, B, bw);

    /* fill in row i of X */
    for (j = 0; j < ncoeffs; ++j)
    {
      double Bj = gsl_vector_get(B, j);
      gsl_matrix_set(Z, i, j, Bj);
    }
  }

  /* do the fit */
  gsl_multifit_wlinear(Z, w, y, c, cov, &chisq, mw);

  /* output the smoothed curve */
  API::MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create(inWS,1,X.size(),Y.size());
  {
    outWS->getAxis(1)->setValue(0, inWS->getAxis(1)->spectraNo(spec));
    double xi, yi, yerr;
    for (MantidVec::size_type i=0;i<Y.size();i++)
    {
      xi = X[i];
      gsl_bspline_eval(xi, B, bw);
      gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
      outWS->dataY(0)[i] = yi;
      outWS->dataE(0)[i] = yerr;
    }
    outWS->dataX(0) = X;
  }

  gsl_bspline_free(bw);
  gsl_vector_free(B);
  gsl_vector_free(x);
  gsl_vector_free(y);
  gsl_matrix_free(Z);
  gsl_vector_free(c);
  gsl_vector_free(w);
  gsl_matrix_free(cov);
  gsl_multifit_linear_free(mw);

  setProperty("OutputWorkspace",outWS);

}
예제 #21
0
		/** Executes the rebin algorithm
		*
		*  @throw runtime_error Thrown if
		*/
		void Rebunch::exec()
		{
			// retrieve the properties
			int n_bunch=getProperty("NBunch");

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

			bool dist = inputW->isDistribution();

			// workspace independent determination of length
                        int histnumber = static_cast<int>(inputW->size()/inputW->blocksize());

			/*
			const std::vector<double>& Xold = inputW->readX(0);
			const std::vector<double>& Yold = inputW->readY(0);
			int size_x=Xold.size();
			int size_y=Yold.size();
			*/
                        int size_x = static_cast<int>(inputW->readX(0).size());
                        int size_y = static_cast<int>(inputW->readY(0).size());

			//signal is the same length for histogram and point data
			int ny=(size_y/n_bunch);
			if(size_y%n_bunch >0)ny+=1;
			// default is for hist
			int nx=ny+1;
			bool point=false;
			if (size_x==size_y)
			{
				point=true;
				nx=ny;
			}

			// make output Workspace the same type is the input, but with new length of signal array
			API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(inputW,histnumber,nx,ny);

            int progress_step = histnumber / 100;
            if (progress_step == 0) progress_step = 1;
			PARALLEL_FOR2(inputW,outputW)
			for (int hist=0; hist <  histnumber;hist++)
			{
				PARALLEL_START_INTERUPT_REGION
				// Ensure that axis information are copied to the output workspace if the axis exists
			        try
				{
				  outputW->getAxis(1)->spectraNo(hist)=inputW->getAxis(1)->spectraNo(hist);
				}
				catch( Exception::IndexError& )
				{ 
				  // Not a Workspace2D
				}

				// get const references to input Workspace arrays (no copying)
				const MantidVec& XValues = inputW->readX(hist);
				const MantidVec& YValues = inputW->readY(hist);
				const MantidVec& YErrors = inputW->readE(hist);

				//get references to output workspace data (no copying)
				MantidVec& XValues_new=outputW->dataX(hist);
				MantidVec& YValues_new=outputW->dataY(hist);
				MantidVec& YErrors_new=outputW->dataE(hist);

				// output data arrays are implicitly filled by function
				if(point)
				{
					rebunch_point(XValues,YValues,YErrors,XValues_new,YValues_new,YErrors_new,n_bunch);
				}
				else
				{
					rebunch_hist(XValues,YValues,YErrors,XValues_new,YValues_new,YErrors_new,n_bunch, dist);
				}

				if (hist % progress_step == 0)
				{
				  progress(double(hist)/histnumber);
				  interruption_point();
				}
				PARALLEL_END_INTERUPT_REGION
			}
			PARALLEL_CHECK_INTERUPT_REGION
			outputW->isDistribution(dist);

			// Copy units
			if (outputW->getAxis(0)->unit().get())
			  outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit();
			try
			{
			  if (inputW->getAxis(1)->unit().get())
			    outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit();
			}
			catch(Exception::IndexError&) {
			  // OK, so this isn't a Workspace2D
			}

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

			return;
		}
예제 #22
0
파일: RadiusSum.cpp 프로젝트: mcvine/mantid
/** Differentiate between Instrument related image (where the position of the
 *pixels depend on the instrument
 *  attached to the workspace) and Numeric image (where the position of the
 *pixels depend on the relative position
 *  in the workspace).
 *
 * An instrument related image has the axis 1 defined as spectra (collection of
 *spectrum numbers each one associated to
 * one or more detectors in the instrument).
 *
 * @param inWS the input workspace
 * @return True if it is an instrument related workspace.
 */
bool RadiusSum::inputWorkspaceHasInstrumentAssociated(
    API::MatrixWorkspace_sptr inWS) {
  return inWS->getAxis(1)->isSpectra();
}
예제 #23
0
/** Executes the algorithm
 *
 *  @throw Exception::FileError If the grouping file cannot be opened or read successfully
 *  @throw runtime_error If unable to run one of the sub-algorithms successfully
 */
void DiffractionFocussing::exec()
{
  // retrieve the properties
  std::string groupingFileName=getProperty("GroupingFileName");

  // Get the input workspace
  MatrixWorkspace_sptr inputW = getProperty("InputWorkspace");

  bool dist = inputW->isDistribution();

  //do this first to check that a valid file is available before doing any work
  std::multimap<int64_t,int64_t> detectorGroups;// <group, UDET>
  if (!readGroupingFile(groupingFileName, detectorGroups))
  {
    throw Exception::FileError("Error reading .cal file",groupingFileName);
  }

  //Convert to d-spacing units
  API::MatrixWorkspace_sptr tmpW = convertUnitsToDSpacing(inputW);

  //Rebin to a common set of bins
  RebinWorkspace(tmpW);

  std::set<int64_t> groupNumbers;
  for(std::multimap<int64_t,int64_t>::const_iterator d = detectorGroups.begin();d!=detectorGroups.end();d++)
  {
    if (groupNumbers.find(d->first) == groupNumbers.end())
    {
      groupNumbers.insert(d->first);
    }
  }

  int iprogress = 0;
  int iprogress_count = static_cast<int>(groupNumbers.size());
  int iprogress_step = iprogress_count / 100;
  if (iprogress_step == 0) iprogress_step = 1;
  std::vector<int64_t> resultIndeces;
  for(std::set<int64_t>::const_iterator g = groupNumbers.begin();g!=groupNumbers.end();g++)
  {
    if (iprogress++ % iprogress_step == 0)
    {
      progress(0.68 + double(iprogress)/iprogress_count/3);
    }
    std::multimap<int64_t,int64_t>::const_iterator from = detectorGroups.lower_bound(*g);
    std::multimap<int64_t,int64_t>::const_iterator to =   detectorGroups.upper_bound(*g);
    std::vector<detid_t> detectorList;
    for(std::multimap<int64_t,int64_t>::const_iterator d = from;d!=to;d++)
      detectorList.push_back(static_cast<detid_t>(d->second));
    // Want version 1 of GroupDetectors here
    API::IAlgorithm_sptr childAlg = createSubAlgorithm("GroupDetectors",-1.0,-1.0,true,1);
    childAlg->setProperty("Workspace", tmpW);
    childAlg->setProperty< std::vector<detid_t> >("DetectorList",detectorList);
    childAlg->executeAsSubAlg();
    try
    {
      // get the index of the combined spectrum
      int ri = childAlg->getProperty("ResultIndex");
      if (ri >= 0)
      {
        resultIndeces.push_back(ri);
      }
    }
    catch(...)
    {
      throw std::runtime_error("Unable to get Properties from GroupDetectors sub-algorithm");
    }
  }

  // Discard left-over spectra, but print warning message giving number discarded
  int discarded = 0;
  const int64_t oldHistNumber = tmpW->getNumberHistograms();
  API::Axis *spectraAxis = tmpW->getAxis(1);
  for(int64_t i=0; i < oldHistNumber; i++)
    if ( spectraAxis->spectraNo(i) >= 0 && find(resultIndeces.begin(),resultIndeces.end(),i) == resultIndeces.end())
    {
      ++discarded;
    }
  g_log.warning() << "Discarded " << discarded << " spectra that were not assigned to any group" << std::endl;

  // Running GroupDetectors leads to a load of redundant spectra
  // Create a new workspace that's the right size for the meaningful spectra and copy them in
  int64_t newSize = tmpW->blocksize();
  API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(tmpW,resultIndeces.size(),newSize+1,newSize);
  // Copy units
  outputW->getAxis(0)->unit() = tmpW->getAxis(0)->unit();
  outputW->getAxis(1)->unit() = tmpW->getAxis(1)->unit();

  API::Axis *spectraAxisNew = outputW->getAxis(1);

  for(int64_t hist=0; hist < static_cast<int64_t>(resultIndeces.size()); hist++)
  {
    int64_t i = resultIndeces[hist];
    double spNo = static_cast<double>(spectraAxis->spectraNo(i));
    MantidVec &tmpE = tmpW->dataE(i);
    MantidVec &outE = outputW->dataE(hist);
    MantidVec &tmpY = tmpW->dataY(i);
    MantidVec &outY = outputW->dataY(hist);
    MantidVec &tmpX = tmpW->dataX(i);
    MantidVec &outX = outputW->dataX(hist);
    outE.assign(tmpE.begin(),tmpE.end());
    outY.assign(tmpY.begin(),tmpY.end());
    outX.assign(tmpX.begin(),tmpX.end());
    spectraAxisNew->setValue(hist,spNo);
    spectraAxis->setValue(i,-1);
  }

  progress(1.);

  outputW->isDistribution(dist);

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

  return;
}
예제 #24
0
/** Executes the regroup algorithm
 *
 *  @throw runtime_error Thrown if
 */
void Regroup::exec()
{
  // retrieve the properties
  std::vector<double> rb_params=getProperty("Params");

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

  // can work only if all histograms have the same boundaries
  if (!API::WorkspaceHelpers::commonBoundaries(inputW))
  {
    g_log.error("Histograms with different boundaries");
    throw std::runtime_error("Histograms with different boundaries");
  }

  bool dist = inputW->isDistribution();

  int histnumber = static_cast<int>(inputW->getNumberHistograms());
  MantidVecPtr XValues_new;
  const MantidVec & XValues_old = inputW->readX(0);
  std::vector<int> xoldIndex;// indeces of new x in XValues_old
  // create new output X axis
  int ntcnew = newAxis(rb_params,XValues_old,XValues_new.access(),xoldIndex);

  // make output Workspace the same type is the input, but with new length of signal array
  API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(inputW,histnumber,ntcnew,ntcnew-1);

  int progress_step = histnumber / 100;
  if (progress_step == 0) progress_step = 1;
  for (int hist=0; hist <  histnumber;hist++)
  {
    // get const references to input Workspace arrays (no copying)
    const MantidVec& XValues = inputW->readX(hist);
    const MantidVec& YValues = inputW->readY(hist);
    const MantidVec& YErrors = inputW->readE(hist);

    //get references to output workspace data (no copying)
    MantidVec& YValues_new=outputW->dataY(hist);
    MantidVec& YErrors_new=outputW->dataE(hist);

    // output data arrays are implicitly filled by function
    rebin(XValues,YValues,YErrors,xoldIndex,YValues_new,YErrors_new, dist);

    outputW->setX(hist,XValues_new);

    if (hist % progress_step == 0)
    {
        progress(double(hist)/histnumber);
        interruption_point();
    }
  }

  outputW->isDistribution(dist);

  // Copy units
  if (outputW->getAxis(0)->unit().get())
    outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit();
  try
  {
    if (inputW->getAxis(1)->unit().get())
      outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit();
   }
  catch(Exception::IndexError) {
    // OK, so this isn't a Workspace2D
  }

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

  return;
}
예제 #25
0
파일: ScaleX.cpp 프로젝트: trnielsen/mantid
    /**
     * Executes the algorithm
     */
    void ScaleX::exec()
    {
      //Get input workspace and offset
      const MatrixWorkspace_sptr inputW = getProperty("InputWorkspace");

      factor = getProperty("Factor");

      API::MatrixWorkspace_sptr outputW = createOutputWS(inputW);

      //Get number of histograms
      int histnumber = static_cast<int>(inputW->getNumberHistograms());

      m_progress = new API::Progress(this, 0.0, 1.0, histnumber+1);
      m_progress->report("Scaling X");

	    wi_min = 0;
      wi_max = histnumber-1;
      //check if workspace indexes have been set
      int tempwi_min = getProperty("IndexMin");
      int tempwi_max = getProperty("IndexMax");
      if ( tempwi_max != Mantid::EMPTY_INT() )
      {
        if ((wi_min <= tempwi_min) && (tempwi_min <= tempwi_max) && (tempwi_max <= wi_max))
        {
          wi_min = tempwi_min;
          wi_max = tempwi_max;
        }
        else
        {
          g_log.error("Invalid Workspace Index min/max properties");
          throw std::invalid_argument("Inconsistent properties defined");
        }
      }


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

      // do the shift in X
      PARALLEL_FOR2(inputW, outputW)
      for (int i=0; i < histnumber; ++i)
      {
        PARALLEL_START_INTERUPT_REGION
        //Do the offsetting
        for (int j=0; j <  static_cast<int>(inputW->readX(i).size()); ++j)
        {
          //Change bin value by offset
          if ((i >= wi_min) && (i <= wi_max)) outputW->dataX(i)[j] = inputW->readX(i)[j] * factor;
          else outputW->dataX(i)[j] = inputW->readX(i)[j];
        }
        //Copy y and e data
        outputW->dataY(i) = inputW->dataY(i);
        outputW->dataE(i) = inputW->dataE(i);

        if( (i >= wi_min) && (i <= wi_max) && factor<0 )
        {
          std::reverse( outputW->dataX(i).begin(), outputW->dataX(i).end() );
          std::reverse( outputW->dataY(i).begin(), outputW->dataY(i).end() );
          std::reverse( outputW->dataE(i).begin(), outputW->dataE(i).end() );
        }

        m_progress->report("Scaling X");
        PARALLEL_END_INTERUPT_REGION
      }
      PARALLEL_CHECK_INTERUPT_REGION

      // Copy units
      if (outputW->getAxis(0)->unit().get())
          outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit();
      try
      {
          if (inputW->getAxis(1)->unit().get())
              outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit();
      }
      catch(Exception::IndexError &) {
          // OK, so this isn't a Workspace2D
      }

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