/** Converts detector IDs to spectra indexes * @param WS :: the workspace on which the calculations are being performed * @param specNum1 :: spectrum number of the output of the first monitor * @param specNum2 :: spectrum number of the output of the second monitor * @return the indexes of the histograms created by the detector whose ID were passed * @throw NotFoundError if one of the requested spectrum numbers was not found in the workspace */ std::vector<size_t> GetEi::getMonitorSpecIndexs(API::MatrixWorkspace_const_sptr WS, specid_t specNum1, specid_t specNum2) const {// getting spectra numbers from detector IDs is hard because the map works the other way, getting index numbers from spectra numbers has the same problem and we are about to do both std::vector<size_t> specInds; // get the index number of the histogram for the first monitor std::vector<specid_t> specNumTemp(&specNum1, &specNum1+1); WS->getIndicesFromSpectra(specNumTemp, specInds); if ( specInds.size() != 1 ) {// the monitor spectrum isn't present in the workspace, we can't continue from here g_log.error() << "Couldn't find the first monitor spectrum, number " << specNum1 << std::endl; throw Exception::NotFoundError("GetEi::getMonitorSpecIndexs()", specNum1); } // nowe the second monitor std::vector<size_t> specIndexTemp; specNumTemp[0] = specNum2; WS->getIndicesFromSpectra(specNumTemp, specIndexTemp); if ( specIndexTemp.size() != 1 ) {// the monitor spectrum isn't present in the workspace, we can't continue from here g_log.error() << "Couldn't find the second monitor spectrum, number " << specNum2 << std::endl; throw Exception::NotFoundError("GetEi::getMonitorSpecIndexs()", specNum2); } specInds.push_back(specIndexTemp[0]); return specInds; }
/** Make a map containing spectra indexes to group, the indexes could have come from * file, or an array, spectra numbers ... * @param workspace :: the user selected input workspace * @param unUsedSpec :: spectra indexes that are not members of any group */ void GroupDetectors2::getGroups(API::MatrixWorkspace_const_sptr workspace, std::vector<int64_t> &unUsedSpec) { // this is the map that we are going to fill m_GroupSpecInds.clear(); // There are several properties that may contain the user data go through them in order of precedence const std::string filename = getProperty("MapFile"); if ( ! filename.empty() ) {// The file property has been set so try to load the file try { // check if XML file and if yes assume it is a XML grouping file std::string filenameCopy(filename); std::transform(filenameCopy.begin(), filenameCopy.end(), filenameCopy.begin(), tolower); if ( (filenameCopy.find(".xml")) != std::string::npos ) { processXMLFile(filename, workspace, unUsedSpec); } else { // the format of this input file format is described in "GroupDetectors2.h" processFile(filename, workspace, unUsedSpec); } } catch ( std::exception & ) { g_log.error() << name() << ": Error reading input file " << filename << std::endl; throw; } return; } const std::vector<specid_t> spectraList = getProperty("SpectraList"); const std::vector<detid_t> detectorList = getProperty("DetectorList"); const std::vector<size_t> indexList = getProperty("WorkspaceIndexList"); // only look at these other parameters if the file wasn't set if ( ! spectraList.empty() ) { workspace->getIndicesFromSpectra( spectraList, m_GroupSpecInds[0]); g_log.debug() << "Converted " << spectraList.size() << " spectra numbers into spectra indices to be combined\n"; } else {// go through the rest of the properties in order of decreasing presidence, abort when we get the data we need ignore the rest if ( ! detectorList.empty() ) { // we are going to group on the basis of detector IDs, convert from detectors to workspace indices workspace->getIndicesFromDetectorIDs( detectorList, m_GroupSpecInds[0]); g_log.debug() << "Found " << m_GroupSpecInds[0].size() << " spectra indices from the list of " << detectorList.size() << " detectors\n"; } else if ( ! indexList.empty() ) { m_GroupSpecInds[0] = indexList; g_log.debug() << "Read in " << m_GroupSpecInds[0].size() << " spectra indices to be combined\n"; } //check we don't have an index that is too high for the workspace size_t maxIn = static_cast<size_t>(workspace->getNumberHistograms() - 1); std::vector<size_t>::const_iterator it = m_GroupSpecInds[0].begin(); for( ; it != m_GroupSpecInds[0].end() ; ++it ) { if ( *it > maxIn ) { g_log.error() << "Spectra index " << *it << " doesn't exist in the input workspace, the highest possible index is " << maxIn << std::endl; throw std::out_of_range("One of the spectra requested to group does not exist in the input workspace"); } } } if ( m_GroupSpecInds[0].empty() ) { g_log.information() << name() << ": File, WorkspaceIndexList, SpectraList, and DetectorList properties are all empty\n"; throw std::invalid_argument("All list properties are empty, nothing to group"); } // up date unUsedSpec, this is used to find duplicates and when the user has set KeepUngroupedSpectra std::vector<size_t>::const_iterator index = m_GroupSpecInds[0].begin(); for ( ; index != m_GroupSpecInds[0].end(); ++index ) {// the vector<int> m_GroupSpecInds[0] must not index contain numbers that don't exist in the workspaace if ( unUsedSpec[*index] != USED ) { unUsedSpec[*index] = USED; } else g_log.warning() << "Duplicate index, " << *index << ", found\n"; } }