예제 #1
0
/** Integrate the peaks of the workspace using parameters saved in the algorithm
 * class
 */
void CentroidPeaks::integrateEvent() {

  /// Peak workspace to centroid
  Mantid::DataObjects::PeaksWorkspace_sptr inPeakWS =
      getProperty("InPeaksWorkspace");

  /// Output peaks workspace, create if needed
  Mantid::DataObjects::PeaksWorkspace_sptr peakWS =
      getProperty("OutPeaksWorkspace");
  if (peakWS != inPeakWS)
    peakWS = inPeakWS->clone();

  /// Radius to use around peaks
  int PeakRadius = getProperty("PeakRadius");

  int MinPeaks = -1;
  int MaxPeaks = -1;
  size_t Numberwi = inWS->getNumberHistograms();
  int NumberPeaks = peakWS->getNumberPeaks();

  for (int i = 0; i < NumberPeaks; ++i) {
    auto &peak = peakWS->getPeak(i);
    int pixelID = peak.getDetectorID();

    // Find the workspace index for this detector ID
    if (wi_to_detid_map.find(pixelID) != wi_to_detid_map.end()) {
      size_t wi = wi_to_detid_map[pixelID];
      if (MinPeaks == -1 && peak.getRunNumber() == inWS->getRunNumber() &&
          wi < Numberwi)
        MinPeaks = i;
      if (peak.getRunNumber() == inWS->getRunNumber() && wi < Numberwi)
        MaxPeaks = i;
    }
  }

  int Edge = getProperty("EdgePixels");
  Progress prog(this, MinPeaks, 1.0, MaxPeaks);
  PARALLEL_FOR_IF(Kernel::threadSafe(*inWS, *peakWS))
  for (int i = MinPeaks; i <= MaxPeaks; ++i) {
    PARALLEL_START_INTERUPT_REGION
    // Get a direct ref to that peak.
    auto &peak = peakWS->getPeak(i);
    int col = peak.getCol();
    int row = peak.getRow();
    double TOFPeakd = peak.getTOF();
    std::string bankName = peak.getBankName();
    int nCols = 0, nRows = 0;
    sizeBanks(bankName, nCols, nRows);

    double intensity = 0.0;
    double tofcentroid = 0.0;
    if (edgePixel(inst, bankName, col, row, Edge))
      continue;

    double tofstart = TOFPeakd * std::pow(1.004, -PeakRadius);
    double tofend = TOFPeakd * std::pow(1.004, PeakRadius);
    double rowcentroid = 0.0;
    int rowstart = std::max(0, row - PeakRadius);
    int rowend = std::min(nRows - 1, row + PeakRadius);
    double colcentroid = 0.0;
    int colstart = std::max(0, col - PeakRadius);
    int colend = std::min(nCols - 1, col + PeakRadius);
    for (int irow = rowstart; irow <= rowend; ++irow) {
      for (int icol = colstart; icol <= colend; ++icol) {
        if (edgePixel(inst, bankName, icol, irow, Edge))
          continue;
        auto it1 = wi_to_detid_map.find(findPixelID(bankName, icol, irow));
        size_t workspaceIndex = (it1->second);
        EventList el = eventW->getSpectrum(workspaceIndex);
        el.switchTo(WEIGHTED_NOTIME);
        std::vector<WeightedEventNoTime> events = el.getWeightedEventsNoTime();

        // Check for events in tof range
        for (const auto &event : events) {
          double tof = event.tof();
          if (tof > tofstart && tof < tofend) {
            double weight = event.weight();
            intensity += weight;
            rowcentroid += irow * weight;
            colcentroid += icol * weight;
            tofcentroid += tof * weight;
          }
        }
      }
    }
    // Set pixelID to change row and col
    row = int(rowcentroid / intensity);
    boost::algorithm::clamp(row, 0, nRows - 1);
    col = int(colcentroid / intensity);
    boost::algorithm::clamp(col, 0, nCols - 1);
    if (!edgePixel(inst, bankName, col, row, Edge)) {
      peak.setDetectorID(findPixelID(bankName, col, row));

      // Set wavelength to change tof for peak object
      double tof = tofcentroid / intensity;
      Mantid::Kernel::Units::Wavelength wl;
      std::vector<double> timeflight;
      timeflight.push_back(tof);
      double scattering = peak.getScattering();
      double L1 = peak.getL1();
      double L2 = peak.getL2();
      wl.fromTOF(timeflight, timeflight, L1, L2, scattering, 0, 0, 0);
      const double lambda = timeflight[0];
      timeflight.clear();

      peak.setWavelength(lambda);
      peak.setBinCount(intensity);
    }
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION
  removeEdgePeaks(*peakWS);

  // Save the output
  setProperty("OutPeaksWorkspace", peakWS);
}
예제 #2
0
void AnvredCorrection::execEvent()
{

  const int64_t numHists = static_cast<int64_t>(m_inputWS->getNumberHistograms());
  std::string unitStr = m_inputWS->getAxis(0)->unit()->unitID();
  //Create a new outputworkspace with not much in it
  DataObjects::EventWorkspace_sptr correctionFactors;
  correctionFactors = boost::dynamic_pointer_cast<EventWorkspace>(
      API::WorkspaceFactory::Instance().create("EventWorkspace",numHists,2,1) );
  correctionFactors->sortAll(TOF_SORT, NULL);
  //Copy required stuff from it
  API::WorkspaceFactory::Instance().initializeFromParent(m_inputWS, correctionFactors, true);
  bool inPlace = (this->getPropertyValue("InputWorkspace") == this->getPropertyValue("OutputWorkspace"));
  if (inPlace)
    g_log.debug("Correcting EventWorkspace in-place.");

  // If sample not at origin, shift cached positions.
  const V3D samplePos = m_inputWS->getInstrument()->getSample()->getPos();
  const V3D pos = m_inputWS->getInstrument()->getSource()->getPos()-samplePos;
  double L1 = pos.norm();

  Progress prog(this,0.0,1.0,numHists);
  // Loop over the spectra
  PARALLEL_FOR2(eventW,correctionFactors)
  for (int64_t i = 0; i < int64_t(numHists); ++i)
  {
    PARALLEL_START_INTERUPT_REGION

    // Copy over bin boundaries
    const MantidVec& X = eventW->readX(i);
    correctionFactors->dataX(i) = X;

    // Get detector position
    IDetector_const_sptr det;
    try
    {
      det = eventW->getDetector(i);
    } catch (Exception::NotFoundError&)
    {
      // 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, skip onto the next spectrum
    if ( !det ) continue;

    // This is the scattered beam direction
    Instrument_const_sptr inst = eventW->getInstrument();
    V3D dir = det->getPos() - samplePos;
    double L2 = dir.norm();
    // Two-theta = polar angle = scattering angle = between +Z vector and the scattered beam
    double scattering = dir.angle( V3D(0.0, 0.0, 1.0) );

    EventList el = eventW->getEventList(i);
    el.switchTo(WEIGHTED_NOTIME);
    std::vector<WeightedEventNoTime> events = el.getWeightedEventsNoTime();

    std::vector<WeightedEventNoTime>::iterator itev;
    std::vector<WeightedEventNoTime>::iterator itev_end = events.end();

    Mantid::Kernel::Units::Wavelength wl;
    std::vector<double> timeflight;

    // multiplying an event list by a scalar value
    for (itev = events.begin(); itev != itev_end; itev++)
    {
      timeflight.push_back(itev->tof());
      if (unitStr.compare("TOF") == 0)
        wl.fromTOF(timeflight, timeflight, L1, L2, scattering, 0, 0, 0);
      double value = this->getEventWeight(timeflight[0], scattering);
      timeflight.clear();
      itev->m_errorSquared = static_cast<float>(itev->m_errorSquared * value*value);
      itev->m_weight *= static_cast<float>(value);
    }
    correctionFactors->getOrAddEventList(i) +=events;
    
    std::set<detid_t>& dets = eventW->getEventList(i).getDetectorIDs();
    std::set<detid_t>::iterator j;
    for (j = dets.begin(); j != dets.end(); ++j)
      correctionFactors->getOrAddEventList(i).addDetectorID(*j);
    // When focussing 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

  correctionFactors->doneAddingEventLists();
  setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(correctionFactors));

  // Now do some cleaning-up since destructor may not be called immediately
  this->cleanup();
}