Esempio n. 1
0
void UnwrapSNS::execEvent() {
  // set up the output workspace
  MatrixWorkspace_sptr matrixOutW = this->getProperty("OutputWorkspace");
  if (matrixOutW != m_inputWS) {
    matrixOutW = m_inputWS->clone();
    setProperty("OutputWorkspace", matrixOutW);
  }
  auto outW = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutW);

  // set up the progress bar
  m_progress = new Progress(this, 0.0, 1.0, m_numberOfSpectra * 2);

  // algorithm assumes the data is sorted so it can jump out early
  outW->sortAll(Mantid::DataObjects::TOF_SORT, m_progress);

  this->getTofRangeData(true);

  // without the primary flight path the algorithm cannot work
  const auto &spectrumInfo = m_inputWS->spectrumInfo();
  const double L1 = spectrumInfo.l1();

  // do the actual work
  for (int workspaceIndex = 0; workspaceIndex < m_numberOfSpectra;
       workspaceIndex++) {
    std::size_t numEvents = outW->getSpectrum(workspaceIndex).getNumberEvents();
    double Ld = -1.0;
    if (spectrumInfo.hasDetectors(workspaceIndex))
      Ld = L1 + spectrumInfo.l2(workspaceIndex);

    std::vector<double> time_bins;
    if (outW->x(0).size() > 2) {
      this->unwrapX(m_inputWS->x(workspaceIndex), time_bins, Ld);
      outW->setBinEdges(workspaceIndex, std::move(time_bins));
    } else {
      outW->setSharedX(workspaceIndex, m_inputWS->sharedX(workspaceIndex));
    }
    if (numEvents > 0) {
      std::vector<double> times(numEvents);
      outW->getSpectrum(workspaceIndex).getTofs(times);
      double filterVal = m_Tmin * Ld / m_LRef;
      for (size_t j = 0; j < numEvents; j++) {
        if (times[j] < filterVal)
          times[j] += m_frameWidth;
        else
          break; // stop filtering
      }
      outW->getSpectrum(workspaceIndex).setTofs(times);
    }
    m_progress->report();
  }

  outW->clearMRU();
  this->runMaskDetectors();
}
Esempio n. 2
0
void UnwrapSNS::execEvent() {
  // set up the output workspace
  MatrixWorkspace_sptr matrixOutW = this->getProperty("OutputWorkspace");
  if (matrixOutW != m_inputWS) {
    matrixOutW = m_inputWS->clone();
    setProperty("OutputWorkspace", matrixOutW);
  }
  auto outW = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutW);

  // set up the progress bar
  m_progress = new Progress(this, 0.0, 1.0, m_numberOfSpectra * 2);

  // algorithm assumes the data is sorted so it can jump out early
  outW->sortAll(Mantid::DataObjects::TOF_SORT, m_progress);

  this->getTofRangeData(true);

  // do the actual work
  //  PARALLEL_FOR2(m_inputWS, outW)
  for (int workspaceIndex = 0; workspaceIndex < m_numberOfSpectra;
       workspaceIndex++) {
    //    PARALLEL_START_INTERUPT_REGION
    std::size_t numEvents = outW->getSpectrum(workspaceIndex).getNumberEvents();
    bool isMonitor;
    double Ld = this->calculateFlightpath(workspaceIndex, isMonitor);
    MantidVec time_bins;
    if (outW->dataX(0).size() > 2) {
      this->unwrapX(m_inputWS->dataX(workspaceIndex), time_bins, Ld);
      outW->setX(workspaceIndex, time_bins);
    } else {
      outW->setX(workspaceIndex, m_inputWS->dataX(workspaceIndex));
    }
    if (numEvents > 0) {
      MantidVec times(numEvents);
      outW->getSpectrum(workspaceIndex).getTofs(times);
      double filterVal = m_Tmin * Ld / m_LRef;
      for (size_t j = 0; j < numEvents; j++) {
        if (times[j] < filterVal)
          times[j] += m_frameWidth;
        else
          break; // stop filtering
      }
      outW->getSpectrum(workspaceIndex).setTofs(times);
    }
    m_progress->report();
    //    PARALLEL_END_INTERUPT_REGION
  }
  //  PARALLEL_CHECK_INTERUPT_REGION

  outW->clearMRU();
  this->runMaskDetectors();
}
Esempio n. 3
0
/** Remove low resolution TOF from an EventWorkspace
 */
