13#include <Poco/String.h>
14#include <Poco/TemporaryFile.h>
39 {
"Calibration",
"Bm1Counts",
TYPE_INT},
42 {
"Velocity Selector and Choppers",
"MasterChopperFreq",
TYPE_DBL},
43 {
"Velocity Selector and Choppers",
"T0ChopperFreq",
TYPE_DBL},
44 {
"Velocity Selector and Choppers",
"T0ChopperPhase",
TYPE_DBL},
45 {
"Velocity Selector and Choppers",
"FrameSource",
TYPE_STR},
46 {
"Velocity Selector and Choppers",
"Wavelength",
TYPE_DBL},
49 {
"Geometry Setup",
"LTofDet",
TYPE_DBL},
50 {
"Geometry Setup",
"L2Det",
TYPE_DBL},
52 {
"Geometry Setup",
"L2CurtainL",
TYPE_DBL},
53 {
"Geometry Setup",
"L2CurtainR",
TYPE_DBL},
54 {
"Geometry Setup",
"L2CurtainU",
TYPE_DBL},
55 {
"Geometry Setup",
"L2CurtainD",
TYPE_DBL},
57 {
"Geometry Setup",
"CurtainL",
TYPE_DBL},
58 {
"Geometry Setup",
"CurtainR",
TYPE_DBL},
59 {
"Geometry Setup",
"CurtainU",
TYPE_DBL},
60 {
"Geometry Setup",
"CurtainD",
TYPE_DBL},
71 }
catch (std::runtime_error &) {
79 }
catch (std::runtime_error &) {
91 std::vector<std::string> exts;
96 exts.emplace_back(
".tar");
98 "The filename of the stored data to be patched");
116 if (std::strcmp(itr->Name,
"FrameSource") == 0) {
140 throw std::invalid_argument(
"invalid BBY file");
148 const std::vector<std::string> &files = tarFile.
files();
149 for (
auto itr = files.begin(); itr != files.end(); ++itr) {
150 auto len = itr->length();
152 if ((len > 4) && (itr->find_first_of(
"\\/", 0, 2) == std::string::npos)) {
153 if ((itr->compare(0, 3,
"BBY") == 0) && (itr->rfind(
".hdf") == len - 4))
155 else if (itr->rfind(
".bin") == len - 4)
158 if (std::distance(itr, files.end()) != 1)
159 throw std::invalid_argument(
"invalid BBY file (history has to be at the end)");
162 tarFile.
select(itr->c_str());
169 if ((hdfFiles != 1) || (binFiles != 1) || (logFiles > 1))
170 throw std::invalid_argument(
"invalid BBY file");
173 std::string logContent;
175 logContent.resize(logSize);
176 tarFile.
read(&logContent[0], logSize);
180 std::ostringstream logContentNewBuffer;
190 tmp_int = property_value;
192 logContentNewBuffer << itr->Name <<
" = " << tmp_int <<
'\n';
196 tmp_dbl = property_value;
198 logContentNewBuffer << itr->Name <<
" = " << tmp_dbl <<
'\n';
202 if (std::strcmp(itr->Name,
"FrameSource") != 0)
203 throw std::invalid_argument(std::string(
"not implemented: ") + itr->Name);
205 tmp_str =
static_cast<std::string
>(property_value);
206 if (!tmp_str.empty()) {
207 if (Poco::icompare(tmp_str,
EXTERNAL) == 0)
208 logContentNewBuffer << itr->Name <<
" = " <<
EXTERNAL <<
'\n';
209 else if (Poco::icompare(tmp_str,
INTERNAL) == 0)
210 logContentNewBuffer << itr->Name <<
" = " <<
INTERNAL <<
'\n';
212 throw std::invalid_argument(
"invalid: FrameSource");
221 const auto file_it = std::find_if(files.cbegin(), files.cend(),
222 [](
const std::string &file) { return file.rfind(
".hdf") == file.length() - 4; });
223 if (file_it != files.end()) {
224 tarFile.
select(file_it->c_str());
226 Poco::TemporaryFile hdfFile;
227 std::shared_ptr<FILE> handle(fopen(hdfFile.path().c_str(),
"wb"), fclose);
232 while (0 != (bytesRead = tarFile.
read(buffer,
sizeof(buffer))))
233 fwrite(buffer, bytesRead, 1, handle.get());
240 int32_t tmp_int32 = 0;
243 logContentNewBuffer <<
"Bm1Counts = " << tmp_int32 <<
'\n';
245 logContentNewBuffer <<
"AttPos = " << tmp_float <<
'\n';
247 if (
loadNXString(entry,
"instrument/detector/frame_source", tmp_str))
248 logContentNewBuffer <<
"FrameSource = " << tmp_str <<
'\n';
249 if (
loadNXDataSet(entry,
"instrument/nvs067/lambda", tmp_float))
250 logContentNewBuffer <<
"Wavelength = " << tmp_float <<
'\n';
252 if (
loadNXDataSet(entry,
"instrument/master_chopper_freq", tmp_float))
253 logContentNewBuffer <<
"MasterChopperFreq = " << tmp_float <<
'\n';
254 if (
loadNXDataSet(entry,
"instrument/t0_chopper_freq", tmp_float))
255 logContentNewBuffer <<
"T0ChopperFreq = " << tmp_float <<
'\n';
256 if (
loadNXDataSet(entry,
"instrument/t0_chopper_phase", tmp_float))
257 logContentNewBuffer <<
"T0ChopperPhase = " << (tmp_float < 999.0 ? tmp_float : 0.0) <<
'\n';
260 logContentNewBuffer <<
"L1 = " << tmp_float <<
'\n';
262 logContentNewBuffer <<
"LTofDet = " << tmp_float <<
'\n';
264 logContentNewBuffer <<
"L2Det = " << tmp_float <<
'\n';
266 if (
loadNXDataSet(entry,
"instrument/L2_curtainl", tmp_float))
267 logContentNewBuffer <<
"L2CurtainL = " << tmp_float <<
'\n';
268 if (
loadNXDataSet(entry,
"instrument/L2_curtainr", tmp_float))
269 logContentNewBuffer <<
"L2CurtainR = " << tmp_float <<
'\n';
270 if (
loadNXDataSet(entry,
"instrument/L2_curtainu", tmp_float))
271 logContentNewBuffer <<
"L2CurtainU = " << tmp_float <<
'\n';
272 if (
loadNXDataSet(entry,
"instrument/L2_curtaind", tmp_float))
273 logContentNewBuffer <<
"L2CurtainD = " << tmp_float <<
'\n';
275 if (
loadNXDataSet(entry,
"instrument/detector/curtainl", tmp_float))
276 logContentNewBuffer <<
"CurtainL = " << tmp_float <<
'\n';
277 if (
loadNXDataSet(entry,
"instrument/detector/curtainr", tmp_float))
278 logContentNewBuffer <<
"CurtainR = " << tmp_float <<
'\n';
279 if (
loadNXDataSet(entry,
"instrument/detector/curtainu", tmp_float))
280 logContentNewBuffer <<
"CurtainU = " << tmp_float <<
'\n';
281 if (
loadNXDataSet(entry,
"instrument/detector/curtaind", tmp_float))
282 logContentNewBuffer <<
"CurtainD = " << tmp_float <<
'\n';
287 std::string logContentNew = logContentNewBuffer.str();
288 if (logContentNew.empty())
289 throw std::invalid_argument(
"nothing to patch");
292 logContent.append(logContentNew);
297 throw std::runtime_error(
"unable to patch");
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
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
size_t read(void *dst, size_t size)
bool select(const char *file)
const std::vector< std::string > & files() const
static bool append(const std::string &path, const std::string &name, const void *buffer, size_t size)
int64_t selected_size() const
void init() override
Initialise the algorithm.
void exec() override
Execute the algorithm.
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
ListValidator is a validator that requires the value of a property to be one of a defined list of pos...
The concrete, templated class for properties.
std::string getString(const std::string &name) const
Returns a string.
NXDataSetTyped< T > openNXDataSet(const std::string &name) const
Templated method for creating datasets.
Templated class implementation of NXDataSet.
void load()
Read all of the datablock in.
Implements NXentry Nexus class.
Implements NXroot Nexus class.
NXEntry openFirstEntry()
Open the first NXentry in the file.
static char const *const FilenameStr
static char const *const HistoryStr
bool loadNXDataSet(Nexus::NXEntry &entry, const std::string &address, T &value)
bool loadNXString(const Nexus::NXEntry &entry, const std::string &address, std::string &value)
static char const *const EXTERNAL
static char const *const INTERNAL
static PropertyInfo PatchableProperties[]
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.