/** Add workspace2 to workspace1 by adding spectrum. */ MatrixWorkspace_sptr AlignAndFocusPowder::conjoinWorkspaces(API::MatrixWorkspace_sptr ws1, API::MatrixWorkspace_sptr ws2, size_t offset) { // Get information from ws1: maximum spectrum number, and store original // spectrum Nos size_t nspec1 = ws1->getNumberHistograms(); specnum_t maxspecNo1 = 0; std::vector<specnum_t> origspecNos; for (size_t i = 0; i < nspec1; ++i) { specnum_t tmpspecNo = ws1->getSpectrum(i).getSpectrumNo(); origspecNos.push_back(tmpspecNo); if (tmpspecNo > maxspecNo1) maxspecNo1 = tmpspecNo; } g_log.information() << "[DBx536] Max spectrum number of ws1 = " << maxspecNo1 << ", Offset = " << offset << ".\n"; size_t nspec2 = ws2->getNumberHistograms(); // Conjoin 2 workspaces Algorithm_sptr alg = this->createChildAlgorithm("AppendSpectra"); alg->initialize(); ; alg->setProperty("InputWorkspace1", ws1); alg->setProperty("InputWorkspace2", ws2); alg->setProperty("OutputWorkspace", ws1); alg->setProperty("ValidateInputs", false); alg->executeAsChildAlg(); API::MatrixWorkspace_sptr outws = alg->getProperty("OutputWorkspace"); // FIXED : Restore the original spectrum Nos to spectra from ws1 for (size_t i = 0; i < nspec1; ++i) { specnum_t tmpspecNo = outws->getSpectrum(i).getSpectrumNo(); outws->getSpectrum(i).setSpectrumNo(origspecNos[i]); g_log.information() << "[DBx540] Conjoined spectrum " << i << ": restore spectrum number to " << outws->getSpectrum(i).getSpectrumNo() << " from spectrum number = " << tmpspecNo << ".\n"; } // Rename spectrum number if (offset >= 1) { for (size_t i = 0; i < nspec2; ++i) { specnum_t newspecid = maxspecNo1 + static_cast<specnum_t>((i) + offset); outws->getSpectrum(nspec1 + i).setSpectrumNo(newspecid); // ISpectrum* spec = outws->getSpectrum(nspec1+i); // if (spec) // spec->setSpectrumNo(3); } } return outws; }
/** Sum all detector pixels except monitors and masked detectors * @param WS :: The workspace containing the spectrum to sum * @return A Workspace2D containing the sum */ API::MatrixWorkspace_sptr CalculateTransmissionBeamSpreader::sumSpectra(API::MatrixWorkspace_sptr WS) { Algorithm_sptr childAlg = createChildAlgorithm("SumSpectra"); childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", WS); childAlg->setProperty<bool>("IncludeMonitors", false); childAlg->executeAsChildAlg(); return childAlg->getProperty("OutputWorkspace"); }
/** Perform SortEvents on the output workspaces * but only if they are EventWorkspaces. * * @param ws :: any Workspace. Does nothing if not EventWorkspace. */ void AlignAndFocusPowder::doSortEvents(Mantid::API::Workspace_sptr ws) { EventWorkspace_sptr eventWS = boost::dynamic_pointer_cast<EventWorkspace>(ws); if (!eventWS) return; Algorithm_sptr alg = this->createChildAlgorithm("SortEvents"); alg->setProperty("InputWorkspace", eventWS); alg->setPropertyValue("SortBy", "X Value"); alg->executeAsChildAlg(); }
/** Perform SortEvents on the output workspaces (accumulation or output) * but only if they are EventWorkspaces. This will help the GUI * cope with redrawing. * * @param ws :: any Workspace. Does nothing if not EventWorkspace. */ void LoadLiveData::doSortEvents(Mantid::API::Workspace_sptr ws) { EventWorkspace_sptr eventWS = boost::dynamic_pointer_cast<EventWorkspace>(ws); if (!eventWS) return; CPUTimer tim; Algorithm_sptr alg = this->createChildAlgorithm("SortEvents"); alg->setProperty("InputWorkspace", eventWS); alg->setPropertyValue("SortBy", "X Value"); alg->executeAsChildAlg(); g_log.debug() << tim << " to perform SortEvents on " << ws->name() << '\n'; }
/** Extracts a single spectrum from a Workspace2D into a new workspaces. Uses * CropWorkspace to do this. * @param WS :: The workspace containing the spectrum to extract * @param index :: The workspace index of the spectrum to extract * @return A Workspace2D containing the extracted spectrum */ API::MatrixWorkspace_sptr CalculateTransmissionBeamSpreader::extractSpectrum(API::MatrixWorkspace_sptr WS, const size_t index) { // Check that given spectra are monitors if (!WS->getDetector(index)->isMonitor()) { g_log.information( "The Incident Beam Monitor UDET provided is not marked as a monitor"); } Algorithm_sptr childAlg = createChildAlgorithm("ExtractSingleSpectrum", 0.0, 0.4); childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", WS); childAlg->setProperty<int>("WorkspaceIndex", static_cast<int>(index)); childAlg->executeAsChildAlg(); return childAlg->getProperty("OutputWorkspace"); }
/** Get a pointer to an instrument in one of 3 ways: InputWorkspace, * InstrumentName, InstrumentFilename * @param alg :: algorithm from which to get the property values. * */ Geometry::Instrument_const_sptr LoadCalFile::getInstrument3Ways(Algorithm *alg) { MatrixWorkspace_sptr inWS = alg->getProperty("InputWorkspace"); std::string InstrumentName = alg->getPropertyValue("InstrumentName"); std::string InstrumentFilename = alg->getPropertyValue("InstrumentFilename"); // 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."); // ---------- Get the instrument one of 3 ways --------------------------- Instrument_const_sptr inst; if (inWS) { inst = inWS->getInstrument(); } else { Algorithm_sptr childAlg = alg->createChildAlgorithm("LoadInstrument", 0.0, 0.2); MatrixWorkspace_sptr tempWS = boost::make_shared<Workspace2D>(); childAlg->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS); childAlg->setPropertyValue("Filename", InstrumentFilename); childAlg->setPropertyValue("InstrumentName", InstrumentName); childAlg->setProperty("RewriteSpectraMap", Mantid::Kernel::OptionalBool(false)); childAlg->executeAsChildAlg(); inst = tempWS->getInstrument(); } return inst; }
/** Uses 'Linear' as a ChildAlgorithm to fit the log of the exponential curve * expected for the transmission. * @param WS :: The single-spectrum workspace to fit * @return A workspace containing the fit */ API::MatrixWorkspace_sptr CalculateTransmissionBeamSpreader::fitToData(API::MatrixWorkspace_sptr WS) { g_log.information("Fitting the experimental transmission curve"); Algorithm_sptr childAlg = createChildAlgorithm("Linear", 0.6, 1.0); childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", WS); const double lambdaMin = getProperty("MinWavelength"); const double lambdaMax = getProperty("MaxWavelength"); childAlg->setProperty<double>("StartX", lambdaMin); childAlg->setProperty<double>("EndX", lambdaMax); childAlg->executeAsChildAlg(); std::string fitStatus = childAlg->getProperty("FitStatus"); if (fitStatus != "success") { g_log.error("Unable to successfully fit the data: " + fitStatus); throw std::runtime_error("Unable to successfully fit the data"); } // Only get to here if successful MatrixWorkspace_sptr result = childAlg->getProperty("OutputWorkspace"); if (logFit) { // Need to transform back to 'unlogged' double b = childAlg->getProperty("FitIntercept"); double m = childAlg->getProperty("FitSlope"); b = std::pow(10, b); m = std::pow(10, m); const MantidVec &X = result->readX(0); MantidVec &Y = result->dataY(0); MantidVec &E = result->dataE(0); for (size_t i = 0; i < Y.size(); ++i) { Y[i] = b * (std::pow(m, 0.5 * (X[i] + X[i + 1]))); E[i] = std::abs(E[i] * Y[i]); } } return result; }
/** * Determine the instrument from the various input parameters. * * @return The correct instrument. */ Instrument_const_sptr CreateChunkingFromInstrument::getInstrument() { // try the input workspace MatrixWorkspace_sptr inWS = getProperty(PARAM_IN_WKSP); if (inWS) { return inWS->getInstrument(); } // temporary workspace to hang everything else off of MatrixWorkspace_sptr tempWS(new Workspace2D()); // name of the instrument string instName = getPropertyValue(PARAM_INST_NAME); // see if there is an input file string filename = getPropertyValue(PARAM_IN_FILE); if (!filename.empty()) { string top_entry_name("entry"); // TODO make more flexible // get the instrument name from the filename size_t n = filename.rfind('/'); if (n != std::string::npos) { std::string temp = filename.substr(n + 1, filename.size() - n - 1); n = temp.find('_'); if (n != std::string::npos && n > 0) { instName = temp.substr(0, n); } } // read information from the nexus file itself try { NeXus::File nxsfile(filename); // get the run start time string start_time; nxsfile.openGroup(top_entry_name, "NXentry"); nxsfile.readData("start_time", start_time); tempWS->mutableRun().addProperty( "run_start", DateAndTime(start_time).toISO8601String(), true); // get the instrument name nxsfile.openGroup("instrument", "NXinstrument"); nxsfile.readData("name", instName); nxsfile.closeGroup(); // Test if IDF exists in file, move on quickly if not nxsfile.openPath("instrument/instrument_xml"); nxsfile.close(); IAlgorithm_sptr loadInst = createChildAlgorithm("LoadIDFFromNexus", 0.0, 0.2); // Now execute the Child Algorithm. Catch and log any error, but don't // stop. try { loadInst->setPropertyValue("Filename", filename); loadInst->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS); loadInst->setPropertyValue("InstrumentParentPath", top_entry_name); loadInst->execute(); } catch (std::invalid_argument &) { g_log.error("Invalid argument to LoadIDFFromNexus Child Algorithm "); } catch (std::runtime_error &) { g_log.debug("No instrument definition found in " + filename + " at " + top_entry_name + "/instrument"); } if (loadInst->isExecuted()) return tempWS->getInstrument(); else g_log.information("No IDF loaded from Nexus file."); } catch (::NeXus::Exception &) { g_log.information("No instrument definition found in " + filename + " at " + top_entry_name + "/instrument"); } } // run LoadInstrument if other methods have not run string instFilename = getPropertyValue(PARAM_INST_FILE); Algorithm_sptr childAlg = createChildAlgorithm("LoadInstrument", 0.0, 0.2); childAlg->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS); childAlg->setPropertyValue("Filename", instFilename); childAlg->setPropertyValue("InstrumentName", instName); childAlg->executeAsChildAlg(); return tempWS->getInstrument(); }
/* Executes the underlying algorithm to create the MVP model. @param factory : visualisation factory to use. @param loadingProgressUpdate : Handler for GUI updates while algorithm progresses. @param drawingProgressUpdate : Handler for GUI updates while vtkDataSetFactory::create occurs. */ vtkSmartPointer<vtkDataSet> EventNexusLoadingPresenter::execute(vtkDataSetFactory *factory, ProgressAction &loadingProgressUpdate, ProgressAction &drawingProgressUpdate) { using namespace Mantid::API; using namespace Mantid::Geometry; this->m_view->getLoadInMemory(); // TODO, nexus reader algorithm currently has // no use of this. if (this->shouldLoad()) { Poco::NObserver<ProgressAction, Mantid::API::Algorithm::ProgressNotification> observer(loadingProgressUpdate, &ProgressAction::handler); AnalysisDataService::Instance().remove("MD_EVENT_WS_ID"); Algorithm_sptr loadAlg = AlgorithmManager::Instance().createUnmanaged("LoadEventNexus"); loadAlg->initialize(); loadAlg->setChild(true); loadAlg->setPropertyValue("Filename", this->m_filename); loadAlg->setPropertyValue("OutputWorkspace", "temp_ws"); loadAlg->addObserver(observer); loadAlg->executeAsChildAlg(); loadAlg->removeObserver(observer); Workspace_sptr temp = loadAlg->getProperty("OutputWorkspace"); IEventWorkspace_sptr tempWS = boost::dynamic_pointer_cast<IEventWorkspace>(temp); Algorithm_sptr convertAlg = AlgorithmManager::Instance().createUnmanaged( "ConvertToDiffractionMDWorkspace", 1); convertAlg->initialize(); convertAlg->setChild(true); convertAlg->setProperty("InputWorkspace", tempWS); convertAlg->setProperty<bool>("ClearInputWorkspace", false); convertAlg->setProperty<bool>("LorentzCorrection", true); convertAlg->setPropertyValue("OutputWorkspace", "converted_ws"); convertAlg->addObserver(observer); convertAlg->executeAsChildAlg(); convertAlg->removeObserver(observer); IMDEventWorkspace_sptr outWS = convertAlg->getProperty("OutputWorkspace"); AnalysisDataService::Instance().addOrReplace("MD_EVENT_WS_ID", outWS); } Workspace_sptr result = AnalysisDataService::Instance().retrieve("MD_EVENT_WS_ID"); Mantid::API::IMDEventWorkspace_sptr eventWs = boost::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(result); m_wsTypeName = eventWs->id(); factory->setRecursionDepth(this->m_view->getRecursionDepth()); auto visualDataSet = factory->oneStepCreate( eventWs, drawingProgressUpdate); // HACK: progressUpdate should be // argument for drawing! this->extractMetadata(*eventWs); this->appendMetadata(visualDataSet, eventWs->getName()); return visualDataSet; }
/** * Set MDFrames for workspaces from legacy files * @param ws:: poitner to the workspace which needs to be corrected */ void LoadMD::setMDFrameOnWorkspaceFromLegacyFile(API::IMDWorkspace_sptr ws) { g_log.information() << "LoadMD: Encountered a legacy file which has a mismatch between " "its MDFrames and its Special Coordinate System. " "Attempting to convert MDFrames.\n"; auto numberOfDimensions = ws->getNumDims(); // Select an MDFrame based on the special coordinates. // Note that for None, we select a General Coordinate System, // unless the name is "Unknown frame" std::string selectedFrame; switch (m_coordSystem) { case Mantid::Kernel::QLab: selectedFrame = Mantid::Geometry::QLab::QLabName; break; case Mantid::Kernel::QSample: selectedFrame = Mantid::Geometry::QSample::QSampleName; break; case Mantid::Kernel::HKL: selectedFrame = Mantid::Geometry::HKL::HKLName; break; default: selectedFrame = Mantid::Geometry::GeneralFrame::GeneralFrameName; } // Get the old frames just in case something goes wrong. In this case we // reset the frames. std::vector<std::string> oldFrames( numberOfDimensions, Mantid::Geometry::GeneralFrame::GeneralFrameName); for (size_t index = 0; index < numberOfDimensions; ++index) { oldFrames[index] = ws->getDimension(index)->getMDFrame().name(); } // We want to set only up to the first three dimensions to the selected Frame; // Everything else will be set to a General Frame std::vector<std::string> framesToSet( numberOfDimensions, Mantid::Geometry::GeneralFrame::GeneralFrameName); auto fillUpTo = numberOfDimensions > 3 ? 3 : numberOfDimensions; std::fill_n(framesToSet.begin(), fillUpTo, selectedFrame); try { // Set the MDFrames for each axes Algorithm_sptr setMDFrameAlg = this->createChildAlgorithm("SetMDFrame"); int axesCounter = 0; for (auto &frame : framesToSet) { setMDFrameAlg->setProperty("InputWorkspace", ws); setMDFrameAlg->setProperty("MDFrame", frame); setMDFrameAlg->setProperty("Axes", std::vector<int>(1, axesCounter)); ++axesCounter; setMDFrameAlg->executeAsChildAlg(); } } catch (...) { g_log.warning() << "LoadMD: An issue occured while trying to correct " "MDFrames. Trying to revert to original.\n"; // Revert to the old frames. Algorithm_sptr setMDFrameAlg = this->createChildAlgorithm("SetMDFrame"); int axesCounter = 0; for (auto &oldFrame : oldFrames) { setMDFrameAlg->setProperty("InputWorkspace", ws); setMDFrameAlg->setProperty("MDFrame", oldFrame); setMDFrameAlg->setProperty("Axes", std::vector<int>(1, axesCounter)); ++axesCounter; setMDFrameAlg->executeAsChildAlg(); } } }
/** 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."; } }