Skip to content
Snippets Groups Projects
Commit d1879816 authored by Michael Reuter's avatar Michael Reuter
Browse files

Merge remote-tracking branch 'origin/feature/4963_instrument_save_nexus'

parents 1b03e1b2 981cce74
No related branches found
No related tags found
No related merge requests found
......@@ -148,9 +148,6 @@ namespace API
Geometry::Instrument_const_sptr sptr_instrument;
private:
/// Save information about a set of detectors to Nexus
void saveDetectorSetInfoToNexus (::NeXus::File * file, std::vector<detid_t> detIDs ) const;
/// Detector grouping information
det2group_map m_detgroups;
......
......@@ -839,116 +839,11 @@ namespace API
void ExperimentInfo::saveExperimentInfoNexus(::NeXus::File * file) const
{
Instrument_const_sptr instrument = getInstrument();
// Start with instrument info (name, file, full XML text)
file->makeGroup("instrument", "NXinstrument", true);
file->putAttr("version", 1);
file->writeData("name", instrument->getName() );
// XML contents of instrument, as a NX note
file->makeGroup("instrument_xml", "NXnote", true);
file->writeData("data", instrument->getXmlText() );
file->writeData("type", "text/xml"); // mimetype
file->writeData("description", "XML contents of the instrument IDF file.");
file->closeGroup();
file->writeData("instrument_source", Poco::Path(instrument->getFilename()).getFileName());
// Now the parameter map, as a NXnote
const Geometry::ParameterMap& params = constInstrumentParameters();
std::string str = params.asString();
file->makeGroup("instrument_parameter_map", "NXnote", true);
file->writeData("data", str);
file->writeData("type", "text/plain"); // mimetype
file->closeGroup();
// Add physical detector and monitor data
std::vector<detid_t> detectorIDs;
std::vector<detid_t> detmonIDs;
detectorIDs = instrument->getDetectorIDs( true );
detmonIDs = instrument->getDetectorIDs( false );
if( !detmonIDs.empty() )
{
// Add detectors group
file->makeGroup("physical_detectors","NXdetector", true);
file->writeData("number_of_detectors", uint64_t(detectorIDs.size()) );
saveDetectorSetInfoToNexus ( file, detectorIDs );
file->closeGroup(); // detectors
// Create Monitor IDs vector
std::vector<IDetector_const_sptr> detmons;
detmons = instrument->getDetectors( detmonIDs );
std::vector<detid_t> monitorIDs;
for (size_t i=0; i < detmonIDs.size(); i++)
{
if( detmons[i]->isMonitor()) monitorIDs.push_back( detmonIDs[i] );
}
// Add Monitors group
file->makeGroup("physical_monitors","NXmonitor", true);
file->writeData("number_of_monitors", uint64_t(monitorIDs.size()) );
saveDetectorSetInfoToNexus ( file, monitorIDs );
file->closeGroup(); // monitors
}
file->closeGroup(); // (close the instrument group)
instrument->saveNexus( file, "instrument");
m_sample->saveNexus(file, "sample");
m_run->saveNexus(file, "logs");
}
/* A private helper function so save information about a set of detectors to Nexus
* @param file :: open Nexus file ready to recieve the info about the set of detectors
* a group must be open that has only one call of this function.
* @detIDs the dectector IDs of the detectors belonging to the set
*/
void ExperimentInfo::saveDetectorSetInfoToNexus (::NeXus::File * file, std::vector<detid_t> detIDs ) const
{
Instrument_const_sptr instrument = getInstrument();
size_t nDets = detIDs.size();
if( nDets == 0) return;
std::vector<IDetector_const_sptr> detectors;
detectors = instrument->getDetectors( detIDs );
Geometry::IObjComponent_const_sptr sample = instrument->getSample();
Kernel::V3D sample_pos;
if(sample) sample_pos = sample->getPos();
std::vector<double> a_angles( nDets );
std::vector<double> p_angles( nDets );
std::vector<double> distances( nDets );
for (size_t i=0; i < nDets; i++)
{
if( sample)
{
Kernel::V3D pos = detectors[i]->getPos() - sample_pos;
pos.getSpherical( distances[i], p_angles[i], a_angles[i]);
} else {
a_angles[i] = detectors[i]->getPhi()*180.0/M_PI;
}
}
file->writeData("detector_number", detIDs);
file->writeData("azimuthal_angle", a_angles);
file->openData("azimuthal_angle");
file->putAttr("units","degree");
file->closeData();
if(sample)
{
file->writeData("polar_angle", p_angles);
file->openData("polar_angle");
file->putAttr("units","degree");
file->closeData();
file->writeData("distance", distances);
file->openData("distance");
file->putAttr("units","metre");
file->closeData();
}
}
//--------------------------------------------------------------------------------------------
/** Load the object from an open NeXus file.
* @param file :: open NeXus file
......
......@@ -223,6 +223,9 @@ namespace Mantid
boost::shared_ptr<const ReferenceFrame> getReferenceFrame() const;
private:
/// Save information about a set of detectors to Nexus
void saveDetectorSetInfoToNexus (::NeXus::File * file, std::vector<detid_t> detIDs ) const;
/// Private copy assignment operator
Instrument& operator=(const Instrument&);
......
......@@ -10,6 +10,7 @@
#include <algorithm>
#include <iostream>
#include <sstream>
#include <Poco/Path.h>
using namespace Mantid::Kernel;
using Mantid::Kernel::Exception::NotFoundError;
......@@ -1057,14 +1058,111 @@ namespace Mantid
{
file->makeGroup(group, "NXinstrument", 1);
file->putAttr("version", 1);
file->writeData("name", getName() );
// XML contents of instrument, as a NX note
file->makeGroup("instrument_xml", "NXnote", true);
file->writeData("data", getXmlText() );
file->writeData("type", "text/xml"); // mimetype
file->writeData("description", "XML contents of the instrument IDF file.");
file->closeGroup();
file->writeData("instrument_source", Poco::Path(getFilename()).getFileName());
// Now the parameter map, as a NXnote via its saveNexus method
if(isParametrized()){
const Geometry::ParameterMap& params = *getParameterMap();
params.saveNexus( file, "instrument_parameter_map" );
}
// Add physical detector and monitor data
std::vector<detid_t> detectorIDs;
std::vector<detid_t> detmonIDs;
detectorIDs = getDetectorIDs( true );
detmonIDs = getDetectorIDs( false );
if( !detmonIDs.empty() )
{
// Add detectors group
file->makeGroup("physical_detectors","NXdetector", true);
file->writeData("number_of_detectors", uint64_t(detectorIDs.size()) );
saveDetectorSetInfoToNexus ( file, detectorIDs );
file->closeGroup(); // detectors
// Create Monitor IDs vector
std::vector<IDetector_const_sptr> detmons;
detmons = getDetectors( detmonIDs );
std::vector<detid_t> monitorIDs;
for (size_t i=0; i < detmonIDs.size(); i++)
{
if( detmons[i]->isMonitor()) monitorIDs.push_back( detmonIDs[i] );
}
// Add Monitors group
file->makeGroup("physical_monitors","NXmonitor", true);
file->writeData("number_of_monitors", uint64_t(monitorIDs.size()) );
saveDetectorSetInfoToNexus ( file, monitorIDs );
file->closeGroup(); // monitors
}
file->closeGroup();
}
/* A private helper function so save information about a set of detectors to Nexus
* @param file :: open Nexus file ready to recieve the info about the set of detectors
* a group must be open that has only one call of this function.
* @param detIDs :: the dectector IDs of the detectors belonging to the set
*/
void Instrument::saveDetectorSetInfoToNexus (::NeXus::File * file, std::vector<detid_t> detIDs ) const
{
size_t nDets = detIDs.size();
if( nDets == 0) return;
std::vector<IDetector_const_sptr> detectors;
detectors = getDetectors( detIDs );
Geometry::IObjComponent_const_sptr sample = getSample();
Kernel::V3D sample_pos;
if(sample) sample_pos = sample->getPos();
std::vector<double> a_angles( nDets );
std::vector<double> p_angles( nDets );
std::vector<double> distances( nDets );
for (size_t i=0; i < nDets; i++)
{
if( sample)
{
Kernel::V3D pos = detectors[i]->getPos() - sample_pos;
pos.getSpherical( distances[i], p_angles[i], a_angles[i]);
} else {
a_angles[i] = detectors[i]->getPhi()*180.0/M_PI;
}
}
file->writeData("detector_number", detIDs);
file->writeData("azimuthal_angle", a_angles);
file->openData("azimuthal_angle");
file->putAttr("units","degree");
file->closeData();
if(sample)
{
file->writeData("polar_angle", p_angles);
file->openData("polar_angle");
file->putAttr("units","degree");
file->closeData();
file->writeData("distance", distances);
file->openData("distance");
file->putAttr("units","metre");
file->closeData();
}
}
//--------------------------------------------------------------------------------------------
/** Load the object from an open NeXus file.
* @param file :: open NeXus file
* @param group :: name of the group to open
*/
* @param file :: open NeXus file
* @param group :: name of the group to open
*/
void Instrument::loadNexus(::NeXus::File * file, const std::string & group)
{
file->openGroup(group, "NXinstrument");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment