Skip to content

Commit

Permalink
Re #9249 Center and rotate detector according to data file
Browse files Browse the repository at this point in the history
  • Loading branch information
YRaoul committed May 26, 2014
1 parent 2a36af7 commit db20f7c
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 7 deletions.
Expand Up @@ -57,7 +57,10 @@ class DLLExport LoadHelper {
void dumpNexusAttributes(NXhandle nxfileID, std::string& indentStr);
std::string dateTimeInIsoFormat(std::string);
void moveComponent(API::MatrixWorkspace_sptr ws, const std::string &componentName,const Kernel::V3D& newPos);
void rotateComponent(API::MatrixWorkspace_sptr ws, const std::string &componentName, const Kernel::Quat & rot);
Kernel::V3D getComponentPosition(API::MatrixWorkspace_sptr ws, const std::string &componentName);
template<typename T>
T getPropertyFromRun(API::MatrixWorkspace_const_sptr inputWS, const std::string& propertyName);
};

} // namespace DataHandling
Expand Down
Expand Up @@ -60,6 +60,8 @@ namespace DataHandling
void loadNexusEntriesIntoProperties(std::string nexusfilename);
std::vector< std::vector<int> > loadMonitors(NeXus::NXEntry& entry);
void runLoadInstrument();
void centerDetector(double);
void placeDetector(double, double);

API::MatrixWorkspace_sptr m_localWorkspace;

