Beispiel #1
0
    /**
     * Return true if the two workspaces are compatible for this operation
     * Virtual: will be overridden as needed.
     * @param lhs :: left-hand workspace to check
     * @param rhs :: right-hand workspace to check
     * @return flag for the compatibility to the two workspaces
     */
    bool BinaryOperation::checkCompatibility(const API::MatrixWorkspace_const_sptr lhs,const API::MatrixWorkspace_const_sptr rhs) const
    {
      Unit_const_sptr lhs_unit;
      Unit_const_sptr rhs_unit;
      if ( lhs->axes() && rhs->axes() ) // If one of these is a WorkspaceSingleValue then we don't want to check units match
      {
        lhs_unit = lhs->getAxis(0)->unit();
        rhs_unit = rhs->getAxis(0)->unit();
      }

      const std::string lhs_unitID = ( lhs_unit ? lhs_unit->unitID() : "" );
      const std::string rhs_unitID = ( rhs_unit ? rhs_unit->unitID() : "" );

      // Check the workspaces have the same units and distribution flag
      if ( lhs_unitID != rhs_unitID && lhs->blocksize() > 1 && rhs->blocksize() > 1 )
      {
        g_log.error("The two workspace are not compatible because they have different units on the X axis.");
        return false;
      }

      // Check the size compatibility
      if (!checkSizeCompatibility(lhs,rhs))
      {
        std::ostringstream ostr;
        ostr<<"The sizes of the two workspaces " <<
            "(" << lhs->getName() << ": " << lhs->getNumberHistograms() << " spectra, blocksize " << lhs->blocksize() << ")"
            << " and " <<
            "(" << rhs->getName() << ": " << rhs->getNumberHistograms() << " spectra, blocksize " << rhs->blocksize() << ")"
            << " are not compatible for algorithm "<<this->name();
        g_log.error() << ostr.str() << std::endl;
        throw std::invalid_argument( ostr.str() );
      }

      return true;
    }
Beispiel #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 MantidVec &inX = inputWorkspace->readX(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 = WorkspaceFactory::Instance().create(
      inputWorkspace, newNhist, newXsize, newYsize);

  // 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);
  } else {
    newYAxis = new API::NumericAxis(inX);
  }

  newYAxis->unit() = inputWorkspace->getAxis(0)->unit();
  outputWorkspace->getAxis(0)->unit() = inputWorkspace->getAxis(1)->unit();
  outputWorkspace->replaceAxis(1, newYAxis);
  setProperty("OutputWorkspace", outputWorkspace);
  return outputWorkspace;
}
Beispiel #3
0
/**
 * Return true if the two workspaces are compatible for this operation
 * Virtual: will be overridden as needed.
 * @param lhs :: left-hand workspace to check
 * @param rhs :: right-hand workspace to check
 * @return flag for the compatibility to the two workspaces
 */
bool BinaryOperation::checkCompatibility(
    const API::MatrixWorkspace_const_sptr lhs,
    const API::MatrixWorkspace_const_sptr rhs) const {
  Unit_const_sptr lhs_unit;
  Unit_const_sptr rhs_unit;
  if (lhs->axes() && rhs->axes()) // If one of these is a WorkspaceSingleValue
                                  // then we don't want to check units match
  {
    lhs_unit = lhs->getAxis(0)->unit();
    rhs_unit = rhs->getAxis(0)->unit();
  }

  const std::string lhs_unitID = (lhs_unit ? lhs_unit->unitID() : "");
  const std::string rhs_unitID = (rhs_unit ? rhs_unit->unitID() : "");

  // Check the workspaces have the same units and distribution flag
  if (lhs_unitID != rhs_unitID && lhs->blocksize() > 1 &&
      rhs->blocksize() > 1) {
    g_log.error("The two workspace are not compatible because they have "
                "different units on the X axis.");
    return false;
  }

  // Check the size compatibility
  std::string checkSizeCompatibilityResult = checkSizeCompatibility(lhs, rhs);
  if (!checkSizeCompatibilityResult.empty()) {
    throw std::invalid_argument(checkSizeCompatibilityResult);
  }

  return true;
}
Beispiel #4
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;
}
Beispiel #5
0
// internal helper function which extract one or two axis from input matrix
// workspace;
void MDTransfNoQ::getAxes(API::MatrixWorkspace_const_sptr inWS,
                          API::NumericAxis *&pXAxis,
                          API::NumericAxis *&pYAxis) {
  // get the X axis of input workspace, it has to be there; if not axis throws
  // invalid index
  pXAxis = dynamic_cast<API::NumericAxis *>(inWS->getAxis(0));
  if (!pXAxis) {
    std::string ERR =
        "Can not retrieve X axis from the source workspace: " + inWS->getName();
    throw(std::invalid_argument(ERR));
  }
  // get optional Y axis which can be used in NoQ-kind of algorithms
  pYAxis = dynamic_cast<API::NumericAxis *>(inWS->getAxis(1));
}
/** Initialization method:
@param bkgWS    -- shared pointer to the workspace which contains background
@param sourceWS -- shared pointer to the workspace to remove background from
@param emode    -- energy conversion mode used during internal units conversion
(0 -- elastic, 1-direct, 2 indirect, as defined in Units conversion
@param pLog     -- pointer to the logger class which would report errors
@param nThreads -- number of threads to be used for background removal
@param inPlace  -- if the background removal occurs from the existing workspace
or target workspace has to be cloned.
*/
void BackgroundHelper::initialize(const API::MatrixWorkspace_const_sptr &bkgWS,
                                  const API::MatrixWorkspace_sptr &sourceWS,
                                  int emode, Kernel::Logger *pLog, int nThreads,
                                  bool inPlace) {
  m_bgWs = bkgWS;
  m_wkWS = sourceWS;
  m_Emode = emode;
  m_pgLog = pLog;
  m_inPlace = inPlace;

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

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

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

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

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

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

  m_Efix = this->getEi(sourceWS);
}
Beispiel #7
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);
}
Beispiel #8
0
/** Remove peaks from a input workspace
  */
