Example #1
0
void EQSANSSensitivityCorrection::exec()
{
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  MatrixWorkspace_sptr effWS = getProperty("EfficiencyWorkspace");
  const double factor = getProperty("Factor");
  const double error = getProperty("Error");

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

  // Now create a workspace to put in the wavelength-dependence
  MatrixWorkspace_sptr lambdaWS = WorkspaceFactory::Instance().create(inputWS);

  // Number of X bins
  const int xLength = static_cast<int>(inputWS->readY(0).size());
  // Number of detector pixels
  const int numHists = static_cast<int>(inputWS->getNumberHistograms());
  const MantidVec& XIn = inputWS->dataX(0);
  MantidVec& YOut = lambdaWS->dataY(0);
  MantidVec& EOut = lambdaWS->dataE(0);

  progress.report("Computing detector efficiency");
  for (int i = 0; i < xLength; i++)
  {
    double wl = (XIn[i]+XIn[i+1])/2.0;
    YOut[i] = 1.0-std::exp(-factor*wl);
    EOut[i] = std::fabs(factor)*std::exp(-factor*wl)*error;
  }

  progress.report("Computing detector efficiency");
  for (int i = 0; i < numHists; i++)
  {
    MantidVec& YOut_i = lambdaWS->dataY(i);
    MantidVec& EOut_i = lambdaWS->dataE(i);
    MantidVec& XOut_i = lambdaWS->dataX(i);
    YOut_i = YOut;
    EOut_i = EOut;
    XOut_i = XIn;
  }

  lambdaWS = lambdaWS * effWS;
  MatrixWorkspace_sptr outputWS = inputWS / lambdaWS;
  setProperty("OutputWorkspace", outputWS);
  setProperty("OutputEfficiencyWorkspace", lambdaWS);

  setProperty("OutputMessage", "Applied wavelength-dependent sensitivity correction");
}
void ImggFormatsConvertViewQtWidget::writeImg(
    MatrixWorkspace_sptr inWks, const std::string &outputName,
    const std::string &outFormat) const {
  if (!inWks)
    return;
  auto width = inWks->getNumberHistograms();
  if (0 == width)
    return;
  auto height = inWks->blocksize();

  QImage img(QSize(static_cast<int>(width), static_cast<int>(height)),
             QImage::Format_Indexed8);

  int tableSize = 256;
  QVector<QRgb> grayscale(tableSize);
  for (int i = 0; i < grayscale.size(); i++) {
    int level = i; // would be equivalent: qGray(i, i, i);
    grayscale[i] = qRgb(level, level, level);
  }
  img.setColorTable(grayscale);

  // only 16 to 8 bits color map supported with current libraries
  const double scaleFactor = std::numeric_limits<unsigned short int>::max() /
                             std::numeric_limits<unsigned char>::max();
  for (int yi = 0; yi < static_cast<int>(width); ++yi) {
    const auto &row = inWks->readY(yi);
    for (int xi = 0; xi < static_cast<int>(width); ++xi) {
      int scaled = static_cast<int>(row[xi] / scaleFactor);
      // Images not from IMAT, just crop. This needs much improvement when
      // we have proper Load/SaveImage algorithms
      if (scaled > 255)
        scaled = 255;
      if (scaled < 0)
        scaled = 0;
      img.setPixel(xi, yi, scaled);
    }
  }

  writeImgFile(img, outputName, outFormat);
}
Example #3
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;
}
/**
 * This function handles the logic for summing RebinnedOutput workspaces.
 * @param outputWorkspace the workspace to hold the summed input
 * @param progress the progress indicator
 * @param numSpectra
 * @param numMasked
 * @param numZeros
 */
