diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadHelper.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadHelper.h index e9e31d60f64d616010bc51913c3b03c0f2d315c3..bf34c77e49f10af27c8143cea0cbb35ab8963a1b 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadHelper.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadHelper.h @@ -48,6 +48,11 @@ public: double getL1(const API::MatrixWorkspace_sptr&); double getL2(const API::MatrixWorkspace_sptr&, int detId = 1); double getInstrumentProperty(const API::MatrixWorkspace_sptr&, std::string); + void RecurseForProperties(NXhandle nxfileID, + API::Run& runDetails, + std::string& parent_name, + std::string& parent_class, + int indent); std::string dateTimeInIsoFormat(std::string); }; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h index 1ed45c67f9302154ef81dae09829243d88c9729c..82754b25a24b271c77dfbf174ad8a04da92b616c 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h @@ -4,6 +4,11 @@ #include "MantidKernel/System.h" #include "MantidAPI/Algorithm.h" +#include "MantidAPI/IFileLoader.h" +#include "MantidNexus/NexusClasses.h" +#include "MantidDataHandling/LoadHelper.h" + + namespace Mantid { namespace DataHandling @@ -31,11 +36,13 @@ namespace DataHandling File change history is stored at: <https://github.com/mantidproject/mantid> Code Documentation is available at: <http://doxygen.mantidproject.org> */ - class DLLExport LoadILLReflectometry : public API::Algorithm + class DLLExport LoadILLReflectometry : public API::IFileLoader<Kernel::NexusDescriptor> { public: LoadILLReflectometry(); virtual ~LoadILLReflectometry(); + /// Returns a confidence value that this algorithm can load a file + int confidence(Kernel::NexusDescriptor & descriptor) const; virtual const std::string name() const; virtual int version() const; @@ -46,6 +53,26 @@ namespace DataHandling void init(); void exec(); + void initWorkSpace(NeXus::NXEntry& entry, std::vector< std::vector<int> > monitorsData); + void setInstrumentName(const NeXus::NXEntry &firstEntry, const std::string &instrumentNamePath); + void loadDataDetails(NeXus::NXEntry& entry); + void loadDataIntoTheWorkSpace(NeXus::NXEntry& entry, std::vector< std::vector<int> > monitorsData); + void loadNexusEntriesIntoProperties(std::string nexusfilename); + std::vector< std::vector<int> > loadMonitors(NeXus::NXEntry& entry); + void runLoadInstrument(); + + API::MatrixWorkspace_sptr m_localWorkspace; + + std::string m_instrumentName; ///< Name of the instrument + + size_t m_numberOfTubes; // number of tubes - X + size_t m_numberOfPixelsPerTube; //number of pixels per tube - Y + size_t m_numberOfChannels; // time channels - Z + + size_t m_numberOfHistograms; + + std::vector<std::string> m_supportedInstruments; + LoadHelper m_loader; }; @@ -53,4 +80,4 @@ namespace DataHandling } // namespace DataHandling } // namespace Mantid -#endif /* MANTID_DATAHANDLING_LOADILLREFLECTOMETRY_H_ */ \ No newline at end of file +#endif /* MANTID_DATAHANDLING_LOADILLREFLECTOMETRY_H_ */ diff --git a/Code/Mantid/Framework/DataHandling/src/LoadHelper.cpp b/Code/Mantid/Framework/DataHandling/src/LoadHelper.cpp index 59b45f25b22713467df4ed54623fa4ce2ec5d535..7e487bd619779c8bd0b5ee4ddb76a7f3a3a31236 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadHelper.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadHelper.cpp @@ -138,6 +138,161 @@ double LoadHelper::getInstrumentProperty(const API::MatrixWorkspace_sptr& worksp } } +/** + * Recursively add properties from a nexus file + * + * @param nxfileID :: The Nexus file to be parsed + * @param runDetails :: where to add properties + * @param parent_name :: nexus caller name + * @param parent_class :: nexus caller class + * @param level :: current level in nexus tree + * + */ +void LoadHelper::RecurseForProperties(NXhandle nxfileID, + API::Run& runDetails, + std::string& parent_name, + std::string& parent_class, + int level) { + + std::string indent_str(level*2, ' ');// Two space by indent level + + // Link ? + + // Attributes ? + //dump_attributes(nxfileID, indent_str); + + // Classes + NXstatus stat; ///< return status + int datatype; ///< NX data type if a dataset, e.g. NX_CHAR, NX_FLOAT32, see napi.h + char nxname[NX_MAXNAMELEN],nxclass[NX_MAXNAMELEN]; + + while(NXgetnextentry(nxfileID,nxname,nxclass,&datatype) != NX_EOD) + { + g_log.debug()<<indent_str<<parent_name<<"."<<nxname<<" ; "<<nxclass<<std::endl; + + if((stat=NXopengroup(nxfileID,nxname,nxclass))==NX_OK){ + + // Go down to one level + std::string p_nxname(nxname);//current names can be useful for next level + std::string p_nxclass(nxclass); + + RecurseForProperties(nxfileID, runDetails, p_nxname, p_nxclass, level+1); + + NXclosegroup(nxfileID); + }// if(NXopengroup + else if ((stat=NXopendata (nxfileID, nxname))==NX_OK) + { + //dump_attributes(nxfileID, indent_str); + g_log.debug()<<indent_str<<nxname<<" opened."<<std::endl; + + if (parent_class=="NXData") { + g_log.debug()<<indent_str<<"skipping NXData"<<std::endl; + /* nothing */ + } else if (parent_class=="NXMonitor") { + g_log.debug()<<indent_str<<"skipping NXMonitor"<<std::endl; + /* nothing */ + } else { // create a property + int rank; + int dims[4]; + int type; + + std::string property_name; + // Exclude "entry0" from name for level 1 property + if (parent_name == "entry0") + property_name = nxname; + else + property_name = parent_name+"."+nxname; + + g_log.debug()<<indent_str<<"considering property "<<property_name<<std::endl; + + // Get the value + NXgetinfo(nxfileID, &rank, dims, &type); + + // Note, we choose to ignore "multidim properties + if (rank!=1) { + g_log.debug()<<indent_str<<"ignored multi dimension data on "<<property_name<<std::endl; + } else { + void *dataBuffer; + NXmalloc (&dataBuffer, rank, dims, type); + if (NXgetdata(nxfileID, dataBuffer) != NX_OK) { + NXfree(&dataBuffer); + throw std::runtime_error("Cannot read data from NeXus file"); + } + + if (type==NX_CHAR) { + runDetails.addProperty(property_name, std::string((const char *)dataBuffer)); + } else if ((type==NX_FLOAT32) + ||(type==NX_FLOAT64) + ||(type==NX_INT16) + ||(type==NX_INT32) + ||(type==NX_UINT16) + ) { + + // Look for "units" + NXstatus units_status; + char units_sbuf[NX_MAXNAMELEN]; + int units_len=NX_MAXNAMELEN; + int units_type=NX_CHAR; + + units_status=NXgetattr(nxfileID,const_cast<char*>("units"),(void *)units_sbuf,&units_len,&units_type); + if(units_status!=NX_ERROR) + { + g_log.debug()<<indent_str<<"[ "<<property_name<<" has unit "<<units_sbuf<<" ]"<<std::endl; + } + + + if ((type==NX_FLOAT32)||(type==NX_FLOAT64)) { + // Mantid numerical properties are double only. + double property_double_value=0.0; + if (type==NX_FLOAT32) { + property_double_value = *((float*)dataBuffer); + } else if (type==NX_FLOAT64) { + property_double_value = *((double*)dataBuffer); + } + + if(units_status!=NX_ERROR) + runDetails.addProperty(property_name, property_double_value, std::string(units_sbuf)); + else + runDetails.addProperty(property_name, property_double_value); + + } else { + // int case + int property_int_value=0; + if (type==NX_INT16) { + property_int_value = *((short int*)dataBuffer); + } else if (type==NX_INT32) { + property_int_value = *((int*)dataBuffer); + }else if (type==NX_UINT16) { + property_int_value = *((short unsigned int*)dataBuffer); + } + + if(units_status!=NX_ERROR) + runDetails.addProperty(property_name, property_int_value, std::string(units_sbuf)); + else + runDetails.addProperty(property_name, property_int_value); + + }// if (type==... + + + + } else { + g_log.debug()<<indent_str<<"unexpected data on "<<property_name<<std::endl; + } + + NXfree(&dataBuffer); + } + } + + NXclosedata(nxfileID); + } else { + g_log.debug()<<indent_str<<"unexpected status ("<<stat<<") on "<<nxname<<std::endl; + } + + }// while NXgetnextentry + + +}// RecurseForProperties + /** * Parses the date as formatted at the ILL: * 29-Jun-12 11:27:26 diff --git a/Code/Mantid/Framework/DataHandling/src/LoadILL.cpp b/Code/Mantid/Framework/DataHandling/src/LoadILL.cpp index 1e7ac2758a106596782efd6e56f10d2a55d9889a..96ab00e08efed2df7ec5f51ea1962e7ad2f26c0f 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadILL.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadILL.cpp @@ -69,7 +69,11 @@ namespace Mantid // fields existent only at the ILL if (descriptor.pathExists("/entry0/wavelength") && descriptor.pathExists("/entry0/experiment_identifier") - && descriptor.pathExists("/entry0/mode")) { + && descriptor.pathExists("/entry0/mode") + && !descriptor.pathExists("/entry0/dataSD") // This one is for LoadILLIndirect + && !descriptor.pathExists("/entry0/instrument/VirtualChopper") // This one is for LoadILLReflectometry + ) + { return 80; } else diff --git a/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp b/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp index 087c850b6d007d86b6e0ab947193b36469e294ad..72d075534a397fa4f798784aa1457b694a65368e 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp @@ -1,70 +1,370 @@ /*WIKI* -TODO: Enter a full wiki-markup description of your algorithm here. You can then use the Build/wiki_maker.py script to generate your full wiki page. -*WIKI*/ + TODO: Enter a full wiki-markup description of your algorithm here. You can then use the Build/wiki_maker.py script to generate your full wiki page. + *WIKI*/ #include "MantidDataHandling/LoadILLReflectometry.h" +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/RegisterFileLoader.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidGeometry/Instrument/ComponentHelper.h" -namespace Mantid +#include <boost/algorithm/string.hpp> + +#include <nexus/napi.h> +#include <iostream> + +namespace Mantid { +namespace DataHandling { + +using namespace Kernel; +using namespace API; +using namespace NeXus; + +// Register the algorithm into the AlgorithmFactory +DECLARE_NEXUS_FILELOADER_ALGORITHM (LoadILLReflectometry); + +//---------------------------------------------------------------------------------------------- +/** Constructor + */ +LoadILLReflectometry::LoadILLReflectometry() { + m_numberOfTubes = 0; // number of tubes - X + m_numberOfPixelsPerTube = 0; //number of pixels per tube - Y + m_numberOfChannels = 0; // time channels - Z + m_numberOfHistograms = 0; + m_supportedInstruments.push_back("D17"); +} + +//---------------------------------------------------------------------------------------------- +/** Destructor + */ +LoadILLReflectometry::~LoadILLReflectometry() { +} + +//---------------------------------------------------------------------------------------------- +/// Algorithm's name for identification. @see Algorithm::name +const std::string LoadILLReflectometry::name() const { + return "LoadILLReflectometry"; +} +; + +/// Algorithm's version for identification. @see Algorithm::version +int LoadILLReflectometry::version() const { + return 1; +} +; + +/// Algorithm's category for identification. @see Algorithm::category +const std::string LoadILLReflectometry::category() const { + return "DataHandling"; +} + +//---------------------------------------------------------------------------------------------- +/// Sets documentation strings for this algorithm +void LoadILLReflectometry::initDocs() { + this->setWikiSummary("Loads a ILL/D17 nexus file. "); + this->setOptionalMessage("Loads a ILL/D17 nexus file. "); +} + +/** + * Return the confidence with with this algorithm can load the file + * @param descriptor A descriptor for the file + * @returns An integer specifying the confidence level. 0 indicates it will not be used + */ +int LoadILLReflectometry::confidence( + Kernel::NexusDescriptor & descriptor) const { + + // fields existent only at the ILL + if (descriptor.pathExists("/entry0/wavelength") // ILL + && descriptor.pathExists("/entry0/experiment_identifier") // ILL + && descriptor.pathExists("/entry0/mode") // ILL + && descriptor.pathExists("/entry0/instrument/Chopper1") // TO BE DONE + && descriptor.pathExists("/entry0/instrument/Chopper2") // ??? + ) { + return 80; + } else { + return 0; + } +} + +//---------------------------------------------------------------------------------------------- +/** Initialize the algorithm's properties. + */ +void LoadILLReflectometry::init() { + declareProperty( + new FileProperty("Filename", "", FileProperty::Load, ".nxs"), + "File path of the Data file to load"); + + declareProperty( + new WorkspaceProperty<>("OutputWorkspace", "", Direction::Output), + "The name to use for the output workspace"); +} + +//---------------------------------------------------------------------------------------------- +/** Execute the algorithm. + */ +void LoadILLReflectometry::exec() { + // Retrieve filename + std::string filenameData = getPropertyValue("Filename"); + + // open the root node + NeXus::NXRoot dataRoot(filenameData); + NXEntry firstEntry = dataRoot.openFirstEntry(); + + // Load Monitor details: n. monitors x monitor contents + std::vector<std::vector<int> > monitorsData = loadMonitors(firstEntry); + + + // Load Data details (number of tubes, channels, etc) + loadDataDetails(firstEntry); + + std::string instrumentPath = m_loader.findInstrumentNexusPath(firstEntry); + setInstrumentName(firstEntry, instrumentPath); + + initWorkSpace(firstEntry, monitorsData); + + g_log.debug("Building properties..."); + loadNexusEntriesIntoProperties(filenameData); + +// g_log.debug("Loading data..."); + loadDataIntoTheWorkSpace(firstEntry, monitorsData); + + // load the instrument from the IDF if it exists + g_log.debug("Loading instrument definition..."); + runLoadInstrument(); + + //moveSingleDetectors(); Work in progress + + // Set the output workspace property + setProperty("OutputWorkspace", m_localWorkspace); +} + + +/** +* Set member variable with the instrument name +*/ +void LoadILLReflectometry::setInstrumentName(const NeXus::NXEntry &firstEntry, + const std::string &instrumentNamePath) { + + if (instrumentNamePath == "") { + std::string message( + "Cannot set the instrument name from the Nexus file!"); + g_log.error(message); + throw std::runtime_error(message); + } + m_instrumentName = m_loader.getStringFromNexusPath(firstEntry, + instrumentNamePath + "/name"); + boost::to_upper(m_instrumentName);// "D17" in file, keep it upper case. + g_log.debug() << "Instrument name set to: " + m_instrumentName << std::endl; + +} + + +/** + * Creates the workspace and initialises member variables with + * the corresponding values + * + * @param entry :: The Nexus entry + * @param monitorsData :: Monitors data already loaded + * + */ +void LoadILLReflectometry::initWorkSpace(NeXus::NXEntry& /*entry*/, std::vector< std::vector<int> > monitorsData) { -namespace DataHandling + + // dim0 * m_numberOfPixelsPerTube is the total number of detectors + m_numberOfHistograms = m_numberOfTubes * m_numberOfPixelsPerTube; + + g_log.debug() << "NumberOfTubes: " << m_numberOfTubes << std::endl; + g_log.debug() << "NumberOfPixelsPerTube: " << m_numberOfPixelsPerTube << std::endl; + g_log.debug() << "NumberOfChannels: " << m_numberOfChannels << std::endl; + g_log.debug() << "Monitors: " << monitorsData.size() << std::endl; + g_log.debug() << "Monitors[0]: " << monitorsData[0].size() << std::endl; + g_log.debug() << "Monitors[1]: " << monitorsData[1].size() << std::endl; + + // Now create the output workspace + + m_localWorkspace = WorkspaceFactory::Instance().create( + "Workspace2D", + m_numberOfHistograms+monitorsData.size(), + m_numberOfChannels + 1, + m_numberOfChannels); + + m_localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); + + m_localWorkspace->setYUnitLabel("Counts"); + +} + + +/** +* Load Data details (number of tubes, channels, etc) +* @param entry First entry of nexus file +*/ +void LoadILLReflectometry::loadDataDetails(NeXus::NXEntry& entry) { + // read in the data + NXData dataGroup = entry.openNXData("data"); + NXInt data = dataGroup.openIntData(); - // Register the algorithm into the AlgorithmFactory - DECLARE_ALGORITHM(LoadILLReflectometry) - + m_numberOfTubes = static_cast<size_t>(data.dim0()); + m_numberOfPixelsPerTube = static_cast<size_t>(data.dim1()); + m_numberOfChannels = static_cast<size_t>(data.dim2()); - //---------------------------------------------------------------------------------------------- - /** Constructor +} + + + + +/** + * Load monitors data found in nexus file + * + * @param entry :: The Nexus entry + * */ - LoadILLReflectometry::LoadILLReflectometry() - { - } - - //---------------------------------------------------------------------------------------------- - /** Destructor +std::vector< std::vector<int> > LoadILLReflectometry::loadMonitors(NeXus::NXEntry& entry){ + // read in the data + g_log.debug("Fetching monitor data..."); + + NXData dataGroup = entry.openNXData("monitor1/data"); + NXInt data = dataGroup.openIntData(); + // load the counts from the file into memory + data.load(); + + std::vector< std::vector<int> > monitors(1);// vector of monitors with one entry + std::vector<int> monitor1(data(), data()+data.size()); + monitors[0].swap(monitor1); + + // There is two monitors in data file, but the second one seems to be always 0 + dataGroup = entry.openNXData("monitor2/data"); + data = dataGroup.openIntData(); + data.load(); + + std::vector<int> monitor2(data(), data()+data.size()); + monitors.push_back(monitor2); + + return monitors; +} + + +/** + * Load data found in nexus file + * + * @param entry :: The Nexus entry + * @param monitorsData :: Monitors data already loaded + * */ - LoadILLReflectometry::~LoadILLReflectometry() - { +void LoadILLReflectometry::loadDataIntoTheWorkSpace(NeXus::NXEntry& entry, std::vector< std::vector<int> > monitorsData) +{ + + // read in the data + NXData dataGroup = entry.openNXData("data"); + NXInt data = dataGroup.openIntData(); + // load the counts from the file into memory + data.load(); + + + + // Assign calculated bins to first X axis +//// m_localWorkspace->dataX(0).assign(detectorTofBins.begin(), detectorTofBins.end()); + + size_t spec = 0; + size_t nb_monitors = monitorsData.size(); + + Progress progress(this, 0, 1, m_numberOfTubes * m_numberOfPixelsPerTube + nb_monitors); + + // Assign fake values to first X axis <<to be completed>> + for (size_t i = 0; i <= m_numberOfChannels; ++i) { + m_localWorkspace->dataX(0)[i] = double(i); } - - - //---------------------------------------------------------------------------------------------- - /// Algorithm's name for identification. @see Algorithm::name - const std::string LoadILLReflectometry::name() const { return "LoadILLReflectometry";}; - - /// Algorithm's version for identification. @see Algorithm::version - int LoadILLReflectometry::version() const { return 1;}; - - /// Algorithm's category for identification. @see Algorithm::category - const std::string LoadILLReflectometry::category() const { return TODO: FILL IN A CATEGORY;} - - //---------------------------------------------------------------------------------------------- - /// Sets documentation strings for this algorithm - void LoadILLReflectometry::initDocs() - { - this->setWikiSummary("TODO: Enter a quick description of your algorithm."); - this->setOptionalMessage("TODO: Enter a quick description of your algorithm."); + + // First, Monitor + for (size_t im = 0; im<nb_monitors; im++){ + + if (im > 0) + { + m_localWorkspace->dataX(im) = m_localWorkspace->readX(0); + } + + // Assign Y + int* monitor_p = monitorsData[im].data(); + m_localWorkspace->dataY(im).assign(monitor_p, monitor_p + m_numberOfChannels); + + progress.report(); } - //---------------------------------------------------------------------------------------------- - /** Initialize the algorithm's properties. - */ - void LoadILLReflectometry::init() + + // Then Tubes + for (size_t i = 0; i < m_numberOfTubes; ++i) { - declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input), "An input workspace."); - declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output), "An output workspace."); - } + for (size_t j = 0; j < m_numberOfPixelsPerTube; ++j) + { - //---------------------------------------------------------------------------------------------- - /** Execute the algorithm. + // just copy the time binning axis to every spectra + m_localWorkspace->dataX(spec+nb_monitors) = m_localWorkspace->readX(0); + + // Assign Y + int* data_p = &data(static_cast<int>(i), static_cast<int>(j), 0); + m_localWorkspace->dataY(spec+nb_monitors).assign(data_p, data_p + m_numberOfChannels); + + // Assign Error + MantidVec& E = m_localWorkspace->dataE(spec+nb_monitors); + std::transform(data_p, data_p + m_numberOfChannels, E.begin(), + LoadHelper::calculateStandardError); + + ++spec; + progress.report(); + } + }// for m_numberOfTubes + + +}// LoadILLIndirect::loadDataIntoTheWorkSpace + + + + +void LoadILLReflectometry::loadNexusEntriesIntoProperties(std::string nexusfilename) { + + API::Run & runDetails = m_localWorkspace->mutableRun(); + + // Open NeXus file + NXhandle nxfileID; + NXstatus stat=NXopen(nexusfilename.c_str(), NXACC_READ, &nxfileID); + if(stat==NX_ERROR) + { + g_log.debug() << "convertNexusToProperties: Error loading " << nexusfilename; + throw Kernel::Exception::FileError("Unable to open File:" , nexusfilename); + } + m_loader.RecurseForProperties(nxfileID, runDetails, nexusfilename, nexusfilename, 0); + + // Add also "Facility", as asked + runDetails.addProperty("Facility", std::string("ILL")); + + stat=NXclose(&nxfileID); +} + + + + +/** + * Run the Child Algorithm LoadInstrument. */ - void LoadILLReflectometry::exec() - { - // TODO Auto-generated execute stub - } +void LoadILLReflectometry::runLoadInstrument() { + + IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument"); + + // Now execute the Child Algorithm. Catch and log any error, but don't stop. + try { + + loadInst->setPropertyValue("InstrumentName", m_instrumentName); + loadInst->setProperty<MatrixWorkspace_sptr>("Workspace", m_localWorkspace); + loadInst->execute(); + + } catch (...) { + g_log.information("Cannot load the instrument definition."); + } +} } // namespace DataHandling -} // namespace Mantid \ No newline at end of file +} // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/test/LoadILLReflectometryTest.h b/Code/Mantid/Framework/DataHandling/test/LoadILLReflectometryTest.h index 36e01f4441f85c01a56efe2041bd70f210805bbd..b977f7113104efed31bb1c856cb7570543077c8b 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadILLReflectometryTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadILLReflectometryTest.h @@ -4,57 +4,70 @@ #include <cxxtest/TestSuite.h> #include "MantidDataHandling/LoadILLReflectometry.h" +#include "MantidAPI/AnalysisDataService.h" +using namespace Mantid::API; using Mantid::DataHandling::LoadILLReflectometry; -class LoadILLReflectometryTest : public CxxTest::TestSuite -{ +class LoadILLReflectometryTest: public CxxTest::TestSuite { public: - // This pair of boilerplate methods prevent the suite being created statically - // This means the constructor isn't called when running other tests - static LoadILLReflectometryTest *createSuite() { return new LoadILLReflectometryTest(); } - static void destroySuite( LoadILLReflectometryTest *suite ) { delete suite; } - - - void test_Init() - { - LoadILLReflectometry alg; - TS_ASSERT_THROWS_NOTHING( alg.initialize() ) - TS_ASSERT( alg.isInitialized() ) - } - - void test_exec() - { - // Name of the output workspace. - std::string outWSName("LoadILLReflectometryTest_OutputWS"); - - LoadILLReflectometry alg; - TS_ASSERT_THROWS_NOTHING( alg.initialize() ) - TS_ASSERT( alg.isInitialized() ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("REPLACE_PROPERTY_NAME_HERE!!!!", "value") ); - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); - TS_ASSERT_THROWS_NOTHING( alg.execute(); ); - TS_ASSERT( alg.isExecuted() ); - - // Retrieve the workspace from data service. TODO: Change to your desired type - Workspace_sptr ws; - TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS<Workspace>(outWSName) ); - TS_ASSERT(ws); - if (!ws) return; - - // TODO: Check the results - - // Remove workspace from the data service. - AnalysisDataService::Instance().remove(outWSName); - } - - void test_Something() - { - TSM_ASSERT( "You forgot to write a test!", 0); - } + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static LoadILLReflectometryTest *createSuite() { + return new LoadILLReflectometryTest(); + } + static void destroySuite(LoadILLReflectometryTest *suite) { + delete suite; + } + LoadILLReflectometryTest() : + m_dataFile("ILLD17_111686.nxs") { + } -}; + void test_Init() { + LoadILLReflectometry loader; + TS_ASSERT_THROWS_NOTHING(loader.initialize()) + TS_ASSERT(loader.isInitialized()) + } + + void testName() { + LoadILLReflectometry loader; + TS_ASSERT_EQUALS(loader.name(), "LoadILLReflectometry"); + } + + void test_exec() { + // Name of the output workspace. + std::string outWSName("LoadILLReflectometryTest_OutputWS"); + + LoadILLReflectometry loader; + TS_ASSERT_THROWS_NOTHING(loader.initialize()) + TS_ASSERT(loader.isInitialized()) + TS_ASSERT_THROWS_NOTHING( + loader.setPropertyValue("Filename", m_dataFile)); + TS_ASSERT_THROWS_NOTHING( + loader.setPropertyValue("OutputWorkspace", outWSName)); + TS_ASSERT_THROWS_NOTHING(loader.execute() + ; ); + TS_ASSERT(loader.isExecuted()); + + MatrixWorkspace_sptr output = + AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( + outWSName); + TS_ASSERT(output); + + if (!output) + return; + // TODO: Check the results + + // Remove workspace from the data service. + AnalysisDataService::Instance().clear(); + } + + +private: + std::string m_dataFile; + +}; -#endif /* MANTID_DATAHANDLING_LOADILLREFLECTOMETRYTEST_H_ */ \ No newline at end of file +#endif /* MANTID_DATAHANDLING_LOADILLREFLECTOMETRYTEST_H_ */ diff --git a/Code/Mantid/instrument/D17_Definition.xml b/Code/Mantid/instrument/D17_Definition.xml new file mode 100644 index 0000000000000000000000000000000000000000..aa49eaec8d3d646af1c8796d1a85713444e83544 --- /dev/null +++ b/Code/Mantid/instrument/D17_Definition.xml @@ -0,0 +1,339 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- For help on the notation used to specify an Instrument Definition File see http://www.mantidproject.org/IDF --> +<instrument 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 Schema/IDFSchema.xsd" name="D17" valid-from="1900-01-31 23:59:59" +valid-to="2100-01-31 23:59:59" last-modified="2014-04-04 08:24:08"> + <!-- Author: ricardo.leal@ill.fr --> + <defaults> + <length unit="meter" /> + <angle unit="degree" /> + <reference-frame> + <!-- The z-axis is set parallel to and in the direction of the beam. the + y-axis points up and the coordinate system is right handed. --> + <along-beam axis="z" /> + <pointing-up axis="y" /> + <handedness val="right" /> + </reference-frame> + </defaults> + <component type="moderator"> + <location z="-2" /> + </component> + <type name="moderator" is="Source"></type> + <!-- Sample position --> + <component type="sample-position"> + <location y="0.0" x="0.0" z="0.0" /> + </component> + <type name="sample-position" is="SamplePos" /> + <!--MONITORS--> + <component type="monitors" idlist="monitors"> + <location /> + </component> + <type name="monitors"> + <component type="monitor"> + <location z="0.0181" name="monitor1" /> + </component> + </type> + <!--MONITOR SHAPE--> + <!--FIXME: Do something real here.--> + <type is="monitor" name="monitor"> + <cylinder id="cyl-approx"> + <centre-of-bottom-base y="0.0" x="0.0" z="0.0" /> + <axis y="0.0" x="0.0" z="1.0" /> + <radius val="0.01" /> + <height val="0.03" /> + </cylinder> + <algebra val="cyl-approx" /> + </type> + <!--MONITOR IDs--> + <idlist idname="monitors"> + <id val="1" /> + </idlist> + <idlist idname="detectors"> + <id start="1" end="256" /> + </idlist> + <!-- Detector list def --> + <component type="detectors" idlist="detectors"> + <location /> + </component> + <!-- Detector Banks --> + <type name="detectors"> + <component type="bank_uniq"> + <location /> + </component> + </type> + <!-- Definition of the unique existent bank (made of tubes) --> + <type name="bank_uniq"> + <component type="standard_tube"> + <location r="3.000000" t="0.000000" name="tube_uniq" /> + </component> + </type> + <!-- Definition of standard_tube --> + <type name="standard_tube" outline="yes"> + <component type="standard_pixel"> + <location y="0.000000" /> + <location y="0.001176" /> + <location y="0.002353" /> + <location y="0.003529" /> + <location y="0.004706" /> + <location y="0.005882" /> + <location y="0.007059" /> + <location y="0.008235" /> + <location y="0.009412" /> + <location y="0.010588" /> + <location y="0.011765" /> + <location y="0.012941" /> + <location y="0.014118" /> + <location y="0.015294" /> + <location y="0.016471" /> + <location y="0.017647" /> + <location y="0.018824" /> + <location y="0.020000" /> + <location y="0.021176" /> + <location y="0.022353" /> + <location y="0.023529" /> + <location y="0.024706" /> + <location y="0.025882" /> + <location y="0.027059" /> + <location y="0.028235" /> + <location y="0.029412" /> + <location y="0.030588" /> + <location y="0.031765" /> + <location y="0.032941" /> + <location y="0.034118" /> + <location y="0.035294" /> + <location y="0.036471" /> + <location y="0.037647" /> + <location y="0.038824" /> + <location y="0.040000" /> + <location y="0.041176" /> + <location y="0.042353" /> + <location y="0.043529" /> + <location y="0.044706" /> + <location y="0.045882" /> + <location y="0.047059" /> + <location y="0.048235" /> + <location y="0.049412" /> + <location y="0.050588" /> + <location y="0.051765" /> + <location y="0.052941" /> + <location y="0.054118" /> + <location y="0.055294" /> + <location y="0.056471" /> + <location y="0.057647" /> + <location y="0.058824" /> + <location y="0.060000" /> + <location y="0.061176" /> + <location y="0.062353" /> + <location y="0.063529" /> + <location y="0.064706" /> + <location y="0.065882" /> + <location y="0.067059" /> + <location y="0.068235" /> + <location y="0.069412" /> + <location y="0.070588" /> + <location y="0.071765" /> + <location y="0.072941" /> + <location y="0.074118" /> + <location y="0.075294" /> + <location y="0.076471" /> + <location y="0.077647" /> + <location y="0.078824" /> + <location y="0.080000" /> + <location y="0.081176" /> + <location y="0.082353" /> + <location y="0.083529" /> + <location y="0.084706" /> + <location y="0.085882" /> + <location y="0.087059" /> + <location y="0.088235" /> + <location y="0.089412" /> + <location y="0.090588" /> + <location y="0.091765" /> + <location y="0.092941" /> + <location y="0.094118" /> + <location y="0.095294" /> + <location y="0.096471" /> + <location y="0.097647" /> + <location y="0.098824" /> + <location y="0.100000" /> + <location y="0.101176" /> + <location y="0.102353" /> + <location y="0.103529" /> + <location y="0.104706" /> + <location y="0.105882" /> + <location y="0.107059" /> + <location y="0.108235" /> + <location y="0.109412" /> + <location y="0.110588" /> + <location y="0.111765" /> + <location y="0.112941" /> + <location y="0.114118" /> + <location y="0.115294" /> + <location y="0.116471" /> + <location y="0.117647" /> + <location y="0.118824" /> + <location y="0.120000" /> + <location y="0.121176" /> + <location y="0.122353" /> + <location y="0.123529" /> + <location y="0.124706" /> + <location y="0.125882" /> + <location y="0.127059" /> + <location y="0.128235" /> + <location y="0.129412" /> + <location y="0.130588" /> + <location y="0.131765" /> + <location y="0.132941" /> + <location y="0.134118" /> + <location y="0.135294" /> + <location y="0.136471" /> + <location y="0.137647" /> + <location y="0.138824" /> + <location y="0.140000" /> + <location y="0.141176" /> + <location y="0.142353" /> + <location y="0.143529" /> + <location y="0.144706" /> + <location y="0.145882" /> + <location y="0.147059" /> + <location y="0.148235" /> + <location y="0.149412" /> + <location y="0.150588" /> + <location y="0.151765" /> + <location y="0.152941" /> + <location y="0.154118" /> + <location y="0.155294" /> + <location y="0.156471" /> + <location y="0.157647" /> + <location y="0.158824" /> + <location y="0.160000" /> + <location y="0.161176" /> + <location y="0.162353" /> + <location y="0.163529" /> + <location y="0.164706" /> + <location y="0.165882" /> + <location y="0.167059" /> + <location y="0.168235" /> + <location y="0.169412" /> + <location y="0.170588" /> + <location y="0.171765" /> + <location y="0.172941" /> + <location y="0.174118" /> + <location y="0.175294" /> + <location y="0.176471" /> + <location y="0.177647" /> + <location y="0.178824" /> + <location y="0.180000" /> + <location y="0.181176" /> + <location y="0.182353" /> + <location y="0.183529" /> + <location y="0.184706" /> + <location y="0.185882" /> + <location y="0.187059" /> + <location y="0.188235" /> + <location y="0.189412" /> + <location y="0.190588" /> + <location y="0.191765" /> + <location y="0.192941" /> + <location y="0.194118" /> + <location y="0.195294" /> + <location y="0.196471" /> + <location y="0.197647" /> + <location y="0.198824" /> + <location y="0.200000" /> + <location y="0.201176" /> + <location y="0.202353" /> + <location y="0.203529" /> + <location y="0.204706" /> + <location y="0.205882" /> + <location y="0.207059" /> + <location y="0.208235" /> + <location y="0.209412" /> + <location y="0.210588" /> + <location y="0.211765" /> + <location y="0.212941" /> + <location y="0.214118" /> + <location y="0.215294" /> + <location y="0.216471" /> + <location y="0.217647" /> + <location y="0.218824" /> + <location y="0.220000" /> + <location y="0.221176" /> + <location y="0.222353" /> + <location y="0.223529" /> + <location y="0.224706" /> + <location y="0.225882" /> + <location y="0.227059" /> + <location y="0.228235" /> + <location y="0.229412" /> + <location y="0.230588" /> + <location y="0.231765" /> + <location y="0.232941" /> + <location y="0.234118" /> + <location y="0.235294" /> + <location y="0.236471" /> + <location y="0.237647" /> + <location y="0.238824" /> + <location y="0.240000" /> + <location y="0.241176" /> + <location y="0.242353" /> + <location y="0.243529" /> + <location y="0.244706" /> + <location y="0.245882" /> + <location y="0.247059" /> + <location y="0.248235" /> + <location y="0.249412" /> + <location y="0.250588" /> + <location y="0.251765" /> + <location y="0.252941" /> + <location y="0.254118" /> + <location y="0.255294" /> + <location y="0.256471" /> + <location y="0.257647" /> + <location y="0.258824" /> + <location y="0.260000" /> + <location y="0.261176" /> + <location y="0.262353" /> + <location y="0.263529" /> + <location y="0.264706" /> + <location y="0.265882" /> + <location y="0.267059" /> + <location y="0.268235" /> + <location y="0.269412" /> + <location y="0.270588" /> + <location y="0.271765" /> + <location y="0.272941" /> + <location y="0.274118" /> + <location y="0.275294" /> + <location y="0.276471" /> + <location y="0.277647" /> + <location y="0.278824" /> + <location y="0.280000" /> + <location y="0.281176" /> + <location y="0.282353" /> + <location y="0.283529" /> + <location y="0.284706" /> + <location y="0.285882" /> + <location y="0.287059" /> + <location y="0.288235" /> + <location y="0.289412" /> + <location y="0.290588" /> + <location y="0.291765" /> + <location y="0.292941" /> + <location y="0.294118" /> + <location y="0.295294" /> + <location y="0.296471" /> + <location y="0.297647" /> + <location y="0.298824" /> + <location y="0.300000" /> + </component> + </type> + <type name="standard_pixel" is="detector"> + <cylinder id="shape"> + <centre-of-bottom-base x="0.0" y="-0.006144" z="0.0" /> + <axis x="0.0" y="1.0" z="0.0" /> + <radius val="0.0127" /> + <height val=".0114341328125" /> + </cylinder> + <algebra val="shape" /> + </type> +</instrument> diff --git a/Code/Mantid/instrument/Facilities.xml b/Code/Mantid/instrument/Facilities.xml index dc58aba686363b4c00d86ed2d4d143e0f4c9819f..2076402b27ed0229c67f8930a1e1a07143d16d92 100644 --- a/Code/Mantid/instrument/Facilities.xml +++ b/Code/Mantid/instrument/Facilities.xml @@ -476,6 +476,10 @@ <technique>SANS</technique> </instrument> + <instrument name="D17"> + <technique>Reflectometry</technique> + </instrument> + </facility> <facility name="SINQ" FileExtensions=".hdf"> diff --git a/Test/AutoTestData/ILLD17_111686.nxs b/Test/AutoTestData/ILLD17_111686.nxs new file mode 100644 index 0000000000000000000000000000000000000000..5ff9a291b6584284202f583b8bfcf6352b271faa Binary files /dev/null and b/Test/AutoTestData/ILLD17_111686.nxs differ