/************************************************ * * SANS instrument to be installed at ISIS-1 and ISIS-2 * * written by K. Lieutenant, Jul 2005 * * %Parameters * SRC : [-] target station (ISIS1, ISIS2) * LMBD_MIN : [Ang] min. wavelength, for which the choppers are set * SAMPLE : [-] defines the sample file * Q_BINS : [-] number of Q bins * * not used * D_MIN : [Ang] minimal d-spacing value, D_max = D_min + 2.0 * ***************************************************/ DEFINE INSTRUMENT SANS(string SRC="ISIS1", LMBD_MIN=0.2, string SAMPLE="NAC.laz", int Q_BINS=500) DECLARE %{ #define ISIS_1 11 #define ISIS_2 12 #define L2V 3956.036 #define fmt_laue {1,2,3,4,5,0,0,0} %include "monitor_nd-lib" MONND_DECLARE(Detector_d_spc); // will monitor d-spacing in MyMonitor MONND_DECLARE(Detector_Mtrns); // will monitor Q-values in MyMonitor double Min(double value1, double value2) { if(value1 < value2) return value1 ; else return value2 ; } double Max(double value1, double value2) { if(value1 > value2) return value1 ; else return value2 ; } short eSource, /* enum for source */ det_h_bins, /* number of detector bins in horizontal */ det_w_bins; /* and vertical direction */ double freq, /* repetition rate of the source [Hz] */ omega, /* 2*pi*freq [rad/s]*/ period, /* time between 2 pulses [s] */ pulse_len, /* pulse length accepted by choppers[s] */ total_len, /* total length of instrument [m] */ src_width, /* moderator width [m] */ src_height, /* moderator height [m] */ lmbd_av, /* average wavelength [Ang] */ speed_av, /* corresponding speed [m/s] */ Lmin, Lmax, /* min. and max. wavelength [Ang] */ Emin, Emax, /* min. and max. energy [meV] */ chop_rad, /* dist. between axle & wnd. centre [m] */ chp1_dist, /* distance source - chopper 1 [m] */ chp2_dist, /* distance source - chopper 2 [m] */ chp1_angle, /* window width of chopper 1 [deg] */ chp2_angle, /* window width of chopper 2 [deg] */ chp1_width, /* corr. window widths of the choppers */ chp2_width, /* that give the wanted widths in deg */ chp1_time, /* time offsets */ chp2_time, /* for the right phases */ chp1_pha, /* angular offsets */ chp2_pha, /* for the right phases */ mon_width, /* width of the monitors [m] */ mon_height, /* heigth of the monitors [m] */ mon0_dist, /* position of source monitor [m] */ mon1_dist, /* distance source - monitor 1 [m] */ mon2_dist, /* distance source - monitor 2 [m] */ mon3_dist, /* distance source - monitor 3 [m] */ mon4_dist, /* distance source - monitor 4 [m] */ slit_width, /* width of slits 1 - 5 [m] */ slit_height, /* heigth of slits 1 - 5 [m] */ slit1_dist, /* distance source - slit 1 [m] */ slit2_dist, /* distance source - slit 2 [m] */ slit3_dist, /* distance source - slit 3 [m] */ slit4_dist, /* distance source - slit 4 [m] */ slit5_dist, /* distance source - slit 5 [m] */ scrp_dist, /* distance source - beam scraper [m] */ scrp_rad, /* radius of scraper [m] */ smpl_dist, /* distance source - sample [m] */ smpl_diam, /* radius of sample [m] */ smpl_height, /* height of sample [m] */ stop_dist, /* distance source - beamstop [m] */ stop_rad, /* radius of beamstop [m] */ detect_min, /* minimal detection angle [deg] */ detect_max, /* maximal detection angle [deg] */ det_rad, /* radius of detector [m] */ det_vpos, /* vert. pos. allowing for gravity [m] */ two_theta, /* scattering angle [rad] */ Tp_anf, /* beginning of pulse [s] */ Tp_end, /* end of pulse [s] */ Tp_cntr, /* centre of pulse [s] */ v, /* ratio: (dist. WB-chop - det) / (dist src - WB chop) */ T_hs, /* half-shadow time [s] */ v_max_ctr, /* max. speed for centre of pulse [m/s] */ v_min, v_max,/* min. and max. speed by choppers [m/s] */ Tar_min, /* min. and max. arrival time [s] */ Tar_max, Tev_min, /* min. and max. evaluation time [s] */ Tev_max, LCmin, LCmax,/* wavelength range by choppers [Ang] */ Gv = 0.00, /* gravitation [m/s/s]*/ TMmin,TMmax, /* limits of time (monitor) range [s] */ LMmin,LMmax; /* limits of lambda (monitor) range[Ang] */ char sSource[11], /* name of the source */ sMod [11], /* name of the moderator */ sOptL [80], /* String def. lambda-monitor options */ sOptLrd[80], /* String def. lambda-monitor options for circular disk */ sOptT [80], /* String def. time-monitor options */ sOptEva[80], /* String def. tof-monitor at detector options */ sOptAng[99], /* String defining scat.angle detector options */ sOptDsp[99], /* String defining d-spacing detector options */ sOptQ [99], /* String defining momentum transfer detector options */ sOptPSD[99], /* String defining PSD detector options */ sSampleFile[80]; /* file containing description of powder sample */ %} INITIALIZE %{ MONND_USER_TITLE(Detector_d_spc, 1, "d-spacing"); MONND_USER_TITLE(Detector_Mtrns, 1, "Q"); strcpy (sSource, SRC); sprintf(sSampleFile, "%s", SAMPLE); if ( strcmp(sSource, "ISIS1")==0 || strcmp(sSource, "ISIS-1")==0 || strcmp(sSource, "isis1")==0 || strcmp(sSource, "isis-1")==0) { eSource= ISIS_1; strcpy(sMod, "gem"); freq = 50.0; pulse_len = 0.0002; } else if ( strcmp(sSource, "ISIS2")==0 || strcmp(sSource, "ISIS-2")==0 || strcmp(sSource, "isis2")==0 || strcmp(sSource, "isis-2")==0) { eSource= ISIS_2; strcpy(sMod, "groove"); freq = 10.0; pulse_len = 0.001; } else { fprintf(stderr, "Source unknown, instrument supports only SNS, ISIS1 or ISIS2"); } /* source and guide system */ /* ----------------------- */ omega = 2.0*PI*freq; period = 1.0/freq; src_width = -1.0; // 0.084; gde_width + gd1_dist*tan(max_div_h*DEG2RAD); src_height = -1.0; // 0.090; gde_height + gd1_dist*tan(max_div_v*DEG2RAD); /* chopper system */ /* -------------- */ chop_rad = 0.25; chp1_dist = 6.50; chp2_dist = 9.75; chp1_angle = 112.0; chp2_angle = 150.0; chp1_width = 2.0*chop_rad*tan(DEG2RAD*chp1_angle/2.0); chp2_width = 2.0*chop_rad*tan(DEG2RAD*chp2_angle/2.0); /* sample and detector */ /* ------------------- */ smpl_dist = 17.000; smpl_diam = 0.010; smpl_height = 0.005; det_rad = 1.400; total_len = smpl_dist + det_rad; detect_min = 5.32; detect_max = 171.40; stop_dist = 20.15; stop_rad = (stop_dist - smpl_dist)*sin(DEG2RAD*detect_min); /* apertures and monitors */ /* ---------------------- */ slit_width = 0.020; slit_height = 0.040; scrp_rad = smpl_diam/2.0; mon_width = 0.100; mon_height = 0.100; slit1_dist = 6.352; slit2_dist = 8.145; slit3_dist = 10.265; slit4_dist = 12.675; slit5_dist = 15.350; scrp_dist = 16.544; mon0_dist = 0.001; mon1_dist = 6.220; mon2_dist = 10.147; mon3_dist = 15.535; mon4_dist = 20.145; /* wavelength range and evaluation time */ Tp_anf = 0.0; if (LMBD_MIN == 0) { Tp_end = 0.0; Tp_cntr = 0.0; chp1_time = 0.019302; chp2_time = 0.019493; v_min = chp2_dist / ((chp2_time-0.020) + 0.5*period*chp2_angle/360.0 - Tp_anf); v_max = L2V/0.01; speed_av = 2.0*v_min; } else { Tp_end = pulse_len; Tp_cntr = 0.5*(Tp_end + Tp_anf); v_max_ctr = L2V/LMBD_MIN; chp2_time = chp2_dist / v_max_ctr + 0.5*period * chp2_angle/360.0 + Tp_cntr; speed_av = chp2_dist / (chp2_time - Tp_cntr); chp1_time = chp1_dist / speed_av + Tp_cntr; v_min = chp2_dist / (chp2_time + 0.5*period*chp2_angle/360.0 - Tp_anf); v_max = chp2_dist / (chp2_time - 0.5*period*chp2_angle/360.0 - Tp_end); } chp1_pha= 360.0*chp1_time/period; chp2_pha= 360.0*chp2_time/period; v = (total_len - chp2_dist) / chp2_dist; T_hs = 2*asin(0.5*slit_width/chop_rad)/omega; Tar_min = total_len/v_max + Tp_end; Tar_max = total_len/v_min + Tp_anf; if (LMBD_MIN == 0) Tev_min = Max(Tar_min, Tar_max - period); else Tev_min = Max(Tar_min, Tar_max - period) + v*T_hs; Tev_max = Min(Tar_max, Tar_min + period) - v*T_hs; LCmin = L2V * (Tev_min - Tp_cntr) / total_len; LCmax = L2V * (Tev_max - Tp_cntr) / total_len; Lmin = Max(0.1*floor(10.0*L2V/v_max),0.01); Lmax = 0.1*ceil (10.0*L2V/v_min); Emin = VS2E*pow(L2V/Lmax,2); Emax = VS2E*pow(L2V/Lmin,2); /* monitors */ LMmin = Max(Lmin - 0.1, 0.0); LMmax = Lmax + 0.1; TMmin = 0.000; TMmax = 1.0/freq; sprintf(sOptL , "lambda limits=[%f,%f] bins=100", LMmin, LMmax); sprintf(sOptLrd, "disk, lambda limits=[%f,%f] bins=100", LMmin, LMmax); sprintf(sOptT, "time limits=[%f,%f] bins=100", TMmin, TMmax); sprintf(sOptEva, "sphere, time limits=[%f,%f] bins=100, exclusive", Tev_min, Tev_max); sprintf(sOptPSD ,"sphere, x limits=[%f,%f] bins=100, y limits=[%f,%f] bins=100", -det_rad-0.1, det_rad+0.1, -det_rad-0.1, det_rad+0.1); sprintf(sOptAng ,"sphere, phi limits=[%f,%f] bins=%d, exclusive", detect_min, detect_max, (int)(detect_max-detect_min)); sprintf(sOptDsp ,"sphere, user1 limits=[0.0,8.0] bins=%d", Q_BINS); sprintf(sOptQ ,"sphere, user2 limits=[0.0,10.0] bins=%d", Q_BINS); printf("\nDiffractometer at %s\n", sSource); printf("--------------------------\n"); printf("2*pi*freq : %11.4f rad/s \n", omega); printf("time between 2 pulses : %11.4f s \n", period); printf("pulse (beginning, centre, end) : %11.4f s, %10.4f s, %10.4f s \n", Tp_anf, Tp_cntr, Tp_end); printf("gravitation used : %11.4f m/s/s \n", Gv); printf("wavelength range : %11.4f - %10.4f Ang \n", Lmin, Lmax); printf("energy range : %11.4f - %10.4f meV \n", Emin, Emax); printf("average speed : %11.4f m/s \n", speed_av); printf("dist. between axle & wnd centre: %11.4f m \n", chop_rad); printf("chopper 1 (dist, width, time) : %11.4f m, %10.4f deg, %10.4f m, %10.4f ms,%9.4f deg\n", chp1_dist, chp1_angle, chp1_width, 1000.0*chp1_time, chp1_pha); printf("chopper 2 (dist, width, time) : %11.4f m, %10.4f deg, %10.4f m, %10.4f ms,%9.4f deg\n", chp2_dist, chp2_angle, chp2_width, 1000.0*chp2_time, chp2_pha); printf("monitor distances : %11.4f m, %10.4f m, %10.4f m, %10.4f m \n", mon1_dist, mon2_dist, mon3_dist, mon4_dist); printf("aperture distances : %11.4f m, %10.4f m, %10.4f m, %10.4f m, %9.4f m, %9.4f m\n", slit1_dist, slit2_dist, slit3_dist, slit4_dist, slit5_dist, scrp_dist); if (src_width > 0.0) printf("moderator width : %11.4f m \n", src_width); else printf("moderator width : real size \n"); if (src_height > 0.0) printf("moderator height : %11.4f m \n", src_height); else printf("moderator height : real size \n"); printf("size of apert. 1 - 5 (w x h) : %11.4f x %10.4f m \n", slit_width, slit_height); printf("radius of beam scraper : %11.4f m \n", scrp_rad); printf("sample size (diam,h) : %11.4f , %10.4f m \n", smpl_diam, smpl_height); printf("beamstop radius : %11.4f m \n", stop_rad); printf("detector radius : %11.4f m \n\n", det_rad); printf("half-shadow time, ratio v : %11.4f s, %10.4f \n", T_hs, v); printf("min. and max. speed : %11.4f , %10.4f km/s\n", 0.001*v_min, 0.001*v_max); printf("arrival time at detector : %11.4f - %10.4f ms \n", 1000.0*Tar_min, 1000.0*Tar_max); printf("evaluation time : %11.4f - %10.4f ms \n", 1000.0*Tev_min, 1000.0*Tev_max); printf("lambda range set by choppers : %11.4f - %10.4f Ang\n\n",L2V/v_max, L2V/v_min); printf("detectable lambda range : %11.4f - %10.4f Ang\n\n",LCmin, LCmax); printf("powder data file : %s \n", sSampleFile); printf("time monitor : %s \n", sOptT); printf("lambda monitor : %s \n", sOptL); printf("lambda monitor circular : %s \n", sOptLrd); printf("detector PSD : %s \n", sOptPSD); printf("detector time : %s \n", sOptEva); printf("detector Q : %s \n", sOptQ); printf("detector d-spacing : %s \n\n", sOptDsp); %} TRACE /* Source */ /* ------ */ COMPONENT armSource = Arm() AT (0,0,0) ABSOLUTE COMPONENT source = ISIS_moderator( Face = sMod, dist = scrp_dist, xw = 2*scrp_rad, yh = 2*scrp_rad, E0 = -Lmin, E1 = -Lmax, modXsize = src_width, modYsize = src_height, CAngle = 0.0, SAC = 1) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT TimeMon_Source = Monitor_nD( options="time limits=[0,0.002] bins=100", filename = "source.mtt", xwidth = mon_width, yheight = mon_height) AT (0, 0, mon0_dist) ABSOLUTE COMPONENT LmbdMon_Source = Monitor_nD( options=sOptL, filename = "monitor1.mtl", xwidth = mon_width, yheight = mon_height) AT (0, 0, mon1_dist) ABSOLUTE /* slits + choppers */ /* ---------------- */ COMPONENT Slit_1 = Slit( xmin = -0.5*slit_width, ymin = -0.5*slit_height, xmax = 0.5*slit_width, ymax = 0.5*slit_height) AT (0, 0, slit1_dist) ABSOLUTE COMPONENT Chopper1 = Chopper( R = chop_rad, w=chp1_width, f = omega, n = 1, pha = chp1_time, IsFirst=0) AT (0, 0, chp1_dist) ABSOLUTE COMPONENT Slit_2 = Slit( xmin = -0.5*slit_width, ymin = -0.5*slit_height, xmax = 0.5*slit_width, ymax = 0.5*slit_height) AT (0, 0, slit2_dist) ABSOLUTE COMPONENT Chopper2 = Chopper( R = chop_rad, w=chp2_width, f = omega, n = 1, pha = chp2_time, IsFirst=0) AT (0, 0, chp2_dist) ABSOLUTE COMPONENT LmbdMon_Chop_2 = Monitor_nD( options=sOptL, filename = "chopper2.mtl", xwidth = mon_width, yheight = mon_height) AT (0, 0, mon2_dist) ABSOLUTE COMPONENT TimeMon_Chop_2 = Monitor_nD( options=sOptT, filename = "chopper2.mtt", xwidth = mon_width, yheight = mon_height) AT (0, 0, mon2_dist) ABSOLUTE COMPONENT Slit_3 = Slit( xmin = -0.5*slit_width, ymin = -0.5*slit_height, xmax = 0.5*slit_width, ymax = 0.5*slit_height) AT (0, 0, slit3_dist) ABSOLUTE COMPONENT Monitor_Slit_3 = Monitor( xwidth = slit_width, yheight = slit_height) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Slit_4 = Slit( xmin = -0.5*slit_width, ymin = -0.5*slit_height, xmax = 0.5*slit_width, ymax = 0.5*slit_height) AT (0, 0, slit4_dist) ABSOLUTE COMPONENT Monitor_Slit_4 = Monitor( xwidth = slit_width, yheight = slit_height) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Slit_5 = Slit( xmin = -0.5*slit_width, ymin = -0.5*slit_height, xmax = 0.5*slit_width, ymax = 0.5*slit_height) AT (0, 0, slit5_dist) ABSOLUTE COMPONENT LmbdMon_Slit_5 = Monitor_nD( options=sOptL, filename = "slit_5.mtl", xwidth = mon_width, yheight = mon_height) AT (0, 0, mon3_dist) ABSOLUTE /* beam scraper + sample */ /* --------------------- */ COMPONENT FluxMon_Sample = Monitor( xwidth = 0.010, yheight = 0.010) AT (0, 0, scrp_dist) ABSOLUTE COMPONENT Beam_Scraper = Slit( radius=scrp_rad) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT LmbdMon_Sample = Monitor_nD( options=sOptLrd, filename = "sample.mtl", xwidth = mon_width) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT TimeMon_Sample = Monitor_nD( options=sOptT, filename = "sample.mtt", xwidth = mon_width, yheight = mon_height) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Sample = PowderN( format = Lazy, reflections = sSampleFile, radius = smpl_diam/2.0, yheight = smpl_height, Vc = 1079.1) AT (0, 0, smpl_dist) ABSOLUTE ROTATED (90, 0, 0) RELATIVE armSource /* beamstop and detector */ /* --------------------- */ /* COMPONENT LmbdMon_Beamstop = Monitor_nD( options=sOptLrd, filename = "beamstop.mtl", xwidth = stop_rad) AT (0, 0, mon4_dist) ABSOLUTE ROTATED (0,0,0) ABSOLUTE */ COMPONENT Beamstop = Beamstop( radius = stop_rad) AT (0, 0, stop_dist) ABSOLUTE ROTATED (0,0,0) ABSOLUTE EXTEND %{ ALLOW_BACKPROP; %} COMPONENT Detector_flPSD = Monitor_nD( options= sOptPSD, filename = "detector.psd", xwidth = 2*det_rad-0.0001, yheight = 2*det_rad-0.0001) AT ( 0, 0, 0) RELATIVE Sample ROTATED (-90, 0, 0) RELATIVE Sample COMPONENT Detector_Teval = Monitor_nD( options= sOptEva, filename = "detector.tof", xwidth = 2*det_rad) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Detector_4_pi_ = Monitor_4PI( ) AT (0, 0, 0) RELATIVE PREVIOUS EXTEND %{ two_theta = atan2(sqrt(x*x+y*y), z); MONND_USER_VALUE(Detector_d_spc, 1, 0.5*L2V*t/(smpl_dist+det_rad)/sin(two_theta/2.0)); MONND_USER_VALUE(Detector_Mtrns, 2, 4.0*PI/(L2V*t/(smpl_dist+det_rad)/sin(two_theta/2.0))); %} COMPONENT Detector_angle = Monitor_nD( options= sOptAng, filename = "detector.sca", xwidth = 2*det_rad+0.0001) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Detector_d_spc = Monitor_nD( options= sOptDsp, filename = "detector.eds", xwidth = 2*det_rad+0.0002) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Detector_Mtrns = Monitor_nD( options= sOptQ, filename = "detector.emt", xwidth = 2*det_rad+0.0003) AT (0, 0, 0) RELATIVE PREVIOUS END