Expand Down
36 changes: 34 additions & 2 deletions Code/Mantid/Framework/DataHandling/src/LoadHelper.cpp
Expand Up @@ -311,7 +311,7 @@ void LoadHelper::addNexusFieldsToWsRun(NXhandle nxfileID,

if (dims[0]!=1) {
g_log.debug()<<indent_str<<property_name<<" is an array..."<<std::endl;
if (dims[0]>10) {
if (dims[0]>9) {
g_log.debug()<<indent_str<<" skipping it (size="<<dims[0]<<")."<<std::endl;
NXfree(&dataBuffer);
continue;
Expand All @@ -336,7 +336,7 @@ void LoadHelper::addNexusFieldsToWsRun(NXhandle nxfileID,
else
runDetails.addProperty(property_name, property_double_value);
} else {
// An array
// An array, converted to "name_index", with index < 10 (see test above)
for (int dim_index=0 ; dim_index<dims[0]; dim_index++) {
if (type==NX_FLOAT32) {
property_double_value = ((float*)dataBuffer)[dim_index];
Expand Down Expand Up @@ -441,6 +441,27 @@ void LoadHelper::moveComponent(API::MatrixWorkspace_sptr ws, const std::string &

}

void LoadHelper::rotateComponent(API::MatrixWorkspace_sptr ws, const std::string &componentName, const Kernel::Quat & rot) {

try {

Geometry::Instrument_const_sptr instrument = ws->getInstrument();
Geometry::IComponent_const_sptr component = instrument->getComponentByName(componentName);

//g_log.debug() << tube->getName() << " : t = " << theta << " ==> t = " << newTheta << "\n";
Geometry::ParameterMap& pmap = ws->instrumentParameters();
Geometry::ComponentHelper::rotateComponent(*component, pmap, rot, Geometry::ComponentHelper::Absolute);

} catch (Mantid::Kernel::Exception::NotFoundError&) {
throw std::runtime_error(
"Error when trying to move the " + componentName + " : NotFoundError");
} catch (std::runtime_error &) {
throw std::runtime_error(
"Error when trying to move the " + componentName + " : runtime_error");
}

}

V3D LoadHelper::getComponentPosition(API::MatrixWorkspace_sptr ws, const std::string &componentName) {
try {
Geometry::Instrument_const_sptr instrument = ws->getInstrument();
Expand All @@ -453,5 +474,16 @@ V3D LoadHelper::getComponentPosition(API::MatrixWorkspace_sptr ws, const std::st
}
}

template<typename T>
T LoadHelper::getPropertyFromRun(API::MatrixWorkspace_const_sptr inputWS, const std::string& propertyName){
if (inputWS->run().hasProperty(propertyName)) {
Kernel::Property* prop = inputWS->run().getProperty(propertyName);
return boost::lexical_cast<T>(prop->value());
} else {
std::string mesg = "No '" + propertyName + "' property found in the input workspace....";
throw std::runtime_error(mesg);
}
}

} // namespace DataHandling
} // namespace Mantid
55 changes: 54 additions & 1 deletion Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp
Expand Up @@ -132,7 +132,30 @@ void LoadILLReflectometry::exec() {
g_log.debug("Loading instrument definition...");
runLoadInstrument();

//moveSingleDetectors(); Work in progress



// 1) Move

// Get distance and tilt angle stored in nexus file
// Mantid way
// auto angleProp = dynamic_cast<PropertyWithValue<double>*>(m_localWorkspace->run().getProperty("dan.value"));
// Nexus way
double angle = firstEntry.getFloat("instrument/dan/value");// detector angle in degrees
double distance = firstEntry.getFloat("instrument/det/value");// detector distance in millimeter
distance /= 1000;// convert to meter
placeDetector(distance, angle);

// 2) Center, (must be done after move)
int par1_101 = firstEntry.getInt("instrument/PSD/ny");
g_log.debug("Note: using PSD/ny instead of PSD/nx. Should be corrected in next D17 nexus file.");
double xCenter = 0.1325 / par1_101;// As in lamp, but in meter
centerDetector(xCenter);


// Set the channel width property
auto channel_width = dynamic_cast<PropertyWithValue<double>*>(m_localWorkspace->run().getProperty("monitor1.time_of_flight_0"));
m_localWorkspace->mutableRun().addProperty<double>("channel_width", *channel_width, true); //overwrite

// Set the output workspace property
setProperty("OutputWorkspace", m_localWorkspace);
Expand Down Expand Up @@ -367,7 +390,37 @@ void LoadILLReflectometry::runLoadInstrument() {
}
}

void LoadILLReflectometry::centerDetector(double xCenter) {

std::string componentName("uniq_detector");
V3D pos = m_loader.getComponentPosition(m_localWorkspace, componentName);
// TODO confirm!
pos.setX(pos.X() - xCenter);
m_loader.moveComponent(m_localWorkspace, componentName, pos);

}

void LoadILLReflectometry::placeDetector(
double distance /* meter */,
double angle /* degree */) {

std::string componentName("uniq_detector");
V3D pos = m_loader.getComponentPosition(m_localWorkspace, componentName);

double r, theta, phi;
pos.getSpherical(r, theta, phi);


V3D newpos;
newpos.spherical(distance, angle, phi);

m_loader.moveComponent(m_localWorkspace, componentName, newpos);

// Apply a local rotation to stay perpendicular to the beam
const V3D axis(0.0,1.0,0.0);
Quat rotation(angle, axis);
m_loader.rotateComponent(m_localWorkspace, componentName, rotation);

}
} // namespace DataHandling
} // namespace Mantid
23 changes: 23 additions & 0 deletions Code/Mantid/Framework/DataHandling/test/LoadILLReflectometryTest.h
Expand Up @@ -55,6 +55,14 @@ class LoadILLReflectometryTest: public CxxTest::TestSuite {
outWSName);
TS_ASSERT(output);

TS_ASSERT_EQUALS(output->getNumberHistograms(),256+2);

double channelWidth = getPropertyFromRun<double>(output, "channel_width");
TS_ASSERT_EQUALS(channelWidth, 57.0);




if (!output)
return;

Expand All @@ -68,6 +76,21 @@ class LoadILLReflectometryTest: public CxxTest::TestSuite {
private:
std::string m_dataFile;


template<typename T>
T getPropertyFromRun(MatrixWorkspace_const_sptr inputWS,
const std::string& propertyName) {
if (inputWS->run().hasProperty(propertyName)) {
Mantid::Kernel::Property* prop = inputWS->run().getProperty(propertyName);
return boost::lexical_cast<T>(prop->value());
} else {
std::string mesg = "No '" + propertyName
+ "' property found in the input workspace....";
throw std::runtime_error(mesg);
}
}


};

#endif /* MANTID_DATAHANDLING_LOADILLREFLECTOMETRYTEST_H_ */
6 changes: 3 additions & 3 deletions Code/Mantid/instrument/D17_Definition.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- For help on the notation used to specify an Instrument Definition File see http://www.mantidproject.org/IDF -->
<instrument xmlns="http://www.mantidproject.org/IDF/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 Schema/IDFSchema.xsd" name="D17" valid-from="1900-01-31 23:59:59"
valid-to="2100-01-31 23:59:59" last-modified="2014-05-16 13:27:36">
valid-to="2100-01-31 23:59:59" last-modified="2014-05-26 14:06:31">
<!-- Author: ricardo.leal@ill.fr -->
<defaults>
<length unit="meter" />
Expand Down Expand Up @@ -54,8 +54,8 @@ valid-to="2100-01-31 23:59:59" last-modified="2014-05-16 13:27:36">
</component>
<!-- Detector Panels -->
<type name="detectors">
<component type="uniq_detector" idstart="2" idfillbyfirst="x" idstep="1" idstepbyrow="256">
<location z='3.100000' />
<component type="uniq_detector" idstart="2" idfillbyfirst="x" idstep="1" idstepbyrow="256" name="uniq_detector">
<location z="3.100000" />
</component>
</type>
<!-- Definition of the detector -->
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/instrument/D17_Parameters.xml
Expand Up @@ -13,7 +13,7 @@
<parameter name="channel_width" type="string">
<value val="monitor1.time_of_flight_0" />
</parameter>
<!-- Get value from poperties -->
<!-- Get value from properties -->
<parameter name="detector_distance" type="string">
<value val="det.value" />
</parameter>
Expand Down

0 comments on commit db20f7c

Please sign in to comment.