Exemplo n.º 1
0
/** Execute the algorithm for a EventWorkspace input
 * @param ws :: EventWorkspace
 */
void SmoothNeighbours::execEvent(Mantid::DataObjects::EventWorkspace_sptr ws) {
  m_progress->resetNumSteps(inWS->getNumberHistograms(), 0.5, 1.0);

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

  EventWorkspace_sptr outWS;
  // Make a brand new EventWorkspace
  outWS = boost::dynamic_pointer_cast<EventWorkspace>(
      API::WorkspaceFactory::Instance().create(
          "EventWorkspace", numberOfSpectra, YLength + 1, YLength));
  // Copy geometry over.
  API::WorkspaceFactory::Instance().initializeFromParent(*ws, *outWS, false);
  // Ensure thread-safety
  outWS->sortAll(TOF_SORT, nullptr);

  this->setProperty("OutputWorkspace",
                    boost::dynamic_pointer_cast<MatrixWorkspace>(outWS));

  // Go through all the output workspace
  PARALLEL_FOR_IF(Kernel::threadSafe(*ws, *outWS))
  for (int outWIi = 0; outWIi < int(numberOfSpectra); outWIi++) {
    PARALLEL_START_INTERUPT_REGION

    // Create the output event list (empty)
    EventList &outEL = outWS->getSpectrum(outWIi);

    // Which are the neighbours?
    std::vector<weightedNeighbour> &neighbours = m_neighbours[outWIi];
    std::vector<weightedNeighbour>::iterator it;
    for (it = neighbours.begin(); it != neighbours.end(); ++it) {
      size_t inWI = it->first;
      // if(sum)outEL.copyInfoFrom(*ws->getSpectrum(inWI));
      double weight = it->second;
      // Copy the event list
      EventList tmpEL = ws->getSpectrum(inWI);
      // Scale it
      tmpEL *= weight;
      // Add it
      outEL += tmpEL;
    }

    // Copy the single detector ID (of the center) and spectrum number from the
    // input workspace
    // if (!sum) outEL.copyInfoFrom(*ws->getSpectrum(outWIi));

    m_progress->report("Summing");
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  // Give the 0-th X bins to all the output spectra.
  outWS->setAllX(inWS->binEdges(0));
  if (expandSumAllPixels)
    spreadPixels(outWS);
}
Exemplo n.º 2
0
void EQSANSTofStructure::execEvent(
    Mantid::DataObjects::EventWorkspace_sptr inputWS, double threshold,
    double frame_offset, double tof_frame_width, double tmp_frame_width,
    bool frame_skipping) {
  const size_t numHists = inputWS->getNumberHistograms();
  Progress progress(this, 0.0, 1.0, numHists);

  // Get the nominal sample-to-detector distance (in mm)
  Mantid::Kernel::Property *prop =
      inputWS->run().getProperty("sample_detector_distance");
  auto dp = dynamic_cast<Mantid::Kernel::PropertyWithValue<double> *>(prop);
  if (!dp) {
    throw std::runtime_error("sample_detector_distance log not found.");
  }
  const double SDD = *dp / 1000.0;

  // Loop through the spectra and apply correction
  PARALLEL_FOR1(inputWS)
  for (int64_t ispec = 0; ispec < int64_t(numHists); ++ispec) {

    IDetector_const_sptr det;
    try {
      det = inputWS->getDetector(ispec);
    } catch (Exception::NotFoundError &) {
      g_log.warning() << "Workspace index " << ispec
                      << " has no detector assigned to it - discarding\n";
      // 'continue' statement moved outside catch block because Mac Intel
      // compiler has a problem with it being here in an openmp block.
    }
    if (!det)
      continue;

    // Get the flight path from the sample to the detector pixel
    const V3D samplePos = inputWS->getInstrument()->getSample()->getPos();
    const V3D scattered_flight_path = det->getPos() - samplePos;

    // Sample-to-source distance
    const V3D sourcePos = inputWS->getInstrument()->getSource()->getPos();
    const V3D SSD = samplePos - sourcePos;
    double tof_factor =
        (SSD.norm() + scattered_flight_path.norm()) / (SSD.norm() + SDD);

    PARALLEL_START_INTERUPT_REGION

    // Get the pointer to the output event list
    std::vector<TofEvent> &events = inputWS->getSpectrum(ispec).getEvents();
    std::vector<TofEvent>::iterator it;
    std::vector<TofEvent> clean_events;

    for (it = events.begin(); it < events.end(); ++it) {
      double newtof = it->tof();
      newtof += frame_offset;
      // Correct for the scattered neutron flight path
      if (flight_path_correction)
        newtof /= tof_factor;

      while (newtof < threshold)
        newtof += tmp_frame_width;

      // Remove events that don't fall within the accepted time window
      double rel_tof = newtof - frame_tof0;
      double x = (static_cast<int>(floor(rel_tof * 10)) %
                  static_cast<int>(floor(tof_frame_width * 10))) *
                 0.1;
      if (x < low_tof_cut || x > tof_frame_width - high_tof_cut) {
        continue;
      }
      // At this point the events in the second frame are still off by a frame
      if (frame_skipping && rel_tof > tof_frame_width)
        newtof += tof_frame_width;
      clean_events.emplace_back(newtof, it->pulseTime());
    }
    events.clear();
    events.reserve(clean_events.size());
    for (it = clean_events.begin(); it < clean_events.end(); ++it) {
      events.push_back(*it);
    }

    progress.report("TOF structure");
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION
}