Esempio n. 1
0
/** Checks if workspaces input to Q1D or Qxy are reasonable
  @param dataWS data workspace
  @param binWS (WavelengthAdj) workpace that will be checked to see if it has one spectrum and the same number of bins as dataWS
  @param detectWS (PixelAdj) passing NULL for this wont raise an error, if set it will be checked this workspace has as many histograms as dataWS each with one bin
  @throw invalid_argument if the workspaces are not mututially compatible
*/
void Qhelper::examineInput(API::MatrixWorkspace_const_sptr dataWS, 
     API::MatrixWorkspace_const_sptr binAdj, API::MatrixWorkspace_const_sptr detectAdj)
{
  if ( dataWS->getNumberHistograms() < 1 )
  {
    throw std::invalid_argument("Empty data workspace passed, can not continue");
  }

  //it is not an error for these workspaces not to exist
  if (binAdj)
  {
    if ( binAdj->getNumberHistograms() != 1 )
    {
      throw std::invalid_argument("The WavelengthAdj workspace must have one spectrum");
    }
    if ( binAdj->readY(0).size() != dataWS->readY(0).size() )
    {
      throw std::invalid_argument("The WavelengthAdj workspace's bins must match those of the detector bank workspace");
    }
    MantidVec::const_iterator reqX = dataWS->readX(0).begin();
    MantidVec::const_iterator testX = binAdj->readX(0).begin();
    for ( ; reqX != dataWS->readX(0).end(); ++reqX, ++testX)
    {
      if ( *reqX != *testX )
      {
        throw std::invalid_argument("The WavelengthAdj workspace must have matching bins with the detector bank workspace");
      }
    }
    if ( binAdj->isDistribution() != dataWS->isDistribution() )
    {
      throw std::invalid_argument("The distrbution/raw counts status of the wavelengthAdj and DetBankWorkspace must be the same, use ConvertToDistribution");
    }
  }
  else if( ! dataWS->isDistribution() )
  {
    //throw std::invalid_argument("The data workspace must be a distrbution if there is no Wavelength dependent adjustment");
  }
  
  if (detectAdj)
  {
    if ( detectAdj->blocksize() != 1 )
    {
      throw std::invalid_argument("The PixelAdj workspace must point to a workspace with single bin spectra, as only the first bin is used");
    }
    if ( detectAdj->getNumberHistograms() != dataWS->getNumberHistograms() )
    {
      throw std::invalid_argument("The PixelAdj workspace must have one spectrum for each spectrum in the detector bank workspace");
    }
  }
}
Esempio n. 2
0
/**
 * Creates the output workspace for this algorithm
 * @param inputWorkspace A parent workspace to initialize from.
 * @return A pointer to the output workspace.
 */
API::MatrixWorkspace_sptr Transpose::createOutputWorkspace(
    API::MatrixWorkspace_const_sptr inputWorkspace) {
  Mantid::API::Axis *yAxis = getVerticalAxis(inputWorkspace);
  const size_t oldNhist = inputWorkspace->getNumberHistograms();
  const 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;
}
Esempio n. 3
0
/**
 *  Return true if the units and distribution-type of the workspaces make them
 * compatible
 *  @param lhs :: first workspace to check for compatibility
 *  @param rhs :: second workspace to check for compatibility
 *  @return workspace unit compatibility flag
 */
bool Plus::checkUnitCompatibility(
    const API::MatrixWorkspace_const_sptr lhs,
    const API::MatrixWorkspace_const_sptr rhs) const {
  if (lhs->size() > 1 && rhs->size() > 1) {
    if (lhs->YUnit() != rhs->YUnit()) {
      g_log.error("The two workspaces are not compatible because they have "
                  "different units for the data (Y).");
      return false;
    }
    if (lhs->isDistribution() != rhs->isDistribution()) {
      g_log.error("The two workspaces are not compatible because one is "
                  "flagged as a distribution.");
      return false;
    }
  }
  return true;
}
Esempio n. 4
0
/** Checks that the two input workspace have common binning & size, the same instrument & unit.
 *  Also calls the checkForOverlap method.
 *  @param ws1 :: The first input workspace
 *  @param ws2 :: The second input workspace
 *  @throw std::invalid_argument If the workspaces are not compatible
 */
