/** * Places the detector at the right sample_detector_distance */ void LoadSpice2D::moveDetector(double sample_detector_distance, double translation_distance) { // Some tests fail if the detector is moved here. // TODO: Move the detector here and not the SANSLoad UNUSED_ARG(translation_distance); // Move the detector to the right position API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent"); // Finding the name of the detector object. std::string detID = m_workspace->getInstrument()->getStringParameter("detector-name")[0]; g_log.information("Moving " + detID); try { mover->setProperty<API::MatrixWorkspace_sptr>("Workspace", m_workspace); mover->setProperty("ComponentName", detID); mover->setProperty("Z", sample_detector_distance / 1000.0); // mover->setProperty("X", -translation_distance); mover->execute(); } catch (std::invalid_argument &e) { g_log.error("Invalid argument to MoveInstrumentComponent Child Algorithm"); g_log.error(e.what()); } catch (std::runtime_error &e) { g_log.error( "Unable to successfully run MoveInstrumentComponent Child Algorithm"); g_log.error(e.what()); } }
/** * Execute the algorithm. */ void FitResolutionConvolvedModel::exec() { API::IAlgorithm_sptr fit = createFittingAlgorithm(); fit->setPropertyValue("Function", createFunctionString()); fit->setProperty("InputWorkspace", getPropertyValue(INPUT_WS_NAME)); fit->setProperty("DomainType", "Simple"); // Parallel not quite giving correct answers fit->setProperty("Minimizer", "Levenberg-MarquardtMD"); const int maxIter = niterations(); fit->setProperty("MaxIterations", maxIter); fit->setProperty("CreateOutput", true); fit->setPropertyValue("Output", getPropertyValue(SIMULATED_NAME)); try { fit->execute(); } catch (std::exception &exc) { throw std::runtime_error( std::string("FitResolutionConvolvedModel - Error running Fit: ") + exc.what()); } // Pass on the relevant properties IMDEventWorkspace_sptr simulatedData = fit->getProperty("OutputWorkspace"); this->setProperty(SIMULATED_NAME, simulatedData); if (this->existsProperty(OUTPUT_PARS)) { ITableWorkspace_sptr outputPars = fit->getProperty("OutputParameters"); setProperty(OUTPUT_PARS, outputPars); } if (this->existsProperty(OUTPUTCOV_MATRIX)) { ITableWorkspace_sptr covarianceMatrix = fit->getProperty("OutputNormalisedCovarianceMatrix"); setProperty(OUTPUTCOV_MATRIX, covarianceMatrix); } }
/** * Fit peak without background i.e, with background removed * inspired from FitPowderDiffPeaks.cpp * copied from PoldiPeakDetection2.cpp * @param workspaceindex :: indice of the row to use @param center :: gaussian parameter - center @param sigma :: gaussian parameter - width @param height :: gaussian parameter - height @param startX :: fit range - start X value @param endX :: fit range - end X value @returns A boolean status flag, true for fit success, false else */ bool ConvertEmptyToTof::doFitGaussianPeak(int workspaceindex, double ¢er, double &sigma, double &height, double startX, double endX) { g_log.debug("Calling doFitGaussianPeak..."); // 1. Estimate sigma = sigma * 0.5; // 2. Use factory to generate Gaussian auto temppeak = API::FunctionFactory::Instance().createFunction("Gaussian"); auto gaussianpeak = boost::dynamic_pointer_cast<API::IPeakFunction>(temppeak); gaussianpeak->setHeight(height); gaussianpeak->setCentre(center); gaussianpeak->setFwhm(sigma); // 3. Constraint double centerleftend = center - sigma * 0.5; double centerrightend = center + sigma * 0.5; std::ostringstream os; os << centerleftend << " < PeakCentre < " << centerrightend; auto *centerbound = API::ConstraintFactory::Instance().createInitialized( gaussianpeak.get(), os.str(), false); gaussianpeak->addConstraint(centerbound); g_log.debug("Calling createChildAlgorithm : Fit..."); // 4. Fit API::IAlgorithm_sptr fitalg = createChildAlgorithm("Fit", -1, -1, true); fitalg->initialize(); fitalg->setProperty( "Function", boost::dynamic_pointer_cast<API::IFunction>(gaussianpeak)); fitalg->setProperty("InputWorkspace", m_inputWS); fitalg->setProperty("WorkspaceIndex", workspaceindex); fitalg->setProperty("Minimizer", "Levenberg-MarquardtMD"); fitalg->setProperty("CostFunction", "Least squares"); fitalg->setProperty("MaxIterations", 1000); fitalg->setProperty("Output", "FitGaussianPeak"); fitalg->setProperty("StartX", startX); fitalg->setProperty("EndX", endX); // 5. Result bool successfulfit = fitalg->execute(); if (!fitalg->isExecuted() || !successfulfit) { // Early return due to bad fit g_log.warning() << "Fitting Gaussian peak for peak around " << gaussianpeak->centre() << '\n'; return false; } // 6. Get result center = gaussianpeak->centre(); height = gaussianpeak->height(); double fwhm = gaussianpeak->fwhm(); return fwhm > 0.0; }
/** Group detectors in the workspace. * @param ws :: A local workspace * @param spectraList :: A list of spectra to group. */ void PlotAsymmetryByLogValue::groupDetectors(API::MatrixWorkspace_sptr& ws,const std::vector<int>& spectraList) { API::IAlgorithm_sptr group = createChildAlgorithm("GroupDetectors"); group->setProperty("InputWorkspace",ws); group->setProperty("SpectraList",spectraList); group->setProperty("KeepUngroupedSpectra",true); group->execute(); ws = group->getProperty("OutputWorkspace"); }
/** Fit function * Minimizer: "Levenberg-MarquardtMD"/"Simplex" */ bool RefinePowderInstrumentParameters2::doFitFunction(IFunction_sptr function, Workspace2D_sptr dataws, int wsindex, string minimizer, int numiters, double& chi2, string& fitstatus) { // 0. Debug output stringstream outss; outss << "Fit function: " << m_positionFunc->asString() << endl << "Data To Fit: \n"; for (size_t i = 0; i < dataws->readX(0).size(); ++i) outss << dataws->readX(wsindex)[i] << "\t\t" << dataws->readY(wsindex)[i] << "\t\t" << dataws->readE(wsindex)[i] << "\n"; g_log.information() << outss.str(); // 1. Create and setup fit algorithm API::IAlgorithm_sptr fitalg = createChildAlgorithm("Fit", 0.0, 0.2, true); fitalg->initialize(); fitalg->setProperty("Function", function); fitalg->setProperty("InputWorkspace", dataws); fitalg->setProperty("WorkspaceIndex", wsindex); fitalg->setProperty("Minimizer", minimizer); fitalg->setProperty("CostFunction", "Least squares"); fitalg->setProperty("MaxIterations", numiters); fitalg->setProperty("CalcErrors", true); // 2. Fit bool successfulfit = fitalg->execute(); if (!fitalg->isExecuted() || ! successfulfit) { // Early return due to bad fit g_log.warning("Fitting to instrument geometry function failed. "); chi2 = DBL_MAX; fitstatus = "Minimizer throws exception."; return false; } // 3. Understand solution chi2 = fitalg->getProperty("OutputChi2overDoF"); string tempfitstatus = fitalg->getProperty("OutputStatus"); fitstatus = tempfitstatus; bool goodfit = fitstatus.compare("success") == 0; stringstream dbss; dbss << "Fit Result (GSL): Chi^2 = " << chi2 << "; Fit Status = " << fitstatus << ", Return Bool = " << goodfit << std::endl; vector<string> funcparnames = function->getParameterNames(); for (size_t i = 0; i < funcparnames.size(); ++i) dbss << funcparnames[i] << " = " << setw(20) << function->getParameter(funcparnames[i]) << " +/- " << function->getError(i) << "\n"; g_log.debug() << dbss.str(); return goodfit; }
void LoadNexusMonitors2::runLoadLogs(const std::string filename, API::MatrixWorkspace_sptr localWorkspace) { // do the actual work API::IAlgorithm_sptr loadLogs = createChildAlgorithm("LoadNexusLogs"); // Now execute the Child Algorithm. Catch and log any error, but don't stop. try { g_log.information() << "Loading logs from NeXus file..." << std::endl; loadLogs->setPropertyValue("Filename", filename); loadLogs->setProperty<API::MatrixWorkspace_sptr>("Workspace", localWorkspace); loadLogs->execute(); } catch (...) { g_log.error() << "Error while loading Logs from Nexus. Some sample logs " "may be missing." << std::endl; } }
/** Run the Child Algorithm LoadInstrument (as for LoadRaw) * @param inst_name :: The name written in the Nexus file * @param localWorkspace :: The workspace to insert the instrument into */ void LoadSpice2D::runLoadInstrument( const std::string &inst_name, DataObjects::Workspace2D_sptr localWorkspace) { API::IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument"); // Now execute the Child Algorithm. Catch and log any error, but don't stop. try { loadInst->setPropertyValue("InstrumentName", inst_name); loadInst->setProperty<API::MatrixWorkspace_sptr>("Workspace", localWorkspace); loadInst->setProperty("RewriteSpectraMap", Mantid::Kernel::OptionalBool(true)); loadInst->execute(); } catch (std::invalid_argument &) { g_log.information("Invalid argument to LoadInstrument Child Algorithm"); } catch (std::runtime_error &) { g_log.information( "Unable to successfully run LoadInstrument Child Algorithm"); } }
/** * Gaussian fit to determine peak position if no user position given. * * @return :: detector position of the peak: Gaussian fit and position * of the maximum (serves as start value for the optimization) */ double LoadILLReflectometry::reflectometryPeak() { if (!isDefault("BeamCentre")) { return getProperty("BeamCentre"); } size_t startIndex; size_t endIndex; std::tie(startIndex, endIndex) = fitIntegrationWSIndexRange(*m_localWorkspace); IAlgorithm_sptr integration = createChildAlgorithm("Integration"); integration->initialize(); integration->setProperty("InputWorkspace", m_localWorkspace); integration->setProperty("OutputWorkspace", "__unused_for_child"); integration->setProperty("StartWorkspaceIndex", static_cast<int>(startIndex)); integration->setProperty("EndWorkspaceIndex", static_cast<int>(endIndex)); integration->execute(); MatrixWorkspace_sptr integralWS = integration->getProperty("OutputWorkspace"); IAlgorithm_sptr transpose = createChildAlgorithm("Transpose"); transpose->initialize(); transpose->setProperty("InputWorkspace", integralWS); transpose->setProperty("OutputWorkspace", "__unused_for_child"); transpose->execute(); integralWS = transpose->getProperty("OutputWorkspace"); rebinIntegralWorkspace(*integralWS); // determine initial height: maximum value const auto maxValueIt = std::max_element(integralWS->y(0).cbegin(), integralWS->y(0).cend()); const double height = *maxValueIt; // determine initial centre: index of the maximum value const size_t maxIndex = std::distance(integralWS->y(0).cbegin(), maxValueIt); const double centreByMax = static_cast<double>(maxIndex); g_log.debug() << "Peak maximum position: " << centreByMax << '\n'; // determine sigma const auto &ys = integralWS->y(0); auto lessThanHalfMax = [height](const double x) { return x < 0.5 * height; }; using IterType = HistogramData::HistogramY::const_iterator; std::reverse_iterator<IterType> revMaxValueIt{maxValueIt}; auto revMinFwhmIt = std::find_if(revMaxValueIt, ys.crend(), lessThanHalfMax); auto maxFwhmIt = std::find_if(maxValueIt, ys.cend(), lessThanHalfMax); std::reverse_iterator<IterType> revMaxFwhmIt{maxFwhmIt}; if (revMinFwhmIt == ys.crend() || maxFwhmIt == ys.cend()) { g_log.warning() << "Couldn't determine fwhm of beam, using position of max " "value as beam center.\n"; return centreByMax; } const double fwhm = static_cast<double>(std::distance(revMaxFwhmIt, revMinFwhmIt) + 1); g_log.debug() << "Initial fwhm (full width at half maximum): " << fwhm << '\n'; // generate Gaussian auto func = API::FunctionFactory::Instance().createFunction("CompositeFunction"); auto sum = boost::dynamic_pointer_cast<API::CompositeFunction>(func); func = API::FunctionFactory::Instance().createFunction("Gaussian"); auto gaussian = boost::dynamic_pointer_cast<API::IPeakFunction>(func); gaussian->setHeight(height); gaussian->setCentre(centreByMax); gaussian->setFwhm(fwhm); sum->addFunction(gaussian); func = API::FunctionFactory::Instance().createFunction("LinearBackground"); func->setParameter("A0", 0.); func->setParameter("A1", 0.); sum->addFunction(func); // call Fit child algorithm API::IAlgorithm_sptr fit = createChildAlgorithm("Fit"); fit->initialize(); fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(sum)); fit->setProperty("InputWorkspace", integralWS); fit->setProperty("StartX", centreByMax - 3 * fwhm); fit->setProperty("EndX", centreByMax + 3 * fwhm); fit->execute(); const std::string fitStatus = fit->getProperty("OutputStatus"); if (fitStatus != "success") { g_log.warning("Fit not successful, using position of max value.\n"); return centreByMax; } const auto centre = gaussian->centre(); g_log.debug() << "Sigma: " << gaussian->fwhm() << '\n'; g_log.debug() << "Estimated peak position: " << centre << '\n'; return centre; }
/** * Executes the algorithm */ void PlotPeakByLogValue::exec() { // Create a list of the input workspace const std::vector<InputData> wsNames = makeNames(); std::string fun = getPropertyValue("Function"); //int wi = getProperty("WorkspaceIndex"); std::string logName = getProperty("LogValue"); bool sequential = getPropertyValue("FitType") == "Sequential"; bool isDataName = false; // if true first output column is of type string and is the data source name ITableWorkspace_sptr result = WorkspaceFactory::Instance().createTable("TableWorkspace"); if (logName == "SourceName") { result->addColumn("str","Source name"); isDataName = true; } else if (logName.empty()) { result->addColumn("double","axis-1"); } else { result->addColumn("double",logName); } // Create an instance of the fitting function to obtain the names of fitting parameters IFitFunction* ifun = FunctionFactory::Instance().createInitialized(fun); if (!ifun) { throw std::invalid_argument("Fitting function failed to initialize"); } for(size_t iPar=0;iPar<ifun->nParams();++iPar) { result->addColumn("double",ifun->parameterName(iPar)); result->addColumn("double",ifun->parameterName(iPar)+"_Err"); } result->addColumn("double","Chi_squared"); delete ifun; setProperty("OutputWorkspace",result); double dProg = 1./static_cast<double>(wsNames.size()); double Prog = 0.; for(int i=0;i<static_cast<int>(wsNames.size());++i) { InputData data = getWorkspace(wsNames[i]); if (!data.ws) { g_log.warning() << "Cannot access workspace " << wsNames[i].name << '\n'; continue; } if (data.i < 0 && data.indx.empty()) { g_log.warning() << "Zero spectra selected for fitting in workspace " << wsNames[i].name << '\n'; continue; } int j,jend; if (data.i >= 0) { j = data.i; jend = j + 1; } else {// no need to check data.indx.empty() j = data.indx.front(); jend = data.indx.back() + 1; } dProg /= abs(jend - j); for(;j < jend;++j) { // Find the log value: it is either a log-file value or simply the workspace number double logValue; if (logName.empty()) { API::Axis* axis = data.ws->getAxis(1); logValue = (*axis)(j); } else if (logName != "SourceName") { Kernel::Property* prop = data.ws->run().getLogData(logName); if (!prop) { throw std::invalid_argument("Log value "+logName+" does not exist"); } TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(prop); logValue = logp->lastValue(); } std::string resFun = fun; std::vector<double> errors; double chi2; try { // Fit the function API::IAlgorithm_sptr fit = createSubAlgorithm("Fit"); fit->initialize(); fit->setProperty("InputWorkspace",data.ws); //fit->setPropertyValue("InputWorkspace",data.ws->getName()); fit->setProperty("WorkspaceIndex",j); fit->setPropertyValue("Function",fun); fit->setPropertyValue("StartX",getPropertyValue("StartX")); fit->setPropertyValue("EndX",getPropertyValue("EndX")); fit->setPropertyValue("Minimizer",getPropertyValue("Minimizer")); fit->setPropertyValue("CostFunction",getPropertyValue("CostFunction")); fit->execute(); resFun = fit->getPropertyValue("Function"); errors = fit->getProperty("Errors"); chi2 = fit->getProperty("OutputChi2overDoF"); } catch(...) { g_log.error("Error in Fit subalgorithm"); throw; } if (sequential) { fun = resFun; } // Extract the fitted parameters and put them into the result table TableRow row = result->appendRow(); if (isDataName) { row << wsNames[i].name; } else { row << logValue; } ifun = FunctionFactory::Instance().createInitialized(resFun); for(size_t iPar=0;iPar<ifun->nParams();++iPar) { row << ifun->getParameter(iPar) << errors[iPar]; } row << chi2; delete ifun; Prog += dProg; progress(Prog); interruption_point(); } // for(;j < jend;++j) } }
/** Get a workspace identified by an InputData structure. * @param data :: InputData with name and either spec or i fields defined. * @return InputData structure with the ws field set if everything was OK. */ PlotPeakByLogValue::InputData PlotPeakByLogValue::getWorkspace(const InputData& data) { InputData out(data); if (API::AnalysisDataService::Instance().doesExist(data.name)) { DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( API::AnalysisDataService::Instance().retrieve(data.name)); if (ws) { out.ws = ws; } else { return data; } } else { std::ifstream fil(data.name.c_str()); if (!fil) { g_log.warning() << "File "<<data.name<<" does not exist\n"; return data; } fil.close(); std::string::size_type i = data.name.find_last_of('.'); if (i == std::string::npos) { g_log.warning() << "Cannot open file "<<data.name<<"\n"; return data; } std::string ext = data.name.substr(i); try { API::IAlgorithm_sptr load = createSubAlgorithm("Load"); load->initialize(); load->setPropertyValue("FileName",data.name); load->execute(); if (load->isExecuted()) { API::Workspace_sptr rws = load->getProperty("OutputWorkspace"); if (rws) { DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(rws); if (ws) { out.ws = ws; } else { API::WorkspaceGroup_sptr gws = boost::dynamic_pointer_cast<API::WorkspaceGroup>(rws); if (gws) { std::vector<std::string> wsNames = gws->getNames(); std::string propName = "OUTPUTWORKSPACE_" + boost::lexical_cast<std::string>(data.period); if (load->existsProperty(propName)) { Workspace_sptr rws1 = load->getProperty(propName); out.ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(rws1); } } } } } } catch(std::exception& e) { g_log.error(e.what()); return data; } } if (!out.ws) return data; API::Axis* axis = out.ws->getAxis(1); if (axis->isSpectra()) {// spectra axis if (out.spec < 0) { if (out.i >= 0) { out.spec = axis->spectraNo(out.i); } else {// i < 0 && spec < 0 => use start and end for(size_t i=0;i<axis->length();++i) { double s = double(axis->spectraNo(i)); if (s >= out.start && s <= out.end) { out.indx.push_back(static_cast<int>(i)); } } } } else { for(size_t i=0;i<axis->length();++i) { int j = axis->spectraNo(i); if (j == out.spec) { out.i = static_cast<int>(i); break; } } } if (out.i < 0 && out.indx.empty()) { return data; } } else {// numeric axis out.spec = -1; if (out.i >= 0) { out.indx.clear(); } else { if (out.i < -1) { out.start = (*axis)(0); out.end = (*axis)(axis->length()-1); } for(size_t i=0;i<axis->length();++i) { double s = (*axis)(i); if (s >= out.start && s <= out.end) { out.indx.push_back(static_cast<int>(i)); } } } } return out; }
/// Overwrites Algorithm exec method void LoadSpice2D::exec() { std::string fileName = getPropertyValue("Filename"); const double wavelength_input = getProperty("Wavelength"); const double wavelength_spread_input = getProperty("WavelengthSpread"); // Set up the DOM parser and parse xml file DOMParser pParser; Document* pDoc; try { pDoc = pParser.parse(fileName); } catch (...) { throw Kernel::Exception::FileError("Unable to parse File:", fileName); } // Get pointer to root element Element* pRootElem = pDoc->documentElement(); if (!pRootElem->hasChildNodes()) { throw Kernel::Exception::NotFoundError("No root element in Spice XML file", fileName); } // Read in start time const std::string start_time = pRootElem->getAttribute("start_time"); Element* sasEntryElem = pRootElem->getChildElement("Header"); throwException(sasEntryElem, "Header", fileName); // Read in scan title Element* element = sasEntryElem->getChildElement("Scan_Title"); throwException(element, "Scan_Title", fileName); std::string wsTitle = element->innerText(); // Read in instrument name element = sasEntryElem->getChildElement("Instrument"); throwException(element, "Instrument", fileName); std::string instrument = element->innerText(); // Read sample thickness double sample_thickness = 0; from_element<double>(sample_thickness, sasEntryElem, "Sample_Thickness", fileName); double source_apert = 0.0; from_element<double>(source_apert, sasEntryElem, "source_aperture_size", fileName); double sample_apert = 0.0; from_element<double>(sample_apert, sasEntryElem, "sample_aperture_size", fileName); double source_distance = 0.0; from_element<double>(source_distance, sasEntryElem, "source_distance", fileName); // Read in wavelength and wavelength spread double wavelength = 0; double dwavelength = 0; if ( isEmpty(wavelength_input) ) { from_element<double>(wavelength, sasEntryElem, "wavelength", fileName); from_element<double>(dwavelength, sasEntryElem, "wavelength_spread", fileName); } else { wavelength = wavelength_input; dwavelength = wavelength_spread_input; } // Read in positions sasEntryElem = pRootElem->getChildElement("Motor_Positions"); throwException(sasEntryElem, "Motor_Positions", fileName); // Read in the number of guides int nguides = 0; from_element<int>(nguides, sasEntryElem, "nguides", fileName); // Read in sample-detector distance in mm double distance = 0; from_element<double>(distance, sasEntryElem, "sample_det_dist", fileName); distance *= 1000.0; // Read in beam trap positions double highest_trap = 0; double trap_pos = 0; from_element<double>(trap_pos, sasEntryElem, "trap_y_25mm", fileName); double beam_trap_diam = 25.4; from_element<double>(highest_trap, sasEntryElem, "trap_y_101mm", fileName); if (trap_pos>highest_trap) { highest_trap = trap_pos; beam_trap_diam = 101.6; } from_element<double>(trap_pos, sasEntryElem, "trap_y_50mm", fileName); if (trap_pos>highest_trap) { highest_trap = trap_pos; beam_trap_diam = 50.8; } from_element<double>(trap_pos, sasEntryElem, "trap_y_76mm", fileName); if (trap_pos>highest_trap) { highest_trap = trap_pos; beam_trap_diam = 76.2; } // Read in counters sasEntryElem = pRootElem->getChildElement("Counters"); throwException(sasEntryElem, "Counters", fileName); double countingTime = 0; from_element<double>(countingTime, sasEntryElem, "time", fileName); double monitorCounts = 0; from_element<double>(monitorCounts, sasEntryElem, "monitor", fileName); // Read in the data image Element* sasDataElem = pRootElem->getChildElement("Data"); throwException(sasDataElem, "Data", fileName); // Read in the data buffer element = sasDataElem->getChildElement("Detector"); throwException(element, "Detector", fileName); std::string data_str = element->innerText(); // Read in the detector dimensions from the Detector tag int numberXPixels = 0; int numberYPixels = 0; std::string data_type = element->getAttribute("type"); boost::regex b_re_sig("INT\\d+\\[(\\d+),(\\d+)\\]"); if (boost::regex_match(data_type, b_re_sig)) { boost::match_results<std::string::const_iterator> match; boost::regex_search(data_type, match, b_re_sig); // match[0] is the full string Kernel::Strings::convert(match[1], numberXPixels); Kernel::Strings::convert(match[2], numberYPixels); } if (numberXPixels==0 || numberYPixels==0) g_log.notice() << "Could not read in the number of pixels!" << std::endl; // We no longer read from the meta data because that data is wrong //from_element<int>(numberXPixels, sasEntryElem, "Number_of_X_Pixels", fileName); //from_element<int>(numberYPixels, sasEntryElem, "Number_of_Y_Pixels", fileName); // Store sample-detector distance declareProperty("SampleDetectorDistance", distance, Kernel::Direction::Output); // Create the output workspace // Number of bins: we use a single dummy TOF bin int nBins = 1; // Number of detectors: should be pulled from the geometry description. Use detector pixels for now. // The number of spectram also includes the monitor and the timer. int numSpectra = numberXPixels*numberYPixels + LoadSpice2D::nMonitors; DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( API::WorkspaceFactory::Instance().create("Workspace2D", numSpectra, nBins+1, nBins)); ws->setTitle(wsTitle); ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("Wavelength"); ws->setYUnit(""); API::Workspace_sptr workspace = boost::static_pointer_cast<API::Workspace>(ws); setProperty("OutputWorkspace", workspace); // Parse out each pixel. Pixels can be separated by white space, a tab, or an end-of-line character Poco::StringTokenizer pixels(data_str, " \n\t", Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY); Poco::StringTokenizer::Iterator pixel = pixels.begin(); // Check that we don't keep within the size of the workspace size_t pixelcount = pixels.count(); if( pixelcount != static_cast<size_t>(numberXPixels*numberYPixels) ) { throw Kernel::Exception::FileError("Inconsistent data set: " "There were more data pixels found than declared in the Spice XML meta-data.", fileName); } if( numSpectra == 0 ) { throw Kernel::Exception::FileError("Empty data set: the data file has no pixel data.", fileName); } // Go through all detectors/channels int ipixel = 0; // Store monitor count store_value(ws, ipixel++, monitorCounts, monitorCounts>0 ? sqrt(monitorCounts) : 0.0, wavelength, dwavelength); // Store counting time store_value(ws, ipixel++, countingTime, 0.0, wavelength, dwavelength); // Store detector pixels while (pixel != pixels.end()) { //int ix = ipixel%npixelsx; //int iy = (int)ipixel/npixelsx; // Get the count value and assign it to the right bin double count = 0.0; from_string<double>(count, *pixel, std::dec); // Data uncertainties, computed according to the HFIR/IGOR reduction code // The following is what I would suggest instead... // error = count > 0 ? sqrt((double)count) : 0.0; double error = sqrt( 0.5 + fabs( count - 0.5 )); store_value(ws, ipixel, count, error, wavelength, dwavelength); // Set the spectrum number ws->getAxis(1)->setValue(ipixel, ipixel); ++pixel; ipixel++; } // run load instrument runLoadInstrument(instrument, ws); runLoadMappingTable(ws, numberXPixels, numberYPixels); // Set the run properties ws->mutableRun().addProperty("sample-detector-distance", distance, "mm", true); ws->mutableRun().addProperty("beam-trap-diameter", beam_trap_diam, "mm", true); ws->mutableRun().addProperty("number-of-guides", nguides, true); ws->mutableRun().addProperty("source-sample-distance", source_distance, "mm", true); ws->mutableRun().addProperty("source-aperture-diameter", source_apert, "mm", true); ws->mutableRun().addProperty("sample-aperture-diameter", sample_apert, "mm", true); ws->mutableRun().addProperty("sample-thickness", sample_thickness, "cm", true); ws->mutableRun().addProperty("wavelength", wavelength, "Angstrom", true); ws->mutableRun().addProperty("wavelength-spread", dwavelength, "Angstrom", true); ws->mutableRun().addProperty("timer", countingTime, "sec", true); ws->mutableRun().addProperty("monitor", monitorCounts, "", true); ws->mutableRun().addProperty("start_time", start_time, "", true); ws->mutableRun().addProperty("run_start", start_time, "", true); // Move the detector to the right position API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent"); // Finding the name of the detector object. std::string detID = ws->getInstrument()->getStringParameter("detector-name")[0]; g_log.information("Moving "+detID); try { mover->setProperty<API::MatrixWorkspace_sptr> ("Workspace", ws); mover->setProperty("ComponentName", detID); mover->setProperty("Z", distance/1000.0); mover->execute(); } catch (std::invalid_argument& e) { g_log.error("Invalid argument to MoveInstrumentComponent Child Algorithm"); g_log.error(e.what()); } catch (std::runtime_error& e) { g_log.error("Unable to successfully run MoveInstrumentComponent Child Algorithm"); g_log.error(e.what()); } // Release the XML document memory pDoc->release(); }
void MaskBinsFromTable::exec() { MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); DataObjects::TableWorkspace_sptr paramWS = getProperty("MaskingInformation"); // 1. Check input table workspace and column order g_log.debug() << "Lines of parameters workspace = " << paramWS->rowCount() << std::endl; bool colname_specx = false; if (!paramWS) { throw std::invalid_argument("Input table workspace is not accepted."); } else { std::vector<std::string> colnames = paramWS->getColumnNames(); // check colum name order if (colnames.size() < 3) { g_log.error() << "Input MaskingInformation table workspace has fewer than 3 columns. " << colnames.size() << " columns indeed" << std::endl; throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns."); } if (colnames[0].compare("XMin") == 0) { // 1. Style XMin, XMax, SpectraList. Check rest if (colnames[1].compare("XMax") != 0 || colnames[2].compare("SpectraList") != 0) { g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl; throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns."); } } else if (colnames[0].compare("SpectraList") == 0) { // 2. Style SpectraList, XMin, XMax colname_specx = true; if (colnames[1].compare("XMin") != 0 || colnames[2].compare("XMax") != 0) { g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl; throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns."); } } else { g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl; throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns."); } } // 2. Loop over all rows bool firstloop = true; API::MatrixWorkspace_sptr outputws = this->getProperty("OutputWorkspace"); for (size_t ib = 0; ib < paramWS->rowCount(); ++ib) { API::TableRow therow = paramWS->getRow(ib); double xmin, xmax; std::string speclist; if (colname_specx) { therow >> speclist >> xmin >> xmax; } else { therow >> xmin >> xmax >> speclist; } g_log.debug() << "Row " << ib << " XMin = " << xmin << " XMax = " << xmax << " SpectraList = " << speclist << std::endl; API::IAlgorithm_sptr maskbins = this->createChildAlgorithm("MaskBins", 0, 0.3, true); maskbins->initialize(); if (firstloop) { maskbins->setProperty("InputWorkspace", inputWS); firstloop = false; } else { maskbins->setProperty("InputWorkspace", outputws); } maskbins->setProperty("OutputWorkspace", outputws); maskbins->setPropertyValue("SpectraList", speclist); maskbins->setProperty("XMin", xmin); maskbins->setProperty("XMax", xmax); bool isexec = maskbins->execute(); if (!isexec) { g_log.error() << "MaskBins() is not executed for row " << ib << std::endl; throw std::runtime_error("MaskBins() is not executed"); } outputws = maskbins->getProperty("OutputWorkspace"); if (!outputws) { g_log.error() << "OutputWorkspace is not retrieved for row " << ib << ". " << std::endl; throw std::runtime_error("OutputWorkspace is not got from MaskBins"); } }