I’m converting this code to run in ROOT. My first inclination was to use TVector3D, since it also has a rotateUz method like G4ThreeVector (which is a CLHEP::Hep3Vector).

In this new paradigm, what approach is one supposed to use for rotating vectors, rotateUz in particular? I see the ROOT::Math::VectorUtil and ROOT::Math::AxisAngle classes, but I am not facile with vector rotations; I don’t get which methods might correspond to rotateUz (if indeed any of them do).

I saw that. The problem for lazy 'ol me is: TVector3D::RotateUz effectively takes as arguments two vectors, the second of which is a unit vector pointing in the new direction of the z-axis (I think; the documentation is unclear). VectorUtil::RotateZ take as arguments a vector and an angle; that second angle is simply a rotation about the z-axis. I don’t know how to connect one to the other.

No problem; I’m not in a rush. For now, I’ve worked around the problem by copying the TVector3D::RotateUz code into a separate function, using ROOT::Math::XYZVector arguments.

Of course, just to make life interesting, I see that the code for RotateUz in TVector3D and CLHEP::ThreeVector is not the same. If I were more motivated, I’d go through the trig identifies to verify that the methods have identical functionality. Or maybe they don’t…

I am not sure exactly what TVector3::RotateUz does, for CLHEP from the documentation I see that is equivalent first to a rotation along the Y axis of an angle theta followed by a rotation along the Z axis by an angle phi.
Given the direction (u1,u2,u3), the angle theta should be such theta = acos(u3) and phi = atan(u2/u1). You can then use the ROOT::Math::RotationZYX class using an angle 0 for psi (rotation along X)

In the end, I chickened out and went with TVector3D. There were other functions like “orthogonal” that were just not clear in the XYZVector / VecUtil mechanism. My poor python-addled brain couldn’t figure it all out.