Background:
Below is a calculation of the diffracted wavevector $\mathbf{k_1}$ from an initial wavevector $\mathbf{k_0} = -k_0 \mathbf{\hat{z}}$ incident on a planar surface with normal $\mathbf{\hat{n}}$, having a periodic surface grating of reciprocal vector $\mathbf{g}$, where $\mathbf{g} \perp \mathbf{n}$.
A physical example might be holding a DVD face-up but slightly tilted, and pointing a laser pointer straight down at it. Then $k_0 = 2 \pi / \lambda$ and $g = 2 \pi / d$ where $\lambda$ is the laser pointer wavelength and $d$ is the local spacing of the lines on the DVD. The direction of $\mathbf{g}$ will be the local perpendicular of the grating lines.
Conservation of energy gives $k_1 = k_0$, and the direction of $\mathbf{k_1}$ tells us where the diffracted spot hits the ceiling above our heads.
Problem:
My application is electron diffraction. I will vary the energy and therefore $k_0$, and record the resulting $\mathbf{k_1}$ directions.
I want to solve the inverse problem; given a set of $k_0$ magnitudes and $\mathbf{k_1}$ directions, solve for $\mathbf{\hat{n}}$ and $\mathbf{g}$.
I suspect some fitting will be required, I plan to over-specify the problem by making many measurements.
As far as I can tell, it's a search of "only" four-dimensional space; the tip of $\mathbf{n}$ lies on the unit sphere and $\mathbf{g}$ lies in the plane perpendicular to $\mathbf{n}$. So I could just do a 4D grid to make sure I avoid local minima then use a standard minimization.
But I wonder, is there some way to invert this problem and back-calculate $\mathbf{n}$ and $\mathbf{g}$ if I didn't over-specify the problem?
$$\mathbf{k_0} = -k_0 \mathbf{\hat{z}}$$
$$\mathbf{k_{0, perp}} = -k_0 \ (\mathbf{\hat{z}} \cdot \mathbf{\hat{n}}) \ \mathbf{\hat{n}}$$
$$\mathbf{k_{0, para}} = k_0 \ (\mathbf{\hat{n}} \ (\mathbf{\hat{z}} \cdot \mathbf{\hat{n}}) - \mathbf{\hat{z}}) + \mathbf{g}$$
$$\mathbf{k_{1, perp}} = \sqrt{k_0^2 - k^2_{1, para}} \ \mathbf{\hat{n}}$$
$$\mathbf{k_1} = \mathbf{k_{0, para}} + \mathbf{k_{1, perp}} $$
in Python: https://pastebin.com/b3c86JJJ