Commit 6713380b authored by Lamar Moore's avatar Lamar Moore
Browse files

Fix detector color issue #21339

parent 6f18fe75
......@@ -215,11 +215,13 @@ private:
calculateIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace);
/// Sum the counts in detectors if the workspace has equal bins for all
/// spectra
void sumDetectorsUniform(const std::vector<size_t> &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(const std::vector<size_t> &dets, std::vector<double> &x,
std::vector<double> &y, size_t size) const;
void sumDetectorsRagged(const std::vector<size_t> &dets,
std::vector<double> &x, std::vector<double> &y,
size_t size) const;
void setupPickColors();
......@@ -258,22 +260,13 @@ private:
bool m_volumeRender;
/// Color map scale type: linear or log
GraphOptions::ScaleType m_scaleType;
/// All det ids in the instrument in order of pickIDs, populated by Obj..Actor
/// constructors
mutable std::vector<Mantid::detid_t> m_detIDs;
/// All non-detector component IDs in order of pickIDs. For any index i a
/// pickID of the component
/// is m_detIDs.size() + i.
mutable std::vector<Mantid::Geometry::ComponentID> m_nonDetIDs;
/// All detector positions, in order of pickIDs, populated by Obj..Actor
/// constructors
mutable std::vector<Mantid::Kernel::V3D> m_detPos;
/// Position to refer to when detector not found
const Mantid::Kernel::V3D m_defaultPos;
/// Colors in order of component info
mutable std::vector<GLColor> m_colors;
std::vector<GLColor> m_colors;
std::vector<size_t> m_monitors;
std::vector<size_t> m_components;
/// Colour of a masked detector
GLColor m_maskedColor;
/// Colour of a "failed" detector
......
......@@ -45,6 +45,8 @@ size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) {
index += b - 1;
return index;
}
GLColor defaultDetectorColor() { return GLColor(200, 200, 200, 1); }
} // namespace
double InstrumentActor::m_tolerance = 0.00001;
......@@ -81,6 +83,13 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling,
"InstrumentActor passed a workspace that isn't a MatrixWorkspace");
const auto &componentInfo = sharedWorkspace->componentInfo();
const auto &detectorInfo = sharedWorkspace->detectorInfo();
for (size_t i = 0; i < componentInfo.size(); ++i) {
if (!componentInfo.isDetector(i))
m_components.push_back(i);
else if (detectorInfo.isMonitor(i))
m_monitors.push_back(i);
}
m_isCompVisible.assign(componentInfo.size(), true);
setupPickColors();
......@@ -343,15 +352,7 @@ void InstrumentActor::clearMasks() {
}
std::vector<size_t> InstrumentActor::getMonitors() const {
const auto &detectorInfo = getDetectorInfo();
std::vector<size_t> monitors;
for (size_t i = 0; i < detectorInfo.size(); i++) {
if (detectorInfo.isMonitor(i))
monitors.push_back(i);
}
return monitors;
return m_monitors;
}
Instrument_const_sptr InstrumentActor::getInstrument() const {
......@@ -647,15 +648,22 @@ void InstrumentActor::resetColors() {
if (detectorInfo.isMasked(detIndex) || masked) {
m_colors[detIndex] = m_maskedColor;
continue;
} else {
auto integratedValue = m_specIntegrs[wi];
color = m_colorMap.rgb(qwtInterval, integratedValue);
auto color = m_colorMap.rgb(qwtInterval, integratedValue);
m_colors[detIndex] = GLColor(
qRed(color), qGreen(color), qBlue(color),
static_cast<int>(255 * (integratedValue / m_DataMaxScaleValue)));
continue;
}
continue;
}
}
for (auto comp : m_components)
m_colors[comp] = defaultDetectorColor();
setupPickColors();
invalidateDisplayLists();
emit colorMapChanged();
......@@ -1136,12 +1144,11 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin,
auto workspace = getWorkspace();
calculateIntegratedSpectra(*workspace);
auto monitors = getMonitors();
std::vector<size_t> monitorIndices;
monitorIndices.reserve(monitors.size());
for (auto monitor : monitors)
monitorIndices.push_back(getWorkspaceIndex(monitor));
monitorIndices.reserve(m_monitors.size());
for (auto monitor : m_monitors)
monitorIndices.push_back(getWorkspaceIndex(monitor));
// check that there is at least 1 non-monitor spectrum
if (monitorIndices.size() == m_specIntegrs.size()) {
......@@ -1158,30 +1165,40 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin,
m_DataMinValue = DBL_MAX;
m_DataMaxValue = -DBL_MAX;
// Now we need to convert to a vector where each entry is the sum for the
// detector ID at that spot (in integrated_values).
for (size_t i = 0; i < m_specIntegrs.size(); ++i) {
// skip the monitors
if (std::find(monitorIndices.begin(), monitorIndices.end(), i) !=
monitorIndices.end()) {
continue;
}
double sum = m_specIntegrs[i];
if (!std::isfinite(sum)) {
throw std::runtime_error(
"The workspace contains values that cannot be displayed (infinite "
"or NaN).\n"
"Please run ReplaceSpecialValues algorithm for correction.");
}
if (sum < m_DataMinValue) {
m_DataMinValue = sum;
}
if (sum > m_DataMaxValue) {
m_DataMaxValue = sum;
}
if (sum > 0 && sum < m_DataPositiveMinValue) {
m_DataPositiveMinValue = sum;
}
if (std::any_of(m_specIntegrs.begin(), m_specIntegrs.end(),
[](double val) { return !std::isfinite(val); }))
throw std::runtime_error(
"The workspace contains values that cannot be displayed (infinite "
"or NaN).\n"
"Please run ReplaceSpecialValues algorithm for correction.");
std::vector<double> copy;
copy.reserve(m_specIntegrs.size());
size_t i = 0;
const auto &spectrumInfo = workspace->spectrumInfo();
//Ignore monitors indices if multiple detectors aren't grouped.
std::remove_copy_if(
m_specIntegrs.cbegin(), m_specIntegrs.cend(), std::back_inserter(copy),
[&spectrumInfo, &monitorIndices, &i](double val) {
auto ret = spectrumInfo.spectrumDefinition(i).size() == 0 &&
std::find(monitorIndices.begin(), monitorIndices.end(),
i) != monitorIndices.end();
++i;
return ret;
});
copy.shrink_to_fit();
auto res = std::minmax_element(copy.cbegin(), copy.cend());
m_DataMinValue = *res.first;
m_DataMaxValue = *res.second;
if (m_DataMinValue > 0)
m_DataPositiveMinValue = m_DataMinValue;
else {
auto lb = std::lower_bound(copy.cbegin(), copy.cend(), 0);
if (lb != copy.cend())
m_DataPositiveMinValue = *lb;
}
}
......
......@@ -1130,12 +1130,12 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) {
actor.invertMaskWorkspace();
}
}
for (auto det : dets)
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) {
for (auto det : detList) {
try {
if (isROI && wsFresh) {
if (wsMask->isMasked(det))
......
......@@ -860,36 +860,36 @@ QString ComponentInfoController::displayDetectorInfo(size_t index) {
}
QString text;
// collect info about selected detector and add it to text
const auto &actor = m_instrWidget->getInstrumentActor();
const auto &componentInfo = actor.getComponentInfo();
auto detid = actor.getDetID(index);
text = "Selected detector: " +
QString::fromStdString(componentInfo.name(index)) + "\n";
text += "Detector ID: " + QString::number(detid) + '\n';
QString wsIndex;
wsIndex = QString::number(actor.getWorkspaceIndex(index));
text += "Workspace index: " + wsIndex + '\n';
Mantid::Kernel::V3D pos = componentInfo.position(index);
text += "xyz: " + QString::number(pos.X()) + "," +
QString::number(pos.Y()) + "," + QString::number(pos.Z()) + '\n';
double r, t, p;
pos.getSpherical(r, t, p);
text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," +
QString::number(p) + '\n';
if (componentInfo.hasParent(index)) {
QString textpath;
auto parent = index;
while (componentInfo.hasParent(parent)) {
parent = componentInfo.parent(parent);
textpath =
"/" + QString::fromStdString(componentInfo.name(parent)) + textpath;
}
text += "Component path:" + textpath + "/" +
QString::fromStdString(componentInfo.name(index)) + '\n';
// collect info about selected detector and add it to text
const auto &actor = m_instrWidget->getInstrumentActor();
const auto &componentInfo = actor.getComponentInfo();
auto detid = actor.getDetID(index);
text = "Selected detector: " +
QString::fromStdString(componentInfo.name(index)) + "\n";
text += "Detector ID: " + QString::number(detid) + '\n';
QString wsIndex;
wsIndex = QString::number(actor.getWorkspaceIndex(index));
text += "Workspace index: " + wsIndex + '\n';
Mantid::Kernel::V3D pos = componentInfo.position(index);
text += "xyz: " + QString::number(pos.X()) + "," + QString::number(pos.Y()) +
"," + QString::number(pos.Z()) + '\n';
double r, t, p;
pos.getSpherical(r, t, p);
text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," +
QString::number(p) + '\n';
if (componentInfo.hasParent(index)) {
QString textpath;
auto parent = index;
while (componentInfo.hasParent(parent)) {
parent = componentInfo.parent(parent);
textpath =
"/" + QString::fromStdString(componentInfo.name(parent)) + textpath;
}
text += "Component path:" + textpath + "/" +
QString::fromStdString(componentInfo.name(index)) + '\n';
const double integrated = actor.getIntegratedCounts(index);
const QString counts =
integrated == -1.0 ? "N/A" : QString::number(integrated);
......@@ -1189,7 +1189,8 @@ void DetectorPlotController::plotSingle(size_t detindex) {
* LENGTH
* PHI
* The units can be set with setTubeXUnits(...) method.
* @param detindex :: A detector index. The miniplot will display data for a component
* @param detindex :: A detector index. The miniplot will display data for a
* component
* containing the detector
* with this id.
*/
......@@ -1215,7 +1216,8 @@ void DetectorPlotController::plotTube(size_t detindex) {
/**
* Plot the accumulated data in a tube against time of flight.
* @param detindex :: A detector id. The miniplot will display data for a component
* @param detindex :: A detector id. The miniplot will display data for a
* component
* containing the detector
* with this id.
*/
......@@ -1245,13 +1247,14 @@ void DetectorPlotController::plotTubeSums(size_t detindex) {
* LENGTH
* PHI
* The units can be set with setTubeXUnits(...) method.
* @param detindex :: A detector index. The miniplot will display data for a component
* @param detindex :: A detector index. The miniplot will display data for a
* component
* containing the detector
* with this id.
*/
void DetectorPlotController::plotTubeIntegrals(size_t detindex) {
const auto &actor = m_instrWidget->getInstrumentActor();
const auto &componentInfo =actor.getComponentInfo();
const auto &componentInfo = actor.getComponentInfo();
std::vector<double> x, y;
prepareDataForIntegralsPlot(detindex, x, y);
if (x.empty() || y.empty()) {
......@@ -1305,7 +1308,8 @@ void DetectorPlotController::prepareDataForSinglePlot(
/**
* Prepare data for plotting accumulated data in a tube against time of flight.
* @param detindex :: A detector index. The miniplot will display data for a component
* @param detindex :: A detector index. The miniplot will display data for a
* component
* containing the detector with this index.
* @param x :: Vector of x coordinates (output)
* @param y :: Vector of y coordinates (output)
......
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