Workspace2D_sptr
RemovePeaks::removePeaks(API::MatrixWorkspace_const_sptr dataws, int wsindex,
                         double numfwhm) {
  // Check
  if (m_vecPeakCentre.empty())
    throw runtime_error("RemovePeaks has not been setup yet. ");

  // Initialize vectors
  const MantidVec &vecX = dataws->readX(wsindex);
  const MantidVec &vecY = dataws->readY(wsindex);
  const MantidVec &vecE = dataws->readE(wsindex);

  size_t sizex = vecX.size();
  vector<bool> vec_useX(sizex, true);

  // Exclude regions
  size_t numbkgdpoints =
      excludePeaks(vecX, vec_useX, m_vecPeakCentre, m_vecPeakFWHM, numfwhm);
  size_t numbkgdpointsy = numbkgdpoints;
  size_t sizey = vecY.size();
  if (sizex > sizey)
    --numbkgdpointsy;

  // Construct output workspace
  Workspace2D_sptr outws = boost::dynamic_pointer_cast<Workspace2D>(
      WorkspaceFactory::Instance().create("Workspace2D", 1, numbkgdpoints,
                                          numbkgdpointsy));
  outws->getAxis(0)->setUnit(dataws->getAxis(0)->unit()->unitID());
  MantidVec &outX = outws->dataX(0);
  MantidVec &outY = outws->dataY(0);
  MantidVec &outE = outws->dataE(0);
  size_t index = 0;
  for (size_t i = 0; i < sizex; ++i) {
    if (vec_useX[i]) {
      if (index >= numbkgdpoints)
        throw runtime_error("Programming logic error (1)");
      outX[index] = vecX[i];
      ++index;
    }
  }
  index = 0;
  for (size_t i = 0; i < sizey; ++i) {
    if (vec_useX[i]) {
      if (index >= numbkgdpointsy)
        throw runtime_error("Programming logic error (2)");
      outY[index] = vecY[i];
      outE[index] = vecE[i];
      ++index;
    }
  }

  return outws;
}
/** Checks that the axes of the input workspaces match and creates the output
 * workspace if necessary
 *  @param w1 ::  The first input workspace
 *  @param w2 ::  The second input workspace
 *  @param out :: Pointer to the output workspace
 */
