MANTID_API_DLL Mantid::API::IMDEventWorkspace_const_sptr IPropertyManager::getValue<Mantid::API::IMDEventWorkspace_const_sptr>( const std::string &name) const { PropertyWithValue<Mantid::API::IMDEventWorkspace_const_sptr> *prop = dynamic_cast< PropertyWithValue<Mantid::API::IMDEventWorkspace_const_sptr> *>( getPointerToProperty(name)); if (prop) { return prop->operator()(); } else { // Every other class with this behaviour allows you to get a shared_ptr<T> // property as a shared_ptr<const T>. This class should be consistent, so // try that: PropertyWithValue<Mantid::API::IMDEventWorkspace_sptr> *nonConstProp = dynamic_cast<PropertyWithValue<Mantid::API::IMDEventWorkspace_sptr> *>( getPointerToProperty(name)); if (nonConstProp) { return nonConstProp->operator()(); } else { std::string message = "Attempt to assign property " + name + " to incorrect type. Expected const shared_ptr<IMDEventWorkspace>."; throw std::runtime_error(message); } } }
void PoldiTruncateData::exec() { MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace"); setChopperFromWorkspace(inputWorkspace); setTimeBinWidthFromWorkspace(inputWorkspace); try { MatrixWorkspace_sptr cropped = getCroppedWorkspace(inputWorkspace); setProperty("OutputWorkspace", cropped); if(!getPointerToProperty("ExtraCountsWorkspaceName")->isDefault()) { try { MatrixWorkspace_sptr extraCounts = getExtraCountsWorkspace(inputWorkspace); std::string extraCountsWorkspaceName = getProperty("ExtraCountsWorkspaceName"); declareProperty(new WorkspaceProperty<MatrixWorkspace>("ExtraCountsWorkspace", extraCountsWorkspaceName, Direction::Output)); setProperty("ExtraCountsWorkspace", extraCounts); } catch(std::invalid_argument) { m_log.warning() << "Extra count information was requested, but there are no extra bins." << std::endl; } } } catch(std::invalid_argument) { m_log.error() << "Cannot crop workspace. Please check the timing information." << std::endl; m_log.error() << " Calculated bin count: " << getCalculatedBinCount() << std::endl; m_log.error() << " Bin count in the workspace: " << getActualBinCount() << std::endl; removeProperty("OutputWorkspace"); } }
MANTID_API_DLL Mantid::API::IMDWorkspace_const_sptr IPropertyManager::getValue<Mantid::API::IMDWorkspace_const_sptr>( const std::string &name) const { PropertyWithValue<Mantid::API::IMDWorkspace_sptr> *prop = dynamic_cast<PropertyWithValue<Mantid::API::IMDWorkspace_sptr> *>( getPointerToProperty(name)); if (prop) { return prop->operator()(); } else { std::string message = "Attempt to assign property " + name + " to incorrect type. Expected const IMDWorkspace."; throw std::runtime_error(message); } }
template<> DLLExport Mantid::DataObjects::OffsetsWorkspace_const_sptr IPropertyManager::getValue<Mantid::DataObjects::OffsetsWorkspace_const_sptr>(const std::string &name) const { PropertyWithValue<Mantid::DataObjects::OffsetsWorkspace_sptr>* prop = dynamic_cast<PropertyWithValue<Mantid::DataObjects::OffsetsWorkspace_sptr>*>(getPointerToProperty(name)); if (prop) { return prop->operator()(); } else { std::string message = "Attempt to assign property "+ name +" to incorrect type. Expected const OffsetsWorkspace."; throw std::runtime_error(message); } }
DLLExport Mantid::API::IPeaksWorkspace_sptr IPropertyManager::getValue<Mantid::API::IPeaksWorkspace_sptr>( const std::string &name) const { PropertyWithValue<Mantid::API::IPeaksWorkspace_sptr> *prop = dynamic_cast<PropertyWithValue<Mantid::API::IPeaksWorkspace_sptr> *>( getPointerToProperty(name)); if (prop) { return *prop; } else { std::string message = "Attempt to assign property " + name + " to incorrect type. Expected shared_ptr<PeaksWorkspace>."; throw std::runtime_error(message); } }
/** * Execute the algorithm. */ void LoadBBY::exec() { // Delete the output workspace name if it existed std::string outName = getPropertyValue("OutputWorkspace"); if (API::AnalysisDataService::Instance().doesExist(outName)) API::AnalysisDataService::Instance().remove(outName); // Get the name of the data file. std::string filename = getPropertyValue(FilenameStr); ANSTO::Tar::File tarFile(filename); if (!tarFile.good()) throw std::invalid_argument("invalid BBY file"); // region of intreset std::vector<bool> roi = createRoiVector(getPropertyValue(MaskStr)); double tofMinBoundary = getProperty(FilterByTofMinStr); double tofMaxBoundary = getProperty(FilterByTofMaxStr); double timeMinBoundary = getProperty(FilterByTimeStartStr); double timeMaxBoundary = getProperty(FilterByTimeStopStr); if (isEmpty(tofMaxBoundary)) tofMaxBoundary = std::numeric_limits<double>::infinity(); if (isEmpty(timeMaxBoundary)) timeMaxBoundary = std::numeric_limits<double>::infinity(); API::Progress prog(this, 0.0, 1.0, Progress_Total); prog.doReport("creating instrument"); // create workspace DataObjects::EventWorkspace_sptr eventWS = boost::make_shared<DataObjects::EventWorkspace>(); eventWS->initialize(HISTO_BINS_Y * HISTO_BINS_X, 2, // number of TOF bin boundaries 1); // set the units eventWS->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("TOF"); eventWS->setYUnit("Counts"); // set title const std::vector<std::string> &subFiles = tarFile.files(); for (const auto &subFile : subFiles) if (subFile.compare(0, 3, "BBY") == 0) { std::string title = subFile; if (title.rfind(".hdf") == title.length() - 4) title.resize(title.length() - 4); if (title.rfind(".nx") == title.length() - 3) title.resize(title.length() - 3); eventWS->setTitle(title); break; } // create instrument InstrumentInfo instrumentInfo; // Geometry::Instrument_sptr instrument = createInstrument(tarFile, /* ref */ instrumentInfo); // eventWS->setInstrument(instrument); // load events size_t numberHistograms = eventWS->getNumberHistograms(); std::vector<EventVector_pt> eventVectors(numberHistograms, nullptr); std::vector<size_t> eventCounts(numberHistograms, 0); // phase correction Kernel::Property *periodMasterProperty = getPointerToProperty(PeriodMasterStr); Kernel::Property *periodSlaveProperty = getPointerToProperty(PeriodSlaveStr); Kernel::Property *phaseSlaveProperty = getPointerToProperty(PhaseSlaveStr); double periodMaster; double periodSlave; double phaseSlave; if (periodMasterProperty->isDefault() || periodSlaveProperty->isDefault() || phaseSlaveProperty->isDefault()) { if (!periodMasterProperty->isDefault() || !periodSlaveProperty->isDefault() || !phaseSlaveProperty->isDefault()) { throw std::invalid_argument("Please specify PeriodMaster, PeriodSlave " "and PhaseSlave or none of them."); } // if values have not been specified in loader then use values from hdf file periodMaster = instrumentInfo.period_master; periodSlave = instrumentInfo.period_slave; phaseSlave = instrumentInfo.phase_slave; } else { periodMaster = getProperty(PeriodMasterStr); periodSlave = getProperty(PeriodSlaveStr); phaseSlave = getProperty(PhaseSlaveStr); if ((periodMaster < 0.0) || (periodSlave < 0.0)) throw std::invalid_argument( "Please specify a positive value for PeriodMaster and PeriodSlave."); } double period = periodSlave; double shift = -1.0 / 6.0 * periodMaster - periodSlave * phaseSlave / 360.0; // count total events per pixel to reserve necessary memory ANSTO::EventCounter eventCounter( roi, HISTO_BINS_Y, period, shift, tofMinBoundary, tofMaxBoundary, timeMinBoundary, timeMaxBoundary, eventCounts); loadEvents(prog, "loading neutron counts", tarFile, eventCounter); // prepare event storage ANSTO::ProgressTracker progTracker(prog, "creating neutron event lists", numberHistograms, Progress_ReserveMemory); for (size_t i = 0; i != numberHistograms; ++i) { DataObjects::EventList &eventList = eventWS->getEventList(i); eventList.setSortOrder(DataObjects::PULSETIME_SORT); eventList.reserve(eventCounts[i]); eventList.setDetectorID(static_cast<detid_t>(i)); eventList.setSpectrumNo(static_cast<detid_t>(i)); DataObjects::getEventsFrom(eventList, eventVectors[i]); progTracker.update(i); } progTracker.complete(); ANSTO::EventAssigner eventAssigner( roi, HISTO_BINS_Y, period, shift, tofMinBoundary, tofMaxBoundary, timeMinBoundary, timeMaxBoundary, eventVectors); loadEvents(prog, "loading neutron events", tarFile, eventAssigner); Kernel::cow_ptr<MantidVec> axis; MantidVec &xRef = axis.access(); xRef.resize(2, 0.0); xRef[0] = std::max( 0.0, floor(eventCounter.tofMin())); // just to make sure the bins hold it all xRef[1] = eventCounter.tofMax() + 1; eventWS->setAllX(axis); // count total number of masked bins size_t maskedBins = 0; for (size_t i = 0; i != roi.size(); i++) if (!roi[i]) maskedBins++; if (maskedBins > 0) { // create list of masked bins std::vector<size_t> maskIndexList(maskedBins); size_t maskIndex = 0; for (size_t i = 0; i != roi.size(); i++) if (!roi[i]) maskIndexList[maskIndex++] = i; API::IAlgorithm_sptr maskingAlg = createChildAlgorithm("MaskDetectors"); maskingAlg->setProperty("Workspace", eventWS); maskingAlg->setProperty("WorkspaceIndexList", maskIndexList); maskingAlg->executeAsChildAlg(); } // set log values API::LogManager &logManager = eventWS->mutableRun(); logManager.addProperty("filename", filename); logManager.addProperty("att_pos", static_cast<int>(instrumentInfo.att_pos)); logManager.addProperty("frame_count", static_cast<int>(eventCounter.numFrames())); logManager.addProperty("period", period); // currently beam monitor counts are not available, instead number of frames // times period is used logManager.addProperty( "bm_counts", static_cast<double>(eventCounter.numFrames()) * period / 1.0e6); // static_cast<double>(instrumentInfo.bm_counts) // currently Kernel::time_duration duration = boost::posix_time::microseconds(static_cast<boost::int64_t>( static_cast<double>(eventCounter.numFrames()) * period)); Kernel::DateAndTime start_time("2000-01-01T00:00:00"); Kernel::DateAndTime end_time(start_time + duration); logManager.addProperty("start_time", start_time.toISO8601String()); logManager.addProperty("end_time", end_time.toISO8601String()); std::string time_str = start_time.toISO8601String(); AddSinglePointTimeSeriesProperty(logManager, time_str, "L1_chopper_value", instrumentInfo.L1_chopper_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_det_value", instrumentInfo.L2_det_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtainl_value", instrumentInfo.L2_curtainl_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtainr_value", instrumentInfo.L2_curtainr_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtainu_value", instrumentInfo.L2_curtainu_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtaind_value", instrumentInfo.L2_curtaind_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "D_det_value", instrumentInfo.D_det_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtainl_value", instrumentInfo.D_curtainl_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtainr_value", instrumentInfo.D_curtainr_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtainu_value", instrumentInfo.D_curtainu_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtaind_value", instrumentInfo.D_curtaind_value); AddSinglePointTimeSeriesProperty(logManager, time_str, "curtain_rotation", 10.0); API::IAlgorithm_sptr loadInstrumentAlg = createChildAlgorithm("LoadInstrument"); loadInstrumentAlg->setProperty("Workspace", eventWS); loadInstrumentAlg->setPropertyValue("InstrumentName", "BILBY"); loadInstrumentAlg->setProperty("RewriteSpectraMap", Mantid::Kernel::OptionalBool(false)); loadInstrumentAlg->executeAsChildAlg(); setProperty("OutputWorkspace", eventWS); }
/// Executes the algorithm void PoldiFitPeaks2D::exec() { std::vector<PoldiPeakCollection_sptr> peakCollections = getPeakCollectionsFromInput(); // Try to setup the 2D data and poldi instrument MatrixWorkspace_sptr ws = getProperty("InputWorkspace"); setDeltaTFromWorkspace(ws); setPoldiInstrument(boost::make_shared<PoldiInstrumentAdapter>(ws)); setTimeTransformerFromInstrument(m_poldiInstrument); // If a profile function is selected, set it on the peak collections. Property *profileFunctionProperty = getPointerToProperty("PeakProfileFunction"); if (!profileFunctionProperty->isDefault()) { for (auto &peakCollection : peakCollections) { peakCollection->setProfileFunctionName(profileFunctionProperty->value()); } } // Perform 2D-fit and return Fit algorithm to extract various information IAlgorithm_sptr fitAlgorithm = calculateSpectrum(peakCollections, ws); // The FitFunction is used to generate... IFunction_sptr fitFunction = getFunction(fitAlgorithm); // ...a calculated 1D-spectrum... MatrixWorkspace_sptr outWs1D = get1DSpectrum(fitFunction, ws); // ...a vector of peak collections. std::vector<PoldiPeakCollection_sptr> integralPeaks = getCountPeakCollections(fitFunction); for (size_t i = 0; i < peakCollections.size(); ++i) { assignMillerIndices(peakCollections[i], integralPeaks[i]); } // Get the calculated 2D workspace setProperty("OutputWorkspace", getWorkspace(fitAlgorithm)); // Set the output peaks depending on whether it's one or more workspaces if (integralPeaks.size() == 1) { setProperty("RefinedPoldiPeakWorkspace", integralPeaks.front()->asTableWorkspace()); } else { WorkspaceGroup_sptr peaksGroup = boost::make_shared<WorkspaceGroup>(); for (auto &integralPeak : integralPeaks) { peaksGroup->addWorkspace(integralPeak->asTableWorkspace()); } setProperty("RefinedPoldiPeakWorkspace", peaksGroup); } // Set the 1D-spectrum output setProperty("Calculated1DSpectrum", outWs1D); // If it was a PawleyFit, also produce one or more cell parameter tables. bool isPawleyFit = getProperty("PawleyFit"); if (isPawleyFit) { Poldi2DFunction_sptr poldi2DFunction = boost::dynamic_pointer_cast<Poldi2DFunction>(fitFunction); std::vector<ITableWorkspace_sptr> cells; if (poldi2DFunction) { for (size_t i = 0; i < poldi2DFunction->nFunctions(); ++i) { try { ITableWorkspace_sptr cell = getRefinedCellParameters(poldi2DFunction->getFunction(i)); cells.push_back(cell); } catch (const std::invalid_argument &) { // do nothing } } if (cells.size() == 1) { setProperty("RefinedCellParameters", cells.front()); } else { WorkspaceGroup_sptr cellsGroup = boost::make_shared<WorkspaceGroup>(); for (auto &cell : cells) { cellsGroup->addWorkspace(cell); } setProperty("RefinedCellParameters", cellsGroup); } } else { g_log.warning() << "Warning: Cell parameter table is empty."; } } // Optionally output the raw fitting parameters. Property *rawFitParameters = getPointerToProperty("RawFitParameters"); if (!rawFitParameters->isDefault()) { ITableWorkspace_sptr parameters = fitAlgorithm->getProperty("OutputParameters"); setProperty("RawFitParameters", parameters); } }
//---------------------------------------------------------------------------------------------- /// Execute the algorithm. void EstimateFitParameters::execConcrete() { auto costFunction = getCostFunctionInitialized(); auto func = costFunction->getFittingFunction(); // Use additional constraints on parameters tied in some way // to the varied parameters to exculde unwanted results. std::vector<std::unique_ptr<IConstraint>> constraints; std::string constraintStr = getProperty("Constraints"); if (!constraintStr.empty()) { Expression expr; expr.parse(constraintStr); expr.toList(); for (auto &term : expr.terms()) { IConstraint *c = ConstraintFactory::Instance().createInitialized(func.get(), term); constraints.push_back(std::unique_ptr<IConstraint>(c)); } } // Ranges to use with random number generators: one for each free parameter. std::vector<std::pair<double, double>> ranges; ranges.reserve(costFunction->nParams()); for (size_t i = 0; i < func->nParams(); ++i) { if (!func->isActive(i)) { continue; } auto constraint = func->getConstraint(i); if (constraint == nullptr) { func->fix(i); continue; } auto boundary = dynamic_cast<Constraints::BoundaryConstraint *>(constraint); if (boundary == nullptr) { throw std::runtime_error("Parameter " + func->parameterName(i) + " must have a boundary constraint. "); } if (!boundary->hasLower()) { throw std::runtime_error("Constraint of " + func->parameterName(i) + " must have a lower bound."); } if (!boundary->hasUpper()) { throw std::runtime_error("Constraint of " + func->parameterName(i) + " must have an upper bound."); } // Use the lower and upper bounds of the constraint to set the range // of a generator with uniform distribution. ranges.push_back(std::make_pair(boundary->lower(), boundary->upper())); } // Number of parameters could have changed costFunction->reset(); if (costFunction->nParams() == 0) { throw std::runtime_error("No parameters are given for which to estimate " "initial values. Set boundary constraints to " "parameters that need to be estimated."); } size_t nSamples = static_cast<int>(getProperty("NSamples")); unsigned int seed = static_cast<int>(getProperty("Seed")); if (getPropertyValue("Type") == "Monte Carlo") { int nOutput = getProperty("NOutputs"); auto outputWorkspaceProp = getPointerToProperty("OutputWorkspace"); if (outputWorkspaceProp->isDefault() || nOutput <= 0) { nOutput = 1; } auto output = runMonteCarlo(*costFunction, ranges, constraints, nSamples, static_cast<size_t>(nOutput), seed); if (!outputWorkspaceProp->isDefault()) { auto table = API::WorkspaceFactory::Instance().createTable(); auto column = table->addColumn("str", "Name"); column->setPlotType(6); for (size_t i = 0; i < output.size(); ++i) { column = table->addColumn("double", std::to_string(i + 1)); column->setPlotType(2); } for (size_t i = 0, ia = 0; i < m_function->nParams(); ++i) { if (m_function->isActive(i)) { TableRow row = table->appendRow(); row << m_function->parameterName(i); for (auto &j : output) { row << j[ia]; } ++ia; } } setProperty("OutputWorkspace", table); } } else { size_t nSelection = static_cast<int>(getProperty("Selection")); size_t nIterations = static_cast<int>(getProperty("NIterations")); runCrossEntropy(*costFunction, ranges, constraints, nSamples, nSelection, nIterations, seed); } bool fixBad = getProperty("FixBadParameters"); if (fixBad) { fixBadParameters(*costFunction, ranges); } }
template <> DLLExport Property* IPropertyManager::getValue<Property*>(const std::string &name) const { return getPointerToProperty(name); }
/** Initialisation method */ void Fit::init() { declareProperty(new API::FunctionProperty("Function"),"Parameters defining the fitting function and its initial values"); declareProperty(new API::WorkspaceProperty<API::Workspace>("InputWorkspace","",Kernel::Direction::Input), "Name of the input Workspace"); std::vector<std::string> domainTypes; domainTypes.push_back( "Simple" ); domainTypes.push_back( "Sequential" ); domainTypes.push_back( "Parallel" ); declareProperty("DomainType","Simple", Kernel::IValidator_sptr(new Kernel::ListValidator<std::string>(domainTypes)), "The type of function domain to use: Simple, Sequential, or Parallel.", Kernel::Direction::Input); declareProperty("Ties","", Kernel::Direction::Input); getPointerToProperty("Ties")->setDocumentation("Math expressions defining ties between parameters of the fitting function."); declareProperty("Constraints","", Kernel::Direction::Input); getPointerToProperty("Constraints")->setDocumentation("List of constraints"); auto mustBePositive = boost::shared_ptr< Kernel::BoundedValidator<int> >( new Kernel::BoundedValidator<int>() ); mustBePositive->setLower(0); declareProperty("MaxIterations", 500, mustBePositive->clone(), "Stop after this number of iterations if a good fit is not found" ); declareProperty("IgnoreInvalidData",false,"Flag to ignore infinities, NaNs and data with zero errors."); declareProperty("OutputStatus","", Kernel::Direction::Output); getPointerToProperty("OutputStatus")->setDocumentation( "Whether the fit was successful" ); declareProperty("OutputChi2overDoF",0.0, "Returns the goodness of the fit", Kernel::Direction::Output); // Disable default gsl error handler (which is to call abort!) gsl_set_error_handler_off(); std::vector<std::string> minimizerOptions = API::FuncMinimizerFactory::Instance().getKeys(); declareProperty("Minimizer","Levenberg-Marquardt", Kernel::IValidator_sptr(new Kernel::StartsWithValidator(minimizerOptions)), "Minimizer to use for fitting. Minimizers available are \"Levenberg-Marquardt\", \"Simplex\", \"Conjugate gradient (Fletcher-Reeves imp.)\", \"Conjugate gradient (Polak-Ribiere imp.)\", \"BFGS\", and \"Levenberg-MarquardtMD\""); std::vector<std::string> costFuncOptions = API::CostFunctionFactory::Instance().getKeys(); // select only CostFuncFitting variety for(auto it = costFuncOptions.begin(); it != costFuncOptions.end(); ++it) { auto costFunc = boost::dynamic_pointer_cast<CostFuncFitting>( API::CostFunctionFactory::Instance().create(*it) ); if (!costFunc) { *it = ""; } } declareProperty("CostFunction","Least squares", Kernel::IValidator_sptr(new Kernel::ListValidator<std::string>(costFuncOptions)), "The cost function to be used for the fit, default is Least squares", Kernel::Direction::InOut); declareProperty("CreateOutput", false, "Set to true to create output workspaces with the results of the fit" "(default is false)." ); declareProperty("Output", "", "A base name for the output workspaces (if not given default names will be created)." ); declareProperty("CalcErrors", false, "Set to true to calcuate errors when output isn't created " "(default is false)." ); declareProperty("OutputCompositeMembers",false, "If true and CreateOutput is true then the value of each member of a Composite Function is also output."); declareProperty(new Kernel::PropertyWithValue<bool>("ConvolveMembers", false), "If true and OutputCompositeMembers is true members of any Convolution are output convolved\n" "with corresponding resolution"); declareProperty("OutputParametersOnly", false, "Set to true to output only the parameters and not workspace(s) with the calculated values\n" "(default is false, ignored if CreateOutput is false and Output is an empty string)." ); }
/** Give settings to a property to determine when it gets enabled/hidden. * Passes ownership of the given IPropertySettings object to the named * property * @param name :: property name * @param settings :: IPropertySettings */ void IPropertyManager::setPropertySettings( const std::string &name, std::unique_ptr<IPropertySettings> settings) { Property *prop = getPointerToProperty(name); if (prop) prop->setSettings(std::move(settings)); }