Goniometer.h 4.3 KB
Newer Older
1
2
3
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2007 ISIS Rutherford Appleton Laboratory UKRI,
4
5
//   NScD Oak Ridge National Laboratory, European Spallation Source,
//   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6
// SPDX - License - Identifier: GPL - 3.0 +
7
#pragma once
8

LamarMoore's avatar
LamarMoore committed
9
#include "MantidGeometry/Crystal/AngleUnits.h"
10
11
#include "MantidKernel/Matrix.h"
#include "MantidKernel/V3D.h"
12
#include <nexus/NeXusFile.hpp>
LamarMoore's avatar
LamarMoore committed
13
#include <string>
David Fairbrother's avatar
David Fairbrother committed
14
#include <utility>
15

16
17
namespace Mantid {
namespace Geometry {
18
19

/**
20
21
22
23
24
25
  Class to represent a particular goniometer setting, which is described by the
  rotation matrix.
  For a particular sample environment, it stores the rotation motors (names,
  angles, ...). If copied from
  one workspace to another, one might need to just change the angle value for
  one particular axis.
26
27
28
29
30
31

  @class Goniometer
  @author Andrei Savici, SNS, ORNL
  @date 04/13/2011
 */

32
33
34
35
36
37
38
39
40
41
42
enum RotationSense {
  CW = -1, /// Clockwise rotation
  CCW = 1
}; /// Counter clockwise rotation

/// Structure containing a rotation axis: name, direction, angle, sense
struct GoniometerAxis {
  std::string name;         /// GoniometerAxis name
  Kernel::V3D rotationaxis; /// GoniometerAxis direction
  double angle;             /// Rotation angle
  int sense;                /// Rotation sense (1 for CCW, -1 for CW)
43
  int angleunit;            /// angle units are angDegrees or angRadians (see AngleUnits.h)
44
  /// Constructor
Peterson, Peter's avatar
Peterson, Peter committed
45
46
  GoniometerAxis(std::string initname, const Kernel::V3D &initrotationaxis, double initangle, int initsense,
                 int initangleunit)
47
48
49
      : name(std::move(initname)), rotationaxis(initrotationaxis), angle(initangle), sense(initsense),
        angleunit(initangleunit) {}
  GoniometerAxis() : name(""), rotationaxis(), angle(0.), sense(0), angleunit(0) {}
50
51
52
53
54
55
56
57
58
59

  void saveNexus(::NeXus::File *file, const std::string &group) const;
  void loadNexus(::NeXus::File *file, const std::string &group);
};

class MANTID_GEOMETRY_DLL Goniometer {
public:
  // Default constructor
  Goniometer();
  // Constructor from a rotation matrix
David Fairbrother's avatar
David Fairbrother committed
60
  Goniometer(const Kernel::DblMatrix &rot);
61
  // Default destructor
62
  virtual ~Goniometer() = default;
63
64
65
66
67
68
69
  // Return rotation matrix
  const Kernel::DblMatrix &getR() const;
  // Set the rotation matrix
  void setR(Kernel::DblMatrix rot);
  // Return information about axes
  std::string axesInfo();
  // Add axis to goniometer
70
  void pushAxis(const std::string &name, double axisx, double axisy, double axisz, double angle = 0., int sense = CCW,
David Fairbrother's avatar
David Fairbrother committed
71
                int angUnit = angDegrees);
72
73
  // Set rotation angle for an axis in the units the angle is set (default --
  // degrees)
David Fairbrother's avatar
David Fairbrother committed
74
  void setRotationAngle(const std::string &name, double value);
75
76
77
  // Set rotation angle for an axis in the units the angle is set (default --
  // degrees)
  void setRotationAngle(size_t axisnumber, double value);
78
79
  // Calculate goniometer for rotation around y-axis for constant wavelength
  // from Q Sample
80
  void calcFromQSampleAndWavelength(const Mantid::Kernel::V3D &Q, double wavelength, bool flip_x = false,
81
                                    bool inner = false);
82
83
84
  // Get axis object
  const GoniometerAxis &getAxis(size_t axisnumber) const;
  // Get axis object
David Fairbrother's avatar
David Fairbrother committed
85
  const GoniometerAxis &getAxis(const std::string &axisname) const;
86
87
88
89
90
  // Return the number of axes
  size_t getNumberAxes() const;
  // Make a default universal goniometer
  void makeUniversalGoniometer();
  // Return Euler angles acording to a convention
David Fairbrother's avatar
David Fairbrother committed
91
  std::vector<double> getEulerAngles(const std::string &convention = "YZX");
92
93
94
95
96

  void saveNexus(::NeXus::File *file, const std::string &group) const;
  void loadNexus(::NeXus::File *file, const std::string &group);
  /// the method reports if the goniometer was defined with some parameters
  bool isDefined() const;
97
98
  bool operator==(const Goniometer &other) const;
  bool operator!=(const Goniometer &other) const;
99
100
101
102
103
104
105
106
107
108
109
110

private:
  /// Global rotation matrix of the goniometer
  Kernel::DblMatrix R;
  /// Motors vector contains GoniometerAxis objects, the last one is the closest
  /// to the sample
  std::vector<GoniometerAxis> motors;
  /// Flag to specify if the goniometer is initialized from a rotation matrix
  bool initFromR;
  /// Private function to recalculate R when setRotationAngle is called
  void recalculateR();
};
111
112
} // namespace Geometry
} // namespace Mantid