Commit bc9dddc7 authored by Campbell, Stuart's avatar Campbell, Stuart
Browse files

refs #5439. Initial skeleton of algorithm.

Not functional yet, just committing for safety. Not in CMake.
Reads instrument name from NeXus file, then determines IDF.
Runs LoadEmptyInstrument().
parent 526045b8
#include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h"
namespace Mantid
namespace DataHandling
/** AppendGeometryToSNSNexus : Appends geometry information to a NeXus file.
@date 2012-06-01
Copyright © 2012 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
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 <>.
File change history is stored at: <>
Code Documentation is available at: <>
class DLLExport AppendGeometryToSNSNexus : public API::Algorithm
virtual ~AppendGeometryToSNSNexus();
virtual const std::string name() const;
virtual int version() const;
virtual const std::string category() const;
virtual void initDocs();
void init();
void exec();
/// The filename of the NeXus file to append geometry info to
std::string m_filename;
/// Instrument name
std::string m_instrument;
/// IDF filename
std::string m_idf_filename;
/// Get the instrument name from the NeXus file
std::string getInstrumentName(const std::string & nxfilename);
} // namespace DataHandling
} // namespace Mantid
This algorithm is intended to append the geometry information into a raw NeXus file.
It is initially for use only at the SNS, as it is needed for the currently upgrade program.
But there is nothing preventing it being used elsewhere.
The algorithm takes the geometry information in the IDF togther with the log values in a given NeXus file
and calculates the resolved positions of all the detectors and then writes this into the NeXus file specified.
#include "MantidDataHandling/AppendGeometryToSNSNexus.h"
#include "MantidKernel/System.h"
#include "MantidAPI/FileProperty.h"
#include "MantidDataObjects/Workspace2D.h"
#include "MantidNexusCPP/NeXusFile.hpp"
#include "MantidNexusCPP/NeXusException.hpp"
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace ::NeXus;
namespace Mantid
namespace DataHandling
// Register the algorithm into the AlgorithmFactory
/** Constructor
/** Destructor
/// Algorithm's name for identification. @see Algorithm::name
const std::string AppendGeometryToSNSNexus::name() const { return "AppendGeometryToSNSNexus";};
/// Algorithm's version for identification. @see Algorithm::version
int AppendGeometryToSNSNexus::version() const { return 1;};
/// Algorithm's category for identification. @see Algorithm::category
const std::string AppendGeometryToSNSNexus::category() const { return "DataHandling\\DataAcquisition";}
/// Sets documentation strings for this algorithm
void AppendGeometryToSNSNexus::initDocs()
this->setWikiSummary("Appends the resolved instrument geometry to a NeXus file.");
this->setOptionalMessage("Appends the resolved instrument geometry to a NeXus file.");
/** Initialize the algorithm's properties.
void AppendGeometryToSNSNexus::init()
// Declare potential extensions for input NeXus file
std::vector<std::string> extensions;
declareProperty(new API::FileProperty("Filename", "", API::FileProperty::Load, extensions),
"The name of the NeXus file to append geometry to.");
/** Execute the algorithm.
void AppendGeometryToSNSNexus::exec()
// Retrieve filename from the properties
m_filename = getPropertyValue("Filename");
// Let's look for the instrument name
m_instrument = getInstrumentName(m_filename);
// Temp workspace name to load the instrument into
std::string workspaceName = "__" + m_instrument + "_geometry_ws";
// Now what is the instrument definition filename ?
m_idf_filename = ExperimentInfo::getInstrumentFilename(m_instrument);
g_log.debug() << "Loading instrument definition from " << m_idf_filename << "." << std::endl;
// Let's load the empty instrument
IAlgorithm_sptr alg = AlgorithmFactory::Instance().create("LoadEmptyInstrument", 1);
alg->setPropertyValue("Filename", m_idf_filename);
alg->setPropertyValue("OutputWorkspace", workspaceName);
MatrixWorkspace_sptr ws;
ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(workspaceName);
// Get the number of histograms/detectors
const size_t numHistograms = ws->getNumberHistograms();
g_log.notice() << "Number of Histograms = " << numHistograms << std::endl;
for (size_t i=0; i < numHistograms; ++i)
Geometry::IDetector_const_sptr det = ws->getDetector(i);
if (det->isMonitor())
// TODO: Do the correct thing for the monitors
// Detector
// Clean up the workspace
std::string AppendGeometryToSNSNexus::getInstrumentName(const std::string &nxfilename)
std::string instrument;
// Open the NeXus file
::NeXus::File nxfile(nxfilename);
// What is the first entry ?
std::map<std::string, std::string> entries = nxfile.getEntries();
// For now, let's just open the first entry
nxfile.openGroup(entries.begin()->first, "NXentry");
g_log.debug() << "Using entry '" << entries.begin()->first << "' to determine instrument name." << std::endl;
nxfile.openGroup("instrument", "NXinstrument");
instrument = nxfile.getStrData();
catch (::NeXus::Exception &)
// TODO: try and get the instrument name from the filename instead.
instrument = "";
g_log.debug() << " Instrument name read from NeXus file is " << instrument << std::endl;
return instrument;
} // namespace Mantid
} // namespace DataHandling
#include <cxxtest/TestSuite.h>
#include "MantidKernel/Timer.h"
#include "MantidKernel/System.h"
#include <iostream>
#include <iomanip>
#include "MantidDataHandling/AppendGeometryToSNSNexus.h"
using namespace Mantid;
using namespace Mantid::DataHandling;
using namespace Mantid::API;
class AppendGeometryToSNSNexusTest : public CxxTest::TestSuite
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static AppendGeometryToSNSNexusTest *createSuite() { return new AppendGeometryToSNSNexusTest(); }
static void destroySuite( AppendGeometryToSNSNexusTest *suite ) { delete suite; }
void test_Init()
AppendGeometryToSNSNexus alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
void test_exec()
// // Name of the output workspace.
// std::string outWSName("AppendGeometryToSNSNexusTest_OutputWS");
AppendGeometryToSNSNexus alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", "CNCS_7860_event.nxs") );
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.
void xtest_Something()
TSM_ASSERT( "You forgot to write a test!", 0);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment