/** function extracts the coordinates from additional workspace properties and *places them to proper position within * the vector of MD coordinates for the particular workspace. * * @param inWS2D -- input workspace * @param dimPropertyNames -- names of properties which should be treated as *dimensions * @param AddCoord -- * * @return AddCoord -- vector of additional coordinates (derived from WS *properties) for current multidimensional event */ void MDWSDescription::fillAddProperties( Mantid::API::MatrixWorkspace_const_sptr inWS2D, const std::vector<std::string> &dimPropertyNames, std::vector<coord_t> &AddCoord) { size_t nDimPropNames = dimPropertyNames.size(); if (AddCoord.size() != nDimPropNames) AddCoord.resize(nDimPropNames); for (size_t i = 0; i < nDimPropNames; i++) { // HACK: A METHOD, Which converts TSP into value, correspondent to time // scale of matrix workspace has to be developed and deployed! Kernel::Property *pProperty = (inWS2D->run().getProperty(dimPropertyNames[i])); Kernel::TimeSeriesProperty<double> *run_property = dynamic_cast<Kernel::TimeSeriesProperty<double> *>(pProperty); if (run_property) { AddCoord[i] = coord_t(run_property->firstValue()); } else { // e.g Ei can be a property and dimension Kernel::PropertyWithValue<double> *proc_property = dynamic_cast<Kernel::PropertyWithValue<double> *>(pProperty); if (!proc_property) { std::string ERR = " Can not interpret property, used as dimension.\n Property: " + dimPropertyNames[i] + " is neither a time series (run) property " "nor a property with value<double>"; throw(std::invalid_argument(ERR)); } AddCoord[i] = coord_t(*(proc_property)); } } }
std::tuple<double, double, double> EnggDiffFittingModel::getDifcDifaTzero( Mantid::API::MatrixWorkspace_const_sptr ws) { const auto run = ws->run(); const auto difc = run.getPropertyValueAsType<double>("difc"); const auto difa = run.getPropertyValueAsType<double>("difa"); const auto tzero = run.getPropertyValueAsType<double>("tzero"); return std::tuple<double, double, double>(difc, difa, tzero); }
/**The method responsible for analyzing input workspace parameters and *preprocessing detectors positions into reciprocal space * * @param InWS2D -- input Matrix workspace with defined instrument * @param dEModeRequested -- energy conversion mode (direct/indirect/elastic) * @param updateMasks -- if full detector positions calculations or just update *masking requested * @param OutWSName -- the name for the preprocessed detectors workspace to *have in the analysis data service * * @return shared pointer to the workspace with preprocessed detectors *information. */ DataObjects::TableWorkspace_const_sptr ConvertToMDParent::preprocessDetectorsPositions( const Mantid::API::MatrixWorkspace_const_sptr &InWS2D, const std::string &dEModeRequested, bool updateMasks, const std::string &OutWSName) { DataObjects::TableWorkspace_sptr TargTableWS; Kernel::DeltaEMode::Type Emode; // Do we need to reuse output workspace bool storeInDataService(true); std::string tOutWSName(OutWSName); if (tOutWSName == "-" || tOutWSName.empty()) // TargTableWS is recalculated each time; { storeInDataService = false; tOutWSName = "ServiceTableWS"; // TODO: should be hidden? } else { storeInDataService = true; } // if output workspace exists in dataservice, we may try to use it if (storeInDataService && API::AnalysisDataService::Instance().doesExist(tOutWSName)) { TargTableWS = API::AnalysisDataService::Instance() .retrieveWS<DataObjects::TableWorkspace>(tOutWSName); // get number of all histograms (may be masked or invalid) size_t nHist = InWS2D->getNumberHistograms(); size_t nDetMap = TargTableWS->rowCount(); if (nHist == nDetMap) { // let's take at least some precaution to ensure that instrument have not // changed std::string currentWSInstrumentName = InWS2D->getInstrument()->getName(); std::string oldInstrName = TargTableWS->getLogs()->getPropertyValueAsType<std::string>( "InstrumentName"); if (oldInstrName == currentWSInstrumentName) { // a direct mode instrument can be unchanged but incident energy can be // different. // It is cheap operation so we should always replace incident energy on // the target workspace bool hasEi = InWS2D->run().hasProperty("Ei"); bool hasEfix = InWS2D->run().hasProperty("eFixed"); if (hasEi || hasEfix) { double Ei; if (hasEi) Ei = InWS2D->run().getPropertyValueAsType<double>("Ei"); if (hasEfix) Ei = InWS2D->run().getPropertyValueAsType<double>("eFixed"); TargTableWS->logs()->addProperty<double>("Ei", Ei, true); } else { Emode = Kernel::DeltaEMode::fromString(dEModeRequested); if (Emode == Kernel::DeltaEMode::Direct) throw(std::invalid_argument( "Input neutron's energy has to be present at the workspace as " "Ei or eFixed number log in Direct inelastic mode")); // if(Emode==Kernel::DeltaEMode::Indirect && !hasEfix) // throw(std::invalid_argument("Input neutron's energy has to be // present at the workspace as eFixed number log in Indirect // inelastic mode")); } if (!updateMasks) return TargTableWS; // Target workspace with preprocessed detectors exists and seems is // correct one. // We still need to update masked detectors information TargTableWS = this->runPreprocessDetectorsToMDChildUpdatingMasks( InWS2D, tOutWSName, dEModeRequested, Emode); return TargTableWS; } } else // there is a workspace in the data service with the same name but // this ws is not suitable as target for this algorithm. { // Should delete this WS from the dataservice API::AnalysisDataService::Instance().remove(tOutWSName); } } // No result found in analysis data service or the result is unsatisfactory. // Try to calculate target workspace. TargTableWS = this->runPreprocessDetectorsToMDChildUpdatingMasks( InWS2D, tOutWSName, dEModeRequested, Emode); if (storeInDataService) API::AnalysisDataService::Instance().addOrReplace(tOutWSName, TargTableWS); // else // TargTableWS->setName(OutWSName); // check if we got what we wanted: // in direct or indirect mode input ws has to have input energy if (Emode == Kernel::DeltaEMode::Direct || Emode == Kernel::DeltaEMode::Indirect) { double m_Ei = TargTableWS->getLogs()->getPropertyValueAsType<double>("Ei"); if (isNaN(m_Ei)) { // Direct mode needs Ei if (Emode == Kernel::DeltaEMode::Direct) throw(std::invalid_argument( "Input neutron's energy has to be defined in inelastic mode ")); // Do we have at least something for Indirect? float *eFixed = TargTableWS->getColDataArray<float>("eFixed"); if (!eFixed) throw(std::invalid_argument( "Input neutron's energy has to be defined in inelastic mode ")); uint32_t NDetectors = TargTableWS->getLogs()->getPropertyValueAsType<uint32_t>( "ActualDetectorsNum"); for (uint32_t i = 0; i < NDetectors; i++) if (isNaN(*(eFixed + i))) throw( std::invalid_argument("Undefined eFixed energy for detector N: " + boost::lexical_cast<std::string>(i))); } } return TargTableWS; }