예제 #1
0
/** Initialize unit conversion helper
 * This method is interface to internal initialize method, which actually takes
 all parameters UnitConversion helper needs from
 * targetWSDescr class

 * @param targetWSDescr -- the class which contains all information about target
 workspace
                         including energy transfer mode, number of dimensions,
 input workspace etc.
 * @param unitsTo       -- the ID of the units conversion helper would help to
 convert to
 * @param forceViaTOF   -- force to perform unit conversion via TOF even if
 quick conversion exist (by default, false)
 *
*/
void UnitsConversionHelper::initialize(const MDWSDescription &targetWSDescr,
                                       const std::string &unitsTo,
                                       bool forceViaTOF) {
  // obtain input workspace units
  API::MatrixWorkspace_const_sptr inWS2D = targetWSDescr.getInWS();
  if (!inWS2D)
    throw(std::runtime_error("UnitsConversionHelper::initialize Should not be "
                             "able to call this function when workpsace is "
                             "undefined"));

  API::NumericAxis *pAxis =
      dynamic_cast<API::NumericAxis *>(inWS2D->getAxis(0));
  if (!pAxis)
    throw(std::invalid_argument(
        "Cannot retrieve numeric X axis from the input workspace: " +
        inWS2D->name()));

  std::string unitsFrom = inWS2D->getAxis(0)->unit()->unitID();

  // get detectors positions and other data needed for units conversion:
  if (!(targetWSDescr.m_PreprDetTable))
    throw std::runtime_error("MDWSDescription does not have a detector table");

  int Emode = (int)targetWSDescr.getEMode();

  this->initialize(unitsFrom, unitsTo, targetWSDescr.m_PreprDetTable, Emode,
                   forceViaTOF);
}
예제 #2
0
void UnitsConversionHelper::initialize(const MDWSDescription &TWSD, const std::string &units_to)
{   
  // obtain input workspace units
    API::MatrixWorkspace_const_sptr inWS2D = TWSD.getInWS();
    if(!inWS2D.get()){
        throw(std::logic_error("UnitsConversionHelper::initialize Should not be able to call this function when workpsace is undefined"));
    }
    API::NumericAxis *pAxis = dynamic_cast<API::NumericAxis *>(inWS2D->getAxis(0));
    if(!pAxis){
        std::string ERR = "can not retrieve numeric X axis from the input workspace: "+inWS2D->name();
        throw(std::invalid_argument(ERR));
   }
   pSourceWSUnit =   inWS2D->getAxis(0)->unit();
   if(!pSourceWSUnit){
        throw(std::logic_error(" can not retrieve source workspace units from the source workspace's numeric axis"));
   }
   // Check how input workspace units relate to the units requested
   UnitCnvrsn = analyzeUnitsConversion(pSourceWSUnit->unitID(),units_to);


   // get units class, requested by ChildAlgorithm
   pTargetUnit = Kernel::UnitFactory::Instance().create(units_to);
   if(!pTargetUnit){
         throw(std::logic_error(" can not retrieve target unit from the units factory"));
   }

   // get detectors positions and other data needed for units conversion:
    pTwoTheta =  &(TWSD.getDetectors()->getTwoTheta());      
    pL2       =  &(TWSD.getDetectors()->getL2());

    L1        =  TWSD.getDetectors()->getL1();
   // get efix
    efix      =  TWSD.getEi();
    emode     =  (int)TWSD.getEMode();

}
예제 #3
0
/** function initalizes all variables necessary for converting workspace
 * variables into MD variables in ModQ (elastic/inelastic) cases  */
