Mantid
Loading...
Searching...
No Matches
Transpose.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
15
16namespace Mantid::Algorithms {
17
18// Register the algorithm into the AlgorithmFactory
19DECLARE_ALGORITHM(Transpose)
20
21using namespace Kernel;
22using namespace API;
23
25 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input,
26 std::make_shared<CommonBinsValidator>()),
27 "The input workspace.");
28 declareProperty(std::make_unique<WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output),
29 "The output workspace.");
30}
31
33 MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
34 MatrixWorkspace_sptr outputWorkspace = createOutputWorkspace(inputWorkspace);
35
36 // Things to take care of RebinnedOutput workspaces
38 std::dynamic_pointer_cast<const DataObjects::RebinnedOutput>(inputWorkspace);
39 DataObjects::RebinnedOutput_sptr outRebinWorkspace =
40 std::dynamic_pointer_cast<DataObjects::RebinnedOutput>(outputWorkspace);
41
42 size_t newNhist = outputWorkspace->getNumberHistograms();
43 size_t newXsize = outputWorkspace->x(0).size();
44 size_t newYsize = outputWorkspace->blocksize();
45
46 // Create a shareable X vector for the output workspace
47 Axis *inputYAxis = getVerticalAxis(inputWorkspace);
48 std::vector<double> newXValues(newXsize);
49 for (size_t i = 0; i < newXsize; ++i) {
50 newXValues[i] = (*inputYAxis)(i);
51 }
52 auto newXVector = Kernel::make_cow<HistogramData::HistogramX>(std::move(newXValues));
53
54 Progress progress(this, 0.0, 1.0, newNhist * newYsize);
55 progress.report("Swapping data values");
56 PARALLEL_FOR_IF(Kernel::threadSafe(*inputWorkspace, *outputWorkspace))
57 for (int64_t i = 0; i < static_cast<int64_t>(newNhist); ++i) {
59
60 outputWorkspace->setSharedX(i, newXVector);
61
62 auto &outY = outputWorkspace->mutableY(i);
63 auto &outE = outputWorkspace->mutableE(i);
64
65 // because setF wants a COW pointer
67 std::vector<double> &outF = F.access();
68
69 if (outRebinWorkspace) {
70 outF.resize(newYsize);
71 }
72
73 for (int64_t j = 0; j < int64_t(newYsize); ++j) {
74 progress.report();
75 outY[j] = inputWorkspace->y(j)[i];
76 outE[j] = inputWorkspace->e(j)[i];
77 if (outRebinWorkspace) {
78 outF[j] = inRebinWorkspace->dataF(j)[i];
79 }
80 }
81 if (outRebinWorkspace) {
82 outRebinWorkspace->setF(i, F);
83 }
84
86 }
88}
89
96 Mantid::API::Axis *yAxis = getVerticalAxis(inputWorkspace);
97 const size_t oldNhist = inputWorkspace->getNumberHistograms();
98 const auto &inX = inputWorkspace->x(0);
99 const size_t oldYlength = inputWorkspace->blocksize();
100 const size_t oldVerticalAxislength = yAxis->length();
101
102 // The input Y axis may be binned so the new X data should be too
103 size_t newNhist(oldYlength), newXsize(oldVerticalAxislength), newYsize(oldNhist);
104 MatrixWorkspace_sptr outputWorkspace = inputWorkspace->cloneEmpty();
105 outputWorkspace->initialize(newNhist, newXsize, newYsize);
106 outputWorkspace->setTitle(inputWorkspace->getTitle());
107 outputWorkspace->setComment(inputWorkspace->getComment());
108 outputWorkspace->copyExperimentInfoFrom(inputWorkspace.get());
109 outputWorkspace->setYUnit(inputWorkspace->YUnit());
110 outputWorkspace->setYUnitLabel(inputWorkspace->YUnitLabel());
111 outputWorkspace->setDistribution(inputWorkspace->isDistribution());
112
113 // Create a new numeric axis for Y the same length as the old X array
114 // Values come from input X
115 std::unique_ptr<API::NumericAxis> newYAxis(nullptr);
116 if (inputWorkspace->isHistogramData()) {
117 newYAxis = std::make_unique<API::BinEdgeAxis>(inX.rawData());
118 } else {
119 newYAxis = std::make_unique<API::NumericAxis>(inX.rawData());
120 }
121
122 newYAxis->unit() = inputWorkspace->getAxis(0)->unit();
123 outputWorkspace->getAxis(0)->unit() = inputWorkspace->getAxis(1)->unit();
124 outputWorkspace->replaceAxis(1, std::move(newYAxis));
125 setProperty("OutputWorkspace", outputWorkspace);
126 return outputWorkspace;
127}
128
135 API::Axis *yAxis;
136 try {
137 yAxis = workspace->getAxis(1);
139 throw std::invalid_argument("Axis(1) not found on input workspace.");
140 }
141 // Can't put text in dataX
142 if (yAxis->isText()) {
143 throw std::invalid_argument("Axis(1) is a text axis. Transpose is unable to cope with text axes.");
144 }
145 return yAxis;
146}
147
148} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
#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...
Definition: MultiThreaded.h:94
#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.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
Class to represent the axis of a workspace.
Definition: Axis.h:30
virtual bool isText() const
Returns true if the axis is Text.
Definition: Axis.h:54
virtual std::size_t length() const =0
Get the length of the axis.
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A property class for workspaces.
void init() override
Initialisation code.
Definition: Transpose.cpp:24
API::MatrixWorkspace_sptr createOutputWorkspace(const API::MatrixWorkspace_const_sptr &inputWorkspace)
Create the output workspace.
Definition: Transpose.cpp:95
void exec() override
Execution code.
Definition: Transpose.cpp:32
API::Axis * getVerticalAxis(const API::MatrixWorkspace_const_sptr &workspace) const
Return the vertical axis on the workspace, throwing if it is not valid.
Definition: Transpose.cpp:134
Exception for index errors.
Definition: Exception.h:284
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
Implements a copy on write data template.
Definition: cow_ptr.h:41
DataType & access()
Access function.
Definition: cow_ptr.h:147
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 RebinnedOutput > RebinnedOutput_const_sptr
shared pointer to a const RebinnedOutput
std::shared_ptr< RebinnedOutput > RebinnedOutput_sptr
shared pointer to the RebinnedOutput class
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.
Definition: MultiThreaded.h:22
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54