From fb5eea97709f1c6f223602b94261da8e09e20469 Mon Sep 17 00:00:00 2001 From: John Hill <john.r.hill@stfc.ac.uk> Date: Wed, 6 Aug 2014 16:28:05 +0100 Subject: [PATCH] Refs #10061 added files for loader --- .../Framework/DataHandling/CMakeLists.txt | 8 +- .../inc/MantidDataHandling/LoadFITS.h | 96 ++++++ .../Framework/DataHandling/src/LoadFITS.cpp | 294 ++++++++++++++++++ .../docs/source/algorithms/LoadFITS-v1.rst | 14 + 4 files changed, 409 insertions(+), 3 deletions(-) create mode 100644 Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h create mode 100644 Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp create mode 100644 Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst diff --git a/Code/Mantid/Framework/DataHandling/CMakeLists.txt b/Code/Mantid/Framework/DataHandling/CMakeLists.txt index 8edcfd12003..5527225abe3 100644 --- a/Code/Mantid/Framework/DataHandling/CMakeLists.txt +++ b/Code/Mantid/Framework/DataHandling/CMakeLists.txt @@ -22,7 +22,7 @@ set ( SRC_FILES src/Load.cpp src/LoadAscii.cpp src/LoadAscii2.cpp - src/LoadBBY.cpp + src/LoadBBY.cpp src/LoadCalFile.cpp src/LoadCanSAS1D.cpp src/LoadCanSAS1D2.cpp @@ -34,6 +34,7 @@ set ( SRC_FILES src/LoadEventNexus.cpp src/LoadEventPreNexus.cpp src/LoadEventPreNexus2.cpp + src/LoadFITS.cpp src/LoadFullprofResolution.cpp src/LoadGSASInstrumentFile.cpp src/LoadGSS.cpp @@ -163,7 +164,7 @@ set ( INC_FILES inc/MantidDataHandling/Load.h inc/MantidDataHandling/LoadAscii.h inc/MantidDataHandling/LoadAscii2.h - inc/MantidDataHandling/LoadBBY.h + inc/MantidDataHandling/LoadBBY.h inc/MantidDataHandling/LoadCalFile.h inc/MantidDataHandling/LoadCanSAS1D.h inc/MantidDataHandling/LoadCanSAS1D2.h @@ -175,6 +176,7 @@ set ( INC_FILES inc/MantidDataHandling/LoadEventNexus.h inc/MantidDataHandling/LoadEventPreNexus.h inc/MantidDataHandling/LoadEventPreNexus2.h + inc/MantidDataHandling/LoadFITS.h inc/MantidDataHandling/LoadFullprofResolution.h inc/MantidDataHandling/LoadGSASInstrumentFile.h inc/MantidDataHandling/LoadGSS.h @@ -226,7 +228,7 @@ set ( INC_FILES inc/MantidDataHandling/LoadSassena.h inc/MantidDataHandling/LoadSpec.h inc/MantidDataHandling/LoadSpice2D.h - inc/MantidDataHandling/LoadTOFRawNexus.h + inc/MantidDataHandling/LoadTOFRawNexus.h inc/MantidDataHandling/MaskDetectors.h inc/MantidDataHandling/MaskDetectorsInShape.h inc/MantidDataHandling/MergeLogs.h diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h new file mode 100644 index 00000000000..06ee83f0b03 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h @@ -0,0 +1,96 @@ +#ifndef MANTID_DATAHANDLING_LOADFITS_H_ +#define MANTID_DATAHANDLING_LOADFITS_H_ + +#include "MantidAPI/IFileLoader.h" + + +namespace Mantid +{ +namespace DataHandling +{ + /** LoadFITS : Load FITS files to TableWorkspace(s) + + Copyright © 2014 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://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ + + class DLLExport LoadFITS : public API::IFileLoader<Kernel::FileDescriptor> + { + public: + LoadFITS() {} + virtual ~LoadFITS() {} + + /// Algorithm's name for identification overriding a virtual method + virtual const std::string name() const { return "LoadFITS" ;} + + ///Summary of algorithms purpose + virtual const std::string summary() const {return "Load data from FITS files.";} + + /// 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 "DataHandling";} + + /// Returns a confidence value that this algorithm can load a file + virtual int confidence(Kernel::FileDescriptor & descriptor) const; + + private: + /// Initialisation code + void init(); + /// Execution code + void exec(); + + ///// Implement abstract Algorithm methods + //void init(); + ///// Implement abstract Algorithm methods + //void exec(); + + ///// Load file to a vector of strings + //void loadFile(std::string filename, std::vector<std::string>& lines); + + ///// Get Histogram type + //std::string getHistogramType(const std::vector<std::string>& lines); + + ///// Get Number of banks + //size_t getNumberOfBanks(const std::vector<std::string>& lines); + + ///// Scan imported file for bank information + //void scanBanks(const std::vector<std::string>& lines, std::vector<size_t>& bankStartIndex ); + + ///// Parse bank in file to a map + //void parseBank(std::map<std::string, double>& parammap, const std::vector<std::string>& lines, size_t bankid, size_t startlineindex, int nProf); + + ///// Find first INS line at or after lineIndex + //size_t findINSLine(const std::vector<std::string>& lines, size_t lineIndex); + + ///// Generate output workspace + //DataObjects::TableWorkspace_sptr genTableWorkspace(std::map<size_t, std::map<std::string, double> > bankparammap); + + + }; + + + + +} // namespace DataHandling +} // namespace Mantid + +#endif // MANTID_DATAHANDLING_LOADFITS_H_ diff --git a/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp b/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp new file mode 100644 index 00000000000..2275a68b869 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp @@ -0,0 +1,294 @@ +#include "MantidDataHandling/LoadFITS.h" + +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/RegisterFileLoader.h" +//#include "MantidAPI/WorkspaceValidators.h" +//#include "MantidKernel/UnitFactory.h" +//#include "MantidGeometry/Instrument.h" +//#include "MantidGeometry/Instrument/RectangularDetector.h" +//#include "MantidGeometry/Objects/ShapeFactory.h" +// +//#include "MantidNexus/NexusClasses.h" +// +//#include <boost/math/special_functions/fpclassify.hpp> +//#include <Poco/File.h> +//#include <iostream> +//#include <fstream> +//#include <iomanip> + +using namespace Mantid::DataHandling; +using namespace Mantid::API; +using namespace Mantid::Kernel; + +namespace Mantid +{ +namespace DataHandling +{ + // Register the algorithm into the AlgorithmFactory + DECLARE_FILELOADER_ALGORITHM(LoadFITS); + + int LoadFITS::confidence(Kernel::FileDescriptor & descriptor) const + { + return (descriptor.extension() == ".fits" || descriptor.extension() == ".fit") ? 80 : 0; + } + + /** + * Execute the algorithm. + */ + void LoadFITS::exec() + { + // Delete the output workspace name if it existed + std::string outName = getPropertyValue("OutputWorkspace"); + if (AnalysisDataService::Instance().doesExist(outName)) + AnalysisDataService::Instance().remove(outName); + + // Get the name of the file. + std::string filenameBin = getPropertyValue("Filename"); + + size_t nBins = 1; + double tofMinBoundary = 5; + double tofMaxBoundary = 5; + + //// 100 for "loading neutron counts", 100 for "creating neutron event lists", 100 for "loading neutron events" + //Progress prog(this, 0.0, 1.0, 100 + 100 + 100); + //prog.doReport("creating instrument"); + + // Create a workspace + DataObjects::EventWorkspace_sptr eventWS(new DataObjects::EventWorkspace()); + + eventWS->initialize( + nHist, + nBins + 1, // number of TOF bin boundaries + nBins); + + // Set the units + eventWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); + eventWS->setYUnit("Counts"); + + // ??? + //eventWS->setYUnitLabel("Counts"); + + eventWS->setTitle("my title"); + eventWS->mutableRun().addProperty("Filename", filenameBin); + //eventWS->mutableRun().addProperty("run_number", 1); + //eventWS->mutableRun().addProperty("run_start", "1991-01-01T00:00:00", true ); + //eventWS->mutableRun().addProperty("duration", duration[0], units); + + // Build instrument geometry + + // Create a new instrument and set its name + std::string instrumentname = "BILBY"; + Geometry::Instrument_sptr instrument(new Geometry::Instrument(instrumentname)); + eventWS->setInstrument(instrument); + + // Add dummy source and samplepos to instrument + + // Create an instrument component wich will represent the sample position. + Geometry::ObjComponent *samplepos = new Geometry::ObjComponent("Sample",instrument.get()); + instrument->add(samplepos); + instrument->markAsSamplePos(samplepos); + // Put the sample in the centre of the coordinate system + samplepos->setPos(0.0,0.0,0.0); + + // Create a component to represent the source + Geometry::ObjComponent *source = new Geometry::ObjComponent("Source",instrument.get()); + instrument->add(source); + instrument->markAsSource(source); + + // Read in the L1 value and place the source at (0,0,-L1) + double l1 = 3949.1824; + source->setPos(0.0,0.0,-1.0*l1); + + // Create a component for the detector. + + size_t xPixelCount = HISTO_BINS_X / 6; + size_t yPixelCount = HISTO_BINS_Y; + size_t pixelCount = xPixelCount * yPixelCount; + + // We assumed that these are the dimensions of the detector, and height is in y direction and width is in x direction + double width = 0.4; // meters + double height = 1.0; + + // We assumed that individual pixels have the same size and shape of a cuboid with dimensions: + double pixel_width = width / static_cast<double>(xPixelCount); + double pixel_height = height / static_cast<double>(yPixelCount); + + // Create size strings for shape creation + std::string pixel_width_str = boost::lexical_cast<std::string>(pixel_width / 2); + std::string pixel_height_str = boost::lexical_cast<std::string>(pixel_height / 2); + std::string pixel_depth_str = "0.00001"; // Set the depth of a pixel to a very small number + + // Define shape of a pixel as an XML string. See http://www.mantidproject.org/HowToDefineGeometricShape for details + // on shapes in Mantid. + std::string detXML = + "<cuboid id=\"pixel\">" + "<left-front-bottom-point x=\"+"+pixel_width_str+"\" y=\"-"+pixel_height_str+"\" z=\"0\" />" + "<left-front-top-point x=\"+"+pixel_width_str+"\" y=\"-"+pixel_height_str+"\" z=\""+pixel_depth_str+"\" />" + "<left-back-bottom-point x=\"-"+pixel_width_str+"\" y=\"-"+pixel_height_str+"\" z=\"0\" />" + "<right-front-bottom-point x=\"+"+pixel_width_str+"\" y=\"+"+pixel_height_str+"\" z=\"0\" />" + "</cuboid>"; + + // Create a shape object which will be shared by all pixels. + Geometry::Object_sptr shape = Geometry::ShapeFactory().createShape(detXML); + + double detectorZ = 5; + double angle = 10; + + double curtZOffset = width / 2 * sin(angle * 3.14159265359 / 180); + + if (!filenameHdf.empty()) { + NeXus::NXRoot root(filenameHdf); + NeXus::NXEntry entry = root.openFirstEntry(); + + } + + // 6 detector banks are available + + // curtain 1 + AddDetectorBank( + instrument, + xPixelCount, + yPixelCount, + 0 * pixelCount, + shape, + width, + height, + Kernel::V3D(+(width + height) / 2, 0, detectorZ - curtZOffset), + Kernel::Quat( 0, Kernel::V3D(0, 0, 1)) * Kernel::Quat(angle, Kernel::V3D(0, 1, 0))); + + // curtain 2 + AddDetectorBank( + instrument, + xPixelCount, + yPixelCount, + 1 * pixelCount, + shape, + width, + height, + Kernel::V3D(-(width + height) / 2, 0, detectorZ - curtZOffset), + Kernel::Quat(180, Kernel::V3D(0, 0, 1)) * Kernel::Quat(angle, Kernel::V3D(0, 1, 0))); + + // curtain 3 + AddDetectorBank( + instrument, + xPixelCount, + yPixelCount, + 2 * pixelCount, + shape, + width, + height, + Kernel::V3D(0, +(width + height) / 2, detectorZ - curtZOffset), + Kernel::Quat( 90, Kernel::V3D(0, 0, 1)) * Kernel::Quat(angle, Kernel::V3D(0, 1, 0))); + + // curtain 4 + AddDetectorBank( + instrument, + xPixelCount, + yPixelCount, + 3 * pixelCount, + shape, + width, + height, + Kernel::V3D(0, -(width + height) / 2, detectorZ - curtZOffset), + Kernel::Quat(-90, Kernel::V3D(0, 0, 1)) * Kernel::Quat(angle, Kernel::V3D(0, 1, 0))); + + // back 1 + AddDetectorBank( + instrument, + xPixelCount, + yPixelCount, + 4 * pixelCount, + shape, + width, + height, + Kernel::V3D(-width / 2 - 0.05, 0, detectorZ), + Kernel::Quat(180, Kernel::V3D(0, 0, 1))); + + // back 2 + AddDetectorBank( + instrument, + xPixelCount, + yPixelCount, + 5 * pixelCount, + shape, + width, + height, + Kernel::V3D(+width / 2 + 0.05, 0, detectorZ), + Kernel::Quat( 0, Kernel::V3D(0, 0, 1))); + + // load events + + size_t numberHistograms = eventWS->getNumberHistograms(); + + std::vector<EventVector_pt> eventVectors(numberHistograms, NULL); + std::vector<size_t> eventCounts(numberHistograms, 0); + std::vector<detid_t> detIDs = instrument->getDetectorIDs(); + + // count total events per pixel to reserve necessary memory + LoadFile_Counts(prog, filenameBin, HISTO_BINS_X, HISTO_BINS_Y, tofMinBoundary, tofMaxBoundary, eventCounts); + + // for progress notifications + size_t progCount = 100; + size_t progStep = numberHistograms / progCount; + size_t progNext = progStep; + + auto progMsg = "creating neutron event lists"; + prog.doReport(progMsg); + for (size_t i = 0; i != numberHistograms; ++i) { + DataObjects::EventList& eventList = eventWS->getEventList(i); + + eventList.setSortOrder(DataObjects::PULSETIME_SORT); // why not PULSETIME[TOF]_SORT ? + eventList.reserve(eventCounts[i]); + eventList.setDetectorID(detIDs[i]); + eventList.setSpectrumNo(detIDs[i]); + + DataObjects::getEventsFrom(eventList, eventVectors[i]); + + if ((progNext <= i) && (progCount != 0)) { + prog.report(progMsg); + progNext += progStep; + progCount--; + } + } + if (progCount != 0) + prog.reportIncrement(progCount, progMsg); + + double shortest_tof(0.0), longest_tof(0.0); + LoadFile_Events(prog, filenameBin, HISTO_BINS_X, HISTO_BINS_Y, tofMinBoundary, tofMaxBoundary, eventVectors, shortest_tof, longest_tof); + + cow_ptr<MantidVec> axis; + MantidVec& xRef = axis.access(); + xRef.resize(2, 0.0); + if (longest_tof != 0.0) { + xRef[0] = std::max(0.0, shortest_tof - 1); // just to make sure the bins hold it all + xRef[1] = longest_tof + 1; + } + eventWS->setAllX(axis); + + setProperty("OutputWorkspace", eventWS); + } + + /** + * Initialise the algorithm. Declare properties which can be set before execution (input) or + * read from after the execution (output). + */ + void LoadFITS::init() + { + // Specify file extensions which can be associated with a BBY file. + std::vector<std::string> exts; + + // Declare the Filename algorithm property. Mandatory. Sets the path to the file to load. + exts.clear(); + exts.push_back(".fit"); + declareProperty( + new API::FileProperty("Filename", "", API::FileProperty::Load, exts), + "The input filename of the stored data"); + + declareProperty( + new API::WorkspaceProperty<API::IEventWorkspace>("OutputWorkspace", "", Kernel::Direction::Output)); + } + + +} +} \ No newline at end of file diff --git a/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst b/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst new file mode 100644 index 00000000000..557447bc10f --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst @@ -0,0 +1,14 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Load data from FITS files + +.. categories:: -- GitLab