void PointByPointVCorrection::check_validity(
    API::MatrixWorkspace_const_sptr &w1, API::MatrixWorkspace_const_sptr &w2,
    API::MatrixWorkspace_sptr &out) {
  // First check that the instrument matches for both input workspaces
  if (w1->getInstrument()->getName() != w2->getInstrument()->getName()) {
    g_log.error("The input workspaces have different instrument definitions");
    throw std::runtime_error(
        "The input workspaces have different instrument definitions");
  }
  // Check that the two workspaces are the same size
  if (w1->size() != w2->size()) {
    g_log.error("The input workspaces are not the same size");
    throw std::runtime_error("The input workspaces are not the same size");
  }
  // Now check that the bins match
  if (!WorkspaceHelpers::matchingBins(*w1, *w2)) {
    g_log.error("The input workspaces have different binning");
    throw std::runtime_error("The input workspaces have different binning");
  }
  const Mantid::API::Axis *const axis1 = w1->getAxis(1);
  const Mantid::API::Axis *const axis2 = w2->getAxis(1);
  if (!((*axis1) == (*axis2))) // Spectra axis are different, so division does
                               // not make any sense
  {
    g_log.error(
        "The two workspaces InputW1 and InputW2 have different spectra list");
    throw std::runtime_error(
        "The two workspaces InputW1 and InputW2 have different spectra list");
  }

  if (out != w1 && out != w2) // Create a new workspace only if it is different
                              // from of the input ones.
  {
    out = API::WorkspaceFactory::Instance().create(w1);
    setProperty("OutputWorkspace", out);
  } else if (out == w2) {
    g_log.warning("Any masking in the output workspaces will be taken from the "
                  "vanadium workspace (InputW2)");
  }
}
Beispiel #10
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);
}
Beispiel #11
0
/**  returns the units, the input ws is actually in as they coinside with input
 * units for this class */
