Newer
Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidDataHandling/UpdateInstrumentFromRaw.h"
Gigg, Martyn Anthony
committed
#include "MantidGeometry/Instrument/Instrument.h"
#include "MantidGeometry/Instrument/Detector.h"
#include "MantidGeometry/Instrument/CompAssembly.h"
#include "MantidGeometry/Instrument/Component.h"
#include "LoadRaw/isisraw.h"
#include "MantidKernel/ArrayProperty.h"
Gigg, Martyn Anthony
committed
#include "MantidKernel/ConfigService.h"
#include "MantidAPI/FileProperty.h"
#include <fstream>
namespace Mantid
{
namespace DataHandling
{
DECLARE_ALGORITHM(UpdateInstrumentFromRaw)
using namespace Kernel;
using namespace API;
Gigg, Martyn Anthony
committed
using Geometry::Instrument;
/// Empty default constructor
UpdateInstrumentFromRaw::UpdateInstrumentFromRaw()
{}
/// Initialisation method.
void UpdateInstrumentFromRaw::init()
{
Janik Zikovsky
committed
//this->setWikiSummary("Updating detector positions initially loaded in from Instrument Defintion File ([[InstrumentDefinitionFile|IDF]]) from information in raw files. Note doing this will results in a slower performance (likely slightly slower performance) compared to specifying the correct detector positions in the IDF in the first place. It is assumed that the positions specified in the raw file are all with respect to the a coordinate system defined with its origin at the sample position.Note that this algorithm moves the detectors without subsequent rotation, hence this means that detectors may not for example face the sample perfectly after this algorithm has been applied.");
//this->setOptionalMessage("Updating detector positions initially loaded in from Instrument Defintion File (IDF) from information in raw files. Note doing this will results in a slower performance (likely slightly slower performance) compared to specifying the correct detector positions in the IDF in the first place. It is assumed that the positions specified in the raw file are all with respect to the a coordinate system defined with its origin at the sample position. Note that this algorithm moves the detectors without subsequent rotation, hence this means that detectors may not for example face the sample perfectly after this algorithm has been applied.");
// When used as a sub-algorithm the workspace name is not used - hence the "Anonymous" to satisfy the validator
declareProperty(
new WorkspaceProperty<MatrixWorkspace>("Workspace","Anonymous",Direction::InOut),
"The name of the workspace in which to store the imported instrument" );
std::vector<std::string> exts;
Peterson, Peter
committed
exts.push_back(".raw");
exts.push_back(".s*");
declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts),
"The filename (including its full or relative path) of an ISIS RAW file.\n"
Steve Williams
committed
"The file extension must either be .raw or .s??" );
}
/** Executes the algorithm. Reading in the file and creating and populating
* the output workspace
*
* @throw FileError Thrown if unable to parse XML file
*/
void UpdateInstrumentFromRaw::exec()
{
// Retrieve the filename from the properties
m_filename = getPropertyValue("Filename");
// Get the input workspace
const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace");
// open raw file
ISISRAW iraw(NULL);
if (iraw.readFromFile(m_filename.c_str(),false) != 0)
{
g_log.error("Unable to open file " + m_filename);
throw Exception::FileError("Unable to open File:" , m_filename);
}
Gigg, Martyn Anthony
committed
boost::shared_ptr<Instrument> instrument = localWorkspace->getBaseInstrument();
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
if (instrument.get() == 0)
{
g_log.error("Trying to use ParInstrument as an Instrument.");
throw std::runtime_error("Trying to use ParInstrument as an Instrument.");
}
// get instrument samplepos
Geometry::IObjComponent_sptr samplepos = instrument->getSample();
progress(0.5);
// add detectors
const int numDetector = iraw.i_det; // number of detectors
const int* const detID = iraw.udet; // detector IDs
const float* const r = iraw.len2; // distance from sample
const float* const angle = iraw.tthe; // angle between indicent beam and direction from sample to detector (two-theta)
const float* const phi=iraw.ut;
// Is ut01 (=phi) present? Sometimes an array is present but has wrong values e.g.all 1.0 or all 2.0
bool phiPresent = iraw.i_use>0 && phi[0]!= 1.0 && phi[0] !=2.0;
double prog=0.5;
for (int i = 0; i < numDetector; ++i)
{
// check if detID[i] is represented in IDF and if yes set position
try
{
// throws exception if not found
Geometry::IDetector_sptr det = instrument->getDetector(detID[i]);
// get postion of parent
Geometry::V3D parentPos = det->getPos() - det->getRelativePos();
// Get position from raw file.
Geometry::V3D pos;
if(phiPresent)
pos.spherical(r[i], angle[i], phi[i]);
else
pos.spherical(r[i], angle[i], 0.0 );
// sets new relative position to parent so that its absolute position
// is where the raw file says it is.
det->setPos(pos-parentPos);
}
catch (...)
{
// if detector was not found do nothing in this case
}
progress(prog);
}
return;
}
} // namespace DataHandling
} // namespace Mantid