void RemoveLowResTOF::execEvent(const SpectrumInfo &spectrumInfo) {
  // set up the output workspace
  MatrixWorkspace_sptr matrixOutW = getProperty("OutputWorkspace");
  auto outW = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutW);

  MatrixWorkspace_sptr matrixLowResW = getProperty("LowResTOFWorkspace");
  if (m_outputLowResTOF) {
    matrixLowResW = m_inputWS->clone();
    setProperty("LowResTOFWorkspace", matrixLowResW);
  }
  auto lowW = boost::dynamic_pointer_cast<EventWorkspace>(matrixLowResW);

  g_log.debug() << "TOF range was " << m_inputEvWS->getTofMin() << " to "
                << m_inputEvWS->getTofMax() << " microseconds\n";

  std::size_t numEventsOrig = outW->getNumberEvents();
  // set up the progress bar
  m_progress = make_unique<Progress>(this, 0.0, 1.0, m_numberOfSpectra * 2);

  // algorithm assumes the data is sorted so it can jump out early
  outW->sortAll(Mantid::DataObjects::TOF_SORT, m_progress.get());

  this->getTminData(true);
  size_t numClearedEventLists = 0;
  size_t numClearedEvents = 0;

  // do the actual work
  for (size_t workspaceIndex = 0; workspaceIndex < m_numberOfSpectra;
       workspaceIndex++) {
    if (outW->getSpectrum(workspaceIndex).getNumberEvents() > 0) {
      double tmin = this->calcTofMin(workspaceIndex, spectrumInfo);
      if (tmin != tmin) {
        // Problematic
        g_log.warning() << "tmin for workspaceIndex " << workspaceIndex
                        << " is nan. Clearing out data. "
                        << "There are "
                        << outW->getSpectrum(workspaceIndex).getNumberEvents()
                        << " of it. \n";
        numClearedEventLists += 1;
        numClearedEvents += outW->getSpectrum(workspaceIndex).getNumberEvents();
        outW->getSpectrum(workspaceIndex).clear(false);

        if (m_outputLowResTOF)
          lowW->getSpectrum(workspaceIndex).clear(false);
      } else if (tmin > 0.) {
        // there might be events between 0 and tmin (i.e., low resolution)
        outW->getSpectrum(workspaceIndex).maskTof(0., tmin);
        if (outW->getSpectrum(workspaceIndex).getNumberEvents() == 0)
          numClearedEventLists += 1;

        if (m_outputLowResTOF) {
          double tmax = lowW->getSpectrum(workspaceIndex).getTofMax();
          if (tmax != tmax) {
            g_log.warning() << "tmax for workspaceIndex " << workspaceIndex
                            << " is nan. Clearing out data. \n";
            lowW->getSpectrum(workspaceIndex).clear(false);
          } else {
            // There is possibility that tmin calculated is larger than TOF-MAX
            // of the spectrum
            if (tmax + DBL_MIN > tmin)
              lowW->getSpectrum(workspaceIndex).maskTof(tmin, tmax + DBL_MIN);
          }
        }
      } else {
        // do nothing if tmin <= 0. for outW
        if (m_outputLowResTOF) {
          // tmin = 0.  no event will be in low resolution
          lowW->getSpectrum(workspaceIndex).clear(false);
        }
      } //
    }
  }
  g_log.information() << "Went from " << numEventsOrig << " events to "
                      << outW->getNumberEvents() << " events ("
                      << (static_cast<double>(numEventsOrig -
                                              outW->getNumberEvents()) *
                          100. / static_cast<double>(numEventsOrig))
                      << "% removed)\n";
  if (numClearedEventLists > 0)
    g_log.warning()
        << numClearedEventLists << " spectra of " << m_numberOfSpectra
        << " had all data removed.  The number of removed events is "
        << numClearedEvents << ".\n";
  g_log.debug() << "TOF range is now " << outW->getTofMin() << " to "
                << outW->getTofMax() << " microseconds\n";
  outW->clearMRU();
}
Esempio n. 4
0
void CorrectKiKf::execEvent() {
  g_log.information("Processing event workspace");

  const MatrixWorkspace_const_sptr matrixInputWS =
      getProperty("InputWorkspace");
  auto inputWS =
      boost::dynamic_pointer_cast<const EventWorkspace>(matrixInputWS);

  // generate the output workspace pointer
  API::MatrixWorkspace_sptr matrixOutputWS = getProperty("OutputWorkspace");
  if (matrixOutputWS != matrixInputWS) {
    matrixOutputWS = matrixInputWS->clone();
    setProperty("OutputWorkspace", matrixOutputWS);
  }
  auto outputWS = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS);

  const std::string emodeStr = getProperty("EMode");
  double efixedProp = getProperty("EFixed"), efixed;

  if (efixedProp == EMPTY_DBL()) {
    if (emodeStr == "Direct") {
      // Check if it has been store on the run object for this workspace
      if (inputWS->run().hasProperty("Ei")) {
        Kernel::Property *eiprop = inputWS->run().getProperty("Ei");
        efixedProp = boost::lexical_cast<double>(eiprop->value());
        g_log.debug() << "Using stored Ei value " << efixedProp << "\n";
      } else {
        throw std::invalid_argument(
            "No Ei value has been set or stored within the run information.");
      }
    } else {
      // If not specified, will try to get Ef from the parameter file for
      // indirect geometry,
      // but it will be done for each spectrum separately, in case of different
      // analyzer crystals
    }
  }

  // Get the parameter map
  const ParameterMap &pmap = outputWS->constInstrumentParameters();

  int64_t numHistograms = static_cast<int64_t>(inputWS->getNumberHistograms());
  API::Progress prog = API::Progress(this, 0.0, 1.0, numHistograms);
  PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS))
  for (int64_t i = 0; i < numHistograms; ++i) {
    PARALLEL_START_INTERUPT_REGION

    double Efi = 0;
    // Now get the detector object for this histogram to check if monitor
    // or to get Ef for indirect geometry
    if (emodeStr == "Indirect") {
      if (efixedProp != EMPTY_DBL())
        Efi = efixedProp;
      else
        try {
          IDetector_const_sptr det = inputWS->getDetector(i);
          if (!det->isMonitor()) {
            try {
              Parameter_sptr par = pmap.getRecursive(det.get(), "Efixed");
              if (par) {
                Efi = par->value<double>();
                g_log.debug() << "Detector: " << det->getID()
                              << " EFixed: " << Efi << "\n";
              }
            } catch (std::runtime_error &) { /* Throws if a DetectorGroup, use
                                                single provided value */
            }
          }

        } catch (std::runtime_error &) {
          g_log.information() << "Workspace Index " << i
                              << ": cannot find detector"
                              << "\n";
        }
    }

    if (emodeStr == "Indirect")
      efixed = Efi;
    else
      efixed = efixedProp;

    // Do the correction
    auto &evlist = outputWS->getSpectrum(i);
    switch (evlist.getEventType()) {
    case TOF:
      // Switch to weights if needed.
      evlist.switchTo(WEIGHTED);
    /* no break */
    // Fall through

    case WEIGHTED:
      correctKiKfEventHelper(evlist.getWeightedEvents(), efixed, emodeStr);
      break;

    case WEIGHTED_NOTIME:
      correctKiKfEventHelper(evlist.getWeightedEventsNoTime(), efixed,
                             emodeStr);
      break;
    }

    prog.report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  outputWS->clearMRU();
  if (inputWS->getNumberEvents() != outputWS->getNumberEvents()) {
    g_log.information() << "Ef <= 0 or Ei <= 0 for "
                        << inputWS->getNumberEvents() -
                               outputWS->getNumberEvents() << " events, out of "
                        << inputWS->getNumberEvents() << '\n';
    if (efixedProp == EMPTY_DBL())
      g_log.information() << "Try to set fixed energy\n";
  }
}
Esempio n. 5
0
void ModeratorTzero::execEvent(const std::string &emode) {
  g_log.information("Processing event workspace");

  const MatrixWorkspace_const_sptr matrixInputWS =
      getProperty("InputWorkspace");

  // generate the output workspace pointer
  API::MatrixWorkspace_sptr matrixOutputWS = getProperty("OutputWorkspace");
  if (matrixOutputWS != matrixInputWS) {
    matrixOutputWS = matrixInputWS->clone();
    setProperty("OutputWorkspace", matrixOutputWS);
  }
  auto outputWS = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS);

  // calculate tof shift once for all neutrons if emode==Direct
  double t0_direct(-1);
  if (emode == "Direct") {
    Kernel::Property *eiprop = outputWS->run().getProperty("Ei");
    double Ei = boost::lexical_cast<double>(eiprop->value());
    mu::Parser parser;
    parser.DefineVar("incidentEnergy", &Ei); // associate E1 to this parser
    parser.SetExpr(m_formula);
    t0_direct = parser.Eval();
  }

  const auto &spectrumInfo = outputWS->spectrumInfo();
  const double Lss = spectrumInfo.l1();

  // Loop over the spectra
  const size_t numHists = static_cast<size_t>(outputWS->getNumberHistograms());
  Progress prog(this, 0.0, 1.0, numHists); // report progress of algorithm
  PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS))
  for (int i = 0; i < static_cast<int>(numHists); ++i) {
    PARALLEL_START_INTERUPT_REGION
    size_t wsIndex = static_cast<size_t>(i);
    EventList &evlist = outputWS->getSpectrum(wsIndex);
    if (evlist.getNumberEvents() > 0) // don't bother with empty lists
    {
      double L1(Lss); // distance from source to sample
      double L2(-1);  // distance from sample to detector

      if (spectrumInfo.hasDetectors(i)) {
        if (spectrumInfo.isMonitor(i)) {
          // redefine the sample as the monitor
          L1 = Lss + spectrumInfo.l2(i); // L2 in SpectrumInfo defined negative
          L2 = 0;
        } else {
          L2 = spectrumInfo.l2(i);
        }
      } else {
        g_log.error() << "Unable to calculate distances to/from detector" << i
                      << '\n';
      }

      if (L2 >= 0) {
        // One parser for each parallel processor needed (except Edirect mode)
        double E1;
        mu::Parser parser;
        parser.DefineVar("incidentEnergy", &E1); // associate E1 to this parser
        parser.SetExpr(m_formula);

        // fast neutrons are shifted by min_t0_next, irrespective of tof
        double v1_max = L1 / m_t1min;
        E1 = m_convfactor * v1_max * v1_max;
        double min_t0_next = parser.Eval();

        if (emode == "Indirect") {
          double t2(-1.0); // time from sample to detector. (-1) signals error
          if (spectrumInfo.isMonitor(i)) {
            t2 = 0.0;
          } else {
            static const double convFact =
                1.0e-6 * sqrt(2 * PhysicalConstants::meV /
                              PhysicalConstants::NeutronMass);
            std::vector<double> wsProp =
                spectrumInfo.detector(i).getNumberParameter("Efixed");
            if (!wsProp.empty()) {
              double E2 = wsProp.at(0);        //[E2]=meV
              double v2 = convFact * sqrt(E2); //[v2]=meter/microsec
              t2 = L2 / v2;
            } else {
              // t2 is kept to -1 if no Efixed is found
              g_log.debug() << "Efixed not found for detector " << i << '\n';
            }
          }
          if (t2 >= 0) // t2 < 0 when no detector info is available
          {
            // fix the histogram bins
            auto &x = evlist.mutableX();
            for (double &tof : x) {
              if (tof < m_t1min + t2)
                tof -= min_t0_next;
              else
                tof -= CalculateT0indirect(tof, L1, t2, E1, parser);
            }

            MantidVec tofs = evlist.getTofs();
            for (double &tof : tofs) {
              if (tof < m_t1min + t2)
                tof -= min_t0_next;
              else
                tof -= CalculateT0indirect(tof, L1, t2, E1, parser);
            }
            evlist.setTofs(tofs);
            evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED);
          } // end of if( t2>= 0)
        }   // end of if(emode=="Indirect")
        else if (emode == "Elastic") {
          // Apply t0 correction to histogram bins
          auto &x = evlist.mutableX();
          for (double &tof : x) {
            if (tof < m_t1min * (L1 + L2) / L1)
              tof -= min_t0_next;
            else
              tof -= CalculateT0elastic(tof, L1 + L2, E1, parser);
          }

          MantidVec tofs = evlist.getTofs();
          for (double &tof : tofs) {
            // add a [-0.1,0.1] microsecond noise to avoid artifacts
            // resulting from original tof data
            if (tof < m_t1min * (L1 + L2) / L1)
              tof -= min_t0_next;
            else
              tof -= CalculateT0elastic(tof, L1 + L2, E1, parser);
          }
          evlist.setTofs(tofs);
          evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED);
        } // end of else if(emode=="Elastic")
        else if (emode == "Direct") {
          // fix the histogram bins
          evlist.mutableX() -= t0_direct;

          MantidVec tofs = evlist.getTofs();
          for (double &tof : tofs) {
            tof -= t0_direct;
          }
          evlist.setTofs(tofs);
          evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED);
        } // end of else if(emode=="Direct")
      }   // end of if(L2 >= 0)
    }     // end of if (evlist.getNumberEvents() > 0)
    prog.report();
    PARALLEL_END_INTERUPT_REGION
  } // end of for (int i = 0; i < static_cast<int>(numHists); ++i)
  PARALLEL_CHECK_INTERUPT_REGION
  outputWS->clearMRU(); // Clears the Most Recent Used lists */
} // end of void ModeratorTzero::execEvent()