Commit 6f18fe75 authored by Lamar Moore's avatar Lamar Moore
Browse files

minor speed improvement re #21339

parent 0bdf9d08
......@@ -82,7 +82,7 @@ public:
/// Apply the mask in the attached mask workspace to the data.
void applyMaskWorkspace();
/// Add a range of bins for masking
void addMaskBinsData(const QList<int> &detIDs);
void addMaskBinsData(const std::vector<size_t> &indices);
/// Remove the attached mask workspace without applying the mask.
/// Remove the bin masking data.
void clearMasks();
......@@ -135,6 +135,7 @@ public:
size_t getDetectorByDetID(Mantid::detid_t detID) const;
/// Get a detector ID by a pick ID converted form a color in the pick image.
Mantid::detid_t getDetID(size_t pickID) const;
QList<Mantid::detid_t> getDetIDs(const std::vector<size_t> &dets) const;
/// Get a component ID for a non-detector.
Mantid::Geometry::ComponentID getComponentID(size_t pickID) const;
/// Get position of a detector by a pick ID converted form a color in the pick
......@@ -144,12 +145,12 @@ public:
const std::vector<Mantid::detid_t> &getAllDetIDs() const;
/// Get displayed color of a detector by its index.
GLColor getColor(size_t index) const;
/// Get the workspace index of a detector by its detector ID.
size_t getWorkspaceIndex(Mantid::detid_t id) const;
/// Get the integrated counts of a detector by its detector ID.
double getIntegratedCounts(Mantid::detid_t id) const;
/// Get the workspace index of a detector by its detector Index.
size_t getWorkspaceIndex(size_t index) const;
/// Get the integrated counts of a detector by its detector Index.
double getIntegratedCounts(size_t index) const;
/// Sum the counts in detectors
void sumDetectors(QList<int> &dets, std::vector<double> &x,
void sumDetectors(const std::vector<size_t> &dets, std::vector<double> &x,
std::vector<double> &y, size_t size = 0) const;
/// Calc indexes for min and max bin values
void getBinMinMaxIndex(size_t wi, size_t &imin, size_t &imax) const;
......@@ -214,10 +215,10 @@ private:
calculateIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace);
/// Sum the counts in detectors if the workspace has equal bins for all
/// spectra
void sumDetectorsUniform(QList<int> &dets, std::vector<double> &x,
void sumDetectorsUniform(const std::vector<size_t> &dets, std::vector<double> &x,
std::vector<double> &y) const;
/// Sum the counts in detectors if the workspace is ragged
void sumDetectorsRagged(QList<int> &dets, std::vector<double> &x,
void sumDetectorsRagged(const std::vector<size_t> &dets, std::vector<double> &x,
std::vector<double> &y, size_t size) const;
void setupPickColors();
......@@ -257,10 +258,6 @@ private:
bool m_volumeRender;
/// Color map scale type: linear or log
GraphOptions::ScaleType m_scaleType;
/// The workspace's detector ID to workspace index map
Mantid::detid2index_map m_detid2index_map;
/// All det ids in the instrument in order of pickIDs, populated by Obj..Actor
/// constructors
mutable std::vector<Mantid::detid_t> m_detIDs;
......@@ -281,14 +278,12 @@ private:
GLColor m_maskedColor;
/// Colour of a "failed" detector
GLColor m_failedColor;
/// The collection of actors for the instrument components
// GLActorCollection m_scene;
static double m_tolerance;
std::vector<GLColor> m_pickColors;
std::vector<bool> m_isCompVisible;
std::vector<size_t> m_detIndex2WsIndex;
// Two display lists for normal rendering and picking
mutable GLuint m_displayListId[2];
mutable bool m_useDisplayList[2];
......
......@@ -200,7 +200,7 @@ public slots:
void clear();
private:
QString displayDetectorInfo(Mantid::detid_t detid);
QString displayDetectorInfo(size_t index);
QString displayNonDetectorInfo(Mantid::Geometry::ComponentID compID);
QString displayPeakInfo(Mantid::Geometry::IPeak *peak);
QString displayPeakAngles(const std::pair<Mantid::Geometry::IPeak *,
......@@ -237,7 +237,7 @@ public:
InstrumentWidget *instrWidget, OneCurvePlot *plot);
void setEnabled(bool on) { m_enabled = on; }
void setPlotData(size_t pickID);
void setPlotData(QList<int> detIDs);
void setPlotData(const std::vector<size_t> &detIndices);
void updatePlot();
void clear();
void savePlotToWorkspace();
......@@ -255,17 +255,17 @@ private slots:
void addPeak(double x, double y);
private:
void plotSingle(int detid);
void plotTube(int detid);
void plotTubeSums(int detid);
void plotTubeIntegrals(int detid);
void prepareDataForSinglePlot(int detid, std::vector<double> &x,
void plotSingle(size_t detindex);
void plotTube(size_t detindex);
void plotTubeSums(size_t detindex);
void plotTubeIntegrals(size_t detindex);
void prepareDataForSinglePlot(size_t detindex, std::vector<double> &x,
std::vector<double> &y,
std::vector<double> *err = nullptr);
void prepareDataForSumsPlot(int detid, std::vector<double> &x,
void prepareDataForSumsPlot(size_t detindex, std::vector<double> &x,
std::vector<double> &y,
std::vector<double> *err = nullptr);
void prepareDataForIntegralsPlot(int detid, std::vector<double> &x,
void prepareDataForIntegralsPlot(size_t detindex, std::vector<double> &x,
std::vector<double> &y,
std::vector<double> *err = nullptr);
static double getOutOfPlaneAngle(const Mantid::Kernel::V3D &pos,
......
......@@ -36,7 +36,7 @@ File change history is stored at: <https://github.com/mantidproject/mantid>
*/
class MaskBinsData {
public:
void addXRange(double start, double end, const QList<int> &indices);
void addXRange(double start, double end, const std::vector<size_t> &indices);
void mask(const std::string &wsName) const;
bool isEmpty() const;
void subtractIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace,
......@@ -53,7 +53,7 @@ private:
BinMask(double s = 0.0, double e = 0.0) : start(s), end(e) {}
double start;
double end;
QList<int> spectra;
std::vector<size_t> spectra;
};
QList<BinMask> m_masks;
};
......
......@@ -40,8 +40,8 @@ public:
void setWireframe(bool on);
void componentSelected(size_t componentIndex) override;
void getSelectedDetectors(QList<int> &dets) override;
void getMaskedDetectors(QList<int> &dets) const override;
void getSelectedDetectors(std::vector<size_t> &dets) override;
void getMaskedDetectors(std::vector<size_t> &dets) const override;
void resize(int, int) override;
QString getInfoText() const override;
/// Load settings for the 3D projection from a project file
......
......@@ -113,9 +113,9 @@ public:
/// NULL deselects components and selects the whole instrument
virtual void componentSelected(size_t componentIndex) = 0;
/// fill in a list of detector ids which were selected by the selction tool
virtual void getSelectedDetectors(QList<int> &dets) = 0;
virtual void getSelectedDetectors(std::vector<size_t> &dets) = 0;
/// fill in a list of detector ids which were masked by the mask shapes
virtual void getMaskedDetectors(QList<int> &dets) const = 0;
virtual void getMaskedDetectors(std::vector<size_t> &dets) const = 0;
virtual QString getInfoText() const;
/// Change the interaction mode
......
......@@ -60,8 +60,8 @@ public:
/** @name Implemented public virtual methods */
//@{
void componentSelected(size_t componentIndex) override;
void getSelectedDetectors(QList<int> &dets) override;
void getMaskedDetectors(QList<int> &dets) const override;
void getSelectedDetectors(std::vector<size_t> &dets) override;
void getMaskedDetectors(std::vector<size_t> &dets) const override;
void setPeaksWorkspace(boost::shared_ptr<Mantid::API::IPeaksWorkspace> pws);
QString getInfoText() const override;
RectF getSurfaceBounds() const override;
......
......@@ -45,8 +45,6 @@ size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) {
index += b - 1;
return index;
}
GLColor defaultDetectorColor() { return GLColor(200, 200, 200); }
} // namespace
double InstrumentActor::m_tolerance = 0.00001;
......@@ -142,6 +140,7 @@ InstrumentActor::~InstrumentActor() {
void InstrumentActor::setUpWorkspace(
boost::shared_ptr<const Mantid::API::MatrixWorkspace> sharedWorkspace,
double scaleMin, double scaleMax) {
const size_t nHist = sharedWorkspace->getNumberHistograms();
m_WkspBinMinValue = DBL_MAX;
m_WkspBinMaxValue = -DBL_MAX;
......@@ -168,6 +167,14 @@ void InstrumentActor::setUpWorkspace(
}
}
const auto &spectrumInfo = sharedWorkspace->spectrumInfo();
m_detIndex2WsIndex.resize(sharedWorkspace->componentInfo().size());
for (size_t wi = 0; wi < spectrumInfo.size(); wi++) {
const auto &specDef = spectrumInfo.spectrumDefinition(wi);
for (auto info : specDef)
m_detIndex2WsIndex[info.first] = wi;
}
// set some values as the variables will be used
m_DataPositiveMinValue = DBL_MAX;
m_DataMinValue = -DBL_MAX;
......@@ -182,9 +189,6 @@ void InstrumentActor::setUpWorkspace(
// set the ragged flag using a workspace validator
auto wsValidator = Mantid::API::CommonBinsValidator();
m_ragged = !wsValidator.isValid(sharedWorkspace).empty();
/// Keep the pointer to the detid2index map
m_detid2index_map = sharedWorkspace->getDetectorIDToWorkspaceIndexMap();
}
void InstrumentActor::setComponentVisible(size_t componentIndex) {
......@@ -394,6 +398,14 @@ Mantid::detid_t InstrumentActor::getDetID(size_t pickID) const {
return -1;
}
QList<Mantid::detid_t>
InstrumentActor::getDetIDs(const std::vector<size_t> &dets) const {
QList<Mantid::detid_t> detIDs;
for (auto det : dets)
detIDs.append(getDetID(det));
return detIDs;
}
/**
* Get a component id of a picked component.
*/
......@@ -412,13 +424,8 @@ InstrumentActor::getComponentID(size_t pickID) const {
* @throws Exception::NotFoundError If the detector is not represented in the
* workspace
*/
size_t InstrumentActor::getWorkspaceIndex(Mantid::detid_t id) const {
auto mapEntry = m_detid2index_map.find(id);
if (mapEntry == m_detid2index_map.end()) {
throw Kernel::Exception::NotFoundError("Detector ID not in workspace", id);
}
return mapEntry->second;
size_t InstrumentActor::getWorkspaceIndex(size_t index) const {
return m_detIndex2WsIndex[index];
}
/**
......@@ -436,18 +443,12 @@ void InstrumentActor::setIntegrationRange(const double &xmin,
}
/** Gives the total signal in the spectrum relating to the given detector
* @param id The detector id
* @return The signal, or -1 if the detector is not represented in the
* workspace
* @param index The detector index
* @return The signal
*/
double InstrumentActor::getIntegratedCounts(Mantid::detid_t id) const {
try {
size_t i = getWorkspaceIndex(id);
double InstrumentActor::getIntegratedCounts(size_t index) const {
size_t i = getWorkspaceIndex(index);
return m_specIntegrs.at(i);
} catch (NotFoundError &) {
// If the detector is not represented in the workspace
return -1.0;
}
}
/**
......@@ -457,14 +458,14 @@ double InstrumentActor::getIntegratedCounts(Mantid::detid_t id) const {
* appropriate summation
* method.
*
* @param dets :: A list of detector IDs to sum.
* @param dets :: A list of detector Indices to sum.
* @param x :: (output) Time of flight values (or whatever values the x axis
* has) to plot against.
* @param y :: (output) The sums of the counts for each bin.
* @param size :: (optional input) Size of the output vectors. If not given it
* will be determined automatically.
*/
void InstrumentActor::sumDetectors(QList<int> &dets, std::vector<double> &x,
void InstrumentActor::sumDetectors(const std::vector<size_t> &dets, std::vector<double> &x,
std::vector<double> &y, size_t size) const {
Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
if (size > ws->blocksize() || size == 0) {
......@@ -485,26 +486,16 @@ void InstrumentActor::sumDetectors(QList<int> &dets, std::vector<double> &x,
* the x-axis.
* Assumes that all spectra share the x vector.
*
* @param dets :: A list of detector IDs to sum.
* @param dets :: A list of detector Indices to sum.
* @param x :: (output) Time of flight values (or whatever values the x axis
* has) to plot against.
* @param y :: (output) The sums of the counts for each bin.
*/
void InstrumentActor::sumDetectorsUniform(QList<int> &dets,
void InstrumentActor::sumDetectorsUniform(const std::vector<size_t> &dets,
std::vector<double> &x,
std::vector<double> &y) const {
size_t wi;
bool isDataEmpty = dets.isEmpty();
if (!isDataEmpty) {
try {
wi = getWorkspaceIndex(dets[0]);
} catch (Mantid::Kernel::Exception::NotFoundError &) {
isDataEmpty =
true; // Detector doesn't have a workspace index relating to it
}
}
bool isDataEmpty = dets.empty();
if (isDataEmpty) {
x.clear();
......@@ -514,6 +505,7 @@ void InstrumentActor::sumDetectorsUniform(QList<int> &dets,
// find the bins inside the integration range
size_t imin, imax;
auto wi = getWorkspaceIndex(dets[0]);
getBinMinMaxIndex(wi, imin, imax);
Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
......@@ -521,15 +513,11 @@ void InstrumentActor::sumDetectorsUniform(QList<int> &dets,
x.assign(XPoints.begin() + imin, XPoints.begin() + imax);
y.resize(x.size(), 0);
// sum the spectra
foreach (int id, dets) {
try {
size_t index = getWorkspaceIndex(id);
const auto &Y = ws->y(index);
std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(),
std::plus<double>());
} catch (Mantid::Kernel::Exception::NotFoundError &) {
continue; // Detector doesn't have a workspace index relating to it
}
for (auto det : dets) {
auto index = getWorkspaceIndex(det);
const auto &Y = ws->y(index);
std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(),
std::plus<double>());
}
}
......@@ -544,11 +532,11 @@ void InstrumentActor::sumDetectorsUniform(QList<int> &dets,
* @param y :: (output) The sums of the counts for each bin.
* @param size :: (input) Size of the output vectors.
*/
void InstrumentActor::sumDetectorsRagged(QList<int> &dets,
void InstrumentActor::sumDetectorsRagged(const std::vector<size_t> &dets,
std::vector<double> &x,
std::vector<double> &y,
size_t size) const {
if (dets.isEmpty() || size == 0) {
if (dets.empty() || size == 0) {
x.clear();
y.clear();
return;
......@@ -565,9 +553,9 @@ void InstrumentActor::sumDetectorsRagged(QList<int> &dets,
size_t nSpec = 0; // number of actual spectra to add
// fill in the temp workspace with the data from the detectors
foreach (int id, dets) {
for(auto det: dets) {
try {
size_t index = getWorkspaceIndex(id);
size_t index = getWorkspaceIndex(det);
dws->setHistogram(nSpec, ws->histogram(index));
double xmin = dws->x(nSpec).front();
double xmax = dws->x(nSpec).back();
......@@ -1149,13 +1137,11 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin,
auto workspace = getWorkspace();
calculateIntegratedSpectra(*workspace);
auto monitors = getMonitors();
const auto &detectorIDs = getDetectorInfo().detectorIDs();
std::vector<detid_t> monitorIDs;
monitorIDs.reserve(monitors.size());
for (auto mon : monitors)
monitorIDs.push_back(detectorIDs[mon]);
std::vector<size_t> monitorIndices;
auto monitorIndices = workspace->getIndicesFromDetectorIDs(monitorIDs);
monitorIndices.reserve(monitors.size());
for (auto monitor : monitors)
monitorIndices.push_back(getWorkspaceIndex(monitor));
// check that there is at least 1 non-monitor spectrum
if (monitorIndices.size() == m_specIntegrs.size()) {
......@@ -1187,7 +1173,6 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin,
"or NaN).\n"
"Please run ReplaceSpecialValues algorithm for correction.");
}
// integrated_values[i] = sum;
if (sum < m_DataMinValue) {
m_DataMinValue = sum;
}
......@@ -1207,14 +1192,13 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin,
}
/// Add a range of bins for masking
void InstrumentActor::addMaskBinsData(const QList<int> &detIDs) {
QList<int> indices;
foreach (int id, detIDs) {
auto index = m_detid2index_map[id];
indices.append(static_cast<int>(index));
}
if (!indices.isEmpty()) {
m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, indices);
void InstrumentActor::addMaskBinsData(const std::vector<size_t> &indices) {
std::vector<size_t> wsIndices;
wsIndices.reserve(indices.size());
for (auto det: indices)
wsIndices.push_back(getWorkspaceIndex(det));
if (!indices.empty()) {
m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, wsIndices);
auto workspace = getWorkspace();
calculateIntegratedSpectra(*workspace);
resetColors();
......
......@@ -729,9 +729,10 @@ void InstrumentWidgetMaskTab::saveMaskToTable() {
*/
void InstrumentWidgetMaskTab::extractDetsToWorkspace() {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QList<int> dets;
std::vector<size_t> dets;
m_instrWidget->getSurface()->getMaskedDetectors(dets);
DetXMLFile mapFile(dets);
const auto &actor = m_instrWidget->getInstrumentActor();
DetXMLFile mapFile(actor.getDetIDs(dets));
std::string fname = mapFile();
if (!fname.empty()) {
std::string workspaceName = m_instrWidget->getWorkspaceName().toStdString();
......@@ -751,9 +752,10 @@ void InstrumentWidgetMaskTab::extractDetsToWorkspace() {
*/
void InstrumentWidgetMaskTab::sumDetsToWorkspace() {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QList<int> dets;
std::vector<size_t> dets;
m_instrWidget->getSurface()->getMaskedDetectors(dets);
DetXMLFile mapFile(dets, DetXMLFile::Sum);
DetXMLFile mapFile(m_instrWidget->getInstrumentActor().getDetIDs(dets),
DetXMLFile::Sum);
std::string fname = mapFile();
if (!fname.empty()) {
......@@ -773,9 +775,10 @@ void InstrumentWidgetMaskTab::saveIncludeGroupToFile() {
QString fname = m_instrWidget->getSaveFileName("Save grouping file",
"XML files (*.xml);;All (*)");
if (!fname.isEmpty()) {
QList<int> dets;
std::vector<size_t> dets;
m_instrWidget->getSurface()->getMaskedDetectors(dets);
DetXMLFile mapFile(dets, DetXMLFile::Sum, fname);
DetXMLFile mapFile(m_instrWidget->getInstrumentActor().getDetIDs(dets),
DetXMLFile::Sum, fname);
}
}
......@@ -783,10 +786,10 @@ void InstrumentWidgetMaskTab::saveExcludeGroupToFile() {
QString fname = m_instrWidget->getSaveFileName("Save grouping file",
"XML files (*.xml);;All (*)");
if (!fname.isEmpty()) {
QList<int> dets;
std::vector<size_t> dets;
m_instrWidget->getSurface()->getMaskedDetectors(dets);
DetXMLFile mapFile(m_instrWidget->getInstrumentActor().getAllDetIDs(), dets,
fname);
const auto &actor = m_instrWidget->getInstrumentActor();
DetXMLFile mapFile(actor.getAllDetIDs(), actor.getDetIDs(dets), fname);
}
}
......@@ -1109,11 +1112,12 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) {
m_instrWidget->updateInstrumentView(); // to refresh the pick image
Mantid::API::IMaskWorkspace_sptr wsFresh;
QList<int> dets;
const auto &actor = m_instrWidget->getInstrumentActor();
std::vector<size_t> dets;
// get detectors covered by the shapes
m_instrWidget->getSurface()->getMaskedDetectors(dets);
if (!dets.isEmpty()) {
auto wsMask = m_instrWidget->getInstrumentActor().getMaskWorkspace();
if (!dets.empty()) {
auto wsMask = actor.getMaskWorkspace();
// have to cast up to the MaskWorkspace to get access to clone()
std::set<Mantid::detid_t> detList;
......@@ -1122,21 +1126,22 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) {
// but not if the mask is fresh and empty
if (wsMask->getNumberMasked() > 0) {
wsFresh = boost::dynamic_pointer_cast<Mantid::API::IMaskWorkspace>(
m_instrWidget->getInstrumentActor().extractCurrentMask());
m_instrWidget->getInstrumentActor().invertMaskWorkspace();
actor.extractCurrentMask());
actor.invertMaskWorkspace();
}
}
foreach (int id, dets) { detList.insert(id); }
for (auto det : dets)
detList.insert(actor.getDetID(det));
if (!detList.empty()) {
// try to mask each detector separately and ignore any failure
for (auto det = detList.begin(); det != detList.end(); ++det) {
for (auto det: detList) {
try {
if (isROI && wsFresh) {
if (wsMask->isMasked(*det))
wsFresh->setMasked(*det);
if (wsMask->isMasked(det))
wsFresh->setMasked(det);
} else {
wsMask->setMasked(*det);
wsMask->setMasked(det);
}
} catch (...) {
}
......@@ -1160,7 +1165,7 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) {
}
void InstrumentWidgetMaskTab::storeBinMask() {
QList<int> dets;
std::vector<size_t> dets;
// get detectors covered by the shapes
m_instrWidget->getSurface()->getMaskedDetectors(dets);
// mask some bins
......
......@@ -742,7 +742,7 @@ void InstrumentWidgetPickTab::updatePlotMultipleDetectors() {
return;
ProjectionSurface &surface = *getSurface();
if (surface.hasMasks()) {
QList<int> dets;
std::vector<size_t> dets;
surface.getMaskedDetectors(dets);
m_plotController->setPlotData(dets);
} else {
......@@ -830,10 +830,10 @@ void ComponentInfoController::displayInfo(size_t pickID) {
}
const auto &actor = m_instrWidget->getInstrumentActor();
const auto &componentInfo = actor.getComponentInfo();
QString text = "";
int detid = actor.getDetID(pickID);
if (detid >= 0) {
text += displayDetectorInfo(detid);
if (componentInfo.isDetector(pickID)) {
text += displayDetectorInfo(pickID);
} else if (auto componentID = actor.getComponentID(pickID)) {
text += displayNonDetectorInfo(componentID);
} else {
......@@ -851,56 +851,51 @@ void ComponentInfoController::displayInfo(size_t pickID) {
/**
* Return string with info on a detector.
* @param detid :: A detector ID.
* @param index :: A detector Index.
*/
QString ComponentInfoController::displayDetectorInfo(Mantid::detid_t detid) {
QString ComponentInfoController::displayDetectorInfo(size_t index) {
if (m_instrWidgetBlocked) {
clear();
return "";
}
QString text;
if (detid >= 0) {
// collect info about selected detector and add it to text
const auto &actor = m_instrWidget->getInstrumentActor();
const auto &componentInfo = actor.getComponentInfo();
auto det = actor.getDetectorByDetID(detid);
auto detid = actor.getDetID(index);
text = "Selected detector: " +
QString::fromStdString(componentInfo.name(det)) + "\n";
QString::fromStdString(componentInfo.name(index)) + "\n";
text += "Detector ID: " + QString::number(detid) + '\n';
QString wsIndex;
try {
wsIndex = QString::number(actor.getWorkspaceIndex(detid));
} catch (Mantid::Kernel::Exception::NotFoundError &) {
// Detector doesn't have a workspace index relating to it
wsIndex = "None";
}
wsIndex = QString::number(actor.getWorkspaceIndex(index));
text += "Workspace index: "</