Пример #1
0
void
MDHistoToWorkspace2D::checkW2D(Mantid::DataObjects::Workspace2D_sptr outWS) {
  size_t nSpectra = outWS->getNumberHistograms();
  size_t length = outWS->blocksize();
  MantidVec x, y, e;

  g_log.information() << "W2D has " << nSpectra << " histograms of length "
                      << length;
  for (size_t i = 0; i < nSpectra; i++) {
    ISpectrum *spec = outWS->getSpectrum(i);
    x = spec->dataX();
    y = spec->dataY();
    e = spec->dataE();
    if (x.size() != length) {
      g_log.information() << "Spectrum " << i << " x-size mismatch, is "
                          << x.size() << " should be " << length << "\n";
    }
    if (y.size() != length) {
      g_log.information() << "Spectrum " << i << " y-size mismatch, is "
                          << y.size() << " should be " << length << "\n";
    }
    if (e.size() != length) {
      g_log.information() << "Spectrum " << i << " e-size mismatch, is "
                          << e.size() << " should be " << length << "\n";
    }
  }
}
Пример #2
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;
}
/**
 * Apply the created mapping to the workspace
 */
void CreateSimulationWorkspace::applyDetectorMapping() {
  size_t wsIndex(0);
  for (auto iter = m_detGroups.begin(); iter != m_detGroups.end(); ++iter) {
    ISpectrum *spectrum = m_outputWS->getSpectrum(wsIndex);
    spectrum->setSpectrumNo(
        static_cast<specid_t>(wsIndex + 1)); // Ensure a contiguous mapping
    spectrum->clearDetectorIDs();
    spectrum->addDetectorIDs(iter->second);
    ++wsIndex;
  }
}
Пример #4
0
    /**
     * Execute the algorithm
     */
    void ExtractMasking::exec()
    {
      MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");

      const int nHist = static_cast<int>(inputWS->getNumberHistograms());
      const int xLength(1), yLength(1);
      // Create a new workspace for the results, copy from the input to ensure that we copy over the instrument and current masking
      MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(inputWS, nHist, xLength, yLength);

      Progress prog(this,0.0,1.0,nHist);
      MantidVecPtr xValues;
      xValues.access() = MantidVec(1, 0.0);

      PARALLEL_FOR2(inputWS, outputWS)
      for( int i = 0; i < nHist; ++i )
      {
        PARALLEL_START_INTERUPT_REGION
        // Spectrum in the output workspace
        ISpectrum * outSpec = outputWS->getSpectrum(i);
        // Spectrum in the input workspace
        const ISpectrum * inSpec = inputWS->getSpectrum(i);

        // Copy X, spectrum number and detector IDs
        outSpec->setX(xValues);
        outSpec->copyInfoFrom(*inSpec);

        IDetector_const_sptr inputDet;
        bool inputIsMasked(false);
        try
        {
          inputDet = inputWS->getDetector(i);
          if( inputDet->isMasked() )
          {
            inputIsMasked = true;
          }
        }
        catch(Kernel::Exception::NotFoundError &)
        {
          inputIsMasked = false;
        }

        if( inputIsMasked )
        {
          outSpec->dataY()[0] = 0.0;
          outSpec->dataE()[0] = 0.0;
        }
        else
        {
          outSpec->dataY()[0] = 1.0;
          outSpec->dataE()[0] = 1.0;
        }
        prog.report();

        PARALLEL_END_INTERUPT_REGION
      }
      PARALLEL_CHECK_INTERUPT_REGION

      setProperty("OutputWorkspace", outputWS);
    }
