Beispiel #1
0
/** Read a data file that contains only one spectrum into a workspace
*  @return the new workspace
*/
const API::MatrixWorkspace_sptr LoadRKH::read1D() {
  g_log.information()
      << "file appears to contain 1D information, reading in 1D data mode\n";

  // The 3rd line contains information regarding the number of points in the
  // file and
  // start and end reading points
  int totalPoints(0), readStart(0), readEnd(0), buried(0);
  std::string fileline;

  getline(m_fileIn, fileline);
  std::istringstream is(fileline);
  // Get data information
  for (int counter = 1; counter < 8; ++counter) {
    switch (counter) {
    case 1:
      is >> totalPoints;
      break;
    case 5:
      is >> readStart;
      break;
    case 6:
      is >> readEnd;
      break;
    default:
      is >> buried;
      break;
    }
  }

  g_log.information()
      << "Total number of data points declared to be in the data file: "
      << totalPoints << "\n";

  // What are we reading?
  std::string firstColVal = getProperty("FirstColumnValue");
  bool colIsUnit(true);
  if (m_RKHKeys.find(firstColVal) != m_RKHKeys.end()) {
    colIsUnit = false;
    readStart = 1;
    readEnd = totalPoints;
  }

  if (readStart < 1 || readEnd < 1 || readEnd < readStart ||
      readStart > totalPoints || readEnd > totalPoints) {
    g_log.error("Invalid data range specfied.");
    m_fileIn.close();
    throw std::invalid_argument("Invalid data range specfied.");
  }

  g_log.information() << "Reading started on data line: " << readStart << "\n";
  g_log.information() << "Reading finished on data line: " << readEnd << "\n";

  // The 4th and 5th line do not contain useful information either
  skipLines(m_fileIn, 2);

  int pointsToRead = readEnd - readStart + 1;
  // Now stream sits at the first line of data
  std::vector<double> columnOne, ydata, errdata, xError;
  columnOne.reserve(readEnd);
  ydata.reserve(readEnd);
  errdata.reserve(readEnd);

  auto hasXError = hasXerror(m_fileIn);

  Progress prog(this, 0.0, 1.0, readEnd);

  if (hasXError) {
    xError.reserve(readEnd);
    readLinesWithXErrorForRKH1D(m_fileIn, readStart, readEnd, columnOne, ydata,
                                errdata, xError, prog);
  } else {
    readLinesForRKH1D(m_fileIn, readStart, readEnd, columnOne, ydata, errdata,
                      prog);
  }
  m_fileIn.close();

  assert(pointsToRead == static_cast<int>(columnOne.size()));
  assert(pointsToRead == static_cast<int>(ydata.size()));
  assert(pointsToRead == static_cast<int>(errdata.size()));

  if (hasXError) {
    assert(pointsToRead == static_cast<int>(xError.size()));
  }

  if (colIsUnit) {
    MatrixWorkspace_sptr localworkspace = WorkspaceFactory::Instance().create(
        "Workspace2D", 1, pointsToRead, pointsToRead);
    localworkspace->getAxis(0)->unit() =
        UnitFactory::Instance().create(firstColVal);
    localworkspace->dataX(0) = columnOne;
    localworkspace->dataY(0) = ydata;
    localworkspace->dataE(0) = errdata;
    if (hasXError) {
      localworkspace->dataDx(0) = xError;
    }
    return localworkspace;
  } else {
    MatrixWorkspace_sptr localworkspace =
        WorkspaceFactory::Instance().create("Workspace2D", pointsToRead, 1, 1);
    // Set the appropriate values
    for (int index = 0; index < pointsToRead; ++index) {
      localworkspace->getSpectrum(index)
          .setSpectrumNo(static_cast<int>(columnOne[index]));
      localworkspace->dataY(index)[0] = ydata[index];
      localworkspace->dataE(index)[0] = errdata[index];
    }

    if (hasXError) {
      for (int index = 0; index < pointsToRead; ++index) {
        localworkspace->dataDx(index)[0] = xError[index];
      }
    }
    return localworkspace;
  }
}
Beispiel #2
0
    /**
    * Reads the data from the file. It is assumed that the provided file stream has its position
    * set such that the first call to getline will be give the first line of data
    * @param file :: A reference to a file stream
    * @returns A pointer to a new workspace
    */
    API::Workspace_sptr LoadAscii::readData(std::ifstream & file) const
    {
      // Get the first line and find the number of spectra from the number of columns
      std::string line;
      getline(file,line);
      boost::trim(line);

      std::list<std::string> columns;
      const int numCols = splitIntoColumns(columns, line);
      if( numCols < 2 ) 
      {
        g_log.error() << "Invalid data format found in file \"" << getPropertyValue("Filename") << "\"\n";
        throw std::runtime_error("Invalid data format. Fewer than 2 columns found.");
      }
      size_t numSpectra(0);
      bool haveErrors(false);
      bool haveXErrors(false);
      // Assume single data set with no errors
      if( numCols == 2 )
      {
        numSpectra = numCols/2;
      }
      // Data with errors
      else if( (numCols-1) % 2 == 0 )
      {
        numSpectra = (numCols - 1)/2;
        haveErrors = true;
      }
      // Data with errors on both X and Y (4-column file)
      else if( numCols == 4 )
      {
        numSpectra = 1;
        haveErrors = true;
        haveXErrors = true;
      }
      else
      {
        g_log.error() << "Invalid data format found in file \"" << getPropertyValue("Filename") << "\"\n";
        g_log.error() << "LoadAscii requires the number of columns to be an even multiple of either 2 or 3.";
        throw std::runtime_error("Invalid data format.");
      }

      // A quick check at the number of lines won't be accurate enough as potentially there
      // could be blank lines and comment lines
      int numBins(0), lineNo(0);
      std::vector<DataObjects::Histogram1D> spectra(numSpectra);
      std::vector<double> values(numCols, 0.);
      do
      {
        ++lineNo;
        boost::trim(line);
        if( this->skipLine(line) ) continue;
        columns.clear();
        int lineCols = this->splitIntoColumns(columns, line); 
        if( lineCols != numCols )
        {
          std::ostringstream ostr;
          ostr << "Number of columns changed at line " << lineNo;
          throw std::runtime_error(ostr.str());
        }

        try
        {
          fillInputValues(values, columns); //ignores nans and replaces them with 0
        }
        catch(boost::bad_lexical_cast&)
        {
          g_log.error() << "Invalid value on line " << lineNo << " of \""
            << getPropertyValue("Filename") << "\"\n";
          throw std::runtime_error("Invalid value encountered.");
        }

        for (size_t i = 0; i < numSpectra; ++i)
        {
          spectra[i].dataX().push_back(values[0]);
          spectra[i].dataY().push_back(values[i*2+1]);
          if( haveErrors )
          {
            spectra[i].dataE().push_back(values[i*2+2]);
          }
          if( haveXErrors )
          {
            // Note: we only have X errors with 4-column files.
            // We are only here when i=0.
            spectra[i].dataDx().push_back(values[3]);
          }
        }
        ++numBins;
      }
      while(getline(file,line));

      MatrixWorkspace_sptr localWorkspace = boost::dynamic_pointer_cast<MatrixWorkspace>
        (WorkspaceFactory::Instance().create("Workspace2D",numSpectra,numBins,numBins));
      try 
      {
        localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create(getProperty("Unit"));
      } 
      catch (Exception::NotFoundError&) 
      {
        // Asked for dimensionless workspace (obviously not in unit factory)
      }

      for (size_t i = 0; i < numSpectra; ++i)
      {
        localWorkspace->dataX(i) = spectra[i].dataX();
        localWorkspace->dataY(i) = spectra[i].dataY();
        /* If Y or E errors are not there, DON'T copy across as the 'spectra' vectors
           have not been filled above. The workspace will by default have vectors of
           the right length filled with zeroes. */
        if ( haveErrors ) localWorkspace->dataE(i) = spectra[i].dataE();
        if ( haveXErrors ) localWorkspace->dataDx(i) = spectra[i].dataDx();
        // Just have spectrum number start at 1 and count up
        localWorkspace->getSpectrum(i)->setSpectrumNo(static_cast<specid_t>(i)+1);
      }
      return localWorkspace;
    }
