human
Solve the following python programming problem given the following code:
# Convolution in theta and phi representation
def convolve(x,func1,func2):
    #integral in angle phi
    def fun2(x2,xl2, func):
        phi  = np.linspace(0,2*np.pi,200)
        ret2 = np.zeros(xl2.shape)
        for i in range(len(xl2)):
            ret2[i] = np.trapz(func(np.sqrt(xl2[i]**2 + x2**2 - 2*x2*xl2[i]*np.cos(phi))),x=phi)
        return ret2
    
    #Integral in theta'
    xl  = x.copy()
    ret = np.zeros(x.shape)
    for i in range(len(x)):
        ret[i] = np.trapz(xl*func1(xl)*fun2(x[i],xl,func2),x=xl)
    return ret
Given the above code, generate some markdown instructions for it.
assistant
#Here is the Python code you requested.

Double Layer Scattering
According to the paper, the angular distribution of a beam with initial angular distribution $h_0(\theta)$ after passing througth the window is given by the convolution:
\begin{equation}
h_1(\theta,\lambda) = \int_0^\infty \text{d}\theta'\, \theta'h_0(\theta')\int_0^{2\pi} \text{d}\phi \, f(\theta'',\lambda) 
\quad \text{with} \quad \theta'' = \sqrt{\theta'^2 + \theta^2 - 2\theta'\theta\cos(\phi)}
\end{equation}
where $\theta'$ is the incoming azimuthal angle, $\theta''$ is the scattered azimuthal angle, $\phi$ is the difference between the initial and scattered polar angles and $\theta$ is the final angle.
Analogously, to obtain the double layer scattering distribution for a parallel beam, we must convolve:
\begin{equation}
f(\theta) = \int_0^\infty \text{d}\theta'\, \theta'f_1(\theta',\lambda_1)\int_0^{2\pi} \text{d}\phi \, f_2(\theta'',\lambda_2).
\end{equation}
Lets define this convolution: