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

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

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

  newYAxis->unit() = inputWorkspace->getAxis(0)->unit();
  outputWorkspace->getAxis(0)->unit() = inputWorkspace->getAxis(1)->unit();
  outputWorkspace->replaceAxis(1, newYAxis);
  setProperty("OutputWorkspace", outputWorkspace);
  return outputWorkspace;
}
MatrixWorkspace_sptr
ImggFormatsConvertViewQtWidget::loadImg(const std::string &inputName,
                                        const std::string &inFormat) const {

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

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

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

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

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

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

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

  return;
}
Ejemplo n.º 4
0
/**  Populate output workspace with results
*   @param outWS :: [input/output] Output workspace to populate
*   @param nplots :: [input] Number of histograms
*/
void PlotAsymmetryByLogValue::saveResultsToADS(MatrixWorkspace_sptr &outWS,
                                               int nplots) {

  if (nplots == 2) {
    size_t i = 0;
    for (auto &value : m_logValue) {
      size_t run = value.first;
      outWS->dataX(0)[i] = static_cast<double>(run); // run number
      outWS->dataY(0)[i] = value.second;             // log value
      outWS->dataY(1)[i] = m_redY[run];              // redY
      outWS->dataE(1)[i] = m_redE[run];              // redE
      i++;
    }
  } else {
    size_t i = 0;
    for (auto &value : m_logValue) {
      size_t run = value.first;
      outWS->dataX(0)[i] = static_cast<double>(run); // run number
      outWS->dataY(0)[i] = value.second;             // log value
      outWS->dataY(1)[i] = m_diffY[run];             // diffY
      outWS->dataE(1)[i] = m_diffE[run];             // diffE
      outWS->dataY(2)[i] = m_redY[run];              // redY
      outWS->dataE(2)[i] = m_redE[run];              // redE
      outWS->dataY(3)[i] = m_greenY[run];            // greenY
      outWS->dataE(3)[i] = m_greenE[run];            // greenE
      outWS->dataY(4)[i] = m_sumY[run];              // sumY
      outWS->dataE(4)[i] = m_sumE[run];              // sumE
      i++;
    }
  }
  // Set the title!
  outWS->setTitle(m_allProperties);

  // Save results to ADS
  // We can't set an output property to store the results as this algorithm
  // is executed as a child algorithm in the Muon ALC interface
  // If current results were saved as a property we couln't used
  // the functionality to re-use previous results in ALC
  AnalysisDataService::Instance().addOrReplace(m_currResName, outWS);
}
Ejemplo n.º 5
0
/** Reads the header information from a file containing 2D data
*  @param[in] initalLine the second line in the file
*  @param[out] outWrksp the workspace that the data will be writen to
*  @param[out] axis0Data x-values for the workspace
*  @return a progress bar object
*  @throw NotFoundError if there is compulsulary data is missing from the file
*  @throw invalid_argument if there is an inconsistency in the header information
*/
Progress LoadRKH::read2DHeader(const std::string & initalLine, MatrixWorkspace_sptr & outWrksp, MantidVec & axis0Data)
{
    const std::string XUnit(readUnit(initalLine));

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

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

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

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

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

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

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

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

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


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

    return prog;
}
Ejemplo n.º 6
0
WorkspaceGroup_sptr PolarizationCorrection::execPA(WorkspaceGroup_sptr inWS) {

  if (isPropertyDefault(cAlphaLabel())) {
    throw std::invalid_argument("Must provide as input for PA: " +
                                cAlphaLabel());
  }
  if (isPropertyDefault(cApLabel())) {
    throw std::invalid_argument("Must provide as input for PA: " + cApLabel());
  }

  size_t itemIndex = 0;
  MatrixWorkspace_sptr Ipp =
      boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
  MatrixWorkspace_sptr Ipa =
      boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
  MatrixWorkspace_sptr Iap =
      boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
  MatrixWorkspace_sptr Iaa =
      boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));

  Ipp->setTitle("Ipp");
  Iaa->setTitle("Iaa");
  Ipa->setTitle("Ipa");
  Iap->setTitle("Iap");

  auto cropAlg = this->createChildAlgorithm("CropWorkspace");
  cropAlg->initialize();
  cropAlg->setProperty("InputWorkspace", Ipp);
  cropAlg->setProperty("EndWorkspaceIndex", 0);
  cropAlg->execute();
  MatrixWorkspace_sptr croppedIpp = cropAlg->getProperty("OutputWorkspace");

  MatrixWorkspace_sptr ones = copyShapeAndFill(croppedIpp, 1.0);
  // The ones workspace is now identical to the input workspaces in x, but has 1
  // as y values. It can therefore be used to build real polynomial functions.

  const VecDouble c_rho = getProperty(crhoLabel());
  const VecDouble c_alpha = getProperty(cAlphaLabel());
  const VecDouble c_pp = getProperty(cppLabel());
  const VecDouble c_ap = getProperty(cApLabel());

  const auto rho = this->execPolynomialCorrection(
      ones, c_rho); // Execute polynomial expression
  const auto pp = this->execPolynomialCorrection(
      ones, c_pp); // Execute polynomial expression
  const auto alpha = this->execPolynomialCorrection(
      ones, c_alpha); // Execute polynomial expression
  const auto ap = this->execPolynomialCorrection(
      ones, c_ap); // Execute polynomial expression

  const auto A0 = (Iaa * pp * ap) + (ap * Ipa * rho * pp) +
                  (ap * Iap * alpha * pp) + (Ipp * ap * alpha * rho * pp);
  const auto A1 = pp * Iaa;
  const auto A2 = pp * Iap;
  const auto A3 = ap * Iaa;
  const auto A4 = ap * Ipa;
  const auto A5 = ap * alpha * Ipp;
  const auto A6 = ap * alpha * Iap;
  const auto A7 = pp * rho * Ipp;
  const auto A8 = pp * rho * Ipa;

  const auto D = pp * ap * (rho + alpha + 1.0 + (rho * alpha));

  const auto nIpp =
      (A0 - A1 + A2 - A3 + A4 + A5 - A6 + A7 - A8 + Ipp + Iaa - Ipa - Iap) / D;
  const auto nIaa =
      (A0 + A1 - A2 + A3 - A4 - A5 + A6 - A7 + A8 + Ipp + Iaa - Ipa - Iap) / D;
  const auto nIpa =
      (A0 - A1 + A2 + A3 - A4 - A5 + A6 + A7 - A8 - Ipp - Iaa + Ipa + Iap) / D;
  const auto nIap =
      (A0 + A1 - A2 - A3 + A4 + A5 - A6 - A7 + A8 - Ipp - Iaa + Ipa + Iap) / D;

  WorkspaceGroup_sptr dataOut = boost::make_shared<WorkspaceGroup>();
  dataOut->addWorkspace(nIpp);
  dataOut->addWorkspace(nIpa);
  dataOut->addWorkspace(nIap);
  dataOut->addWorkspace(nIaa);
  size_t totalGroupEntries(dataOut->getNumberOfEntries());
  for (size_t i = 1; i < totalGroupEntries; i++) {
    auto alg = this->createChildAlgorithm("ReplaceSpecialValues");
    alg->setProperty("InputWorkspace", dataOut->getItem(i));
    alg->setProperty("OutputWorkspace", "dataOut_" + std::to_string(i));
    alg->setProperty("NaNValue", 0.0);
    alg->setProperty("NaNError", 0.0);
    alg->setProperty("InfinityValue", 0.0);
    alg->setProperty("InfinityError", 0.0);
    alg->execute();
  }
  // Preserve the history of the inside workspaces
  nIpp->history().addHistory(Ipp->getHistory());
  nIaa->history().addHistory(Iaa->getHistory());
  nIpa->history().addHistory(Ipa->getHistory());
  nIap->history().addHistory(Iap->getHistory());

  return dataOut;
}
Ejemplo n.º 7
0
/** Load an individual "<SASentry>" element into a new workspace. It extends the
*LoadCanSAS1D
* in the direction of loading the SAStransmission_spectrum as well. (which was
*introduced in version 1.1)
*
* @param[in] workspaceData points to a "<SASentry>" element
* @param[out] runName the name this workspace should take
* @return dataWS this workspace will be filled with data
* @throw NotFoundError if any expected elements couldn't be read
* @throw NotImplementedError if the entry doesn't contain exactly one run
*/
MatrixWorkspace_sptr
LoadCanSAS1D2::loadEntry(Poco::XML::Node *const workspaceData,
                         std::string &runName) {
  MatrixWorkspace_sptr main_out =
      LoadCanSAS1D::loadEntry(workspaceData, runName);
  bool loadTrans = getProperty("LoadTransmission");
  if (!loadTrans)
    return main_out; // all done. It is not to load the transmission, nor check
                     // if it exists.

  Element *workspaceElem = dynamic_cast<Element *>(workspaceData);
  //  check(workspaceElem, "<SASentry>"); // already done at
  //  LoadCanSAS1D::loadEntry
  Poco::AutoPtr<NodeList> sasTransList =
      workspaceElem->getElementsByTagName("SAStransmission_spectrum");
  if (!sasTransList->length()) {
    g_log.warning() << "There is no transmission data for this file "
                    << getPropertyValue("Filename") << std::endl;
    return main_out;
  }

  for (unsigned short trans_index = 0; trans_index < sasTransList->length();
       trans_index++) {
    // foreach SAStransmission_spectrum
    Node *idataElem = sasTransList->item(trans_index);
    Element *sasTrasElem = dynamic_cast<Element *>(idataElem);
    if (!sasTrasElem)
      continue;
    std::vector<API::MatrixWorkspace_sptr> &group =
        (sasTrasElem->getAttribute("name") == "sample") ? trans_gp
                                                        : trans_can_gp;

    // getting number of Tdata elements in the xml file
    Poco::AutoPtr<NodeList> tdataElemList =
        sasTrasElem->getElementsByTagName("Tdata");
    size_t nBins = tdataElemList->length();

    MatrixWorkspace_sptr dataWS =
        WorkspaceFactory::Instance().create("Workspace2D", 1, nBins, nBins);

    createLogs(workspaceElem, dataWS);

    std::string title = main_out->getTitle();
    title += ":trans";
    title += sasTrasElem->getAttribute("name");
    dataWS->setTitle(title);
    dataWS->isDistribution(true);
    dataWS->setYUnit("");

    // load workspace data
    MantidVec &X = dataWS->dataX(0);
    MantidVec &Y = dataWS->dataY(0);
    MantidVec &E = dataWS->dataE(0);
    int vecindex = 0;
    // iterate through each Tdata element  and get the values of "Lambda",
    //"T" and "Tdev" text nodes and fill X,Y,E vectors
    for (unsigned long index = 0; index < nBins; ++index) {
      Node *idataElem = tdataElemList->item(index);
      Element *elem = dynamic_cast<Element *>(idataElem);
      if (elem) {
        // setting X vector
        std::string nodeVal;
        Element *qElem = elem->getChildElement("Lambda");
        check(qElem, "Lambda");
        nodeVal = qElem->innerText();
        std::stringstream x(nodeVal);
        double d;
        x >> d;
        X[vecindex] = d;

        // setting Y vector
        Element *iElem = elem->getChildElement("T");
        check(qElem, "T");
        nodeVal = iElem->innerText();
        std::stringstream y(nodeVal);
        y >> d;
        Y[vecindex] = d;

        // setting the error vector
        Element *idevElem = elem->getChildElement("Tdev");
        check(qElem, "Tdev");
        nodeVal = idevElem->innerText();
        std::stringstream e(nodeVal);
        e >> d;
        E[vecindex] = d;
        ++vecindex;
      }
    }

    runLoadInstrument(main_out->getInstrument()->getName(), dataWS);
    dataWS->getAxis(0)->setUnit("Wavelength");

    // add to group
    group.push_back(dataWS);
  }
  return main_out;
}
Ejemplo n.º 8
0
/**
 * Read histogram data
 * @param histogramEntries map of the file entries that have histogram
 * @param outputGroup pointer to the workspace group
 * @param nxFile Reads data from inside first first top entry
 */
