void SANSSensitivityCorrection::exec() { // Output log m_output_message = ""; Progress progress(this, 0.0, 1.0, 10); // Reduction property manager const std::string reductionManagerName = getProperty("ReductionProperties"); boost::shared_ptr<PropertyManager> reductionManager; if (PropertyManagerDataService::Instance().doesExist(reductionManagerName)) { reductionManager = PropertyManagerDataService::Instance().retrieve(reductionManagerName); } else { reductionManager = boost::make_shared<PropertyManager>(); PropertyManagerDataService::Instance().addOrReplace(reductionManagerName, reductionManager); } if (!reductionManager->existsProperty("SensitivityAlgorithm")) { auto algProp = make_unique<AlgorithmProperty>("SensitivityAlgorithm"); algProp->setValue(toString()); reductionManager->declareProperty(std::move(algProp)); } progress.report("Loading sensitivity file"); const std::string fileName = getPropertyValue("Filename"); // Look for an entry for the dark current in the reduction table Poco::Path path(fileName); const std::string entryName = "Sensitivity" + path.getBaseName(); MatrixWorkspace_sptr floodWS; std::string floodWSName = "__sensitivity_" + path.getBaseName(); if (reductionManager->existsProperty(entryName)) { std::string wsName = reductionManager->getPropertyValue(entryName); floodWS = boost::dynamic_pointer_cast<MatrixWorkspace>( AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName)); m_output_message += " |Using " + wsName + "\n"; g_log.debug() << "SANSSensitivityCorrection :: Using sensitivity workspace: " << wsName << "\n"; } else { // Load the flood field if we don't have it already // First, try to determine whether we need to load data or a sensitivity // workspace... if (!floodWS && fileCheck(fileName)) { g_log.debug() << "SANSSensitivityCorrection :: Loading sensitivity file: " << fileName << "\n"; IAlgorithm_sptr loadAlg = createChildAlgorithm("Load", 0.1, 0.3); loadAlg->setProperty("Filename", fileName); loadAlg->executeAsChildAlg(); Workspace_sptr floodWS_ws = loadAlg->getProperty("OutputWorkspace"); floodWS = boost::dynamic_pointer_cast<MatrixWorkspace>(floodWS_ws); // Check that it's really a sensitivity file if (!floodWS->run().hasProperty("is_sensitivity")) { // Reset pointer floodWS.reset(); g_log.error() << "A processed Mantid workspace was loaded but it " "wasn't a sensitivity file!\n"; } } // ... if we don't, just load the data and process it if (!floodWS) { // Read in default beam center double center_x = getProperty("BeamCenterX"); double center_y = getProperty("BeamCenterY"); if (isEmpty(center_x) || isEmpty(center_y)) { if (reductionManager->existsProperty("LatestBeamCenterX") && reductionManager->existsProperty("LatestBeamCenterY")) { center_x = reductionManager->getProperty("LatestBeamCenterX"); center_y = reductionManager->getProperty("LatestBeamCenterY"); m_output_message += " |Setting beam center to [" + Poco::NumberFormatter::format(center_x, 1) + ", " + Poco::NumberFormatter::format(center_y, 1) + "]\n"; } else m_output_message += " |No beam center provided: skipping!\n"; } const std::string rawFloodWSName = "__flood_data_" + path.getBaseName(); MatrixWorkspace_sptr rawFloodWS; if (!reductionManager->existsProperty("LoadAlgorithm")) { IAlgorithm_sptr loadAlg = createChildAlgorithm("Load", 0.1, 0.3); loadAlg->setProperty("Filename", fileName); if (!isEmpty(center_x) && loadAlg->existsProperty("BeamCenterX")) loadAlg->setProperty("BeamCenterX", center_x); if (!isEmpty(center_y) && loadAlg->existsProperty("BeamCenterY")) loadAlg->setProperty("BeamCenterY", center_y); loadAlg->setPropertyValue("OutputWorkspace", rawFloodWSName); loadAlg->executeAsChildAlg(); Workspace_sptr tmpWS = loadAlg->getProperty("OutputWorkspace"); rawFloodWS = boost::dynamic_pointer_cast<MatrixWorkspace>(tmpWS); m_output_message += " | Loaded " + fileName + " (Load algorithm)\n"; } else { // Get load algorithm as a string so that we can create a completely // new proxy and ensure that we don't overwrite existing properties IAlgorithm_sptr loadAlg0 = reductionManager->getProperty("LoadAlgorithm"); const std::string loadString = loadAlg0->toString(); IAlgorithm_sptr loadAlg = Algorithm::fromString(loadString); loadAlg->setChild(true); loadAlg->setProperty("Filename", fileName); loadAlg->setPropertyValue("OutputWorkspace", rawFloodWSName); if (!isEmpty(center_x) && loadAlg->existsProperty("BeamCenterX")) loadAlg->setProperty("BeamCenterX", center_x); if (!isEmpty(center_y) && loadAlg->existsProperty("BeamCenterY")) loadAlg->setProperty("BeamCenterY", center_y); loadAlg->execute(); rawFloodWS = loadAlg->getProperty("OutputWorkspace"); m_output_message += " |Loaded " + fileName + "\n"; if (loadAlg->existsProperty("OutputMessage")) { std::string msg = loadAlg->getPropertyValue("OutputMessage"); m_output_message += " |" + Poco::replace(msg, "\n", "\n |") + "\n"; } } // Check whether we just loaded a flood field data set, or the actual // sensitivity if (!rawFloodWS->run().hasProperty("is_sensitivity")) { const std::string darkCurrentFile = getPropertyValue("DarkCurrentFile"); // Look for a dark current subtraction algorithm std::string dark_result; if (reductionManager->existsProperty("DarkCurrentAlgorithm")) { IAlgorithm_sptr darkAlg = reductionManager->getProperty("DarkCurrentAlgorithm"); darkAlg->setChild(true); darkAlg->setProperty("InputWorkspace", rawFloodWS); darkAlg->setProperty("OutputWorkspace", rawFloodWS); // Execute as-is if we use the sample dark current, otherwise check // whether a dark current file was provided. // Otherwise do nothing if (getProperty("UseSampleDC")) { darkAlg->execute(); if (darkAlg->existsProperty("OutputMessage")) dark_result = darkAlg->getPropertyValue("OutputMessage"); } else if (!darkCurrentFile.empty()) { darkAlg->setProperty("Filename", darkCurrentFile); darkAlg->setProperty("PersistentCorrection", false); darkAlg->execute(); if (darkAlg->existsProperty("OutputMessage")) dark_result = darkAlg->getPropertyValue("OutputMessage"); else dark_result = " Dark current subtracted\n"; } } else if (!darkCurrentFile.empty()) { // We need to subtract the dark current for the flood field but no // dark // current subtraction was set for the sample! Use the default dark // current algorithm if we can find it. if (reductionManager->existsProperty("DefaultDarkCurrentAlgorithm")) { IAlgorithm_sptr darkAlg = reductionManager->getProperty("DefaultDarkCurrentAlgorithm"); darkAlg->setChild(true); darkAlg->setProperty("InputWorkspace", rawFloodWS); darkAlg->setProperty("OutputWorkspace", rawFloodWS); darkAlg->setProperty("Filename", darkCurrentFile); darkAlg->setProperty("PersistentCorrection", false); darkAlg->execute(); if (darkAlg->existsProperty("OutputMessage")) dark_result = darkAlg->getPropertyValue("OutputMessage"); } else { // We are running out of options g_log.error() << "No dark current algorithm provided to load [" << getPropertyValue("DarkCurrentFile") << "]: skipped!\n"; dark_result = " No dark current algorithm provided: skipped\n"; } } m_output_message += " |" + Poco::replace(dark_result, "\n", "\n |") + "\n"; // Look for solid angle correction algorithm if (reductionManager->existsProperty("SANSSolidAngleCorrection")) { IAlgorithm_sptr solidAlg = reductionManager->getProperty("SANSSolidAngleCorrection"); solidAlg->setChild(true); solidAlg->setProperty("InputWorkspace", rawFloodWS); solidAlg->setProperty("OutputWorkspace", rawFloodWS); solidAlg->execute(); std::string msg = "Solid angle correction applied\n"; if (solidAlg->existsProperty("OutputMessage")) msg = solidAlg->getPropertyValue("OutputMessage"); m_output_message += " |" + Poco::replace(msg, "\n", "\n |") + "\n"; } // Apply transmission correction as needed double floodTransmissionValue = getProperty("FloodTransmissionValue"); double floodTransmissionError = getProperty("FloodTransmissionError"); if (!isEmpty(floodTransmissionValue)) { g_log.debug() << "SANSSensitivityCorrection :: Applying transmission " "to flood field\n"; IAlgorithm_sptr transAlg = createChildAlgorithm("ApplyTransmissionCorrection"); transAlg->setProperty("InputWorkspace", rawFloodWS); transAlg->setProperty("OutputWorkspace", rawFloodWS); transAlg->setProperty("TransmissionValue", floodTransmissionValue); transAlg->setProperty("TransmissionError", floodTransmissionError); transAlg->setProperty("ThetaDependent", true); transAlg->execute(); rawFloodWS = transAlg->getProperty("OutputWorkspace"); m_output_message += " |Applied transmission to flood field\n"; } // Calculate detector sensitivity IAlgorithm_sptr effAlg = createChildAlgorithm("CalculateEfficiency"); effAlg->setProperty("InputWorkspace", rawFloodWS); const double minEff = getProperty("MinEfficiency"); const double maxEff = getProperty("MaxEfficiency"); const std::string maskFullComponent = getPropertyValue("MaskedFullComponent"); const std::string maskEdges = getPropertyValue("MaskedEdges"); const std::string maskComponent = getPropertyValue("MaskedComponent"); effAlg->setProperty("MinEfficiency", minEff); effAlg->setProperty("MaxEfficiency", maxEff); effAlg->setProperty("MaskedFullComponent", maskFullComponent); effAlg->setProperty("MaskedEdges", maskEdges); effAlg->setProperty("MaskedComponent", maskComponent); effAlg->execute(); floodWS = effAlg->getProperty("OutputWorkspace"); } else { floodWS = rawFloodWS; } // Patch as needed if (reductionManager->existsProperty("SensitivityPatchAlgorithm")) { IAlgorithm_sptr patchAlg = reductionManager->getProperty("SensitivityPatchAlgorithm"); patchAlg->setChild(true); patchAlg->setProperty("Workspace", floodWS); patchAlg->execute(); m_output_message += " |Sensitivity patch applied\n"; } floodWS->mutableRun().addProperty("is_sensitivity", 1, "", true); } std::string floodWSOutputName = getPropertyValue("OutputSensitivityWorkspace"); if (floodWSOutputName.empty()) { setPropertyValue("OutputSensitivityWorkspace", floodWSName); AnalysisDataService::Instance().addOrReplace(floodWSName, floodWS); reductionManager->declareProperty( Kernel::make_unique<WorkspaceProperty<>>(entryName, floodWSName, Direction::InOut)); reductionManager->setPropertyValue(entryName, floodWSName); reductionManager->setProperty(entryName, floodWS); } setProperty("OutputSensitivityWorkspace", floodWS); } progress.report(3, "Loaded flood field"); // Check whether we need to apply the correction to a workspace MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); if (inputWS) { // Divide sample data by detector efficiency IAlgorithm_sptr divideAlg = createChildAlgorithm("Divide", 0.6, 0.7); divideAlg->setProperty("LHSWorkspace", inputWS); divideAlg->setProperty("RHSWorkspace", floodWS); divideAlg->executeAsChildAlg(); MatrixWorkspace_sptr outputWS = divideAlg->getProperty("OutputWorkspace"); // Copy over the efficiency's masked pixels to the reduced workspace IAlgorithm_sptr maskAlg = createChildAlgorithm("MaskDetectors", 0.75, 0.85); maskAlg->setProperty("Workspace", outputWS); maskAlg->setProperty("MaskedWorkspace", floodWS); maskAlg->executeAsChildAlg(); setProperty("OutputWorkspace", outputWS); } setProperty("OutputMessage", "Sensitivity correction computed\n" + m_output_message); progress.report("Performed sensitivity correction"); }
/** * Handles saving the reductions from the generic algorithm. */ void IndirectDiffractionReduction::saveReductions() { for (const auto wsName : m_plotWorkspaces) { const auto workspaceExists = AnalysisDataService::Instance().doesExist(wsName); if (workspaceExists) { QString tofWsName = QString::fromStdString(wsName) + "_tof"; std::string instName = (m_uiForm.iicInstrumentConfiguration->getInstrumentName()) .toStdString(); std::string mode = (m_uiForm.iicInstrumentConfiguration->getReflectionName()) .toStdString(); BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromConvUnitsProps; inputFromConvUnitsProps["InputWorkspace"] = tofWsName.toStdString(); BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromReductionProps; inputFromReductionProps["InputWorkspace"] = (wsName + "_dRange"); if (m_uiForm.ckGSS->isChecked()) { if (instName == "OSIRIS" && mode == "diffonly") { QString gssFilename = tofWsName + ".gss"; IAlgorithm_sptr saveGSS = AlgorithmManager::Instance().create("SaveGSS"); saveGSS->initialize(); saveGSS->setProperty("Filename", gssFilename.toStdString()); m_batchAlgoRunner->addAlgorithm(saveGSS, inputFromConvUnitsProps); } else { // Convert to TOF for GSS IAlgorithm_sptr convertUnits = AlgorithmManager::Instance().create("ConvertUnits"); convertUnits->initialize(); convertUnits->setProperty("InputWorkspace", wsName); convertUnits->setProperty("OutputWorkspace", tofWsName.toStdString()); convertUnits->setProperty("Target", "TOF"); m_batchAlgoRunner->addAlgorithm(convertUnits); // Save GSS std::string gssFilename = wsName + ".gss"; IAlgorithm_sptr saveGSS = AlgorithmManager::Instance().create("SaveGSS"); saveGSS->initialize(); saveGSS->setProperty("Filename", gssFilename); m_batchAlgoRunner->addAlgorithm(saveGSS, inputFromConvUnitsProps); } } if (m_uiForm.ckNexus->isChecked()) { // Save NEXus using SaveNexusProcessed std::string nexusFilename = wsName + ".nxs"; IAlgorithm_sptr saveNexus = AlgorithmManager::Instance().create("SaveNexusProcessed"); saveNexus->initialize(); saveNexus->setProperty("InputWorkspace", wsName); saveNexus->setProperty("Filename", nexusFilename); m_batchAlgoRunner->addAlgorithm(saveNexus); } if (m_uiForm.ckAscii->isChecked()) { // Save ASCII using SaveAscii version 1 std::string asciiFilename = wsName + ".dat"; IAlgorithm_sptr saveASCII = AlgorithmManager::Instance().create("SaveAscii", 1); saveASCII->initialize(); saveASCII->setProperty("InputWorkspace", wsName); saveASCII->setProperty("Filename", asciiFilename); m_batchAlgoRunner->addAlgorithm(saveASCII); } } else showInformationBox(QString::fromStdString( "Workspace '" + wsName + "' not found\nUnable to plot workspace")); } m_batchAlgoRunner->executeBatchAsync(); }
/** * Runs a diffraction reduction for OSIRIS operating in diffonly mode using the * OSIRISDiffractionReduction algorithm. */ void IndirectDiffractionReduction::runOSIRISdiffonlyReduction() { // Get the files names from MWRunFiles widget, and convert them from Qt forms // into stl equivalents. QStringList fileNames = m_uiForm.rfSampleFiles->getFilenames(); std::vector<std::string> stlFileNames; stlFileNames.reserve(fileNames.size()); std::transform(fileNames.begin(), fileNames.end(), std::back_inserter(stlFileNames), toStdString); // Use the file names to suggest a workspace name to use. Report to logger // and stop if unable to parse correctly. QString drangeWsName; QString tofWsName; try { QString nameBase = QString::fromStdString( Mantid::Kernel::MultiFileNameParsing::suggestWorkspaceName( stlFileNames)); tofWsName = nameBase + "_tof"; drangeWsName = nameBase + "_dRange"; } catch (std::runtime_error &re) { g_log.error(re.what()); return; } bool manualDRange(m_uiForm.ckManualDRange->isChecked()); IAlgorithm_sptr osirisDiffReduction = AlgorithmManager::Instance().create("OSIRISDiffractionReduction"); osirisDiffReduction->initialize(); osirisDiffReduction->setProperty( "Sample", m_uiForm.rfSampleFiles->getFilenames().join(",").toStdString()); osirisDiffReduction->setProperty( "Vanadium", m_uiForm.rfVanadiumFile->getFilenames().join(",").toStdString()); osirisDiffReduction->setProperty( "CalFile", m_uiForm.rfCalFile->getFirstFilename().toStdString()); osirisDiffReduction->setProperty("LoadLogFiles", m_uiForm.ckLoadLogs->isChecked()); osirisDiffReduction->setProperty("OutputWorkspace", drangeWsName.toStdString()); auto specMin = boost::lexical_cast<std::string, int>(m_uiForm.spSpecMin->value()); auto specMax = boost::lexical_cast<std::string, int>(m_uiForm.spSpecMax->value()); osirisDiffReduction->setProperty("SpectraMin", specMin); osirisDiffReduction->setProperty("SpectraMax", specMax); osirisDiffReduction->setProperty("DetectDRange", !manualDRange); if (manualDRange) osirisDiffReduction->setProperty( "DRange", static_cast<long>(m_uiForm.spDRange->value())); if (m_uiForm.ckUseCan->isChecked()) { osirisDiffReduction->setProperty( "Container", m_uiForm.rfCanFiles->getFilenames().join(",").toStdString()); if (m_uiForm.ckCanScale->isChecked()) osirisDiffReduction->setProperty("ContainerScaleFactor", m_uiForm.spCanScale->value()); } m_batchAlgoRunner->addAlgorithm(osirisDiffReduction); BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromReductionProps; inputFromReductionProps["InputWorkspace"] = drangeWsName.toStdString(); IAlgorithm_sptr convertUnits = AlgorithmManager::Instance().create("ConvertUnits"); convertUnits->initialize(); convertUnits->setProperty("OutputWorkspace", tofWsName.toStdString()); convertUnits->setProperty("Target", "TOF"); m_batchAlgoRunner->addAlgorithm(convertUnits, inputFromReductionProps); m_plotWorkspaces.clear(); m_plotWorkspaces.push_back(tofWsName.toStdString()); m_plotWorkspaces.push_back(drangeWsName.toStdString()); // Handles completion of the diffraction algorithm chain connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); m_batchAlgoRunner->executeBatchAsync(); }
/** Execute the algorithm. */ void CreateMDWorkspace::exec() { // Get the properties and validate them std::string eventType = getPropertyValue("EventType"); int ndims_prop = getProperty("Dimensions"); if (ndims_prop <= 0) throw std::invalid_argument( "You must specify a number of dimensions >= 1."); int mind = this->getProperty("MinRecursionDepth"); int maxd = this->getProperty("MaxRecursionDepth"); if (mind > maxd) throw std::invalid_argument( "MinRecursionDepth must be <= MaxRecursionDepth."); if (mind < 0 || maxd < 0) throw std::invalid_argument( "MinRecursionDepth and MaxRecursionDepth must be positive."); size_t ndims = static_cast<size_t>(ndims_prop); std::vector<double> extents = getProperty("Extents"); std::vector<std::string> names = getProperty("Names"); std::vector<std::string> units = getProperty("Units"); std::vector<std::string> frames = getProperty("Frames"); if (extents.size() != ndims * 2) throw std::invalid_argument("You must specify twice as many extents " "(min,max) as there are dimensions."); if (names.size() != ndims) throw std::invalid_argument( "You must specify as many names as there are dimensions."); if (units.size() != ndims) throw std::invalid_argument( "You must specify as many units as there are dimensions."); // If no frames are specified we want to default to the General Frame, // to ensure backward compatibility. But if they are only partly specified, // then we want to throw an error. It should be either used correctly or not // at all if (!frames.empty() && frames.size() != ndims) { throw std::invalid_argument( "You must specify as many frames as there are dimensions."); } if (frames.empty()) { frames.resize(ndims); std::fill(frames.begin(), frames.end(), GeneralFrame::GeneralFrameName); } // Have the factory create it IMDEventWorkspace_sptr out = MDEventFactory::CreateMDWorkspace(ndims, eventType); // Give all the dimensions for (size_t d = 0; d < ndims; d++) { auto frame = createMDFrame(frames[d], units[d]); MDHistoDimension *dim = new MDHistoDimension( names[d], names[d], *frame, static_cast<coord_t>(extents[d * 2]), static_cast<coord_t>(extents[d * 2 + 1]), 1); out->addDimension(MDHistoDimension_sptr(dim)); } // Initialize it using the dimension out->initialize(); // Call the templated function to finish ints CALL_MDEVENT_FUNCTION(this->finish, out); // --- File back end ? ---------------- std::string filename = getProperty("Filename"); if (!filename.empty()) { // First save to the NXS file g_log.notice() << "Running SaveMD" << std::endl; IAlgorithm_sptr alg = createChildAlgorithm("SaveMD"); alg->setPropertyValue("Filename", filename); alg->setProperty("InputWorkspace", boost::dynamic_pointer_cast<IMDWorkspace>(out)); alg->executeAsChildAlg(); // And now re-load it with this file as the backing. g_log.notice() << "Running LoadMD" << std::endl; alg = createChildAlgorithm("LoadMD"); alg->setPropertyValue("Filename", filename); alg->setProperty("FileBackEnd", true); alg->setPropertyValue("Memory", getPropertyValue("Memory")); alg->executeAsChildAlg(); // Replace the workspace with the loaded, file-backed one IMDWorkspace_sptr temp; temp = alg->getProperty("OutputWorkspace"); out = boost::dynamic_pointer_cast<IMDEventWorkspace>(temp); } // Save it on the output. setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(out)); }
/** Loads the instrument into a workspace. */ void VesuvioL1ThetaResolution::loadInstrument() { // Get the filename for the VESUVIO IDF MatrixWorkspace_sptr tempWS = WorkspaceFactory::Instance().create("Workspace2D", 1, 1, 1); const std::string vesuvioIPF = tempWS->getInstrumentFilename("VESUVIO"); // Load an empty VESUVIO instrument workspace IAlgorithm_sptr loadInst = AlgorithmManager::Instance().create("LoadEmptyInstrument"); loadInst->initialize(); loadInst->setChild(true); loadInst->setLogging(false); loadInst->setProperty("OutputWorkspace", "__evs"); loadInst->setProperty("Filename", vesuvioIPF); loadInst->execute(); m_instWorkspace = loadInst->getProperty("OutputWorkspace"); // Load the PAR file if provided const std::string parFilename = getPropertyValue("PARFile"); if (!parFilename.empty()) { g_log.information() << "Loading PAR file: " << parFilename << '\n'; // Get header format std::map<size_t, std::string> headerFormats; headerFormats[5] = "spectrum,theta,t0,-,R"; headerFormats[6] = "spectrum,-,theta,t0,-,R"; std::ifstream parFile(parFilename); if (!parFile) { throw std::runtime_error("Cannot open PAR file"); } std::string header; getline(parFile, header); g_log.debug() << "PAR file header: " << header << '\n'; boost::trim(header); std::vector<std::string> headers; boost::split(headers, header, boost::is_any_of("\t "), boost::token_compress_on); size_t numCols = headers.size(); g_log.debug() << "PAR file columns: " << numCols << '\n'; std::string headerFormat = headerFormats[numCols]; if (headerFormat.empty()) { std::stringstream error; error << "Unrecognised PAR file header. Number of colums: " << numCols << " (expected either 5 or 6."; throw std::runtime_error(error.str()); } g_log.debug() << "PAR file header format: " << headerFormat << '\n'; // Update instrument IAlgorithm_sptr updateInst = AlgorithmManager::Instance().create("UpdateInstrumentFromFile"); updateInst->initialize(); updateInst->setChild(true); updateInst->setLogging(false); updateInst->setProperty("Workspace", m_instWorkspace); updateInst->setProperty("Filename", parFilename); updateInst->setProperty("MoveMonitors", false); updateInst->setProperty("IgnorePhi", true); updateInst->setProperty("AsciiHeader", headerFormat); updateInst->execute(); m_instWorkspace = updateInst->getProperty("Workspace"); } const int specIdxMin = static_cast<int>( m_instWorkspace->getIndexFromSpectrumNumber(getProperty("SpectrumMin"))); const int specIdxMax = static_cast<int>( m_instWorkspace->getIndexFromSpectrumNumber(getProperty("SpectrumMax"))); // Crop the workspace to just the detectors we are interested in IAlgorithm_sptr crop = AlgorithmManager::Instance().create("CropWorkspace"); crop->initialize(); crop->setChild(true); crop->setLogging(false); crop->setProperty("InputWorkspace", m_instWorkspace); crop->setProperty("OutputWorkspace", "__evs"); crop->setProperty("StartWorkspaceIndex", specIdxMin); crop->setProperty("EndWorkspaceIndex", specIdxMax); crop->execute(); m_instWorkspace = crop->getProperty("OutputWorkspace"); m_sample = m_instWorkspace->getInstrument()->getSample(); }
/** * Integrate each spectra to get the number of counts * @param inputWS :: The workspace to integrate * @param indexMin :: The lower bound of the spectra to integrate * @param indexMax :: The upper bound of the spectra to integrate * @param lower :: The lower bound * @param upper :: The upper bound * @param outputWorkspace2D :: set to true to output a workspace 2D even if the * input is an EventWorkspace * @returns A workspace containing the integrated counts */ MatrixWorkspace_sptr DetectorDiagnostic::integrateSpectra( MatrixWorkspace_sptr inputWS, const int indexMin, const int indexMax, const double lower, const double upper, const bool outputWorkspace2D) { g_log.debug() << "Integrating input spectra.\n"; // If the input spectra only has one bin, assume it has been integrated // already // but we need to pass it to the algorithm so that a copy of the input // workspace is // actually created to use for further calculations // get percentage completed estimates for now, t0 and when we've finished t1 double t0 = m_fracDone, t1 = advanceProgress(RTGetTotalCounts); IAlgorithm_sptr childAlg = createChildAlgorithm("Integration", t0, t1); childAlg->setProperty("InputWorkspace", inputWS); childAlg->setProperty("StartWorkspaceIndex", indexMin); childAlg->setProperty("EndWorkspaceIndex", indexMax); // pass inputed values straight to this integration trusting the checking done // there childAlg->setProperty("RangeLower", lower); childAlg->setProperty("RangeUpper", upper); childAlg->setPropertyValue("IncludePartialBins", "1"); childAlg->executeAsChildAlg(); // Convert to 2D if desired, and if the input was an EventWorkspace. MatrixWorkspace_sptr outputW = childAlg->getProperty("OutputWorkspace"); MatrixWorkspace_sptr finalOutputW = outputW; if (outputWorkspace2D && boost::dynamic_pointer_cast<EventWorkspace>(outputW)) { g_log.debug() << "Converting output Event Workspace into a Workspace2D.\n"; childAlg = createChildAlgorithm("ConvertToMatrixWorkspace", t0, t1); childAlg->setProperty("InputWorkspace", outputW); childAlg->executeAsChildAlg(); finalOutputW = childAlg->getProperty("OutputWorkspace"); } return finalOutputW; }
/** * 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(); }
} IAlgorithm_sptr algo = createChildAlgorithm("CreateWorkspace", 0.7, 1.0); algo->setProperty< std::vector<double> >("DataX", std::vector<double>(2,0.0) ); algo->setProperty< std::vector<double> >("DataY", y_values ); algo->setProperty< std::vector<double> >("DataE", e_values ); algo->setProperty<int>("NSpec", numSpec ); algo->execute(); inputWS = algo->getProperty("OutputWorkspace"); WorkspaceFactory::Instance().initializeFromParent(inputWSWvl, inputWS, false); } else { // Sum up all the wavelength bins IAlgorithm_sptr childAlg = createChildAlgorithm("Integration"); childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWSWvl); childAlg->executeAsChildAlg(); inputWS = childAlg->getProperty("OutputWorkspace"); } // Define box around center of mass so that only pixels in an area // _centered_ on the latest center position are considered. At each // iteration we will recompute the bounding box, and we will make // it as large as possible. The largest box is defined as: double xmin0 = 0; double xmax0 = 0; double ymin0 = 0; double ymax0 = 0; // Starting values for the bounding box and the center
/** Calculate the integral asymmetry for a workspace. * The calculation is done by MuonAsymmetryCalc and SimpleIntegration algorithms. * @param ws :: The workspace * @param Y :: Reference to a variable receiving the value of asymmetry * @param E :: Reference to a variable receiving the value of the error */ void PlotAsymmetryByLogValue::calcIntAsymmetry(API::MatrixWorkspace_sptr ws, double& Y, double& E) { Property* startXprop = getProperty("TimeMin"); Property* endXprop = getProperty("TimeMax"); bool setX = !startXprop->isDefault() && !endXprop->isDefault(); double startX(0.0),endX(0.0); if (setX) { startX = getProperty("TimeMin"); endX = getProperty("TimeMax"); } if (!m_int) { // "Differential asymmetry" IAlgorithm_sptr asym = createSubAlgorithm("AsymmetryCalc"); asym->initialize(); asym->setProperty("InputWorkspace",ws); asym->setPropertyValue("OutputWorkspace","tmp"); if ( !m_autogroup ) { asym->setProperty("ForwardSpectra",m_forward_list); asym->setProperty("BackwardSpectra",m_backward_list); } asym->execute(); MatrixWorkspace_sptr asymWS = asym->getProperty("OutputWorkspace"); IAlgorithm_sptr integr = createSubAlgorithm("Integration"); integr->setProperty("InputWorkspace",asymWS); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); API::MatrixWorkspace_sptr out = integr->getProperty("OutputWorkspace"); Y = out->readY(0)[0]; E = out->readE(0)[0]; } else { // "Integral asymmetry" IAlgorithm_sptr integr = createSubAlgorithm("Integration"); integr->setProperty("InputWorkspace", ws); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); API::MatrixWorkspace_sptr intWS = integr->getProperty("OutputWorkspace"); IAlgorithm_sptr asym = createSubAlgorithm("AsymmetryCalc"); asym->initialize(); asym->setProperty("InputWorkspace",intWS); asym->setPropertyValue("OutputWorkspace","tmp"); if ( !m_autogroup ) { asym->setProperty("ForwardSpectra",m_forward_list); asym->setProperty("BackwardSpectra",m_backward_list); } asym->execute(); MatrixWorkspace_sptr out = asym->getProperty("OutputWorkspace"); Y = out->readY(0)[0]; E = out->readE(0)[0]; } }
void MonitorDlg::update() { if (!m_tree) { m_tree = new QTreeWidget(this); m_tree->setColumnCount(3); m_tree->setSelectionMode(QAbstractItemView::NoSelection); // Make the algorithm name column wider m_tree->setColumnWidth(0, 220); QStringList hList; hList << "Algorithm" << "Progress" << ""; m_tree->setHeaderLabels(hList); QHeaderView *hHeader = (QHeaderView *)m_tree->header(); hHeader->setResizeMode(1, QHeaderView::Stretch); hHeader->setResizeMode(2, QHeaderView::Fixed); hHeader->setStretchLastSection(false); } else m_tree->clear(); if (!isVisible()) return; m_algMonitor->lock(); QVector<Mantid::API::AlgorithmID>::const_iterator iend = m_algMonitor->algorithms().end(); for (QVector<Mantid::API::AlgorithmID>::const_iterator itr = m_algMonitor->algorithms().begin(); itr != iend; ++itr) { IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().getAlgorithm(*itr); // m_algorithms << alg; QStringList iList; iList << QString::fromStdString(alg->name()); QTreeWidgetItem *algItem = new QTreeWidgetItem(iList); m_tree->addTopLevelItem(algItem); QProgressBar *algProgress = new QProgressBar; algProgress->setAlignment(Qt::AlignHCenter); AlgButton *cancelButton = new AlgButton("Cancel", alg); m_tree->setItemWidget(algItem, 1, algProgress); m_tree->setItemWidget(algItem, 2, cancelButton); const std::vector<Mantid::Kernel::Property *> &prop_list = alg->getProperties(); for (std::vector<Mantid::Kernel::Property *>::const_iterator prop = prop_list.begin(); prop != prop_list.end(); ++prop) { QStringList lstr; Mantid::Kernel::MaskedProperty<std::string> *maskedProp = dynamic_cast<Mantid::Kernel::MaskedProperty<std::string> *>(*prop); if (maskedProp) { lstr << QString::fromStdString(maskedProp->name()) + ": " << QString::fromStdString(maskedProp->getMaskedValue()); } else { lstr << QString::fromStdString((**prop).name()) + ": " << QString::fromStdString((**prop).value()); } if ((**prop).isDefault()) lstr << " Default"; algItem->addChild(new QTreeWidgetItem(lstr)); } connect( cancelButton, SIGNAL(clicked(Mantid::API::AlgorithmID, QPushButton *)), m_algMonitor, SLOT(cancel(Mantid::API::AlgorithmID, QPushButton *))); } m_algMonitor->unlock(); }
/* Call Fit as child algorithm for each spectra * @param index : the workspace index */ void FindEPP::fitGaussian(int64_t index) { size_t spectrum = static_cast<size_t>(index); m_outWS->cell<int>(spectrum, 0) = static_cast<int>(spectrum); const auto &x = m_inWS->x(spectrum).rawData(); const auto &y = m_inWS->y(spectrum).rawData(); const auto &e = m_inWS->e(spectrum).rawData(); // Find the maximum value and it's index const auto maxIt = std::max_element(y.begin(), y.end()); const double height = *maxIt; size_t maxIndex = static_cast<size_t>(std::distance(y.begin(), maxIt)); if (height > 0) { // Find how many bins are around maximum, that are above half-maximum // Initialize the distances of the half-maxima bins from maximum size_t leftHalf = maxIndex, rightHalf = x.size() - maxIndex - 1; // Find the first bin on the right side of maximum, that drops below // half-maximum for (auto it = maxIt; it != y.end(); ++it) { if (*it < 0.5 * height) { rightHalf = it - maxIt - 1; break; } } // Find the first bin on the left side of maximum, that drops below // half-maximum for (auto it = maxIt; it != y.begin(); --it) { if (*it < 0.5 * height) { leftHalf = maxIt - it - 1; break; } } g_log.debug() << "Peak in spectrum #" << spectrum << " has last bins above 0.5*max at " << leftHalf << "\t" << rightHalf << "\n"; // We want to fit only if there are at least 3 bins (including the maximum // itself) above half-maximum if (rightHalf + leftHalf >= 2) { // Prepare the initial parameters for the fit double fwhm = x[maxIndex + rightHalf] - x[maxIndex - leftHalf]; double sigma = fwhm / (2. * sqrt(2. * log(2.))); double center = x[maxIndex]; double start = center - 3. * fwhm; double end = center + 3. * fwhm; std::stringstream function; function << "name=Gaussian,PeakCentre="; function << center << ",Height=" << height << ",Sigma=" << sigma; g_log.debug() << "Fitting spectrum #" << spectrum << " with: " << function.str() << "\n"; IAlgorithm_sptr fitAlg = createChildAlgorithm("Fit", 0., 0., false); fitAlg->setProperty("Function", function.str()); fitAlg->setProperty("InputWorkspace", m_inWS); fitAlg->setProperty("WorkspaceIndex", static_cast<int>(spectrum)); fitAlg->setProperty("StartX", start); fitAlg->setProperty("EndX", end); fitAlg->setProperty("CreateOutput", true); fitAlg->setProperty("OutputParametersOnly", true); fitAlg->executeAsChildAlg(); const std::string status = fitAlg->getProperty("OutputStatus"); ITableWorkspace_sptr fitResult = fitAlg->getProperty("OutputParameters"); if (status == "success") { m_outWS->cell<double>(spectrum, 1) = fitResult->cell<double>(1, 1); m_outWS->cell<double>(spectrum, 2) = fitResult->cell<double>(1, 2); m_outWS->cell<double>(spectrum, 3) = fitResult->cell<double>(2, 1); m_outWS->cell<double>(spectrum, 4) = fitResult->cell<double>(2, 2); m_outWS->cell<double>(spectrum, 5) = fitResult->cell<double>(0, 1); m_outWS->cell<double>(spectrum, 6) = fitResult->cell<double>(0, 2); m_outWS->cell<double>(spectrum, 7) = fitResult->cell<double>(3, 1); m_outWS->cell<std::string>(spectrum, 8) = status; } else { g_log.debug() << "Fit failed in spectrum #" << spectrum << ". \nReason :" << status << ". \nSetting the maximum.\n"; m_outWS->cell<std::string>(spectrum, 8) = "fitFailed"; m_outWS->cell<double>(spectrum, 1) = x[maxIndex]; m_outWS->cell<double>(spectrum, 2) = 0.; m_outWS->cell<double>(spectrum, 5) = height; m_outWS->cell<double>(spectrum, 6) = e[maxIndex]; } } else { g_log.information() << "Found <=3 bins above half maximum in spectrum #" << index << ". Not fitting.\n"; m_outWS->cell<std::string>(spectrum, 8) = "narrowPeak"; m_outWS->cell<double>(spectrum, 1) = x[maxIndex]; m_outWS->cell<double>(spectrum, 2) = 0.; m_outWS->cell<double>(spectrum, 5) = height; m_outWS->cell<double>(spectrum, 6) = e[maxIndex]; } } else { g_log.notice() << "Negative maximum in spectrum #" << spectrum << ". Skipping.\n"; m_outWS->cell<std::string>(spectrum, 8) = "negativeMaximum"; } m_progress->report(); }
void StepScan::generateCurve( const QString & var ) { // Create a matrix workspace out of the variable that's asked for IAlgorithm_sptr alg = AlgorithmManager::Instance().create("ConvertTableToMatrixWorkspace"); alg->setLogging(false); // Don't log this algorithm alg->setPropertyValue("InputWorkspace", m_tableWSName); m_plotWSName = "__plot_" + m_tableWSName; alg->setPropertyValue("OutputWorkspace", m_plotWSName); alg->setPropertyValue("ColumnX", var.toStdString() ); alg->setPropertyValue("ColumnY", "Counts" ); alg->execute(); // Now create one for the normalisation, if required if ( m_uiForm.normalization->currentIndex() != 0 ) { IAlgorithm_sptr norm = AlgorithmManager::Instance().create("ConvertTableToMatrixWorkspace"); norm->setChild(true); norm->setLogging(false); // Don't log this algorithm norm->setPropertyValue("InputWorkspace", m_tableWSName); norm->setPropertyValue("OutputWorkspace", "dummyName"); norm->setPropertyValue("ColumnX", var.toStdString() ); // TODO: Protect against column being missing (e.g. if monitor not found in data) norm->setPropertyValue("ColumnY", m_uiForm.normalization->currentText().toStdString() ); norm->execute(); MatrixWorkspace_sptr top = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(m_plotWSName); MatrixWorkspace_sptr bottom = norm->getProperty("OutputWorkspace"); top /= bottom; } plotCurve(); }
/** Execute the algorithm. */ void RemovePromptPulse::exec() { // verify there is a width parameter specified double width = this->getProperty("Width"); if (this->isEmpty(width)) { throw std::runtime_error("Failed to specify \'Width\' parameter"); } // need the input workspace in general API::MatrixWorkspace_const_sptr inputWS = this->getProperty("InputWorkspace"); // get the frequency double frequency = this->getProperty("Frequency"); if (this->isEmpty(frequency)) // it wasn't specified so try divination { frequency = this->getFrequency(inputWS->run()); if (this->isEmpty(frequency)) { throw std::runtime_error("Failed to determine the frequency"); } } g_log.information() << "Using frequency of " << frequency << "Hz\n"; double period = 1000000. / frequency; // period in microseconds // determine the overall tof window for the data double tmin; double tmax; getTofRange(inputWS, tmin, tmax); g_log.information() << "Data tmin=" << tmin << ", tmax=" << tmax << ", period=" << period << " microseconds\n"; // calculate the times for the prompt pulse std::vector<double> pulseTimes = this->calculatePulseTimes(tmin, tmax, period); if (pulseTimes.empty()) { g_log.notice() << "Not applying filter since prompt pulse is not in data " "range (period = " << period << ")\n"; setProperty("OutputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(inputWS)); return; } g_log.information() << "Calculated prompt pulses at "; for (double pulseTime : pulseTimes) g_log.information() << pulseTime << " "; g_log.information() << " microseconds\n"; MatrixWorkspace_sptr outputWS; for (double &pulseTime : pulseTimes) { double right = pulseTime + width; g_log.notice() << "Filtering tmin=" << pulseTime << ", tmax=" << right << " microseconds\n"; // run maskbins to do the work on the first prompt pulse IAlgorithm_sptr algo = this->createChildAlgorithm("MaskBins"); if (outputWS) { algo->setProperty<MatrixWorkspace_sptr>( "InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(outputWS)); } else { // should only be first time algo->setProperty<MatrixWorkspace_sptr>( "InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(inputWS)); outputWS = this->getProperty("OutputWorkspace"); } // always write to correct output workspace algo->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS); algo->setProperty<double>("XMin", pulseTime); algo->setProperty<double>("XMax", right); algo->executeAsChildAlg(); // copy over the output workspace outputWS = algo->getProperty("OutputWorkspace"); } setProperty("OutputWorkspace", outputWS); }
/** * Create histogram workspace * @returns Created workspace */ MatrixWorkspace_sptr LoadFITS::initAndPopulateHistogramWorkspace() { MantidVecPtr x; x.access().resize(m_allHeaderInfo.size() + 1); // Init time bins double binCount = 0; for(size_t i=0;i<m_allHeaderInfo.size() + 1; ++i) { x.access()[i] = binCount; if(i != m_allHeaderInfo.size()) binCount += m_allHeaderInfo[i].timeBin; } size_t spectraCount = 0; if(m_allHeaderInfo[0].numberOfAxis > 0) spectraCount += m_allHeaderInfo[0].axisPixelLengths[0]; // Presumably 2 axis, but futureproofing. for(int i=1;i<m_allHeaderInfo[0].numberOfAxis;++i) { spectraCount *= m_allHeaderInfo[0].axisPixelLengths[i]; } MatrixWorkspace_sptr retVal(new DataObjects::Workspace2D); retVal->initialize(spectraCount, m_allHeaderInfo.size()+1, m_allHeaderInfo.size()); IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument"); try { std::string directoryName = Kernel::ConfigService::Instance().getInstrumentDirectory(); directoryName = directoryName + "/IMAT_Definition.xml"; loadInst->setPropertyValue("Filename", directoryName); loadInst->setProperty<MatrixWorkspace_sptr>("Workspace", retVal); loadInst->execute(); } catch (std::exception & ex) { g_log.information("Cannot load the instrument definition. " + string(ex.what()) ); } int bitsPerPixel = m_allHeaderInfo[0].bitsPerPixel; // assumes all files have the same, which they should. vector<vector<double> > yVals(spectraCount, std::vector<double>(m_binChunkSize)); vector<vector<double> > eVals(spectraCount, std::vector<double>(m_binChunkSize)); // allocate memory to contain the data section of the file: void * bufferAny = NULL; bufferAny = malloc ((bitsPerPixel/8)*spectraCount); if (bufferAny == NULL) { throw std::runtime_error("FITS loader couldn't allocate enough memory to run. Try a smaller chunk size."); } size_t steps = static_cast<size_t>(ceil(m_allHeaderInfo.size()/m_binChunkSize)); Progress prog(this,0.0,1.0,steps); // Load a chunk of files at a time into workspace try { for(size_t i=0; i<m_allHeaderInfo.size(); i+=m_binChunkSize) { loadChunkOfBinsFromFile(retVal, yVals, eVals, bufferAny, x, spectraCount, bitsPerPixel, i); prog.report(name()); } } catch(...) { // Exceptions should be handled internally, but catch here to free any memory. Belt and braces. free(bufferAny); g_log.error("FITS Loader unable to correctly parse files."); throw std::runtime_error("FITS loader unable to correctly parse files."); } // Memory no longer needed free (bufferAny); retVal->mutableRun().addProperty("Filename", m_allHeaderInfo[0].filePath); // Set the Unit of the X Axis try { retVal->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); } catch ( Exception::NotFoundError & ) { retVal->getAxis(0)->unit() = UnitFactory::Instance().create("Label"); Unit_sptr unit = retVal->getAxis(0)->unit(); boost::shared_ptr<Units::Label> label = boost::dynamic_pointer_cast<Units::Label>(unit); label->setLabel("TOF", "TOF"); } retVal->setYUnit("Counts"); retVal->setTitle("Test Workspace"); return retVal; }
void EQSANSLoad::exec() { // Verify the validity of the inputs //TODO: this should be done by the new data management algorithm used for // live data reduction (when it's implemented...) const std::string fileName = getPropertyValue("Filename"); EventWorkspace_sptr inputEventWS = getProperty("InputWorkspace"); if (fileName.size()==0 && !inputEventWS) { g_log.error() << "EQSANSLoad input error: Either a valid file path or an input workspace must be provided" << std::endl; throw std::runtime_error("EQSANSLoad input error: Either a valid file path or an input workspace must be provided"); } else if (fileName.size()>0 && inputEventWS) { g_log.error() << "EQSANSLoad input error: Either a valid file path or an input workspace must be provided, but not both" << std::endl; throw std::runtime_error("EQSANSLoad input error: Either a valid file path or an input workspace must be provided, but not both"); } // Read in default TOF cuts const bool skipTOFCorrection = getProperty("SkipTOFCorrection"); m_low_TOF_cut = getProperty("LowTOFCut"); m_high_TOF_cut = getProperty("HighTOFCut"); // Read in default beam center m_center_x = getProperty("BeamCenterX"); m_center_y = getProperty("BeamCenterY"); const bool noBeamCenter = getProperty("NoBeamCenter"); // Reduction property manager const std::string reductionManagerName = getProperty("ReductionProperties"); boost::shared_ptr<PropertyManager> reductionManager; if (PropertyManagerDataService::Instance().doesExist(reductionManagerName)) { reductionManager = PropertyManagerDataService::Instance().retrieve(reductionManagerName); } else { reductionManager = boost::make_shared<PropertyManager>(); PropertyManagerDataService::Instance().addOrReplace(reductionManagerName, reductionManager); } if (!reductionManager->existsProperty("LoadAlgorithm")) { AlgorithmProperty *loadProp = new AlgorithmProperty("LoadAlgorithm"); setPropertyValue("InputWorkspace", ""); setProperty("NoBeamCenter", false); loadProp->setValue(toString()); reductionManager->declareProperty(loadProp); } if (!reductionManager->existsProperty("InstrumentName")) { reductionManager->declareProperty(new PropertyWithValue<std::string>("InstrumentName", "EQSANS") ); } // Output log m_output_message = ""; // Check whether we need to load the data if (!inputEventWS) { const bool loadMonitors = getProperty("LoadMonitors"); IAlgorithm_sptr loadAlg = createChildAlgorithm("LoadEventNexus", 0, 0.2); loadAlg->setProperty("LoadMonitors", loadMonitors); loadAlg->setProperty("MonitorsAsEvents", false); loadAlg->setProperty("Filename", fileName); if (skipTOFCorrection) { if (m_low_TOF_cut>0.0) loadAlg->setProperty("FilterByTofMin", m_low_TOF_cut); if (m_high_TOF_cut>0.0) loadAlg->setProperty("FilterByTofMax", m_high_TOF_cut); } loadAlg->execute(); IEventWorkspace_sptr dataWS_asWks = loadAlg->getProperty("OutputWorkspace"); dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS_asWks); // Get monitor workspace as necessary std::string mon_wsname = getPropertyValue("OutputWorkspace")+"_monitors"; if (loadMonitors && loadAlg->existsProperty("MonitorWorkspace")) { MatrixWorkspace_sptr monWS = loadAlg->getProperty("MonitorWorkspace"); declareProperty(new WorkspaceProperty<>("MonitorWorkspace", mon_wsname, Direction::Output), "Monitors from the Event NeXus file"); setProperty("MonitorWorkspace", monWS); } } else { MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); EventWorkspace_sptr outputEventWS = boost::dynamic_pointer_cast<EventWorkspace>(outputWS); if (inputEventWS != outputEventWS) { IAlgorithm_sptr copyAlg = createChildAlgorithm("CloneWorkspace", 0, 0.2); copyAlg->setProperty("InputWorkspace", inputEventWS); copyAlg->executeAsChildAlg(); Workspace_sptr dataWS_asWks = copyAlg->getProperty("OutputWorkspace"); dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS_asWks); } else { dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(inputEventWS); } } // Get the sample-detector distance double sdd = 0.0; const double sample_det_dist = getProperty("SampleDetectorDistance"); if (!isEmpty(sample_det_dist)) { sdd = sample_det_dist; } else { if (!dataWS->run().hasProperty("detectorZ")) { g_log.error() << "Could not determine Z position: the SampleDetectorDistance property was not set " "and the run logs do not contain the detectorZ property" << std::endl; throw std::invalid_argument("Could not determine Z position: stopping execution"); } Mantid::Kernel::Property* prop = dataWS->run().getProperty("detectorZ"); Mantid::Kernel::TimeSeriesProperty<double>* dp = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double>* >(prop); sdd = dp->getStatistics().mean; // Modify SDD according to offset if given const double sample_det_offset = getProperty("SampleDetectorDistanceOffset"); if (!isEmpty(sample_det_offset)) { sdd += sample_det_offset; } } dataWS->mutableRun().addProperty("sample_detector_distance", sdd, "mm", true); // Move the detector to its correct position IAlgorithm_sptr mvAlg = createChildAlgorithm("MoveInstrumentComponent", 0.2, 0.4); mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS); mvAlg->setProperty("ComponentName", "detector1"); mvAlg->setProperty("Z", sdd/1000.0); mvAlg->setProperty("RelativePosition", false); mvAlg->executeAsChildAlg(); g_log.information() << "Moving detector to " << sdd/1000.0 << " meters" << std::endl; m_output_message += " Detector position: " + Poco::NumberFormatter::format(sdd/1000.0, 3) + " m\n"; // Get the run number so we can find the proper config file int run_number = 0; std::string config_file = ""; if (dataWS->run().hasProperty("run_number")) { Mantid::Kernel::Property* prop = dataWS->run().getProperty("run_number"); Mantid::Kernel::PropertyWithValue<std::string>* dp = dynamic_cast<Mantid::Kernel::PropertyWithValue<std::string>* >(prop); const std::string run_str = *dp; Poco::NumberParser::tryParse(run_str, run_number); // Find a proper config file config_file = findConfigFile(run_number); } else { g_log.error() << "Could not find run number for workspace " << getPropertyValue("OutputWorkspace") << std::endl; m_output_message += " Could not find run number for data file\n"; } // Process the config file bool use_config = getProperty("UseConfig"); if (use_config && config_file.size()>0) { // Special case to force reading the beam center from the config file // We're adding this to be compatible with the original EQSANS load // written in python if (m_center_x==0.0 && m_center_y==0.0) { setProperty("UseConfigBeam", true); } readConfigFile(config_file); } else if (use_config) { use_config = false; g_log.error() << "Cound not find config file for workspace " << getPropertyValue("OutputWorkspace") << std::endl; m_output_message += " Could not find configuration file for run " + Poco::NumberFormatter::format(run_number) + "\n"; } // If we use the config file, move the moderator position if (use_config) { if (m_moderator_position > -13.0) g_log.error() << "Moderator position seems close to the sample, please check" << std::endl; g_log.information() << "Moving moderator to " << m_moderator_position << std::endl; m_output_message += " Moderator position: " + Poco::NumberFormatter::format(m_moderator_position, 3) + " m\n"; mvAlg = createChildAlgorithm("MoveInstrumentComponent", 0.4, 0.45); mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS); mvAlg->setProperty("ComponentName", "moderator"); mvAlg->setProperty("Z", m_moderator_position); mvAlg->setProperty("RelativePosition", false); mvAlg->executeAsChildAlg(); } // Get source aperture radius getSourceSlitSize(); // Move the beam center to its proper position if (!noBeamCenter) { if (isEmpty(m_center_x) || isEmpty(m_center_y)) { if (reductionManager->existsProperty("LatestBeamCenterX") && reductionManager->existsProperty("LatestBeamCenterY")) { m_center_x = reductionManager->getProperty("LatestBeamCenterX"); m_center_y = reductionManager->getProperty("LatestBeamCenterY"); } } moveToBeamCenter(); // Add beam center to reduction properties, as the last beam center position that was used. // This will give us our default position next time. if (!reductionManager->existsProperty("LatestBeamCenterX")) reductionManager->declareProperty(new PropertyWithValue<double>("LatestBeamCenterX", m_center_x) ); else reductionManager->setProperty("LatestBeamCenterX", m_center_x); if (!reductionManager->existsProperty("LatestBeamCenterY")) reductionManager->declareProperty(new PropertyWithValue<double>("LatestBeamCenterY", m_center_y) ); else reductionManager->setProperty("LatestBeamCenterY", m_center_y); } // Modify TOF const bool correct_for_flight_path = getProperty("CorrectForFlightPath"); double wl_min = 0.0; double wl_max = 0.0; double wl_combined_max = 0.0; if (skipTOFCorrection) { m_output_message += " Skipping EQSANS TOF correction: assuming a single frame\n"; dataWS->mutableRun().addProperty("is_frame_skipping", 0, true); if (correct_for_flight_path) { g_log.error() << "CorrectForFlightPath and SkipTOFCorrection can't be set to true at the same time" << std::endl; m_output_message += " Skipped flight path correction: see error log\n"; } } else { m_output_message += " Flight path correction "; if (!correct_for_flight_path) m_output_message += "NOT "; m_output_message += "applied\n"; DataObjects::EventWorkspace_sptr dataWS_evt = boost::dynamic_pointer_cast<EventWorkspace>(dataWS); IAlgorithm_sptr tofAlg = createChildAlgorithm("EQSANSTofStructure", 0.5, 0.7); tofAlg->setProperty<EventWorkspace_sptr>("InputWorkspace", dataWS_evt); tofAlg->setProperty("LowTOFCut", m_low_TOF_cut); tofAlg->setProperty("HighTOFCut", m_high_TOF_cut); tofAlg->setProperty("FlightPathCorrection", correct_for_flight_path); tofAlg->executeAsChildAlg(); wl_min = tofAlg->getProperty("WavelengthMin"); wl_max = tofAlg->getProperty("WavelengthMax"); if (wl_min != wl_min || wl_max != wl_max) { g_log.error() << "Bad wavelength range" << std::endl; g_log.error() << m_output_message << std::endl; } const bool frame_skipping = tofAlg->getProperty("FrameSkipping"); dataWS->mutableRun().addProperty("wavelength_min", wl_min, "Angstrom", true); dataWS->mutableRun().addProperty("wavelength_max", wl_max, "Angstrom", true); dataWS->mutableRun().addProperty("is_frame_skipping", int(frame_skipping), true); wl_combined_max = wl_max; m_output_message += " Wavelength range: " + Poco::NumberFormatter::format(wl_min, 1) + " - " + Poco::NumberFormatter::format(wl_max, 1); if (frame_skipping) { const double wl_min2 = tofAlg->getProperty("WavelengthMinFrame2"); const double wl_max2 = tofAlg->getProperty("WavelengthMaxFrame2"); wl_combined_max = wl_max2; dataWS->mutableRun().addProperty("wavelength_min_frame2", wl_min2, "Angstrom", true); dataWS->mutableRun().addProperty("wavelength_max_frame2", wl_max2, "Angstrom", true); m_output_message += " and " + Poco::NumberFormatter::format(wl_min2, 1) + " - " + Poco::NumberFormatter::format(wl_max2, 1) + " Angstrom\n"; } else m_output_message += " Angstrom\n"; } // Convert to wavelength const double ssd = fabs(dataWS->getInstrument()->getSource()->getPos().Z())*1000.0; const double conversion_factor = 3.9560346 / (sdd+ssd); m_output_message += " TOF to wavelength conversion factor: " + Poco::NumberFormatter::format(conversion_factor) + "\n"; if (skipTOFCorrection) { DataObjects::EventWorkspace_sptr dataWS_evt = boost::dynamic_pointer_cast<EventWorkspace>(dataWS); if (dataWS_evt->getNumberEvents()==0) throw std::invalid_argument("No event to process: check your TOF cuts"); wl_min = dataWS_evt->getTofMin()*conversion_factor; wl_max = dataWS_evt->getTofMax()*conversion_factor; wl_combined_max = wl_max; g_log.information() << "Wavelength range: " << wl_min << " to " << wl_max << std::endl; dataWS->mutableRun().addProperty("wavelength_min", wl_min, "Angstrom", true); dataWS->mutableRun().addProperty("wavelength_max", wl_max, "Angstrom", true); } IAlgorithm_sptr scAlg = createChildAlgorithm("ScaleX", 0.7, 0.71); scAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); scAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS); scAlg->setProperty("Factor", conversion_factor); scAlg->executeAsChildAlg(); dataWS->getAxis(0)->setUnit("Wavelength"); // Rebin so all the wavelength bins are aligned const bool preserveEvents = getProperty("PreserveEvents"); const double wl_step = getProperty("WavelengthStep"); std::string params = Poco::NumberFormatter::format(wl_min, 2) + "," + Poco::NumberFormatter::format(wl_step, 2) + "," + Poco::NumberFormatter::format(wl_combined_max, 2); IAlgorithm_sptr rebinAlg = createChildAlgorithm("Rebin", 0.71, 0.72); rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); if (preserveEvents) rebinAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS); rebinAlg->setPropertyValue("Params", params); rebinAlg->setProperty("PreserveEvents", preserveEvents); rebinAlg->executeAsChildAlg(); if (!preserveEvents) dataWS = rebinAlg->getProperty("OutputWorkspace"); dataWS->mutableRun().addProperty("event_ws", getPropertyValue("OutputWorkspace"), true); setProperty<MatrixWorkspace_sptr>("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS)); //m_output_message = "Loaded " + fileName + '\n' + m_output_message; setPropertyValue("OutputMessage", m_output_message); }
/** Calculate the integral asymmetry for a workspace (red & green). * The calculation is done by MuonAsymmetryCalc and SimpleIntegration algorithms. * @param ws_red :: The red workspace * @param ws_green :: The green workspace * @param Y :: Reference to a variable receiving the value of asymmetry * @param E :: Reference to a variable receiving the value of the error */ void PlotAsymmetryByLogValue::calcIntAsymmetry(API::MatrixWorkspace_sptr ws_red, API::MatrixWorkspace_sptr ws_green,double& Y, double& E) { if ( !m_autogroup ) { groupDetectors(ws_red,m_backward_list); groupDetectors(ws_red,m_forward_list); groupDetectors(ws_green,m_backward_list); groupDetectors(ws_green,m_forward_list); } Property* startXprop = getProperty("TimeMin"); Property* endXprop = getProperty("TimeMax"); bool setX = !startXprop->isDefault() && !endXprop->isDefault(); double startX(0.0),endX(0.0); if (setX) { startX = getProperty("TimeMin"); endX = getProperty("TimeMax"); } if (!m_int) { // "Differential asymmetry" API::MatrixWorkspace_sptr tmpWS = API::WorkspaceFactory::Instance().create( ws_red,1,ws_red->readX(0).size(),ws_red->readY(0).size()); for(size_t i=0;i<tmpWS->dataY(0).size();i++) { double FNORM = ws_green->readY(0)[i] + ws_red->readY(0)[i]; FNORM = FNORM != 0.0 ? 1.0 / FNORM : 1.0; double BNORM = ws_green->readY(1)[i] + ws_red->readY(1)[i]; BNORM = BNORM != 0.0 ? 1.0 / BNORM : 1.0; double ZF = ( ws_green->readY(0)[i] - ws_red->readY(0)[i] ) * FNORM; double ZB = ( ws_green->readY(1)[i] - ws_red->readY(1)[i] ) * BNORM; tmpWS->dataY(0)[i] = ZB - ZF; tmpWS->dataE(0)[i] = (1.0+ZF*ZF)*FNORM+(1.0+ZB*ZB)*BNORM; } IAlgorithm_sptr integr = createSubAlgorithm("Integration"); integr->setProperty("InputWorkspace",tmpWS); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); MatrixWorkspace_sptr out = integr->getProperty("OutputWorkspace"); Y = out->readY(0)[0] / static_cast<double>(tmpWS->dataY(0).size()); E = out->readE(0)[0] / static_cast<double>(tmpWS->dataY(0).size()); } else { // "Integral asymmetry" IAlgorithm_sptr integr = createSubAlgorithm("Integration"); integr->setProperty("InputWorkspace", ws_red); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); API::MatrixWorkspace_sptr intWS_red = integr->getProperty("OutputWorkspace"); integr = createSubAlgorithm("Integration"); integr->setProperty("InputWorkspace", ws_green); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); API::MatrixWorkspace_sptr intWS_green = integr->getProperty("OutputWorkspace"); double YIF = ( intWS_green->readY(0)[0] - intWS_red->readY(0)[0] ) / ( intWS_green->readY(0)[0] + intWS_red->readY(0)[0] ); double YIB = ( intWS_green->readY(1)[0] - intWS_red->readY(1)[0] ) / ( intWS_green->readY(1)[0] + intWS_red->readY(1)[0] ); Y = YIB - YIF; double VARIF = (1.0 + YIF*YIF) / ( intWS_green->readY(0)[0] + intWS_red->readY(0)[0] ); double VARIB = (1.0 + YIB*YIB) / ( intWS_green->readY(1)[0] + intWS_red->readY(1)[0] ); E = sqrt( VARIF + VARIB ); } }
/** * Function that encapulates the standard detector vanadium tests. * @param inputWS : the detector vanadium workspace to test * @param nFails : placeholder for the number of failures * @return : the resulting mask from the checks */ API::MatrixWorkspace_sptr DetectorDiagnostic::doDetVanTest(API::MatrixWorkspace_sptr inputWS, int &nFails) { MatrixWorkspace_sptr localMask; // FindDetectorsOutsideLimits // get the relevant inputs double lowThreshold = this->getProperty("LowThreshold"); double highThreshold = this->getProperty("HighThreshold"); // run the ChildAlgorithm IAlgorithm_sptr fdol = this->createChildAlgorithm( "FindDetectorsOutsideLimits", m_fracDone, m_fracDone + m_progStepWidth); m_fracDone += m_progStepWidth; fdol->setProperty("InputWorkspace", inputWS); fdol->setProperty("OutputWorkspace", localMask); fdol->setProperty("StartWorkspaceIndex", m_minIndex); fdol->setProperty("EndWorkspaceIndex", m_maxIndex); fdol->setProperty("RangeLower", m_rangeLower); fdol->setProperty("RangeUpper", m_rangeUpper); fdol->setProperty("LowThreshold", lowThreshold); fdol->setProperty("HighThreshold", highThreshold); fdol->executeAsChildAlg(); localMask = fdol->getProperty("OutputWorkspace"); int localFails = fdol->getProperty("NumberOfFailures"); nFails += localFails; // get the relevant inputs for the MedianDetectorTests int parents = this->getProperty("LevelsUp"); double significanceTest = this->getProperty("SignificanceTest"); double lowThresholdFrac = this->getProperty("LowThresholdFraction"); double highThresholdFrac = this->getProperty("HighThresholdFraction"); double lowOutlier = this->getProperty("LowOutlier"); double highOutlier = this->getProperty("HighOutlier"); bool excludeZeroes = this->getProperty("ExcludeZeroesFromMedian"); bool correctforSA = this->getProperty("CorrectForSolidAngle"); // MedianDetectorTest // apply mask to what we are going to input this->applyMask(inputWS, localMask); // run the ChildAlgorithm IAlgorithm_sptr mdt = this->createChildAlgorithm( "MedianDetectorTest", m_fracDone, m_fracDone + m_progStepWidth); m_fracDone += m_progStepWidth; mdt->setProperty("InputWorkspace", inputWS); mdt->setProperty("StartWorkspaceIndex", m_minIndex); mdt->setProperty("EndWorkspaceIndex", m_maxIndex); mdt->setProperty("RangeLower", m_rangeLower); mdt->setProperty("RangeUpper", m_rangeUpper); mdt->setProperty("LevelsUp", parents); mdt->setProperty("SignificanceTest", significanceTest); mdt->setProperty("LowThreshold", lowThresholdFrac); mdt->setProperty("HighThreshold", highThresholdFrac); mdt->setProperty("LowOutlier", lowOutlier); mdt->setProperty("HighOutlier", highOutlier); mdt->setProperty("ExcludeZeroesFromMedian", excludeZeroes); mdt->setProperty("CorrectForSolidAngle", correctforSA); mdt->executeAsChildAlg(); localMask = mdt->getProperty("OutputWorkspace"); localFails = mdt->getProperty("NumberOfFailures"); nFails += localFails; this->applyMask(inputWS, localMask); return localMask; }
/** * Executes the algorithm */ void PlotAsymmetryByLogValue::exec() { m_forward_list = getProperty("ForwardSpectra"); m_backward_list = getProperty("BackwardSpectra"); m_autogroup = ( m_forward_list.size() == 0 && m_backward_list.size() == 0); //double alpha = getProperty("Alpha"); std::string logName = getProperty("LogValue"); int red = getProperty("Red"); int green = getProperty("Green"); std::string stype = getProperty("Type"); m_int = stype == "Integral"; std::string firstFN = getProperty("FirstRun"); std::string lastFN = getProperty("LastRun"); std::string ext = firstFN.substr(firstFN.find_last_of(".")); firstFN.erase(firstFN.size()-4); lastFN.erase(lastFN.size()-4); std::string fnBase = firstFN; size_t i = fnBase.size()-1; while(isdigit(fnBase[i])) i--; if (i == fnBase.size()-1) { g_log.error("File name must end with a number."); throw Exception::FileError("File name must end with a number.",firstFN); } fnBase.erase(i+1); firstFN.erase(0,fnBase.size()); lastFN.erase(0,fnBase.size()); size_t is = atoi(firstFN.c_str()); // starting run number size_t ie = atoi(lastFN.c_str()); // last run number int w = static_cast<int>(firstFN.size()); // The number of runs size_t npoints = ie - is + 1; // Create the 2D workspace for the output int nplots = green != EMPTY_INT() ? 4 : 1; MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create("Workspace2D", nplots, // the number of plots npoints, // the number of data points on a plot npoints // it's not a histogram ); TextAxis* tAxis = new TextAxis(nplots); if (nplots == 1) { tAxis->setLabel(0,"Asymmetry"); } else { tAxis->setLabel(0,"Red-Green"); tAxis->setLabel(1,"Red"); tAxis->setLabel(2,"Green"); tAxis->setLabel(3,"Red+Green"); } outWS->replaceAxis(1,tAxis); Progress progress(this,0,1,ie-is+2); for(size_t i=is;i<=ie;i++) { std::ostringstream fn,fnn; fnn << std::setw(w) << std::setfill('0') << i ; fn << fnBase << fnn.str() << ext; // Load a muon nexus file with auto_group set to true IAlgorithm_sptr loadNexus = createSubAlgorithm("LoadMuonNexus"); loadNexus->setPropertyValue("Filename", fn.str()); loadNexus->setPropertyValue("OutputWorkspace","tmp"+fnn.str()); if (m_autogroup) loadNexus->setPropertyValue("AutoGroup","1"); loadNexus->execute(); std::string wsProp = "OutputWorkspace"; DataObjects::Workspace2D_sptr ws_red; DataObjects::Workspace2D_sptr ws_green; // Run through the periods of the loaded file and do calculations on the selected ones Workspace_sptr tmp = loadNexus->getProperty(wsProp); WorkspaceGroup_sptr wsGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(tmp); if (!wsGroup) { ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmp); TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName)); if (!logp) { throw std::invalid_argument("Log "+logName+" does not exist or not a double type"); } double Y,E; calcIntAsymmetry(ws_red,Y,E); outWS->dataY(0)[i-is] = Y; outWS->dataX(0)[i-is] = logp->lastValue(); outWS->dataE(0)[i-is] = E; } else { for( int period = 1; period <= wsGroup->getNumberOfEntries(); ++period ) { std::stringstream suffix; suffix << period; wsProp = "OutputWorkspace_" + suffix.str();// form the property name for higher periods // Do only one period if (green == EMPTY_INT() && period == red) { Workspace_sptr tmpff = loadNexus->getProperty(wsProp); ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmpff); TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName)); if (!logp) { throw std::invalid_argument("Log "+logName+" does not exist or not a double type"); } double Y,E; calcIntAsymmetry(ws_red,Y,E); outWS->dataY(0)[i-is] = Y; outWS->dataX(0)[i-is] = logp->lastValue(); outWS->dataE(0)[i-is] = E; } else // red & green { if (period == red) { Workspace_sptr temp = loadNexus->getProperty(wsProp); ws_red = boost::dynamic_pointer_cast<Workspace2D>(temp); } if (period == green) { Workspace_sptr temp = loadNexus->getProperty(wsProp); ws_green = boost::dynamic_pointer_cast<Workspace2D>(temp); } } } // red & green claculation if (green != EMPTY_INT()) { if (!ws_red || !ws_green) throw std::invalid_argument("Red or green period is out of range"); TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName)); if (!logp) { throw std::invalid_argument("Log "+logName+" does not exist or not a double type"); } double Y,E; double Y1,E1; calcIntAsymmetry(ws_red,Y,E); calcIntAsymmetry(ws_green,Y1,E1); outWS->dataY(1)[i-is] = Y; outWS->dataX(1)[i-is] = logp->lastValue(); outWS->dataE(1)[i-is] = E; outWS->dataY(2)[i-is] = Y1; outWS->dataX(2)[i-is] = logp->lastValue(); outWS->dataE(2)[i-is] = E1; outWS->dataY(3)[i-is] = Y + Y1; outWS->dataX(3)[i-is] = logp->lastValue(); outWS->dataE(3)[i-is] = sqrt(E*E+E1*E1); // move to last for safety since some grouping takes place in the // calcIntAsymmetry call below calcIntAsymmetry(ws_red,ws_green,Y,E); outWS->dataY(0)[i-is] = Y; outWS->dataX(0)[i-is] = logp->lastValue(); outWS->dataE(0)[i-is] = E; } else if (!ws_red) throw std::invalid_argument("Red period is out of range"); } progress.report(); } outWS->getAxis(0)->title() = logName; outWS->setYUnitLabel("Asymmetry"); // Assign the result to the output workspace property setProperty("OutputWorkspace", outWS); }
//---------------------------------------------------------------------------------------------- /// @copydoc Mantid::API::Algorithm::exec() void ResetNegatives::exec() { MatrixWorkspace_sptr inputWS = this->getProperty("InputWorkspace"); MatrixWorkspace_sptr outputWS = this->getProperty("OutputWorkspace"); // get the minimum for each spectrum IAlgorithm_sptr alg = this->createChildAlgorithm("Min", 0., .1); alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWS); alg->executeAsChildAlg(); MatrixWorkspace_const_sptr minWS = alg->getProperty("OutputWorkspace"); // determine if there is anything to do int64_t nHist = static_cast<int64_t>(minWS->getNumberHistograms()); bool hasNegative = false; for (int64_t i = 0; i < nHist; i++) { if (minWS->readY(i)[0] < 0) { hasNegative = true; } break; } // get out early if there is nothing to do if (!hasNegative) { g_log.information() << "No values are negative. Copying InputWorkspace to OutputWorkspace\n"; if (inputWS != outputWS) { IAlgorithm_sptr alg = this->createChildAlgorithm("CloneWorkspace", .1, 1.); alg->setProperty<Workspace_sptr>("InputWorkspace", inputWS); alg->executeAsChildAlg(); Workspace_sptr temp = alg->getProperty("OutputWorkspace"); setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(temp)); } return; } // sort the event list to make it fast and thread safe DataObjects::EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>( inputWS ); if (eventWS) eventWS->sortAll(DataObjects::TOF_SORT, NULL); Progress prog(this, .1, 1., 2*nHist); // generate output workspace - copy X and dY outputWS = API::WorkspaceFactory::Instance().create(inputWS); PARALLEL_FOR2(inputWS,outputWS) for (int64_t i = 0; i < nHist; i++) { PARALLEL_START_INTERUPT_REGION outputWS->dataY(i) = inputWS->readY(i); outputWS->dataE(i) = inputWS->readE(i); outputWS->setX(i, inputWS->refX(i)); // share the pointer more prog.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // do the actual work if (this->getProperty("AddMinimum")) { this->pushMinimum(minWS, outputWS, prog); } else { this->changeNegatives(minWS, this->getProperty("ResetValue"), outputWS, prog); } setProperty("OutputWorkspace",outputWS); }
void HFIRDarkCurrentSubtraction::exec() { std::string output_message = ""; // Reduction property manager const std::string reductionManagerName = getProperty("ReductionProperties"); boost::shared_ptr<PropertyManager> reductionManager; if (PropertyManagerDataService::Instance().doesExist(reductionManagerName)) { reductionManager = PropertyManagerDataService::Instance().retrieve(reductionManagerName); } else { reductionManager = boost::make_shared<PropertyManager>(); PropertyManagerDataService::Instance().addOrReplace(reductionManagerName, reductionManager); } // If the load algorithm isn't in the reduction properties, add it const bool persistent = getProperty("PersistentCorrection"); if (!reductionManager->existsProperty("DarkCurrentAlgorithm") && persistent) { AlgorithmProperty *algProp = new AlgorithmProperty("DarkCurrentAlgorithm"); algProp->setValue(toString()); reductionManager->declareProperty(algProp); } Progress progress(this,0.0,1.0,10); MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); const std::string fileName = getPropertyValue("Filename"); MatrixWorkspace_sptr darkWS; std::string darkWSName = getPropertyValue("OutputDarkCurrentWorkspace"); progress.report("Subtracting dark current"); // Look for an entry for the dark current in the reduction table Poco::Path path(fileName); const std::string entryName = "DarkCurrent"+path.getBaseName(); if (reductionManager->existsProperty(entryName)) { darkWS = reductionManager->getProperty(entryName); darkWSName = reductionManager->getPropertyValue(entryName); output_message += darkWSName + '\n'; } else { // Load the dark current if we don't have it already if (darkWSName.size()==0) { darkWSName = "__dark_current_"+path.getBaseName(); setPropertyValue("OutputDarkCurrentWorkspace", darkWSName); } IAlgorithm_sptr loadAlg; if (!reductionManager->existsProperty("LoadAlgorithm")) { loadAlg = createChildAlgorithm("HFIRLoad", 0.1, 0.3); loadAlg->setProperty("Filename", fileName); loadAlg->setProperty("ReductionProperties", reductionManagerName); loadAlg->executeAsChildAlg(); } else { IAlgorithm_sptr loadAlg0 = reductionManager->getProperty("LoadAlgorithm"); const std::string loadString = loadAlg0->toString(); loadAlg = Algorithm::fromString(loadString); loadAlg->setChild(true); loadAlg->setProperty("Filename", fileName); loadAlg->setProperty("ReductionProperties", reductionManagerName); loadAlg->setPropertyValue("OutputWorkspace", darkWSName); loadAlg->execute(); } darkWS = loadAlg->getProperty("OutputWorkspace"); output_message += "\n Loaded " + fileName + "\n"; if (loadAlg->existsProperty("OutputMessage")) { std::string msg = loadAlg->getPropertyValue("OutputMessage"); output_message += " |" + Poco::replace(msg, "\n", "\n |") + "\n"; } setProperty("OutputDarkCurrentWorkspace", darkWS); reductionManager->declareProperty(new WorkspaceProperty<>(entryName,"",Direction::Output)); reductionManager->setPropertyValue(entryName, darkWSName); reductionManager->setProperty(entryName, darkWS); } progress.report(3, "Loaded dark current"); // Perform subtraction double darkTimer = getCountingTime(darkWS); double dataTimer = getCountingTime(inputWS); IAlgorithm_sptr scaleAlg = createChildAlgorithm("Scale", 0.3, 0.5); scaleAlg->setProperty("InputWorkspace", darkWS); scaleAlg->setProperty("Factor", dataTimer/darkTimer); scaleAlg->setProperty("Operation", "Multiply"); scaleAlg->executeAsChildAlg(); MatrixWorkspace_sptr scaledDarkWS = scaleAlg->getProperty("OutputWorkspace"); // Zero out timer and monitor so that we don't subtract them out for(size_t i=0; i<scaledDarkWS->dataY(0).size(); i++) { scaledDarkWS->dataY(DEFAULT_TIMER_ID)[i]=0.0; scaledDarkWS->dataE(DEFAULT_TIMER_ID)[i]=0.0; scaledDarkWS->dataY(DEFAULT_MONITOR_ID)[i]=0.0; scaledDarkWS->dataE(DEFAULT_MONITOR_ID)[i]=0.0; } IAlgorithm_sptr minusAlg = createChildAlgorithm("Minus", 0.5, 0.7); minusAlg->setProperty("LHSWorkspace", inputWS); minusAlg->setProperty("RHSWorkspace", scaledDarkWS); MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); minusAlg->setProperty("OutputWorkspace", outputWS); minusAlg->executeAsChildAlg(); MatrixWorkspace_sptr correctedWS = minusAlg->getProperty("OutputWorkspace"); setProperty("OutputWorkspace", correctedWS); setProperty("OutputMessage", "Dark current subtracted: "+output_message); progress.report("Subtracted dark current"); }
/** Executes the algorithm * * @throw Exception::FileError If the grouping file cannot be opened or read successfully */ void GetDetOffsetsMultiPeaks::exec() { const double BAD_OFFSET(1000.); // mark things that didn't work with this MatrixWorkspace_sptr inputW=getProperty("InputWorkspace"); double maxOffset=getProperty("MaxOffset"); int nspec=static_cast<int>(inputW->getNumberHistograms()); // Create the output OffsetsWorkspace OffsetsWorkspace_sptr outputW(new OffsetsWorkspace(inputW->getInstrument())); // determine min/max d-spacing of the workspace double wkspDmin, wkspDmax; inputW->getXMinMax(wkspDmin, wkspDmax); // Create the output MaskWorkspace MatrixWorkspace_sptr maskWS(new MaskWorkspace(inputW->getInstrument())); //To get the workspace index from the detector ID detid2index_map * pixel_to_wi = maskWS->getDetectorIDToWorkspaceIndexMap(true); // the peak positions and where to fit std::vector<double> peakPositions = getProperty("DReference"); std::sort(peakPositions.begin(), peakPositions.end()); std::vector<double> fitWindows = generateWindows(wkspDmin, wkspDmax, peakPositions, this->getProperty("FitWindowMaxWidth")); g_log.information() << "windows : "; if (fitWindows.empty()) { g_log.information() << "empty\n"; } else { for (std::vector<double>::const_iterator it = fitWindows.begin(); it != fitWindows.end(); ++it) g_log.information() << *it << " "; g_log.information() << "\n"; } // some shortcuts for event workspaces EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>( inputW ); bool isEvent = false; if (eventW) isEvent = true; // cache the peak and background function names m_peakType = this->getPropertyValue("PeakFunction"); m_backType = this->getPropertyValue("BackgroundType"); // the maximum allowable chisq value for an individual peak fit m_maxChiSq = this->getProperty("MaxChiSq"); // Fit all the spectra with a gaussian Progress prog(this, 0, 1.0, nspec); // cppcheck-suppress syntaxError PRAGMA_OMP(parallel for schedule(dynamic, 1) ) for (int wi=0;wi<nspec;++wi) { PARALLEL_START_INTERUPT_REGION double offset = 0.0; double fitSum = 0.0; // checks for dead detectors if ((isEvent) && (eventW->getEventList(wi).empty())) { // dead detector will be masked offset = BAD_OFFSET; } else { const MantidVec& Y = inputW->readY(wi); const int YLength = static_cast<int>(Y.size()); double sumY = 0.0; for (int i = 0; i < YLength; i++) sumY += Y[i]; if (sumY < 1.e-30) { // Dead detector will be masked offset=BAD_OFFSET; } } if (offset < 10.) { // Fit the peak std::vector<double> peakPosToFit, peakPosFitted, chisq; size_t nparams; double minD, maxD; fitSpectra(wi, inputW, peakPositions, fitWindows, nparams, minD, maxD, peakPosToFit, peakPosFitted, chisq); if (nparams > 0) { //double * params = new double[2*nparams+1]; double params[153]; if(nparams > 50) nparams = 50; params[0] = static_cast<double>(nparams); params[1] = minD; params[2] = maxD; for (size_t i = 0; i < nparams; i++) { params[i+3] = peakPosToFit[i]; } for (size_t i = 0; i < nparams; i++) { params[i+3+nparams] = peakPosFitted[i]; } for (size_t i = 0; i < nparams; i++) { params[i+3+2*nparams] = chisq[i]; } const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex; gsl_multimin_fminimizer *s = NULL; gsl_vector *ss, *x; gsl_multimin_function minex_func; // finally do the fitting size_t nopt = 1; size_t iter = 0; int status = 0; double size; /* Starting point */ x = gsl_vector_alloc (nopt); gsl_vector_set_all (x, 0.0); /* Set initial step sizes to 0.001 */ ss = gsl_vector_alloc (nopt); gsl_vector_set_all (ss, 0.001); /* Initialize method and iterate */ minex_func.n = nopt; minex_func.f = &gsl_costFunction; minex_func.params = ¶ms; s = gsl_multimin_fminimizer_alloc (T, nopt); gsl_multimin_fminimizer_set (s, &minex_func, x, ss); do { iter++; status = gsl_multimin_fminimizer_iterate(s); if (status) break; size = gsl_multimin_fminimizer_size (s); status = gsl_multimin_test_size (size, 1e-4); } while (status == GSL_CONTINUE && iter < 50); // Output summary to log file std::string reportOfDiffractionEventCalibrateDetectors = gsl_strerror(status); g_log.debug() << " Workspace Index = " << wi << " Method used = " << " Simplex" << " Iteration = " << iter << " Status = " << reportOfDiffractionEventCalibrateDetectors << " Minimize Sum = " << s->fval << " Offset = " << gsl_vector_get (s->x, 0) << " \n"; offset = gsl_vector_get (s->x, 0); fitSum = s->fval; gsl_vector_free(x); gsl_vector_free(ss); gsl_multimin_fminimizer_free (s); //delete [] params; } else { offset = BAD_OFFSET; } } double mask=0.0; if (std::abs(offset) > maxOffset) { offset = 0.0; mask = 1.0; } // Get the list of detectors in this pixel const std::set<detid_t> & dets = inputW->getSpectrum(wi)->getDetectorIDs(); // Most of the exec time is in FitSpectra, so this critical block should not be a problem. PARALLEL_CRITICAL(GetDetOffsetsMultiPeaks_setValue) { // Use the same offset for all detectors from this pixel std::set<detid_t>::iterator it; for (it = dets.begin(); it != dets.end(); ++it) { outputW->setValue(*it, offset, fitSum); if (mask == 1.) { // Being masked maskWS->maskWorkspaceIndex((*pixel_to_wi)[*it]); maskWS->dataY((*pixel_to_wi)[*it])[0] = mask; } else { // Using the detector maskWS->dataY((*pixel_to_wi)[*it])[0] = mask; } } } prog.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Return the output setProperty("OutputWorkspace",outputW); setProperty("MaskWorkspace",maskWS); // Also save to .cal file, if requested std::string filename=getProperty("GroupingFileName"); if (!filename.empty()) { progress(0.9, "Saving .cal file"); IAlgorithm_sptr childAlg = createChildAlgorithm("SaveCalFile"); childAlg->setProperty("OffsetsWorkspace", outputW); childAlg->setProperty("MaskWorkspace", maskWS); childAlg->setPropertyValue("Filename", filename); childAlg->executeAsChildAlg(); } }
void EQSANSLoad::exec() { // Read in default TOF cuts m_low_TOF_cut = getProperty("LowTOFCut"); m_high_TOF_cut = getProperty("HighTOFCut"); // Read in default beam center m_center_x = getProperty("BeamCenterX"); m_center_y = getProperty("BeamCenterY"); TableWorkspace_sptr reductionTable = getProperty("ReductionTableWorkspace"); ReductionTableHandler reductionHandler(reductionTable); if (!reductionTable) { const std::string reductionTableName = getPropertyValue("ReductionTableWorkspace"); if (reductionTableName.size()>0) setProperty("ReductionTableWorkspace", reductionHandler.getTable()); } if (reductionHandler.findStringEntry("LoadAlgorithm").size()==0) reductionHandler.addEntry("LoadAlgorithm", toString()); const std::string fileName = getPropertyValue("Filename"); // Output log m_output_message = ""; IAlgorithm_sptr loadAlg = createSubAlgorithm("LoadEventNexus", 0, 0.2); loadAlg->setProperty("Filename", fileName); loadAlg->executeAsSubAlg(); IEventWorkspace_sptr dataWS_tmp = loadAlg->getProperty("OutputWorkspace"); dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS_tmp); // Get the sample-detector distance double sdd = 0.0; const double sample_det_dist = getProperty("SampleDetectorDistance"); if (!isEmpty(sample_det_dist)) { sdd = sample_det_dist; } else { Mantid::Kernel::Property* prop = dataWS->run().getProperty("detectorZ"); Mantid::Kernel::TimeSeriesProperty<double>* dp = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double>* >(prop); sdd = dp->getStatistics().mean; // Modify SDD according to offset if given const double sample_det_offset = getProperty("SampleDetectorDistanceOffset"); if (!isEmpty(sample_det_offset)) { sdd += sample_det_offset; } } dataWS->mutableRun().addProperty("sample_detector_distance", sdd, "mm", true); // Move the detector to its correct position IAlgorithm_sptr mvAlg = createSubAlgorithm("MoveInstrumentComponent", 0.2, 0.4); mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS); mvAlg->setProperty("ComponentName", "detector1"); mvAlg->setProperty("Z", sdd/1000.0); mvAlg->setProperty("RelativePosition", false); mvAlg->executeAsSubAlg(); g_log.information() << "Moving detector to " << sdd/1000.0 << std::endl; m_output_message += " Detector position: " + Poco::NumberFormatter::format(sdd/1000.0, 3) + " m\n"; // Get the run number so we can find the proper config file int run_number = 0; std::string config_file = ""; if (dataWS->run().hasProperty("run_number")) { Mantid::Kernel::Property* prop = dataWS->run().getProperty("run_number"); Mantid::Kernel::PropertyWithValue<std::string>* dp = dynamic_cast<Mantid::Kernel::PropertyWithValue<std::string>* >(prop); const std::string run_str = *dp; Poco::NumberParser::tryParse(run_str, run_number); // Find a proper config file config_file = findConfigFile(run_number); } else { g_log.error() << "Could not find run number for workspace " << getPropertyValue("OutputWorkspace") << std::endl; m_output_message += " Could not find run number for data file\n"; } // Process the config file bool use_config = getProperty("UseConfig"); if (use_config && config_file.size()>0) { readConfigFile(config_file); } else if (use_config) { use_config = false; g_log.error() << "Cound not find config file for workspace " << getPropertyValue("OutputWorkspace") << std::endl; m_output_message += " Could not find configuration file for run " + Poco::NumberFormatter::format(run_number) + "\n"; } // If we use the config file, move the moderator position if (use_config) { if (m_moderator_position > -13.0) g_log.error() << "Moderator position seems close to the sample, please check" << std::endl; g_log.information() << "Moving moderator to " << m_moderator_position << std::endl; m_output_message += " Moderator position: " + Poco::NumberFormatter::format(m_moderator_position, 3) + " m\n"; mvAlg = createSubAlgorithm("MoveInstrumentComponent", 0.4, 0.45); mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS); mvAlg->setProperty("ComponentName", "moderator"); mvAlg->setProperty("Z", m_moderator_position); mvAlg->setProperty("RelativePosition", false); mvAlg->executeAsSubAlg(); } // Get source aperture radius getSourceSlitSize(); // Move the beam center to its proper position moveToBeamCenter(); // Modify TOF bool correct_for_flight_path = getProperty("CorrectForFlightPath"); m_output_message += " Flight path correction "; if (!correct_for_flight_path) m_output_message += "NOT "; m_output_message += "applied\n"; DataObjects::EventWorkspace_sptr dataWS_evt = boost::dynamic_pointer_cast<EventWorkspace>(dataWS_tmp); IAlgorithm_sptr tofAlg = createSubAlgorithm("EQSANSTofStructure", 0.5, 0.7); tofAlg->setProperty<EventWorkspace_sptr>("InputWorkspace", dataWS_evt); tofAlg->setProperty("LowTOFCut", m_low_TOF_cut); tofAlg->setProperty("HighTOFCut", m_high_TOF_cut); tofAlg->setProperty("FlightPathCorrection", correct_for_flight_path); tofAlg->executeAsSubAlg(); const double wl_min = tofAlg->getProperty("WavelengthMin"); const double wl_max = tofAlg->getProperty("WavelengthMax"); const bool frame_skipping = tofAlg->getProperty("FrameSkipping"); dataWS->mutableRun().addProperty("wavelength_min", wl_min, "Angstrom", true); dataWS->mutableRun().addProperty("wavelength_max", wl_max, "Angstrom", true); dataWS->mutableRun().addProperty("is_frame_skipping", int(frame_skipping), true); double wl_combined_max = wl_max; m_output_message += " Wavelength range: " + Poco::NumberFormatter::format(wl_min, 1) + " - " + Poco::NumberFormatter::format(wl_max, 1); if (frame_skipping) { const double wl_min2 = tofAlg->getProperty("WavelengthMinFrame2"); const double wl_max2 = tofAlg->getProperty("WavelengthMaxFrame2"); wl_combined_max = wl_max2; dataWS->mutableRun().addProperty("wavelength_min_frame2", wl_min2, "Angstrom", true); dataWS->mutableRun().addProperty("wavelength_max_frame2", wl_max2, "Angstrom", true); m_output_message += " and " + Poco::NumberFormatter::format(wl_min2, 1) + " - " + Poco::NumberFormatter::format(wl_max2, 1) + " Angstrom\n"; } else m_output_message += " Angstrom\n"; // Convert to wavelength const double ssd = fabs(dataWS->getInstrument()->getSource()->getPos().Z())*1000.0; const double conversion_factor = 3.9560346 / (sdd+ssd); m_output_message += " TOF to wavelength conversion factor: " + Poco::NumberFormatter::format(conversion_factor) + "\n"; IAlgorithm_sptr scAlg = createSubAlgorithm("ScaleX", 0.7, 0.71); scAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); scAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS); scAlg->setProperty("Factor", conversion_factor); scAlg->executeAsSubAlg(); dataWS->getAxis(0)->setUnit("Wavelength"); // Rebin so all the wavelength bins are aligned const bool preserveEvents = getProperty("PreserveEvents"); std::string params = Poco::NumberFormatter::format(wl_min, 2) + ",0.1," + Poco::NumberFormatter::format(wl_combined_max, 2); IAlgorithm_sptr rebinAlg = createSubAlgorithm("Rebin", 0.71, 0.72); rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); if (preserveEvents) rebinAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS); rebinAlg->setPropertyValue("Params", params); rebinAlg->setProperty("PreserveEvents", preserveEvents); rebinAlg->executeAsSubAlg(); if (!preserveEvents) dataWS = rebinAlg->getProperty("OutputWorkspace"); dataWS->mutableRun().addProperty("event_ws", getPropertyValue("OutputWorkspace"), true); setProperty<MatrixWorkspace_sptr>("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS)); setPropertyValue("OutputMessage", m_output_message); }
/** Executes the algorithm * @throw Exception::FileError If the calibration file cannot be opened and read successfully * @throw Exception::InstrumentDefinitionError If unable to obtain the source-sample distance */ void AlignDetectors::exec() { // Get the input workspace MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); // Read in the calibration data const std::string calFileName = getProperty("CalibrationFile"); OffsetsWorkspace_sptr offsetsWS = getProperty("OffsetsWorkspace"); progress(0.0,"Reading calibration file"); if (offsetsWS && !calFileName.empty()) throw std::invalid_argument("You must specify either CalibrationFile or OffsetsWorkspace but not both."); if (!offsetsWS && calFileName.empty()) throw std::invalid_argument("You must specify either CalibrationFile or OffsetsWorkspace."); if (!calFileName.empty()) { // Load the .cal file IAlgorithm_sptr alg = createChildAlgorithm("LoadCalFile"); alg->setPropertyValue("CalFilename", calFileName); alg->setProperty("InputWorkspace", inputWS); alg->setProperty<bool>("MakeGroupingWorkspace", false); alg->setProperty<bool>("MakeOffsetsWorkspace", true); alg->setProperty<bool>("MakeMaskWorkspace", false); alg->setPropertyValue("WorkspaceName", "temp"); alg->executeAsChildAlg(); offsetsWS = alg->getProperty("OutputOffsetsWorkspace"); } const int64_t numberOfSpectra = inputWS->getNumberHistograms(); // generate map of the tof->d conversion factors this->tofToDmap = calcTofToD_ConversionMap(inputWS, offsetsWS); //Check if its an event workspace EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); if (eventW != NULL) { this->execEvent(); return; } API::MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); // If input and output workspaces are not the same, create a new workspace for the output if (outputWS != inputWS ) { outputWS = WorkspaceFactory::Instance().create(inputWS); setProperty("OutputWorkspace",outputWS); } // Set the final unit that our output workspace will have outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("dSpacing"); // Initialise the progress reporting object Progress progress(this,0.0,1.0,numberOfSpectra); // Loop over the histograms (detector spectra) PARALLEL_FOR2(inputWS,outputWS) for (int64_t i = 0; i < int64_t(numberOfSpectra); ++i) { PARALLEL_START_INTERUPT_REGION try { // Get the input spectrum number at this workspace index const ISpectrum * inSpec = inputWS->getSpectrum(size_t(i)); const double factor = calcConversionFromMap(this->tofToDmap, inSpec->getDetectorIDs()); // Get references to the x data MantidVec& xOut = outputWS->dataX(i); // Make sure reference to input X vector is obtained after output one because in the case // where the input & output workspaces are the same, it might move if the vectors were shared. const MantidVec& xIn = inSpec->readX(); //std::transform( xIn.begin(), xIn.end(), xOut.begin(), std::bind2nd(std::multiplies<double>(), factor) ); // the above transform creates wrong output in parallel in debug in Visual Studio for(size_t k = 0; k < xOut.size(); ++k) { xOut[k] = xIn[k] * factor; } // Copy the Y&E data outputWS->dataY(i) = inSpec->readY(); outputWS->dataE(i) = inSpec->readE(); } catch (Exception::NotFoundError &) { // Zero the data in this case outputWS->dataX(i).assign(outputWS->readX(i).size(),0.0); outputWS->dataY(i).assign(outputWS->readY(i).size(),0.0); outputWS->dataE(i).assign(outputWS->readE(i).size(),0.0); } progress.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION }
void SavePAR::exec() { // Get the input workspace MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace"); // Get the sample position const Kernel::V3D samplePos = inputWorkspace->getInstrument()->getSample()->getPos(); // Retrieve the filename from the properties const std::string filename = getProperty("Filename"); // Get a pointer to the sample IComponent_const_sptr sample = inputWorkspace->getInstrument()->getSample(); std::ofstream outPAR_file(filename.c_str()); if (!outPAR_file) { g_log.error("Failed to open (PAR) file:" + filename); throw Kernel::Exception::FileError("Failed to open (PAR) file:", filename); } // execute the ChildAlgorithm to calculate the detector's parameters; IAlgorithm_sptr spCalcDetPar = this->createChildAlgorithm("FindDetectorsPar", 0, 1, true, 1); spCalcDetPar->initialize(); spCalcDetPar->setPropertyValue("InputWorkspace", inputWorkspace->getName()); // calculate linear rather then angular detector's sizes; spCalcDetPar->setPropertyValue("ReturnLinearRanges", "1"); // in test mode, request the ChildAlgortithm to create output workspace and add it to dataservice if(!det_par_ws_name.empty()){ spCalcDetPar->setPropertyValue("OutputParTable",det_par_ws_name); } // let's not do this for the time being /* std::string parFileName = this->getPropertyValue("ParFile"); if(!(parFileName.empty()||parFileName=="not_used.par")){ spCalcDetPar->setPropertyValue("ParFile",parFileName); }*/ spCalcDetPar->execute(); // FindDetectorsPar * pCalcDetPar = dynamic_cast<FindDetectorsPar *>(spCalcDetPar.get()); if(!pCalcDetPar){ // "can not get pointer to FindDetectorsPar algorithm" throw(std::bad_cast()); } const std::vector<double> & azimuthal = pCalcDetPar->getAzimuthal(); const std::vector<double> & polar = pCalcDetPar->getPolar(); const std::vector<double> & azimuthal_width = pCalcDetPar->getAzimWidth(); const std::vector<double> & polar_width = pCalcDetPar->getPolarWidth(); const std::vector<double> & secondary_flightpath= pCalcDetPar->getFlightPath(); const std::vector<size_t> & det_ID = pCalcDetPar->getDetID(); size_t nDetectors = pCalcDetPar->getNDetectors(); // Write the number of detectors to the file. outPAR_file <<" "<< nDetectors << std::endl; for (size_t i = 0; i < nDetectors; ++i) { // verify if no detector defined; volatile double NanID = azimuthal[i]; if(NanID !=azimuthal[i] )continue; // skip NaN -s // Now write all the detector info. outPAR_file << std::fixed << std::setprecision(3); outPAR_file.width(10); outPAR_file <<secondary_flightpath[i]; outPAR_file.width(10); outPAR_file<< polar[i]; outPAR_file.width(10); outPAR_file << (-azimuthal[i]); outPAR_file.width(10); outPAR_file << polar_width[i]; outPAR_file.width(10); outPAR_file << azimuthal_width[i]; outPAR_file.width(10); outPAR_file << det_ID[i] << std::endl; } // Close the file outPAR_file.close(); }
/** * Loads the .cal file if necessary. */ void AlignAndFocusPowder::loadCalFile(const std::string &calFileName) { // check if the workspaces exist with their canonical names so they are not // reloaded for chunks if ((!m_groupWS) && (!calFileName.empty())) { try { m_groupWS = AnalysisDataService::Instance().retrieveWS<GroupingWorkspace>( m_instName + "_group"); } catch (Exception::NotFoundError &) { ; // not noteworthy } } if ((!m_calibrationWS) && (!calFileName.empty())) { OffsetsWorkspace_sptr offsetsWS = getProperty("OffsetsWorkspace"); if (offsetsWS) { convertOffsetsToCal(offsetsWS); } else { try { m_calibrationWS = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>( m_instName + "_cal"); } catch (Exception::NotFoundError &) { ; // not noteworthy } if (!m_calibrationWS) { try { OffsetsWorkspace_sptr offsetsWS = AnalysisDataService::Instance().retrieveWS<OffsetsWorkspace>( m_instName + "_offsets"); convertOffsetsToCal(offsetsWS); } catch (Exception::NotFoundError &) { ; // not noteworthy } } } } if ((!m_maskWS) && (!calFileName.empty())) { try { m_maskWS = AnalysisDataService::Instance().retrieveWS<MaskWorkspace>( m_instName + "_mask"); } catch (Exception::NotFoundError &) { ; // not noteworthy } } // see if everything exists to exit early if (m_groupWS && m_calibrationWS && m_maskWS) return; // see if the calfile is specified if (calFileName.empty()) return; g_log.information() << "Loading Calibration file \"" << calFileName << "\"\n"; // bunch of booleans to keep track of things bool loadGrouping = !m_groupWS; bool loadCalibration = !m_calibrationWS; bool loadMask = !m_maskWS; IAlgorithm_sptr alg = createChildAlgorithm("LoadDiffCal"); alg->setProperty("InputWorkspace", m_inputW); alg->setPropertyValue("Filename", calFileName); alg->setProperty<bool>("MakeCalWorkspace", loadCalibration); alg->setProperty<bool>("MakeGroupingWorkspace", loadGrouping); alg->setProperty<bool>("MakeMaskWorkspace", loadMask); alg->setPropertyValue("WorkspaceName", m_instName); alg->executeAsChildAlg(); // replace workspaces as appropriate if (loadGrouping) { m_groupWS = alg->getProperty("OutputGroupingWorkspace"); const std::string name = m_instName + "_group"; AnalysisDataService::Instance().addOrReplace(name, m_groupWS); this->setPropertyValue("GroupingWorkspace", name); } if (loadCalibration) { m_calibrationWS = alg->getProperty("OutputCalWorkspace"); const std::string name = m_instName + "_cal"; AnalysisDataService::Instance().addOrReplace(name, m_calibrationWS); this->setPropertyValue("CalibrationWorkspace", name); } if (loadMask) { m_maskWS = alg->getProperty("OutputMaskWorkspace"); const std::string name = m_instName + "_mask"; AnalysisDataService::Instance().addOrReplace(name, m_maskWS); this->setPropertyValue("MaskWorkspace", name); } return; }
/** Execute the algorithm. */ void StartLiveData::exec() { // Validate the inputs bool FromNow = getProperty("FromNow"); bool FromStartOfRun = getProperty("FromStartOfRun"); bool FromTime = getProperty("FromTime"); int numChecked = 0; if (FromNow) numChecked++; if (FromStartOfRun) numChecked++; if (FromTime) numChecked++; if (numChecked != 1) throw std::runtime_error("Please check exactly one of FromNow, FromStartOfRun, FromTime."); // Adjust the StartTime if you are starting from run/now. if (FromNow) this->setPropertyValue("StartTime", DateAndTime::getCurrentTime().toISO8601String()); else if (FromStartOfRun) // TODO: implement throw Kernel::Exception::NotImplementedError("Cannot start from the run start yet."); // Get the listener (and start listening) as early as possible ILiveListener_sptr listener = this->getLiveListener(); // TODO: Wait a bit to make sure something gets accumulated? LoadLiveData loadAlg; loadAlg.initialize(); loadAlg.setChild(true); // Copy settings from THIS to LoadAlg loadAlg.copyPropertyValuesFrom(*this); // Force replacing the output workspace on the first run, to clear out old junk. loadAlg.setPropertyValue("AccumulationMethod", "Replace"); // Give the listener directly to LoadLiveData (don't re-create it) loadAlg.setLiveListener(listener); // Run the LoadLiveData for the first time. loadAlg.executeAsChildAlg(); // Copy the output workspace properties from LoadLiveData Workspace_sptr outWS = loadAlg.getProperty("OutputWorkspace"); this->setProperty("OutputWorkspace", outWS); Workspace_sptr accumWS = loadAlg.getProperty("AccumulationWorkspace"); this->setProperty("AccumulationWorkspace", accumWS); double UpdateEvery = this->getProperty("UpdateEvery"); if (UpdateEvery > 0) { // Create the MonitorLiveData but DO NOT make a AlgorithmProxy to it IAlgorithm_sptr algBase = AlgorithmManager::Instance().create("MonitorLiveData", -1, false); MonitorLiveData * monitorAlg = dynamic_cast<MonitorLiveData*>(algBase.get()); if (!monitorAlg) throw std::runtime_error("Error creating the MonitorLiveData algorithm"); // Copy settings from THIS to monitorAlg monitorAlg->initialize(); monitorAlg->copyPropertyValuesFrom(*this); monitorAlg->setProperty("UpdateEvery", UpdateEvery); // Give the listener directly to LoadLiveData (don't re-create it) monitorAlg->setLiveListener(listener); // Launch asyncronously monitorAlg->executeAsync(); } }
/** * Runs a diffraction reduction for any instrument in any mode. * * @param instName Name of the instrument * @param mode Mode instrument is operating in (diffspec/diffonly) */ void IndirectDiffractionReduction::runGenericReduction(QString instName, QString mode) { // Get rebin string QString rebinStart = m_uiForm.leRebinStart->text(); QString rebinWidth = m_uiForm.leRebinWidth->text(); QString rebinEnd = m_uiForm.leRebinEnd->text(); QString rebin = ""; if (!rebinStart.isEmpty() && !rebinWidth.isEmpty() && !rebinEnd.isEmpty()) rebin = rebinStart + "," + rebinWidth + "," + rebinEnd; // Get detector range std::vector<long> detRange; detRange.push_back(static_cast<long>(m_uiForm.spSpecMin->value())); detRange.push_back(static_cast<long>(m_uiForm.spSpecMax->value())); // Get generic reduction algorithm instance IAlgorithm_sptr msgDiffReduction = AlgorithmManager::Instance().create("ISISIndirectDiffractionReduction"); msgDiffReduction->initialize(); // Get save formats std::vector<std::string> saveFormats; if (m_uiForm.ckGSS->isChecked()) saveFormats.emplace_back("gss"); if (m_uiForm.ckNexus->isChecked()) saveFormats.emplace_back("nxs"); if (m_uiForm.ckAscii->isChecked()) saveFormats.emplace_back("ascii"); // Set algorithm properties msgDiffReduction->setProperty("Instrument", instName.toStdString()); msgDiffReduction->setProperty("Mode", mode.toStdString()); // Check if Cal file is used if (instName == "OSIRIS" && mode == "diffspec") { if (m_uiForm.ckUseCalib->isChecked()) { const auto calFile = m_uiForm.rfCalFile_only->getText().toStdString(); msgDiffReduction->setProperty("CalFile", calFile); } } msgDiffReduction->setProperty("SumFiles", m_uiForm.ckSumFiles->isChecked()); msgDiffReduction->setProperty("LoadLogFiles", m_uiForm.ckLoadLogs->isChecked()); msgDiffReduction->setProperty( "InputFiles", m_uiForm.rfSampleFiles->getFilenames().join(",").toStdString()); msgDiffReduction->setProperty("SpectraRange", detRange); msgDiffReduction->setProperty("RebinParam", rebin.toStdString()); msgDiffReduction->setProperty("OutputWorkspace", "IndirectDiffraction_Workspaces"); if (m_uiForm.ckUseCan->isChecked()) { msgDiffReduction->setProperty( "ContainerFiles", m_uiForm.rfCanFiles->getFilenames().join(",").toStdString()); if (m_uiForm.ckCanScale->isChecked()) msgDiffReduction->setProperty("ContainerScaleFactor", m_uiForm.spCanScale->value()); } // Add the pproperty for grouping policy if needed if (m_uiForm.ckIndividualGrouping->isChecked()) msgDiffReduction->setProperty("GroupingPolicy", "Individual"); m_batchAlgoRunner->addAlgorithm(msgDiffReduction); // Handles completion of the diffraction algorithm chain connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); m_batchAlgoRunner->executeBatchAsync(); }
/** Execute the algorithm. */ void DgsReduction::exec() { // Reduction property manager - don't call getProcessProperties as // it will reuse. This needs to create a fresh one every time const std::string reductionManagerName = this->getProperty("ReductionProperties"); if (reductionManagerName.empty()) { g_log.error() << "ERROR: Reduction Property Manager name is empty\n"; return; } this->reductionManager = boost::make_shared<PropertyManager>(); PropertyManagerDataService::Instance().addOrReplace(reductionManagerName, this->reductionManager); // Put all properties except input files/workspaces into property manager. const std::vector<Property *> props = this->getProperties(); for (auto prop : props) { if (!boost::contains(prop->name(), "Input")) { this->reductionManager->declareProperty( std::unique_ptr<Property>(prop->clone())); } } Progress progress(this, 0, 1, 7); progress.report(); // Determine the default facility const FacilityInfo defaultFacility = ConfigService::Instance().getFacility(); // Need to load data to get certain bits of information. Workspace_sptr sampleWS = this->loadInputData("Sample"); MatrixWorkspace_sptr WS = boost::dynamic_pointer_cast<MatrixWorkspace>(sampleWS); this->reductionManager->declareProperty( Kernel::make_unique<PropertyWithValue<std::string>>( "InstrumentName", WS->getInstrument()->getName())); // Check the facility for the loaded file and make sure it's the // same as the default. const InstrumentInfo info = ConfigService::Instance().getInstrument(WS->getInstrument()->getName()); if (defaultFacility.name() != info.facility().name()) { std::ostringstream mess; mess << "Default facility must be set to " << info.facility().name(); mess << " in order for reduction to work!"; throw std::runtime_error(mess.str()); } MatrixWorkspace_sptr sampleMonWS = this->getProperty("SampleInputMonitorWorkspace"); const bool showIntermedWS = this->getProperty("ShowIntermediateWorkspaces"); // Get output workspace pointer and name MatrixWorkspace_sptr outputWS = this->getProperty("OutputWorkspace"); std::string outputWsName = this->getPropertyValue("OutputWorkspace"); if (boost::ends_with(outputWsName, "_spe")) { boost::erase_all(outputWsName, "_spe"); } progress.report("Loading hard mask..."); // Load the hard mask if available MatrixWorkspace_sptr hardMaskWS = this->loadHardMask(); if (hardMaskWS && showIntermedWS) { std::string hardMaskName = outputWsName + "_hardmask"; this->declareProperty(Kernel::make_unique<WorkspaceProperty<>>( "ReductionHardMask", hardMaskName, Direction::Output)); this->setProperty("ReductionHardMask", hardMaskWS); } progress.report("Loading grouping file..."); // Load the grouping file if available MatrixWorkspace_sptr groupingWS = this->loadGroupingFile(""); if (groupingWS && showIntermedWS) { std::string groupName = outputWsName + "_grouping"; this->declareProperty(Kernel::make_unique<WorkspaceProperty<>>( "ReductionGrouping", groupName, Direction::Output)); this->setProperty("ReductionGrouping", groupingWS); } // This will be diagnostic mask if DgsDiagnose is run and hard mask if not. MatrixWorkspace_sptr maskWS; // Process the sample detector vanadium if present Workspace_sptr detVanWS = this->loadInputData("DetectorVanadium", false); MatrixWorkspace_sptr detVanMonWS = this->getProperty("DetectorVanadiumInputMonitorWorkspace"); bool isProcessedDetVan = this->getProperty("UseProcessedDetVan"); // Process a comparison detector vanadium if present Workspace_sptr detVan2WS = this->loadInputData("DetectorVanadium2", false); MatrixWorkspace_sptr detVan2MonWS = this->getProperty("DetectorVanadium2InputMonitorWorkspace"); IAlgorithm_sptr detVan; Workspace_sptr idetVanWS; if (detVanWS && !isProcessedDetVan) { std::string detVanMaskName = outputWsName + "_diagmask"; IAlgorithm_sptr diag = this->createChildAlgorithm("DgsDiagnose"); diag->setProperty("DetVanWorkspace", detVanWS); diag->setProperty("DetVanMonitorWorkspace", detVanMonWS); diag->setProperty("DetVanCompWorkspace", detVan2WS); diag->setProperty("DetVanCompMonitorWorkspace", detVan2MonWS); diag->setProperty("SampleWorkspace", sampleWS); diag->setProperty("SampleMonitorWorkspace", sampleMonWS); diag->setProperty("HardMaskWorkspace", hardMaskWS); diag->setProperty("ReductionProperties", getPropertyValue("ReductionProperties")); diag->executeAsChildAlg(); maskWS = diag->getProperty("OutputWorkspace"); if (showIntermedWS) { this->declareProperty(Kernel::make_unique<WorkspaceProperty<>>( "SampleDetVanDiagMask", detVanMaskName, Direction::Output)); this->setProperty("SampleDetVanDiagMask", maskWS); } detVan = this->createChildAlgorithm("DgsProcessDetectorVanadium"); detVan->setProperty("InputWorkspace", detVanWS); detVan->setProperty("InputMonitorWorkspace", detVanMonWS); detVan->setProperty("MaskWorkspace", maskWS); std::string idetVanName = outputWsName + "_idetvan"; detVan->setProperty("ReductionProperties", getPropertyValue("ReductionProperties")); detVan->executeAsChildAlg(); MatrixWorkspace_sptr oWS = detVan->getProperty("OutputWorkspace"); idetVanWS = boost::dynamic_pointer_cast<Workspace>(oWS); if (showIntermedWS) { this->declareProperty(Kernel::make_unique<WorkspaceProperty<>>( "IntegratedNormWorkspace", idetVanName, Direction::Output)); this->setProperty("IntegratedNormWorkspace", idetVanWS); } } else { idetVanWS = detVanWS; maskWS = boost::dynamic_pointer_cast<MatrixWorkspace>(idetVanWS); detVanWS.reset(); } progress.report("Converting to energy transfer..."); IAlgorithm_sptr etConv = this->createChildAlgorithm("DgsConvertToEnergyTransfer"); etConv->setProperty("InputWorkspace", sampleWS); etConv->setProperty("InputMonitorWorkspace", sampleMonWS); etConv->setProperty("IntegratedDetectorVanadium", idetVanWS); const double ei = this->getProperty("IncidentEnergyGuess"); etConv->setProperty("IncidentEnergyGuess", ei); if (!maskWS && hardMaskWS) { maskWS = hardMaskWS; } etConv->setProperty("MaskWorkspace", maskWS); if (groupingWS) { etConv->setProperty("GroupingWorkspace", groupingWS); } etConv->setProperty("ReductionProperties", getPropertyValue("ReductionProperties")); std::string tibWsName = this->getPropertyValue("OutputWorkspace") + "_tib"; etConv->executeAsChildAlg(); outputWS = etConv->getProperty("OutputWorkspace"); MatrixWorkspace_sptr tibWS = etConv->getProperty("OutputTibWorkspace"); if (tibWS && showIntermedWS) { this->declareProperty(Kernel::make_unique<WorkspaceProperty<>>( "SampleTibWorkspace", tibWsName, Direction::Output)); this->setProperty("SampleTibWorkspace", tibWS); } Workspace_sptr absSampleWS = this->loadInputData("AbsUnitsSample", false); progress.report("Absolute units reduction..."); // Perform absolute normalisation if necessary if (absSampleWS) { std::string absWsName = outputWsName + "_absunits"; // Collect the other workspaces first. MatrixWorkspace_sptr absSampleMonWS = this->getProperty("AbsUnitsSampleInputMonitorWorkspace"); Workspace_sptr absDetVanWS = this->loadInputData("AbsUnitsDetectorVanadium", false); MatrixWorkspace_sptr absDetVanMonWS = this->getProperty("AbsUnitsDetectorVanadiumInputMonitorWorkspace"); MatrixWorkspace_sptr absGroupingWS = this->loadGroupingFile("AbsUnits"); // Run the absolute normalisation reduction IAlgorithm_sptr absUnitsRed = this->createChildAlgorithm("DgsAbsoluteUnitsReduction"); absUnitsRed->setProperty("InputWorkspace", absSampleWS); absUnitsRed->setProperty("InputMonitorWorkspace", absSampleMonWS); absUnitsRed->setProperty("DetectorVanadiumWorkspace", absDetVanWS); absUnitsRed->setProperty("DetectorVanadiumMonitorWorkspace", absDetVanMonWS); absUnitsRed->setProperty("GroupingWorkspace", absGroupingWS); absUnitsRed->setProperty("MaskWorkspace", maskWS); absUnitsRed->setProperty("ReductionProperties", getPropertyValue("ReductionProperties")); absUnitsRed->executeAsChildAlg(); MatrixWorkspace_sptr absUnitsWS = absUnitsRed->getProperty("OutputWorkspace"); //!!! There is Property outputMaskWorkspace to get masks? It looks like one // is using wrong property for masks MatrixWorkspace_sptr absMaskWS = absUnitsRed->getProperty("OutputWorkspace"); IAlgorithm_sptr mask = this->createChildAlgorithm("MaskDetectors"); mask->setProperty("Workspace", outputWS); mask->setProperty("MaskedWorkspace", absMaskWS); mask->executeAsChildAlg(); outputWS = mask->getProperty("Workspace"); // Do absolute normalisation outputWS = divide(outputWS, absUnitsWS); if (showIntermedWS) { this->declareProperty(Kernel::make_unique<WorkspaceProperty<>>( "AbsUnitsWorkspace", absWsName, Direction::Output)); this->setProperty("AbsUnitsWorkspace", absUnitsWS); this->declareProperty(Kernel::make_unique<WorkspaceProperty<>>( "AbsUnitsDiagMask", outputWsName + "_absunits_diagmask", Direction::Output)); this->setProperty("AbsUnitsDiagMask", absMaskWS); } } progress.report(); // Convert from DeltaE to powder S(Q,W) const bool doPowderConvert = this->getProperty("DoPowderDataConversion"); if (doPowderConvert) { g_log.notice() << "Converting to powder S(Q,W)\n"; // Collect information std::string sqwWsName = outputWsName + "_pd_sqw"; std::vector<double> qBinning = this->getProperty("PowderMomTransferRange"); const double initialEnergy = boost::lexical_cast<double>(outputWS->run().getProperty("Ei")->value()); IAlgorithm_sptr sofqw = this->createChildAlgorithm("SofQW3"); sofqw->setProperty("InputWorkspace", outputWS); sofqw->setProperty("QAxisBinning", qBinning); sofqw->setProperty("EMode", "Direct"); sofqw->setProperty("EFixed", initialEnergy); sofqw->executeAsChildAlg(); MatrixWorkspace_sptr sqwWS = sofqw->getProperty("OutputWorkspace"); this->declareProperty(Kernel::make_unique<WorkspaceProperty<>>( "PowderSqwWorkspace", sqwWsName, Direction::Output)); this->setProperty("PowderSqwWorkspace", sqwWS); const bool saveProcNexus = this->getProperty("SavePowderNexusFile"); if (saveProcNexus) { std::string saveProcNexusFilename = this->getProperty("SavePowderNexusFilename"); if (saveProcNexusFilename.empty()) { saveProcNexusFilename = sqwWsName + ".nxs"; } IAlgorithm_sptr saveNxs = this->createChildAlgorithm("SaveNexus"); saveNxs->setProperty("InputWorkspace", sqwWS); saveNxs->setProperty("Filename", saveProcNexusFilename); saveNxs->executeAsChildAlg(); } } progress.report(); this->setProperty("OutputWorkspace", outputWS); }
/** * Loads an empty instrument and returns a pointer to the workspace. * * Optionally loads an IPF if a reflection was provided. * * @param instrumentName Name of an inelastic indiretc instrument (IRIS, OSIRIN, *TOSCA, VESUVIO) * @param reflection Reflection mode to load parameters for (diffspec or *diffonly) */ MatrixWorkspace_sptr IndirectDiffractionReduction::loadInstrument(std::string instrumentName, std::string reflection) { std::string idfPath = Mantid::Kernel::ConfigService::Instance().getString( "instrumentDefinition.directory"); std::string parameterFilename = idfPath + instrumentName + "_Definition.xml"; IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("LoadEmptyInstrument"); loadAlg->setChild(true); loadAlg->initialize(); loadAlg->setProperty("Filename", parameterFilename); loadAlg->setProperty("OutputWorkspace", "__InDiff_Inst"); loadAlg->execute(); MatrixWorkspace_sptr instWorkspace = loadAlg->getProperty("OutputWorkspace"); // Load parameter file if a reflection was given if (!reflection.empty()) { std::string ipfFilename = idfPath + instrumentName + "_diffraction_" + reflection + "_Parameters.xml"; IAlgorithm_sptr loadParamAlg = AlgorithmManager::Instance().create("LoadParameterFile"); loadParamAlg->setChild(true); loadParamAlg->initialize(); loadParamAlg->setProperty("Filename", ipfFilename); loadParamAlg->setProperty("Workspace", instWorkspace); loadParamAlg->execute(); } return instWorkspace; }
/** * Loads an empty instrument into a workspace and returns a pointer to it. * * If an analyser and reflection are supplied then the corresponding IPF is also *loaded. * The workspace is not stored in ADS. * * @param instrumentName Name of the instrument to load * @param analyser Analyser being used (optional) * @param reflection Relection being used (optional) * @returns Pointer to instrument workspace */ Mantid::API::MatrixWorkspace_sptr IndirectDataReduction::loadInstrumentIfNotExist(std::string instrumentName, std::string analyser, std::string reflection) { std::string idfDirectory = Mantid::Kernel::ConfigService::Instance().getString( "instrumentDefinition.directory"); try { std::string parameterFilename = idfDirectory + instrumentName + "_Definition.xml"; IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("LoadEmptyInstrument"); loadAlg->setChild(true); loadAlg->setLogging(false); loadAlg->initialize(); loadAlg->setProperty("Filename", parameterFilename); loadAlg->setProperty("OutputWorkspace", "__IDR_Inst"); loadAlg->execute(); MatrixWorkspace_sptr instWorkspace = loadAlg->getProperty("OutputWorkspace"); // Load the IPF if given an analyser and reflection if (!analyser.empty() && !reflection.empty()) { std::string ipfFilename = idfDirectory + instrumentName + "_" + analyser + "_" + reflection + "_Parameters.xml"; IAlgorithm_sptr loadParamAlg = AlgorithmManager::Instance().create("LoadParameterFile"); loadParamAlg->setChild(true); loadParamAlg->setLogging(false); loadParamAlg->initialize(); loadParamAlg->setProperty("Filename", ipfFilename); loadParamAlg->setProperty("Workspace", instWorkspace); loadParamAlg->execute(); } return instWorkspace; } catch (std::exception &ex) { g_log.warning() << "Failed to load instrument with error: " << ex.what() << ". The current facility may not be fully " "supported.\n"; return MatrixWorkspace_sptr(); } }