Пример #5
0
void ConvertToMatrixWorkspace::exec()
{
  MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
  // Let's see if we have to do anything first. Basically we want to avoid the data copy if we can
  DataObjects::EventWorkspace_const_sptr eventW = 
    boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>(inputWorkspace);
  MatrixWorkspace_sptr outputWorkspace;
  if( eventW )
  {
    g_log.information() << "Converting EventWorkspace to Workspace2D.\n";

    const size_t numHists = inputWorkspace->getNumberHistograms();
    Progress prog(this,0.0,1.0,numHists*2);

    // Sort the input workspace in-place by TOF. This can be faster if there are few event lists.
    eventW->sortAll(TOF_SORT, &prog);

    // Create the output workspace. This will copy many aspects fron the input one.
    outputWorkspace = WorkspaceFactory::Instance().create(inputWorkspace);

    // ...but not the data, so do that here.
    PARALLEL_FOR2(inputWorkspace,outputWorkspace)
    for (int64_t i = 0; i < (int64_t)numHists; ++i)
    {
      PARALLEL_START_INTERUPT_REGION
      const ISpectrum * inSpec = inputWorkspace->getSpectrum(i);
      ISpectrum * outSpec = outputWorkspace->getSpectrum(i);

      outSpec->copyInfoFrom(*inSpec);
      outSpec->setX(inSpec->ptrX());
      outSpec->dataY() = inSpec->dataY();
      outSpec->dataE() = inSpec->dataE();
      
      prog.report("Binning");

      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    outputWorkspace->generateSpectraMap();
  }
  else
  {
Пример #6
0
void GatherWorkspaces::execEvent() {

  // Every process in an MPI job must hit this next line or everything hangs!
  mpi::communicator included; // The communicator containing all processes
  // The root process needs to create a workspace of the appropriate size
  EventWorkspace_sptr outputWorkspace;
  if (included.rank() == 0) {
    g_log.debug() << "Total number of spectra is " << totalSpec << "\n";
    // Create the workspace for the output
    outputWorkspace = boost::dynamic_pointer_cast<EventWorkspace>(
        API::WorkspaceFactory::Instance().create("EventWorkspace", sumSpec,
                                                 numBins + hist, numBins));
    // Copy geometry over.
    API::WorkspaceFactory::Instance().initializeFromParent(
        eventW, outputWorkspace, true);
    setProperty("OutputWorkspace", outputWorkspace);
    ExperimentInfo_sptr inWS = inputWorkspace;
    outputWorkspace->copyExperimentInfoFrom(inWS.get());
  }

  for (size_t wi = 0; wi < totalSpec; wi++) {
    if (included.rank() == 0) {
      // How do we accumulate the data?
      std::string accum = this->getPropertyValue("AccumulationMethod");
      std::vector<Mantid::DataObjects::EventList> out_values;
      gather(included, eventW->getEventList(wi), out_values, 0);
      for (int i = 0; i < included.size(); i++) {
        size_t index = wi; // accum == "Add"
        if (accum == "Append")
          index = wi + i * totalSpec;
        outputWorkspace->dataX(index) = eventW->readX(wi);
        outputWorkspace->getOrAddEventList(index) += out_values[i];
        const ISpectrum *inSpec = eventW->getSpectrum(wi);
        ISpectrum *outSpec = outputWorkspace->getSpectrum(index);
        outSpec->clearDetectorIDs();
        outSpec->addDetectorIDs(inSpec->getDetectorIDs());
      }
    } else {
      gather(included, eventW->getEventList(wi), 0);
    }
  }
}
Пример #7
0
/**
*  Only to be used if the KeepUnGrouped property is true, moves the spectra that were not selected
*  to be in a group to the end of the output spectrum
*  @param unGroupedSet :: list of WORKSPACE indexes that were included in a group
*  @param inputWS :: user selected input workspace for the algorithm
*  @param outputWS :: user selected output workspace for the algorithm
*  @param outIndex :: the next spectra index available after the grouped spectra
*/
void GroupDetectors2::moveOthers(const std::set<int64_t> &unGroupedSet, API::MatrixWorkspace_const_sptr inputWS, API::MatrixWorkspace_sptr outputWS,
         size_t outIndex)
{
  g_log.debug() << "Starting to copy the ungrouped spectra" << std::endl;
  double prog4Copy = (1. - 1.*static_cast<double>(m_FracCompl))/static_cast<double>(unGroupedSet.size());

  std::set<int64_t>::const_iterator copyFrIt = unGroupedSet.begin();
  // go thorugh all the spectra in the input workspace
  for ( ; copyFrIt != unGroupedSet.end(); ++copyFrIt )
  {
    if( *copyFrIt == USED ) continue; //Marked as not to be used
    size_t sourceIndex = static_cast<size_t>(*copyFrIt);

    // The input spectrum we'll copy
    const ISpectrum * inputSpec = inputWS->getSpectrum(sourceIndex);

    // Destination of the copying
    ISpectrum * outputSpec = outputWS->getSpectrum(outIndex);

    // Copy the data
    outputSpec->dataX() = inputSpec->dataX();
    outputSpec->dataY() = inputSpec->dataY();
    outputSpec->dataE() = inputSpec->dataE();

    // Spectrum numbers etc.
    outputSpec->setSpectrumNo(inputSpec->getSpectrumNo());
    outputSpec->clearDetectorIDs();
    outputSpec->addDetectorIDs( inputSpec->getDetectorIDs() );

    // go to the next free index in the output workspace
    outIndex ++;
    // make regular progress reports and check for cancelling the algorithm
    if ( outIndex % INTERVAL == 0 )
    {
      m_FracCompl += INTERVAL*prog4Copy;
      if ( m_FracCompl > 1.0 )
      {
        m_FracCompl = 1.0;
      }
      progress(m_FracCompl);
      interruption_point();
    }
  }
  // Refresh the spectraDetectorMap
  outputWS->generateSpectraMap();

  g_log.debug() << name() << " copied " << unGroupedSet.size()-1 << " ungrouped spectra\n";
}
Пример #8
0
  /** Executes the algorithm
   *
   *  @throw Exception::FileError If the grouping file cannot be opened or read successfully
   *  @throw runtime_error If unable to run one of the Child Algorithms successfully
   */
  void ReadGroupsFromFile::exec()
  {
    MatrixWorkspace_const_sptr ws = getProperty("InstrumentWorkspace");

    // Get the instrument.
    Instrument_const_sptr inst = ws->getInstrument();

    // Create a copy (without the data) of the workspace - it will contain the
    Workspace2D_sptr localWorkspace =
        boost::dynamic_pointer_cast<Workspace2D>(WorkspaceFactory::Instance().create(ws, ws->getNumberHistograms(), 2, 1));
    if (!localWorkspace)
      throw std::runtime_error("Failed when creating a Workspace2D from the input!");

    const std::string groupfile=getProperty("GroupingFilename");

    if ( ! groupfile.empty() )
    {
      std::string filename(groupfile);
      std::transform(filename.begin(), filename.end(), filename.begin(), tolower);
      if ( filename.find(".xml") != std::string::npos )
      {
        readXMLGroupingFile(groupfile);
      }
      else
      {
        readGroupingFile(groupfile);
      }
    }

    // Get the instrument.
    const int64_t nHist=localWorkspace->getNumberHistograms();

    // Determine whether the user wants to see unselected detectors or not
    const std::string su=getProperty("ShowUnselected");
    bool showunselected=(!su.compare("True"));
    bool success=false;

    for (int64_t i=0;i<nHist;i++)
    {
      ISpectrum * spec = localWorkspace->getSpectrum(i);
      const std::set<detid_t> & dets = spec->getDetectorIDs();
      if (dets.empty()) // Nothing
      {
        spec->dataY()[0]=0.0;
        continue;
      }
      // Find the first detector ID in the list
      calmap::const_iterator it=calibration.find(*dets.begin());
      if (it==calibration.end()) //Could not find the detector
      {
        spec->dataY()[0]=0.0;
        continue;
      }
      if (showunselected)
      {
        if (((*it).second).second==0)
          spec->dataY()[0]=0.0;
        else
          spec->dataY()[0]=static_cast<double>(((*it).second).first);
      }
      else
        spec->dataY()[0]=static_cast<double>(((*it).second).first);
      if (!success) success=true; //At least one detector is found in the cal file

    }
    progress(1);

    calibration.clear();
    if (!success) //Do some cleanup
    {
      localWorkspace.reset();
      throw std::runtime_error("Fail to found a detector in "+groupfile+" existing in instrument "+inst->getName());
    }
    setProperty("OutputWorkspace",localWorkspace);
    return;
  }
Пример #9
0
/**
  @ throw invalid_argument if the workspaces are not mututially compatible
*/
void Q1D2::exec()
{
  m_dataWS = getProperty("DetBankWorkspace");
  MatrixWorkspace_const_sptr waveAdj = getProperty("WavelengthAdj");
  MatrixWorkspace_const_sptr pixelAdj = getProperty("PixelAdj");
  MatrixWorkspace_const_sptr wavePixelAdj = getProperty("WavePixelAdj");
  const bool doGravity = getProperty("AccountForGravity");
  m_doSolidAngle = getProperty("SolidAngleWeighting");

  //throws if we don't have common binning or another incompatibility
  Qhelper helper;
  helper.examineInput(m_dataWS, waveAdj, pixelAdj);
  // FIXME: how to examine the wavePixelAdj? 
  g_log.debug() << "All input workspaces were found to be valid\n";
  // normalization as a function of wavelength (i.e. centers of x-value bins)
  double const * const binNorms = waveAdj ? &(waveAdj->readY(0)[0]) : NULL;
  // error on the wavelength normalization
  double const * const binNormEs = waveAdj ? &(waveAdj->readE(0)[0]) : NULL;

  //define the (large number of) data objects that are going to be used in all iterations of the loop below

  // this will become the output workspace from this algorithm
  MatrixWorkspace_sptr outputWS = setUpOutputWorkspace(getProperty("OutputBinning"));

  const MantidVec & QOut = outputWS->readX(0);
  MantidVec & YOut = outputWS->dataY(0);
  MantidVec & EOutTo2 = outputWS->dataE(0);
  // normalisation that is applied to counts in each Q bin
  MantidVec normSum(YOut.size(), 0.0);
  // the error on the normalisation
  MantidVec normError2(YOut.size(), 0.0);

  const int numSpec = static_cast<int>(m_dataWS->getNumberHistograms());
  Progress progress(this, 0.05, 1.0, numSpec+1);

  PARALLEL_FOR3(m_dataWS, outputWS, pixelAdj)
  for (int i = 0; i < numSpec; ++i)
  {
    PARALLEL_START_INTERUPT_REGION
    // Get the pixel relating to this spectrum
    IDetector_const_sptr det;
    try {
      det = m_dataWS->getDetector(i);
    } catch (Exception::NotFoundError&) {
      g_log.warning() << "Workspace index " << i << " (SpectrumIndex = " << m_dataWS->getSpectrum(i)->getSpectrumNo() << ") has no detector assigned to it - discarding" << std::endl;
      // Catch if no detector. Next line tests whether this happened - test placed
      // outside here because Mac Intel compiler doesn't like 'continue' in a catch
      // in an openmp block.
    }
    // If no detector found or if detector is masked shouldn't be included skip onto the next spectrum
    if ( !det || det->isMonitor() || det->isMasked() )
    {
      continue;
    }

    //get the bins that are included inside the RadiusCut/WaveCutcut off, those to calculate for
    //const size_t wavStart = waveLengthCutOff(i);
    const size_t wavStart = helper.waveLengthCutOff(m_dataWS, getProperty("RadiusCut"), getProperty("WaveCut"), i);
    if (wavStart >=  m_dataWS->readY(i).size())
    {
      // all the spectra in this detector are out of range
      continue;
    }
    
    const size_t numWavbins = m_dataWS->readY(i).size()-wavStart;
    // make just one call to new to reduce CPU overhead on each thread, access to these 
    // three "arrays" is via iterators
    MantidVec _noDirectUseStorage_(3*numWavbins);
    //normalization term
    MantidVec::iterator norms = _noDirectUseStorage_.begin();
    // the error on these weights, it contributes to the error calculation on the output workspace
    MantidVec::iterator normETo2s = norms + numWavbins;
    // the Q values calculated from input wavelength workspace
    MantidVec::iterator QIn = normETo2s + numWavbins;

    // the weighting for this input spectrum that is added to the normalization
    calculateNormalization(wavStart, i, pixelAdj, wavePixelAdj, binNorms, binNormEs, norms, normETo2s);

    // now read the data from the input workspace, calculate Q for each bin
    convertWavetoQ(i, doGravity, wavStart, QIn);

    // Pointers to the counts data and it's error
    MantidVec::const_iterator YIn = m_dataWS->readY(i).begin()+wavStart;
    MantidVec::const_iterator EIn = m_dataWS->readE(i).begin()+wavStart;

    //when finding the output Q bin remember that the input Q bins (from the convert to wavelength) start high and reduce
    MantidVec::const_iterator loc = QOut.end();
    // sum the Q contributions from each individual spectrum into the output array
    const MantidVec::const_iterator end = m_dataWS->readY(i).end();
    for( ; YIn != end; ++YIn, ++EIn, ++QIn, ++norms, ++normETo2s)
    {
      //find the output bin that each input y-value will fall into, remembering there is one more bin boundary than bins
      getQBinPlus1(QOut, *QIn, loc);
      // ignore counts that are out of the output range
      if ( (loc != QOut.begin()) && (loc != QOut.end()) )
      {
        // the actual Q-bin to add something to
        const size_t bin = loc - QOut.begin() - 1;
        PARALLEL_CRITICAL(q1d_counts_sum)
        {
          YOut[bin] += *YIn;
          normSum[bin] += *norms;
          //these are the errors squared which will be summed and square rooted at the end
          EOutTo2[bin] += (*EIn)*(*EIn);
          normError2[bin] += *normETo2s;
        }
      }
    }
    
    PARALLEL_CRITICAL(q1d_spectra_map)
    {
      progress.report("Computing I(Q)");

      // Add up the detector IDs in the output spectrum at workspace index 0
      const ISpectrum * inSpec = m_dataWS->getSpectrum(i);
      ISpectrum * outSpec = outputWS->getSpectrum(0);
      outSpec->addDetectorIDs( inSpec->getDetectorIDs() );
    }

    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  bool doOutputParts = getProperty("OutputParts");
  if (doOutputParts)
  {
      MatrixWorkspace_sptr ws_sumOfCounts = WorkspaceFactory::Instance().create(outputWS);
      ws_sumOfCounts->dataX(0) = outputWS->dataX(0);
      ws_sumOfCounts->dataY(0) = outputWS->dataY(0);
      for (size_t i = 0; i < outputWS->dataE(0).size(); i++)
      {
        ws_sumOfCounts->dataE(0)[i] = sqrt(outputWS->dataE(0)[i]);
      }      

      MatrixWorkspace_sptr ws_sumOfNormFactors = WorkspaceFactory::Instance().create(outputWS);
      ws_sumOfNormFactors->dataX(0) = outputWS->dataX(0);
      for (size_t i = 0; i < ws_sumOfNormFactors->dataY(0).size(); i++)
      {
        ws_sumOfNormFactors->dataY(0)[i] = normSum[i];
        ws_sumOfNormFactors->dataE(0)[i] = sqrt(normError2[i]);
      }

      helper.outputParts(this, ws_sumOfCounts, ws_sumOfNormFactors);
  }


  progress.report("Normalizing I(Q)");
  //finally divide the number of counts in each output Q bin by its weighting
  normalize(normSum, normError2, YOut, EOutTo2);

  outputWS->updateSpectraUsingMap();

  setProperty("OutputWorkspace",outputWS);
}
Пример #10
0
/**
*  Move the user selected spectra in the input workspace into groups in the output workspace
*  @param inputWS :: user selected input workspace for the algorithm
*  @param outputWS :: user selected output workspace for the algorithm
*  @param prog4Copy :: the amount of algorithm progress to attribute to moving a single spectra
*  @return number of new grouped spectra
*/
size_t GroupDetectors2::formGroups( API::MatrixWorkspace_const_sptr inputWS, API::MatrixWorkspace_sptr outputWS, 
            const double prog4Copy)
{
  // get "Behaviour" string
  const std::string behaviour = getProperty("Behaviour");
  int bhv = 0;
  if ( behaviour == "Average" ) bhv = 1;

  API::MatrixWorkspace_sptr beh = API::WorkspaceFactory::Instance().create(
    "Workspace2D", static_cast<int>(m_GroupSpecInds.size()), 1, 1);

  g_log.debug() << name() << ": Preparing to group spectra into " << m_GroupSpecInds.size() << " groups\n";

  // where we are copying spectra to, we start copying to the start of the output workspace
  size_t outIndex = 0;
  // Only used for averaging behaviour. We may have a 1:1 map where a Divide would be waste as it would be just dividing by 1
  bool requireDivide(false);
  for ( storage_map::const_iterator it = m_GroupSpecInds.begin(); it != m_GroupSpecInds.end() ; ++it )
  {
    // This is the grouped spectrum
    ISpectrum * outSpec = outputWS->getSpectrum(outIndex);

    // The spectrum number of the group is the key
    outSpec->setSpectrumNo(it->first);
    // Start fresh with no detector IDs
    outSpec->clearDetectorIDs();

    // Copy over X data from first spectrum, the bin boundaries for all spectra are assumed to be the same here
    outSpec->dataX() = inputWS->readX(0);

    // the Y values and errors from spectra being grouped are combined in the output spectrum
    // Keep track of number of detectors required for masking
    size_t nonMaskedSpectra(0);
    beh->dataX(outIndex)[0] = 0.0;
    beh->dataE(outIndex)[0] = 0.0;
    for( std::vector<size_t>::const_iterator wsIter = it->second.begin(); wsIter != it->second.end(); ++wsIter)
    {
      const size_t originalWI = *wsIter;

      // detectors to add to firstSpecNum
      const ISpectrum * fromSpectrum = inputWS->getSpectrum(originalWI);

      // Add up all the Y spectra and store the result in the first one
      // Need to keep the next 3 lines inside loop for now until ManagedWorkspace mru-list works properly
      MantidVec &firstY = outSpec->dataY();
      MantidVec::iterator fYit;
      MantidVec::iterator fEit = outSpec->dataE().begin();
      MantidVec::const_iterator Yit = fromSpectrum->dataY().begin();
      MantidVec::const_iterator Eit = fromSpectrum->dataE().begin();
      for (fYit = firstY.begin(); fYit != firstY.end(); ++fYit, ++fEit, ++Yit, ++Eit)
      {
        *fYit += *Yit;
        // Assume 'normal' (i.e. Gaussian) combination of errors
        *fEit = std::sqrt( (*fEit)*(*fEit) + (*Eit)*(*Eit) );
      }

      // detectors to add to the output spectrum
      outSpec->addDetectorIDs(fromSpectrum->getDetectorIDs() );
      try
      {
        Geometry::IDetector_const_sptr det = inputWS->getDetector(originalWI);
        if( !det->isMasked() ) ++nonMaskedSpectra;
      }
      catch(Exception::NotFoundError&)
      {
        // If a detector cannot be found, it cannot be masked
        ++nonMaskedSpectra;
      }
    }
    if( nonMaskedSpectra == 0 ) ++nonMaskedSpectra; // Avoid possible divide by zero
    if(!requireDivide) requireDivide = (nonMaskedSpectra > 1);
    beh->dataY(outIndex)[0] = static_cast<double>(nonMaskedSpectra);

    // make regular progress reports and check for cancelling the algorithm
    if ( outIndex % INTERVAL == 0 )
    {
      m_FracCompl += INTERVAL*prog4Copy;
      if ( m_FracCompl > 1.0 )
        m_FracCompl = 1.0;
      progress(m_FracCompl);
      interruption_point();
    }
    outIndex ++;
  }
  
  // Refresh the spectraDetectorMap
  outputWS->generateSpectraMap();

  if ( bhv == 1 && requireDivide )
  {
    g_log.debug() << "Running Divide algorithm to perform averaging.\n";
    Mantid::API::IAlgorithm_sptr divide = createChildAlgorithm("Divide");
    divide->initialize();
    divide->setProperty<API::MatrixWorkspace_sptr>("LHSWorkspace", outputWS);
    divide->setProperty<API::MatrixWorkspace_sptr>("RHSWorkspace", beh);
    divide->setProperty<API::MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
    divide->execute();
  }

  g_log.debug() << name() << " created " << outIndex << " new grouped spectra\n";
  return outIndex;
}
Пример #11
0
/** Load a single bank into the workspace
 *
 * @param nexusfilename :: file to open
 * @param entry_name :: NXentry name
 * @param bankName :: NXdata bank name
 * @param WS :: workspace to modify
 * @param id_to_wi :: det ID to workspace index mapping
 */
void LoadTOFRawNexus::loadBank(const std::string &nexusfilename,
                               const std::string &entry_name,
                               const std::string &bankName,
                               API::MatrixWorkspace_sptr WS,
                               const detid2index_map &id_to_wi) {
  g_log.debug() << "Loading bank " << bankName << std::endl;
  // To avoid segfaults on RHEL5/6 and Fedora
  m_fileMutex.lock();

  // Navigate to the point in the file
  auto file = new ::NeXus::File(nexusfilename);
  file->openGroup(entry_name, "NXentry");
  file->openGroup("instrument", "NXinstrument");
  file->openGroup(bankName, "NXdetector");

  size_t m_numPixels = 0;
  std::vector<uint32_t> pixel_id;

  if (!m_assumeOldFile) {
    // Load the pixel IDs
    file->readData("pixel_id", pixel_id);
    m_numPixels = pixel_id.size();
    if (m_numPixels == 0) {
      file->close();
      m_fileMutex.unlock();
      g_log.warning() << "Invalid pixel_id data in " << bankName << std::endl;
      return;
    }
  } else {
    // Load the x and y pixel offsets
    std::vector<float> xoffsets;
    std::vector<float> yoffsets;
    file->readData("x_pixel_offset", xoffsets);
    file->readData("y_pixel_offset", yoffsets);

    m_numPixels = xoffsets.size() * yoffsets.size();
    if (0 == m_numPixels) {
      file->close();
      m_fileMutex.unlock();
      g_log.warning() << "Invalid (x,y) offsets in " << bankName << std::endl;
      return;
    }

    size_t bankNum = 0;
    if (bankName.size() > 4) {
      if (bankName.substr(0, 4) == "bank") {
        bankNum = boost::lexical_cast<size_t>(bankName.substr(4));
        bankNum--;
      } else {
        file->close();
        m_fileMutex.unlock();
        g_log.warning() << "Invalid bank number for " << bankName << std::endl;
        return;
      }
    }

    // All good, so construct the pixel ID listing
    size_t numX = xoffsets.size();
    size_t numY = yoffsets.size();

    for (size_t i = 0; i < numX; i++) {
      for (size_t j = 0; j < numY; j++) {
        pixel_id.push_back(
            static_cast<uint32_t>(j + numY * (i + numX * bankNum)));
      }
    }
  }

  size_t iPart = 0;
  if (m_spec_max != Mantid::EMPTY_INT()) {
    uint32_t ifirst = pixel_id[0];
    range_check out_range(m_spec_min, m_spec_max, id_to_wi);
    auto newEnd = std::remove_if(pixel_id.begin(), pixel_id.end(), out_range);
    pixel_id.erase(newEnd, pixel_id.end());
    // check if beginning or end of array was erased
    if (ifirst != pixel_id[0])
      iPart = m_numPixels - pixel_id.size();
    m_numPixels = pixel_id.size();
    if (m_numPixels == 0) {
      file->close();
      m_fileMutex.unlock();
      g_log.warning() << "No pixels from " << bankName << std::endl;
      return;
    };
  }
  // Load the TOF vector
  std::vector<float> tof;
  file->readData(m_axisField, tof);
  size_t m_numBins = tof.size() - 1;
  if (tof.size() <= 1) {
    file->close();
    m_fileMutex.unlock();
    g_log.warning() << "Invalid " << m_axisField << " data in " << bankName
                    << std::endl;
    return;
  }

  // Make a shared pointer
  MantidVecPtr Xptr;
  MantidVec &X = Xptr.access();
  X.resize(tof.size(), 0);
  X.assign(tof.begin(), tof.end());

  // Load the data. Coerce ints into double.
  std::string errorsField = "";
  std::vector<double> data;
  file->openData(m_dataField);
  file->getDataCoerce(data);
  if (file->hasAttr("errors"))
    file->getAttr("errors", errorsField);
  file->closeData();

  // Load the errors
  bool hasErrors = !errorsField.empty();
  std::vector<double> errors;
  if (hasErrors) {
    try {
      file->openData(errorsField);
      file->getDataCoerce(errors);
      file->closeData();
    } catch (...) {
      g_log.information() << "Error loading the errors field, '" << errorsField
                          << "' for bank " << bankName
                          << ". Will use sqrt(counts). " << std::endl;
      hasErrors = false;
    }
  }

  /*if (data.size() != m_numBins * m_numPixels)
  { file->close(); m_fileMutex.unlock(); g_log.warning() << "Invalid size of '"
  << m_dataField << "' data in " << bankName << std::endl; return; }
  if (hasErrors && (errors.size() != m_numBins * m_numPixels))
  { file->close(); m_fileMutex.unlock(); g_log.warning() << "Invalid size of '"
  << errorsField << "' errors in " << bankName << std::endl; return; }
*/
  // Have all the data I need
  m_fileMutex.unlock();
  file->close();

  for (size_t i = iPart; i < iPart + m_numPixels; i++) {
    // Find the workspace index for this detector
    detid_t pixelID = pixel_id[i - iPart];
    size_t wi = id_to_wi.find(pixelID)->second;

    // Set the basic info of that spectrum
    ISpectrum *spec = WS->getSpectrum(wi);
    spec->setSpectrumNo(specid_t(wi + 1));
    spec->setDetectorID(pixel_id[i - iPart]);
    // Set the shared X pointer
    spec->setX(X);

    // Extract the Y
    MantidVec &Y = spec->dataY();
    Y.assign(data.begin() + i * m_numBins, data.begin() + (i + 1) * m_numBins);

    MantidVec &E = spec->dataE();

    if (hasErrors) {
      // Copy the errors from the loaded document
      E.assign(errors.begin() + i * m_numBins,
               errors.begin() + (i + 1) * m_numBins);
    } else {
      // Now take the sqrt(Y) to give E
      E = Y;
      std::transform(E.begin(), E.end(), E.begin(), (double (*)(double))sqrt);
    }
  }

  // Done!
}
Пример #12
0
/**
 * This function deals with the logic necessary for summing a Workspace2D.
 * @param outSpec The spectrum for the summed output.
 * @param progress The progress indicator.
 * @param numSpectra The number of spectra contributed to the sum.
 * @param numMasked The spectra dropped from the summations because they are
 * masked.
 * @param numZeros The number of zero bins in histogram workspace or empty
 * spectra for event workspace.
 */
void SumSpectra::doWorkspace2D(ISpectrum &outSpec, Progress &progress,
                               size_t &numSpectra, size_t &numMasked,
                               size_t &numZeros) {
  // Get references to the output workspaces's data vectors
  auto &OutputYSum = outSpec.mutableY();
  auto &OutputYError = outSpec.mutableE();

  std::vector<double> Weight;
  std::vector<size_t> nZeros;
  if (m_calculateWeightedSum) {
    Weight.assign(OutputYSum.size(), 0);
    nZeros.assign(OutputYSum.size(), 0);
  }
  numSpectra = 0;
  numMasked = 0;
  numZeros = 0;

  MatrixWorkspace_sptr in_ws = getProperty("InputWorkspace");
  // Clean workspace of any NANs or Inf values
  auto localworkspace = replaceSpecialValues(in_ws);
  const auto &spectrumInfo = localworkspace->spectrumInfo();
  // Loop over spectra
  for (const auto wsIndex : this->m_indices) {
    // Don't go outside the range.
    if ((wsIndex >= this->m_numberOfSpectra) || (wsIndex < 0)) {
      g_log.error() << "Invalid index " << wsIndex
                    << " was specified. Sum was aborted.\n";
      break;
    }

    if (spectrumInfo.hasDetectors(wsIndex)) {
      // Skip monitors, if the property is set to do so
      if (!m_keepMonitors && spectrumInfo.isMonitor(wsIndex))
        continue;
      // Skip masked detectors
      if (spectrumInfo.isMasked(wsIndex)) {
        numMasked++;
        continue;
      }
    }
    numSpectra++;

    const auto &YValues = localworkspace->y(wsIndex);
    const auto &YErrors = localworkspace->e(wsIndex);

    // Retrieve the spectrum into a vector

    for (int i = 0; i < m_yLength; ++i) {
      if (m_calculateWeightedSum) {
        if (std::isnormal(YErrors[i])) {
          const double errsq = YErrors[i] * YErrors[i];
          OutputYError[i] += errsq;
          Weight[i] += 1. / errsq;
          OutputYSum[i] += YValues[i] / errsq;
        } else {
          nZeros[i]++;
        }

      } else {
        OutputYSum[i] += YValues[i];
        OutputYError[i] += YErrors[i] * YErrors[i];
      }
    }

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

    progress.report();
  }

  if (m_calculateWeightedSum) {
    numZeros = 0;
    for (size_t i = 0; i < Weight.size(); i++) {
      if (numSpectra > nZeros[i])
        OutputYSum[i] *= double(numSpectra - nZeros[i]) / Weight[i];
      if (nZeros[i] != 0)
        numZeros += nZeros[i];
    }
  }
}
Пример #13
0
void GroupDetectors::exec()
{
  // Get the input workspace
  const MatrixWorkspace_sptr WS = getProperty("Workspace");

  std::vector<size_t> indexList = getProperty("WorkspaceIndexList");
  std::vector<specid_t> spectraList = getProperty("SpectraList");
  const std::vector<detid_t> detectorList = getProperty("DetectorList");

  // Could create a Validator to replace the below
  if ( indexList.empty() && spectraList.empty() && detectorList.empty() )
  {
    g_log.information(name() +
      ": WorkspaceIndexList, SpectraList, and DetectorList properties are all empty, no grouping done");
    return;
  }

  // Bin boundaries need to be the same, so check if they actually are
  if (!API::WorkspaceHelpers::commonBoundaries(WS))
  {
    g_log.error("Can only group if the histograms have common bin boundaries");
    throw std::runtime_error("Can only group if the histograms have common bin boundaries");
  }

  // If the spectraList property has been set, need to loop over the workspace looking for the
  // appropriate spectra number and adding the indices they are linked to the list to be processed
  if ( ! spectraList.empty() )
  {
    WS->getIndicesFromSpectra(spectraList,indexList);
  }// End dealing with spectraList
  else if ( ! detectorList.empty() )
  {
    // Dealing with DetectorList
    //convert from detectors to workspace indices
    WS->getIndicesFromDetectorIDs(detectorList, indexList);
  }

  if ( indexList.empty() )
  {
      g_log.warning("Nothing to group");
      return;
  }

  const size_t vectorSize = WS->blocksize();

  const specid_t firstIndex = static_cast<specid_t>(indexList[0]);
  ISpectrum * firstSpectrum = WS->getSpectrum(firstIndex);

  setProperty("ResultIndex",firstIndex);

  // loop over the spectra to group
  Progress progress(this, 0.0, 1.0, static_cast<int>(indexList.size()-1));
  for (size_t i = 0; i < indexList.size()-1; ++i)
  {
    // The current spectrum
    const size_t currentIndex = indexList[i+1];
    ISpectrum * spec = WS->getSpectrum(currentIndex);

    // Add the current detector to belong to the first spectrum
    firstSpectrum->addDetectorIDs(spec->getDetectorIDs());

    // Add up all the Y spectra and store the result in the first one
    // Need to keep the next 3 lines inside loop for now until ManagedWorkspace mru-list works properly
    MantidVec &firstY = WS->dataY(firstIndex);
    MantidVec::iterator fYit;
    MantidVec::iterator fEit = firstSpectrum->dataE().begin();
    MantidVec::iterator Yit = spec->dataY().begin();
    MantidVec::iterator Eit = spec->dataE().begin();
    for (fYit = firstY.begin(); fYit != firstY.end(); ++fYit, ++fEit, ++Yit, ++Eit)
    {
      *fYit += *Yit;
      // Assume 'normal' (i.e. Gaussian) combination of errors
      *fEit = sqrt( (*fEit)*(*fEit) + (*Eit)*(*Eit) );
    }

    // Now zero the now redundant spectrum and set its spectraNo to indicate this (using -1)
    // N.B. Deleting spectra would cause issues for ManagedWorkspace2D, hence the the approach taken here
    spec->dataY().assign(vectorSize,0.0);
    spec->dataE().assign(vectorSize,0.0);
    spec->setSpectrumNo(-1);
    spec->clearDetectorIDs();
    progress.report();
  }

}
Пример #14
0
/**
 * This function handles the logic for summing RebinnedOutput workspaces.
 * @param outputWorkspace the workspace to hold the summed input
 * @param progress the progress indicator
 * @param numSpectra
 * @param numMasked
 * @param numZeros
 */
void SumSpectra::doRebinnedOutput(MatrixWorkspace_sptr outputWorkspace,
                                  Progress &progress, size_t &numSpectra,
                                  size_t &numMasked, size_t &numZeros) {
  // Get a copy of the input workspace
  MatrixWorkspace_sptr temp = getProperty("InputWorkspace");

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

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

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

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

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

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

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

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

    progress.report();
  }

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

  // Create the correct representation
  outWS->finalize();
}
Пример #15
0
void GatherWorkspaces::exec() {
  // Every process in an MPI job must hit this next line or everything hangs!
  mpi::communicator world; // The communicator containing all processes

  inputWorkspace = getProperty("InputWorkspace");

  // Create a new communicator that includes only those processes that have an
  // input workspace
  const int haveWorkspace(inputWorkspace ? 1 : 0);
  included = world.split(haveWorkspace);

  // If the present process doesn't have an input workspace then its work is
  // done
  if (!haveWorkspace) {
    g_log.information("No input workspace on this process, so nothing to do.");
    return;
  }

  // Get the number of bins in each workspace and check they're all the same
  numBins = inputWorkspace->blocksize();
  std::vector<std::size_t> all_numBins;
  all_gather(included, numBins, all_numBins);
  if (std::count(all_numBins.begin(), all_numBins.end(), numBins) !=
      (int)all_numBins.size()) {
    // All the processes will error out if all the workspaces don't have the
    // same number of bins
    throw Exception::MisMatch<std::size_t>(
        numBins, 0, "All input workspaces must have the same number of bins");
  }
  // Also check that all workspaces are either histogram or not
  // N.B. boost mpi doesn't seem to like me using booleans in the all_gather
  hist = inputWorkspace->isHistogramData();
  std::vector<int> all_hist;
  all_gather(included, hist, all_hist);
  if (std::count(all_hist.begin(), all_hist.end(), hist) !=
      (int)all_hist.size()) {
    // All the processes will error out if we don't have either all histogram or
    // all point-data workspaces
    throw Exception::MisMatch<int>(
        hist, 0,
        "The input workspaces must be all histogram or all point data");
  }

  // How do we accumulate the data?
  std::string accum = this->getPropertyValue("AccumulationMethod");
  // Get the total number of spectra in the combined inputs
  totalSpec = inputWorkspace->getNumberHistograms();
  sumSpec = totalSpec;
  if (accum == "Append") {
    reduce(included, totalSpec, sumSpec, std::plus<std::size_t>(), 0);
  } else if (accum == "Add") {
    // barrier only helps when memory is too low for communication
    // included.barrier();
  }

  eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWorkspace);
  if (eventW != NULL) {
    if (getProperty("PreserveEvents")) {
      // Input workspace is an event workspace. Use the other exec method
      this->execEvent();
      return;
    }
  }

  // The root process needs to create a workspace of the appropriate size
  MatrixWorkspace_sptr outputWorkspace;
  if (included.rank() == 0) {
    g_log.debug() << "Total number of spectra is " << sumSpec << "\n";
    // Create the workspace for the output
    outputWorkspace = WorkspaceFactory::Instance().create(
        inputWorkspace, sumSpec, numBins + hist, numBins);
    setProperty("OutputWorkspace", outputWorkspace);
    ExperimentInfo_sptr inWS = inputWorkspace;
    outputWorkspace->copyExperimentInfoFrom(inWS.get());
  }

  for (size_t wi = 0; wi < totalSpec; wi++) {
    if (included.rank() == 0) {
      const ISpectrum *inSpec = inputWorkspace->getSpectrum(wi);
      if (accum == "Add") {
        outputWorkspace->dataX(wi) = inputWorkspace->readX(wi);
        reduce(included, inputWorkspace->readY(wi), outputWorkspace->dataY(wi),
               vplus(), 0);
        reduce(included, inputWorkspace->readE(wi), outputWorkspace->dataE(wi),
               eplus(), 0);
      } else if (accum == "Append") {
        // Copy over data from own input workspace
        outputWorkspace->dataX(wi) = inputWorkspace->readX(wi);
        outputWorkspace->dataY(wi) = inputWorkspace->readY(wi);
        outputWorkspace->dataE(wi) = inputWorkspace->readE(wi);

        const int numReqs(3 * (included.size() - 1));
        mpi::request reqs[numReqs];
        int j(0);

        // Receive data from all the other processes
        // This works because the process ranks are ordered the same in
        // 'included' as
        // they are in 'world', but in general this is not guaranteed. TODO:
        // robustify
        for (int i = 1; i < included.size(); ++i) {
          size_t index = wi + i * totalSpec;
          reqs[j++] = included.irecv(i, 0, outputWorkspace->dataX(index));
          reqs[j++] = included.irecv(i, 1, outputWorkspace->dataY(index));
          reqs[j++] = included.irecv(i, 2, outputWorkspace->dataE(index));
          ISpectrum *outSpec = outputWorkspace->getSpectrum(index);
          outSpec->clearDetectorIDs();
          outSpec->addDetectorIDs(inSpec->getDetectorIDs());
        }

        // Make sure everything's been received before exiting the algorithm
        mpi::wait_all(reqs, reqs + numReqs);
      }
      ISpectrum *outSpec = outputWorkspace->getSpectrum(wi);
      outSpec->clearDetectorIDs();
      outSpec->addDetectorIDs(inSpec->getDetectorIDs());
    } else {
      if (accum == "Add") {
        reduce(included, inputWorkspace->readY(wi), vplus(), 0);
        reduce(included, inputWorkspace->readE(wi), eplus(), 0);
      } else if (accum == "Append") {
        mpi::request reqs[3];

        // Send the spectrum to the root process
        reqs[0] = included.isend(0, 0, inputWorkspace->readX(0));
        reqs[1] = included.isend(0, 1, inputWorkspace->readY(0));
        reqs[2] = included.isend(0, 2, inputWorkspace->readE(0));

        // Make sure the sends have completed before exiting the algorithm
        mpi::wait_all(reqs, reqs + 3);
      }
    }
  }
}
Пример #16
0
/// Construct from ISpectrum.
Histogram1D::Histogram1D(const ISpectrum &other)
    : ISpectrum(other), m_histogram(other.histogram()) {}
Пример #17
0
/** Executes the algorithm
 *
 */
void SumSpectra::exec()
{
  // Try and retrieve the optional properties
  m_MinSpec = getProperty("StartWorkspaceIndex");
  m_MaxSpec = getProperty("EndWorkspaceIndex");
  const std::vector<int> indices_list = getProperty("ListOfWorkspaceIndices");

  keepMonitors = getProperty("IncludeMonitors");

  // Get the input workspace
  MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");

  numberOfSpectra = static_cast<int>(localworkspace->getNumberHistograms());
  this->yLength = static_cast<int>(localworkspace->blocksize());

  // Check 'StartSpectrum' is in range 0-numberOfSpectra
  if ( m_MinSpec > numberOfSpectra )
  {
    g_log.warning("StartWorkspaceIndex out of range! Set to 0.");
    m_MinSpec = 0;
  }

  if (indices_list.empty())
  {
    //If no list was given and no max, just do all.
    if ( isEmpty(m_MaxSpec) ) m_MaxSpec = numberOfSpectra-1;
  }

  //Something for m_MaxSpec was given but it is out of range?
  if (!isEmpty(m_MaxSpec) && ( m_MaxSpec > numberOfSpectra-1 || m_MaxSpec < m_MinSpec ))
  {
    g_log.warning("EndWorkspaceIndex out of range! Set to max Workspace Index");
    m_MaxSpec = numberOfSpectra;
  }

  //Make the set of indices to sum up from the list
  this->indices.insert(indices_list.begin(), indices_list.end());

  //And add the range too, if any
  if (!isEmpty(m_MaxSpec))
  {
    for (int i = m_MinSpec; i <= m_MaxSpec; i++)
      this->indices.insert(i);
  }

  //determine the output spectrum id
  m_outSpecId = this->getOutputSpecId(localworkspace);
  g_log.information() << "Spectra remapping gives single spectra with spectra number: "
                      << m_outSpecId << "\n";

  m_CalculateWeightedSum = getProperty("WeightedSum");

 
  EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(localworkspace);
  if (eventW)
  {
    m_CalculateWeightedSum = false;
    this->execEvent(eventW, this->indices);
  }
  else
  {
    //-------Workspace 2D mode -----

    // Create the 2D workspace for the output
    MatrixWorkspace_sptr outputWorkspace = API::WorkspaceFactory::Instance().create(localworkspace,
                                                           1,localworkspace->readX(0).size(),this->yLength);
    size_t numSpectra(0); // total number of processed spectra
    size_t numMasked(0);  // total number of the masked and skipped spectra
    size_t numZeros(0);   // number of spectra which have 0 value in the first column (used in special cases of evaluating how good Puasonian statistics is)
  
    Progress progress(this, 0, 1, this->indices.size());

    // This is the (only) output spectrum
    ISpectrum * outSpec = outputWorkspace->getSpectrum(0);

    // Copy over the bin boundaries
    outSpec->dataX() = localworkspace->readX(0);

    //Build a new spectra map
    outSpec->setSpectrumNo(m_outSpecId);
    outSpec->clearDetectorIDs();

    if (localworkspace->id() == "RebinnedOutput")
    {
      this->doRebinnedOutput(outputWorkspace, progress,numSpectra,numMasked,numZeros);
    }
    else
    {
      this->doWorkspace2D(localworkspace, outSpec, progress,numSpectra,numMasked,numZeros);
    }

    // Pointer to sqrt function
    MantidVec& YError = outSpec->dataE();
    typedef double (*uf)(double);
    uf rs=std::sqrt;
    //take the square root of all the accumulated squared errors - Assumes Gaussian errors
    std::transform(YError.begin(), YError.end(), YError.begin(), rs);

    outputWorkspace->generateSpectraMap();
    // set up the summing statistics
    outputWorkspace->mutableRun().addProperty("NumAllSpectra",int(numSpectra),"",true);
    outputWorkspace->mutableRun().addProperty("NumMaskSpectra",int(numMasked),"",true);
    outputWorkspace->mutableRun().addProperty("NumZeroSpectra",int(numZeros),"",true);


    // Assign it to the output workspace property
    setProperty("OutputWorkspace", outputWorkspace);

  }
}
Пример #18
0
/// Construct from ISpectrum.
Histogram1D::Histogram1D(const ISpectrum &other) : ISpectrum(other) {
    dataY() = other.readY();
    dataE() = other.readE();
}
Пример #19
0
/** Executes the algorithm
 *  @throw std::invalid_argument If the input workspaces do not meet the requirements of this algorithm
 */
void ConjoinWorkspaces::exec()
{
  // Retrieve the input workspaces
  MatrixWorkspace_const_sptr ws1 = getProperty("InputWorkspace1");
  MatrixWorkspace_const_sptr ws2 = getProperty("InputWorkspace2");
  event_ws1 = boost::dynamic_pointer_cast<const EventWorkspace>(ws1);
  event_ws2 = boost::dynamic_pointer_cast<const EventWorkspace>(ws2);

  //Make sure that we are not mis-matching EventWorkspaces and other types of workspaces
  if (((event_ws1) && (!event_ws2)) || ((!event_ws1) && (event_ws2)))
  {
    const std::string message("Only one of the input workspaces are of type EventWorkspace; please use matching workspace types (both EventWorkspace's or both Workspace2D's).");
    g_log.error(message);
    throw std::invalid_argument(message);
  }

  if (event_ws1 && event_ws2)
  {
    //Both are event workspaces. Use the special method
    this->execEvent();
    return;
  }

  // Check that the input workspaces meet the requirements for this algorithm
  this->validateInputs(ws1,ws2);

  // Create the output workspace
  const size_t totalHists = ws1->getNumberHistograms() + ws2->getNumberHistograms();
  MatrixWorkspace_sptr output = WorkspaceFactory::Instance().create("Workspace2D",totalHists,ws1->readX(0).size(),
                                                                             ws1->readY(0).size());
  // Copy over stuff from first input workspace
  WorkspaceFactory::Instance().initializeFromParent(ws1,output,true);

  // Create the X values inside a cow pointer - they will be shared in the output workspace
  cow_ptr<MantidVec> XValues;
  XValues.access() = ws1->readX(0);

  // Initialize the progress reporting object
  m_progress = new API::Progress(this, 0.0, 1.0, totalHists);

  // Loop over the input workspaces in turn copying the data into the output one
  const int64_t& nhist1 = ws1->getNumberHistograms();
  PARALLEL_FOR2(ws1, output)
  for (int64_t i = 0; i < nhist1; ++i)
  {
    PARALLEL_START_INTERUPT_REGION
    ISpectrum * outSpec = output->getSpectrum(i);
    const ISpectrum * inSpec = ws1->getSpectrum(i);

    // Copy X,Y,E
    outSpec->setX(XValues);
    outSpec->setData(inSpec->dataY(), inSpec->dataE());
    // Copy the spectrum number/detector IDs
    outSpec->copyInfoFrom(*inSpec);

    // Propagate masking, if needed
    if ( ws1->hasMaskedBins(i) )
    {
      const MatrixWorkspace::MaskList& inputMasks = ws1->maskedBins(i);
      MatrixWorkspace::MaskList::const_iterator it;
      for (it = inputMasks.begin(); it != inputMasks.end(); ++it)
      {
        output->flagMasked(i,(*it).first,(*it).second);
      }
    }    
    m_progress->report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION


  //For second loop we use the offset from the first
  const int64_t& nhist2 = ws2->getNumberHistograms();

  PARALLEL_FOR2(ws2, output)
  for (int64_t j = 0; j < nhist2; ++j)
  {
    PARALLEL_START_INTERUPT_REGION
    // The spectrum in the output workspace
    ISpectrum * outSpec = output->getSpectrum(nhist1 + j);
    // Spectrum in the second workspace
    const ISpectrum * inSpec = ws2->getSpectrum(j);

    // Copy X,Y,E
    outSpec->setX(XValues);
    outSpec->setData(inSpec->dataY(), inSpec->dataE());
    // Copy the spectrum number/detector IDs
    outSpec->copyInfoFrom(*inSpec);

    // Propagate masking, if needed
    if ( ws2->hasMaskedBins(j) )
    {
      const MatrixWorkspace::MaskList& inputMasks = ws2->maskedBins(j);
      MatrixWorkspace::MaskList::const_iterator it;
      for (it = inputMasks.begin(); it != inputMasks.end(); ++it)
      {
        output->flagMasked(nhist1 + j,(*it).first,(*it).second);
      }
    }
    m_progress->report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  this->fixSpectrumNumbers(ws1,ws2, output);

  // Delete the second input workspace from the ADS
  AnalysisDataService::Instance().remove(getPropertyValue("InputWorkspace2"));
  // Set the result workspace to the first input
  setProperty("InputWorkspace1",output);
}