void ConjoinWorkspaces::validateInputs(API::MatrixWorkspace_const_sptr ws1, API::MatrixWorkspace_const_sptr ws2) const
{
  // This is the full check for common binning
  if ( !WorkspaceHelpers::commonBoundaries(ws1) || !WorkspaceHelpers::commonBoundaries(ws2) )
  {
    g_log.error("Both input workspaces must have common binning for all their spectra");
    throw std::invalid_argument("Both input workspaces must have common binning for all their spectra");
  }

  if ( ws1->getInstrument()->getName() != ws2->getInstrument()->getName() )
  {
    const std::string message("The input workspaces are not compatible because they come from different instruments");
    g_log.error(message);
    throw std::invalid_argument(message);
  }

  Unit_const_sptr ws1_unit = ws1->getAxis(0)->unit();
  Unit_const_sptr ws2_unit = ws2->getAxis(0)->unit();
  const std::string ws1_unitID = ( ws1_unit ? ws1_unit->unitID() : "" );
  const std::string ws2_unitID = ( ws2_unit ? ws2_unit->unitID() : "" );

  if ( ws1_unitID != ws2_unitID )
  {
    const std::string message("The input workspaces are not compatible because they have different units on the X axis");
    g_log.error(message);
    throw std::invalid_argument(message);
  }

  if ( ws1->isDistribution()   != ws2->isDistribution() )
  {
    const std::string message("The input workspaces have inconsistent distribution flags");
    g_log.error(message);
    throw std::invalid_argument(message);
  }

  if ( !WorkspaceHelpers::matchingBins(ws1,ws2,true) )
  {
    const std::string message("The input workspaces are not compatible because they have different binning");
    g_log.error(message);
    throw std::invalid_argument(message);
  }

  this->checkForOverlap(ws1,ws2, true);
}
Esempio n. 5
0
/** Initialise the member variables
 *  @param inputWS The input workspace
 */
void ConvertUnits::setupMemberVariables(const API::MatrixWorkspace_const_sptr inputWS)
{
  m_numberOfSpectra = inputWS->getNumberHistograms();
  // In the context of this algorithm, we treat things as a distribution if the flag is set
  // AND the data are not dimensionless
  m_distribution = inputWS->isDistribution() && !inputWS->YUnit().empty();
  //Check if its an event workspace
  m_inputEvents = ( boost::dynamic_pointer_cast<const EventWorkspace>(inputWS) != NULL );

  m_inputUnit = inputWS->getAxis(0)->unit();
  const std::string targetUnit = getPropertyValue("Target");
  m_outputUnit = UnitFactory::Instance().create(targetUnit);
}
Esempio n. 6
0
 /**
  * Calculate the Y and E values for the given possible overlap
  * @param inputWS :: A pointer to the inputWS
  * @param newPoly :: A reference to a polygon to test for overlap
  * @returns A pair of Y and E values
  */
 std::pair<double,double> 
 SofQW2::calculateYE(API::MatrixWorkspace_const_sptr inputWS,
                     const ConvexPolygon & newPoly) const
 {
   // Build a list intersection locations in terms of workspace indices
   // along with corresponding weights from that location
   std::vector<BinWithWeight> overlaps = findIntersections(inputWS, newPoly);
   std::pair<double,double> binValues(0,0);
   if( inputWS->isDistribution() )
   {
     const double newWidth = newPoly[3].X() - newPoly[0].X(); // For distribution
     binValues = calculateDistYE(inputWS, overlaps, newWidth);
   }
   else
   {
     binValues = calculateYE(inputWS, overlaps);
   }
   return binValues;
 }
Esempio n. 7
0
 void Multiply::setOutputUnits(const API::MatrixWorkspace_const_sptr lhs,const API::MatrixWorkspace_const_sptr rhs,API::MatrixWorkspace_sptr out)
 {
   if ( !lhs->isDistribution() || !rhs->isDistribution() ) out->isDistribution(false);
 }
