Example #1
0
/**
 * Computes the square root of the errors and if the input was a distribution
 * this divides by the new bin-width
 * @param outputWS The workspace containing the output data
 * @param inputWS The input workspace used for testing distribution state
 */
void Rebin2D::normaliseOutput(MatrixWorkspace_sptr outputWS, MatrixWorkspace_const_sptr inputWS)
{
    //PARALLEL_FOR1(outputWS)
    for(int64_t i = 0; i < static_cast<int64_t>(outputWS->getNumberHistograms()); ++i)
    {
        PARALLEL_START_INTERUPT_REGION

        MantidVec & outputY = outputWS->dataY(i);
        MantidVec & outputE = outputWS->dataE(i);
        for(size_t j = 0; j < outputWS->blocksize(); ++j)
        {
            m_progress->report("Calculating errors");
            const double binWidth = (outputWS->readX(i)[j+1] - outputWS->readX(i)[j]);
            double eValue = std::sqrt(outputE[j]);
            // Don't do this for a RebinnedOutput workspace. The fractions
            // take care of such things.
            if( inputWS->isDistribution() && inputWS->id() != "RebinnedOutput")
            {
                outputY[j] /= binWidth;
                eValue /= binWidth;
            }
            outputE[j] = eValue;
        }

        PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    outputWS->isDistribution(inputWS->isDistribution());
}
Example #2
0
/** Populates the output workspaces
* @param inWS :: [input] The input workspace
* @param spec :: [input] The current spectrum being analyzed
* @param nspec :: [input] The total number of histograms in the input workspace
* @param result :: [input] The result to be written in the output workspace
* @param outWS :: [input] The output workspace to populate
*/
void MaxEnt::populateDataWS(const MatrixWorkspace_sptr &inWS, size_t spec,
                            size_t nspec, const std::vector<double> &result,
                            MatrixWorkspace_sptr &outWS) {

  if (result.size() % 2)
    throw std::invalid_argument("Cannot write results to output workspaces");

  int npoints = static_cast<int>(result.size() / 2);
  int npointsX = inWS->isHistogramData() ? npoints + 1 : npoints;
  MantidVec X(npointsX);
  MantidVec YR(npoints);
  MantidVec YI(npoints);
  MantidVec E(npoints, 0.);

  double x0 = inWS->readX(spec)[0];
  double dx = inWS->readX(spec)[1] - x0;

  for (int i = 0; i < npoints; i++) {
    X[i] = x0 + i * dx;
    YR[i] = result[2 * i];
    YI[i] = result[2 * i + 1];
  }
  if (npointsX == npoints + 1)
    X[npoints] = x0 + npoints * dx;

  outWS->dataX(spec).assign(X.begin(), X.end());
  outWS->dataY(spec).assign(YR.begin(), YR.end());
  outWS->dataE(spec).assign(E.begin(), E.end());
  outWS->dataX(nspec + spec).assign(X.begin(), X.end());
  outWS->dataY(nspec + spec).assign(YI.begin(), YI.end());
  outWS->dataE(nspec + spec).assign(E.begin(), E.end());
}
/** Rebins the distributions and sets error values.
 */
MatrixWorkspace_sptr
VesuvioL1ThetaResolution::processDistribution(MatrixWorkspace_sptr ws,
                                              const double binWidth) {
  const size_t numHist = ws->getNumberHistograms();

  double xMin(DBL_MAX);
  double xMax(DBL_MIN);
  for (size_t i = 0; i < numHist; i++) {
    const std::vector<double> &x = ws->readX(i);
    xMin = std::min(xMin, x.front());
    xMax = std::max(xMax, x.back());
  }

  std::stringstream binParams;
  binParams << xMin << "," << binWidth << "," << xMax;

  IAlgorithm_sptr rebin = AlgorithmManager::Instance().create("Rebin");
  rebin->initialize();
  rebin->setChild(true);
  rebin->setLogging(false);
  rebin->setProperty("InputWorkspace", ws);
  rebin->setProperty("OutputWorkspace", "__rebin");
  rebin->setProperty("Params", binParams.str());
  rebin->execute();
  ws = rebin->getProperty("OutputWorkspace");

  for (size_t i = 0; i < numHist; i++) {
    const std::vector<double> &y = ws->readY(i);
    std::vector<double> &e = ws->dataE(i);

    std::transform(y.begin(), y.end(), e.begin(), SquareRoot());
  }

  return ws;
}
  /**
   * Replots the energy mini plot
   */
  void ISISCalibration::calPlotEnergy()
  {
    if ( ! m_uiForm.leRunNo->isValid() )
    {
      emit showMessageBox("Run number not valid.");
      return;
    }

    QString files = m_uiForm.leRunNo->getFilenames().join(",");

    QFileInfo fi(m_uiForm.leRunNo->getFirstFilename());

    QString detRange = QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + ","
                     + QString::number(m_dblManager->value(m_properties["ResSpecMax"]));

    IAlgorithm_sptr reductionAlg = AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer");
    reductionAlg->initialize();
    reductionAlg->setProperty("Instrument", getInstrumentConfiguration()->getInstrumentName().toStdString());
    reductionAlg->setProperty("Analyser", getInstrumentConfiguration()->getAnalyserName().toStdString());
    reductionAlg->setProperty("Reflection", getInstrumentConfiguration()->getReflectionName().toStdString());
    reductionAlg->setProperty("InputFiles", files.toStdString());
    reductionAlg->setProperty("OutputWorkspace", "__IndirectCalibration_reduction");
    reductionAlg->setProperty("SpectraRange", detRange.toStdString());
    reductionAlg->execute();

    if(!reductionAlg->isExecuted())
    {
      g_log.warning("Could not generate energy preview plot.");
      return;
    }

    WorkspaceGroup_sptr reductionOutputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>("__IndirectCalibration_reduction");
    if(reductionOutputGroup->size() == 0)
    {
      g_log.warning("No result workspaces, cannot plot energy preview.");
      return;
	}

    MatrixWorkspace_sptr energyWs = boost::dynamic_pointer_cast<MatrixWorkspace>(reductionOutputGroup->getItem(0));
    if(!energyWs)
    {
      g_log.warning("No result workspaces, cannot plot energy preview.");
      return;
    }

    const Mantid::MantidVec & dataX = energyWs->readX(0);
    QPair<double, double> range(dataX.front(), dataX.back());

    auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground");
    setPlotPropertyRange(resBackground, m_properties["ResStart"], m_properties["ResEnd"], range);

    m_uiForm.ppResolution->clear();
    m_uiForm.ppResolution->addSpectrum("Energy", energyWs, 0);
    m_uiForm.ppResolution->resizeX();

    calSetDefaultResolution(energyWs);

    m_uiForm.ppResolution->replot();
  }
Example #5
0
/**  Calculate the integral asymmetry for a pair of workspaces (red & green).
*   @param ws_red :: The red workspace
*   @param ws_green :: The green workspace
*   @param Y :: Reference to a variable receiving the value of asymmetry
*   @param E :: Reference to a variable receiving the value of the error
*/
void PlotAsymmetryByLogValue::calcIntAsymmetry(MatrixWorkspace_sptr ws_red,
                                               MatrixWorkspace_sptr ws_green,
                                               double &Y, double &E) {
  if (!m_int) { //  "Differential asymmetry"

    MatrixWorkspace_sptr tmpWS = WorkspaceFactory::Instance().create(
        ws_red, 1, ws_red->readX(0).size(), ws_red->readY(0).size());

    for (size_t i = 0; i < tmpWS->dataY(0).size(); i++) {
      double FNORM = ws_green->readY(0)[i] + ws_red->readY(0)[i];
      FNORM = FNORM != 0.0 ? 1.0 / FNORM : 1.0;
      double BNORM = ws_green->readY(1)[i] + ws_red->readY(1)[i];
      BNORM = BNORM != 0.0 ? 1.0 / BNORM : 1.0;
      double ZF = (ws_green->readY(0)[i] - ws_red->readY(0)[i]) * FNORM;
      double ZB = (ws_green->readY(1)[i] - ws_red->readY(1)[i]) * BNORM;
      tmpWS->dataY(0)[i] = ZB - ZF;
      tmpWS->dataE(0)[i] = (1.0 + ZF * ZF) * FNORM + (1.0 + ZB * ZB) * BNORM;
    }

    IAlgorithm_sptr integr = createChildAlgorithm("Integration");
    integr->setProperty("InputWorkspace", tmpWS);
    integr->setProperty("RangeLower", m_minTime);
    integr->setProperty("RangeUpper", m_maxTime);
    integr->execute();
    MatrixWorkspace_sptr out = integr->getProperty("OutputWorkspace");

    Y = out->readY(0)[0] / static_cast<double>(tmpWS->dataY(0).size());
    E = out->readE(0)[0] / static_cast<double>(tmpWS->dataY(0).size());
  } else {
    //  "Integral asymmetry"
    IAlgorithm_sptr integr = createChildAlgorithm("Integration");
    integr->setProperty("InputWorkspace", ws_red);
    integr->setProperty("RangeLower", m_minTime);
    integr->setProperty("RangeUpper", m_maxTime);
    integr->execute();
    MatrixWorkspace_sptr intWS_red = integr->getProperty("OutputWorkspace");

    integr = createChildAlgorithm("Integration");
    integr->setProperty("InputWorkspace", ws_green);
    integr->setProperty("RangeLower", m_minTime);
    integr->setProperty("RangeUpper", m_maxTime);
    integr->execute();
    MatrixWorkspace_sptr intWS_green = integr->getProperty("OutputWorkspace");

    double YIF = (intWS_green->readY(0)[0] - intWS_red->readY(0)[0]) /
                 (intWS_green->readY(0)[0] + intWS_red->readY(0)[0]);
    double YIB = (intWS_green->readY(1)[0] - intWS_red->readY(1)[0]) /
                 (intWS_green->readY(1)[0] + intWS_red->readY(1)[0]);

    Y = YIB - YIF;

    double VARIF =
        (1.0 + YIF * YIF) / (intWS_green->readY(0)[0] + intWS_red->readY(0)[0]);
    double VARIB =
        (1.0 + YIB * YIB) / (intWS_green->readY(1)[0] + intWS_red->readY(1)[0]);

    E = sqrt(VARIF + VARIB);
  }
}
Example #6
0
/**
 * Replots the raw data mini plot and the energy mini plot
 */
void ISISCalibration::calPlotRaw() {

  QString filename = m_uiForm.leRunNo->getFirstFilename();

  // Don't do anything if the file we would plot has not changed
  if (filename == m_lastCalPlotFilename)
    return;

  m_lastCalPlotFilename = filename;

  if (filename.isEmpty()) {
    emit showMessageBox("Cannot plot raw data without filename");
    return;
  }

  QFileInfo fi(filename);
  QString wsname = fi.baseName();

  auto instDetails = getInstrumentDetails();
  int specMin = instDetails["spectra-min"].toInt();
  int specMax = instDetails["spectra-max"].toInt();

  if (!loadFile(filename, wsname, specMin, specMax)) {
    emit showMessageBox("Unable to load file.\nCheck whether your file exists "
                        "and matches the selected instrument in the Energy "
                        "Transfer tab.");
    return;
  }

  MatrixWorkspace_sptr input = boost::dynamic_pointer_cast<MatrixWorkspace>(
      AnalysisDataService::Instance().retrieve(wsname.toStdString()));

  const Mantid::MantidVec &dataX = input->readX(0);
  QPair<double, double> range(dataX.front(), dataX.back());

  m_uiForm.ppCalibration->clear();
  m_uiForm.ppCalibration->addSpectrum("Raw", input, 0);
  m_uiForm.ppCalibration->resizeX();

  auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak");
  auto calBackground =
      m_uiForm.ppCalibration->getRangeSelector("CalBackground");
  setPlotPropertyRange(calPeak, m_properties["CalELow"],
                       m_properties["CalEHigh"], range);
  setPlotPropertyRange(calBackground, m_properties["CalStart"],
                       m_properties["CalEnd"], range);

  setDefaultInstDetails();

  m_uiForm.ppCalibration->replot();

  // Also replot the energy
  calPlotEnergy();
}
 /** 
  * Checks the input workspace's X data structure is logical.
  * @param inputWS pointer to input workspace
  * @returns True if the X structure of the given input is what we expect, i.e. NX=NY+1
  */
 bool ConvertToPointData::isWorkspaceLogical(const MatrixWorkspace_sptr inputWS) const
 {
   const size_t numBins = inputWS->blocksize();
   const size_t numBoundaries = inputWS->readX(0).size();
   if( numBoundaries != (numBins + 1) )
   {
     g_log.error() << "The number of bin boundaries must be one greater than the number of bins. "
       << "Found nbins=" << numBins << " and nBoundaries=" << numBoundaries << "\n";
     return false;
   }
   return true;
 }
MatrixWorkspace_sptr
PolarizationCorrection::copyShapeAndFill(MatrixWorkspace_sptr &base,
                                         const double &value) {
  MatrixWorkspace_sptr wsTemplate = WorkspaceFactory::Instance().create(base);
  // Copy the x-array across to the new workspace.
  for (size_t i = 0; i < wsTemplate->getNumberHistograms(); ++i) {
    wsTemplate->setX(i, base->readX(i));
  }
  auto zeroed = this->multiply(wsTemplate, 0);
  auto filled = this->add(zeroed, value);
  return filled;
}
Example #9
0
/** Validate the input properties.
*/
std::map<std::string, std::string> MaxEnt::validateInputs() {

  std::map<std::string, std::string> result;

  MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");

  if (inWS) {

    // 1. X values in input workspace must be (almost) equally spaced

    const double warningLevel = 0.01;
    const double errorLevel = 0.5;
    bool printWarning = false;
    // Average spacing
    const MantidVec &X = inWS->readX(0);
    const double dx =
        (X[X.size() - 1] - X[0]) / static_cast<double>(X.size() - 1);
    for (size_t i = 1; i < X.size() - 1; i++) {
      // 1% accuracy exceeded, but data still usable
      if (std::abs(X[i] - X[0] - static_cast<double>(i) * dx) / dx >
          warningLevel) {
        printWarning = true;
        if (std::abs(X[i] - X[0] - static_cast<double>(i) * dx) / dx >
            errorLevel) {
          // 50% accuracy exceeded, data not usable
          printWarning = false;
          result["InputWorkspace"] =
              "X axis must be linear (all bins have same width)";
          break;
        }
      }
    }
    if (printWarning) {
      g_log.warning() << "Bin widths differ by more than " << warningLevel * 100
                      << "% of average\n";
    }

    // 2. If the input signal is complex, we expect an even number of histograms
    // in the input workspace

    size_t nhistograms = inWS->getNumberHistograms();
    bool complex = getProperty("ComplexData");
    if (complex && (nhistograms % 2))
      result["InputWorkspace"] = "The number of histograms in the input "
                                 "workspace must be even for complex data";
  }

  return result;
}
Example #10
0
/**
 * Rebin the input quadrilateral to the output grid
 * @param inputQ The input polygon
 * @param inputWS The input workspace containing the input intensity values
 * @param i The index in the vertical axis direction that inputQ references
 * @param j The index in the horizontal axis direction that inputQ references
 * @param outputWS A pointer to the output workspace that accumulates the data
 * @param verticalAxis A vector containing the output vertical axis bin boundaries
 */
void Rebin2D::rebinToOutput(const Geometry::Quadrilateral & inputQ, MatrixWorkspace_const_sptr inputWS,
                            const size_t i, const size_t j, MatrixWorkspace_sptr outputWS,
                            const std::vector<double> & verticalAxis)
{
    const MantidVec & X = outputWS->readX(0);
    size_t qstart(0), qend(verticalAxis.size()-1), en_start(0), en_end(X.size() - 1);
    if( !getIntersectionRegion(outputWS, verticalAxis, inputQ, qstart, qend, en_start, en_end)) return;

    for( size_t qi = qstart; qi < qend; ++qi )
    {
        const double vlo = verticalAxis[qi];
        const double vhi = verticalAxis[qi+1];
        for( size_t ei = en_start; ei < en_end; ++ei )
        {
            const V2D ll(X[ei], vlo);
            const V2D lr(X[ei+1], vlo);
            const V2D ur(X[ei+1], vhi);
            const V2D ul(X[ei], vhi);
            const Quadrilateral outputQ(ll, lr, ur, ul);

            double yValue = inputWS->readY(i)[j];
            if (boost::math::isnan(yValue))
            {
                continue;
            }
            try
            {
                ConvexPolygon overlap = intersectionByLaszlo(outputQ, inputQ);
                const double weight = overlap.area()/inputQ.area();
                yValue *= weight;
                double eValue = inputWS->readE(i)[j] * weight;
                const double overlapWidth = overlap.largestX() - overlap.smallestX();
                if(inputWS->isDistribution())
                {
                    yValue *= overlapWidth;
                    eValue *= overlapWidth;
                }
                eValue = eValue*eValue;
                PARALLEL_CRITICAL(overlap)
                {
                    outputWS->dataY(qi)[ei] += yValue;
                    outputWS->dataE(qi)[ei] += eValue;
                }
            }
            catch(Geometry::NoIntersectionException &)
            {}
        }
    }
}
Example #11
0
void IQTransform::exec()
{
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  // Print a warning if the input workspace has more than one spectrum
  if ( inputWS->getNumberHistograms() > 1 )
  {
    g_log.warning("This algorithm is intended for use on single-spectrum workspaces.\n"
                  "Only the first spectrum will be transformed.");
  }

  // Do background subtraction from a workspace first because it doesn't like
  // potential conversion to point data that follows. Requires a temporary workspace.
  MatrixWorkspace_sptr tmpWS;
  MatrixWorkspace_sptr backgroundWS = getProperty("BackgroundWorkspace");
  if ( backgroundWS ) tmpWS = subtractBackgroundWS(inputWS,backgroundWS);
  else tmpWS = inputWS;

  // Create the output workspace
  const size_t length = tmpWS->blocksize();
  MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(inputWS,1,length,length);
  m_label->setLabel("");
  outputWS->setYUnit("");
  // Copy the data over. Assume single spectrum input (output will be).
  // Take the mid-point of histogram bins
  if ( tmpWS->isHistogramData() )
  {
    VectorHelper::convertToBinCentre(tmpWS->readX(0),outputWS->dataX(0));
  }
  else
  {
    outputWS->setX(0,tmpWS->refX(0));
  }
  MantidVec& Y = outputWS->dataY(0) = tmpWS->dataY(0);
  outputWS->dataE(0) = tmpWS->dataE(0);

  // Subtract a constant background if requested
  const double background = getProperty("BackgroundValue");
  if ( background > 0.0 ) subtractBackgroundValue(Y,background);

  // Select the desired transformation function and call it
  TransformFunc f = m_transforms.find(getProperty("TransformType"))->second;
  (this->*f)(outputWS);

  // Need the generic label unit on this (unless the unit on the X axis hasn't changed)
  if ( ! m_label->caption().empty() ) outputWS->getAxis(0)->unit() = m_label;
  setProperty("OutputWorkspace",outputWS);
}
Example #12
0
/** Uses 'Linear' as a subalgorithm to fit the log of the exponential curve expected for the transmission.
 *  @param WS :: The single-spectrum workspace to fit
 *  @return A workspace containing the fit
 */
API::MatrixWorkspace_sptr CalculateTransmissionBeamSpreader::fitToData(API::MatrixWorkspace_sptr WS)
{
  g_log.information("Fitting the experimental transmission curve");
  Algorithm_sptr childAlg = createSubAlgorithm("Linear",0.6,1.0);
  childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", WS);
  const double lambdaMin = getProperty("MinWavelength");
  const double lambdaMax = getProperty("MaxWavelength");
  childAlg->setProperty<double>("StartX",lambdaMin);
  childAlg->setProperty<double>("EndX",lambdaMax);
  childAlg->executeAsSubAlg();

  std::string fitStatus = childAlg->getProperty("FitStatus");
  if ( fitStatus != "success" )
  {
    g_log.error("Unable to successfully fit the data: " + fitStatus);
    throw std::runtime_error("Unable to successfully fit the data");
  }
 
  // Only get to here if successful
  MatrixWorkspace_sptr result = childAlg->getProperty("OutputWorkspace");

  if (logFit)
  {
    // Need to transform back to 'unlogged'
    double b = childAlg->getProperty("FitIntercept");
    double m = childAlg->getProperty("FitSlope");
    b = std::pow(10,b);
    m = std::pow(10,m);

    const MantidVec & X = result->readX(0);
    MantidVec & Y = result->dataY(0);
    MantidVec & E = result->dataE(0);
    for (size_t i = 0; i < Y.size(); ++i)
    {
      Y[i] = b*(std::pow(m,0.5*(X[i]+X[i+1])));
      E[i] = std::abs(E[i]*Y[i]);
    }
  }

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

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

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

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

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

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

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

  return outWs;
}
/** Calculate a workspace that contains the result of the fit to the
* transmission fraction that was calculated
*  @param raw [in] the workspace with the unfitted transmission ratio data
*  @param rebinParams [in] the parameters for rebinning
*  @param fitMethod [in] string can be Log, Linear, Poly2, Poly3, Poly4, Poly5,
* Poly6
*  @return a workspace that contains the evaluation of the fit
*  @throw runtime_error if the Linear or ExtractSpectrum algorithm fails during
* execution
*/
API::MatrixWorkspace_sptr
CalculateTransmission::fit(API::MatrixWorkspace_sptr raw,
                           std::vector<double> rebinParams,
                           const std::string fitMethod) {
  MatrixWorkspace_sptr output =
      this->extractSpectra(raw, std::vector<size_t>(1, 0));

  Progress progress(this, m_done, 1.0, 4);
  progress.report("CalculateTransmission: Performing fit");

  // these are calculated by the call to fit below
  double grad(0.0), offset(0.0);
  std::vector<double> coeficients;
  const bool logFit = (fitMethod == "Log");
  if (logFit) {
    g_log.debug("Fitting to the logarithm of the transmission");

    MantidVec &Y = output->dataY(0);
    MantidVec &E = output->dataE(0);
    double start = m_done;
    Progress prog2(this, start, m_done += 0.1, Y.size());
    for (size_t i = 0; i < Y.size(); ++i) {
      // Take the log of each datapoint for fitting. Recalculate errors
      // remembering that d(log(a))/da  = 1/a
      E[i] = std::abs(E[i] / Y[i]);
      Y[i] = std::log10(Y[i]);
      progress.report("Fitting to the logarithm of the transmission");
    }

    // Now fit this to a straight line
    output = fitData(output, grad, offset);
  }                                 // logFit true
  else if (fitMethod == "Linear") { // Linear fit
    g_log.debug("Fitting directly to the data (i.e. linearly)");
    output = fitData(output, grad, offset);
  } else { // fitMethod Polynomial
    int order = getProperty("PolynomialOrder");
    std::stringstream info;
    info << "Fitting the transmission to polynomial order=" << order;
    g_log.information(info.str());
    output = fitPolynomial(output, order, coeficients);
  }

  progress.report("CalculateTransmission: Performing fit");

  // if no rebin parameters were set the output workspace will have the same
  // binning as the input ones, otherwise rebin
  if (!rebinParams.empty()) {
    output = rebin(rebinParams, output);
  }
  progress.report("CalculateTransmission: Performing fit");

  // if there was rebinnning or log fitting we need to recalculate the Ys,
  // otherwise we can just use the workspace kicked out by the fitData()'s call
  // to Linear
  if ((!rebinParams.empty()) || logFit) {
    const MantidVec &X = output->readX(0);
    MantidVec &Y = output->dataY(0);
    if (logFit) {
      // Need to transform back to 'unlogged'
      const double m(std::pow(10, grad));
      const double factor(std::pow(10, offset));

      MantidVec &E = output->dataE(0);
      for (size_t i = 0; i < Y.size(); ++i) {
        // the relationship between the grad and interspt of the log fit and the
        // un-logged value of Y contain this dependence on the X (bin center
        // values)
        Y[i] = factor * (std::pow(m, 0.5 * (X[i] + X[i + 1])));
        E[i] = std::abs(E[i] * Y[i]);
        progress.report();
      }
    } // end logFit
    else if (fitMethod == "Linear") {
      // the simpler linear situation
      for (size_t i = 0; i < Y.size(); ++i) {
        Y[i] = (grad * 0.5 * (X[i] + X[i + 1])) + offset;
      }
    } else { // the polynomial fit
      for (size_t i = 0; i < Y.size(); ++i) {
        double aux = 0;
        double x_v = 0.5 * (X[i] + X[i + 1]);

        for (int j = 0; j < static_cast<int>(coeficients.size()); ++j) {
          aux += coeficients[j] * std::pow(x_v, j);
        }
        Y[i] = aux;
      }
    }
  }
  progress.report("CalculateTransmission: Performing fit");

  return output;
}
/** Calls Gaussian1D as a child algorithm to fit the offset peak in a spectrum
  *
  * @param wi :: The Workspace Index to fit.
  * @param inputW :: Input workspace.
  * @param peakPositions :: Peak positions.
  * @param fitWindows :: Fit windows.
  * @param nparams :: Number of parameters.
  * @param minD :: Min distance.
  * @param maxD :: Max distance.
  * @param peakPosToFit :: Actual peak positions to fit (output).
  * @param peakPosFitted :: Actual peak positions fitted (output).
  * @param chisq :: chisq.
  * @param peakHeights :: vector for fitted heights of peaks
  * @param i_highestpeak:: index of the highest peak among all peaks
  * @param resolution :: spectrum's resolution delta(d)/d
  * @param dev_resolution :: standard deviation resolution
  * @return The number of peaks in range
  */
int GetDetOffsetsMultiPeaks::fitSpectra(
    const int64_t wi, MatrixWorkspace_sptr inputW,
    const std::vector<double> &peakPositions,
    const std::vector<double> &fitWindows, size_t &nparams, double &minD,
    double &maxD, std::vector<double> &peakPosToFit,
    std::vector<double> &peakPosFitted, std::vector<double> &chisq,
    std::vector<double> &peakHeights, int &i_highestpeak, double &resolution,
    double &dev_resolution) {
  // Default overall fit range is the whole spectrum
  const MantidVec &X = inputW->readX(wi);
  minD = X.front();
  maxD = X.back();

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

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

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

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

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

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

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

  nparams = peakPosFitted.size();

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

  return numPeaksInRange;
}
Example #16
0
//------------------------------------------------------------------------------------------------
/// @cond
// Local function used within validateInputs() below in a call to
// std::list::sort(compare)
// to order the input workspaces by the start of their frame (i.e. the first X
// value).
static bool compare(MatrixWorkspace_sptr first, MatrixWorkspace_sptr second) {
    return (first->readX(0).front() < second->readX(0).front());
}
void TOFSANSResolutionByPixel::exec() {
  MatrixWorkspace_sptr inOutWS = getProperty("Workspace");
  double deltaR = getProperty("DeltaR");
  double R1 = getProperty("SourceApertureRadius");
  double R2 = getProperty("SampleApertureRadius");
  // Convert to meters
  deltaR /= 1000.0;
  R1 /= 1000.0;
  R2 /= 1000.0;

  const MatrixWorkspace_sptr sigmaModeratorVSwavelength =
      getProperty("SigmaModerator");

  // create interpolation table from sigmaModeratorVSwavelength
  Kernel::Interpolation lookUpTable;

  const MantidVec xInterpolate = sigmaModeratorVSwavelength->readX(0);
  const MantidVec yInterpolate = sigmaModeratorVSwavelength->readY(0);

  // prefer the input to be a pointworkspace and create interpolation function
  if (sigmaModeratorVSwavelength->isHistogramData()) {
    g_log.notice() << "mid-points of SigmaModerator histogram bins will be "
                      "used for interpolation.";

    for (size_t i = 0; i < xInterpolate.size() - 1; ++i) {
      const double midpoint = xInterpolate[i + 1] - xInterpolate[i];
      lookUpTable.addPoint(midpoint, yInterpolate[i]);
    }
  } else {
    for (size_t i = 0; i < xInterpolate.size(); ++i) {
      lookUpTable.addPoint(xInterpolate[i], yInterpolate[i]);
    }
  }

  const V3D samplePos = inOutWS->getInstrument()->getSample()->getPos();
  const V3D sourcePos = inOutWS->getInstrument()->getSource()->getPos();
  const V3D SSD = samplePos - sourcePos;
  const double L1 = SSD.norm();

  const int numberOfSpectra = static_cast<int>(inOutWS->getNumberHistograms());
  Progress progress(this, 0.0, 1.0, numberOfSpectra);

  for (int i = 0; i < numberOfSpectra; i++) {
    IDetector_const_sptr det;
    try {
      det = inOutWS->getDetector(i);
    } catch (Exception::NotFoundError &) {
      g_log.information() << "Spectrum index " << i
                          << " has no detector assigned to it - discarding"
                          << std::endl;
    }
    // If no detector found or if it's masked or a monitor, skip onto the next
    // spectrum
    if (!det || det->isMonitor() || det->isMasked())
      continue;

    // Get the flight path from the sample to the detector pixel
    const V3D scatteredFlightPathV3D = det->getPos() - samplePos;

    const double L2 = scatteredFlightPathV3D.norm();
    const double Lsum = L1 + L2;

    // calculate part that is wavelenght independent
    const double dTheta2 = (4.0 * M_PI * M_PI / 12.0) *
                           (3.0 * R1 * R1 / (L1 * L1) +
                            3.0 * R2 * R2 * Lsum * Lsum / (L1 * L1 * L2 * L2) +
                            (deltaR * deltaR) / (L2 * L2));

    // Multiplicative factor to go from lambda to Q
    // Don't get fooled by the function name...
    const double theta = inOutWS->detectorTwoTheta(det);
    const double factor = 4.0 * M_PI * sin(theta / 2.0);

    const MantidVec &xIn = inOutWS->readX(i);
    MantidVec &yIn = inOutWS->dataY(i);
    const size_t xLength = xIn.size();

    // for each wavelenght bin of each pixel calculate a q-resolution
    for (size_t j = 0; j < xLength - 1; j++) {
      // use the midpoint of each bin
      const double wl = (xIn[j + 1] + xIn[j]) / 2.0;
      // Calculate q. Alternatively q could be calculated using ConvertUnit
      const double q = factor / wl;

      // wavelenght spread from bin assumed to be
      const double sigmaSpreadFromBin = xIn[j + 1] - xIn[j];

      // wavelenght spread from moderatorm, converted from microseconds to
      // wavelengths
      const double sigmaModerator =
          lookUpTable.value(wl) * 3.9560 / (1000.0 * Lsum);

      // calculate wavelenght resolution from moderator and histogram time bin
      const double sigmaLambda =
          std::sqrt(sigmaSpreadFromBin * sigmaSpreadFromBin / 12.0 +
                    sigmaModerator * sigmaModerator);

      // calculate sigmaQ for a given lambda and pixel
      const double sigmaOverLambdaTimesQ = q * sigmaLambda / wl;
      const double sigmaQ = std::sqrt(
          dTheta2 / (wl * wl) + sigmaOverLambdaTimesQ * sigmaOverLambdaTimesQ);

      // update inout workspace with this sigmaQ
      yIn[j] = sigmaQ;
    }

    progress.report("Computing Q resolution");
  }
}
double DiffractionEventCalibrateDetectors::intensity(
    double x, double y, double z, double rotx, double roty, double rotz,
    std::string detname, std::string inname, std::string outname,
    std::string peakOpt, std::string rb_param, std::string groupWSName) {

  EventWorkspace_sptr inputW = boost::dynamic_pointer_cast<EventWorkspace>(
      AnalysisDataService::Instance().retrieve(inname));

  bool debug = true;
  CPUTimer tim;

  movedetector(x, y, z, rotx, roty, rotz, detname, inputW);
  if (debug)
    std::cout << tim << " to movedetector()\n";

  IAlgorithm_sptr alg3 = createChildAlgorithm("ConvertUnits");
  alg3->setProperty<EventWorkspace_sptr>("InputWorkspace", inputW);
  alg3->setPropertyValue("OutputWorkspace", outname);
  alg3->setPropertyValue("Target", "dSpacing");
  alg3->executeAsChildAlg();
  MatrixWorkspace_sptr outputW = alg3->getProperty("OutputWorkspace");

  if (debug)
    std::cout << tim << " to ConvertUnits\n";

  IAlgorithm_sptr alg4 = createChildAlgorithm("DiffractionFocussing");
  alg4->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputW);
  alg4->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputW);
  alg4->setPropertyValue("GroupingFileName", "");
  alg4->setPropertyValue("GroupingWorkspace", groupWSName);
  alg4->executeAsChildAlg();
  outputW = alg4->getProperty("OutputWorkspace");

  // Remove file
  if (debug)
    std::cout << tim << " to DiffractionFocussing\n";

  IAlgorithm_sptr alg5 = createChildAlgorithm("Rebin");
  alg5->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputW);
  alg5->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputW);
  alg5->setPropertyValue("Params", rb_param);
  alg5->executeAsChildAlg();
  outputW = alg5->getProperty("OutputWorkspace");

  if (debug)
    std::cout << tim << " to Rebin\n";

  // Find point of peak centre
  const MantidVec &yValues = outputW->readY(0);
  auto it = std::max_element(yValues.begin(), yValues.end());
  double peakHeight = *it;
  if (peakHeight == 0)
    return -0.000;
  double peakLoc = outputW->readX(0)[it - yValues.begin()];

  IAlgorithm_sptr fit_alg;
  try {
    // set the ChildAlgorithm no to log as this will be run once per spectra
    fit_alg = createChildAlgorithm("Fit", -1, -1, false);
  } catch (Exception::NotFoundError &) {
    g_log.error("Can't locate Fit algorithm");
    throw;
  }
  std::ostringstream fun_str;
  fun_str << "name=Gaussian,Height=" << peakHeight
          << ",Sigma=0.01,PeakCentre=" << peakLoc;
  fit_alg->setProperty("Function", fun_str.str());
  fit_alg->setProperty("InputWorkspace", outputW);
  fit_alg->setProperty("WorkspaceIndex", 0);
  fit_alg->setProperty("StartX", outputW->readX(0)[0]);
  fit_alg->setProperty("EndX", outputW->readX(0)[outputW->blocksize()]);
  fit_alg->setProperty("MaxIterations", 200);
  fit_alg->setProperty("Output", "fit");
  fit_alg->executeAsChildAlg();

  if (debug)
    std::cout << tim << " to Fit\n";

  std::vector<double> params; // = fit_alg->getProperty("Parameters");
  Mantid::API::IFunction_sptr fun_res = fit_alg->getProperty("Function");
  for (size_t i = 0; i < fun_res->nParams(); ++i) {
    params.push_back(fun_res->getParameter(i));
  }
  peakHeight = params[0];
  peakLoc = params[1];

  movedetector(-x, -y, -z, -rotx, -roty, -rotz, detname, inputW);

  if (debug)
    std::cout << tim << " to movedetector()\n";

  // Optimize C/peakheight + |peakLoc-peakOpt|  where C is scaled by number of
  // events
  EventWorkspace_const_sptr inputE =
      boost::dynamic_pointer_cast<const EventWorkspace>(inputW);
  return (static_cast<int>(inputE->getNumberEvents()) / 1.e6) / peakHeight +
         std::fabs(peakLoc - boost::lexical_cast<double>(peakOpt));
}
/** Executes the algorithm
 *
 */