void MDTransfQ3D::initialize(const MDWSDescription &ConvParams) {
  m_pEfixedArray = NULL;
  m_pDetMasks = NULL;
  //********** Generic part of initialization, common for elastic and inelastic
  // modes:
  // get transformation matrix (needed for CrystalAsPoder mode)
  m_RotMat = ConvParams.getTransfMatrix();

  if (!ConvParams.m_PreprDetTable)
    throw(std::runtime_error("The detectors have not been preprocessed but "
                             "they have to before running initialize"));
  // get pointer to the positions of the preprocessed detectors
  std::vector<Kernel::V3D> const &DetDir =
      ConvParams.m_PreprDetTable->getColVector<Kernel::V3D>("DetDirections");
  m_DetDirecton = &DetDir[0]; //

  // get min and max values defined by the algorithm.
  ConvParams.getMinMax(m_DimMin, m_DimMax);
  // get additional coordinates which are
  m_AddDimCoordinates = ConvParams.getAddCoord();

  //************   specific part of the initialization, dependent on emode:
  m_Emode = ConvParams.getEMode();
  m_NMatrixDim = getNMatrixDimensions(m_Emode);
  if (m_Emode == Kernel::DeltaEMode::Direct ||
      m_Emode == Kernel::DeltaEMode::Indirect) {
    // energy needed in inelastic case
    m_Ei =
        ConvParams.m_PreprDetTable->getLogs()->getPropertyValueAsType<double>(
            "Ei");
    // the wave vector of incident neutrons;
    m_Ki = sqrt(m_Ei / PhysicalConstants::E_mev_toNeutronWavenumberSq);

    m_pEfixedArray = NULL;
    if (m_Emode == (int)Kernel::DeltaEMode::Indirect)
      m_pEfixedArray =
          ConvParams.m_PreprDetTable->getColDataArray<float>("eFixed");
  } else {
    if (m_Emode != Kernel::DeltaEMode::Elastic)
      throw(std::runtime_error("MDTransfQ3D::initialize::Unknown or "
                               "unsupported energy conversion mode"));
    // check if we need to calculate Lorentz corrections and if we do, prepare
    // values for their precalculation:
    m_isLorentzCorrected = ConvParams.isLorentsCorrections();
    if (m_isLorentzCorrected) {
      auto &TwoTheta =
          ConvParams.m_PreprDetTable->getColVector<double>("TwoTheta");
      SinThetaSq.resize(TwoTheta.size());
      for (size_t i = 0; i < TwoTheta.size(); i++) {
        double sth = sin(0.5 * TwoTheta[i]);
        SinThetaSq[i] = sth * sth;
      }
      m_SinThetaSqArray = &SinThetaSq[0];
      if (!m_SinThetaSqArray)
        throw(std::runtime_error("MDTransfQ3D::initialize::Uninitilized "
                                 "Sin(Theta)^2 array for calculating Lorentz "
                                 "corrections"));
    }
  }
  // use detectors masks untill signals are masked by 0 instead of NaN
  m_pDetMasks = ConvParams.m_PreprDetTable->getColDataArray<int>("detMask");
}
예제 #4
0
/** function initializes all variables necessary for converting workspace
 * variables into MD variables in ModQ (elastic/inelastic) cases  */
void MDTransfModQ::initialize(const MDWSDescription &ConvParams) {
  //********** Generic part of initialization, common for elastic and inelastic
  // modes:
  //   pHost      = &Conv;
  // get transformation matrix (needed for CrystalAsPoder mode)
  m_RotMat = ConvParams.getTransfMatrix();
  m_pEfixedArray = nullptr;
  if (!ConvParams.m_PreprDetTable)
    throw(std::runtime_error("The detectors have not been preprocessed but "
                             "they have to before running initialize"));

  // get pointer to the positions of the detectors
  std::vector<Kernel::V3D> const &DetDir =
      ConvParams.m_PreprDetTable->getColVector<Kernel::V3D>("DetDirections");
  m_DetDirecton = &DetDir[0]; //

  // get min and max values defined by the algorithm.
  ConvParams.getMinMax(m_DimMin, m_DimMax);
  // m_DimMin/max here are momentums and they are verified on momentum squared
  // base
  if (m_DimMin[0] < 0)
    m_DimMin[0] = 0;
  if (m_DimMax[0] < 0)
    m_DimMax[0] = 0;

  // m_DimMin here is a momentum and it is verified on momentum squared base
  m_DimMin[0] *= m_DimMin[0];
  m_DimMax[0] *= m_DimMax[0];
  if (std::fabs(m_DimMin[0] - m_DimMax[0]) < FLT_EPSILON ||
      m_DimMax[0] < m_DimMin[0]) {
    std::string ERR = "ModQ coordinate transformation: Min Q^2 value: " +
                      boost::lexical_cast<std::string>(m_DimMin[0]) +
                      " is more or equal then Max Q^2 value: " +
                      boost::lexical_cast<std::string>(m_DimMax[0]);
    throw(std::invalid_argument(ERR));
  }
  m_AddDimCoordinates = ConvParams.getAddCoord();

  //************   specific part of the initialization, dependent on emode:
  m_Emode = ConvParams.getEMode();
  m_NMatrixDim = getNMatrixDimensions(m_Emode);
  if (m_Emode == Kernel::DeltaEMode::Direct ||
      m_Emode == Kernel::DeltaEMode::Indirect) {
    // energy needed in inelastic case
    volatile double Ei =
        ConvParams.m_PreprDetTable->getLogs()->getPropertyValueAsType<double>(
            "Ei");
    m_Ei = Ei;
    if (Ei !=
        m_Ei) // Ei is NaN, try Efixed, but the value should be overridden later
    {
      try {
        m_Ei = ConvParams.m_PreprDetTable->getLogs()
                   ->getPropertyValueAsType<double>("eFixed");
      } catch (...) {
      }
    }

    // the wave vector of incident neutrons;
    m_Ki = sqrt(m_Ei / PhysicalConstants::E_mev_toNeutronWavenumberSq);
    m_pEfixedArray = nullptr;
    if (m_Emode == static_cast<int>(Kernel::DeltaEMode::Indirect))
      m_pEfixedArray =
          ConvParams.m_PreprDetTable->getColDataArray<float>("eFixed");
  } else if (m_Emode != Kernel::DeltaEMode::Elastic)
    throw(std::invalid_argument(
        "MDTransfModQ::initialize::Unknown energy conversion mode"));

  m_pDetMasks = ConvParams.m_PreprDetTable->getColDataArray<int>("detMask");
}