18#include "MantidHistogramData/Histogram.h"
36 m_tolTOF(0.), m_t1min(200.0) {}
43 auto wsValidator = std::make_shared<WorkspaceUnitValidator>(
"TOF");
46 "The name of the input workspace, containing events and/or "
47 "histogram data, in units of time-of-flight");
50 "The name of the output workspace");
53 std::vector<std::string> EModeOptions{
"Indirect",
"Direct",
"Elastic"};
54 this->
declareProperty(
"EMode",
"Indirect", std::make_shared<StringListValidator>(EModeOptions),
55 "The energy mode (default: Indirect)");
58 "Tolerance in the calculation of the emission time, in "
59 "microseconds (default:1)");
61 "Number of iterations (default:1)");
72 if (emode ==
"Direct") {
73 if (!inputWS->run().hasProperty(
"Ei")) {
74 g_log.
error(
"No incident energy value (Ei) has been set or stored.");
80 auto t0_formula = inputWS->getInstrument()->getStringParameter(
"t0_formula");
81 if (t0_formula.empty()) {
82 g_log.
error(
"Unable to retrieve t0_formula among instrument parameters.");
89 if (eventWS !=
nullptr) {
97 if (outputWS != inputWS) {
99 outputWS = create<MatrixWorkspace>(*inputWS);
103 double t0_direct(-1);
104 if (emode ==
"Direct") {
105 auto Ei = inputWS->run().getPropertyValueAsType<
double>(
"Ei");
107 parser.DefineVar(
"incidentEnergy", &Ei);
109 t0_direct = parser.Eval();
112 const auto &spectrumInfo = inputWS->spectrumInfo();
113 const double Lss = spectrumInfo.l1();
115 const auto numHists =
static_cast<size_t>(inputWS->getNumberHistograms());
116 Progress prog(
this, 0.0, 1.0, numHists);
119 for (
int i = 0; i < static_cast<int>(numHists); ++i) {
121 outputWS->setHistogram(i, inputWS->histogram(i));
126 parser.DefineVar(
"incidentEnergy", &
E1);
131 if (spectrumInfo.hasDetectors(i)) {
132 if (spectrumInfo.isMonitor(i)) {
134 L1 = Lss + spectrumInfo.l2(i);
137 L2 = spectrumInfo.l2(i);
140 g_log.
error() <<
"Unable to calculate distances to/from detector" << i <<
'\n';
147 double min_t0_next = parser.Eval();
149 if (emode ==
"Indirect") {
151 if (spectrumInfo.isMonitor(i)) {
155 std::vector<double> wsProp = spectrumInfo.detector(i).getNumberParameter(
"Efixed");
156 if (!wsProp.empty()) {
157 double E2 = wsProp.at(0);
158 double v2 = convFact * sqrt(E2);
162 g_log.
debug() <<
"Efixed not found for detector " << i <<
'\n';
168 auto &outbins = outputWS->mutableX(i);
169 for (
auto &tof : outbins) {
177 else if (emode ==
"Elastic") {
178 auto &outbins = outputWS->mutableX(i);
179 for (
auto &tof : outbins) {
180 if (tof <
m_t1min * (L1 + L2) / L1)
186 else if (emode ==
"Direct") {
187 outputWS->mutableX(i) += -t0_direct;
197 if (inputWS->getAxis(0)->unit().get()) {
198 outputWS->getAxis(0)->unit() = inputWS->getAxis(0)->unit();
201 if (inputWS->getAxis(1)->unit().get()) {
202 outputWS->getAxis(1)->unit() = inputWS->getAxis(1)->unit();
218 if (matrixOutputWS != matrixInputWS) {
219 matrixOutputWS = matrixInputWS->clone();
222 auto outputWS = std::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS);
225 double t0_direct(-1);
226 if (emode ==
"Direct") {
227 auto Ei = outputWS->run().getPropertyValueAsType<
double>(
"Ei");
229 parser.DefineVar(
"incidentEnergy", &Ei);
231 t0_direct = parser.Eval();
234 const auto &spectrumInfo = outputWS->spectrumInfo();
235 const double Lss = spectrumInfo.l1();
238 const auto numHists =
static_cast<size_t>(outputWS->getNumberHistograms());
239 Progress prog(
this, 0.0, 1.0, numHists);
241 for (
int i = 0; i < static_cast<int>(numHists); ++i) {
243 auto wsIndex =
static_cast<size_t>(i);
244 EventList &evlist = outputWS->getSpectrum(wsIndex);
250 if (spectrumInfo.hasDetectors(i)) {
251 if (spectrumInfo.isMonitor(i)) {
253 L1 = Lss + spectrumInfo.l2(i);
256 L2 = spectrumInfo.l2(i);
259 g_log.
error() <<
"Unable to calculate distances to/from detector" << i <<
'\n';
266 parser.DefineVar(
"incidentEnergy", &
E1);
272 double min_t0_next = parser.Eval();
274 if (emode ==
"Indirect") {
276 if (spectrumInfo.isMonitor(i)) {
280 std::vector<double> wsProp = spectrumInfo.detector(i).getNumberParameter(
"Efixed");
281 if (!wsProp.empty()) {
282 double E2 = wsProp.at(0);
283 double v2 = convFact * sqrt(E2);
287 g_log.
debug() <<
"Efixed not found for detector " << i <<
'\n';
294 for (
double &tof :
x) {
302 for (
double &tof : tofs) {
312 else if (emode ==
"Elastic") {
315 for (
double &tof :
x) {
316 if (tof <
m_t1min * (L1 + L2) / L1)
323 for (
double &tof : tofs) {
326 if (tof <
m_t1min * (L1 + L2) / L1)
334 else if (emode ==
"Direct") {
340 std::transform(tofs.begin(), tofs.end(), tofs.begin(), [&t0_direct](
double tof) { return tof - t0_direct; });
350 outputWS->clearMRU();
356 mu::Parser &parser) {
358 double t0_curr, t0_next;
365 double t1 = tof - t0_curr - t2;
368 t0_next = parser.Eval();
377 double t0_curr, t0_next;
384 double v1 = L12 / (tof - t0_curr);
386 t0_next = parser.Eval();
#define DECLARE_ALGORITHM(classname)
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
Base class from which all concrete algorithm classes should be derived.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
HistogramData::HistogramX & mutableX() &
Helper class for reporting progress from algorithms.
A property class for workspaces.
const double m_t1min
tof limit for fast neutrons
void execEvent(const std::string &emode)
Execution code for event workspace.
double CalculateT0elastic(const double &tof, const double &L12, double &E1, mu::Parser &parser)
Calculate emission time from the moderator for a given detector (L1, t2) and TOF when Emode==Elastic.
std::string m_formula
string containing the heuristic regression for the moderator emission time versus neutron energy
void init() override
Virtual method - must be overridden by concrete algorithm.
ModeratorTzero()
Default constructor.
double m_tolTOF
tolerance for calculating E1, in micro-seconds
void exec() override
Execution code for histogram workspace.
const double m_convfactor
size_t m_niter
Maximum number of iterations when calculating the emission time from the moderator.
double gett1min()
output m_t1min
void setFormula(const std::string &formula)
set attribute m_formula
double CalculateT0indirect(const double &tof, const double &L1, const double &t2, double &E1, mu::Parser &parser)
Calculate emission time from the moderator for a given detector (L1, t2) and TOF when Emode==Inelasti...
void setTofs(const MantidVec &tofs) override
Set a list of TOFs to the current event list.
void setSortOrder(const EventSortType order) const
Manually set the event list sort order value.
std::size_t getNumberEvents() const override
Return the number of events in the list.
void getTofs(std::vector< double > &tofs) const override
Fill a vector with the list of TOFs.
Exception for index errors.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void information(const std::string &msg)
Logs at information level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
The concrete, templated class for properties.
std::complex< double > MANTID_API_DLL E1(std::complex< double > z)
Integral for Gamma.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const EventWorkspace > EventWorkspace_const_sptr
shared pointer to a const Workspace2D
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
A namespace containing physical constants that are required by algorithms and unit routines.
static constexpr double NeutronMass
Mass of the neutron in kg.
static constexpr double meV
1 meV in Joules.
Helper class which provides the Collimation Length for SANS instruments.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
@ Input
An input workspace.
@ Output
An output workspace.