/************************************************ * * SANS instrument to be installed at ESS and SNS * * written by by K. Lieutenant, Jul 2005 * ***************************************************/ DEFINE INSTRUMENT SANS(string SRC="ESS", L2=5.0, WIDTH=0.03, LAMBDA=8.0, PATH=8.0) DECLARE %{ #define ESS 11 #define SNS 12 #define L2V 3956.036 double Min(double value1, double value2) { if(value1 < value2) return value1 ; else return value2 ; } short eSource, /* enum for source */ num_blades, /* number of blades */ 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] */ norm_cold, /* factor for intensity per pulse (ESS=1)*/ /* for cold moderator */ src_width, /* moderator width used [m] */ src_height, /* moderator height used [m] */ src_max_wth, /* max. moderator width [m] */ src_max_hite,/* max. moderator height [m] */ lmbd_av, /* average wavelength [Ang] */ del_lmbd, /* max. dev. from av. wavelength [Ang] */ speed_av, /* corresponding speed [m/s] */ Lmin, Lmax, /* min. and max. wavelength [Ang] */ Emin, Emax, /* min. and max. energy [meV] */ max_div_h, /* max. horizontal divergence [Ang] */ max_div_v, /* max. vertical divergence [Ang] */ gde_width, /* width of guides [m] */ gde_height, /* height of guides [m] */ gde_m, /* standard m-value of guides */ gd1_dist, /* distance source - curved guide [m] */ gd1_radius, /* radius of curved guide [m] */ gd1_curv, /* curvature of curved guide [1] */ gd1_m, /* m-value of vert. walls of curved guide */ theta_typ, /* max. refl. angle for non-div. neu. [deg] */ lmbd_min, /* min. lambda of T=1 in curved guide [Ang] */ gd1_len, /* length of curved guide [m] */ gd1a_len, /* length of guide 1 before chopper [m] */ gd1b_len, /* length of guide 1 after chopper [m] */ gd1a_curv, /* curvature of guide before chopper[1] */ gd2_len, /* length of straight guide [m] */ gd2a_len, /* length of guide 2 before chopper [m] */ gd2b_len, /* length of guide 2 after chopper [m] */ gd3_len, /* length of removable guide [m] */ gd3a_len, /* length of guide 3 before chopper [m] */ gd3b_len, /* length of guide 3 after chopper [m] */ chop_rad, /* dist. between axle & wnd. centre [m] */ chp1_dist, /* distance source - chopper 1 [m] */ chp2_dist, /* distance source - chopper 2 [m] */ chp3_dist, /* distance source - chopper 3 [m] */ chp1_angle, /* window width of chopper 1 [deg] */ chp2_angle, /* window width of chopper 2 [deg] */ chp3_angle, /* window width of chopper 3 [deg] */ chp1_width, /* corr. window widths of the choppers */ chp2_width, /* that give the wanted widths in deg */ chp3_width, /* in the component 'chopper' [m] */ chp1_time, /* time offsets */ chp2_time, /* for the right phases */ chp3_time, /* of chopper 1, 2 and 3 [s] */ chp3_vpos, /* vert. pos. allowing for gravity [m] */ max_flight, /* max. flight path guide - sample [m] */ flightpath1, /* real flight path guide - sample [m] */ flightpath2, /* flight path sample - detector [m] */ part1_len, /* length up to end of str. guide [m] */ smpl_dist, /* distance source - sample [m] */ total_len, /* total length of instrument [m] */ smpl_width, /* width of sample [m] */ smpl_height, /* heigth of sample [m] */ smpl_vpos, /* vert. pos. allowing for gravity [m] */ stop_width, /* width of beamstop [m] */ stop_height, /* heigth of beamstop [m] */ det_width, /* width of detector [m] */ det_height, /* heigth of detector [m] */ det_rad, /* dist centre - corner of detector [m] */ det_vpos, /* vert. pos. allowing for gravity [m] */ v, /* ratio: (dist. WB-chop - det) / (dist src - WB chop) */ T_hs, /* half-shadow time [s] */ v_min, v_max,/* min. and max. speed by choppers [m/s] */ Tev_min, /* min. and max. evaluation time [s] */ Tev_max, Gv = 0.00, /* gravitation [m/s/s]*/ wavi= 0.01, /* waviness [deg] */ 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 */ sOptEva[80], /* String def. tof-monitor options */ sOptDtQ[99], /* String defining Q detection options */ sOptPSD[80]; /* String defining PSD detector options */ %} INITIALIZE %{ strcpy(sSource, SRC); if (strcmp(sSource, "SNS")==0 || strcmp(sSource, "sns")==0) { eSource = SNS; freq = 60.0; src_max_wth = 0.10; src_max_hite = 0.12; norm_cold = 2.0/5.0 / (60.0/50.0) / 1.3; // ratio: power[MW]/freq[Hz]* factor // for favourite upstream position } else if (strcmp(sSource, "ESS")==0 || strcmp(sSource, "ess")==0) { eSource = ESS; freq = 50.0; src_max_wth = 0.12; src_max_hite = 0.12; norm_cold = 1.0; } 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; pulse_len = 0.001; gde_width = WIDTH; gde_height = WIDTH; gde_m = 1.0; gd1_m = 3.0; lmbd_min = 4.0; lmbd_av = LAMBDA; speed_av = L2V/lmbd_av; gd1_dist = 2.0; theta_typ = 0.1*lmbd_min*gd1_m; gd1_radius = 2.0*gde_width/pow(tan(theta_typ*DEG2RAD),2.0); gd1_len = ceil(2.0 * sqrt(8.0*gd1_radius*gde_width)) / 2.0 ; gd1_curv = gd1_len/gd1_radius; gd2_len = L2; max_flight = 25.0; flightpath1 = PATH; flightpath2 = PATH; gd3_len = max_flight-PATH; part1_len = gd1_dist + gd1_len + gd2_len; smpl_dist = part1_len + gd3_len + flightpath1; total_len = smpl_dist + flightpath2; del_lmbd = 0.55 * L2V * period / total_len; Lmin = lmbd_av - del_lmbd; Lmax = lmbd_av + del_lmbd; Emin = VS2E*pow(L2V/Lmax,2); Emax = VS2E*pow(L2V/Lmin,2); max_div_h = gd1_m * 0.1 * Lmax; max_div_v = gde_m * 0.1 * Lmax; src_width = Min(src_max_wth, gde_width + gd1_dist*tan(max_div_h*DEG2RAD)); src_height = src_width; /* chopper system */ /* -------------- */ chop_rad = 0.25; chp1_dist = 6.0; chp2_dist = 9.0; chp3_dist = total_len/2.0; gd1a_len = chp1_dist - gd1_dist; gd1b_len = gd1_len - gd1a_len; gd1a_curv = gd1a_len / gd1_radius; gd2a_len = chp2_dist - (gd1_dist + gd1_len); gd2b_len = gd2_len - gd2a_len; if (gd3_len > 0.0) { gd3a_len = Min(chp3_dist - (gd1_dist + gd1_len + gd2_len), gd3_len); gd3b_len = gd3_len - gd3a_len; } else { gd3a_len = gd3b_len = 0.0; } if (gd1a_len < 0.0 || gd1b_len < 0.0 || gd2a_len < 0.0 || gd2b_len < 0.0 || gd3a_len < 0.0 || gd3b_len < 0.0) printf("Error: correct chopper positioning impossible, lengths: %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f m", gd1a_len, gd1b_len, gd2a_len, gd2b_len, gd3a_len, gd3b_len); chp1_angle = 360.0/period*(pulse_len+(period-pulse_len)*chp1_dist/total_len); chp2_angle = 360.0/period*(pulse_len+(period-pulse_len)*chp2_dist/total_len); chp3_angle = 170.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); chp3_width = 2.0*chop_rad*tan(DEG2RAD*chp3_angle/2.0); chp1_time = chp1_dist/speed_av + 0.5*pulse_len; chp2_time = chp2_dist/speed_av + 0.5*pulse_len; chp3_time = chp3_dist/speed_av + 0.5*pulse_len; /* sample and detector */ /* ------------------- */ smpl_width = 0.01; smpl_height = 0.01; stop_width = smpl_width + (smpl_width +gde_width )*flightpath2/flightpath1; stop_height = smpl_height + (smpl_height+gde_height)*flightpath2/flightpath1; det_width = 1.0; det_height = 1.7; det_w_bins = 100; det_h_bins = 170; det_rad = 0.5 * sqrt(det_width*det_width+det_height*det_height); if (chp3_dist > (part1_len + gd3_len)) chp3_vpos = 0.5 * Gv * pow((chp3_dist - part1_len - gd3_len) / speed_av, 2); else chp3_vpos = 0.0; smpl_vpos = 0.5 * Gv * pow( flightpath1 / speed_av, 2); det_vpos = 0.5 * Gv * pow((flightpath1 + flightpath2) / speed_av, 2); if (del_lmbd > 0.0) { LMmin = floor(lmbd_av - del_lmbd); LMmax = ceil (lmbd_av + del_lmbd); } else { LMmin = lmbd_av - 0.2525; LMmax = lmbd_av + 0.2525; } /* evaluation time */ v = (total_len - chp3_dist) / chp3_dist; T_hs = atan(gde_width/chop_rad)/omega; v_min = chp3_dist / (chp3_time + 0.5*period*chp3_angle/360.0 + 0.5*pulse_len); v_max = chp3_dist / (chp3_time - 0.5*period*chp3_angle/360.0 - 0.5*pulse_len); Tev_min = total_len/v_min - period + v*T_hs; Tev_max = total_len/v_max + period - v*T_hs + pulse_len; sprintf(sOptL , "lambda limits=[%f,%f] bins=100 absorb", LMmin, LMmax); sprintf(sOptEva, "time limits=[%f,%f] bins=100 exclusive", Tev_min, Tev_max); sprintf(sOptPSD ,"x limits=[%f,%f] bins=%d, y limits=[%f,%f] bins=%d", -0.5*det_width, 0.5*det_width, det_w_bins, -0.5*det_height, 0.5*det_height, det_h_bins); sprintf(sOptDtQ ,"log kxy limits=[%f,%f] bins=97", -4.0, 0.0); printf("\nSANS instrument 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 length considered : %11.4f s \n", pulse_len); printf("norm factor for cold source : %11.4f \n", norm_cold); printf("gravitation used : %11.4f m/s/s \n", Gv); printf("moderator size (w x h) : %11.4f x %10.4f m \n", src_width, src_height); printf("max. divergence (hor., vert.) : %11.4f, %10.4f deg \n", max_div_h, max_div_v ); printf("wavelength range : %11.4f - %10.4f Ang \n", Lmin, Lmax); printf("energy range : %11.4f - %10.4f meV \n", Emin, Emax); printf("guide size (w x h) : %11.4f x %10.4f m \n", gde_width, gde_height); printf("m-values (stand., curv. guide) : %11.4f, %10.4f \n\n", gde_m, gd1_m); printf("distance: source - curved guide: %11.4f m \n", gd1_dist); printf("lengths of curved guide : %11.4f (= %10.4f +%10.4f) m \n", gd1_len, gd1a_len, gd1b_len); printf(" curvature, radius : %11.4f (= %10.4f + ...... ) deg, %10.4f m\n", RAD2DEG*gd1_curv, RAD2DEG*gd1a_curv, gd1_radius); printf("lengths of straight guide : %11.4f (= %10.4f +%10.4f) m \n", gd2_len, gd2a_len, gd2b_len); printf("lengths of removable guide : %11.4f (= %10.4f +%10.4f) m \n", gd3_len, gd3a_len, gd3b_len); printf("free flight path : %11.4f + %10.4f m \n", flightpath1, flightpath2); printf("sample and detector distance : %11.4f, %10.4f m \n", smpl_dist, total_len); printf("vert. chop., sample & det. pos.: %11.4f, %10.4f, %10.4f m\n\n", chp3_vpos, smpl_vpos, det_vpos); 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 s \n", chp1_dist, chp1_angle, chp1_width, chp1_time); printf("chopper 2 (dist, width, time) : %11.4f m, %10.4f deg, %10.4f m, %10.4f s \n", chp2_dist, chp2_angle, chp2_width, chp2_time); printf("chopper 3 (dist, width, time) : %11.4f m, %10.4f deg, %10.4f m, %10.4f s \n\n", chp3_dist, chp3_angle, chp3_width, chp3_time); printf("sample size (w x h) : %11.4f x %10.4f m \n", smpl_width, smpl_height); printf("beamstop size (w x h) : %11.4f x %10.4f m \n", stop_width, stop_height); printf("detector size (w x h), radius : %11.4f x %10.4f m, %10.4f m \n\n", det_width, det_height, det_rad); printf("half-shadow time, ratio v : %11.4f s, %10.4f \n", T_hs, v); printf("evaluation time : %11.4f - %10.4f s \n", Tev_min, Tev_max); printf("lambda range set by choppers : %11.4f - %10.4f Ang \n\n", L2V/v_max, L2V/v_min); printf("lambda monitor : %s \n", sOptL); printf("detector PSD : %s \n", sOptPSD); printf("detector time : %s \n", sOptEva); printf("detector Q : %s \n\n", sOptDtQ); %} TRACE /* Source */ /* ------ */ COMPONENT armSource = Arm() AT (0,0,0) ABSOLUTE COMPONENT SourceSNS = ESS_moderator_short( dist = gd1_dist, xw = gde_width, yh = gde_height, l_low = Lmin, l_high = Lmax, size = src_width, freq = freq, T = 50, tau = 0.000287, n = 20, I0 = 2.3e11*norm_cold, tau1 = 0.0, branch1 = 0.0, tau2 = 0.000012, n2 = 5, I2 = 9.2e10*norm_cold, chi2 = 0.9, branch2 = 0.5, branchframe = 1.0) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT LmbdMon_Source = Monitor_nD( options=sOptL, filename = "source.mtl", xwidth = gde_width, yheight = gde_height) AT (0, 0, gd1_dist) RELATIVE SourceSNS COMPONENT HDivMon_Source = Monitor_nD( options = "hdiv, limits=[-4,4], bins=80", filename = "source.hdiv", xwidth = gde_width, yheight = gde_height) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT VDivMon_Source = Monitor_nD( options = "vdiv, limits=[-4,4], bins=80", filename = "source.vdiv", xwidth = gde_width, yheight = gde_height) AT (0, 0, 0) RELATIVE PREVIOUS /* curved guide 1 */ /* -------------- */ COMPONENT CurvedGuideA = Guide_curved( w = gde_width, h = gde_height, l = gd1a_len, R0 = 0.99, Qc = 0.021743, alpha = 4.5, m = gd1_m, W = 0.002, r = gd1_radius) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Chopper1 = Chopper( R = chop_rad, w=chp1_width, f = omega, n = 1, pha = chp1_time, IsFirst=0) AT (gd1_radius*(1.0-cos(gd1a_curv+5.0e-06)), 0, gd1_radius*sin(gd1a_curv+5.0e-06)) RELATIVE CurvedGuideA ROTATED (0, RAD2DEG*gd1a_curv, 0) RELATIVE CurvedGuideA COMPONENT CurvedGuideB = Guide_curved( w = gde_width, h = gde_height, l = gd1b_len, R0 = 0.99, Qc = 0.021743, alpha = 4.5, m = gd1_m, W = 0.002, r = gd1_radius) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT HDivMon_GdCurv = Monitor_nD( options = "hdiv, limits=[-4,4], bins=80", filename = "guide_curv.hdiv", xwidth = gde_width, yheight = gde_height) AT (gd1_radius*(1.0-cos(gd1_curv+5.0e-06)), 0, gd1_radius*sin(gd1_curv+5.0e-06)) RELATIVE CurvedGuideA ROTATED (0, RAD2DEG*gd1_curv, 0) RELATIVE CurvedGuideA COMPONENT HPosMon_GdCurv = Monitor_nD( options = "x, limits=[-0.04,0.04], bins=80", filename = "guide_curv.hpos", xwidth = gde_width, yheight = gde_height) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT LmbdMon_GdCurv = Monitor_nD( options=sOptL, filename = "guide_curv.mtl", xwidth = gde_width, yheight = gde_height) AT (0, 0, 0) RELATIVE PREVIOUS /* straight guide 2 */ /* ---------------- */ COMPONENT StraightGuideA = Guide_gravity( w1 = gde_width, h1 = gde_height, w2 = gde_width, h2 = gde_height,l = gd2a_len, R0 = 0.99, m = gde_m, Qc = 0.021743, alpha = 4.5, W = 0.0, wavy=wavi, G=Gv) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Chopper2 = Chopper( R = chop_rad, w=chp2_width, f = omega, n = 1, pha = chp2_time, IsFirst=0) AT (0, 0, gd2a_len) RELATIVE PREVIOUS COMPONENT StraightGuideB = Guide_gravity( w1 = gde_width, h1 = gde_height, w2 = gde_width, h2 = gde_height,l = gd2b_len, R0 = 0.99, m = gde_m, Qc = 0.021743, alpha = 4.5, W = 0.0, wavy=wavi, G=Gv) AT (0, 0, 0) RELATIVE PREVIOUS /* end of part 1 */ /* ------------- */ COMPONENT BegPart2 = Arm() AT (0, 0, gd2b_len) RELATIVE PREVIOUS COMPONENT FluxMon_GdStrt = Monitor( xmin = -0.5*gde_width, xmax = 0.5*gde_height, ymin = -0.5*gde_width, ymax = 0.5*gde_height) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT HDivMon_GdStrt = Monitor_nD( options = "hdiv, limits=[-4,4], bins=80", filename = "guide_str.hdiv", xwidth = gde_width, yheight = gde_height) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT HPosMon_GdStrt = Monitor_nD( options = "x, limits=[-0.04,0.04], bins=80", filename = "guide_str.hpos", xwidth = gde_width, yheight = gde_height) AT (0, 0, 0) RELATIVE PREVIOUS /* removable guide 3 */ /* ----------------- */ COMPONENT RemovableGuideA = Guide_gravity( w1 = gde_width, h1 = gde_height, w2 = gde_width, h2 = gde_height,l = gd3a_len, R0 = 0.99, m = gde_m, Qc = 0.021743, alpha = 4.5, W = 0.0003, wavy=wavi, G=Gv) AT (0, 0, 0.000) RELATIVE PREVIOUS COMPONENT Chop3FormO = Slit( radius = chop_rad + 0.1, cut = 1e-6) AT (0, chp3_vpos - chop_rad, chp3_dist - part1_len) RELATIVE BegPart2 COMPONENT Chop3FormI = Beamstop( radius = chop_rad - 0.1) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Chopper3_flPSD = Monitor_nD( options= sOptPSD, filename = "chopper3.psd", xwidth = 0.7, yheight = 0.7) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Chopper3 = Chopper( R = chop_rad, w=chp3_width, f = omega, n = 1, pha = chp3_time, IsFirst=0) AT (0, chop_rad, 0) RELATIVE Chop3FormO COMPONENT FluxMon_Chop_3 = Monitor( xmin = -0.35, xmax = 0.35, ymin = -0.35 - chop_rad, ymax = 0.35) AT (0, chop_rad, 0) RELATIVE Chop3FormO COMPONENT LmbdMon_WBChop = Monitor_nD( options=sOptL, filename = "chopper.mtl", xwidth = gde_width, yheight = 0.2) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT HDivMon_WBChop = Monitor_nD( options = "hdiv, limits=[-4,4], bins=80", filename = "chopper.hdiv", xwidth = gde_width, yheight = 0.2) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT VDivMon_WBChop = Monitor_nD( options = "vdiv, limits=[-4,4], bins=80", filename = "chopper.vdiv", xwidth = gde_width, yheight = 0.2) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT RemovableGuideB = Guide_gravity( w1 = gde_width, h1 = gde_height, w2 = gde_width, h2 = gde_height,l = gd3b_len, R0 = 0.99, m = gde_m, Qc = 0.021743, alpha = 4.5, W = 0.0003, wavy=wavi, G=Gv) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT LmbdMon_Guide3 = Monitor_nD( options=sOptL, filename = "guide3.mtl", xwidth = gde_width, yheight = 0.2) AT (0, 0, gd3b_len) RELATIVE PREVIOUS /* slit + sample */ /* ------------- */ COMPONENT Slit_Sample = Slit( xmin = -0.5*smpl_width, xmax = 0.5*smpl_height, ymin = -0.5*smpl_width, ymax = 0.5*smpl_height) AT (0, smpl_vpos, smpl_dist - 0.01 - part1_len) RELATIVE BegPart2 COMPONENT LmbdMon_Sample = Monitor_nD( options=sOptL, filename = "sample.mtl", xwidth = smpl_width, yheight = smpl_height) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Sample = Sans_spheres( R = 500, Phi = 0.03, Delta_rho = 0.2, sigma_a = 10, dist = flightpath2, Rdet= det_rad, xwidth = 0.01, yheight = 0.01, zthick = 0.001) AT (0, 0, 0.01) RELATIVE PREVIOUS COMPONENT Monitor_Sample = Monitor_4PI( ) AT (0, 0, 0) RELATIVE PREVIOUS /* beamstop and detector */ /* --------------------- */ COMPONENT Beamstop = Beamstop( xmin = -0.5*stop_width, xmax = 0.5*stop_width, ymin = -0.5*stop_height, ymax = 0.5*stop_height) AT (0, det_vpos, total_len - 0.05 - part1_len) RELATIVE BegPart2 COMPONENT Detector_flPSD = Monitor_nD( options= sOptPSD, filename = "detector.psd", xwidth = det_width, yheight = det_height) AT (0, 0, 0.05) RELATIVE PREVIOUS COMPONENT Detector_T_eval = Monitor_nD( options= sOptEva, filename = "detector.tof", xwidth = det_width, yheight = det_height) AT (0, 0, 0) RELATIVE PREVIOUS COMPONENT Detector_log_Q = Monitor_nD( options= sOptDtQ, filename = "detector.emt", xwidth = det_width, yheight = det_height) AT (0, 0, 0) RELATIVE PREVIOUS /* EXTEND %{ double Q; Q = 4*PI*sin(angle)/wavelength; %}*/ END