Ejemplo n.º 1
0
/** Executes the algorithm
 *  @throw std::invalid_argument If the input workspaces do not meet the requirements of this algorithm
 */
void ConjoinWorkspaces::execEvent()
{
  //We do not need to check that binning is compatible, just that there is no overlap
  this->checkForOverlap(event_ws1, event_ws2, false);

  // Create the output workspace
  const size_t totalHists = event_ws1->getNumberHistograms() + event_ws2->getNumberHistograms();
  // Have the minimum # of histograms in the output.
  EventWorkspace_sptr output = boost::dynamic_pointer_cast<EventWorkspace>(
      WorkspaceFactory::Instance().create("EventWorkspace",
          1, event_ws1->readX(0).size(), event_ws1->readY(0).size())
      );
  // Copy over geometry (but not data) from first input workspace
  WorkspaceFactory::Instance().initializeFromParent(event_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() = event_ws1->readX(0);

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

  const int64_t& nhist1 = event_ws1->getNumberHistograms();
  for (int64_t i = 0; i < nhist1; ++i)
  {
    //Copy the events over
    output->getOrAddEventList(i) = event_ws1->getEventList(i); //Should fire the copy constructor
    m_progress->report();
  }

  //For second loop we use the offset from the first
  const int64_t& nhist2 = event_ws2->getNumberHistograms();
  for (int64_t j = 0; j < nhist2; ++j)
  {
    //This is the workspace index at which we assign in the output
    int64_t output_wi = j + nhist1;
    //Copy the events over
    output->getOrAddEventList(output_wi) = event_ws2->getEventList(j); //Should fire the copy constructor
    m_progress->report();
  }

  //This will make the spectramap axis.
  output->doneAddingEventLists();

  //Set the same bins for all output pixels
  output->setAllX(XValues);

  this->fixSpectrumNumbers(event_ws1, event_ws2, output);

  // Delete the input workspaces from the ADS
  AnalysisDataService::Instance().remove(getPropertyValue("InputWorkspace1"));
  AnalysisDataService::Instance().remove(getPropertyValue("InputWorkspace2"));

  // Create & assign an output workspace property with the workspace name the same as the first input
  declareProperty(new WorkspaceProperty<>("Output",getPropertyValue("InputWorkspace1"),Direction::Output));
  setProperty("Output", boost::dynamic_pointer_cast<MatrixWorkspace>(output) );
}
Ejemplo n.º 2
0
/** Set up an Event workspace
  * @param numentries :: number of log entries to output
  * @param times :: vector of Kernel::DateAndTime
  * @param values :: vector of log value in double
  */
void ExportTimeSeriesLog::setupEventWorkspace(int numentries,
                                              vector<DateAndTime> &times,
                                              vector<double> values) {
  Kernel::DateAndTime runstart(
      m_dataWS->run().getProperty("run_start")->value());

  // Get some stuff from the input workspace
  const size_t numberOfSpectra = 1;
  const int YLength = static_cast<int>(m_dataWS->blocksize());

  // Make a brand new EventWorkspace
  EventWorkspace_sptr outEventWS = boost::dynamic_pointer_cast<EventWorkspace>(
      API::WorkspaceFactory::Instance().create(
          "EventWorkspace", numberOfSpectra, YLength + 1, YLength));
  // Copy geometry over.
  API::WorkspaceFactory::Instance().initializeFromParent(m_dataWS, outEventWS,
                                                         false);

  m_outWS = boost::dynamic_pointer_cast<MatrixWorkspace>(outEventWS);
  if (!m_outWS)
    throw runtime_error(
        "Output workspace cannot be casted to a MatrixWorkspace.");

  g_log.debug("[DBx336] An output workspace is generated.!");

  // Create the output event list (empty)
  EventList &outEL = outEventWS->getOrAddEventList(0);
  outEL.switchTo(WEIGHTED_NOTIME);

  // Allocate all the required memory
  outEL.reserve(numentries);
  outEL.clearDetectorIDs();

  for (size_t i = 0; i < static_cast<size_t>(numentries); i++) {
    Kernel::DateAndTime tnow = times[i];
    int64_t dt = tnow.totalNanoseconds() - runstart.totalNanoseconds();

    // convert to microseconds
    double dtmsec = static_cast<double>(dt) / 1000.0;
    outEL.addEventQuickly(WeightedEventNoTime(dtmsec, values[i], values[i]));
  }
  // Ensure thread-safety
  outEventWS->sortAll(TOF_SORT, NULL);

  // Now, create a default X-vector for histogramming, with just 2 bins.
  Kernel::cow_ptr<MantidVec> axis;
  MantidVec &xRef = axis.access();
  xRef.resize(2);
  std::vector<WeightedEventNoTime> &events = outEL.getWeightedEventsNoTime();
  xRef[0] = events.begin()->tof();
  xRef[1] = events.rbegin()->tof();

  // Set the binning axis using this.
  outEventWS->setX(0, axis);

  return;
}
Ejemplo n.º 3
0
void CompressEvents::exec()
{
  // Get the input workspace
  EventWorkspace_sptr inputWS = getProperty("InputWorkspace");
  EventWorkspace_sptr outputWS = getProperty("OutputWorkspace");
  double tolerance = getProperty("Tolerance");

  // Some starting things
  bool inplace = (inputWS == outputWS);
  const int noSpectra = static_cast<int>(inputWS->getNumberHistograms());
  Progress prog(this,0.0,1.0, noSpectra*2);

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

  // Are we making a copy of the input workspace?
  if (!inplace)
  {
    //Make a brand new EventWorkspace
    outputWS = boost::dynamic_pointer_cast<EventWorkspace>(
        API::WorkspaceFactory::Instance().create("EventWorkspace", inputWS->getNumberHistograms(), 2, 1));
    //Copy geometry over.
    API::WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, false);
    // We DONT copy the data though

    // Do we want to parallelize over event lists, or in each event list
    bool parallel_in_each = noSpectra < PARALLEL_GET_MAX_THREADS;
    //parallel_in_each = false;

    // Loop over the histograms (detector spectra)
    // Don't parallelize the loop if we are going to parallelize each event list.
    // cppcheck-suppress syntaxError
    PRAGMA_OMP( parallel for schedule(dynamic) if (!parallel_in_each) )
    for (int i = 0; i < noSpectra; ++i)
    {
      PARALLEL_START_INTERUPT_REGION
      //the loop variable i can't be signed because of OpenMp rules inforced in Linux. Using this signed type suppresses warnings below
      const size_t index = static_cast<size_t>(i);
      // The input event list
      EventList& input_el = inputWS->getEventList(index);
      // And on the output side
      EventList & output_el = outputWS->getOrAddEventList(index);
      // Copy other settings into output
      output_el.setX( input_el.ptrX() );

      // The EventList method does the work.
      input_el.compressEvents(tolerance, &output_el, parallel_in_each);

      prog.report("Compressing");
      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

  }
Ejemplo n.º 4
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);
    }
  }
}
Ejemplo n.º 5
0
/** Executes the algorithm
 *  @throw std::out_of_range If a property is set to an invalid value for the
 * input workspace
 */
