-
Notifications
You must be signed in to change notification settings - Fork 122
/
ConvertPeaksWorkspace.cpp
171 lines (147 loc) · 6.19 KB
/
ConvertPeaksWorkspace.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2021 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidCrystal/ConvertPeaksWorkspace.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/Run.h"
#include "MantidAPI/Sample.h"
#include "MantidDataObjects/LeanElasticPeak.h"
#include "MantidDataObjects/LeanElasticPeaksWorkspace.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidGeometry/Instrument/Goniometer.h"
#include "MantidKernel/Logger.h"
namespace Mantid::Crystal {
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
using namespace Mantid::Kernel;
/// Config logger
namespace {
Logger logger("ConvertPeaksWorkspace");
}
DECLARE_ALGORITHM(ConvertPeaksWorkspace)
/**
* @brief initialization of alg
*
*/
void ConvertPeaksWorkspace::init() {
// Input peakworkspace
declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>("PeakWorkspace", "", Direction::Input),
"Workspace of Indexed Peaks");
// donor workspace if going from lean to regular
declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("InstrumentWorkspace", "", Direction::Input,
PropertyMode::Optional),
"Donor Workspace with instrument for conversion");
// output
declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>("OutputWorkspace", "", Direction::Output),
"Converted Workspaces");
}
/**
* @brief Inputs validation
*
* @return std::map<std::string, std::string>
*/
std::map<std::string, std::string> ConvertPeaksWorkspace::validateInputs() {
std::map<std::string, std::string> issues;
IPeaksWorkspace_sptr ipws = getProperty("PeakWorkspace");
PeaksWorkspace_sptr pws = std::dynamic_pointer_cast<PeaksWorkspace>(ipws);
LeanElasticPeaksWorkspace_sptr lpws = std::dynamic_pointer_cast<LeanElasticPeaksWorkspace>(ipws);
if (lpws && !pws) {
// case I: missing instrument when converting to PeaksWorkspace
if (getPointerToProperty("InstrumentWorkspace")->isDefault()) {
issues["InstrumentWorkspace"] = "Need a PeaksWorkspace with proper instrument attached to assist conversion.";
}
// case II: instrument cannot be found within donor workspace
else {
Workspace_sptr ws = getProperty("InstrumentWorkspace");
ExperimentInfo_sptr inputExperimentInfo = std::dynamic_pointer_cast<ExperimentInfo>(ws);
if (!inputExperimentInfo) {
issues["InstrumentWorkspace"] = "Invalid instrument found in donor workspace.";
}
}
}
return issues;
}
/**
* @brief Algorithm entrance func
*
*/
void ConvertPeaksWorkspace::exec() {
// parsing input
IPeaksWorkspace_sptr ipws = getProperty("PeakWorkspace");
PeaksWorkspace_sptr pws = std::dynamic_pointer_cast<PeaksWorkspace>(ipws);
LeanElasticPeaksWorkspace_sptr lpws = std::dynamic_pointer_cast<LeanElasticPeaksWorkspace>(ipws);
// decide which route to take
if (pws && !lpws) {
g_log.notice() << "PeaksWorkspace -> LeanElasticPeaksWorkspace\n";
IPeaksWorkspace_sptr outpws = makeLeanElasticPeaksWorkspace(ipws);
setProperty("OutputWorkspace", outpws);
} else {
g_log.notice() << "LeanElasticPeaksWorkspace -> PeaksWorkspace\n";
Workspace_sptr ws = getProperty("InstrumentWorkspace");
IPeaksWorkspace_sptr outpws = makePeaksWorkspace(ipws, ws);
setProperty("OutputWorkspace", outpws);
}
// cleanup
}
/**
* @brief make a LeanElasticPeaksWorkspace using peaks from a regular PeaksWorkspace
*
* @param ipws input PeaksWorkspace as IPeaksWorkspace_sptr
* @return IPeaksWorkspace_sptr
*/
IPeaksWorkspace_sptr ConvertPeaksWorkspace::makeLeanElasticPeaksWorkspace(const IPeaksWorkspace_sptr &ipws) {
// prep
PeaksWorkspace_sptr pws = std::dynamic_pointer_cast<PeaksWorkspace>(ipws);
LeanElasticPeaksWorkspace_sptr lpws = std::make_shared<LeanElasticPeaksWorkspace>();
ExperimentInfo_sptr inputExperimentInfo = std::dynamic_pointer_cast<ExperimentInfo>(ipws);
lpws->copyExperimentInfoFrom(inputExperimentInfo.get());
// down casting Peaks to LeanElasticPeaks
for (int i = 0; i < pws->getNumberPeaks(); ++i) {
LeanElasticPeak lpk(pws->getPeak(i));
lpws->addPeak(lpk);
}
//
IPeaksWorkspace_sptr outpws = std::dynamic_pointer_cast<IPeaksWorkspace>(lpws);
return outpws;
}
/**
* @brief Build a regular PeaksWorkspace using peaks from a LeanElasticPeaksWorkspace and the provided instrument
*
* @param ipws input LeanElasticPeaksWorkspace as IPeaksWorkspace_sptr
* @param ws donor PeaksWorkspace to provide instrument and ExperimentInfo
* @return IPeaksWorkspace_sptr
*/
IPeaksWorkspace_sptr ConvertPeaksWorkspace::makePeaksWorkspace(const IPeaksWorkspace_sptr &ipws,
const Workspace_sptr &ws) {
// prep
LeanElasticPeaksWorkspace_sptr lpws = std::dynamic_pointer_cast<LeanElasticPeaksWorkspace>(ipws);
PeaksWorkspace_sptr pws = std::make_shared<PeaksWorkspace>();
// Instrument_const_sptr inst = ws->getInstrument();
ExperimentInfo_sptr inputExperimentInfo = std::dynamic_pointer_cast<ExperimentInfo>(ws);
pws->copyExperimentInfoFrom(inputExperimentInfo.get());
Instrument_const_sptr inst = inputExperimentInfo->getInstrument();
// up casting LeanElasticPeaks to Peaks
for (int i = 0; i < lpws->getNumberPeaks(); ++i) {
// NOTE:
// This try-catch block here
// - For cases where incorrect goniometer settings leads to a negative wavelength.
// - Have a slightly negative impact on runtime. For example, with a testing pws with 7k peaks
// - with try-catch: runtime ~ 50s
// - without try-catch: runtime ~ 38s
try {
Peak pk(lpws->getPeak(i), inst);
pws->addPeak(pk);
} catch (const std::invalid_argument &errmsg) {
g_log.warning() << errmsg.what() << "\n";
}
}
//
IPeaksWorkspace_sptr outpws = std::dynamic_pointer_cast<IPeaksWorkspace>(pws);
return outpws;
}
} // namespace Mantid::Crystal