diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt index f4fdd1a6cf70662fcf8a682c7b02abd0ee17a53f..fd5c41c184f170891dce64682bfa97776d468020 100644 --- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt @@ -91,6 +91,7 @@ set ( SRC_FILES src/GroupWorkspaces.cpp src/HRPDSlabCanAbsorption.cpp src/He3TubeEfficiency.cpp + src/IDLRebin.cpp src/IQTransform.cpp src/IdentifyNoisyDetectors.cpp src/Integration.cpp @@ -267,6 +268,7 @@ set ( INC_FILES inc/MantidAlgorithms/GroupWorkspaces.h inc/MantidAlgorithms/HRPDSlabCanAbsorption.h inc/MantidAlgorithms/He3TubeEfficiency.h + inc/MantidAlgorithms/IDLRebin.h inc/MantidAlgorithms/IQTransform.h inc/MantidAlgorithms/IdentifyNoisyDetectors.h inc/MantidAlgorithms/Integration.h @@ -432,6 +434,7 @@ set ( TEST_FILES test/GroupWorkspacesTest.h test/HRPDSlabCanAbsorptionTest.h test/He3TubeEfficiencyTest.h + test/IDLRebinTest.h test/IQTransformTest.h test/IdentifyNoisyDetectorsTest.h test/IntegrationTest.h diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/IDLRebin.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/IDLRebin.h new file mode 100644 index 0000000000000000000000000000000000000000..6907b757f1550bc232f8c8af507d66e4a173175a --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/IDLRebin.h @@ -0,0 +1,67 @@ +#ifndef MANTID_ALGORITHMS_VULCANREBIN_H_ +#define MANTID_ALGORITHMS_VULCANREBIN_H_ +/*WIKI* +TODO: Enter wiki description here. +*WIKI*/ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + + +namespace Mantid +{ +namespace Algorithms +{ + + /** IDLRebin : TODO: DESCRIPTION + + @author + @date 2011-10-06 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + class DLLExport IDLRebin : public API::Algorithm + { + public: + IDLRebin(); + ~IDLRebin(); + + /// Algorithm's name for identification overriding a virtual method + virtual const std::string name() const { return "IDLRebin";} + /// Algorithm's version for identification overriding a virtual method + virtual int version() const { return (1);} + /// Algorithm's category for identification overriding a virtual method + virtual const std::string category() const { return "Diffraction";} + + private: + void init(); + void exec(); + + void rebinIDL(const std::vector<double> tofs, const std::vector<double> events, std::vector<double>& rebindata); + size_t locateEventInBin(double eventtof, std::vector<double> tofs); + + }; + + +} // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_VULCANREBIN_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/src/IDLRebin.cpp b/Code/Mantid/Framework/Algorithms/src/IDLRebin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..222ab0078ee046e18ab3cce3c9034ea38b93eb72 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/IDLRebin.cpp @@ -0,0 +1,188 @@ +#include "MantidAlgorithms/IDLRebin.h" +#include "MantidKernel/System.h" +#include "MantidAPI/FileProperty.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/EventList.h" +#include <math.h> +#include <iostream> +#include <fstream> + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ +namespace Algorithms +{ + +DECLARE_ALGORITHM(IDLRebin) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + IDLRebin::IDLRebin() + { + // TODO Auto-generated constructor stub + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + IDLRebin::~IDLRebin() + { + // TODO Auto-generated destructor stub + } + + void IDLRebin::init(){ + + declareProperty(new FileProperty("TOFTemplateFile", "", FileProperty::Load, ".dat"), + "Data file with (tof, y, e) column"); + + declareProperty(new WorkspaceProperty<Mantid::DataObjects::EventWorkspace>("InputWorkspace", "", Direction::Input), + "Input Event Workspace For Rebinning"); + + declareProperty(new FileProperty("OutputFileBank1", "", FileProperty::Save, ".dat"), + "Data file has the rebinned data"); + + declareProperty(new FileProperty("OutputFileBank2", "", FileProperty::Save, ".dat"), + "Data file has the rebinned data"); + + } + + void IDLRebin::exec(){ + + // 1. Get Inputs + DataObjects::EventWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); + std::string templatefilename = getPropertyValue("TOFTemplateFile"); + std::string outputbank1filename = getPropertyValue("OutputFileBank1"); + std::string outputbank2filename = getPropertyValue("OutputFileBank2"); + std::vector<std::string> outputfilenames; + outputfilenames.push_back(outputbank1filename); + outputfilenames.push_back(outputbank2filename); + + // 2. Read TOF template + std::ifstream ifs(templatefilename.c_str()); + if (!ifs){ + g_log.error() << "File " << templatefilename << " cannot be open" << std::endl; + throw std::invalid_argument("Cannot open file"); + } + + std::vector<double> tofs; + std::string line; + double tof, intensity, error; + while(getline(ifs, line)){ + std::stringstream ss(line); + ss >> tof >> intensity >> error; + tofs.push_back(tof); + } + + g_log.notice() << "Number (TOFs) = " << tofs.size() << " within [" << tofs[0] << ", " << tofs[tofs.size()-1] << "]\n"; + + // 3. Rebin + for (size_t ispec=0; ispec < inputWS->getNumberHistograms(); ispec ++){ + // 3.1 Rebin + DataObjects::EventList events = inputWS->getEventList(ispec); + std::vector<double> eventtofs; + events.getTofs(eventtofs); + std::vector<double> rebindata(tofs.size()); + this->rebinIDL(tofs, eventtofs, rebindata); + + // 3.2 Output + g_log.notice() << "Write Spectrum " << ispec << " To File " << outputfilenames[ispec] << std::endl; + std::ofstream ofs(outputfilenames[ispec].c_str()); + for (size_t i = 0; i < rebindata.size(); i ++){ + ofs << tofs[i] << "\t\t" << rebindata[i] << std::endl; + } + + ofs.close(); + + } + + } + + /* + */ + void IDLRebin::rebinIDL(const std::vector<double> tofs, const std::vector<double> events, std::vector<double>& rebindata){ + // 1. Init + g_log.notice() << "Size of RebinnedData = " << rebindata.size() << " Number(Events) = " << events.size() << std::endl; + for (size_t i = 0; i < rebindata.size(); i ++){ + rebindata[i] = 0; + } + + // 2. Rebin + for (size_t i = 0; i < events.size(); i ++){ + // for (size_t i = 0; i < 20; i ++){ + size_t binindex = locateEventInBin(events[i], tofs); + rebindata[binindex] += 1; + } + + return; + } + + /*** + * IDL Style... + */ + size_t IDLRebin::locateEventInBin(double eventtof, std::vector<double> tofs){ + + size_t searchlimit = size_t(log(double(tofs.size()))/log(2))+3; + + // g_log.notice() << "Search count limit = " << searchlimit << std::endl; + + size_t iloc = 0; + + if (eventtof < tofs[0]){ + // Out of lower boundary + iloc = 0; + + } else if (eventtof > tofs[tofs.size()-1]){ + // Out of upper boundary + iloc = tofs.size()-1; + + } else { + // Binary search + size_t ist = 0; + size_t ied = tofs.size()-1; + bool found = false; + + size_t counts = 0; + + while (!found){ + + // g_log.debug() << "Step " << counts << ": " << ist << " .... " << ied << std::endl; + + if (ied-ist == 1 || ied-ist == 0){ + // a) End case, tofs[ist] < eventtof < tofs[ied] + found = true; + iloc = ist; + // g_log.debug() << "Locate Event (" << eventtof << ") Between " << tofs[ist] << " , " << tofs[ied] << std::endl; + + } else { + // b) Binary search + size_t mid = (ied+ist)/2; + if (eventtof < tofs[mid]){ + ied = mid; + } else { + ist = mid; + } + } // if-else + + counts ++; + if (counts > searchlimit){ + iloc = 0; + g_log.error() << "Cannot locate Event with TOF = " << eventtof << " ... Exceeds max search limit: " << searchlimit << std::endl; + g_log.error() << "Final index = " << ist << ", " << ied << " TOF = " << tofs[ist] << ", " << tofs[ied] << std::endl; + throw std::invalid_argument("Debug Stop"); + break; + } + + } // while + } + + return iloc; + } + + + +} // namespace Mantid +} // namespace Algorithms + diff --git a/Code/Mantid/Framework/Algorithms/test/IDLRebinTest.h b/Code/Mantid/Framework/Algorithms/test/IDLRebinTest.h new file mode 100644 index 0000000000000000000000000000000000000000..5b05ca739d3f6124d1a49dbb4a2c092c278d7f63 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/IDLRebinTest.h @@ -0,0 +1,34 @@ +IDIDLL#ifndef MANTID_ALGORITHMS_VULCANREBINTEST_H_ +#define MANTID_ALGORITHMS_VULCANREBINTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidKernel/Timer.h" +#include "MantidKernel/System.h" +#include <iostream> +#include <iomanip> + +#include "MantidAlgorithms/IDLRebin.h" + +using namespace Mantid; +using namespace Mantid::Algorithms; +using namespace Mantid::API; + +class IDLRebinTest : 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 IDLRebinTest *createSuite() { return new IDLRebinTest(); } + static void destroySuite( IDLRebinTest *suite ) { delete suite; } + + + void test_Something() + { + } + + +}; + + +#endif /* MANTID_ALGORITHMS_VULCANREBINTEST_H_ */ +