Commit 3edf7ca5 authored by Hahn, Steven's avatar Hahn, Steven
Browse files

Merge remote-tracking branch 'origin/master' into peaksworkspace_dock

parents 65523811 ee89e5c5
......@@ -27,7 +27,7 @@ enum det_topology {
rect, //< rectangular geometry
cyl, //< cylindrical geometry
undef //< the geometry is yet undefined, if you need to know the geometry, a
// method to identify it must be deployed
// method to identify it must be deployed
};
/** Interface class for detector objects.
......@@ -58,6 +58,9 @@ enum det_topology {
*/
class MANTID_GEOMETRY_DLL IDetector : public virtual IObjComponent {
public:
/// Create a cloned instance with a parameter map applied
virtual IDetector *cloneParameterized(const ParameterMap *map) const = 0;
/// Get the detector ID
virtual detid_t getID() const = 0;
......@@ -108,7 +111,7 @@ public:
/// (Empty) Constructor.
/// prevent Warning C4436
IDetector(){};
IDetector() {}
};
/// Shared pointer to IDetector
......
......@@ -48,8 +48,6 @@ public:
/// A string representation of the component type
std::string type() const override { return "DetectorComponent"; }
/// Constructor for parametrized version
Detector(const Detector *base, const ParameterMap *map);
Detector(const std::string &name, int id, IComponent *parent);
Detector(const std::string &name, int id, boost::shared_ptr<Object> shape,
IComponent *parent);
......@@ -57,6 +55,9 @@ public:
Component *clone() const override { return new Detector(*this); }
// IDetector methods
Detector *cloneParameterized(const ParameterMap *map) const override {
return new Detector(this, map);
}
detid_t getID() const override;
std::size_t nDets() const override {
return 1;
......@@ -88,6 +89,10 @@ private:
const detid_t m_id;
/// Flags if this is a monitor
bool m_isMonitor;
protected:
/// Constructor for parametrized version
Detector(const Detector *base, const ParameterMap *map);
};
} // namespace Geometry
......
......@@ -53,6 +53,9 @@ public:
void addDetector(IDetector_const_sptr det, bool &warn);
// IDetector methods
IDetector *cloneParameterized(const ParameterMap *) const override {
return nullptr;
}
detid_t getID() const override;
std::size_t nDets() const override;
Kernel::V3D getPos() const override;
......@@ -237,11 +240,11 @@ protected:
// functions inherited from IObjComponent
void getBoundingBox(double &, double &, double &, double &, double &,
double &) const {};
double &) const {}
void draw() const override{};
void drawObject() const override{};
void initDraw() const override{};
void draw() const override {}
void drawObject() const override {}
void initDraw() const override {}
/// Returns the shape of the Object
const boost::shared_ptr<const Object> shape() const override {
......
......@@ -49,9 +49,10 @@ class MANTID_GEOMETRY_DLL ParComponentFactory {
public:
/// Create a parameterized detector from the given base component and
/// ParameterMap and
/// return a shared_ptr<Detector>
static boost::shared_ptr<Detector> createDetector(const IDetector *base,
const ParameterMap *map);
/// return a shared_ptr<IDetector>
static boost::shared_ptr<IDetector> createDetector(const IDetector *base,
const ParameterMap *map);
/// Create a parameterized instrument from the given base and ParameterMap
static boost::shared_ptr<Instrument>
createInstrument(boost::shared_ptr<const Instrument> base,
......
......@@ -49,24 +49,32 @@ public:
/// A string representation of the component type
std::string type() const override { return "RectangularDetectorPixel"; }
/// Constructor for parametrized version
RectangularDetectorPixel(const RectangularDetectorPixel *base,
const ParameterMap *map);
RectangularDetectorPixel(const std::string &name, int id,
boost::shared_ptr<Object> shape, IComponent *parent,
RectangularDetector *panel, size_t row, size_t col);
RectangularDetectorPixel();
/// Create a cloned instance with a parameter map applied
RectangularDetectorPixel *
cloneParameterized(const ParameterMap *map) const override {
return new RectangularDetectorPixel(this, map);
}
const Kernel::V3D getRelativePos() const override;
protected:
private:
/// RectangularDetector that is the parent of this pixel.
RectangularDetector *m_panel;
/// Row of the pixel in the panel (y index)
size_t m_row;
/// Column of the pixel in the panel (x index)
size_t m_col;
protected:
/// Constructor for parametrized version
RectangularDetectorPixel(const RectangularDetectorPixel *base,
const ParameterMap *map);
};
} // namespace Geometry
......
......@@ -20,22 +20,12 @@ namespace Geometry {
* @param map A pointer to the ParameterMap
* @returns A pointer to a parameterized component
*/
boost::shared_ptr<Detector>
boost::shared_ptr<IDetector>
ParComponentFactory::createDetector(const IDetector *base,
const ParameterMap *map) {
// RectangularDetectorPixel subclasses Detector so it has to be checked
// before.
const RectangularDetectorPixel *rdp =
dynamic_cast<const RectangularDetectorPixel *>(base);
if (rdp)
return boost::make_shared<RectangularDetectorPixel>(rdp, map);
const Detector *baseDet = dynamic_cast<const Detector *>(base);
if (baseDet)
return boost::shared_ptr<Detector>(
new Detector(baseDet, map)); // g_detPool.create(baseDet,map);
return boost::shared_ptr<Detector>();
// Clone may be a Detector or RectangularDetectorPixel instance (or nullptr)
auto clone = base->cloneParameterized(map);
return boost::shared_ptr<IDetector>(clone);
}
/**
......@@ -63,14 +53,6 @@ ParComponentFactory::createInstrument(boost::shared_ptr<const Instrument> base,
IComponent_sptr
ParComponentFactory::create(boost::shared_ptr<const IComponent> base,
const ParameterMap *map) {
// RectangularDetectorPixel subclasses Detector so it has to be checked
// before.
const RectangularDetectorPixel *rdp =
dynamic_cast<const RectangularDetectorPixel *>(base.get());
if (rdp)
return boost::shared_ptr<IComponent>(
new RectangularDetectorPixel(rdp, map));
boost::shared_ptr<const IDetector> det_sptr =
boost::dynamic_pointer_cast<const IDetector>(base);
if (det_sptr) {
......
......@@ -8,6 +8,8 @@
#include "MantidGeometry/Instrument/RectangularDetector.h"
#include <cxxtest/TestSuite.h>
#include "MantidKernel/DateAndTime.h"
#include "MantidGeometry/Instrument/ParameterMap.h"
#include <boost/make_shared.hpp>
using namespace Mantid;
using namespace Mantid::Kernel;
......@@ -522,4 +524,50 @@ private:
Detector *det, *det2, *det3;
};
class InstrumentTestPerformance : public CxxTest::TestSuite {
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static InstrumentTestPerformance *createSuite() {
return new InstrumentTestPerformance();
}
static void destroySuite(InstrumentTestPerformance *suite) { delete suite; }
InstrumentTestPerformance() {
Mantid::Kernel::V3D sourcePos(0, 0, 0);
Mantid::Kernel::V3D samplePos(0, 0, 1);
Mantid::Kernel::V3D trolley1Pos(0, 0, 3);
Mantid::Kernel::V3D trolley2Pos(0, 0, 6);
m_instrumentNotParameterized = ComponentCreationHelper::sansInstrument(
sourcePos, samplePos, trolley1Pos, trolley2Pos);
auto map = boost::make_shared<ParameterMap>();
m_instrumentParameterized =
boost::make_shared<Instrument>(m_instrumentNotParameterized, map);
}
void test_access_non_parameterized() {
const detid_t nPixels = 100 * 100 * 6;
double pos_x = 0;
for (detid_t i = 1; i <= nPixels; i++) {
pos_x += m_instrumentNotParameterized->getDetector(i)->getPos().X();
}
}
void test_access_parameterized() {
const detid_t nPixels = 100 * 100 * 6;
double pos_x = 0;
for (detid_t i = 1; i <= nPixels; i++) {
pos_x += m_instrumentParameterized->getDetector(i)->getPos().X();
}
}
private:
Instrument_sptr m_instrumentParameterized;
Instrument_sptr m_instrumentNotParameterized;
};
#endif /*INSTRUMENTTEST_H_*/
......@@ -20,7 +20,7 @@ public:
boost::dynamic_pointer_cast<const Detector>(idet).get();
ParameterMap *map = new ParameterMap();
boost::shared_ptr<Detector> pdet;
boost::shared_ptr<IDetector> pdet;
TS_ASSERT_THROWS_NOTHING(pdet =
ParComponentFactory::createDetector(det, map));
TS_ASSERT(pdet);
......
......@@ -14,13 +14,13 @@ public:
Detector det("det1", 0, 0);
ParameterMap_sptr pmap(new ParameterMap());
Detector pdet(&det, pmap.get());
boost::shared_ptr<Detector> pdet(det.cloneParameterized(pmap.get()));
TS_ASSERT_EQUALS(pdet.getName(), "det1");
TS_ASSERT(!pdet.getParent());
TS_ASSERT_EQUALS(pdet.getID(), 0);
TS_ASSERT(!pdet.isMasked());
TS_ASSERT(!pdet.isMonitor());
TS_ASSERT_EQUALS(pdet->getName(), "det1");
TS_ASSERT(!pdet->getParent());
TS_ASSERT_EQUALS(pdet->getID(), 0);
TS_ASSERT(!pdet->isMasked());
TS_ASSERT(!pdet->isMonitor());
}
void testNameParentConstructor() {
......@@ -28,13 +28,13 @@ public:
Detector det("det1", 0, &parent);
ParameterMap_sptr pmap(new ParameterMap());
Detector pdet(&det, pmap.get());
boost::shared_ptr<Detector> pdet(det.cloneParameterized(pmap.get()));
TS_ASSERT_EQUALS(pdet.getName(), "det1");
TS_ASSERT(pdet.getParent());
TS_ASSERT_EQUALS(pdet.getID(), 0);
TS_ASSERT(!pdet.isMasked());
TS_ASSERT(!pdet.isMonitor());
TS_ASSERT_EQUALS(pdet->getName(), "det1");
TS_ASSERT(pdet->getParent());
TS_ASSERT_EQUALS(pdet->getID(), 0);
TS_ASSERT(!pdet->isMasked());
TS_ASSERT(!pdet->isMonitor());
}
void testId() {
......@@ -42,42 +42,42 @@ public:
Detector det("det1", id1, 0);
ParameterMap_sptr pmap(new ParameterMap());
Detector pdet(&det, pmap.get());
boost::shared_ptr<Detector> pdet(det.cloneParameterized(pmap.get()));
TS_ASSERT_EQUALS(pdet.getID(), id1);
TS_ASSERT_EQUALS(pdet->getID(), id1);
}
void testType() {
Detector det("det", 0, 0);
ParameterMap_sptr pmap(new ParameterMap());
Detector pdet(&det, pmap.get());
boost::shared_ptr<Detector> pdet(det.cloneParameterized(pmap.get()));
TS_ASSERT_EQUALS(pdet.type(), "DetectorComponent");
TS_ASSERT_EQUALS(pdet->type(), "DetectorComponent");
}
void testMasked() {
Detector det("det", 0, 0);
ParameterMap_sptr pmap(new ParameterMap());
Detector pdet(&det, pmap.get());
boost::shared_ptr<Detector> pdet(det.cloneParameterized(pmap.get()));
TS_ASSERT(!pdet.isMasked());
TS_ASSERT(!pdet->isMasked());
pmap->addBool(&det, "masked", true);
TS_ASSERT(pdet.isMasked());
TS_ASSERT(pdet->isMasked());
}
void testMonitor() {
Detector det("det", 0, 0);
ParameterMap_sptr pmap(new ParameterMap());
Detector pdet(&det, pmap.get());
boost::shared_ptr<Detector> pdet(det.cloneParameterized(pmap.get()));
TS_ASSERT(!pdet.isMonitor());
TS_ASSERT(!pdet->isMonitor());
TS_ASSERT_THROWS_NOTHING(det.markAsMonitor());
TS_ASSERT(pdet.isMonitor());
TS_ASSERT(pdet->isMonitor());
TS_ASSERT_THROWS_NOTHING(det.markAsMonitor(false));
TS_ASSERT(!pdet.isMonitor());
TS_ASSERT(!pdet->isMonitor());
}
void testGetNumberParameter() {
......@@ -85,8 +85,8 @@ public:
ParameterMap_sptr pmap(new ParameterMap());
pmap->add("double", &det, "testparam", 5.0);
Detector pdet(&det, pmap.get());
IDetector *idet = static_cast<IDetector *>(&pdet);
boost::shared_ptr<Detector> pdet(det.cloneParameterized(pmap.get()));
IDetector *idet = static_cast<IDetector *>(pdet.get());
TS_ASSERT_EQUALS(idet->getNumberParameter("testparam").size(), 1);
TS_ASSERT_DELTA(idet->getNumberParameter("testparam")[0], 5.0, 1e-08);
......@@ -97,8 +97,8 @@ public:
ParameterMap_sptr pmap(new ParameterMap());
pmap->add("V3D", &det, "testparam", Mantid::Kernel::V3D(0.5, 1.0, 1.5));
Detector pdet(&det, pmap.get());
IDetector *idet = static_cast<IDetector *>(&pdet);
boost::shared_ptr<Detector> pdet(det.cloneParameterized(pmap.get()));
IDetector *idet = static_cast<IDetector *>(pdet.get());
std::vector<Mantid::Kernel::V3D> pos =
idet->getPositionParameter("testparam");
......@@ -115,8 +115,8 @@ public:
ParameterMap_sptr pmap(new ParameterMap());
pmap->add("Quat", &det, "testparam",
Mantid::Kernel::Quat(1.0, 0.25, 0.5, 0.75));
Detector pdet(&det, pmap.get());
IDetector *idet = static_cast<IDetector *>(&pdet);
boost::shared_ptr<Detector> pdet(det.cloneParameterized(pmap.get()));
IDetector *idet = static_cast<IDetector *>(pdet.get());
std::vector<Mantid::Kernel::Quat> rot =
idet->getRotationParameter("testparam");
......
......@@ -96,6 +96,7 @@ class SavePlot1DAsJson(PythonAlgorithm):
list(workspace.readX(i)),
list(workspace.readY(i)),
list(workspace.readE(i)),
list(workspace.readDx(i)),
]
serialized['data'][spectrum_no] = arr
continue
......
......@@ -68,6 +68,7 @@ set ( TEST_PY_FILES
SANSFitShiftScaleTest.py
SANSWideAngleCorrectionTest.py
SavePlot1DTest.py
SavePlot1DAsJsonTest.py
SaveVulcanGSSTest.py
SimulatedDensityOfStatesTest.py
SortByQVectorsTest.py
......
......@@ -15,7 +15,7 @@ class SavePlot1DAsJsonTest(unittest.TestCase):
""" Test to Save one curve
"""
datawsname = "constant energy cut"
E, I, err = self._createOneQCurve(datawsname)
E, I, err, dQ = self._createOneQCurve(datawsname)
# Execute
out_path = "tempout_curve.json"
......@@ -28,7 +28,7 @@ class SavePlot1DAsJsonTest(unittest.TestCase):
# Verify ....
d = json.load(open(out_path))[datawsname]
self.assertEqual(d['type'], 'point')
self._checkData(d, E, I, err)
self._checkData(d, E, I, err, dE=dQ)
# Delete the output file
os.remove(out_path)
return
......@@ -106,11 +106,13 @@ class SavePlot1DAsJsonTest(unittest.TestCase):
return
def _checkData(self, s, E, I, err, ID="1"):
def _checkData(self, s, E, I, err, ID="1", dE=None):
d0 = s["data"][ID]
np.testing.assert_array_equal(d0[0], E)
np.testing.assert_array_equal(d0[1], I)
np.testing.assert_array_equal(d0[2], err)
if dE is not None:
np.testing.assert_array_equal(d0[3], dE)
return
......@@ -133,15 +135,17 @@ class SavePlot1DAsJsonTest(unittest.TestCase):
""" Create data workspace
"""
Q = np.arange(0, 13, 1.0)
dQ = 0.1*Q
I = 1000 * np.exp(-Q**2/10**2)
err = I ** .5
# create workspace
dataws = api.CreateWorkspace(
DataX = Q, DataY = I, DataE = err, NSpec = 1,
UnitX = "Momentum")
dataws.setDx(0, dQ)
# Add to data service
AnalysisDataService.addOrReplace(datawsname, dataws)
return Q, I, err
return Q, I, err, dQ
def _createOneHistogram(self, datawsname):
......
......@@ -161,6 +161,12 @@ Mantid::Geometry::Instrument_sptr
createMinimalInstrument(const Mantid::Kernel::V3D &sourcePos,
const Mantid::Kernel::V3D &samplePos,
const Mantid::Kernel::V3D &detectorPos);
Mantid::Geometry::Instrument_sptr
sansInstrument(const Mantid::Kernel::V3D &sourcePos,
const Mantid::Kernel::V3D &samplePos,
const Mantid::Kernel::V3D &trolley1Pos,
const Mantid::Kernel::V3D &trolley2Pos);
}
#endif // COMPONENTCREATIONHELPERS_H_
......@@ -586,4 +586,82 @@ createMinimalInstrument(const Mantid::Kernel::V3D &sourcePos,
return instrument;
}
CompAssembly *makeBank(size_t width, size_t height, Instrument *instrument) {
double width_d = double(width);
double height_d = double(height);
static int bankNo = 1;
auto bank = new CompAssembly("Bank" + std::to_string(bankNo++));
static size_t id = 1;
for (size_t i = 0; i < width; ++i) {
for (size_t j = 0; j < height; ++j) {
Detector *det = new Detector("pixel", int(id++) /*detector id*/, bank);
det->setPos(V3D{double(i), double(j), double(0)});
det->setShape(createSphere(0.01 /*1cm*/, V3D(0, 0, 0), "1"));
bank->add(det);
instrument->markAsDetector(det);
}
}
bank->setPos(V3D{width_d / 2, height_d / 2, 0});
return bank;
}
Instrument_sptr sansInstrument(const Mantid::Kernel::V3D &sourcePos,
const Mantid::Kernel::V3D &samplePos,
const Mantid::Kernel::V3D &trolley1Pos,
const Mantid::Kernel::V3D &trolley2Pos) {
/*
This has been generated for comparison with newer Instrument designs. It is
therefore not
an exact representation of an instrument one might expect to create for SANS.
*/
auto instrument = boost::make_shared<Instrument>();
instrument->setReferenceFrame(boost::make_shared<ReferenceFrame>(
Mantid::Geometry::Y /*up*/, Mantid::Geometry::Z /*along*/, Left,
"0,0,0"));
// A source
ObjComponent *source = new ObjComponent("source");
source->setPos(sourcePos);
source->setShape(createSphere(0.01 /*1cm*/, V3D(0, 0, 0), "1"));
instrument->add(source);
instrument->markAsSource(source);
// A sample
ObjComponent *sample = new ObjComponent("some-surface-holder");
sample->setPos(samplePos);
sample->setShape(createSphere(0.01 /*1cm*/, V3D(0, 0, 0), "1"));
instrument->add(sample);
instrument->markAsSamplePos(sample);
size_t width = 100;
size_t height = 100;
CompAssembly *trolley1 = new CompAssembly("Trolley1");
trolley1->setPos(trolley1Pos);
CompAssembly *trolley2 = new CompAssembly("Trolley2");
trolley2->setPos(trolley2Pos);
CompAssembly *N = makeBank(width, height, instrument.get());
trolley1->add(N);
CompAssembly *E = makeBank(width, height, instrument.get());
trolley1->add(E);
CompAssembly *S = makeBank(width, height, instrument.get());
trolley1->add(S);
CompAssembly *W = makeBank(width, height, instrument.get());
trolley1->add(W);
CompAssembly *l_curtain = makeBank(width, height, instrument.get());
trolley2->add(l_curtain);
CompAssembly *r_curtain = makeBank(width, height, instrument.get());
trolley2->add(r_curtain);
instrument->add(trolley1);
instrument->add(trolley2);
return instrument;
}
}
......@@ -131,38 +131,12 @@ void vtkDataSetToPeaksFilteredDataSet::execute(
}
}
// Now we have all ids for the points, we need to retrieve the ids of the
// cells
std::map<vtkIdType, vtkIdType> uniqueCellTester;
vtkSmartPointer<vtkIdTypeArray> cellIds =
vtkSmartPointer<vtkIdTypeArray>::New();
for (int i = 0; i < ids->GetNumberOfTuples(); i++) {
vtkIdType pId = ids->GetValue(i);
vtkSmartPointer<vtkIdList> cIdList = vtkSmartPointer<vtkIdList>::New();
cIdList->Initialize();
m_inputData->GetPointCells(pId, cIdList);
if (cIdList->GetNumberOfIds() == 0) {
continue;
}
vtkIdType cId = cIdList->GetId(0);
if (uniqueCellTester.count(cId) == 0) {
cellIds->InsertNextValue(cId);
uniqueCellTester.insert(std::pair<vtkIdType, vtkIdType>(cId, cId));
}
}
// Create the selection node and tell it the type of selection
vtkSmartPointer<vtkSelectionNode> selectionNode =
vtkSmartPointer<vtkSelectionNode>::New();
selectionNode->SetFieldType(vtkSelectionNode::CELL);
selectionNode->SetFieldType(vtkSelectionNode::POINT);
selectionNode->SetContentType(vtkSelectionNode::INDICES);
selectionNode->SetSelectionList(cellIds);
selectionNode->SetSelectionList(ids);
vtkSmartPointer<vtkSelection> selection =