35 if (descriptor.hasRootAttr(
"sassena_version") || descriptor.isEntry(
"/qvectors")) {
52 API::AnalysisDataService::Instance().add(wsName, ws);
53 gws->addWorkspace(ws);
64 h5file.openDataSet(setName).getSpace().getSimpleExtentDims(dims);
79using mypair = std::pair<double, int>;
93 std::vector<int> &sorting_indexes) {
96 std::vector<double> qvmod;
99 const std::string setName(
"qvectors");
104 }
catch (H5::Exception &) {
108 auto nq =
static_cast<int>(dims[0]);
109 std::vector<double> buf(nq * 3);
113 }
catch (H5::Exception &) {
114 this->
g_log.
error(
"LoadSassena::loadQvectors cannot proceed");
116 return HistogramData::Points(std::move(qvmod));
120 for (
auto curr = buf.cbegin(); curr != buf.cend(); curr += 3) {
121 qvmod.emplace_back(sqrt(curr[0] * curr[0] + curr[1] * curr[1] + curr[2] * curr[2]));
125 std::vector<mypair> qvmodpair;
126 qvmodpair.reserve(nq);
127 for (
int iq = 0; iq < nq; iq++)
128 qvmodpair.emplace_back(qvmod[iq], iq);
129 std::sort(qvmodpair.begin(), qvmodpair.end(),
compare);
130 for (
int iq = 0; iq < nq; iq++)
131 sorting_indexes.emplace_back(qvmodpair[iq].second);
132 std::sort(qvmod.begin(), qvmod.end());
134 for (
int iq = 0; iq < nq; iq++)
135 sorting_indexes.emplace_back(iq);
139 std::string wsName = gwsName + std::string(
"_") + setName;
140 ws->setTitle(wsName);
142 for (
int iq = 0; iq < nq; iq++) {
143 auto &
Y = ws->mutableY(iq);
144 auto curr = std::next(buf.cbegin(), 3 * sorting_indexes[iq]);
145 Y.assign(curr, std::next(curr, 3));
148 ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create(
"MomentumTransfer");
150 this->
registerWorkspace(gws, wsName, ws,
"X-axis: origin of Q-vectors; Y-axis: tip of Q-vectors");
151 return HistogramData::Points(std::move(qvmod));
166 const HistogramData::Points &qvmod,
const std::vector<int> &sorting_indexes) {
168 auto nq =
static_cast<int>(qvmod.size());
169 std::vector<double> buf(nq * 2);
172 }
catch (H5::Exception &) {
173 this->
g_log.
error(
"LoadSassena::loadFQ cannot proceed");
181 const std::string wsName = gwsName + std::string(
"_") + setName;
182 ws->setTitle(wsName);
184 auto &re = ws->mutableY(0);
185 ws->setPoints(0, qvmod);
186 auto &im = ws->mutableY(1);
187 ws->setPoints(1, qvmod);
189 for (
int iq = 0; iq < nq; ++iq) {
190 auto curr = std::next(buf.cbegin(), 2 * sorting_indexes[iq]);
192 im[iq] = *std::next(curr);
196 ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create(
"MomentumTransfer");
198 this->
registerWorkspace(gws, wsName, ws,
"X-axis: Q-vector modulus; Y-axis: intermediate structure factor");
215 const HistogramData::Points &qvmod,
const std::vector<int> &sorting_indexes) {
220 }
catch (H5::Exception &) {
221 this->
g_log.
error(
"Unable to read " + setName +
" dataset info");
222 this->
g_log.
error(
"LoadSassena::loadFQT cannot proceed");
225 auto nnt =
static_cast<int>(dims[1]);
226 int nt = 2 * nnt - 1;
228 auto nq =
static_cast<int>(qvmod.size());
229 std::vector<double> buf(nq * nnt * 2);
232 }
catch (H5::Exception &) {
233 this->
g_log.
error(
"LoadSassena::loadFQT cannot proceed");
241 const std::string wsReName = gwsName + std::string(
"_") + setName + std::string(
".Re");
242 wsRe->setTitle(wsReName);
246 const std::string wsImName = gwsName + std::string(
"_") + setName + std::string(
".Im");
247 wsIm->setTitle(wsImName);
249 int origin = nnt - 1;
250 for (
int iq = 0; iq < nq; iq++) {
251 auto &reX = wsRe->mutableX(iq);
252 auto &imX = wsIm->mutableX(iq);
253 auto &reY = wsRe->mutableY(iq);
254 auto &imY = wsIm->mutableY(iq);
255 const int index = sorting_indexes[iq];
256 auto curr = std::next(buf.cbegin(),
index * nnt * 2);
257 for (
int it = 0; it < nnt; it++) {
258 reX[origin + it] = it * dt;
259 reY[origin + it] = *curr;
260 reX[origin - it] = -it * dt;
261 reY[origin - it] = *curr;
263 imX[origin + it] = it * dt;
264 imY[origin + it] = *curr;
265 imX[origin - it] = -it * dt;
266 imY[origin - it] = -(*curr);
272 wsRe->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create(
"Label");
273 auto unitPtr = std::dynamic_pointer_cast<Kernel::Units::Label>(wsRe->getAxis(0)->unit());
274 unitPtr->setLabel(
"Time",
"picoseconds");
276 wsIm->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create(
"Label");
277 unitPtr = std::dynamic_pointer_cast<Kernel::Units::Label>(wsIm->getAxis(0)->unit());
278 unitPtr->setLabel(
"Time",
"picoseconds");
281 auto verticalAxisRe = std::make_unique<API::NumericAxis>(nq);
282 auto verticalAxisIm = std::make_unique<API::NumericAxis>(nq);
283 auto verticalAxisReRaw = verticalAxisRe.get();
284 auto verticalAxisImRaw = verticalAxisIm.get();
285 wsRe->replaceAxis(1, std::move(verticalAxisRe));
286 wsIm->replaceAxis(1, std::move(verticalAxisIm));
289 for (
int i = 0; i < nq; ++i) {
290 verticalAxisReRaw->setValue(i, qvmod[i]);
291 verticalAxisImRaw->setValue(i, qvmod[i]);
295 verticalAxisReRaw->unit() = Kernel::UnitFactory::Instance().create(
"MomentumTransfer");
296 verticalAxisReRaw->title() =
"|Q|";
297 verticalAxisImRaw->unit() = Kernel::UnitFactory::Instance().create(
"MomentumTransfer");
298 verticalAxisImRaw->title() =
"|Q|";
301 wsRe->getAxis(0)->title() =
"Energy transfer";
302 wsIm->getAxis(0)->title() =
"Energy transfer";
305 registerWorkspace(gws, wsReName, wsRe,
"X-axis: time; Y-axis: real part of intermediate structure factor");
306 registerWorkspace(gws, wsImName, wsIm,
"X-axis: time; Y-axis: imaginary part of intermediate structure factor");
317 const std::vector<std::string> exts{
".h5",
".hd5"};
322 "The name of the group workspace to be created.");
324 "The Time unit in between data points, in picoseconds. "
325 "Default is 1.0 picosec.");
327 "Sort structure factors by increasing momentum transfer?");
340 if (gws && API::AnalysisDataService::Instance().doesExist(gws->getName())) {
342 API::AnalysisDataService::Instance().deepRemoveGroup(gws->getName());
344 gws = std::make_shared<API::WorkspaceGroup>();
345 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<API::Workspace>(gws));
350 const char *validSets[] = {
"fq",
"fq0",
"fq2",
"fqt"};
351 for (
int iSet = 0; iSet < nvalidSets; iSet++)
359 }
catch (H5::FileIException &) {
365 std::vector<int> sorting_indexes;
366 const auto qvmod = this->
loadQvectors(h5file, gws, sorting_indexes);
368 this->
g_log.
error(
"No Q-vectors read. Unable to proceed");
374 for (std::vector<std::string>::const_iterator it = this->
m_validSets.begin(); it != this->
m_validSets.end(); ++it) {
375 std::string setName = *it;
376 if (h5file.nameExists(setName)) {
377 if (setName ==
"fq" || setName ==
"fq0" || setName ==
"fq2")
378 this->
loadFQ(h5file, gws, setName, qvmod, sorting_indexes);
379 else if (setName ==
"fqt")
380 this->
loadFQT(h5file, gws, setName, qvmod, sorting_indexes);
std::map< DeltaEMode::Type, std::string > index
#define DECLARE_NEXUS_FILELOADER_ALGORITHM(classname)
DECLARE_NEXUS_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro wh...
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
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.
@ Load
allowed here which will be passed to the algorithm
A property class for workspaces.
Load Sassena Output files.
std::string m_filename
name and path of input file
std::vector< std::string > m_validSets
valid datasets
void init() override
Initialization code.
void dataSetDouble(const H5::H5File &h5file, const std::string &setName, std::vector< double > &buf)
Read dataset data to a buffer ot type double.
void exec() override
Execution code.
HistogramData::Points loadQvectors(const H5::H5File &h5file, const API::WorkspaceGroup_sptr &gws, std::vector< int > &sorting_indexes)
Load qvectors dataset, calculate modulus of vectors.
void dataSetInfo(const H5::H5File &h5file, const std::string &setName, hsize_t *dims) const
Read info about one HDF5 dataset, log if error.
void registerWorkspace(const API::WorkspaceGroup_sptr &gws, const std::string &wsName, const DataObjects::Workspace2D_sptr &ws, const std::string &description)
Add a workspace to the group and register in the analysis data service.
void loadFQT(const H5::H5File &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, const HistogramData::Points &qvmod, const std::vector< int > &sorting_indexes)
Load time-dependent structure factor.
void loadFQ(const H5::H5File &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, const HistogramData::Points &qvmod, const std::vector< int > &sorting_indexes)
Load structure factor asa function of q-vector modulus.
Records the filename and the description of failure.
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.
void information(const std::string &msg)
Logs at information level.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::pair< double, int > mypair
bool compare(const mypair &left, const mypair &right)
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
MANTID_NEXUS_DLL H5::FileAccPropList defaultFileAcc()
Default file access is H5F_CLOSE_STRONG.
void readArray1DCoerce(const H5::Group &group, const std::string &name, std::vector< NumT > &output)
@ Input
An input workspace.
@ Output
An output workspace.