void LoadMcStas::readHistogramData(
    const std::map<std::string, std::string> &histogramEntries,
    WorkspaceGroup_sptr &outputGroup, ::NeXus::File &nxFile) {

  std::string nameAttrValueYLABEL;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

} // finish
WorkspaceGroup_sptr
PolarizationCorrectionFredrikze::execPA(WorkspaceGroup_sptr inWS) {

  size_t itemIndex = 0;
  MatrixWorkspace_sptr Ipp =
      boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
  MatrixWorkspace_sptr Ipa =
      boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
  MatrixWorkspace_sptr Iap =
      boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));
  MatrixWorkspace_sptr Iaa =
      boost::dynamic_pointer_cast<MatrixWorkspace>(inWS->getItem(itemIndex++));

  Ipp->setTitle("Ipp");
  Iaa->setTitle("Iaa");
  Ipa->setTitle("Ipa");
  Iap->setTitle("Iap");

  const auto rho = this->getEfficiencyWorkspace(crhoLabel);
  const auto pp = this->getEfficiencyWorkspace(cppLabel);
  const auto alpha = this->getEfficiencyWorkspace(cAlphaLabel);
  const auto ap = this->getEfficiencyWorkspace(cApLabel);

  const auto A0 = (Iaa * pp * ap) + (Ipa * ap * rho * pp) +
                  (Iap * ap * alpha * pp) + (Ipp * ap * alpha * rho * pp);
  const auto A1 = Iaa * pp;
  const auto A2 = Iap * pp;
  const auto A3 = Iaa * ap;
  const auto A4 = Ipa * ap;
  const auto A5 = Ipp * ap * alpha;
  const auto A6 = Iap * ap * alpha;
  const auto A7 = Ipp * pp * rho;
  const auto A8 = Ipa * pp * rho;

  const auto D = pp * ap * (rho + alpha + 1.0 + (rho * alpha));

  const auto nIpp =
      (A0 - A1 + A2 - A3 + A4 + A5 - A6 + A7 - A8 + Ipp + Iaa - Ipa - Iap) / D;
  const auto nIaa =
      (A0 + A1 - A2 + A3 - A4 - A5 + A6 - A7 + A8 + Ipp + Iaa - Ipa - Iap) / D;
  const auto nIap =
      (A0 - A1 + A2 + A3 - A4 - A5 + A6 + A7 - A8 - Ipp - Iaa + Ipa + Iap) / D;
  const auto nIpa =
      (A0 + A1 - A2 - A3 + A4 + A5 - A6 - A7 + A8 - Ipp - Iaa + Ipa + Iap) / D;

  WorkspaceGroup_sptr dataOut = boost::make_shared<WorkspaceGroup>();
  dataOut->addWorkspace(nIpp);
  dataOut->addWorkspace(nIpa);
  dataOut->addWorkspace(nIap);
  dataOut->addWorkspace(nIaa);
  size_t totalGroupEntries(dataOut->getNumberOfEntries());
  for (size_t i = 1; i < totalGroupEntries; i++) {
    auto alg = this->createChildAlgorithm("ReplaceSpecialValues");
    alg->setProperty("InputWorkspace", dataOut->getItem(i));
    alg->setProperty("OutputWorkspace", "dataOut_" + std::to_string(i));
    alg->setProperty("NaNValue", 0.0);
    alg->setProperty("NaNError", 0.0);
    alg->setProperty("InfinityValue", 0.0);
    alg->setProperty("InfinityError", 0.0);
    alg->execute();
  }
  // Preserve the history of the inside workspaces
  nIpp->history().addHistory(Ipp->getHistory());
  nIaa->history().addHistory(Iaa->getHistory());
  nIpa->history().addHistory(Ipa->getHistory());
  nIap->history().addHistory(Iap->getHistory());

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

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

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

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

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

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

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

    }

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

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

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

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

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

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

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

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

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

        progress.report();
        PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

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

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

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

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

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

    // Set OutputWorkspace property
    setProperty("OutputWorkspace", outputWS);
}