void CalculateEfficiency::exec()
{

  // Minimum efficiency. Pixels with lower efficiency will be masked
  double min_eff = getProperty("MinEfficiency");
  // Maximum efficiency. Pixels with higher efficiency will be masked
  double max_eff = getProperty("MaxEfficiency");

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

  // Now create the output workspace
  MatrixWorkspace_sptr outputWS;// = getProperty("OutputWorkspace");

 // DataObjects::EventWorkspace_const_sptr inputEventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);

  // Sum up all the wavelength bins
  IAlgorithm_sptr childAlg = createChildAlgorithm("Integration", 0.0, 0.2);
  childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWS);
  childAlg->executeAsChildAlg();
  rebinnedWS = childAlg->getProperty("OutputWorkspace");

  outputWS = WorkspaceFactory::Instance().create(rebinnedWS);
  WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, false);
  for (int i=0; i<(int)rebinnedWS->getNumberHistograms(); i++)
  {
    outputWS->dataX(i) = rebinnedWS->readX(i);
  }
  setProperty("OutputWorkspace",outputWS);

  double sum = 0.0;
  double err = 0.0;
  int npixels = 0;

  // Loop over spectra and sum all the counts to get normalization
  // Skip monitors and masked detectors
  sumUnmaskedDetectors(rebinnedWS, sum, err, npixels);

  // Normalize each detector pixel by the sum we just found to get the
  // relative efficiency. If the minimum and maximum efficiencies are
  // provided, the pixels falling outside this range will be marked
  // as 'masked' in both the input and output workspace.
  // We mask detectors in the input workspace so that we can resum the
  // counts to find a new normalization factor that takes into account
  // the newly masked detectors.
  normalizeDetectors(rebinnedWS, outputWS, sum, err, npixels, min_eff, max_eff);

  if ( !isEmpty(min_eff) || !isEmpty(max_eff) )
  {
    // Recompute the normalization, excluding the pixels that were outside
    // the acceptable efficiency range.
    sumUnmaskedDetectors(rebinnedWS, sum, err, npixels);

    // Now that we have a normalization factor that excludes bad pixels,
    // recompute the relative efficiency.
    // We pass EMPTY_DBL() to avoid masking pixels that might end up high or low
    // after the new normalization.
    normalizeDetectors(rebinnedWS, outputWS, sum, err, npixels, EMPTY_DBL(), EMPTY_DBL());
  }

  return;
}
void TOFSANSResolutionByPixel::exec()
{
  MatrixWorkspace_sptr inOutWS = getProperty("InputWorkspace");
  double deltaR = getProperty("DeltaR");
  double R1 = getProperty("SourceApertureRadius");
  double R2 = getProperty("SampleApertureRadius");
  // Convert to meters
  deltaR /= 1000.0;
  R1 /= 1000.0;
  R2 /= 1000.0;
  const double sigmaModeratorMicroSec = getProperty("SigmaModerator");

  const V3D samplePos = inOutWS->getInstrument()->getSample()->getPos();
  const V3D sourcePos = inOutWS->getInstrument()->getSource()->getPos();
  const V3D SSD = samplePos - sourcePos;
  const double L1 = SSD.norm();

  const int numberOfSpectra = static_cast<int>(inOutWS->getNumberHistograms());
  Progress progress(this,0.0,1.0,numberOfSpectra);

  //PARALLEL_FOR1(inOutWS)
  for (int i = 0; i < numberOfSpectra; i++)
  {
    //PARALLEL_START_INTERUPT_REGION
    IDetector_const_sptr det;
    try {
      det = inOutWS->getDetector(i);
    } catch (Exception::NotFoundError&) {
      g_log.information() << "Spectrum index " << i << " has no detector assigned to it - discarding" << std::endl;
      // Catch if no detector. Next line tests whether this happened - test placed
      // outside here because Mac Intel compiler doesn't like 'continue' in a catch
      // in an openmp block.
    }
    // If no detector found or if it's masked or a monitor, skip onto the next spectrum
    if ( !det || det->isMonitor() || det->isMasked() ) continue;

    // Get the flight path from the sample to the detector pixel
    const V3D scatteredFlightPathV3D = det->getPos() - samplePos; 

    const double L2 = scatteredFlightPathV3D.norm();
    const double Lsum = L1+L2;

    // calculate part that is wavelenght independent
    const double dTheta2 = (4.0 * M_PI * M_PI / 12.0) * 
      ( 3.0*R1*R1/(L1*L1) + 3.0*R2*R2*Lsum*Lsum/(L1*L1*L2*L2) + (deltaR*deltaR)/(L2*L2) );

    // Multiplicative factor to go from lambda to Q
    // Don't get fooled by the function name...
    const double theta = inOutWS->detectorTwoTheta(det);
    const double factor = 4.0 * M_PI * sin( theta/2.0 );

    const MantidVec& xIn = inOutWS->readX(i);
    MantidVec& yIn = inOutWS->dataY(i);
    const size_t xLength = xIn.size();

    for ( size_t j = 0; j < xLength-1; j++)
    {
      // Calculate q. Alternatively q could be calculated using ConvertUnit
      const double wl = (xIn[j+1]+xIn[j])/2.0;
      const double q = factor/wl;

      // calculate wavelenght resolution from moderator and histogram time bin width and
      // convert to from unit of micro-seconds to Aangstrom
      const double sigmaLambda = sigmaModeratorMicroSec*3.9560/(1000.0*Lsum);

      // calculate sigmaQ for a given lambda and pixel
      const double sigmaOverLambdaTimesQ = q*sigmaLambda/wl;
      const double sigmaQ = std::sqrt(dTheta2/(wl*wl)+sigmaOverLambdaTimesQ*sigmaOverLambdaTimesQ);

      // update inout workspace with this sigmaQ
      yIn[j] = sigmaQ;
    }

    progress.report("Computing Q resolution");
    //PARALLEL_END_INTERUPT_REGION
  }

}
Example #21
0
/**
  @ throw invalid_argument if the workspaces are not mututially compatible
*/
void Q1D2::exec()
{
  m_dataWS = getProperty("DetBankWorkspace");
  MatrixWorkspace_const_sptr waveAdj = getProperty("WavelengthAdj");
  MatrixWorkspace_const_sptr pixelAdj = getProperty("PixelAdj");
  MatrixWorkspace_const_sptr wavePixelAdj = getProperty("WavePixelAdj");
  const bool doGravity = getProperty("AccountForGravity");
  m_doSolidAngle = getProperty("SolidAngleWeighting");

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

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

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

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

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

  PARALLEL_FOR3(m_dataWS, outputWS, pixelAdj)
  for (int i = 0; i < numSpec; ++i)
  {
    PARALLEL_START_INTERUPT_REGION
    // Get the pixel relating to this spectrum
    IDetector_const_sptr det;
    try {
      det = m_dataWS->getDetector(i);
    } catch (Exception::NotFoundError&) {
      g_log.warning() << "Workspace index " << i << " (SpectrumIndex = " << m_dataWS->getSpectrum(i)->getSpectrumNo() << ") has no detector assigned to it - discarding" << std::endl;
      // Catch if no detector. Next line tests whether this happened - test placed
      // outside here because Mac Intel compiler doesn't like 'continue' in a catch
      // in an openmp block.
    }
    // If no detector found or if detector is masked shouldn't be included skip onto the next spectrum
    if ( !det || det->isMonitor() || det->isMasked() )
    {
      continue;
    }

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

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

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

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

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

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

    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

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

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

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


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

  outputWS->updateSpectraUsingMap();

  setProperty("OutputWorkspace",outputWS);
}
Example #22
0
  /**
   * Execute the algorithm.
   */
  void SofQW3::exec()
  {
    MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
    // Do the full check for common binning
    if( !WorkspaceHelpers::commonBoundaries(inputWS) )
    {
      throw std::invalid_argument("The input workspace must have common binning across all spectra");
    }

    RebinnedOutput_sptr outputWS = this->setUpOutputWorkspace(inputWS,
                                                 getProperty("QAxisBinning"),
                                                              m_Qout);
    g_log.debug() << "Workspace type: " << outputWS->id() << std::endl;
    setProperty("OutputWorkspace", outputWS);
    const size_t nEnergyBins = inputWS->blocksize();
    const size_t nHistos = inputWS->getNumberHistograms();

    // Progress reports & cancellation
    const size_t nreports(nHistos * nEnergyBins);
    m_progress = boost::shared_ptr<API::Progress>(new API::Progress(this, 0.0,
                                                                    1.0,
                                                                    nreports));

    // Compute input caches
    this->initCachedValues(inputWS);

    std::vector<double> par = inputWS->getInstrument()->getNumberParameter("detector-neighbour-offset");
    if (par.empty())
    {
      // Index theta cache
      this->initThetaCache(inputWS);
    }
    else
    {
      g_log.debug() << "Offset: " << par[0] << std::endl;
      this->m_detNeighbourOffset = static_cast<int>(par[0]);
      this->getValuesAndWidths(inputWS);
    }

    const MantidVec & X = inputWS->readX(0);

    PARALLEL_FOR2(inputWS, outputWS)
    for (int64_t i = 0; i < static_cast<int64_t>(nHistos); ++i) // signed for openmp
    {
      PARALLEL_START_INTERUPT_REGION

      DetConstPtr detector = inputWS->getDetector(i);
      if (detector->isMasked() || detector->isMonitor())
      {
        continue;
      }

      double theta = this->m_theta[i];
      double phi = 0.0;
      double thetaWidth = 0.0;
      double phiWidth = 0.0;
      // Non-PSD mode
      if (par.empty())
      {
        thetaWidth = this->m_thetaWidth;
      }
      // PSD mode
      else
      {
        phi = this->m_phi[i];
        thetaWidth = this->m_thetaWidths[i];
        phiWidth = this->m_phiWidths[i];
      }

      double thetaHalfWidth = 0.5 * thetaWidth;
      double phiHalfWidth = 0.5 * phiWidth;

      const double thetaLower = theta - thetaHalfWidth;
      const double thetaUpper = theta + thetaHalfWidth;

      const double phiLower = phi - phiHalfWidth;
      const double phiUpper = phi + phiHalfWidth;

      const double efixed = this->getEFixed(detector);

      for(size_t j = 0; j < nEnergyBins; ++j)
      {
        m_progress->report("Computing polygon intersections");
        // For each input polygon test where it intersects with
        // the output grid and assign the appropriate weights of Y/E
        const double dE_j = X[j];
        const double dE_jp1 = X[j+1];

        const V2D ll(dE_j, this->calculateQ(efixed, dE_j, thetaLower, phiLower));
        const V2D lr(dE_jp1, this->calculateQ(efixed, dE_jp1, thetaLower, phiLower));
        const V2D ur(dE_jp1, this->calculateQ(efixed, dE_jp1, thetaUpper, phiUpper));
        const V2D ul(dE_j, this->calculateQ(efixed, dE_j, thetaUpper, phiUpper));
        Quadrilateral inputQ = Quadrilateral(ll, lr, ur, ul);

        this->rebinToFractionalOutput(inputQ, inputWS, i, j, outputWS, m_Qout);
      }

      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    outputWS->finalize();
    this->normaliseOutput(outputWS, inputWS);
  }
/** Convert a SPICE 2D Det MatrixWorkspace to MDEvents and append to an
 * MDEventWorkspace
 * It is optional to use a virtual instrument or copy from input data workspace
 * @brief ConvertCWSDExpToMomentum::convertSpiceMatrixToMomentumMDEvents
 * @param dataws :: data matrix workspace
 * @param usevirtual :: boolean flag to use virtual instrument
 * @param startdetid :: starting detid for detectors from this workspace mapping
 * to virtual instrument in MDEventWorkspace
 * @param runnumber :: run number for all MDEvents created from this matrix
 * workspace
 */
void ConvertCWSDExpToMomentum::convertSpiceMatrixToMomentumMDEvents(
    MatrixWorkspace_sptr dataws, bool usevirtual, const detid_t &startdetid,
    const int runnumber) {
  // Create transformation matrix from which the transformation is
  Kernel::DblMatrix rotationMatrix;
  setupTransferMatrix(dataws, rotationMatrix);

  g_log.information() << "Before insert new event, output workspace has "
                      << m_outputWS->getNEvents() << "Events.\n";

  // Creates a new instance of the MDEventInserte to output workspace
  MDEventWorkspace<MDEvent<3>, 3>::sptr mdws_mdevt_3 =
      boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(m_outputWS);
  MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> inserter(mdws_mdevt_3);

  // Calcualte k_i: it is assumed that all k_i are same for one Pt.
  // number, i.e., one 2D XML file
  Kernel::V3D sourcePos = dataws->getInstrument()->getSource()->getPos();
  Kernel::V3D samplePos = dataws->getInstrument()->getSample()->getPos();
  if (dataws->readX(0).size() != 2)
    throw std::runtime_error(
        "Input matrix workspace has wrong dimension in X-axis.");
  double momentum = 0.5 * (dataws->readX(0)[0] + dataws->readX(0)[1]);
  Kernel::V3D ki = (samplePos - sourcePos) * (momentum / sourcePos.norm());

  g_log.debug() << "Source at " << sourcePos.toString()
                << ", Norm = " << sourcePos.norm()
                << ", momentum = " << momentum << "\n"
                << "k_i = " << ki.toString() << "\n";

  // Go though each spectrum to conver to MDEvent
  size_t numspec = dataws->getNumberHistograms();
  double maxsignal = 0;
  size_t nummdevents = 0;
  for (size_t iws = 0; iws < numspec; ++iws) {
    // Get detector positions and signal
    double signal = dataws->readY(iws)[0];
    // Skip event with 0 signal
    if (signal < 0.001)
      continue;
    double error = dataws->readE(iws)[0];
    Kernel::V3D detpos = dataws->getDetector(iws)->getPos();
    std::vector<Mantid::coord_t> q_sample(3);

    // Calculate Q-sample and new detector ID in virtual instrument.
    Kernel::V3D qlab = convertToQSample(samplePos, ki, detpos, momentum,
                                        q_sample, rotationMatrix);
    detid_t native_detid = dataws->getDetector(iws)->getID();
    detid_t detid = native_detid + startdetid;

    // Insert
    inserter.insertMDEvent(
        static_cast<float>(signal), static_cast<float>(error * error),
        static_cast<uint16_t>(runnumber), detid, q_sample.data());
    updateQRange(q_sample);

    g_log.debug() << "Q-lab = " << qlab.toString() << "\n";
    g_log.debug() << "Insert DetID " << detid << ", signal = " << signal
                  << ", with q_sample = " << q_sample[0] << ", " << q_sample[1]
                  << ", " << q_sample[2] << "\n";

    // Update some statistical inforamtion
    if (signal > maxsignal)
      maxsignal = signal;
    ++nummdevents;
  }

  g_log.information() << "Imported Matrixworkspace: Max. Signal = " << maxsignal
                      << ", Add " << nummdevents << " MDEvents "
                      << "\n";

  // Add experiment info including instrument, goniometer and run number
  ExperimentInfo_sptr expinfo = boost::make_shared<ExperimentInfo>();
  if (usevirtual)
    expinfo->setInstrument(m_virtualInstrument);
  else {
    Geometry::Instrument_const_sptr tmp_inst = dataws->getInstrument();
    expinfo->setInstrument(tmp_inst);
  }
  expinfo->mutableRun().setGoniometer(dataws->run().getGoniometer(), false);
  expinfo->mutableRun().addProperty("run_number", runnumber);
  // Add all the other propertys from original data workspace
  const std::vector<Kernel::Property *> vec_property =
      dataws->run().getProperties();
  for (auto property : vec_property) {
    expinfo->mutableRun().addProperty(property->clone());
  }

  m_outputWS->addExperimentInfo(expinfo);

  return;
}
Example #24
0
IEventWorkspace_sptr RefReduction::loadData(const std::string dataRun,
    const std::string polarization)
{
  const std::string instrument = getProperty("Instrument");

  // Check whether dataRun refers to an existing workspace
  // Create a good name for the raw workspace
  std::string ws_name = "__ref_"+dataRun+"-"+polarization+"_raw";
  IEventWorkspace_sptr rawWS;
  if (AnalysisDataService::Instance().doesExist(dataRun))
  {
    rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(dataRun);
    g_log.notice() << "Found workspace: " << dataRun << std::endl;
    m_output_message += "    |Input data run is a workspace: " + dataRun + "\n";
  }
  else if (AnalysisDataService::Instance().doesExist(ws_name))
  {
    rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(ws_name);
    g_log.notice() << "Using existing workspace: " << ws_name << std::endl;
    m_output_message += "    |Found workspace from previous reduction: " + ws_name + "\n";
  }
  else
  {
    // If we can't find a workspace, find a file to load
    std::string path = FileFinder::Instance().getFullPath(dataRun);

    if (path.size()==0 || !Poco::File(path).exists())
    {
      try
      {
        std::vector<std::string> paths = FileFinder::Instance().findRuns(instrument+dataRun);
        path = paths[0];
      }
      catch(Exception::NotFoundError&) { /* Pass. We report the missing file later. */ }
    }

    if (path.size()==0 || !Poco::File(path).exists())
    {
      try
      {
        std::vector<std::string> paths = FileFinder::Instance().findRuns(dataRun);
        path = paths[0];
      }
      catch(Exception::NotFoundError&) { /* Pass. We report the missing file later. */ }
    }

    if (Poco::File(path).exists()) {
      g_log.notice() << "Found: " << path << std::endl;
      m_output_message += "    |Loading from " + path + "\n";
      IAlgorithm_sptr loadAlg = createChildAlgorithm("LoadEventNexus", 0, 0.2);
      loadAlg->setProperty("Filename", path);
      if (polarization.compare(PolStateNone)!=0)
        loadAlg->setProperty("NXentryName", polarization);
      loadAlg->executeAsChildAlg();
      rawWS = loadAlg->getProperty("OutputWorkspace");
      if (rawWS->getNumberEvents()==0)
      {
        g_log.notice() << "No data in " << polarization << std::endl;
        m_output_message += "    |No data for " + polarization + "\n";
        return rawWS;
      }

      // Move the detector to the right position
      if (instrument.compare("REF_M")==0)
      {
          double det_distance = rawWS->getInstrument()->getDetector(0)->getPos().Z();
          Mantid::Kernel::Property* prop = rawWS->run().getProperty("SampleDetDis");
          Mantid::Kernel::TimeSeriesProperty<double>* dp = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double>* >(prop);
          double sdd = dp->getStatistics().mean/1000.0;
          IAlgorithm_sptr mvAlg = createChildAlgorithm("MoveInstrumentComponent", 0.2, 0.25);
          mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", rawWS);
          mvAlg->setProperty("ComponentName", "detector1");
          mvAlg->setProperty("Z", sdd-det_distance);
          mvAlg->setProperty("RelativePosition", true);
          mvAlg->executeAsChildAlg();
          g_log.notice() << "Ensuring correct Z position: Correction = "
              << Poco::NumberFormatter::format(sdd-det_distance)
              << " m" << std::endl;
      }
      AnalysisDataService::Instance().addOrReplace(ws_name, rawWS);
    } else {
        g_log.error() << "Could not find a data file for " << dataRun << std::endl;
        throw std::invalid_argument("Could not find a data file for the given input");
    }
  }

  // Crop TOF as needed and set binning
  double tofMin = getProperty("TOFMin");
  double tofMax = getProperty("TOFMax");
  if (isEmpty(tofMin) || isEmpty(tofMax))
  {
    const MantidVec& x = rawWS->readX(0);
    if (isEmpty(tofMin)) tofMin = *std::min_element(x.begin(), x.end());
    if (isEmpty(tofMax)) tofMax = *std::max_element(x.begin(), x.end());
  }

  int nBins = getProperty("NBins");
  double tofStep = getProperty("TOFStep");
  if (!isEmpty(nBins))
    tofStep = (tofMax-tofMin)/nBins;
  else
    nBins = (int)floor( (tofMax-tofMin)/tofStep );

  std::vector<double> params;
  params.push_back(tofMin);
  params.push_back(tofStep);
  params.push_back(tofMax);

  IAlgorithm_sptr rebinAlg = createChildAlgorithm("Rebin", 0.25, 0.3);
  rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS);
  rebinAlg->setProperty("Params", params);
  rebinAlg->setProperty("PreserveEvents", true);
  rebinAlg->executeAsChildAlg();
  MatrixWorkspace_sptr outputWS = rebinAlg->getProperty("OutputWorkspace");
  m_output_message += "    |TOF binning: "
      +  Poco::NumberFormatter::format(tofMin) + " to "
      +  Poco::NumberFormatter::format(tofMax) + " in steps of "
      +  Poco::NumberFormatter::format(tofStep) + " microsecs\n";

  // Normalise by current
  IAlgorithm_sptr normAlg = createChildAlgorithm("NormaliseByCurrent", 0.3, 0.35);
  normAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS);
  //normAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
  normAlg->executeAsChildAlg();
  outputWS = normAlg->getProperty("OutputWorkspace");

  // Convert to wavelength
  IAlgorithm_sptr convAlg = createChildAlgorithm("ConvertUnits", 0.35, 0.4);
  convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS);
  convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
  convAlg->setProperty("Target", "Wavelength");
  convAlg->executeAsChildAlg();

  // Rebin in wavelength
  const MantidVec& x = outputWS->readX(0);
  double wlMin = *std::min_element(x.begin(), x.end());
  double wlMax = *std::max_element(x.begin(), x.end());

  std::vector<double> wl_params;
  wl_params.push_back(wlMin);
  wl_params.push_back((wlMax-wlMin)/nBins);
  wl_params.push_back(wlMax);

  IAlgorithm_sptr rebinAlg2 = createChildAlgorithm("Rebin", 0.25, 0.3);
  rebinAlg2->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS);
  rebinAlg2->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
  rebinAlg2->setProperty("Params", wl_params);
  rebinAlg2->setProperty("PreserveEvents", true);
  rebinAlg2->executeAsChildAlg();

  IEventWorkspace_sptr outputEvtWS = boost::dynamic_pointer_cast<IEventWorkspace>(outputWS);
  return outputEvtWS;
}
Example #25
0
void FFTDerivative::execComplexFFT()
{
  MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
  MatrixWorkspace_sptr outWS;

  size_t n = inWS->getNumberHistograms();
  API::Progress progress(this,0,1,n);

  size_t ny = inWS->readY(0).size();
  size_t nx = inWS->readX(0).size();

  // Workspace for holding a copy of a spectrum. Each spectrum is symmetrized to minimize
  // possible edge effects.
  MatrixWorkspace_sptr copyWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>
    (Mantid::API::WorkspaceFactory::Instance().create(inWS,1,nx+ny,ny+ny));

  bool isHist = (nx != ny);

  for(size_t spec = 0; spec < n; ++spec)
  {

    const Mantid::MantidVec& x0 = inWS->readX(spec);
    const Mantid::MantidVec& y0 = inWS->readY(spec);

    Mantid::MantidVec& x1 = copyWS->dataX(0);
    Mantid::MantidVec& y1 = copyWS->dataY(0);

    double xx = 2*x0[0];

    x1[ny] = x0[0];
    y1[ny] = y0[0];

    for(size_t i = 1; i < ny; ++i)
    {
      size_t j1 = ny - i;
      size_t j2 = ny + i;
      x1[j1] = xx - x0[i];
      x1[j2] = x0[i];
      y1[j1] = y1[j2] = y0[i];
    }

    x1[0] = 2*x1[1] - x1[2];
    y1[0] = y0.back();

    if (isHist)
    {
      x1[y1.size()] = x0[ny];
    }

    // Transform symmetrized spectrum
    IAlgorithm_sptr fft = createChildAlgorithm("FFT");
    fft->setProperty("InputWorkspace",copyWS);
    fft->setProperty("Real",0);
    fft->setProperty("Transform","Forward");
    fft->execute();

    MatrixWorkspace_sptr transWS = fft->getProperty("OutputWorkspace");

    Mantid::MantidVec& nu = transWS->dataX(3);
    Mantid::MantidVec& re = transWS->dataY(3);
    Mantid::MantidVec& im = transWS->dataY(4);

    int dn = getProperty("Order");
    bool swap_re_im = dn % 2 != 0;
    int sign_re =  1;
    int sign_im = -1;
    switch(dn % 4)
    {
    case 1: sign_re =  1; sign_im = -1; break;
    case 2: sign_re = -1; sign_im = -1; break;
    case 3: sign_re = -1; sign_im =  1; break;
    }
    // Multiply the transform by (2*pi*i*w)**dn
    for(size_t j=0; j < re.size(); ++j)
    {
      double w = 2 * M_PI * nu[j];
      double ww = w;
      for(int k = dn; k > 1; --k)
      {
        ww *= w;
      }
      double a = sign_re * re[j]*ww;
      double b = sign_im * im[j]*ww;
      if (swap_re_im)
      {
        re[j] = b;
        im[j] = a;
      }
      else
      {
        re[j] = a;
        im[j] = b;
      }
    }

    // Inverse transform
    fft = createChildAlgorithm("FFT");
    fft->setProperty("InputWorkspace",transWS);
    fft->setProperty("Real",3);
    fft->setProperty("Imaginary",4);
    fft->setProperty("Transform","Backward");
    fft->execute();

    transWS = fft->getProperty("OutputWorkspace");

    size_t m2 = transWS->readY(0).size() / 2;
    //size_t my = m2 + (transWS->readY(0).size() % 2 ? 1 : 0);
    //size_t mx = my + (transWS->isHistogramData() ? 1 : 0);

    if (!outWS)
    {
      outWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>
        //(Mantid::API::WorkspaceFactory::Instance().create(inWS,n,mx,my));
        (Mantid::API::WorkspaceFactory::Instance().create(inWS));
    }

    // Save the upper half of the inverse transform for output
    Mantid::MantidVec& x = outWS->dataX(spec);
    Mantid::MantidVec& y = outWS->dataY(spec);
    double dx = x1[m2];
    std::copy(transWS->dataX(0).begin() + m2,transWS->dataX(0).end(),x.begin());
    std::transform(x.begin(),x.end(),x.begin(),std::bind2nd(std::plus<double>(),dx));
    std::copy(transWS->dataY(0).begin() + m2,transWS->dataY(0).end(),y.begin());

    progress.report();

  }

  setProperty("OutputWorkspace",outWS);

}
Example #26
0
void FFTDerivative::execRealFFT()
{

  MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
  MatrixWorkspace_sptr outWS;

  size_t n = inWS->getNumberHistograms();
  API::Progress progress(this,0,1,n);

  size_t ny = inWS->readY(0).size();
  size_t nx = inWS->readX(0).size();

  // Workspace for holding a copy of a spectrum. Each spectrum is symmetrized to minimize
  // possible edge effects.
  MatrixWorkspace_sptr copyWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>
    (Mantid::API::WorkspaceFactory::Instance().create(inWS,1,nx+ny,ny+ny));

  bool isHist = (nx != ny);

  for(size_t spec = 0; spec < n; ++spec)
  {

    const Mantid::MantidVec& x0 = inWS->readX(spec);
    const Mantid::MantidVec& y0 = inWS->readY(spec);

    Mantid::MantidVec& x1 = copyWS->dataX(0);
    Mantid::MantidVec& y1 = copyWS->dataY(0);

    double xx = 2*x0[0];

    x1[ny] = x0[0];
    y1[ny] = y0[0];

    for(size_t i = 1; i < ny; ++i)
    {
      size_t j1 = ny - i;
      size_t j2 = ny + i;
      x1[j1] = xx - x0[i];
      x1[j2] = x0[i];
      y1[j1] = y1[j2] = y0[i];
    }

    x1[0] = 2*x1[1] - x1[2];
    y1[0] = y0.back();

    if (isHist)
    {
      x1[y1.size()] = x0[ny];
    }

    // Transform symmetrized spectrum
    IAlgorithm_sptr fft = createChildAlgorithm("RealFFT");
    fft->setProperty("InputWorkspace",copyWS);
    fft->setProperty("WorkspaceIndex",0);
    fft->setProperty("Transform","Forward");
    fft->execute();

    MatrixWorkspace_sptr transWS = fft->getProperty("OutputWorkspace");

    Mantid::MantidVec& nu = transWS->dataX(0);
    Mantid::MantidVec& re = transWS->dataY(0);
    Mantid::MantidVec& im = transWS->dataY(1);

    int dn = getProperty("Order");
    bool swap_re_im = dn % 2 != 0;
    int sign_re =  1;
    int sign_im = -1;
    switch(dn % 4)
    {
    case 1: sign_re =  1; sign_im = -1; break;
    case 2: sign_re = -1; sign_im = -1; break;
    case 3: sign_re = -1; sign_im =  1; break;
    }
    // Multiply the transform by (2*pi*i*w)**dn
    for(size_t j=0; j < re.size(); ++j)
    {
      double w = 2 * M_PI * nu[j];
      double ww = w;
      for(int k = dn; k > 1; --k)
      {
        ww *= w;
      }
      double a = sign_re * re[j]*ww;
      double b = sign_im * im[j]*ww;
      if (swap_re_im)
      {
        re[j] = b;
        im[j] = a;
      }
      else
      {
        re[j] = a;
        im[j] = b;
      }
    }

    // Inverse transform
    fft = createChildAlgorithm("RealFFT");
    fft->setProperty("InputWorkspace",transWS);
    fft->setProperty("Transform","Backward");
    fft->execute();

    transWS = fft->getProperty("OutputWorkspace");

    size_t m2 = transWS->readY(0).size() / 2;
    size_t my = m2 + ((transWS->readY(0).size() % 2) ? 1 : 0);
    size_t mx = my + (transWS->isHistogramData() ? 1 : 0);

    if (!outWS)
    {
      outWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>
        (Mantid::API::WorkspaceFactory::Instance().create(inWS,n,mx,my));
    }

    // Save the upper half of the inverse transform for output
    Mantid::MantidVec& x = outWS->dataX(spec);
    Mantid::MantidVec& y = outWS->dataY(spec);
    double dx = x1[0];
    std::copy(transWS->dataX(0).begin() + m2,transWS->dataX(0).end(),x.begin());
    std::transform(x.begin(),x.end(),x.begin(),std::bind2nd(std::plus<double>(),dx));
    std::copy(transWS->dataY(0).begin() + m2,transWS->dataY(0).end(),y.begin());

    // shift the data to make x and x0 match. using linear interpolation.
    if (x.size() != x0.size() && false)// TODO: doesn't work at the moment. needs to be working
    {
      std::cerr << "(my != x0.size()) " << x0[0] << "!=" << x[0] << std::endl;
      dx = x0[0] - x[0];
      assert(dx > 0.0);
      double f = (x0[0] - x[0]) / (x0[1] - x0[0]);
      for(size_t i = 0; i < my - 1; ++i)
      {
        y[i] += (y[i+1] - y[i]) * f;
        x[i] = x0[i];
      }
      x.back() += dx;

    }

    progress.report();

  }

  setProperty("OutputWorkspace",outWS);

}
Example #27
0
/**  Checks input properties and compares them to previous values
*   @param is :: [output] Number of the first run
*   @param ie :: [output] Number of the last run
*/
void PlotAsymmetryByLogValue::checkProperties(size_t &is, size_t &ie) {

  // Log Value
  m_logName = getPropertyValue("LogValue");
  // Get function to apply to logValue
  m_logFunc = getPropertyValue("Function");
  // Get type of computation
  m_int = (getPropertyValue("Type") == "Integral");
  // Get grouping properties
  m_forward_list = getProperty("ForwardSpectra");
  m_backward_list = getProperty("BackwardSpectra");
  // Get green and red periods
  m_red = getProperty("Red");
  m_green = getProperty("Green");
  // Get time min and time max
  m_minTime = getProperty("TimeMin");
  m_maxTime = getProperty("TimeMax");
  // Get type of dead-time corrections
  m_dtcType = getPropertyValue("DeadTimeCorrType");
  m_dtcFile = getPropertyValue("DeadTimeCorrFile");
  // Get runs
  std::string firstFN = getProperty("FirstRun");
  std::string lastFN = getProperty("LastRun");

  // Parse run names and get the number of runs
  parseRunNames(firstFN, lastFN, m_filenameBase, m_filenameExt,
                m_filenameZeros);
  is = atoi(firstFN.c_str()); // starting run number
  ie = atoi(lastFN.c_str());  // last run number
  if (ie < is) {
    throw std::runtime_error(
        "First run number is greater than last run number");
  }

  // Create a string holding all the properties
  std::ostringstream ss;
  ss << m_filenameBase << "," << m_filenameExt << "," << m_filenameZeros << ",";
  ss << m_dtcType << "," << m_dtcFile << ",";
  ss << getPropertyValue("ForwardSpectra") << ","
     << getPropertyValue("BackwardSpectra") << ",";
  ss << m_int << "," << m_minTime << "," << m_maxTime << ",";
  ss << m_red << "," << m_green << ",";
  ss << m_logName << ", " << m_logFunc;
  m_allProperties = ss.str();

  // Check if we can re-use results from previous run
  // We can reuse results if:
  // 1. There is a ws in the ADS with name m_currResName
  // 2. It is a MatrixWorkspace
  // 3. It has a title equatl to m_allProperties
  // This ws stores previous results as described below
  if (AnalysisDataService::Instance().doesExist(m_currResName)) {
    MatrixWorkspace_sptr prevResults =
        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
            m_currResName);
    if (prevResults) {
      if (m_allProperties == prevResults->getTitle()) {
        // We can re-use results
        size_t nPoints = prevResults->blocksize();
        size_t nHisto = prevResults->getNumberHistograms();

        if (nHisto == 2) {
          // Only 'red' data
          for (size_t i = 0; i < nPoints; i++) {
            // The first spectrum contains: X -> run number, Y -> log value
            // The second spectrum contains: Y -> redY, E -> redE
            size_t run = static_cast<size_t>(prevResults->readX(0)[i]);
            if ((run >= is) && (run <= ie)) {
              m_logValue[run] = prevResults->readY(0)[i];
              m_redY[run] = prevResults->readY(1)[i];
              m_redE[run] = prevResults->readE(1)[i];
            }
          }
        } else {
          // 'Red' and 'Green' data
          for (size_t i = 0; i < nPoints; i++) {
            // The first spectrum contains: X -> run number, Y -> log value
            // The second spectrum contains: Y -> diffY, E -> diffE
            // The third spectrum contains: Y -> redY, E -> redE
            // The fourth spectrum contains: Y -> greenY, E -> greeE
            // The fifth spectrum contains: Y -> sumY, E -> sumE
            size_t run = static_cast<size_t>(prevResults->readX(0)[i]);
            if ((run >= is) && (run <= ie)) {
              m_logValue[run] = prevResults->readY(0)[i];
              m_diffY[run] = prevResults->readY(1)[i];
              m_diffE[run] = prevResults->readE(1)[i];
              m_redY[run] = prevResults->readY(2)[i];
              m_redE[run] = prevResults->readE(2)[i];
              m_greenY[run] = prevResults->readY(3)[i];
              m_greenE[run] = prevResults->readE(3)[i];
              m_sumY[run] = prevResults->readY(4)[i];
              m_sumE[run] = prevResults->readE(4)[i];
            }
          }
        }
      }
    }
  }
}
Example #28
0
    /**
     * 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);
    }
/**
 * Plots raw time data from .raw file before any data conversion has been
 * performed.
 */
