/*******************************************************************************
*
* McStas, neutron ray-tracing package
*         Copyright 1997-2002, All rights reserved
*         Risoe National Laboratory, Roskilde, Denmark
*         Institut Laue Langevin, Grenoble, France
*
* Component: NPI_tof_theta_monitor
*
* %I
* Written by:  Kim Lefmann
* Date: October 2000
* Version: $Revision: 1.1 $
* Origin: Risoe
* Release: McStas 1.6
* Modified by: Kim Lefmann, October 9, 2001
* Modified by: J Navrátil (NPI Řež), December 10, 2015
*
* Cylindrical (2pi) PSD Time-of-flight monitor.
* 
* %D
* Derived from TOF_cylPSD_monitor.
* Code is extended by the option allowing to define range of scattering angles, therefore creating only a part of the cylinder surface.
* The plot is transposed when compared to TOF_cylPSD_monitor: scattering angles are on the horizontal axis.
*
*
* Example:	TOF_cylPSD_monitor_NPI(nt = 1024, nphi = 960, filename = "Output.dat",
*			radius = 2, yheight = 1.0, tmin = 3e4, tmax = 12e4, amin = 75, amax = 105, restore_neutron = 1)
*
* %P
* INPUT PARAMETERS:
*
* Inherited from NPI_tof_theta_monitor:
* radius:   Cylinder radius (m)
* yheight:  Cylinder height (m)
* nt:       Number of time bins (1)
* tmin:     Beginning of time window (mu-s)
* tmax:     End of time window (mu-s)
* nphi:     Number of angular bins (deg)
* amin:		minimum angle to detect (deg)
* amax:		maximum angle to detect (deg)
* 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)
*
* Newly added
* amin:	[deg]	minimum of scattering angle to be detected
* amax: [deg]	maximum of scattering angle to be detected
*
* OUTPUT PARAMETERS:
*
* TOF_N:    Array of neutron counts
* TOF_p:    Array of neutron weight counts
* TOF_p2:   Array of second moments
*
* %E
*******************************************************************************/

DEFINE COMPONENT NPI_tof_theta_monitor
DEFINITION PARAMETERS ()
SETTING PARAMETERS (string filename=0, radius=1, yheight=0.3, tmin, tmax, amin, amax, restore_neutron=1, verbose=0, int nt=128, int na=90)
OUTPUT PARAMETERS ()
/* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */ 
SHARE
  %{

  %}
DECLARE
  %{
    DArray2d TOF_N;  
    DArray2d TOF_p;  
    DArray2d TOF_p2; 
    double th2_min;
    double th2_max;
    double dth;
    double dtof;
    double tt_0;
    double tt_1;
  %}
INITIALIZE
  %{	
    th2_min = amin*DEG2RAD;
    th2_max = amax*DEG2RAD;
    dth=(th2_max-th2_min)/na;
    tt_0=tmin*1e-6;
    tt_1=tmax*1e-6;
    dtof=(tt_1-tt_0)/nt;
    
    TOF_N = create_darr2d(na, nt);
    TOF_p = create_darr2d(na, nt);
    TOF_p2 = create_darr2d(na, nt);
    
    if (verbose) {
      printf("%s: range 2theta=(%g,%g), time(%g,%g)\n",NAME_CURRENT_COMP,amin,amax,tmin/1000,tmax/1000);
    }

    // Use instance name for monitor output if no input was given
    if (!strcmp(filename,"\0")) sprintf(filename,"%s",NAME_CURRENT_COMP);
  %}
TRACE
  %{
    int i,j;
    double t0,t1,theta2;
    double cos2;
    int cross=cylinder_intersect(&t0, &t1, x, y, z, vx, vy, vz, radius, yheight);
    
    /* don't allow intersections with top/bottom cylinder walls
       only neutrons from inside are allowed 
    */
    if ( (cross!=1) ||  (t0>0) || (t1<0) ) {
      p=0;
    } else {
      PROP_DT(t1);
      
      /* Calculate pixel */
      if (fabs(y)<(0.5*yheight)) {
	cos2=z/sqrt(radius*radius+y*y);
	theta2=acos(cos2);
	if (theta2>th2_min && theta2< th2_max) {
	  i = (int)floor((theta2-th2_min)/dth+0.5);
	  j = (int)floor((t-tt_0)/dtof+0.5);
	  if ( j>=0 && j<nt && i>=0 && i<na ) {
	    double p2=p*p;
	    #pragma acc atomic
	    TOF_N[i][j] = TOF_N[i][j] + 1;
	    #pragma acc atomic
	    TOF_p[i][j] = TOF_p[i][j] + p;
	    #pragma acc atomic
	    TOF_p2[i][j] = TOF_p2[i][j] + p2;
	  } else {
	  }
	}
      }
    }
    if (restore_neutron) {
      RESTORE_NEUTRON(INDEX_CURRENT_COMP, x, y, z, vx, vy, vz, t, sx, sy, sz, p);
    }
  %}
SAVE
  %{
    DETECTOR_OUT_2D(
        "Cylindrical monitor ToF x 2theta",
        "Scattering angle [deg]",
	"Time-of-flight [\\gms]",
        amin, amax, tmin, tmax, 
        na, nt,
        &TOF_N[0][0],&TOF_p[0][0],&TOF_p2[0][0],
        filename);
  %}

FINALLY
  %{
  destroy_darr2d(TOF_N);
  destroy_darr2d(TOF_p);
  destroy_darr2d(TOF_p2);
  %}

MCDISPLAY
%{
  magnify("y");
  circle("xz", 0,0,0,radius);
%}

END



















































