/** 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);
}
Example #2
0
/** Method analyzes the state of UB matrix and goniometer attached to the
  *workspace and decides, which target
  * coordinate system these variables identify.
  *Crystal Frame decided in case if there is UB matrix is present and is not
  *unit matrix
  *Lab frame -- if goniometer is Unit and UB is unit matrix or not present
  *Sample frame -- otherwise
  */
CnvrtToMD::TargetFrame
MDWSTransform::findTargetFrame(MDWSDescription &TargWSDescription) const {

  bool hasGoniometer = TargWSDescription.hasGoniometer();
  bool hasLattice = TargWSDescription.hasLattice();

  if (!hasGoniometer) {
    return LabFrame;
  } else {
    if (hasLattice)
      return HKLFrame;
    else
      return SampleFrame;
  }
}
Example #3
0
void MDTransfNoQ::initialize(const MDWSDescription &ConvParams) {

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

  // get min and max values defined by the algorithm.
  ConvParams.getMinMax(m_DimMin, m_DimMax);

  m_NMatrixDim =
      getNMatrixDimensions(Kernel::DeltaEMode::Undefined, ConvParams.getInWS());
  m_AddDimCoordinates = ConvParams.getAddCoord();

  API::NumericAxis *pXAx;
  this->getAxes(ConvParams.getInWS(), pXAx, m_YAxis);
}
Example #4
0
/** function creates empty MD event workspace with given parameters (workspace
*factory) and stores internal pointer to this workspace for further usage.
*  IT ASLO SETS UP W-TRANSFORMATON. TODO: reconcile w-transformation with MD
*geometry.
*
*@param WSD the class which describes an MD workspace
*
*@returns shared pointer to the created workspace
*/
API::IMDEventWorkspace_sptr
MDEventWSWrapper::createEmptyMDWS(const MDWSDescription &WSD) {

    if (WSD.nDimensions() < 1 || WSD.nDimensions() > MAX_N_DIM) {
        std::string ERR = " Number of requested MD dimensions: " +
                          boost::lexical_cast<std::string>(WSD.nDimensions()) +
                          " exceeds maximal number of MD dimensions: " +
                          boost::lexical_cast<std::string>((int)MAX_N_DIM) +
                          " instantiated during compilation\n";
        throw(std::invalid_argument(ERR));
    }

    m_NDimensions = (int)WSD.nDimensions();
    // call the particular function, which creates the workspace with n_dimensions
    (this->*(wsCreator[m_NDimensions]))(WSD);

    // set up the matrix, which convert momentums from Q in orthogonal crystal
    // coordinate system and units of Angstrom^-1 to hkl or orthogonal hkl or
    // whatever
    m_Workspace->setWTransf(WSD.m_Wtransf);
    return m_Workspace;
}
Example #5
0
/** Method verifies if the information available on the source workspace is
 *sufficient to build appropriate frame
 *@param TargWSDescription -- the class which contains the information about the
 *target workspace
 *@param CoordFrameID     -- the ID of the target frame requested
 *
 * method throws invalid argument if the information on the workspace is
 *insufficient to define the frame requested
*/
void MDWSTransform::checkTargetFrame(
    const MDWSDescription &TargWSDescription,
    const CnvrtToMD::TargetFrame CoordFrameID) const {
  switch (CoordFrameID) {
  case (LabFrame): // nothing needed for lab frame
    return;
  case (SampleFrame):
    if (!TargWSDescription.hasGoniometer())
      throw std::invalid_argument(
          " Sample frame needs goniometer to be defined on the workspace ");
    return;
  case (HKLFrame): // ubMatrix has to be present
    if (!TargWSDescription.hasLattice())
      throw std::invalid_argument(
          " HKL frame needs UB matrix defined on the workspace ");
    if (!TargWSDescription.hasGoniometer())
      g_Log.warning() << "  HKL frame does not have goniometer defined on the "
                         "workspace. Assuming unit goniometer matrix\n";
    return;
  default:
    throw std::runtime_error(
        " Unexpected argument in MDWSTransform::checkTargetFrame");
  }
}
Example #6
0
/** method to build the Q-coordinates transformation.
 *
 * @param TargWSDescription -- the class which describes target MD workspace. In
 Q3D case this description is modified by the method
                               with default Q-axis labels and Q-axis units
 * @param FrameRequested    -- the string which describes the target
 transformation frame in Q3D case. If the string value is '''Auto'''
 *   the frame is selected depending on the presence of UB matrix and goniometer
 settings, namely it can be:
 * a) the laboratory -- (no UB matrix, goniometer angles set to 0)
   b) Q (sample frame)''': the goniometer rotation of the sample is taken out,
 to give Q in the frame of the sample. See [[SetGoniometer]] to specify the
 goniometer used in the experiment.
   c) Crystal or crystal Cartesian (C)- Busing, Levi 1967 coordinate system --
 depending on Q-scale requested
 *  one of the target frames above can be requested explicitly. In this case the
 method throws invalid argument if necessary parameters (UB matrix) is not
 attached to the workspace

 * @param QScaleRequested   -- Q-transformation needed
 *
 * @return the linear representation for the transformation matrix, which
 translate momentums from laboratory to the requested
 *   coordinate system.
*/
std::vector<double>
MDWSTransform::getTransfMatrix(MDWSDescription &TargWSDescription,
                               const std::string &FrameRequested,
                               const std::string &QScaleRequested) const {
  CoordScaling ScaleID = getQScaling(QScaleRequested);
  TargetFrame FrameID = getTargetFrame(FrameRequested);
  std::vector<double> transf =
      getTransfMatrix(TargWSDescription, FrameID, ScaleID);

  if (TargWSDescription.isQ3DMode()) {
    this->setQ3DDimensionsNames(TargWSDescription, FrameID, ScaleID);
  }

  return transf;
}
Example #7
0
/** method sets up all internal variables necessary to convert from Event
Workspace to MDEvent workspace
@param WSD         -- the class describing the target MD workspace, sorurce
Event workspace and the transformations, necessary to perform on these
workspaces
@param inWSWrapper -- the class wrapping the target MD workspace
@param ignoreZeros  -- if zero value signals should be rejected
*/
size_t
ConvToMDEventsWS::initialize(const MDWSDescription &WSD,
                             boost::shared_ptr<MDEventWSWrapper> inWSWrapper,
                             bool ignoreZeros) {
  size_t numSpec = ConvToMDBase::initialize(WSD, inWSWrapper, ignoreZeros);

  m_EventWS =
      boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>(m_InWS2D);
  if (!m_EventWS)
    throw(std::logic_error(
        " ConvertToMDEventWS should work with defined event workspace"));

  // Record any special coordinate system known to the description.
  m_coordinateSystem = WSD.getCoordinateSystem();
  return numSpec;
}
Example #8
0
/**
* Create new MD workspace and set up its box controller using algorithm's box
* controllers properties
* @param targWSDescr :: Description of workspace to create
* @param filebackend :: true if the workspace will have a file back end
* @param filename :: file to use for file back end of workspace
* @return :: Shared pointer for the created workspace
*/
API::IMDEventWorkspace_sptr
ConvertToMD::createNewMDWorkspace(const MDWSDescription &targWSDescr,
                                  const bool filebackend,
                                  const std::string &filename) {
  // create new md workspace and set internal shared pointer of m_OutWSWrapper
  // to this workspace
  API::IMDEventWorkspace_sptr spws =
      m_OutWSWrapper->createEmptyMDWS(targWSDescr);
  if (!spws) {
    g_log.error() << "can not create target event workspace with :"
                  << targWSDescr.nDimensions() << " dimensions\n";
    throw(std::invalid_argument("can not create target workspace"));
  }
  // Build up the box controller
  Mantid::API::BoxController_sptr bc =
      m_OutWSWrapper->pWorkspace()->getBoxController();
  // Build up the box controller, using the properties in
  // BoxControllerSettingsAlgorithm
  this->setBoxController(bc, m_InWS2D->getInstrument());
  if (filebackend) {
    setupFileBackend(filename, m_OutWSWrapper->pWorkspace());
  }

  // Check if the user want sto force a top level split or not
  bool topLevelSplittingChecked = this->getProperty("TopLevelSplitting");

  if (topLevelSplittingChecked) {
    // Perform initial split with the forced settings
    setupTopLevelSplitting(bc);
  }

  // split boxes;
  spws->splitBox();

  // Do we split more due to MinRecursionDepth?
  int minDepth = this->getProperty("MinRecursionDepth");
  int maxDepth = this->getProperty("MaxRecursionDepth");
  if (minDepth > maxDepth)
    throw std::invalid_argument(
        "MinRecursionDepth must be >= MaxRecursionDepth ");
  spws->setMinRecursionDepth(size_t(minDepth));

  return spws;
}
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();

}
Example #10
0
void MDEventWSWrapper::createEmptyEventWS(const MDWSDescription &description) {

    boost::shared_ptr<DataObjects::MDEventWorkspace<DataObjects::MDEvent<nd>, nd>>
            ws = boost::shared_ptr<
                 DataObjects::MDEventWorkspace<DataObjects::MDEvent<nd>, nd>>(
                     new DataObjects::MDEventWorkspace<DataObjects::MDEvent<nd>, nd>());

    auto numBins = description.getNBins();
    size_t nBins(10); // HACK. this means we have 10 bins artificially. This can't
    // be right.
    // Give all the dimensions
    for (size_t d = 0; d < nd; d++) {
        if (!numBins.empty())
            nBins = numBins[d];

        Geometry::MDHistoDimension *dim = NULL;
        if (d < 3 && description.isQ3DMode()) {
            // We should have frame and scale information that we can use correctly
            // for our Q dimensions.
            auto mdFrame = description.getFrame(d);

            dim = new Geometry::MDHistoDimension(
                description.getDimNames()[d], description.getDimIDs()[d], *mdFrame,
                Mantid::coord_t(description.getDimMin()[d]),
                Mantid::coord_t(description.getDimMax()[d]), nBins);

        } else {
            Mantid::Geometry::GeneralFrame frame(description.getDimNames()[d],
                                                 description.getDimUnits()[d]);
            dim = new Geometry::MDHistoDimension(
                description.getDimNames()[d], description.getDimIDs()[d], frame,
                Mantid::coord_t(description.getDimMin()[d]),
                Mantid::coord_t(description.getDimMax()[d]), nBins);
        }

        ws->addDimension(Geometry::MDHistoDimension_sptr(dim));
    }
    ws->initialize();

    m_Workspace = ws;
}
Example #11
0
/** Build meaningful dimension names for different conversion modes
 * @param TargWSDescription the class-container to keep the dimension names and
 dimension unints
 * @param FrameID -- the ID describing the target transformation frame (lab,
 sample, hkl)
 * @param ScaleID -- the scale ID which define how the dimensions are scaled

*/
void MDWSTransform::setQ3DDimensionsNames(
    MDWSDescription &TargWSDescription, CnvrtToMD::TargetFrame FrameID,
    CnvrtToMD::CoordScaling ScaleID) const {

  std::vector<Kernel::V3D> dimDirections;
  // set default dimension names:
  std::vector<std::string> dimNames = TargWSDescription.getDimNames();

  // define B-matrix and Lattice parameters to one in case if no OrientedLattice
  // is there
  Kernel::DblMatrix Bm(3, 3, true);
  std::vector<double> LatPar(3, 1);
  if (TargWSDescription.hasLattice()) { // redefine B-matrix and Lattice
                                        // parameters from real oriented lattice
                                        // if there is one
    auto spLatt = TargWSDescription.getLattice();
    Bm = spLatt->getB();
    for (int i = 0; i < 3; i++)
      LatPar[i] = spLatt->a(i);
  }
  if (FrameID == CnvrtToMD::AutoSelect)
    FrameID = findTargetFrame(TargWSDescription);

  switch (FrameID) {
  case (CnvrtToMD::LabFrame): {
    dimNames[0] = "Q_lab_x";
    dimNames[1] = "Q_lab_y";
    dimNames[2] = "Q_lab_z";
    TargWSDescription.setCoordinateSystem(Mantid::Kernel::QLab);
    TargWSDescription.setFrame(Geometry::QLab::QLabName);
    break;
  }
  case (CnvrtToMD::SampleFrame): {
    dimNames[0] = "Q_sample_x";
    dimNames[1] = "Q_sample_y";
    dimNames[2] = "Q_sample_z";
    TargWSDescription.setCoordinateSystem(Mantid::Kernel::QSample);
    TargWSDescription.setFrame(Geometry::QSample::QSampleName);
    break;
  }
  case (CnvrtToMD::HKLFrame): {
    dimNames[0] = "H";
    dimNames[1] = "K";
    dimNames[2] = "L";

    Kernel::MDUnit_uptr mdUnit(new Kernel::InverseAngstromsUnit);
    TargWSDescription.setCoordinateSystem(Mantid::Kernel::HKL);
    TargWSDescription.setFrame(Geometry::HKL::HKLName);
    break;
  }
  default:
    throw(std::invalid_argument(" Unknown or undefined Target Frame ID"));
  }

  dimDirections.resize(3);
  dimDirections[0] = m_UProj;
  dimDirections[1] = m_VProj;
  dimDirections[2] = m_WProj;
  if (ScaleID == OrthogonalHKLScale) {
    std::vector<Kernel::V3D> uv(2);
    uv[0] = m_UProj;
    uv[1] = m_VProj;
    dimDirections = Kernel::V3D::makeVectorsOrthogonal(uv);
  }
  // axis names:
  if ((FrameID == CnvrtToMD::LabFrame) || (FrameID == CnvrtToMD::SampleFrame))
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimName(i, dimNames[i]);
  else
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimName(
          i, MDAlgorithms::makeAxisName(dimDirections[i], dimNames));

  if (ScaleID == NoScaling) {
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimUnit(i, "A^-1");
  }
  if (ScaleID == SingleScale) {
    double dMax(-1.e+32);
    for (int i = 0; i < 3; i++)
      dMax = (dMax > LatPar[i]) ? (dMax) : (LatPar[i]);
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimUnit(
          i, "in " + MDAlgorithms::sprintfd(2 * M_PI / dMax, 1.e-3) + " A^-1");
  }
  if ((ScaleID == OrthogonalHKLScale) || (ScaleID == HKLScale)) {
    // get the length along each of the axes
    std::vector<double> len;
    Kernel::V3D x;
    x = Bm * dimDirections[0];
    len.push_back(2 * M_PI * x.norm());
    x = Bm * dimDirections[1];
    len.push_back(2 * M_PI * x.norm());
    x = Bm * dimDirections[2];
    len.push_back(2 * M_PI * x.norm());
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimUnit(
          i, "in " + MDAlgorithms::sprintfd(len[i], 1.e-3) + " A^-1");
  }
}
Example #12
0
/**
 Method builds transformation Q=R*U*B*W*h where W-transf is W or WB or
 W*Unit*Lattice_param depending on inputs
*/
Kernel::DblMatrix
MDWSTransform::buildQTrahsf(MDWSDescription &TargWSDescription,
                            CnvrtToMD::CoordScaling ScaleID,
                            bool UnitUB) const {
  // implements strategy
  if (!(TargWSDescription.hasLattice() || UnitUB)) {
    throw(std::invalid_argument("this function should be called only on "
                                "workspace with defined oriented lattice"));
  }

  // if u,v us default, Wmat is unit transformation
  Kernel::DblMatrix Wmat(3, 3, true);
  // derive rotation from u0,v0 u0||ki to u,v
  if (!m_isUVdefault) {
    Wmat[0][0] = m_UProj[0];
    Wmat[1][0] = m_UProj[1];
    Wmat[2][0] = m_UProj[2];
    Wmat[0][1] = m_VProj[0];
    Wmat[1][1] = m_VProj[1];
    Wmat[2][1] = m_VProj[2];
    Wmat[0][2] = m_WProj[0];
    Wmat[1][2] = m_WProj[1];
    Wmat[2][2] = m_WProj[2];
  }
  if (ScaleID == OrthogonalHKLScale) {
    std::vector<Kernel::V3D> dim_directions;
    std::vector<Kernel::V3D> uv(2);
    uv[0] = m_UProj;
    uv[1] = m_VProj;
    dim_directions = Kernel::V3D::makeVectorsOrthogonal(uv);
    for (size_t i = 0; i < 3; ++i)
      for (size_t j = 0; j < 3; ++j)
        Wmat[i][j] = dim_directions[j][i];
  }
  // Now define lab frame to target frame transformation
  Kernel::DblMatrix Scale(3, 3, true);
  Kernel::DblMatrix Transf(3, 3, true);
  boost::shared_ptr<Geometry::OrientedLattice> spLatt;
  if (UnitUB)
    spLatt = boost::shared_ptr<Geometry::OrientedLattice>(
        new Geometry::OrientedLattice(1, 1, 1));
  else
    spLatt = TargWSDescription.getLattice();

  switch (ScaleID) {
  case NoScaling: //< momentums in A^-1
  {
    Transf = spLatt->getU();
    break;
  }
  case SingleScale: //< momentums divided by  2*Pi/Lattice -- equivalent to
    // d-spacing in some sense
    {
      double dMax(-1.e+32);
      for (int i = 0; i < 3; i++)
        dMax = (dMax > spLatt->a(i)) ? (dMax) : (spLatt->a(i));
      for (int i = 0; i < 3; i++)
        Scale[i][i] = (2 * M_PI) / dMax;
      Transf = spLatt->getU();
      break;
    }
  case OrthogonalHKLScale: //< each momentum component divided by appropriate
    // lattice parameter; equivalent to hkl for orthogonal
    // axis
    {
      if (spLatt) {
        for (int i = 0; i < 3; i++) {
          Scale[i][i] = (2 * M_PI) / spLatt->a(i);
        }
        Transf = spLatt->getU();
      }
      break;
    }
  case HKLScale: //< non-orthogonal system for non-orthogonal lattice
  {
    if (spLatt)
      Scale = spLatt->getUB() * (2 * M_PI);
    break;
  }

  default:
    throw(std::invalid_argument("unrecognized conversion mode"));
  }
  TargWSDescription.addProperty("W_MATRIX", Wmat.getVector(), true);
  return Transf * Scale * Wmat;
}
Example #13
0
/** The matrix to convert neutron momentums into the target coordinate system */
std::vector<double>
MDWSTransform::getTransfMatrix(MDWSDescription &TargWSDescription,
                               CnvrtToMD::TargetFrame FrameID,
                               CoordScaling &ScaleID) const {

  Kernel::Matrix<double> mat(3, 3, true);

  bool powderMode = TargWSDescription.isPowder();

  bool has_lattice(true);
  if (!TargWSDescription.hasLattice())
    has_lattice = false;

  if (!(powderMode || has_lattice)) {
    std::string inWsName = TargWSDescription.getWSName();
    // notice about 3D case without lattice
    g_Log.notice()
        << "Can not obtain transformation matrix from the input workspace: "
        << inWsName << " as no oriented lattice has been defined. \n"
                       "Will use unit transformation matrix.\n";
  }
  // set the frame ID to the values, requested by properties
  CnvrtToMD::TargetFrame CoordFrameID(FrameID);
  if (FrameID == AutoSelect || powderMode) // if this value is auto-select, find
                                           // appropriate frame from workspace
                                           // properties
    CoordFrameID = findTargetFrame(TargWSDescription);
  else // if not, and specific target frame requested, verify if everything is
       // available on the workspace for this frame
    checkTargetFrame(
        TargWSDescription,
        CoordFrameID); // throw, if the information is not available

  switch (CoordFrameID) {
  case (CnvrtToMD::LabFrame): {
    ScaleID = NoScaling;
    TargWSDescription.m_Wtransf =
        buildQTrahsf(TargWSDescription, ScaleID, true);
    // ignore goniometer
    mat = TargWSDescription.m_Wtransf;
    break;
  }
  case (CnvrtToMD::SampleFrame): {
    ScaleID = NoScaling;
    TargWSDescription.m_Wtransf =
        buildQTrahsf(TargWSDescription, ScaleID, true);
    // Obtain the transformation matrix to Cartesian related to Crystal
    mat = TargWSDescription.getGoniometerMatr() * TargWSDescription.m_Wtransf;
    break;
  }
  case (CnvrtToMD::HKLFrame): {
    TargWSDescription.m_Wtransf =
        buildQTrahsf(TargWSDescription, ScaleID, false);
    // Obtain the transformation matrix to Cartesian related to Crystal
    if (TargWSDescription.hasGoniometer())
      mat = TargWSDescription.getGoniometerMatr() * TargWSDescription.m_Wtransf;
    else
      mat = TargWSDescription.m_Wtransf;

    break;
  }
  default:
    throw(std::invalid_argument(" Unknown or undefined Target Frame ID"));
  }
  //
  // and this is the transformation matrix to notional
  mat.Invert();

  std::vector<double> rotMat = mat.getVector();
  g_Log.debug()
      << " *********** Q-transformation matrix ***********************\n";
  g_Log.debug()
      << "***     *qx         !     *qy         !     *qz           !\n";
  g_Log.debug() << "q1= " << rotMat[0] << " ! " << rotMat[1] << " ! "
                << rotMat[2] << " !\n";
  g_Log.debug() << "q2= " << rotMat[3] << " ! " << rotMat[4] << " ! "
                << rotMat[5] << " !\n";
  g_Log.debug() << "q3= " << rotMat[6] << " ! " << rotMat[7] << " ! "
                << rotMat[8] << " !\n";
  g_Log.debug()
      << " *********** *********************** ***********************\n";
  return rotMat;
}
Example #14
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");
}
/** 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");
}