From 1ebe98564932599978e6965fb80fb5fbf1d42ef1 Mon Sep 17 00:00:00 2001 From: Ricardo Leal <ricardo.leal@ill.fr> Date: Fri, 22 Nov 2013 11:06:24 +0100 Subject: [PATCH] Re #8365 Move instrument is not working yet --- .../inc/MantidDataHandling/LoadILLAscii.h | 2 + .../MantidDataHandling/LoadILLAsciiHelper.h | 3 +- .../DataHandling/src/LoadILLAscii.cpp | 128 ++++++++++++------ .../DataHandling/src/LoadILLAsciiHelper.cpp | 54 ++++++-- .../DataHandling/test/LoadILLAsciiTest.h | 4 +- Code/Mantid/instrument/D2B_Definition.xml | 4 +- 6 files changed, 139 insertions(+), 56 deletions(-) diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLAscii.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLAscii.h index 014dc356d39..1a9475a0451 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLAscii.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLAscii.h @@ -56,6 +56,8 @@ private: void loadInstrumentName(ILLParser &); void loadInstrumentDetails(ILLParser &p); void loadIDF(API::MatrixWorkspace_sptr &workspace); + void loadsDataIntoTheWS(API::MatrixWorkspace_sptr &, const std::vector<int> &); + void moveDetector(API::MatrixWorkspace_sptr &, double angle); //LoadHelper m_loader; std::string m_instrumentName; ///< Name of the instrument double m_wavelength; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLAsciiHelper.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLAsciiHelper.h index 0f4d162c39a..6c07e7a4571 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLAsciiHelper.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadILLAsciiHelper.h @@ -47,7 +47,8 @@ public: std::string getInstrumentName(); std::vector< std::vector<int> > getSpectraList() const {return spectraList;} std::vector<std::map<std::string, std::string> > getSpectraHeaderList() const {return spectraHeaders;} - template<typename T> T getValueFromHeader(const std::string &field); + template<typename T> T getValueFromHeader(const std::string &); + template<typename T> T getValue(const std::string &, const std::map<std::string, std::string> &); private: void parseFieldR(); void parseFieldA(); diff --git a/Code/Mantid/Framework/DataHandling/src/LoadILLAscii.cpp b/Code/Mantid/Framework/DataHandling/src/LoadILLAscii.cpp index f905bed9ee3..d65e988fc04 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadILLAscii.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadILLAscii.cpp @@ -9,9 +9,11 @@ #include "MantidDataHandling/LoadILLAscii.h" #include "MantidAPI/FileProperty.h" +#include "MantidGeometry/Instrument/ComponentHelper.h" #include "MantidAPI/RegisterFileLoader.h" #include "MantidDataHandling/LoadILLAsciiHelper.h" #include "MantidKernel/UnitFactory.h" +#include "MantidKernel/System.h" #include <algorithm> @@ -20,7 +22,6 @@ namespace DataHandling { using namespace Kernel; using namespace API; -using namespace Mantid::Kernel; // Register the algorithm into the AlgorithmFactory DECLARE_FILELOADER_ALGORITHM(LoadILLAscii) @@ -97,8 +98,9 @@ void LoadILLAscii::initDocs() { void LoadILLAscii::init() { declareProperty(new FileProperty("Filename", "", FileProperty::Load, ""), "Name of the data file to load."); - declareProperty("OutputWorkspacePrefix", "", - "Prefix for the workspaces created by the moving instrument."); + declareProperty( + new WorkspaceProperty<>("OutputWorkspace", "", Direction::Output), + "Name to use for the output workspace"); } @@ -108,76 +110,64 @@ void LoadILLAscii::init() { void LoadILLAscii::exec() { // Init std::string filename = getPropertyValue("Filename"); - std::string prefix = getPropertyValue("OutputWorkspacePrefix"); - ILLParser p(filename); loadInstrumentName(p); p.parse(); loadInstrumentDetails(p); + // get local references to the parsed file const std::vector<std::vector<int> > &spectraList = p.getSpectraList(); const std::vector<std::map<std::string, std::string> > &spectraHeaderList = p.getSpectraHeaderList(); + std::vector<API::MatrixWorkspace_sptr> workspaceList; + workspaceList.reserve(spectraList.size()); + + // iterate parsed file std::vector<std::vector<int> >::const_iterator iSpectra; std::vector<std::map<std::string, std::string> >::const_iterator iSpectraHeader; Progress progress(this, 0, 1, spectraList.size()); - for (iSpectra = spectraList.begin(), iSpectraHeader = - spectraHeaderList.begin(); - iSpectra < spectraList.end() - && iSpectraHeader < spectraHeaderList.end(); + for (iSpectra = spectraList.begin(), iSpectraHeader =spectraHeaderList.begin(); + iSpectra < spectraList.end() && iSpectraHeader < spectraHeaderList.end(); ++iSpectra, ++iSpectraHeader) { - g_log.debug() << "Reading sprectra: " << std::distance(spectraList.begin(),iSpectra) << std::endl; + g_log.debug() << "Reading Spectrum: " << std::distance(spectraList.begin(),iSpectra) << std::endl; std::vector<int> thisSpectrum = *iSpectra; API::MatrixWorkspace_sptr thisWorkspace = WorkspaceFactory::Instance().create("Workspace2D", thisSpectrum.size(), 2, 1); - g_log.debug() << "2" << std::endl; + thisWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create( "Wavelength"); - g_log.debug() << "3" << std::endl; - thisWorkspace->setYUnitLabel("Counts"); loadIDF(thisWorkspace); - // todo : need to mobe instrument - + // todo : need to move instrument + double currentPositionAngle = p.getValue<double>("angles*1000", *iSpectraHeader) / 1000; + moveDetector(thisWorkspace, currentPositionAngle); - thisWorkspace->dataX(0)[0] = m_wavelength - 0.001; - thisWorkspace->dataX(0)[1] = m_wavelength + 0.001; + // + loadsDataIntoTheWS(thisWorkspace,thisSpectrum); + loadIDF(thisWorkspace); // assigns data to the instrument + workspaceList.push_back(thisWorkspace); - - size_t spec = 0; - for (size_t i = 0; i < thisSpectrum.size(); ++i) { - - if (spec > 0) { - // just copy the time binning axis to every spectra - thisWorkspace->dataX(spec) = thisWorkspace->readX(0); - } - // Assign Y - thisWorkspace->dataY(spec)[0] = thisSpectrum[i]; - // Assign Error - thisWorkspace->dataE(spec)[0] = thisSpectrum[i] * thisSpectrum[i]; - - ++spec; - } - - loadIDF(thisWorkspace); // assins data to the instrument - - // Set the output workspace property : concatenate prefix with spectrum number + // JUUST TO SEE the WS in mantiplot std::stringstream outWorkspaceNameStream; - outWorkspaceNameStream << prefix << std::distance(spectraList.begin(),iSpectra); - + outWorkspaceNameStream << "test" << std::distance(spectraList.begin(),iSpectra); AnalysisDataService::Instance().addOrReplace(outWorkspaceNameStream.str(), thisWorkspace); progress.report(); } - p.showHeader(); + //p.showHeader(); + + // TODO: Merge workspaces + + // TODO : Correct (this is like this to work!) + setProperty("OutputWorkspace", WorkspaceFactory::Instance().create("Workspace2D", 128,2, 1)); } @@ -219,5 +209,65 @@ void LoadILLAscii::loadIDF(API::MatrixWorkspace_sptr &workspace) { g_log.information("Cannot load the instrument definition."); } } + +/** + * Loads the scan into the workspace + */ +void LoadILLAscii::loadsDataIntoTheWS(API::MatrixWorkspace_sptr &thisWorkspace, + const std::vector<int> &thisSpectrum) { + + thisWorkspace->dataX(0)[0] = m_wavelength - 0.001; + thisWorkspace->dataX(0)[1] = m_wavelength + 0.001; + + size_t spec = 0; + for (size_t i = 0; i < thisSpectrum.size(); ++i) { + + if (spec > 0) { + // just copy the time binning axis to every spectra + thisWorkspace->dataX(spec) = thisWorkspace->readX(0); + } + // Assign Y + thisWorkspace->dataY(spec)[0] = thisSpectrum[i]; + // Assign Error + thisWorkspace->dataE(spec)[0] = thisSpectrum[i] * thisSpectrum[i]; + + ++spec; + } + + loadIDF(thisWorkspace); // assigns data to the instrument + +} + +/** + * This is not working!!! + * + * Either I have to put a location in bank_uniq to move the whole detector + * or have to move every tube. To be done! + * + * + */ +void LoadILLAscii::moveDetector(API::MatrixWorkspace_sptr &ws, double angle){ + + // todo: put this as a constant somewhere? + const std::string componentName("bank_uniq"); + + // current position + Geometry::Instrument_const_sptr instrument = ws->getInstrument(); + Geometry::IComponent_const_sptr component = instrument->getComponentByName(componentName); + + // position - set all detector distance to constant l2 + double r, theta, phi; + V3D oldPos = component->getPos(); + oldPos.getSpherical(r, theta, phi); + + V3D newPos; + newPos.spherical(r, angle, phi); + + g_log.debug() << "Theta before = " << theta << " ; after = " << angle << "\n"; + Geometry::ParameterMap& pmap = ws->instrumentParameters(); + Geometry::ComponentHelper::moveComponent(*component, pmap, newPos,Geometry::ComponentHelper::Absolute); + +} + } // namespace DataHandling } // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/LoadILLAsciiHelper.cpp b/Code/Mantid/Framework/DataHandling/src/LoadILLAsciiHelper.cpp index 052be19f6b9..2dfc58627e1 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadILLAsciiHelper.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadILLAsciiHelper.cpp @@ -148,8 +148,12 @@ RrAadIitddddddddddddddddAatdddddddFfttttttttddddddddddddddddddddddddddIitdd etc. namespace Mantid { namespace DataHandling { -ILLParser::ILLParser(const std::string &filename) { - fin.open(filename); + +/* + * @param filepath for the raw file + */ +ILLParser::ILLParser(const std::string &filepath) { + fin.open(filepath); } ILLParser::~ILLParser() { @@ -158,8 +162,9 @@ ILLParser::~ILLParser() { } } -/** - * Main function +/* + * Main function that parses the files a fills in the lists (see private + * attributes of this class) */ void ILLParser::parse() { std::string line; @@ -190,11 +195,16 @@ void ILLParser::parse() { /** * Reads the instrument name from the file - * This should be done before parsing the file! + * TODO: + * This must be done before parsing the file, otherwise doesn't work: + * fin.seekg(0, std::ios::beg) ; fin.clear(); + * If the file was already parsed, those functions don't appear to put + * the get stream at the beginning. Needs to be fix. */ std::string ILLParser::getInstrumentName() { if (fin.tellg() != std::ios::beg) { + //TODO: this doesn't seem to work. fin.seekg(0, std::ios::beg); fin.clear(); //throw std::runtime_error("Must be called before reading the file!"); @@ -213,7 +223,7 @@ std::string ILLParser::getInstrumentName() { lineRead += 1; } - // Point to the begining again! + // Point to the beginning again! fin.seekg(0, std::ios::beg); fin.clear(); return instrumentName; @@ -288,7 +298,7 @@ void ILLParser::parseFieldNumeric(std::map<std::string, std::string> &header, index += 1; } } - + // keep the pairs key=value in the header std::vector<std::string>::const_iterator iKey; std::vector<std::string>::const_iterator iValue; for (iKey = keys.begin(), iValue = values.begin(); @@ -301,7 +311,7 @@ void ILLParser::parseFieldNumeric(std::map<std::string, std::string> &header, } /** - * Parses the spectrum + * Parses the field I in the spectrum block */ std::vector<int> ILLParser::parseFieldISpec(int fieldWith) { std::string line; @@ -317,6 +327,7 @@ std::vector<int> ILLParser::parseFieldISpec(int fieldWith) { fieldWith); nSpectraRead += static_cast<int>(s.size()); for (auto it = s.begin(); it != s.end(); ++it) { + // sscanf is much faster than lexical_cast / erase_spaces sscanf(it->c_str(), "%d", &spectrumValues[index]); index += 1; } @@ -325,7 +336,8 @@ std::vector<int> ILLParser::parseFieldISpec(int fieldWith) { } /** - * Shows contents + * Shows contents of the headers + * Just for debug purposes. */ void ILLParser::showHeader() { std::cout << "* Global header" << '\n'; @@ -354,6 +366,9 @@ void ILLParser::showHeader() { } +/** + * Parses the spectrum blocks. Called after the header has been parsed. + */ void ILLParser::startParseSpectra() { std::string line; std::getline(fin, line); @@ -399,6 +414,9 @@ std::vector<std::string> ILLParser::splitLineInFixedWithFields( return outVec; } +/** + * Evaluate the input string to a type <T> + */ template<typename T> T ILLParser::evaluate(std::string field) { boost::algorithm::erase_all(field, " "); @@ -412,9 +430,21 @@ T ILLParser::evaluate(std::string field) { return value; } +/** + * Gets a value from the header. + */ template<typename T> T ILLParser::getValueFromHeader(const std::string &field) { + + return getValue<T>(field,header); +} + +/* + * Get value type <T> from a map<strin,string> + */ +template<typename T> T ILLParser::getValue(const std::string &field, + const std::map<std::string, std::string> &thisHeader ) { T ret; - for (auto it = header.begin(); it != header.end(); ++it) { + for (auto it = thisHeader.begin(); it != thisHeader.end(); ++it) { //std::cout << it->first << "=>" << it->second << '\n'; std::size_t pos = it->first.find(field); if (pos != std::string::npos) { @@ -430,6 +460,8 @@ template<typename T> T ILLParser::getValueFromHeader(const std::string &field) { } // namespace DataHandling }// namespace Mantid -// Concrete template instantiation:The other libraries can't see the template definition so it needs to be instantiated in API +// Concrete template instantiation +// The other libraries can't see the template definition so it needs to be instantiated in API template MANTID_KERNEL_DLL double Mantid::DataHandling::ILLParser::getValueFromHeader(const std::string &); +template MANTID_KERNEL_DLL double Mantid::DataHandling::ILLParser::getValue(const std::string &,const std::map<std::string, std::string> &); diff --git a/Code/Mantid/Framework/DataHandling/test/LoadILLAsciiTest.h b/Code/Mantid/Framework/DataHandling/test/LoadILLAsciiTest.h index 044abb852c3..ae48269b873 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadILLAsciiTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadILLAsciiTest.h @@ -30,14 +30,12 @@ public: } void test_exec() { - // Name of the output workspace. - std::string outWSName("LoadILLAsciiTest_OutputWS"); LoadILLAscii alg; TS_ASSERT_THROWS_NOTHING(alg.initialize()) TS_ASSERT(alg.isInitialized()) TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", m_testFile)); - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspacePrefix", "value")); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", "outputWSName")); TS_ASSERT_THROWS_NOTHING( alg.execute(); ); TS_ASSERT(alg.isExecuted( )); diff --git a/Code/Mantid/instrument/D2B_Definition.xml b/Code/Mantid/instrument/D2B_Definition.xml index 2c87272300c..ffcd7975230 100644 --- a/Code/Mantid/instrument/D2B_Definition.xml +++ b/Code/Mantid/instrument/D2B_Definition.xml @@ -1,6 +1,6 @@ <?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 name="D2B" valid-from="1900-01-31 23:59:59" valid-to="2100-01-31 23:59:59" last-modified="2013-11-05 13:11:35"> +<instrument name="D2B" valid-from="1900-01-31 23:59:59" valid-to="2100-01-31 23:59:59" last-modified="2013-11-22 09:57:44"> <!-- Author: ricardo.leal@ill.fr --> <defaults> <length unit="meter" /> @@ -305,7 +305,7 @@ <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" /> + <radius val="0.00127" /> <height val=".0114341328125" /> </cylinder> <algebra val="shape" /> -- GitLab