36 if (descriptor.hasRootAttr(
"sassena_version") || descriptor.pathExists(
"/qvectors")) {
54 gws->addWorkspace(ws);
67 herr_t errorcode = H5LTget_dataset_info(h5file, setName.c_str(), dims, &class_id, &type_size);
69 g_log.
error(
"Unable to read " + setName +
" dataset info");
81 herr_t errorcode = H5LTread_dataset_double(h5file, setName.c_str(), buf.data());
83 this->
g_log.
error(
"Cannot read " + setName +
" dataset");
90using mypair = std::pair<double, int>;
104 std::vector<int> &sorting_indexes) {
107 std::vector<double> qvmod;
110 const std::string setName(
"qvectors");
116 auto nq =
static_cast<int>(dims[0]);
117 std::vector<double> buf(nq * 3);
119 herr_t errorcode = this->
dataSetDouble(h5file,
"qvectors", buf);
121 this->
g_log.
error(
"LoadSassena::loadQvectors cannot proceed");
123 return HistogramData::Points(std::move(qvmod));
127 for (
auto curr = buf.cbegin(); curr != buf.cend(); curr += 3) {
128 qvmod.emplace_back(sqrt(curr[0] * curr[0] + curr[1] * curr[1] + curr[2] * curr[2]));
132 std::vector<mypair> qvmodpair;
133 qvmodpair.reserve(nq);
134 for (
int iq = 0; iq < nq; iq++)
135 qvmodpair.emplace_back(qvmod[iq], iq);
136 std::sort(qvmodpair.begin(), qvmodpair.end(),
compare);
137 for (
int iq = 0; iq < nq; iq++)
138 sorting_indexes.emplace_back(qvmodpair[iq].second);
139 std::sort(qvmod.begin(), qvmod.end());
141 for (
int iq = 0; iq < nq; iq++)
142 sorting_indexes.emplace_back(iq);
146 std::string wsName = gwsName + std::string(
"_") + setName;
147 ws->setTitle(wsName);
149 for (
int iq = 0; iq < nq; iq++) {
150 auto &
Y = ws->mutableY(iq);
151 auto curr = std::next(buf.cbegin(), 3 * sorting_indexes[iq]);
152 Y.assign(curr, std::next(curr, 3));
157 this->
registerWorkspace(gws, wsName, ws,
"X-axis: origin of Q-vectors; Y-axis: tip of Q-vectors");
158 return HistogramData::Points(std::move(qvmod));
173 const HistogramData::Points &qvmod,
const std::vector<int> &sorting_indexes) {
175 auto nq =
static_cast<int>(qvmod.size());
176 std::vector<double> buf(nq * 2);
177 herr_t errorcode = this->
dataSetDouble(h5file, setName, buf);
179 this->
g_log.
error(
"LoadSassena::loadFQ cannot proceed");
187 const std::string wsName = gwsName + std::string(
"_") + setName;
188 ws->setTitle(wsName);
190 auto &re = ws->mutableY(0);
191 ws->setPoints(0, qvmod);
192 auto &im = ws->mutableY(1);
193 ws->setPoints(1, qvmod);
195 for (
int iq = 0; iq < nq; ++iq) {
196 auto curr = std::next(buf.cbegin(), 2 * sorting_indexes[iq]);
198 im[iq] = *std::next(curr);
204 this->
registerWorkspace(gws, wsName, ws,
"X-axis: Q-vector modulus; Y-axis: intermediate structure factor");
221 const HistogramData::Points &qvmod,
const std::vector<int> &sorting_indexes) {
225 this->
g_log.
error(
"Unable to read " + setName +
" dataset info");
226 this->
g_log.
error(
"LoadSassena::loadFQT cannot proceed");
229 auto nnt =
static_cast<int>(dims[1]);
230 int nt = 2 * nnt - 1;
232 auto nq =
static_cast<int>(qvmod.size());
233 std::vector<double> buf(nq * nnt * 2);
234 herr_t errorcode = this->
dataSetDouble(h5file, setName, buf);
236 this->
g_log.
error(
"LoadSassena::loadFQT cannot proceed");
244 const std::string wsReName = gwsName + std::string(
"_") + setName + std::string(
".Re");
245 wsRe->setTitle(wsReName);
249 const std::string wsImName = gwsName + std::string(
"_") + setName + std::string(
".Im");
250 wsIm->setTitle(wsImName);
252 int origin = nnt - 1;
253 for (
int iq = 0; iq < nq; iq++) {
254 auto &reX = wsRe->mutableX(iq);
255 auto &imX = wsIm->mutableX(iq);
256 auto &reY = wsRe->mutableY(iq);
257 auto &imY = wsIm->mutableY(iq);
258 const int index = sorting_indexes[iq];
259 auto curr = std::next(buf.cbegin(),
index * nnt * 2);
260 for (
int it = 0; it < nnt; it++) {
261 reX[origin + it] = it * dt;
262 reY[origin + it] = *curr;
263 reX[origin - it] = -it * dt;
264 reY[origin - it] = *curr;
266 imX[origin + it] = it * dt;
267 imY[origin + it] = *curr;
268 imX[origin - it] = -it * dt;
269 imY[origin - it] = -(*curr);
276 auto unitPtr = std::dynamic_pointer_cast<Kernel::Units::Label>(wsRe->getAxis(0)->unit());
277 unitPtr->setLabel(
"Time",
"picoseconds");
280 unitPtr = std::dynamic_pointer_cast<Kernel::Units::Label>(wsIm->getAxis(0)->unit());
281 unitPtr->setLabel(
"Time",
"picoseconds");
284 auto verticalAxisRe = std::make_unique<API::NumericAxis>(nq);
285 auto verticalAxisIm = std::make_unique<API::NumericAxis>(nq);
286 auto verticalAxisReRaw = verticalAxisRe.get();
287 auto verticalAxisImRaw = verticalAxisIm.get();
288 wsRe->replaceAxis(1, std::move(verticalAxisRe));
289 wsIm->replaceAxis(1, std::move(verticalAxisIm));
292 for (
int i = 0; i < nq; ++i) {
293 verticalAxisReRaw->setValue(i, qvmod[i]);
294 verticalAxisImRaw->setValue(i, qvmod[i]);
299 verticalAxisReRaw->title() =
"|Q|";
301 verticalAxisImRaw->title() =
"|Q|";
304 wsRe->getAxis(0)->title() =
"Energy transfer";
305 wsIm->getAxis(0)->title() =
"Energy transfer";
308 registerWorkspace(gws, wsReName, wsRe,
"X-axis: time; Y-axis: real part of intermediate structure factor");
309 registerWorkspace(gws, wsImName, wsIm,
"X-axis: time; Y-axis: imaginary part of intermediate structure factor");
320 const std::vector<std::string> exts{
".h5",
".hd5"};
325 "The name of the group workspace to be created.");
327 "The Time unit in between data points, in picoseconds. "
328 "Default is 1.0 picosec.");
330 "Sort structure factors by increasing momentum transfer?");
347 gws = std::make_shared<API::WorkspaceGroup>();
348 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<API::Workspace>(gws));
353 const char *validSets[] = {
"fq",
"fq0",
"fq2",
"fqt"};
354 for (
int iSet = 0; iSet < nvalidSets; iSet++)
359 hid_t h5file = H5Fopen(
m_filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
367 if (H5LTget_attribute_string(h5file,
"/",
"sassena_version", cversion) < 0) {
368 this->
g_log.
error(
"Unable to read Sassena version");
375 std::vector<int> sorting_indexes;
376 const auto qvmod = this->
loadQvectors(h5file, gws, sorting_indexes);
378 this->
g_log.
error(
"No Q-vectors read. Unable to proceed");
385 for (std::vector<std::string>::const_iterator it = this->
m_validSets.begin(); it != this->m_validSets.end(); ++it) {
387 if (H5Lexists(h5file, setName.c_str(), H5P_DEFAULT)) {
388 if (setName ==
"fq" || setName ==
"fq0" || setName ==
"fq2")
389 this->
loadFQ(h5file, gws, setName, qvmod, sorting_indexes);
390 else if (setName ==
"fqt")
391 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.
void loadFQT(const hid_t &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.
std::string m_filename
name and path of input file
HistogramData::Points loadQvectors(const hid_t &h5file, const API::WorkspaceGroup_sptr &gws, std::vector< int > &sorting_indexes)
Load qvectors dataset, calculate modulus of vectors.
std::vector< std::string > m_validSets
valid datasets
void init() override
Initialization code.
void exec() override
Execution code.
void loadFQ(const hid_t &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.
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.
herr_t dataSetInfo(const hid_t &h5file, const std::string &setName, hsize_t *dims) const
Read info about one HDF5 dataset, log if error.
herr_t dataSetDouble(const hid_t &h5file, const std::string &setName, std::vector< double > &buf)
Read dataset data to a buffer ot type double.
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.
Defines a wrapper around a file whose internal structure can be accessed using the NeXus API.
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
Kernel::Logger g_log("ExperimentInfo")
static logger object
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.
@ Input
An input workspace.
@ Output
An output workspace.