/** Execute the algorithm. */ void CreateGroupingWorkspace::exec() { MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); std::string InstrumentName = getPropertyValue("InstrumentName"); std::string InstrumentFilename = getPropertyValue("InstrumentFilename"); std::string OldCalFilename = getPropertyValue("OldCalFilename"); std::string GroupNames = getPropertyValue("GroupNames"); std::string grouping = getPropertyValue("GroupDetectorsBy"); int numGroups = getProperty("FixedGroupCount"); std::string componentName = getPropertyValue("ComponentName"); // Some validation int numParams = 0; if (inWS) numParams++; if (!InstrumentName.empty()) numParams++; if (!InstrumentFilename.empty()) numParams++; if (numParams > 1) throw std::invalid_argument("You must specify exactly ONE way to get an " "instrument (workspace, instrument name, or " "IDF file). You specified more than one."); if (numParams == 0) throw std::invalid_argument("You must specify exactly ONE way to get an " "instrument (workspace, instrument name, or " "IDF file). You specified none."); if (!OldCalFilename.empty() && !GroupNames.empty()) throw std::invalid_argument("You must specify either to use the " "OldCalFilename parameter OR GroupNames but " "not both!"); bool sortnames = false; // ---------- Get the instrument one of 3 ways --------------------------- Instrument_const_sptr inst; if (inWS) { inst = inWS->getInstrument(); } else { Algorithm_sptr childAlg = createChildAlgorithm("LoadInstrument", 0.0, 0.2); MatrixWorkspace_sptr tempWS = boost::make_shared<Workspace2D>(); childAlg->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS); childAlg->setPropertyValue("Filename", InstrumentFilename); childAlg->setProperty("RewriteSpectraMap", Mantid::Kernel::OptionalBool(true)); childAlg->setPropertyValue("InstrumentName", InstrumentName); childAlg->executeAsChildAlg(); inst = tempWS->getInstrument(); } if (GroupNames.empty() && OldCalFilename.empty()) { if (grouping.compare("All") == 0) { GroupNames = inst->getName(); } else if (inst->getName().compare("SNAP") == 0 && grouping.compare("Group") == 0) { GroupNames = "East,West"; } else { sortnames = true; GroupNames = ""; int maxRecurseDepth = this->getProperty("MaxRecursionDepth"); // cppcheck-suppress syntaxError PRAGMA_OMP(parallel for schedule(dynamic, 1) ) for (int num = 0; num < 300; ++num) { PARALLEL_START_INTERUPT_REGION std::ostringstream mess; mess << grouping << num; IComponent_const_sptr comp = inst->getComponentByName(mess.str(), maxRecurseDepth); PARALLEL_CRITICAL(GroupNames) if (comp) GroupNames += mess.str() + ","; PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION } } // --------------------------- Create the output -------------------------- auto outWS = boost::make_shared<GroupingWorkspace>(inst); this->setProperty("OutputWorkspace", outWS); // This will get the grouping std::map<detid_t, int> detIDtoGroup; Progress prog(this, 0.2, 1.0, outWS->getNumberHistograms()); // Make the grouping one of three ways: if (!GroupNames.empty()) detIDtoGroup = makeGroupingByNames(GroupNames, inst, prog, sortnames); else if (!OldCalFilename.empty()) detIDtoGroup = readGroupingFile(OldCalFilename, prog); else if ((numGroups > 0) && !componentName.empty()) detIDtoGroup = makeGroupingByNumGroups(componentName, numGroups, inst, prog); g_log.information() << detIDtoGroup.size() << " entries in the detectorID-to-group map.\n"; setProperty("NumberGroupedSpectraResult", static_cast<int>(detIDtoGroup.size())); if (detIDtoGroup.empty()) { g_log.warning() << "Creating empty group workspace\n"; setProperty("NumberGroupsResult", static_cast<int>(0)); } else { size_t numNotFound = 0; // Make the groups, if any std::map<detid_t, int>::const_iterator it_end = detIDtoGroup.end(); std::map<detid_t, int>::const_iterator it; std::unordered_set<int> groupCount; for (it = detIDtoGroup.begin(); it != it_end; ++it) { int detID = it->first; int group = it->second; groupCount.insert(group); try { outWS->setValue(detID, double(group)); } catch (std::invalid_argument &) { numNotFound++; } } setProperty("NumberGroupsResult", static_cast<int>(groupCount.size())); if (numNotFound > 0) g_log.warning() << numNotFound << " detector IDs (out of " << detIDtoGroup.size() << ") were not found in the instrument\n."; } }
/** Executes the algorithm * * @throw Exception::FileError If the grouping file cannot be opened or read successfully * @throw runtime_error If unable to run one of the sub-algorithms successfully */ void DiffractionFocussing::exec() { // retrieve the properties std::string groupingFileName=getProperty("GroupingFileName"); // Get the input workspace MatrixWorkspace_sptr inputW = getProperty("InputWorkspace"); bool dist = inputW->isDistribution(); //do this first to check that a valid file is available before doing any work std::multimap<int64_t,int64_t> detectorGroups;// <group, UDET> if (!readGroupingFile(groupingFileName, detectorGroups)) { throw Exception::FileError("Error reading .cal file",groupingFileName); } //Convert to d-spacing units API::MatrixWorkspace_sptr tmpW = convertUnitsToDSpacing(inputW); //Rebin to a common set of bins RebinWorkspace(tmpW); std::set<int64_t> groupNumbers; for(std::multimap<int64_t,int64_t>::const_iterator d = detectorGroups.begin();d!=detectorGroups.end();d++) { if (groupNumbers.find(d->first) == groupNumbers.end()) { groupNumbers.insert(d->first); } } int iprogress = 0; int iprogress_count = static_cast<int>(groupNumbers.size()); int iprogress_step = iprogress_count / 100; if (iprogress_step == 0) iprogress_step = 1; std::vector<int64_t> resultIndeces; for(std::set<int64_t>::const_iterator g = groupNumbers.begin();g!=groupNumbers.end();g++) { if (iprogress++ % iprogress_step == 0) { progress(0.68 + double(iprogress)/iprogress_count/3); } std::multimap<int64_t,int64_t>::const_iterator from = detectorGroups.lower_bound(*g); std::multimap<int64_t,int64_t>::const_iterator to = detectorGroups.upper_bound(*g); std::vector<detid_t> detectorList; for(std::multimap<int64_t,int64_t>::const_iterator d = from;d!=to;d++) detectorList.push_back(static_cast<detid_t>(d->second)); // Want version 1 of GroupDetectors here API::IAlgorithm_sptr childAlg = createSubAlgorithm("GroupDetectors",-1.0,-1.0,true,1); childAlg->setProperty("Workspace", tmpW); childAlg->setProperty< std::vector<detid_t> >("DetectorList",detectorList); childAlg->executeAsSubAlg(); try { // get the index of the combined spectrum int ri = childAlg->getProperty("ResultIndex"); if (ri >= 0) { resultIndeces.push_back(ri); } } catch(...) { throw std::runtime_error("Unable to get Properties from GroupDetectors sub-algorithm"); } } // Discard left-over spectra, but print warning message giving number discarded int discarded = 0; const int64_t oldHistNumber = tmpW->getNumberHistograms(); API::Axis *spectraAxis = tmpW->getAxis(1); for(int64_t i=0; i < oldHistNumber; i++) if ( spectraAxis->spectraNo(i) >= 0 && find(resultIndeces.begin(),resultIndeces.end(),i) == resultIndeces.end()) { ++discarded; } g_log.warning() << "Discarded " << discarded << " spectra that were not assigned to any group" << std::endl; // Running GroupDetectors leads to a load of redundant spectra // Create a new workspace that's the right size for the meaningful spectra and copy them in int64_t newSize = tmpW->blocksize(); API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(tmpW,resultIndeces.size(),newSize+1,newSize); // Copy units outputW->getAxis(0)->unit() = tmpW->getAxis(0)->unit(); outputW->getAxis(1)->unit() = tmpW->getAxis(1)->unit(); API::Axis *spectraAxisNew = outputW->getAxis(1); for(int64_t hist=0; hist < static_cast<int64_t>(resultIndeces.size()); hist++) { int64_t i = resultIndeces[hist]; double spNo = static_cast<double>(spectraAxis->spectraNo(i)); MantidVec &tmpE = tmpW->dataE(i); MantidVec &outE = outputW->dataE(hist); MantidVec &tmpY = tmpW->dataY(i); MantidVec &outY = outputW->dataY(hist); MantidVec &tmpX = tmpW->dataX(i); MantidVec &outX = outputW->dataX(hist); outE.assign(tmpE.begin(),tmpE.end()); outY.assign(tmpY.begin(),tmpY.end()); outX.assign(tmpX.begin(),tmpX.end()); spectraAxisNew->setValue(hist,spNo); spectraAxis->setValue(i,-1); } progress(1.); outputW->isDistribution(dist); // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); return; }