void SumSpectra::doRebinnedOutput(MatrixWorkspace_sptr outputWorkspace,
                                  Progress &progress, size_t &numSpectra,
                                  size_t &numMasked, size_t &numZeros) {
  // Get a copy of the input workspace
  MatrixWorkspace_sptr temp = getProperty("InputWorkspace");

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

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

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

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

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

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

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

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

    progress.report();
  }

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

  // Create the correct representation
  outWS->finalize();
}
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));
}
void CalculateEfficiency::normalizeDetectors(MatrixWorkspace_sptr rebinnedWS,
    MatrixWorkspace_sptr outputWS, double sum, double error, int nPixels,
    double min_eff, double max_eff)
{
    // Number of spectra
    const size_t numberOfSpectra = rebinnedWS->getNumberHistograms();

    // Empty vector to store the pixels that outside the acceptable efficiency range
    std::vector<size_t> dets_to_mask;

    for (size_t i = 0; i < numberOfSpectra; i++)
    {
      const double currProgress = 0.4+0.2*((double)i/(double)numberOfSpectra);
      progress(currProgress, "Computing sensitivity");
      // Get the detector object for this spectrum
      IDetector_const_sptr det = rebinnedWS->getDetector(i);
      // If this detector is masked, skip to the next one
      if ( det->isMasked() ) continue;

      // Retrieve the spectrum into a vector
      const MantidVec& YIn = rebinnedWS->readY(i);
      const MantidVec& EIn = rebinnedWS->readE(i);
      MantidVec& YOut = outputWS->dataY(i);
      MantidVec& EOut = outputWS->dataE(i);
      // If this detector is a monitor, skip to the next one
      if ( det->isMonitor() )
      {
        YOut[0] = 1.0;
        EOut[0] = 0.0;
        continue;
      }

      // Normalize counts to get relative efficiency
      YOut[0] = nPixels/sum * YIn[0];
      const double err_sum = YIn[0]/sum*error;
      EOut[0] = nPixels/std::abs(sum) * std::sqrt(EIn[0]*EIn[0] + err_sum*err_sum);

      // Mask this detector if the signal is outside the acceptable band
      if ( !isEmpty(min_eff) && YOut[0] < min_eff ) dets_to_mask.push_back(i);
      if ( !isEmpty(max_eff) && YOut[0] > max_eff ) dets_to_mask.push_back(i);

    }

    // If we identified pixels to be masked, mask them now
    if ( !dets_to_mask.empty() )
    {
      // Mask detectors that were found to be outside the acceptable efficiency band
      try
      {
        IAlgorithm_sptr mask = createChildAlgorithm("MaskDetectors", 0.8, 0.9);
        // First we mask detectors in the output workspace
        mask->setProperty<MatrixWorkspace_sptr>("Workspace", outputWS);
        mask->setProperty< std::vector<size_t> >("WorkspaceIndexList", dets_to_mask);
        mask->execute();

        mask = createChildAlgorithm("MaskDetectors", 0.9, 1.0);
        // Then we mask the same detectors in the input workspace
        mask->setProperty<MatrixWorkspace_sptr>("Workspace", rebinnedWS);
        mask->setProperty< std::vector<size_t> >("WorkspaceIndexList", dets_to_mask);
        mask->execute();
      } catch (std::invalid_argument& err)
      {
        std::stringstream e;
        e << "Invalid argument to MaskDetectors Child Algorithm: " << err.what();
        g_log.error(e.str());
      } catch (std::runtime_error& err)
      {
        std::stringstream e;
        e << "Unable to successfully run MaskDetectors Child Algorithm: " << err.what();
        g_log.error(e.str());
      }
    }
}
Example #7
0
/** Execute the algorithm.
 */
