예제 #1
0
/** 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));
    }
  }
}
예제 #2
0
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;
}