const std::string
MDTransfNoQ::inputUnitID(Kernel::DeltaEMode::Type mode,
                         API::MatrixWorkspace_const_sptr inWS) const {
  UNUSED_ARG(mode);
  API::NumericAxis *pXAxis;
  // get the X axis of input workspace, it has to be there; if not axis throws
  // invalid index
  pXAxis = dynamic_cast<API::NumericAxis *>(inWS->getAxis(0));
  if (!pXAxis) {
    std::string ERR =
        "Can not retrieve X axis from the source workspace: " + inWS->getName();
    throw(std::invalid_argument(ERR));
  }
  return pXAxis->unit()->unitID();
}
Beispiel #12
0
/** Checks that the input workspace and table have compatible dimensions
 * @return a map where: Key = string name of the the property; Value = string
 * describing the problem with the property.
*/
std::map<std::string, std::string> PhaseQuadMuon::validateInputs() {

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

  // Check that input ws and table ws have compatible dimensions
  API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
  API::ITableWorkspace_const_sptr tabWS = getProperty("PhaseTable");
  if (!inputWS) {
    result["InputWorkspace"] = "InputWorkspace is of Incorrect type. Please "
                               "provide a MatrixWorkspace as the "
                               "InputWorkspace";
    return result;
  }
  size_t nspec = inputWS->getNumberHistograms();
  size_t ndet = tabWS->rowCount();

  if (tabWS->columnCount() == 0) {
    result["PhaseTable"] = "Please provide a non-empty PhaseTable.";
  }

  if (nspec != ndet) {
    result["PhaseTable"] = "PhaseTable must have one row per spectrum";
  }

  // PhaseTable should have three columns: (detector, asymmetry, phase)
  if (tabWS->columnCount() != 3) {
    result["PhaseTable"] = "PhaseTable must have three columns";
  }

  // Check units, should be microseconds
  Unit_const_sptr unit = inputWS->getAxis(0)->unit();
  if ((unit->caption() != "Time") || (unit->label().ascii() != "microsecond")) {
    result["InputWorkspace"] = "InputWorkspace units must be microseconds";
  }

  return result;
}
Beispiel #13
0
/** Get groupings from XML file
*  @param fname :: the full path name of the file to open
*  @param workspace :: a pointer to the input workspace, used to get spectra indexes from numbers
*  @param unUsedSpec :: the list of spectra indexes that have been included in a group (so far)
*  @throw FileError if there's any problem with the file or its format
*/
void GroupDetectors2::processXMLFile(std::string fname,
  API::MatrixWorkspace_const_sptr workspace, std::vector<int64_t> &unUsedSpec)
{
  // 1. Get maps for spectrum ID and detector ID
  spec2index_map specs2index;
  const SpectraAxis* axis = dynamic_cast<const SpectraAxis*>(workspace->getAxis(1));
  if (axis)
  {
    axis->getSpectraIndexMap(specs2index);
  }

  detid2index_map* detIdToWiMap = workspace->getDetectorIDToWorkspaceIndexMap(false);

  // 2. Load XML file
  DataHandling::LoadGroupXMLFile loader;
  loader.setDefaultStartingGroupID(0);
  loader.loadXMLFile(fname);
  std::map<int, std::vector<detid_t> > mGroupDetectorsMap = loader.getGroupDetectorsMap();
  std::map<int, std::vector<int> > mGroupSpectraMap = loader.getGroupSpectraMap();

  // 3. Build m_GroupSpecInds
  std::map<int, std::vector<detid_t> >::iterator dit;
  for (dit = mGroupDetectorsMap.begin(); dit != mGroupDetectorsMap.end(); ++ dit)
  {
    int groupid = dit->first;
    std::vector<size_t> tempv;
    m_GroupSpecInds.insert(std::make_pair(groupid, tempv));
  }

  // 4. Detector IDs
  for (dit = mGroupDetectorsMap.begin(); dit != mGroupDetectorsMap.end(); ++ dit)
  {
    int groupid = dit->first;
    std::vector<detid_t> detids = dit->second;

    storage_map::iterator sit;
    sit = m_GroupSpecInds.find(groupid);
    if (sit == m_GroupSpecInds.end())
      continue;

    std::vector<size_t>& wsindexes = sit->second;

    for (size_t i = 0; i < detids.size(); i++)
    {
      detid_t detid = detids[i];
      detid2index_map::iterator ind =detIdToWiMap->find(detid);
      if ( ind != detIdToWiMap->end() )
      {
        size_t wsid = ind->second;
        wsindexes.push_back(wsid);
        if ( unUsedSpec[wsid] != ( 1000 - INT_MAX ) )
        {
          unUsedSpec[wsid] = ( 1000 - INT_MAX );
        }
      }
      else
      {
        g_log.error() << "Detector with ID " << detid << " is not found in instrument " << std::endl;
      }
    } // for index
  } // for group

  // 5. Spectrum IDs
  std::map<int, std::vector<int> >::iterator pit;
  for (pit = mGroupSpectraMap.begin(); pit != mGroupSpectraMap.end(); ++pit)
  {
    int groupid = pit->first;
    std::vector<int> spectra = pit->second;

    storage_map::iterator sit;
    sit = m_GroupSpecInds.find(groupid);
    if (sit == m_GroupSpecInds.end())
      continue;

    std::vector<size_t>& wsindexes = sit->second;

    for (size_t i = 0; i < spectra.size(); i++)
    {
      int specid = spectra[i];
      spec2index_map::iterator ind = specs2index.find(specid);
      if ( ind != specs2index.end() )
      {
        size_t wsid = ind->second;
        wsindexes.push_back(wsid);
        if ( unUsedSpec[wsid] != ( 1000 - INT_MAX ) )
        {
          unUsedSpec[wsid] = ( 1000 - INT_MAX );
        }
      }
      else
      {
        g_log.error() << "Spectrum with ID " << specid<< " is not found in instrument " << std::endl;
      }
    } // for index
  } // for group

  return;
}
Beispiel #14
0
/** Read the spectra numbers in from the input file (the file format is in the
*  source file "GroupDetectors2.h" and make an array of spectra indexes to group
*  @param fname :: the full path name of the file to open
*  @param workspace :: a pointer to the input workspace, used to get spectra indexes from numbers
*  @param unUsedSpec :: the list of spectra indexes that have been included in a group (so far)
*  @throw FileError if there's any problem with the file or its format
*/
void GroupDetectors2::processFile(std::string fname,
  API::MatrixWorkspace_const_sptr workspace, std::vector<int64_t> &unUsedSpec)
{
  // tring to open the file the user told us exists, skip down 20 lines to find out what happens if we can read from it
  g_log.debug() << "Opening input file ... " << fname;
  std::ifstream File(fname.c_str(), std::ios::in);

  std::string firstLine;
  std::getline( File, firstLine );
  // for error reporting keep a count of where we are reading in the file
  size_t lineNum = 1;

  if (File.fail())
  {
    g_log.debug() << " file state failbit set after read attempt\n";
    throw Exception::FileError("Couldn't read file", fname);
  }
  g_log.debug() << " success opening input file " << fname << std::endl;
  progress(m_FracCompl += OPENINGFILE);
  // check for a (user) cancel message
  interruption_point();

  // allow spectra number to spectra index look ups
  spec2index_map specs2index;
  const SpectraAxis* axis = dynamic_cast<const SpectraAxis*>(workspace->getAxis(1));
  if (axis)
  {
    axis->getSpectraIndexMap(specs2index);
  }

  try
  {
    // we don't use the total number of groups report at the top of the file but we'll tell them later if there is a problem with it for their diagnostic purposes
    int totalNumberOfGroups = readInt(firstLine);

    // Reading file now ...
    while ( totalNumberOfGroups == EMPTY_LINE )
    {
      if ( ! File ) throw Exception::FileError("The input file doesn't appear to contain any data", fname);
      std::getline( File, firstLine ), lineNum ++;
      totalNumberOfGroups = readInt(firstLine);
    }

    readFile(specs2index, File, lineNum, unUsedSpec);

    if ( m_GroupSpecInds.size() != static_cast<size_t>(totalNumberOfGroups) )
    {
      g_log.warning() << "The input file header states there are " << totalNumberOfGroups << " but the file contains " << m_GroupSpecInds.size() << " groups\n";
    }
  }
  // add some more info to the error messages, including the line number, to help users correct their files. These problems should cause the algorithm to stop
  catch (std::invalid_argument &e)
  {
    g_log.debug() << "Exception thrown: " << e.what() << std::endl;
    File.close();
    std::string error(e.what() + std::string(" near line number ") + boost::lexical_cast<std::string>(lineNum));
    if (File.fail())
    {
      error = "Input output error while reading file ";
    }
    throw Exception::FileError(error, fname);
  }
  catch (boost::bad_lexical_cast &e)
  {
    g_log.debug() << "Exception thrown: " << e.what() << std::endl;
    File.close();
    std::string error(std::string("Problem reading integer value \"") + e.what() + std::string("\" near line number ") + boost::lexical_cast<std::string>(lineNum));
    if (File.fail())
    {
      error = "Input output error while reading file ";
    }
    throw Exception::FileError(error, fname);
  }
  File.close();
  g_log.debug() << "Closed file " << fname << " after reading in " << m_GroupSpecInds.size() << " groups\n";
  m_FracCompl += fileReadProg( m_GroupSpecInds.size(), specs2index.size() );
  return;
}
/** Checks that the input workspace and table have compatible dimensions
 * @return a map where: Key = string name of the the property; Value = string
 * describing the problem with the property.
 */