void MaxEnt::exec() {

  // MaxEnt parameters
  // Complex data?
  bool complex = getProperty("ComplexData");
  // Image must be positive?
  bool positiveImage = getProperty("PositiveImage");
  // Autoshift
  bool autoShift = getProperty("AutoShift");
  // Increase the number of points in the image by this factor
  size_t densityFactor = getProperty("DensityFactor");
  // Background (default level, sky background, etc)
  double background = getProperty("A");
  // Chi target
  double chiTarget = getProperty("ChiTarget");
  // Required precision for Chi arget
  double chiEps = getProperty("ChiEps");
  // Maximum degree of non-parallelism between S and C
  double angle = getProperty("MaxAngle");
  // Distance penalty for current image
  double distEps = getProperty("DistancePenalty");
  // Maximum number of iterations
  size_t niter = getProperty("MaxIterations");
  // Maximum number of iterations in alpha chop
  size_t alphaIter = getProperty("AlphaChopIterations");
  // Number of spectra and datapoints
  // Read input workspace
  MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
  // Number of spectra
  size_t nspec = inWS->getNumberHistograms();
  // Number of data points
  size_t npoints = inWS->blocksize() * densityFactor;
  // Number of X bins
  size_t npointsX = inWS->isHistogramData() ? npoints + 1 : npoints;

  // The type of entropy we are going to use (depends on the type of image,
  // positive only, or positive and/or negative)
  MaxentData_sptr maxentData;
  if (positiveImage) {
    maxentData = boost::make_shared<MaxentData>(
        boost::make_shared<MaxentEntropyPositiveValues>());
  } else {
    maxentData = boost::make_shared<MaxentData>(
        boost::make_shared<MaxentEntropyNegativeValues>());
  }

  // Output workspaces
  MatrixWorkspace_sptr outImageWS;
  MatrixWorkspace_sptr outDataWS;
  MatrixWorkspace_sptr outEvolChi;
  MatrixWorkspace_sptr outEvolTest;

  nspec = complex ? nspec / 2 : nspec;
  outImageWS =
      WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints);
  outDataWS =
      WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints);
  outEvolChi = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter);
  outEvolTest = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter);

  npoints *= 2;
  for (size_t s = 0; s < nspec; s++) {

    // Start distribution (flat background)
    std::vector<double> image(npoints, background);

    if (complex) {
      auto dataRe = inWS->readY(s);
      auto dataIm = inWS->readY(s + nspec);
      auto errorsRe = inWS->readE(s);
      auto errorsIm = inWS->readE(s + nspec);
      maxentData->loadComplex(dataRe, dataIm, errorsRe, errorsIm, image,
                              background);
    } else {
      auto data = inWS->readY(s);
      auto error = inWS->readE(s);
      maxentData->loadReal(data, error, image, background);
    }

    // To record the algorithm's progress
    std::vector<double> evolChi(niter, 0.);
    std::vector<double> evolTest(niter, 0.);

    // Progress
    Progress progress(this, 0, 1, niter);

    // Run maxent algorithm
    for (size_t it = 0; it < niter; it++) {

      // Calculate quadratic model coefficients
      // (SB eq. 21 and 24)
      maxentData->calculateQuadraticCoefficients();
      double currAngle = maxentData->getAngle();
      double currChisq = maxentData->getChisq();
      auto coeffs = maxentData->getQuadraticCoefficients();

      // Calculate delta to construct new image (SB eq. 25)
      auto delta = move(coeffs, chiTarget / currChisq, chiEps, alphaIter);

      // Apply distance penalty (SB eq. 33)
      image = maxentData->getImage();
      delta = applyDistancePenalty(delta, coeffs, image, background, distEps);

      // Update image according to 'delta' and calculate the new Chi-square
      maxentData->updateImage(delta);
      currChisq = maxentData->getChisq();

      // Record the evolution of Chi-square and angle(S,C)
      evolChi[it] = currChisq;
      evolTest[it] = currAngle;

      // Stop condition, solution found
      if ((std::abs(currChisq / chiTarget - 1.) < chiEps) &&
          (currAngle < angle)) {
        break;
      }

      // Check for canceling the algorithm
      if (!(it % 1000)) {
        interruption_point();
      }

      progress.report();

    } // iterations

    // Get calculated data
    auto solData = maxentData->getReconstructedData();
    auto solImage = maxentData->getImage();

    // Populate the output workspaces
    populateDataWS(inWS, s, nspec, solData, outDataWS);
    populateImageWS(inWS, s, nspec, solImage, outImageWS, autoShift);

    // Populate workspaces recording the evolution of Chi and Test
    // X values
    for (size_t it = 0; it < niter; it++) {
      outEvolChi->dataX(s)[it] = static_cast<double>(it);
      outEvolTest->dataX(s)[it] = static_cast<double>(it);
    }
    // Y values
    outEvolChi->dataY(s).assign(evolChi.begin(), evolChi.end());
    outEvolTest->dataY(s).assign(evolTest.begin(), evolTest.end());
    // No errors

  } // Next spectrum

  setProperty("EvolChi", outEvolChi);
  setProperty("EvolAngle", outEvolTest);
  setProperty("ReconstructedImage", outImageWS);
  setProperty("ReconstructedData", outDataWS);
}
void ImageROIViewQtWidget::showProjectionImage(
    const Mantid::API::WorkspaceGroup_sptr &wsg, size_t idx) {

  MatrixWorkspace_sptr ws;
  try {
    ws = boost::dynamic_pointer_cast<MatrixWorkspace>(wsg->getItem(idx));
    if (!ws)
      return;
  } catch (std::exception &e) {
    QMessageBox::warning(
        this, "Cannot load image",
        "There was a problem while trying to find the image data: " +
            QString::fromStdString(e.what()));
  }

  const size_t MAXDIM = 2048 * 16;
  size_t width;
  try {
    width = boost::lexical_cast<size_t>(ws->run().getLogData("Axis1")->value());
    // TODO: add a settings option for this (like max mem allocation for
    // images)?
    if (width >= MAXDIM)
      width = MAXDIM;
  } catch (std::exception &e) {
    QMessageBox::critical(this, "Cannot load image",
                          "There was a problem while trying to "
                          "find the width of the image: " +
                              QString::fromStdString(e.what()));
    return;
  }

  size_t height;
  try {
    height =
        boost::lexical_cast<size_t>(ws->run().getLogData("Axis2")->value());
    if (height >= MAXDIM)
      height = MAXDIM;
  } catch (std::exception &e) {
    QMessageBox::critical(this, "Cannot load image",
                          "There was a problem while trying to "
                          "find the height of the image: " +
                              QString::fromStdString(e.what()));
    return;
  }

  // images are loaded as 1 histogram == 1 pixel (1 bin per histogram):
  if (height != ws->getNumberHistograms() || width != ws->blocksize()) {
    QMessageBox::critical(
        this, "Image dimensions do not match in the input image workspace",
        "Could not load the expected "
        "number of rows and columns.");
    return;
  }
  // find min and max to scale pixel values
  double min = std::numeric_limits<double>::max(),
         max = std::numeric_limits<double>::min();
  for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
    for (size_t j = 0; j < ws->blocksize(); ++j) {
      const double &v = ws->readY(i)[j];
      if (v < min)
        min = v;
      if (v > max)
        max = v;
    }
  }
  if (min >= max) {
    QMessageBox::warning(
        this, "Empty image!",
        "The image could be loaded but it contains "
        "effectively no information, all pixels have the same value.");
    // black picture
    QPixmap pix(static_cast<int>(width), static_cast<int>(height));
    pix.fill(QColor(0, 0, 0));
    m_ui.label_img->setPixmap(pix);
    m_ui.label_img->show();
    m_basePixmap.reset(new QPixmap(pix));
    return;
  }

  // load / transfer image into a QImage
  QImage rawImg(QSize(static_cast<int>(width), static_cast<int>(height)),
                QImage::Format_RGB32);
  const double max_min = max - min;
  const double scaleFactor = 255.0 / max_min;
  for (size_t yi = 0; yi < width; ++yi) {
    for (size_t xi = 0; xi < width; ++xi) {
      const double &v = ws->readY(yi)[xi];
      // color the range min-max in gray scale. To apply different color
      // maps you'd need to use rawImg.setColorTable() or similar.
      const int scaled = static_cast<int>(scaleFactor * (v - min));
      QRgb vRgb = qRgb(scaled, scaled, scaled);
      rawImg.setPixel(static_cast<int>(xi), static_cast<int>(yi), vRgb);
    }
  }

  // paint and show image
  // direct from image
  QPixmap pix = QPixmap::fromImage(rawImg);
  m_ui.label_img->setPixmap(pix);
  m_ui.label_img->show();
  m_basePixmap.reset(new QPixmap(pix));
  // Alternative, drawing with a painter:
  // QPixmap pix(static_cast<int>(width), static_cast<int>(height));
  // QPainter painter;
  // painter.begin(&pix);
  // painter.drawImage(0, 0, rawImg);
  // painter.end();
  // m_ui.label_img->setPixmap(pix);
  // m_ui.label_img->show();
  // m_basePixmap.reset(new QPixmap(pix));
}
Example #9
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];
            }
          }
        }
      }
    }
  }
}
/**  Calculate the integral asymmetry for a workspace (red & green).
*   The calculation is done by MuonAsymmetryCalc and SimpleIntegration algorithms.
*   @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(API::MatrixWorkspace_sptr ws_red,
        API::MatrixWorkspace_sptr ws_green,double& Y, double& E)
{
    if ( !m_autogroup )
    {
        groupDetectors(ws_red,m_backward_list);
        groupDetectors(ws_red,m_forward_list);
        groupDetectors(ws_green,m_backward_list);
        groupDetectors(ws_green,m_forward_list);
    }

    Property* startXprop = getProperty("TimeMin");
    Property* endXprop = getProperty("TimeMax");
    bool setX = !startXprop->isDefault() && !endXprop->isDefault();
    double startX(0.0),endX(0.0);
    if (setX)
    {
        startX = getProperty("TimeMin");
        endX = getProperty("TimeMax");
    }
    if (!m_int)
    {   //  "Differential asymmetry"

        API::MatrixWorkspace_sptr tmpWS = API::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->setPropertyValue("OutputWorkspace","tmp");
        if (setX)
        {
            integr->setProperty("RangeLower",startX);
            integr->setProperty("RangeUpper",endX);
        }
        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->setPropertyValue("OutputWorkspace","tmp");
        if (setX)
        {
            integr->setProperty("RangeLower",startX);
            integr->setProperty("RangeUpper",endX);
        }
        integr->execute();
        API::MatrixWorkspace_sptr intWS_red = integr->getProperty("OutputWorkspace");

        integr = createChildAlgorithm("Integration");
        integr->setProperty("InputWorkspace", ws_green);
        integr->setPropertyValue("OutputWorkspace","tmp");
        if (setX)
        {
            integr->setProperty("RangeLower",startX);
            integr->setProperty("RangeUpper",endX);
        }
        integr->execute();
        API::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 );
    }

}
/**  Calculate the integral asymmetry for a workspace.
*   The calculation is done by MuonAsymmetryCalc and SimpleIntegration algorithms.
*   @param ws :: The 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(API::MatrixWorkspace_sptr ws, double& Y, double& E)
{
    Property* startXprop = getProperty("TimeMin");
    Property* endXprop = getProperty("TimeMax");
    bool setX = !startXprop->isDefault() && !endXprop->isDefault();
    double startX(0.0),endX(0.0);
    if (setX)
    {
        startX = getProperty("TimeMin");
        endX = getProperty("TimeMax");
    }
    if (!m_int)
    {   //  "Differential asymmetry"
        IAlgorithm_sptr asym = createChildAlgorithm("AsymmetryCalc");
        asym->initialize();
        asym->setProperty("InputWorkspace",ws);
        asym->setPropertyValue("OutputWorkspace","tmp");
        if ( !m_autogroup )
        {
            asym->setProperty("ForwardSpectra",m_forward_list);
            asym->setProperty("BackwardSpectra",m_backward_list);
        }
        asym->execute();
        MatrixWorkspace_sptr asymWS = asym->getProperty("OutputWorkspace");

        IAlgorithm_sptr integr = createChildAlgorithm("Integration");
        integr->setProperty("InputWorkspace",asymWS);
        integr->setPropertyValue("OutputWorkspace","tmp");
        if (setX)
        {
            integr->setProperty("RangeLower",startX);
            integr->setProperty("RangeUpper",endX);
        }
        integr->execute();
        API::MatrixWorkspace_sptr out = integr->getProperty("OutputWorkspace");

        Y = out->readY(0)[0];
        E = out->readE(0)[0];
    }
    else
    {
        //  "Integral asymmetry"
        IAlgorithm_sptr integr = createChildAlgorithm("Integration");
        integr->setProperty("InputWorkspace", ws);
        integr->setPropertyValue("OutputWorkspace","tmp");
        if (setX)
        {
            integr->setProperty("RangeLower",startX);
            integr->setProperty("RangeUpper",endX);
        }
        integr->execute();
        API::MatrixWorkspace_sptr intWS = integr->getProperty("OutputWorkspace");

        IAlgorithm_sptr asym = createChildAlgorithm("AsymmetryCalc");
        asym->initialize();
        asym->setProperty("InputWorkspace",intWS);
        asym->setPropertyValue("OutputWorkspace","tmp");
        if ( !m_autogroup )
        {
            asym->setProperty("ForwardSpectra",m_forward_list);
            asym->setProperty("BackwardSpectra",m_backward_list);
        }
        asym->execute();
        MatrixWorkspace_sptr out = asym->getProperty("OutputWorkspace");

        Y = out->readY(0)[0];
        E = out->readE(0)[0];

    }


}
/** 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 #13
0
  //----------------------------------------------------------------------------------------------
  /// @copydoc Mantid::API::Algorithm::exec()
  void ResetNegatives::exec()
  {
    MatrixWorkspace_sptr inputWS = this->getProperty("InputWorkspace");
    MatrixWorkspace_sptr outputWS = this->getProperty("OutputWorkspace");

    // get the minimum for each spectrum
    IAlgorithm_sptr alg = this->createChildAlgorithm("Min", 0., .1);
    alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWS);
    alg->executeAsChildAlg();
    MatrixWorkspace_const_sptr minWS = alg->getProperty("OutputWorkspace");

    // determine if there is anything to do
    int64_t nHist = static_cast<int64_t>(minWS->getNumberHistograms());
    bool hasNegative = false;
    for (int64_t i = 0; i < nHist; i++)
    {
      if (minWS->readY(i)[0] < 0)
      {
        hasNegative = true;
      }
      break;
    }

    // get out early if there is nothing to do
    if (!hasNegative)
    {
      g_log.information() << "No values are negative. Copying InputWorkspace to OutputWorkspace\n";
      if (inputWS != outputWS)
      {
        IAlgorithm_sptr alg = this->createChildAlgorithm("CloneWorkspace", .1, 1.);
        alg->setProperty<Workspace_sptr>("InputWorkspace", inputWS);
        alg->executeAsChildAlg();

        Workspace_sptr temp = alg->getProperty("OutputWorkspace");
        setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(temp));
      }
      return;
    }

    // sort the event list to make it fast and thread safe
    DataObjects::EventWorkspace_const_sptr eventWS
                 = boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>( inputWS );
    if (eventWS)
      eventWS->sortAll(DataObjects::TOF_SORT, NULL);

    Progress prog(this, .1, 1., 2*nHist);

    // generate output workspace - copy X and dY
    outputWS = API::WorkspaceFactory::Instance().create(inputWS);
    PARALLEL_FOR2(inputWS,outputWS)
    for (int64_t i = 0; i < nHist; i++)
    {
      PARALLEL_START_INTERUPT_REGION
      outputWS->dataY(i) = inputWS->readY(i);
      outputWS->dataE(i) = inputWS->readE(i);
      outputWS->setX(i, inputWS->refX(i)); // share the pointer more
      prog.report();
      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    // do the actual work
    if (this->getProperty("AddMinimum"))
    {
        this->pushMinimum(minWS, outputWS, prog);
    }
    else
    {
      this->changeNegatives(minWS, this->getProperty("ResetValue"), outputWS, prog);
    }

    setProperty("OutputWorkspace",outputWS);
  }
void TOFSANSResolutionByPixel::exec() {
  MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
  double deltaR = getProperty("DeltaR");
  double R1 = getProperty("SourceApertureRadius");
  double R2 = getProperty("SampleApertureRadius");
  const bool doGravity = getProperty("AccountForGravity");

  // Check the input
  checkInput(inWS);

  // Setup outputworkspace
  auto outWS = setupOutputWorkspace(inWS);

  // Convert to meters
  deltaR /= 1000.0;
  R1 /= 1000.0;
  R2 /= 1000.0;

  // The moderator workspace needs to match the data workspace
  // in terms of wavelength binning
  const MatrixWorkspace_sptr sigmaModeratorVSwavelength =
      getModeratorWorkspace(inWS);

  // 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]) / 2.0;
      lookUpTable.addPoint(midpoint, yInterpolate[i]);
    }
  } else {
    for (size_t i = 0; i < xInterpolate.size(); ++i) {
      lookUpTable.addPoint(xInterpolate[i], yInterpolate[i]);
    }
  }

  // Calculate the L1 distance
  const V3D samplePos = inWS->getInstrument()->getSample()->getPos();
  const V3D sourcePos = inWS->getInstrument()->getSource()->getPos();
  const V3D SSD = samplePos - sourcePos;
  const double L1 = SSD.norm();

  // Get the collimation length
  double LCollim = getProperty("CollimationLength");

  if (LCollim == 0.0) {
    auto collimationLengthEstimator = SANSCollimationLengthEstimator();
    LCollim = collimationLengthEstimator.provideCollimationLength(inWS);
    g_log.information() << "No collimation length was specified. A default "
                           "collimation length was estimated to be " << LCollim
                        << std::endl;
  } else {
    g_log.information() << "The collimation length is  " << LCollim
                        << std::endl;
  }

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

  for (int i = 0; i < numberOfSpectra; i++) {
    IDetector_const_sptr det;
    try {
      det = inWS->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 samplePos = inWS->getInstrument()->getSample()->getPos();
    const V3D scatteredFlightPathV3D = det->getPos() - samplePos;
    const double L2 = scatteredFlightPathV3D.norm();

    TOFSANSResolutionByPixelCalculator calculator;
    const double waveLengthIndependentFactor =
        calculator.getWavelengthIndependentFactor(R1, R2, deltaR, LCollim, L2);

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

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

    // Gravity correction
    boost::shared_ptr<GravitySANSHelper> grav;
    if (doGravity) {
      grav = boost::make_shared<GravitySANSHelper>(inWS, det,
                                                   getProperty("ExtraLength"));
    }

    // Get handles on the outputWorkspace
    MantidVec &yOut = outWS->dataY(i);
    // 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
      // If we include a gravity correction we need to adjust sinTheta
      // for each wavelength (in Angstrom)
      if (doGravity) {
        double sinThetaGrav = grav->calcSinTheta(wl);
        factor = 4.0 * M_PI * sinThetaGrav;
      }
      const double q = factor / wl;

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

      // Get the uncertainty in Q
      auto sigmaQ = calculator.getSigmaQValue(lookUpTable.value(wl),
                                              waveLengthIndependentFactor, q,
                                              wl, sigmaSpreadFromBin, L1, L2);

      // Insert the Q value and the Q resolution into the outputworkspace
      yOut[j] = sigmaQ;
    }
    progress.report("Computing Q resolution");
  }

  // Set the y axis label
  outWS->setYUnitLabel("QResolution");

  setProperty("OutputWorkspace", outWS);
}
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");
  }
}
/** 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 #17
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 #18
0
/** Filter non-background data points out and create a background workspace
  */