void ISISEnergyTransfer::plotRaw() {
  using Mantid::specnum_t;
  using MantidQt::API::BatchAlgorithmRunner;

  if (!m_uiForm.dsRunFiles->isValid()) {
    emit showMessageBox("You must select a run file.");
    return;
  }

  int detectorMin = m_uiForm.spPlotTimeSpecMin->value();
  int detectorMax = m_uiForm.spPlotTimeSpecMax->value();

  if (detectorMin > detectorMax) {
    emit showMessageBox(
        "Minimum spectra must be less than or equal to maximum spectra.");
    return;
  }
  const int startBack = m_uiForm.spBackgroundStart->value();
  const int endBack = m_uiForm.spBackgroundEnd->value();

  if (m_uiForm.ckBackgroundRemoval->isChecked() == true) {
    if (startBack > endBack) {
      emit showMessageBox("Background Start must be less than Background End");
      return;
    }
  }

  QString rawFile = m_uiForm.dsRunFiles->getFirstFilename();
  auto pos = rawFile.lastIndexOf(".");
  auto extension = rawFile.right(rawFile.length() - pos);
  QFileInfo rawFileInfo(rawFile);
  std::string name = rawFileInfo.baseName().toStdString();

  IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("Load");
  loadAlg->initialize();
  loadAlg->setProperty("Filename", rawFile.toStdString());
  loadAlg->setProperty("OutputWorkspace", name);
  loadAlg->setProperty("LoadLogFiles", false);
  if (extension.compare(".nxs") == 0) {
    int64_t detectorMin =
        static_cast<int64_t>(m_uiForm.spPlotTimeSpecMin->value());
    int64_t detectorMax =
        static_cast<int64_t>(m_uiForm.spPlotTimeSpecMax->value());
    loadAlg->setProperty("SpectrumMin", detectorMin);
    loadAlg->setProperty("SpectrumMax", detectorMax);
  } else {
    loadAlg->setProperty("SpectrumMin", detectorMin);
    loadAlg->setProperty("SpectrumMax", detectorMax);
  }

  loadAlg->execute();

  if (m_uiForm.ckBackgroundRemoval->isChecked()) {
    MatrixWorkspace_sptr tempWs =
        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(name);
    const double minBack = tempWs->readX(0)[0];
    const double maxBack = tempWs->readX(0)[tempWs->blocksize()];

    if (startBack < minBack) {
      emit showMessageBox("The Start of Background Removal is less than the "
                          "minimum of the data range");
      return;
    }

    if (endBack > maxBack) {
      emit showMessageBox("The End of Background Removal is more than the "
                          "maximum of the data range");
      return;
    }
  }

  // Rebin the workspace to its self to ensure constant binning
  BatchAlgorithmRunner::AlgorithmRuntimeProps inputToRebin;
  inputToRebin["WorkspaceToMatch"] = name;
  inputToRebin["WorkspaceToRebin"] = name;
  inputToRebin["OutputWorkspace"] = name;

  IAlgorithm_sptr rebinAlg =
      AlgorithmManager::Instance().create("RebinToWorkspace");
  rebinAlg->initialize();
  m_batchAlgoRunner->addAlgorithm(rebinAlg, inputToRebin);

  BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromRebin;
  inputFromRebin["InputWorkspace"] = name;

  std::vector<specnum_t> detectorList;
  for (specnum_t i = detectorMin; i <= detectorMax; i++)
    detectorList.push_back(i);

  if (m_uiForm.ckBackgroundRemoval->isChecked()) {
    std::vector<double> range;
    range.push_back(m_uiForm.spBackgroundStart->value());
    range.push_back(m_uiForm.spBackgroundEnd->value());

    IAlgorithm_sptr calcBackAlg =
        AlgorithmManager::Instance().create("CalculateFlatBackground");
    calcBackAlg->initialize();
    calcBackAlg->setProperty("OutputWorkspace", name + "_bg");
    calcBackAlg->setProperty("Mode", "Mean");
    calcBackAlg->setProperty("StartX", range[0]);
    calcBackAlg->setProperty("EndX", range[1]);
    m_batchAlgoRunner->addAlgorithm(calcBackAlg, inputFromRebin);

    BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromCalcBG;
    inputFromCalcBG["InputWorkspace"] = name + "_bg";

    IAlgorithm_sptr groupAlg =
        AlgorithmManager::Instance().create("GroupDetectors");
    groupAlg->initialize();
    groupAlg->setProperty("OutputWorkspace", name + "_grp");
    groupAlg->setProperty("DetectorList", detectorList);
    m_batchAlgoRunner->addAlgorithm(groupAlg, inputFromCalcBG);

    IAlgorithm_sptr rawGroupAlg =
        AlgorithmManager::Instance().create("GroupDetectors");
    rawGroupAlg->initialize();
    rawGroupAlg->setProperty("OutputWorkspace", name + "_grp_raw");
    rawGroupAlg->setProperty("DetectorList", detectorList);
    m_batchAlgoRunner->addAlgorithm(rawGroupAlg, inputFromRebin);
  } else {
    IAlgorithm_sptr rawGroupAlg =
        AlgorithmManager::Instance().create("GroupDetectors");
    rawGroupAlg->initialize();
    rawGroupAlg->setProperty("OutputWorkspace", name + "_grp");
    rawGroupAlg->setProperty("DetectorList", detectorList);
    m_batchAlgoRunner->addAlgorithm(rawGroupAlg, inputFromRebin);
  }

  disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
             SLOT(algorithmComplete(bool)));
  connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
          SLOT(plotRawComplete(bool)));
  m_batchAlgoRunner->executeBatchAsync();
}
Example #30
0
/** Populates the output workspaces
* @param inWS :: [input] The input workspace
* @param spec :: [input] The current spectrum being analyzed
* @param nspec :: [input] The total number of histograms in the input workspace
* @param result :: [input] The result to be written in the output workspace
* @param outWS :: [input] The output workspace to populate
* @param autoShift :: [input] Whether or not to correct the phase shift
*/
void MaxEnt::populateImageWS(const MatrixWorkspace_sptr &inWS, size_t spec,
                             size_t nspec, const std::vector<double> &result,
                             MatrixWorkspace_sptr &outWS, bool autoShift) {

  if (result.size() % 2)
    throw std::invalid_argument("Cannot write results to output workspaces");

  int npoints = static_cast<int>(result.size() / 2);
  int npointsX = inWS->isHistogramData() ? npoints + 1 : npoints;
  MantidVec X(npointsX);
  MantidVec YR(npoints);
  MantidVec YI(npoints);
  MantidVec E(npoints, 0.);

  double x0 = inWS->readX(spec)[0];
  double dx = inWS->readX(spec)[1] - x0;

  double delta = 1. / dx / npoints;
  int isOdd = (inWS->blocksize() % 2) ? 1 : 0;

  double shift = x0 * 2 * M_PI;
  if (!autoShift)
    shift = 0;

  for (int i = 0; i < npoints; i++) {
    int j = (npoints / 2 + i + isOdd) % npoints;
    X[i] = delta * (-npoints / 2 + i);

    double xShift = X[i] * shift;
    double c = cos(xShift);
    double s = sin(xShift);
    YR[i] = result[2 * j] * c - result[2 * j + 1] * s;
    YI[i] = result[2 * j] * s + result[2 * j + 1] * c;
    YR[i] *= dx;
    YI[i] *= dx;
  }
  if (npointsX == npoints + 1)
    X[npoints] = X[npoints - 1] + delta;

  // Caption & label
  auto inputUnit = inWS->getAxis(0)->unit();
  if (inputUnit) {
    boost::shared_ptr<Kernel::Units::Label> lblUnit =
        boost::dynamic_pointer_cast<Kernel::Units::Label>(
            UnitFactory::Instance().create("Label"));
    if (lblUnit) {

      lblUnit->setLabel(
          inverseCaption[inWS->getAxis(0)->unit()->caption()],
          inverseLabel[inWS->getAxis(0)->unit()->label().ascii()]);
      outWS->getAxis(0)->unit() = lblUnit;
    }
  }

  outWS->dataX(spec).assign(X.begin(), X.end());
  outWS->dataY(spec).assign(YR.begin(), YR.end());
  outWS->dataE(spec).assign(E.begin(), E.end());
  outWS->dataX(nspec + spec).assign(X.begin(), X.end());
  outWS->dataY(nspec + spec).assign(YI.begin(), YI.end());
  outWS->dataE(nspec + spec).assign(E.begin(), E.end());
}