/// Execute the algorithm in case of a histogrammed data.
void ExtractSpectra::execHistogram() {
  m_histogram = m_inputWorkspace->isHistogramData();
  // Check for common boundaries in input workspace
  m_commonBoundaries = WorkspaceHelpers::commonBoundaries(m_inputWorkspace);

  // Retrieve and validate the input properties
  this->checkProperties();

  // Create the output workspace
  MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
      m_inputWorkspace, m_workspaceIndexList.size(), m_maxX - m_minX,
      m_maxX - m_minX - m_histogram);

  // If this is a Workspace2D, get the spectra axes for copying in the spectraNo
  // later
  Axis *inAxis1(nullptr);
  TextAxis *outTxtAxis(nullptr);
  NumericAxis *outNumAxis(nullptr);
  if (m_inputWorkspace->axes() > 1) {
    inAxis1 = m_inputWorkspace->getAxis(1);
    auto outAxis1 = outputWorkspace->getAxis(1);
    outTxtAxis = dynamic_cast<TextAxis *>(outAxis1);
    if (!outTxtAxis)
      outNumAxis = dynamic_cast<NumericAxis *>(outAxis1);
  }

  cow_ptr<MantidVec> newX;
  if (m_commonBoundaries) {
    const MantidVec &oldX =
        m_inputWorkspace->readX(m_workspaceIndexList.front());
    newX.access().assign(oldX.begin() + m_minX, oldX.begin() + m_maxX);
  }

  Progress prog(this, 0.0, 1.0, (m_workspaceIndexList.size()));
  // Loop over the required workspace indices, copying in the desired bins
  for (int j = 0; j < static_cast<int>(m_workspaceIndexList.size()); ++j) {
    auto i = m_workspaceIndexList[j];

    bool hasDx = m_inputWorkspace->hasDx(i);

    // Preserve/restore sharing if X vectors are the same
    if (m_commonBoundaries) {
      outputWorkspace->setX(j, newX);
      if (hasDx) {
        const MantidVec &oldDx = m_inputWorkspace->readDx(i);
        outputWorkspace->dataDx(j)
            .assign(oldDx.begin() + m_minX, oldDx.begin() + m_maxX);
      }
    } else {
      // Safe to just copy whole vector 'cos can't be cropping in X if not
      // common
      outputWorkspace->setX(j, m_inputWorkspace->refX(i));
      if (hasDx) {
        outputWorkspace->setDx(j, m_inputWorkspace->refDx(i));
      }
    }

    const MantidVec &oldY = m_inputWorkspace->readY(i);
    outputWorkspace->dataY(j)
        .assign(oldY.begin() + m_minX, oldY.begin() + (m_maxX - m_histogram));
    const MantidVec &oldE = m_inputWorkspace->readE(i);
    outputWorkspace->dataE(j)
        .assign(oldE.begin() + m_minX, oldE.begin() + (m_maxX - m_histogram));

    // copy over the axis entry for each spectrum, regardless of the type of
    // axes present
    if (inAxis1) {
      if (outTxtAxis) {
        outTxtAxis->setLabel(j, inAxis1->label(i));
      } else if (outNumAxis) {
        outNumAxis->setValue(j, inAxis1->operator()(i));
      }
      // spectra axis is handled by copyInfoFrom line
    }
    // Copy spectrum number & detectors
    outputWorkspace->getSpectrum(j)
        ->copyInfoFrom(*m_inputWorkspace->getSpectrum(i));

    if (!m_commonBoundaries)
      this->cropRagged(outputWorkspace, static_cast<int>(i), j);

    // Propagate bin masking if there is any
    if (m_inputWorkspace->hasMaskedBins(i)) {
      const MatrixWorkspace::MaskList &inputMasks =
          m_inputWorkspace->maskedBins(i);
      MatrixWorkspace::MaskList::const_iterator it;
      for (it = inputMasks.begin(); it != inputMasks.end(); ++it) {
        const size_t maskIndex = (*it).first;
        if (maskIndex >= m_minX && maskIndex < m_maxX - m_histogram)
          outputWorkspace->flagMasked(j, maskIndex - m_minX, (*it).second);
      }
    }
    prog.report();
  }

  setProperty("OutputWorkspace", outputWorkspace);
}