void ExtractSpectra::execEvent() {
  m_histogram = m_inputWorkspace->isHistogramData();
  double minX_val = getProperty("XMin");
  double maxX_val = getProperty("XMax");
  if (isEmpty(minX_val))
    minX_val = eventW->getTofMin();
  if (isEmpty(maxX_val))
    maxX_val = eventW->getTofMax();

  // Check for common boundaries in input workspace
  m_commonBoundaries = WorkspaceHelpers::commonBoundaries(m_inputWorkspace);

  // Retrieve and validate the input properties
  this->checkProperties();
  cow_ptr<MantidVec> XValues_new;
  if (m_commonBoundaries) {
    const MantidVec &oldX =
        m_inputWorkspace->readX(m_workspaceIndexList.front());
    XValues_new.access().assign(oldX.begin() + m_minX, oldX.begin() + m_maxX);
  }
  size_t ntcnew = m_maxX - m_minX;

  if (ntcnew < 2) {
    // create new output X axis
    std::vector<double> rb_params;
    rb_params.push_back(minX_val);
    rb_params.push_back(maxX_val - minX_val);
    rb_params.push_back(maxX_val);
    ntcnew = VectorHelper::createAxisFromRebinParams(rb_params,
                                                     XValues_new.access());
  }

  // run inplace branch if appropriate
  MatrixWorkspace_sptr OutputWorkspace = this->getProperty("OutputWorkspace");
  bool inPlace = (OutputWorkspace == m_inputWorkspace);
  if (inPlace)
    g_log.debug("Cropping EventWorkspace in-place.");

  // Create the output workspace
  EventWorkspace_sptr outputWorkspace =
      boost::dynamic_pointer_cast<EventWorkspace>(
          API::WorkspaceFactory::Instance().create(
              "EventWorkspace", m_workspaceIndexList.size(), ntcnew,
              ntcnew - m_histogram));
  eventW->sortAll(TOF_SORT, nullptr);
  outputWorkspace->sortAll(TOF_SORT, nullptr);
  // Copy required stuff from it
  API::WorkspaceFactory::Instance().initializeFromParent(m_inputWorkspace,
                                                         outputWorkspace, true);

  Progress prog(this, 0.0, 1.0, 2 * m_workspaceIndexList.size());
  eventW->sortAll(Mantid::DataObjects::TOF_SORT, &prog);
  // Loop over the required workspace indices, copying in the desired bins
  PARALLEL_FOR2(m_inputWorkspace, outputWorkspace)
  for (int j = 0; j < static_cast<int>(m_workspaceIndexList.size()); ++j) {
    PARALLEL_START_INTERUPT_REGION
    auto i = m_workspaceIndexList[j];
    const EventList &el = eventW->getEventList(i);
    // The output event list
    EventList &outEL = outputWorkspace->getOrAddEventList(j);
    //    // left side of the crop - will erase 0 -> endLeft
    //    std::size_t endLeft;
    //    // right side of the crop - will erase endRight->numEvents+1
    //    std::size_t endRight;

    switch (el.getEventType()) {
    case TOF: {
      std::vector<TofEvent> moreevents;
      moreevents.reserve(el.getNumberEvents()); // assume all will make it
      copyEventsHelper(el.getEvents(), moreevents, minX_val, maxX_val);
      outEL += moreevents;
      break;
    }
    case WEIGHTED: {
      std::vector<WeightedEvent> moreevents;
      moreevents.reserve(el.getNumberEvents()); // assume all will make it
      copyEventsHelper(el.getWeightedEvents(), moreevents, minX_val, maxX_val);
      outEL += moreevents;
      break;
    }
    case WEIGHTED_NOTIME: {
      std::vector<WeightedEventNoTime> moreevents;
      moreevents.reserve(el.getNumberEvents()); // assume all will make it
      copyEventsHelper(el.getWeightedEventsNoTime(), moreevents, minX_val,
                       maxX_val);
      outEL += moreevents;
      break;
    }
    }
    outEL.setSortOrder(el.getSortType());

    // Copy spectrum number & detector IDs
    outEL.copyInfoFrom(el);

    bool hasDx = eventW->hasDx(i);

    if (!m_commonBoundaries) {
      // If the X axis is NOT common, then keep the initial X axis, just clear
      // the events
      outEL.setX(el.dataX());
      if (hasDx) {
        outEL.setDx(el.dataDx());
      }
    } else {
      // Common bin boundaries get all set to the same value
      outEL.setX(XValues_new);
      if (hasDx) {
        const MantidVec &oldDx = m_inputWorkspace->readDx(i);
        cow_ptr<MantidVec> DxValues_new;
        DxValues_new.access().assign(oldDx.begin() + m_minX,
                                     oldDx.begin() + m_maxX);
        outEL.setDx(DxValues_new);
      }
    }

    // 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);
      }
    }
    // When cropping in place, you can clear out old memory from the input one!
    if (inPlace) {
      eventW->getEventList(i).clear();
      Mantid::API::MemoryManager::Instance().releaseFreeMemory();
    }
    prog.report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  setProperty("OutputWorkspace",
              boost::dynamic_pointer_cast<MatrixWorkspace>(outputWorkspace));
}