diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h b/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h index f3c0d6b44ba14e9ac20095bbc489702c4f2ea6e2..23e549868b03e609eb6f26e77fb00395ad7b3a18 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h @@ -62,6 +62,7 @@ protected: // number of frames size_t m_frames; size_t m_framesValid; + int64_t m_startTime; // tof correction const double m_period; const double m_phase; @@ -73,14 +74,15 @@ protected: // methods bool validFrame() const; - virtual void addEventImpl(size_t id, double tof) = 0; + virtual void addEventImpl(size_t id, int64_t pulse, double tof) = 0; public: // construction - EventProcessor(const std::vector<bool> &roi, const size_t stride, + EventProcessor(const std::vector<bool> &roi, size_t stride, const double period, const double phase, - const double tofMinBoundary, const double tofMaxBoundary, - const double timeMinBoundary, const double timeMaxBoundary); + const int64_t startTime, const double tofMinBoundary, + const double tofMaxBoundary, const double timeMinBoundary, + const double timeMaxBoundary); // methods void newFrame(); @@ -96,12 +98,12 @@ protected: double m_tofMax; // methods - void addEventImpl(size_t id, double tof) override; + void addEventImpl(size_t id, int64_t pulse, double tof) override; public: // construction EventCounter(const std::vector<bool> &roi, const size_t stride, - const double period, const double phase, + const double period, const double phase, const int64_t startTime, const double tofMinBoundary, const double tofMaxBoundary, const double timeMinBoundary, const double timeMaxBoundary, std::vector<size_t> &eventCounts); @@ -118,12 +120,12 @@ protected: std::vector<EventVector_pt> &m_eventVectors; // methods - void addEventImpl(size_t id, double tof) override; + void addEventImpl(size_t id, int64_t pulse, double tof) override; public: // construction EventAssigner(const std::vector<bool> &roi, const size_t stride, - const double period, const double phase, + const double period, const double phase, int64_t startTime, const double tofMinBoundary, const double tofMaxBoundary, const double timeMinBoundary, const double timeMaxBoundary, std::vector<EventVector_pt> &eventVectors); @@ -135,18 +137,16 @@ protected: double m_wavelength; // methods - void addEventImpl(size_t id, double tof) override; + void addEventImpl(size_t id, int64_t pulse, double tof) override; public: // construction - EventAssignerFixedWavelength(const std::vector<bool> &roi, - const size_t stride, const double wavelength, - const double period, const double phase, - const double tofMinBoundary, - const double tofMaxBoundary, - const double timeMinBoundary, - const double timeMaxBoundary, - std::vector<EventVector_pt> &eventVectors); + EventAssignerFixedWavelength( + const std::vector<bool> &roi, const size_t stride, + const double wavelength, const double period, const double phase, + const int64_t startTime, const double tofMinBoundary, + const double tofMaxBoundary, const double timeMinBoundary, + const double timeMaxBoundary, std::vector<EventVector_pt> &eventVectors); }; class FastReadOnlyFile { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h b/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h index 0571dc19c2799f5d2e2d15887381b10101f99f3c..3319ee3e59a107f4bbfa6ee2a382cc076cfb17e7 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h @@ -31,46 +31,19 @@ to recognise a file as the one containing Bilby data. class DLLExport LoadBBY : public API::IFileLoader<Kernel::FileDescriptor> { struct InstrumentInfo { - // - int32_t bm_counts; - int32_t att_pos; - bool is_tof; // tof or wavelength data - double wavelength; // -> /nvs067/lambda - // + // core values or non standard conversion std::string sample_name; std::string sample_description; - double sample_aperture; - double sample_x; - double sample_y; - double sample_z; - // - double source_aperture; + std::string start_time; + int32_t bm_counts; + int32_t att_pos; int32_t master1_chopper_id; int32_t master2_chopper_id; - // + bool is_tof; // tof or wavelength data + double wavelength; // -> /nvs067/lambda double period_master; double period_slave; double phase_slave; - // - double Lt0_value; - double Ltof_curtainl_value; - double Ltof_curtainr_value; - double Ltof_curtainu_value; - double Ltof_curtaind_value; - // - double L1_chopper_value; - double L1_source_value; - double L2_det_value; - // - double L2_curtainl_value; - double L2_curtainr_value; - double L2_curtainu_value; - double L2_curtaind_value; - // - double D_curtainl_value; - double D_curtainr_value; - double D_curtainu_value; - double D_curtaind_value; }; public: @@ -100,7 +73,12 @@ private: // instrument creation void createInstrument(ANSTO::Tar::File &tarFile, - InstrumentInfo &instrumentInfo); + InstrumentInfo &instrumentInfo, + std::map<std::string, double> &logParams, + std::map<std::string, std::string> &allParams); + void loadInstrumentParameters(NeXus::NXEntry &entry, + std::map<std::string, double> &logParams, + std::map<std::string, std::string> &allParams); // load nx dataset template <class T> diff --git a/Framework/DataHandling/src/LoadANSTOHelper.cpp b/Framework/DataHandling/src/LoadANSTOHelper.cpp index 3c75d813659f7947912a72461fb42a4b79cb4a3b..c199e80ccf8bff44520184d02274f99166c9b023 100644 --- a/Framework/DataHandling/src/LoadANSTOHelper.cpp +++ b/Framework/DataHandling/src/LoadANSTOHelper.cpp @@ -58,14 +58,15 @@ void ProgressTracker::complete() { // EventProcessor EventProcessor::EventProcessor(const std::vector<bool> &roi, const size_t stride, const double period, - const double phase, const double tofMinBoundary, + const double phase, const int64_t startTime, + const double tofMinBoundary, const double tofMaxBoundary, const double timeMinBoundary, const double timeMaxBoundary) : m_roi(roi), m_stride(stride), m_frames(0), m_framesValid(0), - m_period(period), m_phase(phase), m_tofMinBoundary(tofMinBoundary), - m_tofMaxBoundary(tofMaxBoundary), m_timeMinBoundary(timeMinBoundary), - m_timeMaxBoundary(timeMaxBoundary) {} + m_startTime(startTime), m_period(period), m_phase(phase), + m_tofMinBoundary(tofMinBoundary), m_tofMaxBoundary(tofMaxBoundary), + m_timeMinBoundary(timeMinBoundary), m_timeMaxBoundary(timeMaxBoundary) {} bool EventProcessor::validFrame() const { // frame boundary double frameTime = @@ -104,20 +105,26 @@ void EventProcessor::addEvent(size_t x, size_t y, double tof) { return; // check if neutron is in region of intreset - if (m_roi[id]) - addEventImpl(id, tof); + if (m_roi[id]) { + // absolute pulse time in nanoseconds + auto frames = static_cast<double>(m_frames); + auto frameTime = static_cast<int64_t>(m_period * frames * 1.0e3); + int64_t pulse = m_startTime + frameTime; + + addEventImpl(id, pulse, tof); + } } // EventCounter EventCounter::EventCounter(const std::vector<bool> &roi, const size_t stride, const double period, const double phase, - const double tofMinBoundary, + const int64_t startTime, const double tofMinBoundary, const double tofMaxBoundary, const double timeMinBoundary, const double timeMaxBoundary, std::vector<size_t> &eventCounts) - : EventProcessor(roi, stride, period, phase, tofMinBoundary, tofMaxBoundary, - timeMinBoundary, timeMaxBoundary), + : EventProcessor(roi, stride, period, phase, startTime, tofMinBoundary, + tofMaxBoundary, timeMinBoundary, timeMaxBoundary), m_eventCounts(eventCounts), m_tofMin(std::numeric_limits<double>::max()), m_tofMax(std::numeric_limits<double>::min()) {} size_t EventCounter::numFrames() const { return m_framesValid; } @@ -127,7 +134,8 @@ double EventCounter::tofMin() const { double EventCounter::tofMax() const { return m_tofMin <= m_tofMax ? m_tofMax : 0.0; } -void EventCounter::addEventImpl(size_t id, double tof) { +void EventCounter::addEventImpl(size_t id, int64_t pulse, double tof) { + UNUSED_ARG(pulse); if (m_tofMin > tof) m_tofMin = tof; if (m_tofMax < tof) @@ -137,30 +145,32 @@ void EventCounter::addEventImpl(size_t id, double tof) { } // EventAssigner -EventAssigner::EventAssigner(const std::vector<bool> &roi, const size_t stride, - const double period, const double phase, - const double tofMinBoundary, - const double tofMaxBoundary, - const double timeMinBoundary, - const double timeMaxBoundary, - std::vector<EventVector_pt> &eventVectors) - : EventProcessor(roi, stride, period, phase, tofMinBoundary, tofMaxBoundary, - timeMinBoundary, timeMaxBoundary), +EventAssigner::EventAssigner( + const std::vector<bool> &roi, const size_t stride, const double period, + const double phase, const int64_t startTime, const double tofMinBoundary, + const double tofMaxBoundary, const double timeMinBoundary, + const double timeMaxBoundary, std::vector<EventVector_pt> &eventVectors) + : EventProcessor(roi, stride, period, phase, startTime, tofMinBoundary, + tofMaxBoundary, timeMinBoundary, timeMaxBoundary), m_eventVectors(eventVectors) {} -void EventAssigner::addEventImpl(size_t id, double tof) { - m_eventVectors[id]->push_back(tof); +void EventAssigner::addEventImpl(size_t id, int64_t pulse, double tof) { + m_eventVectors[id]->emplace_back(tof, Types::Core::DateAndTime(pulse)); } // EventAssignerFixedWavelength EventAssignerFixedWavelength::EventAssignerFixedWavelength( const std::vector<bool> &roi, const size_t stride, const double wavelength, - const double period, const double phase, const double tofMinBoundary, - const double tofMaxBoundary, const double timeMinBoundary, - const double timeMaxBoundary, std::vector<EventVector_pt> &eventVectors) - : EventAssigner(roi, stride, period, phase, tofMinBoundary, tofMaxBoundary, - timeMinBoundary, timeMaxBoundary, eventVectors), + const double period, const double phase, const int64_t startTime, + const double tofMinBoundary, const double tofMaxBoundary, + const double timeMinBoundary, const double timeMaxBoundary, + std::vector<EventVector_pt> &eventVectors) + : EventAssigner(roi, stride, period, phase, startTime, tofMinBoundary, + tofMaxBoundary, timeMinBoundary, timeMaxBoundary, + eventVectors), m_wavelength(wavelength) {} -void EventAssignerFixedWavelength::addEventImpl(size_t id, double tof) { +void EventAssignerFixedWavelength::addEventImpl(size_t id, int64_t pulse, + double tof) { + UNUSED_ARG(pulse); UNUSED_ARG(tof); m_eventVectors[id]->push_back(m_wavelength); } diff --git a/Framework/DataHandling/src/LoadBBY.cpp b/Framework/DataHandling/src/LoadBBY.cpp index e7a69ac34ad6e85cecec616184a18d39a6e9f501..78af3f5f34838aaf884f8d288430c48f24d383de 100644 --- a/Framework/DataHandling/src/LoadBBY.cpp +++ b/Framework/DataHandling/src/LoadBBY.cpp @@ -23,9 +23,18 @@ #include "MantidKernel/UnitFactory.h" #include "MantidNexus/NexusClasses.h" +#include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/trim.hpp> #include <boost/math/special_functions/round.hpp> #include <Poco/AutoPtr.h> +#include <Poco/DOM/AutoPtr.h> +#include <Poco/DOM/DOMParser.h> +#include <Poco/DOM/Document.h> +#include <Poco/DOM/Element.h> +#include <Poco/DOM/NodeFilter.h> +#include <Poco/DOM/NodeIterator.h> +#include <Poco/DOM/NodeList.h> #include <Poco/TemporaryFile.h> #include <Poco/Util/PropertyFileConfiguration.h> @@ -196,11 +205,6 @@ void LoadBBY::exec() { API::Progress prog(this, 0.0, 1.0, Progress_Total); prog.doReport("creating instrument"); - // create instrument - InstrumentInfo instrumentInfo; - - createInstrument(tarFile, /* ref */ instrumentInfo); - // create workspace DataObjects::EventWorkspace_sptr eventWS = boost::make_shared<DataObjects::EventWorkspace>(); @@ -209,6 +213,12 @@ void LoadBBY::exec() { 2, // number of TOF bin boundaries 1); + // create instrument + InstrumentInfo instrumentInfo; + std::map<std::string, double> logParams; + std::map<std::string, std::string> allParams; + createInstrument(tarFile, instrumentInfo, logParams, allParams); + // set the units if (instrumentInfo.is_tof) eventWS->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("TOF"); @@ -249,10 +259,14 @@ void LoadBBY::exec() { double period = periodSlave; double shift = -1.0 / 6.0 * periodMaster - periodSlave * phaseSlave / 360.0; + // get the start time from the file + Types::Core::DateAndTime startTime(instrumentInfo.start_time); + auto startInNanosec = startTime.totalNanoseconds(); + // count total events per pixel to reserve necessary memory ANSTO::EventCounter eventCounter( - roi, HISTO_BINS_Y, period, shift, tofMinBoundary, tofMaxBoundary, - timeMinBoundary, timeMaxBoundary, eventCounts); + roi, HISTO_BINS_Y, period, shift, startInNanosec, tofMinBoundary, + tofMaxBoundary, timeMinBoundary, timeMaxBoundary, eventCounts); loadEvents(prog, "loading neutron counts", tarFile, eventCounter); @@ -277,29 +291,37 @@ void LoadBBY::exec() { if (instrumentInfo.is_tof) { ANSTO::EventAssigner eventAssigner( - roi, HISTO_BINS_Y, period, shift, tofMinBoundary, tofMaxBoundary, - timeMinBoundary, timeMaxBoundary, eventVectors); + roi, HISTO_BINS_Y, period, shift, startInNanosec, tofMinBoundary, + tofMaxBoundary, timeMinBoundary, timeMaxBoundary, eventVectors); loadEvents(prog, "loading neutron events (TOF)", tarFile, eventAssigner); } else { ANSTO::EventAssignerFixedWavelength eventAssigner( roi, HISTO_BINS_Y, instrumentInfo.wavelength, period, shift, - tofMinBoundary, tofMaxBoundary, timeMinBoundary, timeMaxBoundary, - eventVectors); + startInNanosec, tofMinBoundary, tofMaxBoundary, timeMinBoundary, + timeMaxBoundary, eventVectors); loadEvents(prog, "loading neutron events (Wavelength)", tarFile, eventAssigner); } + auto getParam = [&allParams](std::string tag, double defValue) { + try { + return std::stod(allParams[tag]); + } catch (std::invalid_argument) { + return defValue; + } + }; if (instrumentInfo.is_tof) { // just to make sure the bins hold it all eventWS->setAllX( HistogramData::BinEdges{std::max(0.0, floor(eventCounter.tofMin())), eventCounter.tofMax() + 1}); } else { - // +/-10% - eventWS->setAllX(HistogramData::BinEdges{instrumentInfo.wavelength * 0.9, - instrumentInfo.wavelength * 1.1}); + double lof = getParam("wavelength_extn_lo", 0.95); + double hif = getParam("wavelength_extn_hi", 1.05); + eventWS->setAllX(HistogramData::BinEdges{instrumentInfo.wavelength * lof, + instrumentInfo.wavelength * hif}); } // count total number of masked bins @@ -342,10 +364,11 @@ void LoadBBY::exec() { Types::Core::time_duration duration = boost::posix_time::microseconds( static_cast<boost::int64_t>(static_cast<double>(frame_count) * period)); - Types::Core::DateAndTime start_time("2000-01-01T00:00:00"); + Types::Core::DateAndTime start_time(instrumentInfo.start_time); Types::Core::DateAndTime end_time(start_time + duration); logManager.addProperty("start_time", start_time.toISO8601String()); + logManager.addProperty("run_start", start_time.toISO8601String()); logManager.addProperty("end_time", end_time.toISO8601String()); logManager.addProperty("is_tof", instrumentInfo.is_tof); @@ -355,59 +378,15 @@ void LoadBBY::exec() { instrumentInfo.sample_name); AddSinglePointTimeSeriesProperty(logManager, time_str, "sample_description", instrumentInfo.sample_description); - AddSinglePointTimeSeriesProperty(logManager, time_str, "sample_aperture", - instrumentInfo.sample_aperture); - AddSinglePointTimeSeriesProperty(logManager, time_str, "sample_x", - instrumentInfo.sample_x); - AddSinglePointTimeSeriesProperty(logManager, time_str, "sample_y", - instrumentInfo.sample_y); - AddSinglePointTimeSeriesProperty(logManager, time_str, "sample_z", - instrumentInfo.sample_z); - AddSinglePointTimeSeriesProperty(logManager, time_str, "wavelength", instrumentInfo.wavelength); - - AddSinglePointTimeSeriesProperty(logManager, time_str, "source_aperture", - instrumentInfo.source_aperture); AddSinglePointTimeSeriesProperty(logManager, time_str, "master1_chopper_id", instrumentInfo.master1_chopper_id); AddSinglePointTimeSeriesProperty(logManager, time_str, "master2_chopper_id", instrumentInfo.master2_chopper_id); - - AddSinglePointTimeSeriesProperty(logManager, time_str, "Lt0_value", - instrumentInfo.Lt0_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "Ltof_curtainl_value", - instrumentInfo.Ltof_curtainl_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "Ltof_curtainr_value", - instrumentInfo.Ltof_curtainr_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "Ltof_curtainu_value", - instrumentInfo.Ltof_curtainu_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "Ltof_curtaind_value", - instrumentInfo.Ltof_curtaind_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "L1_chopper_value", - instrumentInfo.L1_chopper_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "L1", - instrumentInfo.L1_source_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_det_value", - instrumentInfo.L2_det_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtainl_value", - instrumentInfo.L2_curtainl_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtainr_value", - instrumentInfo.L2_curtainr_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtainu_value", - instrumentInfo.L2_curtainu_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtaind_value", - instrumentInfo.L2_curtaind_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtainl_value", - instrumentInfo.D_curtainl_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtainr_value", - instrumentInfo.D_curtainr_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtainu_value", - instrumentInfo.D_curtainu_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtaind_value", - instrumentInfo.D_curtaind_value); - AddSinglePointTimeSeriesProperty(logManager, time_str, "curtain_rotation", - 10.0); + for (auto &x : logParams) { + AddSinglePointTimeSeriesProperty(logManager, time_str, x.first, x.second); + } API::IAlgorithm_sptr loadInstrumentAlg = createChildAlgorithm("LoadInstrument"); @@ -471,52 +450,105 @@ std::vector<bool> LoadBBY::createRoiVector(const std::string &maskfile) { return result; } +// loading instrument parameters +void LoadBBY::loadInstrumentParameters( + NeXus::NXEntry &entry, std::map<std::string, double> &logParams, + std::map<std::string, std::string> &allParams) { + + std::string idfDirectory = + Mantid::Kernel::ConfigService::Instance().getString( + "instrumentDefinition.directory"); + + try { + std::string parameterFilename = idfDirectory + "BILBY_Parameters.xml"; + // Set up the DOM parser and parse xml file + Poco::XML::DOMParser pParser; + Poco::XML::AutoPtr<Poco::XML::Document> pDoc; + try { + pDoc = pParser.parse(parameterFilename); + } catch (...) { + throw Kernel::Exception::FileError("Unable to parse File:", + parameterFilename); + } + Poco::XML::NodeIterator it(pDoc, Poco::XML::NodeFilter::SHOW_ELEMENT); + Poco::XML::Node *pNode = it.nextNode(); + while (pNode) { + if (pNode->nodeName() == "parameter") { + auto pElem = dynamic_cast<Poco::XML::Element *>(pNode); + std::string name = pElem->getAttribute("name"); + auto nodeList = pElem->childNodes(); + for (unsigned long i = 0; i < nodeList->length(); i++) { + auto cNode = nodeList->item(i); + if (cNode->nodeName() == "value") { + auto cElem = dynamic_cast<Poco::XML::Element *>(cNode); + std::string value = cElem->getAttribute("val"); + allParams[name] = value; + } + } + } + pNode = it.nextNode(); + } + + float tmpFloat = 0.0f; + for (auto &x : allParams) { + if (x.first.find("log_") == 0) { + auto logTag = boost::algorithm::trim_copy(x.first.substr(4)); + auto line = x.second; + + // comma separated details + std::vector<std::string> details; + boost::split(details, line, boost::is_any_of(",")); + auto hdfTag = boost::algorithm::trim_copy(details[0]); + try { + // extract the parameter and add it to the parameter dictionary + if (!hdfTag.empty() && loadNXDataSet(entry, hdfTag, tmpFloat)) { + auto factor = std::stod(details[1]); + logParams[logTag] = factor * tmpFloat; + } else { + logParams[logTag] = std::stod(details[2]); + if (!hdfTag.empty()) + g_log.warning() << "Cannot find hdf parameter " + + << hdfTag << ", using default.\n"; + } + + } catch (std::invalid_argument) { + g_log.warning() << "Invalid format for BILBY parameter " << x.first + << std::endl; + } + } + } + } catch (std::exception &ex) { + g_log.warning() << "Failed to load instrument with error: " << ex.what() + << ". The current facility may not be fully " + "supported.\n"; + } +} + // instrument creation void LoadBBY::createInstrument(ANSTO::Tar::File &tarFile, - InstrumentInfo &instrumentInfo) { + InstrumentInfo &instrumentInfo, + std::map<std::string, double> &logParams, + std::map<std::string, std::string> &allParams) { const double toMeters = 1.0 / 1000; - instrumentInfo.bm_counts = 0; - instrumentInfo.att_pos = 0; - instrumentInfo.is_tof = true; - instrumentInfo.wavelength = 0.0; - instrumentInfo.sample_name = "UNKNOWN"; instrumentInfo.sample_description = "UNKNOWN"; - instrumentInfo.sample_aperture = 0.0; - instrumentInfo.sample_x = 0.0; - instrumentInfo.sample_y = 0.0; - instrumentInfo.sample_z = 0.0; + instrumentInfo.start_time = "2000-01-01T00:00:00"; - instrumentInfo.source_aperture = 0.0; + instrumentInfo.bm_counts = 0; + instrumentInfo.att_pos = 0; instrumentInfo.master1_chopper_id = -1; instrumentInfo.master2_chopper_id = -1; + instrumentInfo.is_tof = true; + instrumentInfo.wavelength = 0.0; + instrumentInfo.period_master = 0.0; instrumentInfo.period_slave = (1.0 / 50.0) * 1.0e6; instrumentInfo.phase_slave = 0.0; - instrumentInfo.Lt0_value = 0.0; - instrumentInfo.Ltof_curtainl_value = 0.0; - instrumentInfo.Ltof_curtainr_value = 0.0; - instrumentInfo.Ltof_curtainu_value = 0.0; - instrumentInfo.Ltof_curtaind_value = 0.0; - - instrumentInfo.L1_chopper_value = 18.47258984375; - instrumentInfo.L1_source_value = 16.671; - instrumentInfo.L2_det_value = 33.15616015625; - - instrumentInfo.L2_curtainl_value = 23.28446093750; - instrumentInfo.L2_curtainr_value = 23.28201953125; - instrumentInfo.L2_curtainu_value = 24.28616015625; - instrumentInfo.L2_curtaind_value = 24.28235937500; - - instrumentInfo.D_curtainl_value = 0.3816; - instrumentInfo.D_curtainr_value = 0.4024; - instrumentInfo.D_curtainu_value = 0.3947; - instrumentInfo.D_curtaind_value = 0.3978; - // extract log and hdf file const std::vector<std::string> &files = tarFile.files(); auto file_it = @@ -553,17 +585,9 @@ void LoadBBY::createInstrument(ANSTO::Tar::File &tarFile, instrumentInfo.sample_name = tmp_str; if (loadNXString(entry, "sample/description", tmp_str)) instrumentInfo.sample_description = tmp_str; - if (loadNXDataSet(entry, "sample/sample_aperture", tmp_float)) - instrumentInfo.sample_aperture = tmp_float; - if (loadNXDataSet(entry, "sample/samx", tmp_float)) - instrumentInfo.sample_x = tmp_float; - if (loadNXDataSet(entry, "sample/samy", tmp_float)) - instrumentInfo.sample_y = tmp_float; - if (loadNXDataSet(entry, "sample/samz", tmp_float)) - instrumentInfo.sample_z = tmp_float; - - if (loadNXDataSet(entry, "instrument/source_aperture", tmp_float)) - instrumentInfo.source_aperture = tmp_float; + if (loadNXString(entry, "start_time", tmp_str)) + instrumentInfo.start_time = tmp_str; + if (loadNXDataSet(entry, "instrument/master1_chopper_id", tmp_int32)) instrumentInfo.master1_chopper_id = tmp_int32; if (loadNXDataSet(entry, "instrument/master2_chopper_id", tmp_int32)) @@ -583,42 +607,17 @@ void LoadBBY::createInstrument(ANSTO::Tar::File &tarFile, if (loadNXDataSet(entry, "instrument/t0_chopper_phase", tmp_float)) instrumentInfo.phase_slave = tmp_float < 999.0 ? tmp_float : 0.0; - if (loadNXDataSet(entry, "instrument/Lt0", tmp_float)) - instrumentInfo.Lt0_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/Ltof_curtainl", tmp_float)) - instrumentInfo.Ltof_curtainl_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/Ltof_curtainr", tmp_float)) - instrumentInfo.Ltof_curtainr_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/Ltof_curtainu", tmp_float)) - instrumentInfo.Ltof_curtainu_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/Ltof_curtaind", tmp_float)) - instrumentInfo.Ltof_curtaind_value = tmp_float * toMeters; - - if (loadNXDataSet(entry, "instrument/L2_det", tmp_float)) - instrumentInfo.L2_det_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/Ltof_det", tmp_float)) - instrumentInfo.L1_chopper_value = - tmp_float * toMeters - instrumentInfo.L2_det_value; - if (loadNXDataSet(entry, "instrument/L1", tmp_float)) - instrumentInfo.L1_source_value = tmp_float * toMeters; - - if (loadNXDataSet(entry, "instrument/L2_curtainl", tmp_float)) - instrumentInfo.L2_curtainl_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/L2_curtainr", tmp_float)) - instrumentInfo.L2_curtainr_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/L2_curtainu", tmp_float)) - instrumentInfo.L2_curtainu_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/L2_curtaind", tmp_float)) - instrumentInfo.L2_curtaind_value = tmp_float * toMeters; - - if (loadNXDataSet(entry, "instrument/detector/curtainl", tmp_float)) - instrumentInfo.D_curtainl_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/detector/curtainr", tmp_float)) - instrumentInfo.D_curtainr_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/detector/curtainu", tmp_float)) - instrumentInfo.D_curtainu_value = tmp_float * toMeters; - if (loadNXDataSet(entry, "instrument/detector/curtaind", tmp_float)) - instrumentInfo.D_curtaind_value = tmp_float * toMeters; + loadInstrumentParameters(entry, logParams, allParams); + + // adjust parameters + try { + logParams["L1_chopper_value"] = + logParams["Ltof_det_value"] - logParams["L2_det_value"]; + } catch (std::invalid_argument) { + logParams["L1_chopper_value"] = 18.47258984375; + g_log.warning() << "Cannot find parameter 'L1_chopper_value'" + << ", using default.\n"; + } } } @@ -640,10 +639,6 @@ void LoadBBY::createInstrument(ANSTO::Tar::File &tarFile, if (conf->hasProperty("SampleName")) instrumentInfo.sample_name = conf->getString("SampleName"); - if (conf->hasProperty("SampleAperture")) - instrumentInfo.sample_aperture = conf->getDouble("SampleAperture"); - if (conf->hasProperty("SourceAperture")) - instrumentInfo.source_aperture = conf->getDouble("SourceAperture"); if (conf->hasProperty("MasterChopperFreq")) { auto tmp = conf->getDouble("MasterChopperFreq"); @@ -665,35 +660,35 @@ void LoadBBY::createInstrument(ANSTO::Tar::File &tarFile, if (conf->hasProperty("Wavelength")) instrumentInfo.wavelength = conf->getDouble("Wavelength"); + if (conf->hasProperty("SampleAperture")) + logParams["sample_aperture"] = conf->getDouble("SampleAperture"); + if (conf->hasProperty("SourceAperture")) + logParams["source_aperture"] = conf->getDouble("SourceAperture"); if (conf->hasProperty("L1")) - instrumentInfo.L1_source_value = conf->getDouble("L1") * toMeters; + logParams["L1_source_value"] = conf->getDouble("L1") * toMeters; if (conf->hasProperty("LTofDet")) - instrumentInfo.L1_chopper_value = - conf->getDouble("LTofDet") * toMeters - instrumentInfo.L2_det_value; + logParams["L1_chopper_value"] = + conf->getDouble("LTofDet") * toMeters - logParams["L2_det_value"]; if (conf->hasProperty("L2Det")) - instrumentInfo.L2_det_value = conf->getDouble("L2Det") * toMeters; + logParams["L2_det_value"] = conf->getDouble("L2Det") * toMeters; if (conf->hasProperty("L2CurtainL")) - instrumentInfo.L2_curtainl_value = - conf->getDouble("L2CurtainL") * toMeters; + logParams["L2_curtainl_value"] = conf->getDouble("L2CurtainL") * toMeters; if (conf->hasProperty("L2CurtainR")) - instrumentInfo.L2_curtainr_value = - conf->getDouble("L2CurtainR") * toMeters; + logParams["L2_curtainr_value"] = conf->getDouble("L2CurtainR") * toMeters; if (conf->hasProperty("L2CurtainU")) - instrumentInfo.L2_curtainu_value = - conf->getDouble("L2CurtainU") * toMeters; + logParams["L2_curtainu_value"] = conf->getDouble("L2CurtainU") * toMeters; if (conf->hasProperty("L2CurtainD")) - instrumentInfo.L2_curtaind_value = - conf->getDouble("L2CurtainD") * toMeters; + logParams["L2_curtaind_value"] = conf->getDouble("L2CurtainD") * toMeters; if (conf->hasProperty("CurtainL")) - instrumentInfo.D_curtainl_value = conf->getDouble("CurtainL") * toMeters; + logParams["D_curtainl_value"] = conf->getDouble("CurtainL") * toMeters; if (conf->hasProperty("CurtainR")) - instrumentInfo.D_curtainr_value = conf->getDouble("CurtainR") * toMeters; + logParams["D_curtainr_value"] = conf->getDouble("CurtainR") * toMeters; if (conf->hasProperty("CurtainU")) - instrumentInfo.D_curtainu_value = conf->getDouble("CurtainU") * toMeters; + logParams["D_curtainu_value"] = conf->getDouble("CurtainU") * toMeters; if (conf->hasProperty("CurtainD")) - instrumentInfo.D_curtaind_value = conf->getDouble("CurtainD") * toMeters; + logParams["D_curtaind_value"] = conf->getDouble("CurtainD") * toMeters; } } diff --git a/Framework/DataHandling/test/LoadBBYTest.h b/Framework/DataHandling/test/LoadBBYTest.h index 276e021555cea06a42a005c053508f822142a58d..eee09a3b9032c696f54b57f6ce50c46207212038 100644 --- a/Framework/DataHandling/test/LoadBBYTest.h +++ b/Framework/DataHandling/test/LoadBBYTest.h @@ -24,6 +24,7 @@ using namespace Mantid::API; using namespace Mantid::Kernel; using namespace Mantid::DataHandling; using namespace Mantid::DataObjects; +using namespace Mantid::Types::Core; class LoadBBYTest : public CxxTest::TestSuite { public: @@ -70,10 +71,10 @@ public: // test start and end time TS_ASSERT( - run.getProperty("start_time")->value().compare("2000-01-01T00:00:00") == + run.getProperty("start_time")->value().compare("2014-06-17T09:59:31") == 0) TS_ASSERT( - run.getProperty("end_time")->value().find("2000-01-01T00:00:00.08") == + run.getProperty("end_time")->value().find("2014-06-17T09:59:31.08") == 0) // test data properties @@ -136,6 +137,49 @@ public: ->firstValue(), 10, 1.0e-7); } + + void test_filter_bby_algorithm() { + LoadBBY algToBeTested; + + if (!algToBeTested.isInitialized()) + algToBeTested.initialize(); + + // Filter the event by pulse time when loading + // and confirm that the events are within the range + std::string outputSpace = "LoadBBYTest"; + algToBeTested.setPropertyValue("OutputWorkspace", outputSpace); + std::string inputFile = "BBY0000014.tar"; + algToBeTested.setPropertyValue("Filename", inputFile); + algToBeTested.setPropertyValue("FilterByTimeStart", "0.04"); + algToBeTested.setPropertyValue("FilterByTimeStop", "0.06"); + + TS_ASSERT_THROWS_NOTHING(algToBeTested.execute()); + TS_ASSERT(algToBeTested.isExecuted()); + + // check the filtered events + + // get workspace generated + EventWorkspace_sptr output = + AnalysisDataService::Instance().retrieveWS<EventWorkspace>(outputSpace); + auto run = output->run(); + + // check the number of events and the min and max pulse range + TS_ASSERT_EQUALS(output->getNumberEvents(), 100000); + auto minPulseTime = output->getPulseTimeMin(); + auto maxPulseTime = output->getPulseTimeMax(); + + DateAndTime runstart(run.getProperty("run_start")->value()); + auto timeshift = runstart.totalNanoseconds(); + double minTime = + static_cast<double>(minPulseTime.totalNanoseconds() - timeshift) * + 1.0e-9; + double maxTime = + static_cast<double>(maxPulseTime.totalNanoseconds() - timeshift) * + 1.0e-9; + + TS_ASSERT_LESS_THAN(maxTime, 0.0600001); + TS_ASSERT_LESS_THAN(0.0399999, minTime); + } }; #endif /*LoadBBYTEST_H_*/ diff --git a/instrument/Bilby_Definition.xml b/instrument/BILBY_Definition.xml similarity index 99% rename from instrument/Bilby_Definition.xml rename to instrument/BILBY_Definition.xml index 03c7217d76d58de66e732bc35f7538f3ceec8d94..62b242eaa812d26957c56a316339c9cf2619d9fd 100644 --- a/instrument/Bilby_Definition.xml +++ b/instrument/BILBY_Definition.xml @@ -5,7 +5,7 @@ xmlns="http://www.mantidproject.org/IDF/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd" - name="Bilby" + name="BILBY" valid-from = "1901-01-01 00:00:00" valid-to = "2100-01-01 00:00:00" last-modified="2016-04-15 00:00:00"> diff --git a/instrument/BILBY_Parameters.xml b/instrument/BILBY_Parameters.xml new file mode 100644 index 0000000000000000000000000000000000000000..3c948bb6672de8fc4e2b7e7135a032dd7bd962b3 --- /dev/null +++ b/instrument/BILBY_Parameters.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<parameter-file instrument = "BILBY" valid-from = "1901-01-01T00:00:00"> + + <component-link name = "BILBY"> + + <!-- Bilby parameters --> + <parameter name="wavelength_extn_lo"> + <value val="0.95"/> + </parameter> + <parameter name="wavelength_extn_hi"> + <value val="1.05"/> + </parameter> + + <!-- following parameters are saved to the run log, + parameters are entered as log_[log_name] and the + and the value is: "hdf_tag,scale,def_value" --> + <parameter name="log_sample_aperture" type="string"> + <value val="sample/sample_aperture, 1.0, 0.0"/> + </parameter> + <parameter name="log_sample_x" type="string"> + <value val="sample/samx, 1.0, 0.0"/> + </parameter> + <parameter name="log_sample_y" type="string"> + <value val="sample/samy, 1.0, 0.0"/> + </parameter> + <parameter name="log_sample_z" type="string"> + <value val="sample/samz, 1.0, 0.0"/> + </parameter> + <parameter name="log_source_aperture" type="string"> + <value val="instrument/source_aperture, 1.0, 0.0"/> + </parameter> + + <parameter name="log_Lt0_value" type="string"> + <value val="instrument/Lt0, 0.001, 0.0"/> + </parameter> + <parameter name="log_Ltof_curtainl_value" type="string"> + <value val="instrument/Ltof_curtainl, 0.001, 0.0"/> + </parameter> + <parameter name="log_Ltof_curtainr_value" type="string"> + <value val="instrument/Ltof_curtainr, 0.001, 0.0"/> + </parameter> + <parameter name="log_Ltof_curtainu_value" type="string"> + <value val="instrument/Ltof_curtainu, 0.001, 0.0"/> + </parameter> + <parameter name="log_Ltof_curtaind_value" type="string"> + <value val="instrument/Ltof_curtaind, 0.001, 0.0"/> + </parameter> + + <parameter name="log_L2_det_value" type="string"> + <value val="instrument/L2_det, 0.001, 33.15616015625"/> + </parameter> + <parameter name="log_Ltof_det_value" type="string"> + <value val="instrument/Ltof_det, 0.001, 0.0"/> + </parameter> + <parameter name="log_L1" type="string"> + <value val="instrument/L1, 0.001, 16.671"/> + </parameter> + + <parameter name="log_L2_curtainl_value" type="string"> + <value val="instrument/L2_curtainl, 0.001, 23.28446093750"/> + </parameter> + <parameter name="log_L2_curtainr_value" type="string"> + <value val="instrument/L2_curtainr, 0.001, 23.28201953125"/> + </parameter> + <parameter name="log_L2_curtainu_value" type="string"> + <value val="instrument/L2_curtainu, 0.001, 24.28616015625"/> + </parameter> + <parameter name="log_L2_curtaind_value" type="string"> + <value val="instrument/L2_curtaind, 0.001, 24.28235937500"/> + </parameter> + + <parameter name="log_D_curtainl_value" type="string"> + <value val="instrument/detector/curtainl, 0.001, 0.3816"/> + </parameter> + <parameter name="log_D_curtainr_value" type="string"> + <value val="instrument/detector/curtainr, 0.001, 0.4024"/> + </parameter> + <parameter name="log_D_curtainu_value" type="string"> + <value val="instrument/detector/curtainu, 0.001, 0.3947"/> + </parameter> + <parameter name="log_D_curtaind_value" type="string"> + <value val="instrument/detector/curtaind, 0.001, 0.3978"/> + </parameter> + + <!-- parameter to be added to log that is not in the hdf file --> + <parameter name="log_curtain_rotation" type="string"> + <value val=",,10.0"/> + </parameter> + + + + </component-link> + +</parameter-file> \ No newline at end of file diff --git a/instrument/Facilities.xml b/instrument/Facilities.xml index 15d1dbd910ae3c93e86cd4186aafdd8122c12f44..1d199e72723a39d46ddd8e2cbf896933b8cbfd51 100644 --- a/instrument/Facilities.xml +++ b/instrument/Facilities.xml @@ -851,16 +851,19 @@ <facility name="ANSTO" FileExtensions=".nxs,.tar,.hdf"> <timezone>Australia/Sydney</timezone> - <instrument name="Bilby"> + <instrument name="BILBY" shortname="BBY"> + <zeropadding size="7"/> <technique>Small Angle Scattering</technique> </instrument> - <instrument name="EMUau"> + <instrument name="EMUau" shortname="EMU"> + <zeropadding size="7"/> <technique>Neutron Spectroscopy</technique> <technique>Reactor Indirect Geometry Spectroscopy</technique> </instrument> - <instrument name="PELICAN"> + <instrument name="PELICAN" shortname="PLN"> + <zeropadding size="7"/> <technique>Neutron Spectroscopy</technique> <technique>Inelastic Neutron Scattering</technique> </instrument> diff --git a/scripts/BilbyCustomFunctions_Reduction.py b/scripts/BilbyCustomFunctions_Reduction.py index c7c8dd0b54e89afb7b5bdfab7f685c026113b737..28de92cac9056f3124b17bfa4221c46724aba350 100644 --- a/scripts/BilbyCustomFunctions_Reduction.py +++ b/scripts/BilbyCustomFunctions_Reduction.py @@ -121,12 +121,12 @@ def strip_NaNs(output_workspace, base_output_name): ####################################################################################### def get_pixel_size(): # reads current IDF and get pixelsize from there - """ To get pixel size for Bilby detectors from the Bilby_Definition.xml file """ + """ To get pixel size for Bilby detectors from the BILBY_Definition.xml file """ from mantid.api import ExperimentInfo import xml.etree.cElementTree as ET - currentIDF = ExperimentInfo.getInstrumentFilename("Bilby") + currentIDF = ExperimentInfo.getInstrumentFilename("BILBY") # print currentIDF tree = ET.parse(currentIDF) for node in tree.iter(): diff --git a/scripts/BilbyReductionScript.py b/scripts/BilbyReductionScript.py index 15f48d21740825d0f61dfab69e95bbf104afad8b..fec57060868817044644f609ebefc02c6e7e12a4 100644 --- a/scripts/BilbyReductionScript.py +++ b/scripts/BilbyReductionScript.py @@ -274,10 +274,10 @@ class RunBilbyReduction: ws_tranSam = mantid_api.LoadBBY(transm_file) ws_tranEmp = mantid_api.LoadBBY(ws_emp_file) # empty beam for transmission transm_mask = current_file["mask_transmission"] + '.xml' - ws_tranMsk = mantid_api.LoadMask('Bilby', transm_mask) + ws_tranMsk = mantid_api.LoadMask('BILBY', transm_mask) sam_mask_file = current_file["mask"] + '.xml' - ws_samMsk = mantid_api.LoadMask('Bilby', sam_mask_file) + ws_samMsk = mantid_api.LoadMask('BILBY', sam_mask_file) # scaling: attenuation att_pos = float(ws_tranSam.run().getProperty("att_pos").value)