std::map<std::string, std::string> PhaseQuadMuon::validateInputs() {

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

  // Check that input ws and table ws have compatible dimensions
  API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
  API::ITableWorkspace_const_sptr tabWS = getProperty("PhaseTable");
  if (!inputWS) {
    result["InputWorkspace"] = "InputWorkspace is of Incorrect type. Please "
                               "provide a MatrixWorkspace as the "
                               "InputWorkspace";
    return result;
  }
  size_t nspec = inputWS->getNumberHistograms();
  size_t ndet = tabWS->rowCount();

  if (tabWS->columnCount() == 0) {
    result["PhaseTable"] = "Please provide a non-empty PhaseTable.";
  }

  if (nspec != ndet) {
    result["PhaseTable"] = "PhaseTable must have one row per spectrum";
  }

  // PhaseTable should have three columns: (detector, asymmetry, phase)
  if (tabWS->columnCount() != 3) {
    result["PhaseTable"] = "PhaseTable must have three columns";
  }
  auto names = tabWS->getColumnNames();
  for (auto &name : names) {
    std::transform(name.begin(), name.end(), name.begin(), ::tolower);
  }
  int phaseCount = 0;
  int asymmetryCount = 0;
  for (const std::string &name : names) {
    for (const std::string &goodName : phaseNames) {
      if (name == goodName) {
        phaseCount += 1;
      }
    }
    for (const std::string &goodName : asymmNames) {
      if (name == goodName) {
        asymmetryCount += 1;
      }
    }
  }
  if (phaseCount == 0) {
    result["PhaseTable"] = "PhaseTable needs phases column";
  }
  if (asymmetryCount == 0) {
    result["PhaseTable"] = "PhaseTable needs a asymmetry/asymm/asym column";
  }
  if (phaseCount > 1) {
    result["PhaseTable"] =
        "PhaseTable has " + std::to_string(phaseCount) + " phase columns";
  }
  if (asymmetryCount > 1) {
    result["PhaseTable"] = "PhaseTable has " + std::to_string(asymmetryCount) +
                           " asymmetry/asymm/asym columns";
  }
  // Check units, should be microseconds
  Unit_const_sptr unit = inputWS->getAxis(0)->unit();
  if ((unit->caption() != "Time") || (unit->label().ascii() != "microsecond")) {
    result["InputWorkspace"] = "InputWorkspace units must be microseconds";
  }

  return result;
}
Beispiel #16
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);
  }