20#include <unordered_map>
34 "The name of the workspace to take as input.");
37 "If left empty then all workspace indices are used.");
38 setPropertySettings(
"WorkspaceIndices",
41 declareProperty(
"IncludeData",
false,
"Include the first value from each spectrum.");
42 setPropertySettings(
"IncludeData",
45 declareProperty<bool>(
"IncludeDetectorPosition",
false,
46 "Include the absolute position of the detector group for each spectrum.",
Direction::Input);
47 setPropertySettings(
"IncludeDetectorPosition",
50 declareProperty<bool>(
"OneRowPerDetectorID",
false,
51 "Order rows in table by detector IDs, with each detector ID having its own row. When "
52 "OneRowPerDetectorID=true the table iterates over all detector IDs, so WorkspaceIndices is "
53 "ignored and the row count equals the detector count.",
55 setPropertySettings(
"OneRowPerDetectorID",
60 "The name of the outputted detector table workspace, if left empty then "
61 "the input workspace name + \"-Detectors\" is used.");
71 if (
auto peaks = std::dynamic_pointer_cast<IPeaksWorkspace>(inputWs)) {
72 table = peaks->createDetectorTable();
77 if ((
ws = std::dynamic_pointer_cast<MatrixWorkspace>(inputWs))) {
78 if (
ws->getInstrument()->getSample() ==
nullptr) {
79 throw std::runtime_error(
"Matrix workspace has no instrument information");
92 throw std::runtime_error(
"Detector table can only be created for matrix and peaks workspaces.");
96 if (
table ==
nullptr) {
97 throw std::runtime_error(
"Unknown error while creating detector table workspace");
101 setPropertyValue(
"DetectorTableWorkspace", inputWs->getName() +
"-Detectors");
113 std::map<std::string, std::string> validationOutput;
116 const auto matrix = std::dynamic_pointer_cast<MatrixWorkspace>(inputWS);
119 const int numSpectra =
static_cast<int>(matrix->getNumberHistograms());
120 const std::vector<int> indices =
getProperty(
"WorkspaceIndices");
122 if (std::any_of(indices.cbegin(), indices.cend(),
123 [numSpectra](
const auto index) { return (index >= numSpectra) || (index < 0); })) {
124 validationOutput[
"WorkspaceIndices"] =
"One or more indices out of range of available spectra.";
128 return validationOutput;
143 }
catch (std::invalid_argument &) {
145 }
catch (std::runtime_error &) {
155 beamAxisIndex =
ws->getInstrument()->getReferenceFrame()->pointingAlongBeam();
168 std::vector<std::pair<std::string, std::string>> colNames;
169 colNames.emplace_back(
"int",
"Index");
170 colNames.emplace_back(
"int",
"Spectrum No");
172 colNames.emplace_back(
"int",
"Detector ID(s)");
174 colNames.emplace_back(
"str",
"Detector ID(s)");
177 colNames.emplace_back(
"str",
"Time Indexes");
179 colNames.emplace_back(
"double",
"Data Value");
180 colNames.emplace_back(
"double",
"Data Error");
183 colNames.emplace_back(
"double",
"R");
184 colNames.emplace_back(
"double",
"Theta");
186 colNames.emplace_back(
"double",
"Q elastic");
188 colNames.emplace_back(
"double",
"Phi");
189 colNames.emplace_back(
"str",
"Monitor");
191 colNames.emplace_back(
"double",
"DIFA");
192 colNames.emplace_back(
"double",
"DIFC");
193 colNames.emplace_back(
"double",
"DIFC - Uncalibrated");
194 colNames.emplace_back(
"double",
"TZERO");
197 colNames.emplace_back(
"V3D",
"Position");
203 for (
size_t col = 0; col < colNames.size(); ++col) {
204 auto column =
table->addColumn(colNames.at(col).first, colNames.at(col).second);
206 column->setPlotType(0);
225 theta *= 180.0 / M_PI;
226 }
catch (
const std::exception &ex) {
244 std::set<int> timeIndexSet;
246 timeIndexSet.insert(
int(def.second));
266 }
catch (std::runtime_error &) {
283 difa = diffConsts[UnitParams::difa];
284 difc = diffConsts[UnitParams::difc];
286 tzero = diffConsts[UnitParams::tzero];
290 size_t columnIndex = 0;
326 const auto firstSpectraWithDetectors =
328 [
this](
const auto idx) { return spectrumInfo->hasDetectors(static_cast<size_t>(idx)); });
332 const std::vector<std::string> ¶meters =
spectrumInfo->
detector(
static_cast<size_t>(*firstSpectraWithDetectors))
334 return (!parameters.empty() && find(parameters.begin(), parameters.end(),
"Always") != parameters.end());
342 throw std::runtime_error(
"No detectors found.");
345 data.
wsIndex =
static_cast<int>(wsIndex);
347 auto &spectrum =
ws->getSpectrum(wsIndex);
348 data.
specNo = spectrum.getSpectrumNo();
349 data.
detIds =
dynamic_cast<const std::set<int> &
>(spectrum.getDetectorIDs());
358 data.
q =
getQ(wsIndex);
376 auto wsIndex =
static_cast<size_t>(
workspaceIndices[
static_cast<size_t>(row)]);
382 }
catch (
const std::exception &) {
384 errorData.
wsIndex =
static_cast<int>(wsIndex);
388 errorData.
dataY0 =
ws->y(wsIndex)[0];
389 errorData.
dataE0 =
ws->e(wsIndex)[0];
400 std::unordered_map<int, size_t> detIdToRow;
402 detIdToRow.reserve(wsDetIds.size());
403 for (
size_t r = 0; r < wsDetIds.size(); ++r)
404 detIdToRow[wsDetIds[r]] = r;
406 std::vector<DetectorRowData> rowData(wsDetIds.size());
410 std::vector<uint8_t> writtenToRow(wsDetIds.size(), 0);
416 auto wsIndex =
static_cast<size_t>(
workspaceIndices[
static_cast<size_t>(i)]);
423 }
catch (
const std::exception &) {
424 data.
wsIndex =
static_cast<int>(wsIndex);
433 auto detIds =
dynamic_cast<const std::set<int> &
>(
ws->getSpectrum(wsIndex).getDetectorIDs());
434 for (
int detId : detIds) {
435 auto it = detIdToRow.find(detId);
436 if (it != detIdToRow.end()) {
437 rowData[it->second] = data;
438 rowData[it->second].
detIds = {detId};
439 writtenToRow[it->second] =
true;
449 table->setRowCount(workspaceDetectorIds.size());
450 for (
int i = 0; i < static_cast<int>(rowData.size()); ++i) {
451 if (writtenToRow[i]) {
457 errorData.
detIds = {wsDetIds[i]};
477 std::string truncated;
478 size_t ndets = elements.size();
479 auto iter = elements.begin();
480 auto itEnd = elements.end();
484 auto revIter = elements.rbegin();
488 for (; iter != itEnd; ++iter) {
492 if (!truncated.empty()) {
493 truncated.pop_back();
#define DECLARE_ALGORITHM(classname)
std::map< DeltaEMode::Type, std::string > index
#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.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void setPropertyValue(const std::string &name, const std::string &value) override
Set the value of a property by string N.B.
Show a property as enabled when the workspace pointed to by another is of a given type.
double signedTwoTheta(const size_t index) const
Returns the signed scattering angle 2 theta in radians (angle w.r.t.
bool isMonitor(const size_t index) const
Returns true if the detector(s) associated with the spectrum are monitors.
Kernel::UnitParametersMap diffractometerConstants(const size_t index, std::vector< detid_t > &uncalibratedDets) const
Calculate average diffractometer constants (DIFA, DIFC, TZERO) of detectors associated with this spec...
bool hasDetectors(const size_t index) const
Returns true if the spectrum is associated with detectors in the instrument.
detid_t firstDetectorID(const size_t index) const
Returns the detector ID of the first detector of the spectrum with given index.
double twoTheta(const size_t index) const
Returns the scattering angle 2 theta in radians (angle w.r.t.
double difcUncalibrated(const size_t index) const
Calculate average uncalibrated DIFC value of detectors associated with this spectrum.
Kernel::V3D position(const size_t index) const
Returns the position of the spectrum with given index.
double l2(const size_t index) const
Returns L2 (distance from sample to spectrum).
const SpectrumDefinition & spectrumDefinition(const size_t index) const
Returns a const reference to the SpectrumDefinition of the spectrum.
const Geometry::IDetector & detector(const size_t index) const
Return a const reference to the detector or detector group of the spectrum with given index.
A property class for workspaces.
void populateTableByDetID()
API::MatrixWorkspace_sptr ws
void setup()
Creates table workspace of detector information from a given workspace.
void exec() override
Execution code.
Geometry::PointingAlong beamAxisIndex
const std::string getTimeIndexes(size_t wsIndex)
bool includeDetectorPosition
void writeRowToTable(const int row, const DetectorRowData &data)
void getSphericalCoordinates(size_t wsIndex, double &R, double &theta, double &phi)
double getQ(size_t wsIndex)
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
const API::SpectrumInfo * spectrumInfo
std::vector< API::Column_sptr > m_columnCache
API::ITableWorkspace_sptr table
DetectorRowData calculateWsIdxData(size_t wsIndex)
void getDiffConst(size_t wsIndex, double &difa, double &difc, double &difcUnc, double &tzero)
bool retrieveSignedThetaParameter()
const Geometry::DetectorInfo * detectorInfo
std::vector< int > workspaceIndices
const std::vector< detid_t > & detectorIDs() const
Returns a sorted vector of all detector IDs.
virtual std::vector< std::string > getStringParameter(const std::string &pname, bool recursive=true) const =0
Get a parameter defined as a string.
Support for a property that holds an array of values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void error(const std::string &msg)
Logs at error level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
static double convertToElasticQ(const double theta, const double efixed)
Convert to ElasticQ from Energy.
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::string createTruncatedList(const std::set< int > &elements)
Converts a list to a string, shortened if necessary.
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.
int32_t detid_t
Typedef for a detector ID.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
@ Output
An output workspace.