Esempio n. 8
0
/** Checks if workspaces input to Q1D or Qxy are reasonable
  @param dataWS data workspace
  @param binAdj (WavelengthAdj) workpace that will be checked to see if it has
  one spectrum and the same number of bins as dataWS
  @param detectAdj (PixelAdj) passing NULL for this wont raise an error, if set
  it will be checked this workspace has as many histograms as dataWS each with
  one bin
  @throw invalid_argument if the workspaces are not mututially compatible
*/
void Qhelper::examineInput(API::MatrixWorkspace_const_sptr dataWS,
                           API::MatrixWorkspace_const_sptr binAdj,
                           API::MatrixWorkspace_const_sptr detectAdj) {
  if (dataWS->getNumberHistograms() < 1) {
    throw std::invalid_argument(
        "Empty data workspace passed, can not continue");
  }

  // it is not an error for these workspaces not to exist
  if (binAdj) {
    if (binAdj->getNumberHistograms() != 1) {
      throw std::invalid_argument(
          "The WavelengthAdj workspace must have one spectrum");
    }
    if (binAdj->readY(0).size() != dataWS->readY(0).size()) {
      throw std::invalid_argument("The WavelengthAdj workspace's bins must "
                                  "match those of the detector bank workspace");
    }
    MantidVec::const_iterator reqX = dataWS->readX(0).begin();
    MantidVec::const_iterator testX = binAdj->readX(0).begin();
    for (; reqX != dataWS->readX(0).end(); ++reqX, ++testX) {
      if (*reqX != *testX) {
        throw std::invalid_argument("The WavelengthAdj workspace must have "
                                    "matching bins with the detector bank "
                                    "workspace");
      }
    }
    if (binAdj->isDistribution() != dataWS->isDistribution()) {
      throw std::invalid_argument("The distrbution/raw counts status of the "
                                  "wavelengthAdj and DetBankWorkspace must be "
                                  "the same, use ConvertToDistribution");
    }
  } else if (!dataWS->isDistribution()) {
    // throw std::invalid_argument("The data workspace must be a distrbution if
    // there is no Wavelength dependent adjustment");
  }

  // Perform tests on detectAdj

  if (detectAdj) {
    if (detectAdj->blocksize() != 1) {
      throw std::invalid_argument("The PixelAdj workspace must point to a "
                                  "workspace with single bin spectra, as only "
                                  "the first bin is used");
    }
    if (detectAdj->getNumberHistograms() != dataWS->getNumberHistograms()) {
      throw std::invalid_argument("The PixelAdj workspace must have one "
                                  "spectrum for each spectrum in the detector "
                                  "bank workspace");
    }

    // test that when detector adjustment value less than or equal to zero that
    // the corresponding detector
    // in the workspace is masked

    size_t num_histograms = dataWS->getNumberHistograms();
    for (size_t i = 0; i < num_histograms; i++) {
      double adj = (double)detectAdj->readY(i)[0];
      if (adj <= 0.0) {
        bool det_is_masked;

        try {
          det_is_masked = dataWS->getDetector(i)->isMasked();
        } catch (...) {
          // just ignore. There are times, when the detector is not masked
          // because it does not exist at all.
          det_is_masked = true;
        }
        if (!det_is_masked) {
          throw std::invalid_argument(
              "Every detector with non-positive PixelAdj value must be masked");
        }
      }
    }
  }
}
Esempio n. 9
0
  /** Write out a MatrixWorkspace's data as a 2D matrix.
   * Use writeNexusProcessedDataEvent if writing an EventWorkspace.
   */
  int NexusFileIO::writeNexusProcessedData2D( const API::MatrixWorkspace_const_sptr& localworkspace,
      const bool& uniformSpectra, const std::vector<int>& spec,
      const char * group_name, bool write2Ddata) const
  {
    NXstatus status;

    //write data entry
    status=NXmakegroup(fileID,group_name,"NXdata");
    if(status==NX_ERROR)
      return(2);
    NXopengroup(fileID,group_name,"NXdata");
    // write workspace data
    const size_t nHist=localworkspace->getNumberHistograms();
    if(nHist<1)
      return(2);
    const size_t nSpectBins=localworkspace->readY(0).size();
    const size_t nSpect=spec.size();
    int dims_array[2] = { static_cast<int>(nSpect),static_cast<int>(nSpectBins) };


    // Set the axis labels and values
    Mantid::API::Axis *xAxis=localworkspace->getAxis(0);
    Mantid::API::Axis *sAxis=localworkspace->getAxis(1);
    std::string xLabel,sLabel;
    if ( xAxis->isSpectra() ) xLabel = "spectraNumber";
    else
    {
      if ( xAxis->unit() ) xLabel = xAxis->unit()->unitID();
      else xLabel = "unknown";
    }
    if ( sAxis->isSpectra() ) sLabel = "spectraNumber";
    else
    {
      if ( sAxis->unit() ) sLabel = sAxis->unit()->unitID();
      else sLabel = "unknown";
    }
    // Get the values on the vertical axis
    std::vector<double> axis2;
    if (nSpect < nHist)
      for (size_t i=0;i<nSpect;i++)
        axis2.push_back((*sAxis)(spec[i]));
    else
      for (size_t i=0;i<sAxis->length();i++)
        axis2.push_back((*sAxis)(i));

    int start[2]={0,0};
    int asize[2]={1,dims_array[1]};


    // -------------- Actually write the 2D data ----------------------------
    if (write2Ddata)
    {
      std::string name="values";
      NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array,m_nexuscompression,asize);
      NXopendata(fileID, name.c_str());
      for(size_t i=0;i<nSpect;i++)
      {
        int s = spec[i];
        NXputslab(fileID, reinterpret_cast<void*>(const_cast<double*>(&(localworkspace->readY(s)[0]))),start,asize);
        start[0]++;
      }
      if(m_progress != 0) m_progress->reportIncrement(1, "Writing data");
      int signal=1;
      NXputattr (fileID, "signal", &signal, 1, NX_INT32);
      // More properties
      const std::string axesNames="axis2,axis1";
      NXputattr (fileID, "axes",  reinterpret_cast<void*>(const_cast<char*>(axesNames.c_str())), static_cast<int>(axesNames.size()), NX_CHAR);
      std::string yUnits=localworkspace->YUnit();
      std::string yUnitLabel=localworkspace->YUnitLabel();
      NXputattr (fileID, "units",  reinterpret_cast<void*>(const_cast<char*>(yUnits.c_str())), static_cast<int>(yUnits.size()), NX_CHAR);
      NXputattr (fileID, "unit_label",  reinterpret_cast<void*>(const_cast<char*>(yUnitLabel.c_str())), static_cast<int>(yUnitLabel.size()), NX_CHAR);
      NXclosedata(fileID);

      // error
      name="errors";
      NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array,m_nexuscompression,asize);
      NXopendata(fileID, name.c_str());
      start[0]=0;
      for(size_t i=0;i<nSpect;i++)
      {
        int s = spec[i];
        NXputslab(fileID, reinterpret_cast<void*>(const_cast<double*>(&(localworkspace->readE(s)[0]))),start,asize);
        start[0]++;
      }
      if(m_progress != 0) m_progress->reportIncrement(1, "Writing data");

      // Fractional area for RebinnedOutput
      if (localworkspace->id() == "RebinnedOutput")
      {
        RebinnedOutput_const_sptr rebin_workspace = boost::dynamic_pointer_cast<const RebinnedOutput>(localworkspace);
        name="frac_area";
        NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2,
                              dims_array,m_nexuscompression,asize);
        NXopendata(fileID, name.c_str());
        start[0]=0;
        for(size_t i=0;i<nSpect;i++)
        {
          int s = spec[i];
          NXputslab(fileID, reinterpret_cast<void*>(const_cast<double*>(&(rebin_workspace->readF(s)[0]))),
                           start, asize);
          start[0]++;
        }
        if(m_progress != 0) m_progress->reportIncrement(1, "Writing data");
      }

      NXclosedata(fileID);
    }

    // write X data, as single array or all values if "ragged"
    if(uniformSpectra)
    {
      dims_array[0]=static_cast<int>(localworkspace->readX(0).size());
      NXmakedata(fileID, "axis1", NX_FLOAT64, 1, dims_array);
      NXopendata(fileID, "axis1");
      NXputdata(fileID, reinterpret_cast<void*>(const_cast<double*>(&(localworkspace->readX(0)[0]))));
    }
    else
    {
      dims_array[0]=static_cast<int>(nSpect);
      dims_array[1]=static_cast<int>(localworkspace->readX(0).size());
      NXmakedata(fileID, "axis1", NX_FLOAT64, 2, dims_array);
      NXopendata(fileID, "axis1");
      start[0]=0; asize[1]=dims_array[1];
      for(size_t i=0;i<nSpect;i++)
      {
        NXputslab(fileID, reinterpret_cast<void*>(const_cast<double*>(&(localworkspace->readX(i)[0]))),start,asize);
        start[0]++;
      }
    }
    std::string dist=(localworkspace->isDistribution()) ? "1" : "0";
    NXputattr(fileID, "distribution",  reinterpret_cast<void*>(const_cast<char*>(dist.c_str())), 2, NX_CHAR);
    NXputattr (fileID, "units",  reinterpret_cast<void*>(const_cast<char*>(xLabel.c_str())), static_cast<int>(xLabel.size()), NX_CHAR);

    auto label = boost::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(xAxis->unit());
    if(label)
    {
      NXputattr (fileID, "caption",  reinterpret_cast<void*>(const_cast<char*>(label->caption().c_str())), static_cast<int>(label->caption().size()), NX_CHAR);
      auto unitLbl = label->label();
      NXputattr (fileID, "label",  reinterpret_cast<void*>(const_cast<char*>(unitLbl.ascii().c_str())), static_cast<int>(unitLbl.ascii().size()), NX_CHAR);
    }

    NXclosedata(fileID);

    if ( ! sAxis->isText() )
    {
      // write axis2, maybe just spectra number
      dims_array[0]=static_cast<int>(axis2.size());
      NXmakedata(fileID, "axis2", NX_FLOAT64, 1, dims_array);
      NXopendata(fileID, "axis2");
      NXputdata(fileID, (void*)&(axis2[0]));
      NXputattr (fileID, "units",  reinterpret_cast<void*>(const_cast<char*>(sLabel.c_str())), static_cast<int>(sLabel.size()), NX_CHAR);

      auto label = boost::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(sAxis->unit());
      if(label)
      {
        NXputattr (fileID, "caption",  reinterpret_cast<void*>(const_cast<char*>(label->caption().c_str())), static_cast<int>(label->caption().size()), NX_CHAR);
        auto unitLbl = label->label();
        NXputattr (fileID, "label",  reinterpret_cast<void*>(const_cast<char*>(unitLbl.ascii().c_str())), static_cast<int>(unitLbl.ascii().size()), NX_CHAR);
      }

      NXclosedata(fileID);
    }
    else
    {
      std::string textAxis;
      for ( size_t i = 0; i < sAxis->length(); i ++ )
      {
        std::string label = sAxis->label(i);
        textAxis += label + "\n";
      }
      dims_array[0] = static_cast<int>(textAxis.size());
      NXmakedata(fileID, "axis2", NX_CHAR, 2, dims_array);
      NXopendata(fileID, "axis2");
      NXputdata(fileID,  reinterpret_cast<void*>(const_cast<char*>(textAxis.c_str())));
      NXputattr (fileID, "units",  reinterpret_cast<void*>(const_cast<char*>("TextAxis")), 8, NX_CHAR);

      auto label = boost::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(sAxis->unit());
      if(label)
      {
        NXputattr (fileID, "caption",  reinterpret_cast<void*>(const_cast<char*>(label->caption().c_str())), static_cast<int>(label->caption().size()), NX_CHAR);
        auto unitLbl = label->label();
        NXputattr (fileID, "label",  reinterpret_cast<void*>(const_cast<char*>(unitLbl.ascii().c_str())), static_cast<int>(unitLbl.ascii().size()), NX_CHAR);
      }

      NXclosedata(fileID);
    }

    writeNexusBinMasking(localworkspace);

    status=NXclosegroup(fileID);
    return((status==NX_ERROR)?3:0);
  }