Skip to content
Snippets Groups Projects
Commit 95812aab authored by Anders Markvardsen's avatar Anders Markvardsen
Browse files

Code for Allow nested <rot> when <offsets spherical="delta" /> set in IDF. New...

Code for Allow nested <rot> when <offsets spherical="delta" /> set in IDF. New collection of tests when spherical="delta" plus other additional tests. re #1931
parent b5fd11e5
No related branches found
No related tags found
No related merge requests found
......@@ -210,6 +210,9 @@ namespace Mantid
/// get name of location element
std::string getNameOfLocationElement(Poco::XML::Element* pElem);
/// Calculate the position of comp relative to its parent from info provided by <location> element
Geometry::V3D getRelativeTranslation(const Geometry::IComponent* comp, const Poco::XML::Element* pElem);
};
} // namespace DataHandling
......
......@@ -808,24 +808,17 @@ namespace Mantid
//-----------------------------------------------------------------------------------------------------------------------
/** Set location (position) of comp as specified in XML location element.
/** Calculate the position of comp relative to its parent from info provided by <location> element.
*
* @param comp To set position/location off
* @param pElem Poco::XML element that points a location element in the XML doc
*
* @throw logic_error Thrown if second argument is not a pointer to a 'location' XML element
* @return Thrown if second argument is not a pointer to a 'location' XML element
*/
void LoadInstrument::setLocation(Geometry::IComponent* comp, Poco::XML::Element* pElem)
Geometry::V3D LoadInstrument::getRelativeTranslation(const Geometry::IComponent* comp, const Poco::XML::Element* pElem)
{
// Require that pElem points to an element with tag name 'location'
if ( (pElem->tagName()).compare("location") )
{
g_log.error("Second argument to function setLocation must be a pointer to an XML element with tag name location.");
throw std::logic_error( "Second argument to function setLocation must be a pointer to an XML element with tag name location." );
}
Geometry::V3D pos; // position for <location>
Geometry::V3D retVal; // position relative to parent
// Polar coordinates can be labelled as (r,t,p) or (R,theta,phi)
if ( pElem->hasAttribute("r") || pElem->hasAttribute("t") || pElem->hasAttribute("p") ||
......@@ -851,7 +844,14 @@ namespace Mantid
// Get the parent's absolute position (if the component has a parent)
if ( comp->getParent() )
{
SphVec parent = m_tempPosHolder[comp->getParent().get()];
std::map<const Geometry::IComponent*, SphVec>::iterator it;
it = m_tempPosHolder.find(comp);
SphVec parent;
if ( it == m_tempPosHolder.end() )
parent = m_tempPosHolder[comp->getParent().get()];
else
parent = it->second;
// Add to the current component to get its absolute position
R += parent.r;
theta += parent.theta;
......@@ -871,15 +871,12 @@ namespace Mantid
absPos.spherical(R,theta,phi);
// Subtract the two V3D's to get what we want (child's relative position in x,y,z)
Geometry::V3D relPos;
relPos = absPos - parentPos;
comp->translate(relPos);
retVal = absPos - parentPos;
}
else
{
// In this case, the value given represents a vector from the parent to the child
pos.spherical(R,theta,phi);
comp->translate(pos);
retVal.spherical(R,theta,phi);
}
}
......@@ -891,10 +888,37 @@ namespace Mantid
if ( pElem->hasAttribute("y") ) y = atof((pElem->getAttribute("y")).c_str());
if ( pElem->hasAttribute("z") ) z = atof((pElem->getAttribute("z")).c_str());
pos(x,y,z);
comp->translate(pos);
retVal(x,y,z);
}
return retVal;
}
//-----------------------------------------------------------------------------------------------------------------------
/** Set location (position) of comp as specified in XML location element.
*
* @param comp To set position/location off
* @param pElem Poco::XML element that points a location element in the XML doc
*
* @throw logic_error Thrown if second argument is not a pointer to a 'location' XML element
*/
void LoadInstrument::setLocation(Geometry::IComponent* comp, Poco::XML::Element* pElem)
{
// Require that pElem points to an element with tag name 'location'
if ( (pElem->tagName()).compare("location") )
{
g_log.error("Second argument to function setLocation must be a pointer to an XML element with tag name location.");
throw std::logic_error( "Second argument to function setLocation must be a pointer to an XML element with tag name location." );
}
//Geometry::V3D pos; // position for <location>
comp->translate(getRelativeTranslation(comp, pElem));
// Rotate coordinate system of this component
......@@ -917,17 +941,12 @@ namespace Mantid
}
// Check if sub-elements <trans> or <rot> of present - for now ignore these if m_deltaOffset = true
Element* pRecursive = pElem;
if ( !m_deltaOffsets )
bool stillTransElement = true;
while ( stillTransElement )
{
bool stillTransElement = true;
//Geometry::V3D posTrans;
while ( stillTransElement )
{
// figure out if child element is <trans> or <rot> or none of these
Element* tElem = pRecursive->getChildElement("trans");
......@@ -935,83 +954,57 @@ namespace Mantid
if (tElem && rElem)
{
// if both a <trans> and <rot> child element present. Ignore <rot> element
rElem = NULL;
// if both a <trans> and <rot> child element present. Ignore <rot> element
rElem = NULL;
}
if (!tElem && !rElem)
{
stillTransElement = false;
stillTransElement = false;
}
Geometry::V3D posTrans;
if (tElem)
{
// Polar coordinates can be labelled as (r,t,p) or (R,theta,phi)
if ( tElem->hasAttribute("r") || tElem->hasAttribute("t") || tElem->hasAttribute("p") ||
tElem->hasAttribute("R") || tElem->hasAttribute("theta") || tElem->hasAttribute("phi") )
{
double R=0.0, theta=0.0, phi=0.0;
if ( tElem->hasAttribute("r") ) R = atof((tElem->getAttribute("r")).c_str());
if ( tElem->hasAttribute("t") ) theta = atof((tElem->getAttribute("t")).c_str());
if ( tElem->hasAttribute("p") ) phi = atof((tElem->getAttribute("p")).c_str());
if ( tElem->hasAttribute("R") ) R = atof((tElem->getAttribute("R")).c_str());
if ( tElem->hasAttribute("theta") ) theta = atof((tElem->getAttribute("theta")).c_str());
if ( tElem->hasAttribute("phi") ) phi = atof((tElem->getAttribute("phi")).c_str());
posTrans.spherical(R,theta,phi);
}
else
{
double x=0.0, y=0.0, z=0.0;
if ( tElem->hasAttribute("x") ) x = atof((tElem->getAttribute("x")).c_str());
if ( tElem->hasAttribute("y") ) y = atof((tElem->getAttribute("y")).c_str());
if ( tElem->hasAttribute("z") ) z = atof((tElem->getAttribute("z")).c_str());
posTrans(x,y,z);
}
posTrans = getRelativeTranslation(comp, tElem);
// to get the change in translation relative to current rotation of comp
Geometry::CompAssembly compToGetRot;
Geometry::CompAssembly compRot;
compRot.setRot(comp->getRotation());
compToGetRot.setParent(&compRot);
compToGetRot.setPos(posTrans);
// to get the change in translation relative to current rotation of comp
Geometry::CompAssembly compToGetRot;
Geometry::CompAssembly compRot;
compRot.setRot(comp->getRotation());
compToGetRot.setParent(&compRot);
compToGetRot.setPos(posTrans);
// Apply translation
comp->translate(compToGetRot.getPos());
// Apply translation
comp->translate(compToGetRot.getPos());
// for recursive action
pRecursive = tElem;
// for recursive action
pRecursive = tElem;
} // end translation
if (rElem)
{
double rotAngle = atof( (rElem->getAttribute("val")).c_str() ); // assumed to be in degrees
double rotAngle = atof( (rElem->getAttribute("val")).c_str() ); // assumed to be in degrees
double axis_x = 0.0;
double axis_y = 0.0;
double axis_z = 1.0;
double axis_x = 0.0;
double axis_y = 0.0;
double axis_z = 1.0;
if ( rElem->hasAttribute("axis-x") )
if ( rElem->hasAttribute("axis-x") )
axis_x = atof( (rElem->getAttribute("axis-x")).c_str() );
if ( rElem->hasAttribute("axis-y") )
if ( rElem->hasAttribute("axis-y") )
axis_y = atof( (rElem->getAttribute("axis-y")).c_str() );
if ( rElem->hasAttribute("axis-z") )
if ( rElem->hasAttribute("axis-z") )
axis_z = atof( (rElem->getAttribute("axis-z")).c_str() );
comp->rotate(Geometry::Quat(rotAngle, Geometry::V3D(axis_x,axis_y,axis_z)));
comp->rotate(Geometry::Quat(rotAngle, Geometry::V3D(axis_x,axis_y,axis_z)));
// for recursive action
pRecursive = rElem;
// for recursive action
pRecursive = rElem;
}
} // end while
} // end if ( !m_deltaOffsets )
} // end while
}
......
......@@ -298,6 +298,30 @@ public:
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 8.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 0.0, 0.0001);
ptrDet1 = i->getDetector(1010);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation8");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 11.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 8.0, 0.0001);
ptrDet1 = i->getDetector(1011);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation9");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 11.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), -8.0, 0.0001);
ptrDet1 = i->getDetector(1012);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation10");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 11.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 8.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 0.0, 0.0001);
ptrDet1 = i->getDetector(1013);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation11");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 11.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), -8.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 0.0, 0.0001);
// test parameter rotation
ptrDet1 = i->getDetector(1200);
TS_ASSERT_EQUALS( ptrDet1->getName(), "param rot-test");
......@@ -374,6 +398,119 @@ public:
AnalysisDataService::Instance().remove(wsName);
}
// Tests specific to when <offsets spherical="delta" /> is set in IDF
void testIDFwhenSphericalOffsetSet()
{
LoadEmptyInstrument loader;
TS_ASSERT_THROWS_NOTHING(loader.initialize());
TS_ASSERT( loader.isInitialized() );
loader.setPropertyValue("Filename", "../../../../Test/Instrument/IDFs_for_UNIT_TESTING/IDF_for_UNIT_TESTING4.xml");
inputFile = loader.getPropertyValue("Filename");
wsName = "LoadEmptyInstrumentParamTest";
loader.setPropertyValue("OutputWorkspace", wsName);
TS_ASSERT_THROWS_NOTHING(loader.execute());
TS_ASSERT( loader.isExecuted() );
MatrixWorkspace_sptr ws;
ws = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve(wsName));
// get parameter map
ParameterMap& paramMap = ws->instrumentParameters();
boost::shared_ptr<IInstrument> i = ws->getInstrument();
// check if combined translation works
boost::shared_ptr<IDetector> ptrDet1 = i->getDetector(1001);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translationA");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 10.0, 0.0001);
ptrDet1 = i->getDetector(1002);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translationB");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 20.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 0.0, 0.0001);
ptrDet1 = i->getDetector(1003);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation");
TS_ASSERT_EQUALS( ptrDet1->getID(), 1003);
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 20.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 0.0, 0.0001);
ptrDet1 = i->getDetector(1004);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation2");
TS_ASSERT_EQUALS( ptrDet1->getID(), 1004);
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 25.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 0.0, 0.0001);
ptrDet1 = i->getDetector(1005);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation3");
TS_ASSERT_EQUALS( ptrDet1->getID(), 1005);
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 28.0, 0.0001);
ptrDet1 = i->getDetector(1006);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation4");
TS_ASSERT_EQUALS( ptrDet1->getID(), 1006);
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 28.0, 0.0001);
ptrDet1 = i->getDetector(1007);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation5");
TS_ASSERT_EQUALS( ptrDet1->getID(), 1007);
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 28.0, 0.0001);
ptrDet1 = i->getDetector(1008);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation6");
TS_ASSERT_EQUALS( ptrDet1->getID(), 1008);
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 28.0, 0.0001);
ptrDet1 = i->getDetector(1009);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation7");
TS_ASSERT_EQUALS( ptrDet1->getID(), 1009);
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 19.0, 0.0001);
ptrDet1 = i->getDetector(1010);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation8");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 11.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 8.0, 0.0001);
ptrDet1 = i->getDetector(1011);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation9");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 11.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 0.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), -8.0, 0.0001);
ptrDet1 = i->getDetector(1012);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation10");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 11.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), 8.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 0.0, 0.0001);
ptrDet1 = i->getDetector(1013);
TS_ASSERT_EQUALS( ptrDet1->getName(), "combined translation11");
TS_ASSERT_DELTA( ptrDet1->getPos().X(), 11.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Y(), -8.0, 0.0001);
TS_ASSERT_DELTA( ptrDet1->getPos().Z(), 0.0, 0.0001);
AnalysisDataService::Instance().remove(wsName);
}
// also test that when loading in instrument a 2nd time that parameters defined
// in instrument gets loaded as well
void testToscaParameterTags()
......
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