Ejemplo n.º 1
0
/**
 * @brief Handle setting fit workspace.
 *
 * Creates a list of Q values from each spectrum to be used with WorkspaceIndex
 * attribute.
 *
 * @param ws Pointer to workspace
 */
void InelasticDiffSphere::setWorkspace(
    boost::shared_ptr<const API::Workspace> ws) {
  m_qValueCache.clear();

  auto workspace = boost::dynamic_pointer_cast<const API::MatrixWorkspace>(ws);
  if (!workspace)
    return;

  size_t numHist = workspace->getNumberHistograms();
  for (size_t idx = 0; idx < numHist; idx++) {
    Mantid::Geometry::IDetector_const_sptr det;
    try {
      det = workspace->getDetector(idx);
    } catch (Kernel::Exception::NotFoundError &) {
      m_qValueCache.clear();
      g_log.information("Cannot populate Q values from workspace");
      break;
    }

    try {
      double efixed = workspace->getEFixed(det);
      double usignTheta = 0.5 * workspace->detectorTwoTheta(*det);

      double q = Mantid::Kernel::UnitConversion::run(usignTheta, efixed);

      m_qValueCache.push_back(q);
    } catch (std::runtime_error &) {
      m_qValueCache.clear();
      g_log.information("Cannot populate Q values from workspace");
      return;
    }
  }
}
Ejemplo n.º 2
0
void SANSSolidAngleCorrection::execEvent() {
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");

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

  const int numberOfSpectra =
      static_cast<int>(outputEventWS->getNumberHistograms());
  Progress progress(this, 0.0, 1.0, numberOfSpectra);
  progress.report("Solid Angle Correction");

  PARALLEL_FOR1(outputEventWS)
  for (int i = 0; i < numberOfSpectra; i++) {
    PARALLEL_START_INTERUPT_REGION
    IDetector_const_sptr det;
    try {
      det = outputEventWS->getDetector(i);
    } catch (Exception::NotFoundError &) {
      g_log.warning() << "Workspace index " << i
                      << " has no detector assigned to it - discarding\n";
      // 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 (!det)
      continue;

    // Skip if we have a monitor or if the detector is masked.
    if (det->isMonitor() || det->isMasked())
      continue;

    // Compute solid angle correction factor
    const bool is_tube = getProperty("DetectorTubes");
    const double tanTheta = tan(outputEventWS->detectorTwoTheta(*det));
    const double theta_term = sqrt(tanTheta * tanTheta + 1.0);
    double corr;
    if (is_tube) {
      const double tanAlpha = tan(getYTubeAngle(det, inputWS));
      const double alpha_term = sqrt(tanAlpha * tanAlpha + 1.0);
      corr = alpha_term * theta_term * theta_term;
    } else {
      corr = theta_term * theta_term * theta_term;
    }
    EventList &el = outputEventWS->getSpectrum(i);
    el *= corr;
    progress.report("Solid Angle Correction");
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  setProperty("OutputMessage", "Solid angle correction applied");
}
Ejemplo n.º 3
0
std::vector<Geometry::IDetector_const_sptr>
SpectrumInfo::getDetectorVector(const size_t index) const {
  const auto &det = getDetector(index);
  const auto &ndet = det.nDets();
  if (ndet > 1) {
    const auto group = dynamic_cast<const Geometry::DetectorGroup *>(&det);
    return group->getDetectors();
  } else {
    size_t thread = static_cast<size_t>(PARALLEL_THREAD_NUMBER);
    return {m_lastDetector[thread]};
  }
}
void
RODFDetectorCon::mesoJoin(const std::string& nid,
                          const std::vector<std::string>& oldids) {
    // build the new detector
    const RODFDetector& first = getDetector(*(oldids.begin()));
    RODFDetector* newDet = new RODFDetector(nid, first);
    addDetector(newDet);
    // delete previous
    for (std::vector<std::string>::const_iterator i = oldids.begin(); i != oldids.end(); ++i) {
        removeDetector(*i);
    }
}
Ejemplo n.º 5
0
/**
 * If the InstrumentParameter property is set then it attempts to retrieve the parameter
 * from the component, else it returns the value of the Factor property
 * @param inputWS A pointer to the input workspace
 * @param index The current index to inspect
 * @return Value for the scale factor
 */
double ScaleX::getScaleFactor(const API::MatrixWorkspace_const_sptr & inputWS, const size_t index)
{
  if(m_parname.empty()) return m_algFactor;

  // Try and get factor from component. If we see a DetectorGroup use this will use the first component
  Geometry::IDetector_const_sptr det;
  auto inst = inputWS->getInstrument();

  auto *spec = inputWS->getSpectrum(index);
  const auto & ids = spec->getDetectorIDs();
  const size_t ndets(ids.size());
  if(ndets > 0)
  {
    try
    {
      det = inst->getDetector(*ids.begin());
    }
    catch(Exception::NotFoundError&)
    {
      return 0.0;
    }
  }
  else return 0.0;

  const auto & pmap = inputWS->constInstrumentParameters();
  auto par = pmap.getRecursive(det->getComponentID(), m_parname);
  if(par)
  {
    if(!m_combine) return par->value<double>();
    else return m_binOp(m_algFactor,par->value<double>());
  }
  else
  {
    std::ostringstream os;
    os << "Spectrum at index '" << index << "' has no parameter named '" << m_parname << "'\n";
    throw std::runtime_error(os.str());
  }
}
Ejemplo n.º 6
0
/// Returns true if the detector(s) associated with the spectrum are masked.
bool SpectrumInfo::isMasked(const size_t index) const {
  return getDetector(index).isMasked();
}
Ejemplo n.º 7
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";
  }
}
Ejemplo n.º 8
0
std::string
LaneArea::getLaneID(const std::string& detID) {
    return getDetector(detID)->getLane()->getID();
}
Ejemplo n.º 9
0
double
LaneArea::getPosition(const std::string& detID) {
    return getDetector(detID)->getStartPos();
}
Ejemplo n.º 10
0
/// Return a const reference to the detector with given index.
const Geometry::IDetector &DetectorInfo::detector(const size_t index) const {
  return getDetector(index);
}
Ejemplo n.º 11
0
double
LaneArea::getLastStepMeanSpeed(const std::string& detID) {
    return getDetector(detID)->getCurrentMeanSpeed();
}
Ejemplo n.º 12
0
double
LaneArea::getJamLengthMeters(const std::string& detID) {
    return getDetector(detID)->getCurrentJamLengthInMeters();
}
Ejemplo n.º 13
0
int
LaneArea::getJamLengthVehicle(const std::string& detID) {
    return getDetector(detID)->getCurrentJamLengthInVehicles();
}
Ejemplo n.º 14
0
int
LaneArea::getLastStepHaltingNumber(const std::string& detID) {
    return getDetector(detID)->getCurrentHaltingNumber();
}
Ejemplo n.º 15
0
int
LaneArea::getLastStepVehicleNumber(const std::string& detID) {
    return getDetector(detID)->getCurrentVehicleNumber();
}
Ejemplo n.º 16
0
double
LaneArea::getLength(const std::string& detID) {
    const MSE2Collector* const e2 = getDetector(detID);
    return e2->getLength();
}
Ejemplo n.º 17
0
std::vector<std::string>
LaneArea::getLastStepVehicleIDs(const std::string& detID) {
    return getDetector(detID)->getCurrentVehicleIDs();
}
Ejemplo n.º 18
0
double
LaneArea::getLastStepOccupancy(const std::string& detID) {
    return getDetector(detID)->getCurrentOccupancy();
}
Ejemplo n.º 19
0
/// Helper used by SpectrumInfo.
boost::shared_ptr<const Geometry::IDetector>
DetectorInfo::getDetectorPtr(const size_t index) const {
  size_t thread = static_cast<size_t>(PARALLEL_THREAD_NUMBER);
  static_cast<void>(getDetector(index));
  return m_lastDetector[thread];
}
Ejemplo n.º 20
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);

  // Get pointers to sample and source
  IComponent_const_sptr source = m_instrument->getSource();
  IComponent_const_sptr sample = m_instrument->getSample();
  double Lss = source->getDistance(*sample); // distance from source to sample

  // 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();
  }

  // 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_FOR1(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->getEventList(wsIndex);
    if (evlist.getNumberEvents() > 0) // don't bother with empty lists
    {
      IDetector_const_sptr det;
      double L1(Lss); // distance from source to sample
      double L2(-1);  // distance from sample to detector

      try {
        det = outputWS->getDetector(i);
        if (det->isMonitor()) {
          // redefine the sample as the monitor
          L1 = source->getDistance(*det);
          L2 = 0;
        } else {
          L2 = sample->getDistance(*det);
        }
      } catch (Exception::NotFoundError &) {
        g_log.error() << "Unable to calculate distances to/from detector" << i
                      << std::endl;
      }

      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 (det->isMonitor()) {
            t2 = 0.0;
          } else {
            static const double convFact =
                1.0e-6 * sqrt(2 * PhysicalConstants::meV /
                              PhysicalConstants::NeutronMass);
            std::vector<double> wsProp = det->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
                            << std::endl;
            }
          }
          if (t2 >= 0) // t2 < 0 when no detector info is available
          {
            // fix the histogram bins
            MantidVec &x = evlist.dataX();
            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
          MantidVec &x = evlist.dataX();
          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);

          MantidVec tofs_b = evlist.getTofs();
          MantidVec xarray = evlist.readX();
        } // end of else if(emode=="Elastic")
        else if (emode == "Direct") {
          // fix the histogram bins
          MantidVec &x = evlist.dataX();
          for (double &tof : x) {
            tof -= 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()