/*******************************************************************************
*
* McStas, neutron ray-tracing package
*         Copyright (C) 1997-2010, All rights reserved
*         Risoe National Laboratory, Roskilde, Denmark
*         Institut Laue Langevin, Grenoble, France
*
* Component: Radial_div
*
* %I
* Modified by: Kaspar Hewitt Klenø from Hdiv_monitor (1.12b), Jan 2011.
*
*
* A radial divergence sensitive monitor with wavelength restrictions.
*
* %D
* A radial divergence sensitive monitor with wavelength restrictions. The counts are distributed in
* n pixels.
*
* Example:
*
*%P
* INPUT PARAMETERS:
*
* xmin:            Lower x bound of detector opening (m)
* xmax:            Upper x bound of detector opening (m)
* ymin:            Lower y bound of detector opening (m)
* ymax:            Upper y bound of detector opening (m)
* xwidth:          Width/diameter of detector (x). Overrides xmin,xmax. (m)
* yheight:         Height of detector (y). Overrides ymin,ymax. (m)
* ndiv:            Number of pixel rows (1)
* maxdiv_r:        Maximal radial divergence detected (degrees)
* Lmin:            Minimum wavelength detected (AA)
* Lmax:            Maximum wavelength detected (AA)
* filename:        Name of file in which to store the detector image (text)
* restore_neutron: If set, the monitor does not influence the neutron state (1)
*
* OUTPUT PARAMETERS:
*
* Div_N:           Array of neutron counts
* Div_p:           Array of neutron weight counts
* Div_p2:          Array of second moments
*
*%E
*******************************************************************************/


DEFINE COMPONENT Radial_div

DEFINITION PARAMETERS ()

SETTING PARAMETERS (ndiv=20, restore_neutron=0, string filename, xmin=0, xmax=0, ymin=0, ymax=0, xwidth=0, yheight=0, maxdiv_r=2, Lmin, Lmax)

OUTPUT PARAMETERS ()

STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p)

POLARISATION PARAMETERS (sx,sy,sz)

DECLARE
%{
  DArray1d Div_N;
  DArray1d Div_p;
  DArray1d Div_p2;
%}

INITIALIZE
%{
  int i;

  if (xwidth  > 0) { xmax = xwidth/2;  xmin = -xmax; }
  if (yheight > 0) { ymax = yheight/2; ymin = -ymax; }

  if ((xmin >= xmax) || (ymin >= ymax)) {
          printf("Div1dLam: %s: Null detection area !\n"
                 "ERROR         (xwidth,yheight,xmin,xmax,ymin,ymax). Exiting",
         NAME_CURRENT_COMP);
    exit(0);
  }

  Div_N = create_darr1d(ndiv);
  Div_p = create_darr1d(ndiv);
  Div_p2 = create_darr1d(ndiv);

  for (i=0; i<ndiv; i++) {
/*       printf("radial_div_monitor: %d\n",i); */
    Div_N[i] = 0;
    Div_p[i] = 0;
    Div_p2[i] = 0;
   }
/*     printf("%d %d %d\n",i,ndiv,h_maxdiv); */
%}

TRACE
%{
  int i;
  double h_div, v_div, lambda, r_div;
lambda = (2*PI/V2K)/sqrt(vx*vx + vy*vy + vz*vz);

  PROP_Z0;
  if (x>xmin && x<xmax && y>ymin && y<ymax &&
      lambda > Lmin && lambda < Lmax)
  {
    h_div = RAD2DEG*atan2(vx,vz);
    v_div = RAD2DEG*atan2(vy,vz);
    r_div=sqrt(h_div*h_div+v_div*v_div);
    if (r_div < maxdiv_r)
    {
      i = floor((r_div)*ndiv/(maxdiv_r));
      Div_N[i]++;
      Div_p[i] += p;
      Div_p2[i] += p*p;
      SCATTER;
    }
  }
  if (restore_neutron) {
    RESTORE_NEUTRON(INDEX_CURRENT_COMP, x, y, z, vx, vy, vz, t, sx, sy, sz, p);
  }
%}

SAVE
%{
  DETECTOR_OUT_1D(
      "radial_div",
      "radial divergence [deg]",
      "Intensity",
      "divergence", 0, maxdiv_r, ndiv,
      &Div_N[0],&Div_p[0],&Div_p2[0],
      filename);
%}

FINALLY
%{
  destroy_darr1d(Div_N);
  destroy_darr1d(Div_p);
  destroy_darr1d(Div_p2);
%}

MCDISPLAY
%{
  multiline(5, (double)xmin, (double)ymin, 0.0,
               (double)xmax, (double)ymin, 0.0,
               (double)xmax, (double)ymax, 0.0,
               (double)xmin, (double)ymax, 0.0,
               (double)xmin, (double)ymin, 0.0);
%}


END
