Repository: cctbx/cctbx_project (language: python)

Issue:
nanoBragg performance tuning



Discussion / hints:
@bkpoon Can you look at the new function in scitbx/math?
/azp run XFEL CI
<samp>
Azure Pipelines successfully started running 1 pipeline(s).<br>

</samp>
Rebased on master to get the xfel psana fix in 89fa3008
Closing this since @nksauter is moving the code into master via individual commits 8e12c5ca6, 93f659c5, ee1208ee, and a couple more to come

Fix patch:
diff --git a/scitbx/math/boost_python/r3_rotation.cpp b/scitbx/math/boost_python/r3_rotation.cpp
index e9e43b19a7..6a806b1d5c 100644
--- a/scitbx/math/boost_python/r3_rotation.cpp
+++ b/scitbx/math/boost_python/r3_rotation.cpp
@@ -42,6 +42,17 @@ namespace boost_python {
         arg("angle"),
         arg("deg")=false,
         arg("min_axis_length")=1e-15));
+    def("r3_rotation_axis_and_angle_as_matrix",
+      (af::shared<mat3<double> >(*)(
+        af::shared<vec3<double> > const&,
+        af::shared<double> const&,
+        bool,
+        double const&)
+      ) r3_rotation::axis_and_angle_as_matrix, (
+        arg("axes"),
+        arg("angle"),
+        arg("deg")=false,
+        arg("min_axis_length")=1e-15));
 
     def("r3_rotation_axis_and_angle_as_unit_quaternion",
       (af::tiny<double, 4>(*)(
diff --git a/scitbx/math/r3_rotation.h b/scitbx/math/r3_rotation.h
index 047bea795f..a642b80a03 100644
--- a/scitbx/math/r3_rotation.h
+++ b/scitbx/math/r3_rotation.h
@@ -4,6 +4,7 @@
 #include <scitbx/matrix/row_echelon_full_pivoting_small.h>
 #include <scitbx/mat3.h>
 #include <scitbx/constants.h>
+#include <scitbx/array_family/shared.h>
 
 namespace scitbx { namespace math {
 
@@ -68,6 +69,26 @@ namespace scitbx { namespace math {
        c + w*woc);
   }
 
+  template <typename FloatType>
+  af::shared<mat3<FloatType> >
+  axis_and_angle_as_matrix(
+    af::shared<vec3<FloatType> > const& axes,
+    af::shared<FloatType> const& angles,
+    bool deg=false,
+    FloatType const& min_axis_length=1.e-15)
+  {
+    SCITBX_ASSERT(axes.size() == angles.size());
+    af::shared<mat3<FloatType> > result;
+    result.reserve(axes.size());
+    for (size_t i=0; i<axes.size(); ++i) {
+      result.push_back(
+        axis_and_angle_as_matrix(axes[i], angles[i], deg, min_axis_length)
+      );
+    }
+    return result;
+  }
+
+
   //! Quaternion product.
   /*  Implement this as a standalone function as there is no quaternion class
    */


Test patch:
diff --git a/scitbx/math/tests/tst_r3_rotation.py b/scitbx/math/tests/tst_r3_rotation.py
index 068ed26950..02128f7bfc 100644
--- a/scitbx/math/tests/tst_r3_rotation.py
+++ b/scitbx/math/tests/tst_r3_rotation.py
@@ -38,6 +38,9 @@ def exercise_axis_and_angle(
     8.7903631196301042, -4.3951815598150503, 0,
     0, 7.6126777700894994, 0,
     0, 0, 14.943617303371177])
+  rot_axes = []
+  rot_angles = []
+  rot_matrices = []
   for u in range(-axis_range, axis_range+1):
     for v in range(-axis_range, axis_range+1):
       for w in range(axis_range+1):
@@ -46,6 +49,9 @@ def exercise_axis_and_angle(
             try:
               r = scitbx.math.r3_rotation_axis_and_angle_as_matrix(
                 axis=axis, angle=angle, deg=True)
+              rot_axes.append(axis)
+              rot_angles.append(angle)
+              rot_matrices.append(r)
             except RuntimeError:
               assert axis == (0,0,0)
               try:
@@ -105,6 +111,10 @@ def exercise_axis_and_angle(
                       min_axis_length=1+1.e-5)
                   except RuntimeError: pass
                   else: raise Exception_expected
+  rot_matrices_vectorized = scitbx.math.r3_rotation_axis_and_angle_as_matrix(
+      rot_axes, rot_angles, deg=True)
+  for a,b in zip(rot_matrices, rot_matrices_vectorized):
+    assert a==b
   #
   for i_trial in range(100):
     r = flex.random_double_r3_rotation_matrix()