diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SXDMDNorm.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SXDMDNorm.h index df169b38999be8ad34b6b0d192d7f00bca2f2fee..084b120d75835d359d9054c34e429d7efe81be84 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SXDMDNorm.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SXDMDNorm.h @@ -56,6 +56,11 @@ namespace Mantid void cacheDimensionXValues(); void calculateNormalization(const std::vector<coord_t> &otherValues, const Kernel::Matrix<coord_t> &affineTrans); + std::vector<detid_t> removeGroupedIDs(const API::ExperimentInfo & exptInfo, + const std::vector<detid_t> &detIDs); + Geometry::IDetector_const_sptr getThetaPhi(const detid_t detID, + const API::ExperimentInfo & exptInfo, + double &theta, double &phi); std::vector<Kernel::VMD> calculateIntersections(const double theta, const double phi); /// number of MD dimensions diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SXDMDNorm.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SXDMDNorm.cpp index 4cadedc9b6795e6786039b3db43ca5d2ee87a307..7918a0c74b84a910f416b1fa28ae17374e555db0 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/SXDMDNorm.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/SXDMDNorm.cpp @@ -382,9 +382,12 @@ namespace Mantid const double protonCharge = exptInfoZero.run().getProtonCharge(); auto instrument = exptInfoZero.getInstrument(); - std::vector<detid_t> detIDS = instrument->getDetectorIDs(true); - const int64_t ndets = static_cast<int64_t>(detIDS.size()); - // detector->workspace index map + std::vector<detid_t> detIDs = instrument->getDetectorIDs(true); + // Prune out those that are part of a group and simply leave the head of the group + detIDs = removeGroupedIDs(exptInfoZero, detIDs); + + // Mappings + const int64_t ndets = static_cast<int64_t>(detIDs.size()); const detid2index_map fluxDetToIdx = fluxEventWS->getDetectorIDToWorkspaceIndexMap(); const detid2index_map solidAngDetToIdx = solidAngleWS->getDetectorIDToWorkspaceIndexMap(); @@ -394,12 +397,11 @@ namespace Mantid { PARALLEL_START_INTERUPT_REGION - const auto detID = detIDS[i]; - auto detector = instrument->getDetector(detID); - if(detector->isMonitor() || detector->isMasked()) continue; - - const double theta = detector->getTwoTheta(m_samplePos, m_beamDir); - const double phi = detector->getPhi(); + const auto detID = detIDs[i]; + double theta(0.0), phi(0.0); + auto spectrum = getThetaPhi(detID, exptInfoZero, theta, phi); + if(spectrum->isMonitor() || spectrum->isMasked()) continue; + // Intersections auto intersections = calculateIntersections(theta, phi); if(intersections.empty()) continue; @@ -458,7 +460,50 @@ namespace Mantid } PARALLEL_CHECK_INTERUPT_REGION - delete prog; + delete prog; + } + + /** + * Checks for IDs that are actually part of the same group and just keeps one from the group. + * For a 1:1 map, none will be removed. + * @param exptInfo An ExperimentInfo object that defines the grouping + * @param detIDs A list of existing IDs + * @return A new list of IDs + */ + std::vector<detid_t> SXDMDNorm::removeGroupedIDs(const ExperimentInfo &exptInfo, const std::vector<detid_t> &detIDs) + { + const size_t ntotal = detIDs.size(); + std::vector<detid_t> singleIDs; + singleIDs.reserve(ntotal/2); // reserve half. In the case of 1:1 it will double to the correct size once + + for(auto iter = detIDs.begin(); iter != detIDs.end(); ++iter) + { + const auto & members = exptInfo.getGroupMembers(*iter); + singleIDs.push_back(members.front()); + } + + return singleIDs; + } + + /** + * Get the theta and phi angles for the given ID. If the detector was part of a group, + * as defined in the ExperimentInfo object, then the theta/phi are for the whole set. + * @param detID A reference to a single ID + * @param exptInfo A reference to the ExperimentInfo that defines that spectrum->detector mapping + * @param theta [Output] Set to the theta angle for the detector (set) + * @param phi [Output] Set to the phi angle for the detector (set) + * @return A poiner to the Detector object for this spectrum as a whole + * (may be a single pixel or group) + */ + Geometry::IDetector_const_sptr + SXDMDNorm::getThetaPhi(const detid_t detID, + const ExperimentInfo &exptInfo, + double &theta, double &phi) + { + const auto spectrum = exptInfo.getDetectorByID(detID); + theta = spectrum->getTwoTheta(m_samplePos, m_beamDir); + phi = spectrum->getPhi(); + return spectrum; } /**