Workspace2D_sptr
ProcessBackground::filterForBackground(BackgroundFunction_sptr bkgdfunction) {
  double posnoisetolerance = getProperty("NoiseTolerance");
  double negnoisetolerance = getProperty("NegativeNoiseTolerance");
  if (isEmpty(negnoisetolerance))
    negnoisetolerance = posnoisetolerance;

  // Calcualte theoretical values
  const std::vector<double> x = m_dataWS->readX(m_wsIndex);
  API::FunctionDomain1DVector domain(x);
  API::FunctionValues values(domain);
  bkgdfunction->function(domain, values);

  g_log.information() << "Function used to select background points : "
                      << bkgdfunction->asString() << "\n";

  // Optional output
  string userbkgdwsname = getPropertyValue("UserBackgroundWorkspace");
  if (userbkgdwsname.size() == 0)
    throw runtime_error("In mode SelectBackgroundPoints, "
                        "UserBackgroundWorkspace must be given!");

  size_t sizex = domain.size();
  size_t sizey = values.size();
  MatrixWorkspace_sptr visualws = boost::dynamic_pointer_cast<MatrixWorkspace>(
      WorkspaceFactory::Instance().create("Workspace2D", 4, sizex, sizey));
  for (size_t i = 0; i < sizex; ++i) {
    for (size_t j = 0; j < 4; ++j) {
      visualws->dataX(j)[i] = domain[i];
    }
  }
  for (size_t i = 0; i < sizey; ++i) {
    visualws->dataY(0)[i] = values[i];
    visualws->dataY(1)[i] = m_dataWS->readY(m_wsIndex)[i] - values[i];
    visualws->dataY(2)[i] = posnoisetolerance;
    visualws->dataY(3)[i] = -negnoisetolerance;
  }
  setProperty("UserBackgroundWorkspace", visualws);

  // Filter for background
  std::vector<double> vecx, vecy, vece;
  for (size_t i = 0; i < domain.size(); ++i) {
    // double y = m_dataWS->readY(m_wsIndex)[i];
    // double theoryy = values[i]; y-theoryy
    double purey = visualws->readY(1)[i];
    if (purey < posnoisetolerance && purey > -negnoisetolerance) {
      // Selected
      double x = domain[i];
      double y = m_dataWS->readY(m_wsIndex)[i];
      double e = m_dataWS->readE(m_wsIndex)[i];
      vecx.push_back(x);
      vecy.push_back(y);
      vece.push_back(e);
    }
  }
  g_log.information() << "Found " << vecx.size() << " background points out of "
                      << m_dataWS->readX(m_wsIndex).size()
                      << " total data points. "
                      << "\n";

  // Build new workspace for OutputWorkspace
  size_t nspec = 3;
  Workspace2D_sptr outws =
      boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
          API::WorkspaceFactory::Instance().create("Workspace2D", nspec,
                                                   vecx.size(), vecy.size()));
  for (size_t i = 0; i < vecx.size(); ++i) {
    for (size_t j = 0; j < nspec; ++j)
      outws->dataX(j)[i] = vecx[i];
    outws->dataY(0)[i] = vecy[i];
    outws->dataE(0)[i] = vece[i];
  }

  return outws;
}
Example #19
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);

}