Commit 94401f96 authored by Janik Zikovsky's avatar Janik Zikovsky
Browse files

Refs #2838: GetXY for detector ID added to Rectangular detector, and used in Peak object.

parent b2fbfa5e
......@@ -3,6 +3,7 @@
#include "MantidKernel/System.h"
#include "MantidGeometry/Math/Matrix.h"
#include "MantidGeometry/IInstrument.h"
namespace Mantid
......@@ -15,32 +16,41 @@ namespace DataObjects
* @author Janik Zikovsky
* @date 2011-04-15 13:24:07.963491
*/
class Peak
class DLLExport Peak
{
public:
Peak();
Peak(Mantid::Geometry::IInstrument_sptr m_inst, int m_DetectorID, double m_InitialEnergy);
~Peak();
int getDetectorID() const;
double getFinalEnergy() const;
double getH() const;
double getInitialEnergy() const;
double getIntensity() const;
double getK() const;
double getL() const;
double getInitialEnergy() const;
double getFinalEnergy() const;
double getIntensity() const;
double getSigIntensity() const;
void setDetectorID(int m_DetectorID);
void setFinalEnergy(double m_FinalEnergy);
void setH(double m_H);
void setInitialEnergy(double m_InitialEnergy);
void setIntensity(double m_Intensity);
void setK(double m_K);
void setL(double m_L);
void setHKL(double H, double K, double L);
void setInitialEnergy(double m_InitialEnergy);
void setFinalEnergy(double m_FinalEnergy);
void setIntensity(double m_Intensity);
void setSigIntensity(double m_SigIntensity);
Mantid::Geometry::Matrix<double> getOrientationMatrix() const;
void setOrientationMatrix(Mantid::Geometry::Matrix<double> m_OrientationMatrix);
// -- Still to implement --
// ------ Still to implement -------
double getWavelength();
double getDSpacing();
std::string getBankName();
......@@ -48,17 +58,11 @@ namespace DataObjects
int getCol();
protected:
/// Integrated peak intensity
double m_Intensity;
/// Error (sigma) on peak intensity
double m_SigIntensity;
/// Shared pointer to the instrument (for calculating some values )
Mantid::Geometry::IInstrument_sptr m_inst;
/// Final energy of the peak
double m_FinalEnergy;
/// Initial Energy of the peak
double m_InitialEnergy;
/// Detector pointed to
Mantid::Geometry::IDetector_sptr m_det;
/// ID of the detector
int m_DetectorID;
......@@ -72,6 +76,18 @@ namespace DataObjects
/// L of the peak
double m_L;
/// Integrated peak intensity
double m_Intensity;
/// Error (sigma) on peak intensity
double m_SigIntensity;
/// Initial energy of neutrons at the peak
double m_InitialEnergy;
/// Final energy of the neutrons at peak (normally same as m_InitialEnergy)
double m_FinalEnergy;
/// Sample orientation matrix
Mantid::Geometry::Matrix<double> m_OrientationMatrix;
};
......
#include "MantidDataObjects/Peak.h"
#include "MantidGeometry/Instrument/RectangularDetector.h"
#include "MantidKernel/System.h"
using namespace Mantid;
using namespace Mantid::Kernel;
using namespace Mantid::Geometry;
namespace Mantid
{
namespace DataObjects
......@@ -9,9 +14,21 @@ namespace DataObjects
//----------------------------------------------------------------------------------------------
/** Constructor
*
* @param m_inst :: Shared pointer to the instrument for this peak detection
* @param m_DetectorID :: ID to the detector of the center of the peak
* @param m_InitialEnergy :: incident neutron energy, in mEv (UNITS??)
* @return
*/
Peak::Peak()
Peak::Peak(Mantid::Geometry::IInstrument_sptr m_inst, int m_DetectorID, double m_InitialEnergy)
: m_inst(m_inst),
m_H(0), m_K(0), m_L(0),
m_Intensity(0), m_SigIntensity(0),
m_InitialEnergy(m_InitialEnergy),
m_FinalEnergy(m_InitialEnergy),
m_OrientationMatrix(3,3)
{
this->setDetectorID(m_DetectorID);
}
//----------------------------------------------------------------------------------------------
......@@ -64,6 +81,8 @@ namespace DataObjects
void Peak::setDetectorID(int m_DetectorID)
{
this->m_DetectorID = m_DetectorID;
if (m_inst)
this->m_det = m_inst->getDetector(this->m_DetectorID);
}
void Peak::setFinalEnergy(double m_FinalEnergy)
......@@ -111,6 +130,64 @@ namespace DataObjects
this->m_OrientationMatrix = m_OrientationMatrix;
}
void Peak::setHKL(double H, double K, double L)
{
m_H = H;
m_K = K;
m_L = L;
}
// -------------------------------------------------------------------------------------
/** Calculate the neutron wavelength at the peak */
double Peak::getWavelength()
{
return 0.0; //TODO:
}
// -------------------------------------------------------------------------------------
/** Calculate the d-spacing of the peak */
double Peak::getDSpacing()
{
return 0.0; //TODO:
}
// -------------------------------------------------------------------------------------
/** Find the name of the bank that is the parent of the detector. This works
* best for RectangularDetector instruments (goes up one level)
* @return name of the bank.
*/
std::string Peak::getBankName()
{
if (!m_det) return "";
if (!m_det->getParent()) return "";
return m_det->getParent()->getName();
}
// -------------------------------------------------------------------------------------
/** For RectangularDetectors only, returns the row (y) of the pixel of the detector. */
int Peak::getRow()
{
if (!m_det) throw std::runtime_error("No detector in Peak!");
if (!m_det->getParent()) throw std::runtime_error("No parent to the detector in Peak!");
RectangularDetector_const_sptr retDet = boost::dynamic_pointer_cast<const RectangularDetector>(m_det->getParent());
if (!retDet) throw std::runtime_error("Parent of the detector in Peak is not RectangularDetector: can't find the row!");
std::pair<int,int> xy = retDet->getXYForDetectorID(m_DetectorID);
return xy.second;
}
// -------------------------------------------------------------------------------------
/** For RectangularDetectors only, returns the row of the pixel of the detector. */
int Peak::getCol()
{
if (!m_det) throw std::runtime_error("No detector in Peak!");
if (!m_det->getParent()) throw std::runtime_error("No parent to the detector in Peak!");
RectangularDetector_const_sptr retDet = boost::dynamic_pointer_cast<const RectangularDetector>(m_det->getParent());
if (!retDet) throw std::runtime_error("Parent of the detector in Peak is not RectangularDetector: can't find the col!");
std::pair<int,int> xy = retDet->getXYForDetectorID(m_DetectorID);
return xy.first;
}
} // namespace Mantid
......
......@@ -8,15 +8,46 @@
#include <iomanip>
#include "MantidDataObjects/Peak.h"
#include "MantidTestHelpers/ComponentCreationHelper.h"
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
using namespace Mantid::Kernel;
class PeakTest : public CxxTest::TestSuite
{
public:
/// Common instrument
IInstrument_sptr inst;
void setUp()
{
inst = ComponentCreationHelper::createTestInstrumentRectangular(5, 100);
}
void test_constructor()
{
// detector IDs start at 10000
Peak p(inst, 10000, 2.0);
TS_ASSERT_DELTA(p.getInitialEnergy(), 2.0, 1e-5)
TS_ASSERT_DELTA(p.getFinalEnergy(), 2.0, 1e-5)
TS_ASSERT_DELTA(p.getH(), 0.0, 1e-5)
TS_ASSERT_DELTA(p.getK(), 0.0, 1e-5)
TS_ASSERT_DELTA(p.getL(), 0.0, 1e-5)
TS_ASSERT_EQUALS(p.getDetectorID(), 10000)
}
void test_badDetectorID_throws()
{
Peak p(inst, 10000, 2.0);
TS_ASSERT_THROWS_ANYTHING( p.setDetectorID(7) );
}
void test_Something()
void test_getBank_and_row()
{
Peak p(inst, 10000, 2.0);
TS_ASSERT_EQUALS(p.getBankName(), "bank1")
TS_ASSERT_EQUALS(p.getRow(), 0)
TS_ASSERT_EQUALS(p.getCol(), 0)
}
......
......@@ -73,7 +73,9 @@ public:
virtual IComponent* clone() const;
/// Get a detector at given XY indices.
boost::shared_ptr<Detector> getAtXY(int X, int Y) const;
boost::shared_ptr<Detector> getAtXY(const int X, const int Y) const;
std::pair<int, int> getXYForDetectorID(const int detectorID) const;
int xpixels() const;
int ypixels() const;
......@@ -180,11 +182,21 @@ private:
/// maximum detector id
int m_maxDetId;
/// IDs start here
int m_idstart;
/// IDs are filled in Y fastest
bool m_idfillbyfirst_y;
/// Step size in ID in each row
int m_idstepbyrow;
/// Step size in ID in each col
int m_idstep;
};
DLLExport std::ostream& operator<<(std::ostream&, const RectangularDetector&);
typedef boost::shared_ptr<RectangularDetector> RectangularDetector_sptr;
typedef boost::shared_ptr<const RectangularDetector> RectangularDetector_const_sptr;
} //Namespace Geometry
} //Namespace Mantid
......
......@@ -83,7 +83,7 @@ IComponent* RectangularDetector::clone() const
* @return a pointer to the component in the assembly at the (X,Y) pixel position
* @throw runtime_error if the x/y pixel width is not set, or X/Y are out of range
*/
boost::shared_ptr<Detector> RectangularDetector::getAtXY(int X, int Y) const
boost::shared_ptr<Detector> RectangularDetector::getAtXY(const int X, const int Y) const
{
if ((xpixels() <= 0) || (ypixels() <= 0))
throw std::runtime_error("RectangularDetector::getAtXY: invalid X or Y width set in the object.");
......@@ -99,6 +99,30 @@ boost::shared_ptr<Detector> RectangularDetector::getAtXY(int X, int Y) const
return boost::dynamic_pointer_cast<Detector>( this->operator[](i) );
}
//-------------------------------------------------------------------------------------------------
/** Given a detector ID, return the X,Y coords into the rectangular detector
*
* @param detectorID :: detectorID
* @return pair of (x,y)
*/
std::pair<int, int> RectangularDetector::getXYForDetectorID(const int detectorID) const
{
const RectangularDetector * me = this;
if (m_isParametrized)
me = this->m_rectBase;
int id = detectorID - me->m_idstart;
if ((me->m_idstepbyrow == 0) || (me->m_idstep == 0))
return std::pair<int,int>(-1, -1);
int row = id / me->m_idstepbyrow;
int col = (id % me->m_idstepbyrow) / me->m_idstep;
if (me->m_idfillbyfirst_y) // x is the fast-changing axis
return std::pair<int,int>(row, col);
else
return std::pair<int,int>(col, row);
}
//-------------------------------------------------------------------------------------------------
/// Returns the number of pixels in the X direction.
/// @return number of X pixels
......@@ -244,7 +268,16 @@ void RectangularDetector::initialize(boost::shared_ptr<Object> shape,
m_xstep = xstep;
m_ystep = ystep;
mShape = shape;
/// IDs start here
m_idstart = idstart;
/// IDs are filled in Y fastest
m_idfillbyfirst_y = idfillbyfirst_y;
/// Step size in ID in each row
m_idstepbyrow = idstepbyrow;
/// Step size in ID in each col
m_idstep = idstep;
//TODO: some safety checks
std::string name = this->getName();
int minDetId=idstart,maxDetId=idstart;
......
......@@ -125,6 +125,20 @@ public:
TS_ASSERT_EQUALS(det->getAtXY(0,112)->getID() - 1000000, 112);
TS_ASSERT_EQUALS(det->getAtXY(1,12)->getID() - 1000000, 1012);
std::pair<int,int> xy; int x; int y;
TS_ASSERT_THROWS_NOTHING(xy = det->getXYForDetectorID(1000000)); x = xy.first; y = xy.second;
TS_ASSERT_EQUALS(x, 0); TS_ASSERT_EQUALS(y, 0);
TS_ASSERT_THROWS_NOTHING(xy = det->getXYForDetectorID(1000000+12)); x = xy.first; y = xy.second;
TS_ASSERT_EQUALS(x, 0); TS_ASSERT_EQUALS(y, 12);
TS_ASSERT_THROWS_NOTHING(xy = det->getXYForDetectorID(1000000+112)); x = xy.first; y = xy.second;
TS_ASSERT_EQUALS(x, 0); TS_ASSERT_EQUALS(y, 112);
TS_ASSERT_THROWS_NOTHING(xy = det->getXYForDetectorID(1000000+3012)); x = xy.first; y = xy.second;
TS_ASSERT_EQUALS(x, 3); TS_ASSERT_EQUALS(y, 12);
//Check some positions
TS_ASSERT_EQUALS(det->getAtXY(0,0)->getPos(), V3D( 1000-50., 2000-100., 3000.) );
TS_ASSERT_EQUALS(det->getAtXY(1,0)->getPos(), V3D( 1000-50.+1., 2000-100., 3000.) );
......
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