[69] | 1 | #pragma rtGlobals=1 // Use modern global access method. |
---|
| 2 | #pragma version=5.0 |
---|
[570] | 3 | #pragma IgorVersion=6.1 |
---|
[69] | 4 | |
---|
| 5 | // this file contains globals and functions that are specific to a |
---|
| 6 | // particular facility or data file format |
---|
| 7 | // branched out 29MAR07 - SRK |
---|
[79] | 8 | // |
---|
| 9 | // functions are either labeled with the procedure file that calls them, |
---|
| 10 | // or noted that they are local to this file |
---|
[69] | 11 | |
---|
| 12 | |
---|
| 13 | // initializes globals that are specific to a particular facility |
---|
| 14 | // - number of XY pixels |
---|
| 15 | // - pixexl resolution [cm] |
---|
| 16 | // - detector deadtime constant [s] |
---|
[79] | 17 | // |
---|
| 18 | // called by Initialize.ipf |
---|
| 19 | // |
---|
[69] | 20 | Function InitFacilityGlobals() |
---|
| 21 | |
---|
| 22 | //Detector -specific globals |
---|
| 23 | Variable/G root:myGlobals:gNPixelsX=128 |
---|
| 24 | Variable/G root:myGlobals:gNPixelsY=128 |
---|
| 25 | |
---|
[247] | 26 | // as of Jan2008, detector pixel sizes are read directly from the file header, so they MUST |
---|
| 27 | // be set correctly in instr.cfg |
---|
[69] | 28 | Variable/G root:myGlobals:PixelResNG3_ILL = 1.0 //pixel resolution in cm |
---|
| 29 | Variable/G root:myGlobals:PixelResNG5_ILL = 1.0 |
---|
| 30 | Variable/G root:myGlobals:PixelResNG7_ILL = 1.0 |
---|
| 31 | Variable/G root:myGlobals:PixelResNG3_ORNL = 0.5 |
---|
| 32 | Variable/G root:myGlobals:PixelResNG5_ORNL = 0.5 |
---|
| 33 | Variable/G root:myGlobals:PixelResNG7_ORNL = 0.5 |
---|
| 34 | Variable/G root:myGlobals:PixelResDefault = 0.5 |
---|
| 35 | |
---|
| 36 | Variable/G root:myGlobals:DeadtimeNG3_ILL = 3.0e-6 //deadtime in seconds |
---|
| 37 | Variable/G root:myGlobals:DeadtimeNG5_ILL = 3.0e-6 |
---|
| 38 | Variable/G root:myGlobals:DeadtimeNG7_ILL = 3.0e-6 |
---|
[788] | 39 | Variable/G root:myGlobals:DeadtimeNG3_ORNL_VAX = 3.4e-6 //pre - 23-JUL-2009 used VAX |
---|
| 40 | Variable/G root:myGlobals:DeadtimeNG3_ORNL_ICE = 1.5e-6 //post - 23-JUL-2009 used ICE |
---|
| 41 | Variable/G root:myGlobals:DeadtimeNG5_ORNL = 0.6e-6 //as of 9 MAY 2002 |
---|
| 42 | Variable/G root:myGlobals:DeadtimeNG7_ORNL_VAX = 3.4e-6 //pre 25-FEB-2010 used VAX |
---|
| 43 | Variable/G root:myGlobals:DeadtimeNG7_ORNL_ICE = 2.3e-6 //post 25-FEB-2010 used ICE |
---|
[69] | 44 | Variable/G root:myGlobals:DeadtimeDefault = 3.4e-6 |
---|
[82] | 45 | |
---|
| 46 | //new 11APR07 |
---|
[206] | 47 | Variable/G root:myGlobals:BeamstopXTol = -8 // (cm) is BS Xpos is -5 cm or less, it's a trans measurement |
---|
[82] | 48 | // sample aperture offset is NOT stored in the VAX header, but it should be |
---|
| 49 | // - when it is, remove the global and write an accessor AND make a place for |
---|
| 50 | // it in the RealsRead |
---|
[85] | 51 | Variable/G root:myGlobals:apOff = 5.0 // (cm) distance from sample aperture to sample position |
---|
[82] | 52 | |
---|
[69] | 53 | End |
---|
| 54 | |
---|
| 55 | |
---|
| 56 | //********************** |
---|
| 57 | // Resolution calculation - used by the averaging routines |
---|
| 58 | // to calculate the resolution function at each q-value |
---|
| 59 | // - the return value is not used |
---|
| 60 | // |
---|
| 61 | // equivalent to John's routine on the VAX Q_SIGMA_AVE.FOR |
---|
| 62 | // Incorporates eqn. 3-15 from J. Appl. Cryst. (1995) v. 28 p105-114 |
---|
| 63 | // |
---|
| 64 | // - 21 MAR 07 uses projected BS diameter on the detector |
---|
[79] | 65 | // - APR 07 still need to add resolution with lenses. currently there is no flag in the |
---|
| 66 | // raw data header to indicate the presence of lenses. |
---|
[69] | 67 | // |
---|
[143] | 68 | // - Aug 07 - added input to switch calculation based on lenses (==1 if in) |
---|
| 69 | // |
---|
[79] | 70 | // - called by CircSectAvg.ipf and RectAnnulAvg.ipf |
---|
| 71 | // |
---|
[82] | 72 | // passed values are read from RealsRead |
---|
| 73 | // except DDet and apOff, which are set from globals before passing |
---|
| 74 | // |
---|
[143] | 75 | // |
---|
| 76 | Function/S getResolution(inQ,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,SigmaQ,QBar,fSubS) |
---|
| 77 | Variable inQ, lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses |
---|
[69] | 78 | Variable &fSubS, &QBar, &SigmaQ //these are the output quantities at the input Q value |
---|
| 79 | |
---|
| 80 | //lots of calculation variables |
---|
| 81 | Variable a2, q_small, lp, v_lambda, v_b, v_d, vz, yg, v_g |
---|
| 82 | Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r |
---|
| 83 | |
---|
| 84 | //Constants |
---|
| 85 | Variable vz_1 = 3.956e5 //velocity [cm/s] of 1 A neutron |
---|
| 86 | Variable g = 981.0 //gravity acceleration [cm/s^2] |
---|
| 87 | |
---|
| 88 | String results |
---|
| 89 | results ="Failure" |
---|
| 90 | |
---|
| 91 | S1 *= 0.5*0.1 //convert to radius and [cm] |
---|
| 92 | S2 *= 0.5*0.1 |
---|
| 93 | |
---|
| 94 | L1 *= 100.0 // [cm] |
---|
| 95 | L1 -= apOff //correct the distance |
---|
| 96 | |
---|
| 97 | L2 *= 100.0 |
---|
| 98 | L2 += apOff |
---|
| 99 | del_r *= 0.1 //width of annulus, convert mm to [cm] |
---|
| 100 | |
---|
| 101 | BS *= 0.5*0.1 //nominal BS diameter passed in, convert to radius and [cm] |
---|
| 102 | // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture |
---|
| 103 | Variable LB |
---|
| 104 | LB = 20.1 + 1.61*BS //distance in cm from beamstop to anode plane (empirical) |
---|
| 105 | BS = bs + bs*lb/(l2-lb) //adjusted diameter of shadow from parallax |
---|
| 106 | |
---|
| 107 | //Start resolution calculation |
---|
| 108 | a2 = S1*L2/L1 + S2*(L1+L2)/L1 |
---|
| 109 | q_small = 2.0*Pi*(BS-a2)*(1.0-lambdaWidth)/(lambda*L2) |
---|
| 110 | lp = 1.0/( 1.0/L1 + 1.0/L2) |
---|
| 111 | |
---|
| 112 | v_lambda = lambdaWidth^2/6.0 |
---|
[143] | 113 | |
---|
[248] | 114 | // if(usingLenses==1) //SRK 2007 |
---|
| 115 | if(usingLenses != 0) //SRK 2008 allows for the possibility of different numbers of lenses in header |
---|
[143] | 116 | v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2 //correction to 2nd term |
---|
| 117 | else |
---|
| 118 | v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2 //original form |
---|
| 119 | endif |
---|
| 120 | |
---|
[69] | 121 | v_d = (DDet/2.3548)^2 + del_r^2/12.0 |
---|
| 122 | vz = vz_1 / lambda |
---|
| 123 | yg = 0.5*g*L2*(L1+L2)/vz^2 |
---|
[143] | 124 | v_g = 2.0*(2.0*yg^2*v_lambda) //factor of 2 correction, B. Hammouda, 2007 |
---|
[69] | 125 | |
---|
| 126 | r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) )) |
---|
| 127 | delta = 0.5*(BS - r0)^2/v_d |
---|
| 128 | |
---|
| 129 | if (r0 < BS) |
---|
| 130 | inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta)) |
---|
| 131 | else |
---|
| 132 | inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta)) |
---|
| 133 | endif |
---|
| 134 | |
---|
| 135 | fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) ) |
---|
| 136 | if (fSubS <= 0.0) |
---|
| 137 | fSubS = 1.e-10 |
---|
| 138 | endif |
---|
| 139 | fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi)) |
---|
| 140 | fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d |
---|
| 141 | |
---|
| 142 | rmd = fr*r0 |
---|
| 143 | v_r1 = v_b + fv*v_d +v_g |
---|
| 144 | |
---|
| 145 | rm = rmd + 0.5*v_r1/rmd |
---|
| 146 | v_r = v_r1 - 0.5*(v_r1/rmd)^2 |
---|
| 147 | if (v_r < 0.0) |
---|
| 148 | v_r = 0.0 |
---|
| 149 | endif |
---|
| 150 | QBar = (4.0*Pi/lambda)*sin(0.5*atan(rm/L2)) |
---|
| 151 | SigmaQ = QBar*sqrt(v_r/rmd^2 +v_lambda) |
---|
| 152 | |
---|
[794] | 153 | |
---|
| 154 | // more readable method for calculating the variance in Q |
---|
| 155 | // EXCEPT - this is calculated for Qo, NOT qBar |
---|
| 156 | // (otherwise, they are nearly equivalent, except for close to the beam stop) |
---|
| 157 | // Variable kap,a_val,a_val_l2,m_h |
---|
| 158 | // g = 981.0 //gravity acceleration [cm/s^2] |
---|
| 159 | // m_h = 252.8 // m/h [=] s/cm^2 |
---|
| 160 | // |
---|
| 161 | // kap = 2*pi/lambda |
---|
| 162 | // a_val = L2*(L1+L2)*g/2*(m_h)^2 |
---|
| 163 | // a_val_L2 = a_val/L2*1e-16 //convert 1/cm^2 to 1/A^2 |
---|
| 164 | // |
---|
| 165 | // sigmaQ = 0 |
---|
| 166 | // sigmaQ = 3*(S1/L1)^2 |
---|
| 167 | // |
---|
| 168 | // if(usingLenses != 0) |
---|
| 169 | // sigmaQ += 2*(S2/lp)^2*(lambdaWidth)^2 //2nd term w/ lenses |
---|
| 170 | // else |
---|
| 171 | // sigmaQ += 2*(S2/lp)^2 //2nd term w/ no lenses |
---|
| 172 | // endif |
---|
| 173 | // |
---|
| 174 | // sigmaQ += (del_r/L2)^2 |
---|
| 175 | // sigmaQ += 2*(r0/L2)^2*(lambdaWidth)^2 |
---|
| 176 | // sigmaQ += 4*(a_val_l2)^2*lambda^4*(lambdaWidth)^2 |
---|
| 177 | // |
---|
| 178 | // sigmaQ *= kap^2/12 |
---|
| 179 | // sigmaQ = sqrt(sigmaQ) |
---|
| 180 | |
---|
| 181 | |
---|
[69] | 182 | results = "success" |
---|
| 183 | Return results |
---|
| 184 | End |
---|
| 185 | |
---|
[708] | 186 | |
---|
[509] | 187 | // |
---|
[708] | 188 | //********************** |
---|
| 189 | // 2D resolution function calculation - ***NOT*** in terms of X and Y |
---|
| 190 | // but written in terms of Parallel and perpendicular to the Q vector at each point |
---|
[509] | 191 | // |
---|
[838] | 192 | // -- it is more naturally written this way since the 2D function is an ellipse with its major |
---|
[708] | 193 | // axis pointing in the direction of Q_parallel. Hence there is no way to properly define the |
---|
| 194 | // elliptical gaussian in terms of sigmaX and sigmaY |
---|
[509] | 195 | // |
---|
[838] | 196 | // For a full description of the gravity effect on the resolution, see: |
---|
[509] | 197 | // |
---|
[838] | 198 | // "The effect of gravity on the resolution of small-angle neutron diffraction peaks" |
---|
| 199 | // D.F.R Mildner, J.G. Barker & S.R. Kline J. Appl. Cryst. (2011). 44, 1127-1129. |
---|
| 200 | // [ doi:10.1107/S0021889811033322 ] |
---|
[509] | 201 | // |
---|
[838] | 202 | // 2/17/12 SRK |
---|
| 203 | // NOTE: the first 2/3 of this code is the 1D code, copied here just to have the beam stop |
---|
| 204 | // calculation here, if I decide to implement it. The real calculation is all at the |
---|
| 205 | // bottom and is quite compact |
---|
| 206 | // |
---|
| 207 | // |
---|
| 208 | // |
---|
| 209 | // |
---|
[509] | 210 | // - 21 MAR 07 uses projected BS diameter on the detector |
---|
| 211 | // - APR 07 still need to add resolution with lenses. currently there is no flag in the |
---|
| 212 | // raw data header to indicate the presence of lenses. |
---|
| 213 | // |
---|
| 214 | // - Aug 07 - added input to switch calculation based on lenses (==1 if in) |
---|
| 215 | // |
---|
| 216 | // passed values are read from RealsRead |
---|
| 217 | // except DDet and apOff, which are set from globals before passing |
---|
| 218 | // |
---|
| 219 | // phi is the azimuthal angle, CCW from +x axis |
---|
| 220 | // r_dist is the real-space distance from ctr of detector to QxQy pixel location |
---|
| 221 | // |
---|
[794] | 222 | // MAR 2011 - removed the del_r terms, they don't apply since no bining is done to the 2D data |
---|
| 223 | // |
---|
[509] | 224 | Function/S get2DResolution(inQ,phi,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,r_dist,SigmaQX,SigmaQY,fSubS) |
---|
| 225 | Variable inQ, phi,lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses,r_dist |
---|
| 226 | Variable &SigmaQX,&SigmaQY,&fSubS //these are the output quantities at the input Q value |
---|
| 227 | |
---|
| 228 | //lots of calculation variables |
---|
| 229 | Variable a2, lp, v_lambda, v_b, v_d, vz, yg, v_g |
---|
| 230 | Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r |
---|
[69] | 231 | |
---|
[509] | 232 | //Constants |
---|
| 233 | Variable vz_1 = 3.956e5 //velocity [cm/s] of 1 A neutron |
---|
| 234 | Variable g = 981.0 //gravity acceleration [cm/s^2] |
---|
[708] | 235 | Variable m_h = 252.8 // m/h [=] s/cm^2 |
---|
[509] | 236 | |
---|
| 237 | String results |
---|
| 238 | results ="Failure" |
---|
| 239 | |
---|
| 240 | S1 *= 0.5*0.1 //convert to radius and [cm] |
---|
| 241 | S2 *= 0.5*0.1 |
---|
| 242 | |
---|
| 243 | L1 *= 100.0 // [cm] |
---|
| 244 | L1 -= apOff //correct the distance |
---|
| 245 | |
---|
| 246 | L2 *= 100.0 |
---|
| 247 | L2 += apOff |
---|
| 248 | del_r *= 0.1 //width of annulus, convert mm to [cm] |
---|
| 249 | |
---|
| 250 | BS *= 0.5*0.1 //nominal BS diameter passed in, convert to radius and [cm] |
---|
| 251 | // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture |
---|
| 252 | Variable LB |
---|
| 253 | LB = 20.1 + 1.61*BS //distance in cm from beamstop to anode plane (empirical) |
---|
| 254 | BS = bs + bs*lb/(l2-lb) //adjusted diameter of shadow from parallax |
---|
| 255 | |
---|
| 256 | //Start resolution calculation |
---|
| 257 | a2 = S1*L2/L1 + S2*(L1+L2)/L1 |
---|
| 258 | lp = 1.0/( 1.0/L1 + 1.0/L2) |
---|
| 259 | |
---|
| 260 | v_lambda = lambdaWidth^2/6.0 |
---|
| 261 | |
---|
| 262 | // if(usingLenses==1) //SRK 2007 |
---|
| 263 | if(usingLenses != 0) //SRK 2008 allows for the possibility of different numbers of lenses in header |
---|
| 264 | v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2 //correction to 2nd term |
---|
| 265 | else |
---|
| 266 | v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2 //original form |
---|
| 267 | endif |
---|
| 268 | |
---|
| 269 | v_d = (DDet/2.3548)^2 + del_r^2/12.0 |
---|
| 270 | vz = vz_1 / lambda |
---|
| 271 | yg = 0.5*g*L2*(L1+L2)/vz^2 |
---|
| 272 | v_g = 2.0*(2.0*yg^2*v_lambda) //factor of 2 correction, B. Hammouda, 2007 |
---|
| 273 | |
---|
| 274 | r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) )) |
---|
| 275 | delta = 0.5*(BS - r0)^2/v_d |
---|
| 276 | |
---|
| 277 | if (r0 < BS) |
---|
| 278 | inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta)) |
---|
| 279 | else |
---|
| 280 | inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta)) |
---|
| 281 | endif |
---|
| 282 | |
---|
| 283 | fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) ) |
---|
| 284 | if (fSubS <= 0.0) |
---|
| 285 | fSubS = 1.e-10 |
---|
| 286 | endif |
---|
| 287 | // fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi)) |
---|
| 288 | // fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d |
---|
| 289 | // |
---|
| 290 | // rmd = fr*r0 |
---|
| 291 | // v_r1 = v_b + fv*v_d +v_g |
---|
| 292 | // |
---|
| 293 | // rm = rmd + 0.5*v_r1/rmd |
---|
| 294 | // v_r = v_r1 - 0.5*(v_r1/rmd)^2 |
---|
| 295 | // if (v_r < 0.0) |
---|
| 296 | // v_r = 0.0 |
---|
| 297 | // endif |
---|
| 298 | |
---|
[794] | 299 | Variable kap,a_val,a_val_L2,proj_DDet |
---|
[509] | 300 | |
---|
| 301 | kap = 2*pi/lambda |
---|
[708] | 302 | a_val = L2*(L1+L2)*g/2*(m_h)^2 |
---|
| 303 | a_val_L2 = a_val/L2*1e-16 //convert 1/cm^2 to 1/A^2 |
---|
[515] | 304 | |
---|
[509] | 305 | |
---|
[827] | 306 | // the detector pixel is square, so correct for phi |
---|
| 307 | proj_DDet = DDet*cos(phi) + DDet*sin(phi) |
---|
[509] | 308 | |
---|
| 309 | |
---|
[827] | 310 | ///////// OLD - don't use --- |
---|
| 311 | //in terms of Q_parallel ("x") and Q_perp ("y") - this works, since parallel is in the direction of Q and I |
---|
| 312 | // can calculate that from the QxQy (I just need the projection) |
---|
[813] | 313 | //// for test case with no gravity, set a_val = 0 |
---|
| 314 | //// note that gravity has no wavelength dependence. the lambda^4 cancels out. |
---|
| 315 | //// |
---|
| 316 | //// a_val = 0 |
---|
| 317 | //// a_val_l2 = 0 |
---|
[708] | 318 | // |
---|
[813] | 319 | // |
---|
| 320 | // // this is really sigma_Q_parallel |
---|
| 321 | // SigmaQX = kap*kap/12 * (3*(S1/L1)^2 + 3*(S2/LP)^2 + (proj_DDet/L2)^2 + (sin(phi))^2*8*(a_val_L2)^2*lambda^4*lambdaWidth^2) |
---|
| 322 | // SigmaQX += inQ*inQ*v_lambda |
---|
| 323 | // |
---|
| 324 | // //this is really sigma_Q_perpendicular |
---|
| 325 | // proj_DDet = DDet*sin(phi) + DDet*cos(phi) //not necessary, since DDet is the same in both X and Y directions |
---|
| 326 | // |
---|
| 327 | // SigmaQY = kap*kap/12 * (3*(S1/L1)^2 + 3*(S2/LP)^2 + (proj_DDet/L2)^2 + (cos(phi))^2*8*(a_val_L2)^2*lambda^4*lambdaWidth^2) |
---|
| 328 | // |
---|
| 329 | // SigmaQX = sqrt(SigmaQX) |
---|
| 330 | // SigmaQy = sqrt(SigmaQY) |
---|
| 331 | // |
---|
[708] | 332 | |
---|
[800] | 333 | ///////////////////////////////////////////////// |
---|
[811] | 334 | ///// |
---|
[827] | 335 | // ////// this is all new, inclusion of gravity effect into the parallel component |
---|
| 336 | // perpendicular component is purely geometric, no gravity component |
---|
[838] | 337 | // |
---|
| 338 | // the shadow factor is calculated as above -so keep the above calculations, even though |
---|
| 339 | // most of them are redundant. |
---|
| 340 | // |
---|
| 341 | |
---|
[811] | 342 | //// // |
---|
[813] | 343 | Variable yg_d,acc,sdd,ssd,lambda0,DL_L,sig_l |
---|
[827] | 344 | Variable var_qlx,var_qly,var_ql,qx,qy,sig_perp,sig_para, sig_para_new |
---|
[838] | 345 | |
---|
[813] | 346 | G = 981. //! ACCELERATION OF GRAVITY, CM/SEC^2 |
---|
| 347 | acc = vz_1 // 3.956E5 //! CONVERT WAVELENGTH TO VELOCITY CM/SEC |
---|
| 348 | SDD = L2 //1317 |
---|
| 349 | SSD = L1 //1627 //cm |
---|
| 350 | lambda0 = lambda // 15 |
---|
| 351 | DL_L = lambdaWidth //0.236 |
---|
| 352 | SIG_L = DL_L/sqrt(6) |
---|
| 353 | YG_d = -0.5*G*SDD*(SSD+SDD)*(LAMBDA0/acc)^2 |
---|
| 354 | ///// Print "DISTANCE BEAM FALLS DUE TO GRAVITY (CM) = ",YG |
---|
[838] | 355 | // Print "Gravity q* = ",-2*pi/lambda0*2*yg_d/sdd |
---|
[800] | 356 | |
---|
[813] | 357 | sig_perp = kap*kap/12 * (3*(S1/L1)^2 + 3*(S2/LP)^2 + (proj_DDet/L2)^2) |
---|
| 358 | sig_perp = sqrt(sig_perp) |
---|
| 359 | |
---|
| 360 | |
---|
| 361 | FindQxQy(inQ,phi,qx,qy) |
---|
[827] | 362 | |
---|
| 363 | // missing a factor of 2 here, and the form is different than the paper, so re-write |
---|
| 364 | // VAR_QLY = SIG_L^2 * (QY+4*PI*YG_d/(2*SDD*LAMBDA0))^2 |
---|
| 365 | // VAR_QLX = (SIG_L*QX)^2 |
---|
| 366 | // VAR_QL = VAR_QLY + VAR_QLX //! WAVELENGTH CONTRIBUTION TO VARIANCE |
---|
| 367 | // sig_para = (sig_perp^2 + VAR_QL)^0.5 |
---|
[813] | 368 | |
---|
[827] | 369 | // r_dist is passed in, [=]cm |
---|
| 370 | // from the paper |
---|
| 371 | a_val = 0.5*G*SDD*(SSD+SDD)*m_h^2 * 1e-16 //units now are cm /(A^2) |
---|
[813] | 372 | |
---|
[827] | 373 | var_QL = 1/6*(kap/SDD)^2*(DL_L)^2*(r_dist^2 - 4*r_dist*a_val*lambda0^2*sin(phi) + 4*a_val^2*lambda0^4) |
---|
| 374 | sig_para_new = (sig_perp^2 + VAR_QL)^0.5 |
---|
| 375 | |
---|
| 376 | |
---|
[813] | 377 | ///// return values PBR |
---|
[827] | 378 | SigmaQX = sig_para_new |
---|
[813] | 379 | SigmaQy = sig_perp |
---|
| 380 | |
---|
| 381 | //// |
---|
| 382 | |
---|
[509] | 383 | results = "success" |
---|
| 384 | Return results |
---|
| 385 | End |
---|
| 386 | |
---|
| 387 | |
---|
| 388 | |
---|
| 389 | |
---|
[82] | 390 | //Utility function that returns the detector resolution (in cm) |
---|
[69] | 391 | //Global values are set in the Initialize procedure |
---|
[79] | 392 | // |
---|
| 393 | // |
---|
| 394 | // - called by CircSectAvg.ipf, RectAnnulAvg.ipf, and ProtocolAsPanel.ipf |
---|
| 395 | // |
---|
[82] | 396 | // fileStr is passed as TextRead[3] |
---|
| 397 | // detStr is passed as TextRead[9] |
---|
| 398 | // |
---|
[247] | 399 | // *** as of Jan 2008, depricated. Now detector pixel sizes are read from the file header |
---|
| 400 | // rw[10] = x size (mm); rw[13] = y size (mm) |
---|
| 401 | // |
---|
| 402 | Function xDetectorPixelResolution(fileStr,detStr) |
---|
[69] | 403 | String fileStr,detStr |
---|
| 404 | |
---|
| 405 | Variable DDet |
---|
| 406 | String instr=fileStr[1,3] //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total) |
---|
| 407 | |
---|
| 408 | NVAR PixelResNG3_ILL = root:myGlobals:PixelResNG3_ILL //pixel resolution in cm |
---|
| 409 | NVAR PixelResNG5_ILL = root:myGlobals:PixelResNG5_ILL |
---|
| 410 | NVAR PixelResNG7_ILL = root:myGlobals:PixelResNG7_ILL |
---|
| 411 | NVAR PixelResNG3_ORNL = root:myGlobals:PixelResNG3_ORNL |
---|
| 412 | NVAR PixelResNG5_ORNL = root:myGlobals:PixelResNG5_ORNL |
---|
| 413 | NVAR PixelResNG7_ORNL = root:myGlobals:PixelResNG7_ORNL |
---|
| 414 | NVAR PixelResDefault = root:myGlobals:PixelResDefault |
---|
| 415 | |
---|
| 416 | strswitch(instr) |
---|
| 417 | case "NG3": |
---|
| 418 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 419 | DDet= PixelResNG3_ILL |
---|
| 420 | else |
---|
| 421 | DDet = PixelResNG3_ORNL //detector is ordella-type |
---|
| 422 | endif |
---|
| 423 | break |
---|
| 424 | case "NG5": |
---|
| 425 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 426 | DDet= PixelResNG5_ILL |
---|
| 427 | else |
---|
| 428 | DDet = PixelResNG5_ORNL //detector is ordella-type |
---|
| 429 | endif |
---|
| 430 | break |
---|
| 431 | case "NG7": |
---|
| 432 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 433 | DDet= PixelResNG7_ILL |
---|
| 434 | else |
---|
| 435 | DDet = PixelResNG7_ORNL //detector is ordella-type |
---|
| 436 | endif |
---|
| 437 | break |
---|
| 438 | default: |
---|
| 439 | //return error? |
---|
[82] | 440 | DDet = PixelResDefault //0.5 cm, typical for new ORNL detectors |
---|
[69] | 441 | endswitch |
---|
| 442 | |
---|
| 443 | return(DDet) |
---|
| 444 | End |
---|
| 445 | |
---|
[82] | 446 | //Utility function that returns the detector deadtime (in seconds) |
---|
[69] | 447 | //Global values are set in the Initialize procedure |
---|
[79] | 448 | // |
---|
| 449 | // - called by WorkFileUtils.ipf |
---|
| 450 | // |
---|
[82] | 451 | // fileStr is passed as TextRead[3] |
---|
| 452 | // detStr is passed as TextRead[9] |
---|
[788] | 453 | // dateAndTimeStr is passed as TextRead[1] |
---|
| 454 | // --- if no date/time string is passed, ICE values are the default |
---|
[79] | 455 | // |
---|
[788] | 456 | // Due to the switch from VAX -> ICE, there were some hardware changes that led to |
---|
| 457 | // a change in the effective detector dead time. The dead time was re-measured by J. Barker |
---|
| 458 | // as follows: |
---|
| 459 | // Instrument Date measured deadtime constant |
---|
| 460 | // NG3 DECEMBER 2009 1.5 microseconds |
---|
| 461 | // NG7 APRIL2010 2.3 microseconds |
---|
| 462 | // |
---|
| 463 | // The day of the switch to ICE on NG7 was 25-FEB-2010 (per J. Krzywon) |
---|
| 464 | // The day of the switch to ICE on NG3 was 23-JUL-2009 (per C. Gagnon) |
---|
| 465 | // |
---|
| 466 | // so any data after these dates is to use the new dead time constant. The switch is made on the |
---|
| 467 | // data collection date. |
---|
| 468 | // |
---|
| 469 | // |
---|
| 470 | Function DetectorDeadtime(fileStr,detStr,[dateAndTimeStr]) |
---|
| 471 | String fileStr,detStr,dateAndTimeStr |
---|
[69] | 472 | |
---|
| 473 | Variable deadtime |
---|
| 474 | String instr=fileStr[1,3] //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total) |
---|
| 475 | |
---|
| 476 | NVAR DeadtimeNG3_ILL = root:myGlobals:DeadtimeNG3_ILL //pixel resolution in cm |
---|
| 477 | NVAR DeadtimeNG5_ILL = root:myGlobals:DeadtimeNG5_ILL |
---|
| 478 | NVAR DeadtimeNG7_ILL = root:myGlobals:DeadtimeNG7_ILL |
---|
[788] | 479 | NVAR DeadtimeNG3_ORNL_VAX = root:myGlobals:DeadtimeNG3_ORNL_VAX |
---|
| 480 | NVAR DeadtimeNG3_ORNL_ICE = root:myGlobals:DeadtimeNG3_ORNL_ICE |
---|
[69] | 481 | NVAR DeadtimeNG5_ORNL = root:myGlobals:DeadtimeNG5_ORNL |
---|
[788] | 482 | NVAR DeadtimeNG7_ORNL_VAX = root:myGlobals:DeadtimeNG7_ORNL_VAX |
---|
| 483 | NVAR DeadtimeNG7_ORNL_ICE = root:myGlobals:DeadtimeNG7_ORNL_ICE |
---|
[69] | 484 | NVAR DeadtimeDefault = root:myGlobals:DeadtimeDefault |
---|
| 485 | |
---|
[788] | 486 | // if no date string is passed, default to the ICE values |
---|
| 487 | if(strlen(dateAndTimeStr)==0) |
---|
| 488 | dateAndTimeStr = "01-JAN-2011" //dummy date to force to ICE values |
---|
| 489 | endif |
---|
| 490 | |
---|
| 491 | |
---|
| 492 | Variable NG3_to_ICE = ConvertVAXDay2secs("23-JUL-2009") |
---|
| 493 | Variable NG7_to_ICE = ConvertVAXDay2secs("25-FEB-2010") |
---|
| 494 | Variable fileTime = ConvertVAXDay2secs(dateAndTimeStr) |
---|
| 495 | |
---|
| 496 | |
---|
[69] | 497 | strswitch(instr) |
---|
| 498 | case "NG3": |
---|
| 499 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 500 | deadtime= DeadtimeNG3_ILL |
---|
| 501 | else |
---|
[788] | 502 | if(fileTime > NG3_to_ICE) |
---|
| 503 | deadtime = DeadtimeNG3_ORNL_ICE //detector is ordella-type, using ICE hardware |
---|
| 504 | else |
---|
| 505 | deadtime = DeadtimeNG3_ORNL_VAX //detector is ordella-type |
---|
| 506 | endif |
---|
[69] | 507 | endif |
---|
| 508 | break |
---|
| 509 | case "NG5": |
---|
| 510 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 511 | deadtime= DeadtimeNG5_ILL |
---|
| 512 | else |
---|
| 513 | deadtime = DeadtimeNG5_ORNL //detector is ordella-type |
---|
| 514 | endif |
---|
| 515 | break |
---|
| 516 | case "NG7": |
---|
| 517 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 518 | deadtime= DeadtimeNG7_ILL |
---|
| 519 | else |
---|
[788] | 520 | if(fileTime > NG7_to_ICE) |
---|
| 521 | deadtime = DeadtimeNG7_ORNL_ICE //detector is ordella-type, using ICE hardware |
---|
| 522 | else |
---|
| 523 | deadtime = DeadtimeNG7_ORNL_VAX //detector is ordella-type |
---|
| 524 | endif |
---|
[69] | 525 | endif |
---|
| 526 | break |
---|
| 527 | default: |
---|
| 528 | //return error? |
---|
| 529 | deadtime = DeadtimeDefault //1e-6 seconds, typical for new ORNL detectors |
---|
| 530 | endswitch |
---|
| 531 | |
---|
| 532 | return(deadtime) |
---|
| 533 | End |
---|
| 534 | |
---|
[788] | 535 | // converts ONLY DD-MON-YYYY portion of the data collection time |
---|
| 536 | // to a number of seconds from midnight on 1/1/1904, as Igor likes to do |
---|
| 537 | // |
---|
| 538 | // dateAndTime is the full string of "dd-mon-yyyy hh:mm:ss" as returned by the function |
---|
| 539 | // getFileCreationDate(file) |
---|
| 540 | // |
---|
| 541 | Function ConvertVAXDay2secs(dateAndTime) |
---|
| 542 | string dateAndTime |
---|
| 543 | |
---|
| 544 | Variable day,yr,mon,time_secs |
---|
| 545 | string monStr |
---|
| 546 | |
---|
| 547 | sscanf dateandtime,"%d-%3s-%4d",day,monStr,yr |
---|
| 548 | mon = monStr2num(monStr) |
---|
| 549 | // print yr,mon,day |
---|
| 550 | time_secs = date2secs(yr,mon,day) |
---|
| 551 | |
---|
| 552 | return(time_secs) |
---|
| 553 | end |
---|
| 554 | |
---|
[801] | 555 | // dd-mon-yyyy hh:mm:ss -> seconds |
---|
| 556 | // the VAX uses 24 hr time for hh |
---|
| 557 | // |
---|
| 558 | Function ConvertVAXDateTime2secs(dateAndTime) |
---|
| 559 | string dateAndTime |
---|
| 560 | |
---|
| 561 | Variable day,yr,mon,hh,mm,ss,time_secs |
---|
| 562 | string str,monStr |
---|
| 563 | |
---|
| 564 | str=dateandtime |
---|
| 565 | sscanf str,"%d-%3s-%4d %d:%d:%d",day,monStr,yr,hh,mm,ss |
---|
| 566 | mon = monStr2num(monStr) |
---|
| 567 | // print yr,mon,day,hh,mm,ss |
---|
| 568 | time_secs = date2secs(yr,mon,day) |
---|
| 569 | time_secs += hh*3600 + mm*60 + ss |
---|
| 570 | |
---|
| 571 | |
---|
| 572 | return(time_secs) |
---|
| 573 | end |
---|
| 574 | |
---|
[788] | 575 | // takes a month string and returns the corresponding number |
---|
| 576 | // |
---|
| 577 | Function monStr2num(monStr) |
---|
| 578 | String monStr |
---|
| 579 | |
---|
| 580 | String list=";JAN;FEB;MAR;APR;MAY;JUN;JUL;AUG;SEP;OCT;NOV;DEC;" |
---|
| 581 | return(WhichListItem(monStr, list ,";")) |
---|
| 582 | end |
---|
| 583 | |
---|
| 584 | |
---|
[715] | 585 | //make a three character string of the run number |
---|
| 586 | //Moved to facility utils |
---|
| 587 | Function/S RunDigitString(num) |
---|
| 588 | Variable num |
---|
| 589 | |
---|
| 590 | String numStr="" |
---|
| 591 | if(num<10) |
---|
| 592 | numStr = "00"+num2str(num) |
---|
| 593 | else |
---|
| 594 | if(num<100) |
---|
| 595 | numStr = "0"+num2str(num) |
---|
| 596 | else |
---|
| 597 | numStr = num2str(num) |
---|
| 598 | Endif |
---|
| 599 | Endif |
---|
| 600 | //Print "numstr = ",numstr |
---|
| 601 | return(numstr) |
---|
| 602 | End |
---|
[69] | 603 | |
---|
[715] | 604 | //given a filename of a SANS data filename of the form |
---|
| 605 | //TTTTTnnn.SAn_TTT_Txxx |
---|
| 606 | //returns the prefix "TTTTT" as some number of characters |
---|
| 607 | //returns "" as an invalid file prefix |
---|
| 608 | // |
---|
[750] | 609 | // NCNR-specifc, does not really belong here - but it's a beta procedure used for the |
---|
| 610 | // Combine Files Panel |
---|
[715] | 611 | // |
---|
| 612 | Function/S GetPrefixStrFromFile(item) |
---|
| 613 | String item |
---|
| 614 | String invalid = "" //"" is not a valid run prefix, since it's text |
---|
| 615 | Variable num=-1 |
---|
| 616 | |
---|
| 617 | //find the "dot" |
---|
| 618 | String runStr="" |
---|
| 619 | Variable pos = strsearch(item,".",0) |
---|
| 620 | if(pos == -1) |
---|
| 621 | //"dot" not found |
---|
| 622 | return (invalid) |
---|
| 623 | else |
---|
| 624 | //found, skip the three characters preceeding it |
---|
| 625 | if (pos <=3) |
---|
| 626 | //not enough characters |
---|
| 627 | return (invalid) |
---|
| 628 | else |
---|
| 629 | runStr = item[0,pos-4] |
---|
| 630 | return (runStr) |
---|
| 631 | Endif |
---|
| 632 | Endif |
---|
| 633 | End |
---|
| 634 | |
---|
| 635 | |
---|
| 636 | |
---|
| 637 | |
---|
[69] | 638 | /////VAX filename/Run number parsing utilities |
---|
| 639 | // |
---|
[79] | 640 | // a collection of uilities for processing vax filenames |
---|
[69] | 641 | //and processing lists (especially for display in popup menus) |
---|
| 642 | // |
---|
| 643 | //required to correctly account for VAX supplied version numbers, which |
---|
| 644 | //may or may not be removed by the ftp utility |
---|
| 645 | // |
---|
| 646 | // - parses lists of run numbers into real filenames |
---|
| 647 | // - selects proper detector constants |
---|
| 648 | // |
---|
| 649 | //************************** |
---|
[79] | 650 | // |
---|
[69] | 651 | //given a filename of a SANS data filename of the form |
---|
| 652 | //TTTTTnnn.SAn_TTT_Txxx |
---|
| 653 | //returns the run number "nnn" as a number |
---|
| 654 | //returns -1 as an invalid file number |
---|
[79] | 655 | // |
---|
| 656 | // called by several ipfs |
---|
| 657 | // |
---|
| 658 | // |
---|
[69] | 659 | Function GetRunNumFromFile(item) |
---|
| 660 | String item |
---|
| 661 | Variable invalid = -1 //negative numbers are invalid |
---|
| 662 | Variable num=-1 |
---|
| 663 | |
---|
| 664 | //find the "dot" |
---|
| 665 | String runStr="" |
---|
| 666 | Variable pos = strsearch(item,".",0) |
---|
| 667 | if(pos == -1) |
---|
| 668 | //"dot" not found |
---|
| 669 | return (invalid) |
---|
| 670 | else |
---|
| 671 | //found, get the three characters preceeding it |
---|
| 672 | if (pos <=2) |
---|
| 673 | //not enough characters |
---|
| 674 | return (invalid) |
---|
| 675 | else |
---|
| 676 | runStr = item[pos-3,pos-1] |
---|
| 677 | //convert to a number |
---|
| 678 | num = str2num(runStr) |
---|
| 679 | //if valid, return it |
---|
| 680 | if (num == NaN) |
---|
| 681 | //3 characters were not a number |
---|
| 682 | return (invalid) |
---|
| 683 | else |
---|
| 684 | //run was OK |
---|
| 685 | return (num) |
---|
| 686 | Endif |
---|
| 687 | Endif |
---|
| 688 | Endif |
---|
| 689 | End |
---|
| 690 | |
---|
| 691 | //given a filename of a SANS data filename of the form |
---|
| 692 | //TTTTTnnn.SAn_TTT_Txxx |
---|
| 693 | //returns the run number "nnn" as a STRING of THREE characters |
---|
| 694 | //returns "ABC" as an invalid file number |
---|
[79] | 695 | // |
---|
| 696 | // local function to aid in locating files by run number |
---|
| 697 | // |
---|
[69] | 698 | Function/S GetRunNumStrFromFile(item) |
---|
| 699 | String item |
---|
| 700 | String invalid = "ABC" //"ABC" is not a valid run number, since it's text |
---|
| 701 | Variable num=-1 |
---|
| 702 | |
---|
| 703 | //find the "dot" |
---|
| 704 | String runStr="" |
---|
| 705 | Variable pos = strsearch(item,".",0) |
---|
| 706 | if(pos == -1) |
---|
| 707 | //"dot" not found |
---|
| 708 | return (invalid) |
---|
| 709 | else |
---|
| 710 | //found, get the three characters preceeding it |
---|
| 711 | if (pos <=2) |
---|
| 712 | //not enough characters |
---|
| 713 | return (invalid) |
---|
| 714 | else |
---|
| 715 | runStr = item[pos-3,pos-1] |
---|
| 716 | return (runStr) |
---|
| 717 | Endif |
---|
| 718 | Endif |
---|
| 719 | End |
---|
| 720 | |
---|
[79] | 721 | //returns a string containing the full path to the file containing the |
---|
[69] | 722 | //run number "num". The null string is returned if no valid file can be found |
---|
| 723 | //the path "catPathName" used and is hard-wired, will abort if this path does not exist |
---|
| 724 | //the file returned will be a RAW SANS data file, other types of files are |
---|
| 725 | //filtered out. |
---|
[79] | 726 | // |
---|
| 727 | // called by Buttons.ipf and Transmission.ipf, and locally by parsing routines |
---|
| 728 | // |
---|
[69] | 729 | Function/S FindFileFromRunNumber(num) |
---|
| 730 | Variable num |
---|
| 731 | |
---|
| 732 | String fullName="",partialName="",item="" |
---|
| 733 | //get list of raw data files in folder that match "num" (add leading zeros) |
---|
| 734 | if( (num>999) || (num<=0) ) |
---|
| 735 | //Print "error in FindFileFromRunNumber(num), file number too large or too small" |
---|
| 736 | Return ("") |
---|
| 737 | Endif |
---|
| 738 | //make a three character string of the run number |
---|
| 739 | String numStr="" |
---|
| 740 | if(num<10) |
---|
| 741 | numStr = "00"+num2str(num) |
---|
| 742 | else |
---|
| 743 | if(num<100) |
---|
| 744 | numStr = "0"+num2str(num) |
---|
| 745 | else |
---|
| 746 | numStr = num2str(num) |
---|
| 747 | Endif |
---|
| 748 | Endif |
---|
| 749 | //Print "numstr = ",numstr |
---|
| 750 | |
---|
| 751 | //make sure that path exists |
---|
| 752 | PathInfo catPathName |
---|
| 753 | String path = S_path |
---|
| 754 | if (V_flag == 0) |
---|
| 755 | Abort "folder path does not exist - use Pick Path button" |
---|
| 756 | Endif |
---|
| 757 | String list="",newList="",testStr="" |
---|
| 758 | |
---|
| 759 | list = IndexedFile(catPathName,-1,"????") //get all files in folder |
---|
| 760 | //find (the) one with the number in the run # location in the name |
---|
| 761 | Variable numItems,ii,runFound,isRAW |
---|
| 762 | numItems = ItemsInList(list,";") //get the new number of items in the list |
---|
| 763 | ii=0 |
---|
| 764 | do |
---|
| 765 | //parse through the list in this order: |
---|
| 766 | // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy" |
---|
| 767 | // 2 - exclude by isRaw? (to minimize disk access) |
---|
| 768 | item = StringFromList(ii, list ,";" ) |
---|
| 769 | if(strlen(item) != 0) |
---|
| 770 | //find the run number, if it exists as a three character string |
---|
| 771 | testStr = GetRunNumStrFromFile(item) |
---|
| 772 | runFound= cmpstr(numStr,testStr) //compare the three character strings, 0 if equal |
---|
| 773 | if(runFound == 0) |
---|
| 774 | //the run Number was found |
---|
| 775 | //build valid filename |
---|
| 776 | partialName = FindValidFileName(item) |
---|
| 777 | if(strlen(partialName) != 0) //non-null return from FindValidFileName() |
---|
| 778 | fullName = path + partialName |
---|
| 779 | //check if RAW, if so,this must be the file! |
---|
| 780 | isRAW = CheckIfRawData(fullName) |
---|
| 781 | if(isRaw) |
---|
| 782 | //stop here |
---|
| 783 | return(fullname) |
---|
| 784 | Endif |
---|
| 785 | Endif |
---|
| 786 | Endif |
---|
| 787 | Endif |
---|
| 788 | ii+=1 |
---|
| 789 | while(ii<numItems) //process all items in list |
---|
| 790 | Return ("") //null return if file not found in list |
---|
| 791 | End |
---|
| 792 | |
---|
| 793 | //function to test a binary file to see if it is a RAW binary SANS file |
---|
| 794 | //first checks the total bytes in the file (which for raw data is 33316 bytes) |
---|
| 795 | //**note that the "DIV" file will also show up as a raw file by the run field |
---|
| 796 | //should be listed in CAT/SHORT and in patch windows |
---|
| 797 | // |
---|
| 798 | //Function then checks the file fname (full path:file) for "RAW" run.type field |
---|
| 799 | //if not found, the data is not raw data and zero is returned |
---|
[79] | 800 | // |
---|
| 801 | // called by many procedures (both external and local) |
---|
| 802 | // |
---|
[69] | 803 | Function CheckIfRawData(fname) |
---|
| 804 | String fname |
---|
| 805 | |
---|
| 806 | Variable refnum,totalBytes |
---|
| 807 | String testStr="" |
---|
| 808 | |
---|
| 809 | Open/R/T="????TEXT" refNum as fname |
---|
[541] | 810 | if(strlen(s_filename) == 0) //user cancel (/Z not used, so V_flag not set) |
---|
| 811 | return(0) |
---|
| 812 | endif |
---|
| 813 | |
---|
[79] | 814 | //get the total number of bytes in the file |
---|
[69] | 815 | FStatus refNum |
---|
| 816 | totalBytes = V_logEOF |
---|
| 817 | //Print totalBytes |
---|
[377] | 818 | if(totalBytes < 100) |
---|
| 819 | Close refNum |
---|
| 820 | return(0) //not a raw file |
---|
| 821 | endif |
---|
[69] | 822 | FSetPos refNum,75 |
---|
| 823 | FReadLine/N=3 refNum,testStr |
---|
| 824 | Close refNum |
---|
| 825 | |
---|
[577] | 826 | if(totalBytes == 33316 && ( cmpstr(testStr,"RAW")==0 || cmpstr(testStr,"SIM")==0)) |
---|
[69] | 827 | //true, is raw data file |
---|
| 828 | Return(1) |
---|
| 829 | else |
---|
| 830 | //some other file |
---|
| 831 | Return(0) |
---|
| 832 | Endif |
---|
| 833 | End |
---|
| 834 | |
---|
[857] | 835 | //function to test a file to see if it is a DIV file |
---|
| 836 | // |
---|
| 837 | // returns truth 0/1 |
---|
| 838 | // |
---|
| 839 | // called by many procedures (both external and local) |
---|
| 840 | // |
---|
| 841 | Function CheckIfDIVData(fname) |
---|
| 842 | String fname |
---|
| 843 | |
---|
| 844 | |
---|
| 845 | Variable refnum,totalBytes |
---|
| 846 | // String testStr="" |
---|
| 847 | |
---|
| 848 | Open/R/T="????TEXT" refNum as fname |
---|
| 849 | if(strlen(s_filename) == 0) //user cancel (/Z not used, so V_flag not set) |
---|
| 850 | return(0) |
---|
| 851 | endif |
---|
| 852 | |
---|
| 853 | //get the total number of bytes in the file |
---|
| 854 | FStatus refNum |
---|
| 855 | totalBytes = V_logEOF |
---|
| 856 | //Print totalBytes |
---|
| 857 | if(totalBytes < 100) |
---|
| 858 | Close refNum |
---|
| 859 | return(0) //not a raw file |
---|
| 860 | endif |
---|
| 861 | // FSetPos refNum,75 |
---|
| 862 | // FReadLine/N=3 refNum,testStr |
---|
| 863 | Close refNum |
---|
| 864 | |
---|
| 865 | if(totalBytes == 66116) // && ( cmpstr(testStr,"RAW")==0 || cmpstr(testStr,"SIM")==0)) |
---|
| 866 | //true, is raw data file |
---|
| 867 | Return(1) |
---|
| 868 | else |
---|
| 869 | //some other file |
---|
| 870 | Return(0) |
---|
| 871 | Endif |
---|
| 872 | |
---|
| 873 | End |
---|
| 874 | |
---|
[74] | 875 | //function to check the header of a raw data file (full path specified by fname) |
---|
| 876 | //checks the field of the x-position of the beamstop during data collection |
---|
| 877 | //if the x-position is more negative (farther to the left) than xTol(input) |
---|
| 878 | //the the beamstop is "out" and the file is a transmission run and not a scattering run |
---|
| 879 | //xtol typically set at -5 (cm) - trans runs have bs(x) at -10 to -15 cm |
---|
| 880 | // function returns 1 if beamstop is out, 0 if beamstop is in |
---|
| 881 | // |
---|
[82] | 882 | // tolerance is set as a global value "root:myGlobals:BeamstopXTol" |
---|
[79] | 883 | // |
---|
| 884 | // called by Transmission.ipf, CatVSTable.ipf, NSORT.ipf |
---|
| 885 | // |
---|
[82] | 886 | Function isTransFile(fName) |
---|
[74] | 887 | String fname |
---|
| 888 | |
---|
| 889 | Variable refnum,xpos |
---|
[82] | 890 | NVAR xTol = root:myGlobals:BeamstopXTol |
---|
| 891 | |
---|
[74] | 892 | //pos = 369, read one real value |
---|
| 893 | |
---|
| 894 | SetDataFolder root: |
---|
| 895 | String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q" |
---|
| 896 | String strToExecute="" |
---|
| 897 | // 1 R*4 value |
---|
| 898 | strToExecute = GBLoadStr + "/S=368/U=1" + "\"" + fname + "\"" |
---|
| 899 | Execute strToExecute |
---|
| 900 | Wave w=$"root:tempGBWave0" |
---|
| 901 | xPos = w[0] |
---|
| 902 | KillWaves/Z w |
---|
| 903 | //Print "xPos = ",xpos |
---|
| 904 | |
---|
| 905 | if(xpos<=xTol) |
---|
| 906 | //xpos is farther left (more negative) than xtol (currently -5 cm) |
---|
| 907 | Return(1) |
---|
| 908 | else |
---|
| 909 | //some other file |
---|
| 910 | Return(0) |
---|
| 911 | Endif |
---|
| 912 | End |
---|
| 913 | |
---|
| 914 | |
---|
[69] | 915 | //function to remove all spaces from names when searching for filenames |
---|
| 916 | //the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn) |
---|
| 917 | //but the text field in the header WILL, if less than 3 characters were used for the |
---|
| 918 | //user's initials, and can have leading spaces if prefix was less than 5 characters |
---|
| 919 | // |
---|
| 920 | //returns a string identical to the original string, except with the interior spaces removed |
---|
| 921 | // |
---|
[79] | 922 | // local function for file name manipulation |
---|
| 923 | // |
---|
[69] | 924 | Function/S RemoveAllSpaces(str) |
---|
| 925 | String str |
---|
| 926 | |
---|
| 927 | String tempstr = str |
---|
| 928 | Variable ii,spc,len //should never be more than 2 or 3 trailing spaces in a filename |
---|
| 929 | ii=0 |
---|
| 930 | do |
---|
| 931 | len = strlen(tempStr) |
---|
| 932 | spc = strsearch(tempStr," ",0) //is the last character a space? |
---|
| 933 | if (spc == -1) |
---|
| 934 | break //no more spaces found, get out |
---|
| 935 | endif |
---|
| 936 | str = tempstr |
---|
| 937 | tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string |
---|
| 938 | While(1) //should never be more than 2 or 3 |
---|
| 939 | |
---|
| 940 | If(strlen(tempStr) < 1) |
---|
| 941 | tempStr = "" //be sure to return a null string if problem found |
---|
| 942 | Endif |
---|
| 943 | |
---|
| 944 | //Print strlen(tempstr) |
---|
| 945 | |
---|
| 946 | Return(tempStr) |
---|
| 947 | |
---|
| 948 | End |
---|
| 949 | |
---|
| 950 | |
---|
[79] | 951 | //Function attempts to find valid filename from partial name by checking for |
---|
| 952 | // the existence of the file on disk. |
---|
| 953 | // - checks as is |
---|
| 954 | // - adds ";vers" for possible VAX files |
---|
| 955 | // - strips spaces |
---|
| 956 | // - permutations of upper/lowercase |
---|
[69] | 957 | // |
---|
| 958 | // added 11/99 - uppercase and lowercase versions of the file are tried, if necessary |
---|
| 959 | // since from marquee, the filename field (textread[0]) must be used, and can be a mix of |
---|
| 960 | // upper/lowercase letters, while the filename on the server (should) be all caps |
---|
| 961 | // now makes repeated calls to ValidFileString() |
---|
| 962 | // |
---|
[79] | 963 | // returns a valid filename (No path prepended) or a null string |
---|
| 964 | // |
---|
| 965 | // called by any functions, both external and local |
---|
| 966 | // |
---|
[69] | 967 | Function/S FindValidFilename(partialName) |
---|
| 968 | String PartialName |
---|
| 969 | |
---|
| 970 | String retStr="" |
---|
| 971 | |
---|
| 972 | //try name with no changes - to allow for ABS files that have spaces in the names 12APR04 |
---|
| 973 | retStr = ValidFileString(partialName) |
---|
| 974 | if(cmpstr(retStr,"") !=0) |
---|
| 975 | //non-null return |
---|
| 976 | return(retStr) |
---|
| 977 | Endif |
---|
| 978 | |
---|
| 979 | //if the partial name is derived from the file header, there can be spaces at the beginning |
---|
| 980 | //or in the middle of the filename - depending on the prefix and initials used |
---|
| 981 | // |
---|
| 982 | //remove any leading spaces from the name before starting |
---|
| 983 | partialName = RemoveAllSpaces(partialName) |
---|
| 984 | |
---|
| 985 | //try name with no spaces |
---|
| 986 | retStr = ValidFileString(partialName) |
---|
| 987 | if(cmpstr(retStr,"") !=0) |
---|
| 988 | //non-null return |
---|
| 989 | return(retStr) |
---|
| 990 | Endif |
---|
| 991 | |
---|
| 992 | //try all UPPERCASE |
---|
| 993 | partialName = UpperStr(partialName) |
---|
| 994 | retStr = ValidFileString(partialName) |
---|
| 995 | if(cmpstr(retStr,"") !=0) |
---|
| 996 | //non-null return |
---|
| 997 | return(retStr) |
---|
| 998 | Endif |
---|
| 999 | |
---|
| 1000 | //try all lowercase (ret null if failure) |
---|
| 1001 | partialName = LowerStr(partialName) |
---|
| 1002 | retStr = ValidFileString(partialName) |
---|
| 1003 | if(cmpstr(retStr,"") !=0) |
---|
| 1004 | //non-null return |
---|
| 1005 | return(retStr) |
---|
| 1006 | else |
---|
| 1007 | return(retStr) |
---|
| 1008 | Endif |
---|
| 1009 | End |
---|
| 1010 | |
---|
[79] | 1011 | // Function checks for the existence of a file |
---|
| 1012 | // partialName;vers (to account for VAX filenaming conventions) |
---|
| 1013 | // The partial name is tried first with no version number |
---|
[69] | 1014 | // |
---|
[79] | 1015 | // *** the PATH is hard-wired to catPathName (which is assumed to exist) |
---|
| 1016 | // version numers up to ;10 are tried |
---|
| 1017 | // only the "name;vers" is returned if successful. The path is not prepended |
---|
| 1018 | // |
---|
| 1019 | // local function |
---|
| 1020 | // |
---|
[69] | 1021 | Function/S ValidFileString(partialName) |
---|
| 1022 | String partialName |
---|
| 1023 | |
---|
| 1024 | String tempName = "",msg="" |
---|
| 1025 | Variable ii,refnum |
---|
| 1026 | |
---|
| 1027 | ii=0 |
---|
| 1028 | do |
---|
| 1029 | if(ii==0) |
---|
| 1030 | //first pass, try the partialName |
---|
| 1031 | tempName = partialName |
---|
| 1032 | Open/Z/R/T="????TEXT"/P=catPathName refnum tempName //Does open file (/Z flag) |
---|
| 1033 | if(V_flag == 0) |
---|
| 1034 | //file exists |
---|
| 1035 | Close refnum //YES needed, |
---|
| 1036 | break |
---|
| 1037 | endif |
---|
| 1038 | else |
---|
| 1039 | tempName = partialName + ";" + num2str(ii) |
---|
| 1040 | Open/Z/R/T="????TEXT"/P=catPathName refnum tempName |
---|
| 1041 | if(V_flag == 0) |
---|
| 1042 | //file exists |
---|
| 1043 | Close refnum |
---|
| 1044 | break |
---|
| 1045 | endif |
---|
| 1046 | Endif |
---|
| 1047 | ii+=1 |
---|
| 1048 | //print "ii=",ii |
---|
| 1049 | while(ii<11) |
---|
| 1050 | //go get the selected bits of information, using tempName, which exists |
---|
| 1051 | if(ii>=11) |
---|
| 1052 | //msg = partialName + " not found. is version number > 11?" |
---|
| 1053 | //DoAlert 0, msg |
---|
| 1054 | //PathInfo catPathName |
---|
| 1055 | //Print S_Path |
---|
| 1056 | Return ("") //use null string as error condition |
---|
| 1057 | Endif |
---|
| 1058 | |
---|
| 1059 | Return (tempName) |
---|
| 1060 | End |
---|
| 1061 | |
---|
| 1062 | //returns a string containing filename (WITHOUT the ;vers) |
---|
| 1063 | //the input string is a full path to the file (Mac-style, still works on Win in IGOR) |
---|
| 1064 | //with the folders separated by colons |
---|
[79] | 1065 | // |
---|
| 1066 | // called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf |
---|
| 1067 | // |
---|
[69] | 1068 | Function/S GetFileNameFromPathNoSemi(fullPath) |
---|
| 1069 | String fullPath |
---|
| 1070 | |
---|
| 1071 | Variable offset1,offset2 |
---|
| 1072 | String filename="" |
---|
| 1073 | //String PartialPath |
---|
| 1074 | offset1 = 0 |
---|
| 1075 | do |
---|
| 1076 | offset2 = StrSearch(fullPath, ":", offset1) |
---|
| 1077 | if (offset2 == -1) // no more colons ? |
---|
| 1078 | fileName = FullPath[offset1,strlen(FullPath) ] |
---|
| 1079 | //PartialPath = FullPath[0, offset1-1] |
---|
| 1080 | break |
---|
| 1081 | endif |
---|
| 1082 | offset1 = offset2+1 |
---|
| 1083 | while (1) |
---|
| 1084 | |
---|
| 1085 | //remove version number from name, if it's there - format should be: filename;N |
---|
| 1086 | filename = StringFromList(0,filename,";") //returns null if error |
---|
| 1087 | |
---|
| 1088 | Return filename |
---|
| 1089 | End |
---|
| 1090 | |
---|
| 1091 | //returns a string containing filename (INCLUDING the ;vers) |
---|
| 1092 | //the input string is a full path to the file (Mac-style, still works on Win in IGOR) |
---|
| 1093 | //with the folders separated by colons |
---|
[79] | 1094 | // |
---|
| 1095 | // local, currently unused |
---|
| 1096 | // |
---|
[69] | 1097 | Function/S GetFileNameFromPathKeepSemi(fullPath) |
---|
| 1098 | String fullPath |
---|
| 1099 | |
---|
| 1100 | Variable offset1,offset2 |
---|
| 1101 | String filename |
---|
| 1102 | //String PartialPath |
---|
| 1103 | offset1 = 0 |
---|
| 1104 | do |
---|
| 1105 | offset2 = StrSearch(fullPath, ":", offset1) |
---|
| 1106 | if (offset2 == -1) // no more colons ? |
---|
| 1107 | fileName = FullPath[offset1,strlen(FullPath) ] |
---|
| 1108 | //PartialPath = FullPath[0, offset1-1] |
---|
| 1109 | break |
---|
| 1110 | endif |
---|
| 1111 | offset1 = offset2+1 |
---|
| 1112 | while (1) |
---|
| 1113 | |
---|
| 1114 | //keep version number from name, if it's there - format should be: filename;N |
---|
| 1115 | |
---|
| 1116 | Return filename |
---|
| 1117 | End |
---|
| 1118 | |
---|
| 1119 | //given the full path and filename (fullPath), strips the data path |
---|
| 1120 | //(Mac-style, separated by colons) and returns this path |
---|
| 1121 | //this partial path is the same string that would be returned from PathInfo, for example |
---|
[79] | 1122 | // |
---|
| 1123 | // - allows the user to save to a different path than catPathName |
---|
| 1124 | // |
---|
| 1125 | // called by WriteQIS.ipf |
---|
| 1126 | // |
---|
[69] | 1127 | Function/S GetPathStrFromfullName(fullPath) |
---|
| 1128 | String fullPath |
---|
| 1129 | |
---|
| 1130 | Variable offset1,offset2 |
---|
| 1131 | //String filename |
---|
| 1132 | String PartialPath |
---|
| 1133 | offset1 = 0 |
---|
| 1134 | do |
---|
| 1135 | offset2 = StrSearch(fullPath, ":", offset1) |
---|
| 1136 | if (offset2 == -1) // no more colons ? |
---|
| 1137 | //fileName = FullPath[offset1,strlen(FullPath) ] |
---|
| 1138 | PartialPath = FullPath[0, offset1-1] |
---|
| 1139 | break |
---|
| 1140 | endif |
---|
| 1141 | offset1 = offset2+1 |
---|
| 1142 | while (1) |
---|
| 1143 | |
---|
| 1144 | Return PartialPath |
---|
| 1145 | End |
---|
| 1146 | |
---|
| 1147 | //given the VAX filename, pull off the first 8 characters to make a valid |
---|
| 1148 | //file string that can be used for naming averaged 1-d files |
---|
[79] | 1149 | // |
---|
| 1150 | // called by ProtocolAsPanel.ipf and Tile_2D.ipf |
---|
| 1151 | // |
---|
[69] | 1152 | Function/S GetNameFromHeader(fullName) |
---|
| 1153 | String fullName |
---|
| 1154 | String temp, newName = "" |
---|
| 1155 | Variable spc,ii=0 |
---|
| 1156 | |
---|
| 1157 | //filename is 20 characters NNNNNxxx.SAn_NNN_NNN |
---|
| 1158 | //want the first 8 characters, NNNNNxxx, then strip off any spaces at the beginning |
---|
| 1159 | //NNNNN was entered as less than 5 characters |
---|
| 1160 | //returns a null string if no name can be found |
---|
| 1161 | do |
---|
| 1162 | temp = fullname[ii,7] //characters ii,7 of the name |
---|
| 1163 | spc = strsearch(temp," ",0) |
---|
| 1164 | if (spc == -1) |
---|
| 1165 | break //no more spaces found |
---|
| 1166 | endif |
---|
| 1167 | ii+=1 |
---|
| 1168 | While(ii<8) |
---|
| 1169 | |
---|
| 1170 | If(strlen(temp) < 1) |
---|
| 1171 | newName = "" //be sure to return a null string if problem found |
---|
| 1172 | else |
---|
| 1173 | newName = temp |
---|
| 1174 | Endif |
---|
| 1175 | |
---|
| 1176 | Return(newName) |
---|
| 1177 | End |
---|
| 1178 | |
---|
| 1179 | //list (input) is a list, typically returned from IndexedFile() |
---|
[79] | 1180 | //which is semicolon-delimited, and may contain filenames from the VAX |
---|
[69] | 1181 | //that contain version numbers, where the version number appears as a separate list item |
---|
| 1182 | //(and also as a non-existent file) |
---|
| 1183 | //these numbers must be purged from the list, especially for display in a popup |
---|
| 1184 | //or list processing of filenames |
---|
| 1185 | //the function returns the list, cleaned of version numbers (up to 11) |
---|
| 1186 | //raw data files will typically never have a version number other than 1. |
---|
[79] | 1187 | // |
---|
| 1188 | // if there are no version numbers in the list, the input list is returned |
---|
| 1189 | // |
---|
| 1190 | // called by CatVSTable.ipf, NSORT.ipf, Transmission.ipf, WorkFileUtils.ipf |
---|
| 1191 | // |
---|
[69] | 1192 | Function/S RemoveVersNumsFromList(list) |
---|
| 1193 | String list |
---|
| 1194 | |
---|
| 1195 | //get rid of version numbers first (up to 11) |
---|
| 1196 | Variable ii,num |
---|
| 1197 | String item |
---|
| 1198 | num = ItemsInList(list,";") |
---|
| 1199 | ii=1 |
---|
| 1200 | do |
---|
| 1201 | item = num2str(ii) |
---|
| 1202 | list = RemoveFromList(item, list ,";" ) |
---|
| 1203 | ii+=1 |
---|
| 1204 | while(ii<12) |
---|
| 1205 | |
---|
| 1206 | return (list) |
---|
| 1207 | End |
---|
| 1208 | |
---|
| 1209 | //input is a list of run numbers, and output is a list of filenames (not the full path) |
---|
| 1210 | //*** input list must be COMMA delimited*** |
---|
| 1211 | //output is equivalent to selecting from the CAT table |
---|
| 1212 | //if some or all of the list items are valid filenames, keep them... |
---|
[79] | 1213 | //if an error is encountered, notify of the offending element and return a null list |
---|
[69] | 1214 | // |
---|
| 1215 | //output is COMMA delimited |
---|
| 1216 | // |
---|
| 1217 | // this routine is expecting that the "ask", "none" special cases are handled elsewhere |
---|
| 1218 | //and not passed here |
---|
[79] | 1219 | // |
---|
| 1220 | // called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf |
---|
| 1221 | // |
---|
[69] | 1222 | Function/S ParseRunNumberList(list) |
---|
| 1223 | String list |
---|
| 1224 | |
---|
| 1225 | String newList="",item="",tempStr="" |
---|
| 1226 | Variable num,ii,runNum |
---|
| 1227 | |
---|
| 1228 | //expand number ranges, if any |
---|
| 1229 | list = ExpandNumRanges(list) |
---|
| 1230 | |
---|
| 1231 | num=itemsinlist(list,",") |
---|
| 1232 | |
---|
| 1233 | for(ii=0;ii<num;ii+=1) |
---|
| 1234 | //get the item |
---|
| 1235 | item = StringFromList(ii,list,",") |
---|
| 1236 | //is it already a valid filename? |
---|
| 1237 | tempStr=FindValidFilename(item) //returns filename if good, null if error |
---|
| 1238 | if(strlen(tempstr)!=0) |
---|
| 1239 | //valid name, add to list |
---|
| 1240 | //Print "it's a file" |
---|
| 1241 | newList += tempStr + "," |
---|
| 1242 | else |
---|
| 1243 | //not a valid name |
---|
| 1244 | //is it a number? |
---|
| 1245 | runNum=str2num(item) |
---|
| 1246 | //print runnum |
---|
| 1247 | if(numtype(runNum) != 0) |
---|
| 1248 | //not a number - maybe an error |
---|
| 1249 | DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename." |
---|
| 1250 | return("") |
---|
| 1251 | else |
---|
| 1252 | //a run number or an error |
---|
| 1253 | tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) ) |
---|
| 1254 | if(strlen(tempstr)==0) |
---|
| 1255 | //file not found, error |
---|
| 1256 | DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number." |
---|
| 1257 | return("") |
---|
| 1258 | else |
---|
| 1259 | newList += tempStr + "," |
---|
| 1260 | endif |
---|
| 1261 | endif |
---|
| 1262 | endif |
---|
| 1263 | endfor //loop over all items in list |
---|
| 1264 | |
---|
| 1265 | return(newList) |
---|
| 1266 | End |
---|
| 1267 | |
---|
| 1268 | //takes a comma delimited list that MAY contain number range, and |
---|
| 1269 | //expands any range of run numbers into a comma-delimited list... |
---|
| 1270 | //and returns the new list - if not a range, return unchanged |
---|
[79] | 1271 | // |
---|
| 1272 | // local function |
---|
| 1273 | // |
---|
[69] | 1274 | Function/S ExpandNumRanges(list) |
---|
| 1275 | String list |
---|
| 1276 | |
---|
| 1277 | String newList="",dash="-",item,str |
---|
| 1278 | Variable num,ii,hasDash |
---|
| 1279 | |
---|
| 1280 | num=itemsinlist(list,",") |
---|
| 1281 | // print num |
---|
| 1282 | for(ii=0;ii<num;ii+=1) |
---|
| 1283 | //get the item |
---|
| 1284 | item = StringFromList(ii,list,",") |
---|
| 1285 | //does it contain a dash? |
---|
| 1286 | hasDash = strsearch(item,dash,0) //-1 if no dash found |
---|
| 1287 | if(hasDash == -1) |
---|
| 1288 | //not a range, keep it in the list |
---|
| 1289 | newList += item + "," |
---|
| 1290 | else |
---|
| 1291 | //has a dash (so it's a range), expand (or add null) |
---|
| 1292 | newList += ListFromDash(item) |
---|
| 1293 | endif |
---|
| 1294 | endfor |
---|
| 1295 | |
---|
| 1296 | return newList |
---|
| 1297 | End |
---|
| 1298 | |
---|
| 1299 | //be sure to add a trailing comma to the return string... |
---|
[79] | 1300 | // |
---|
| 1301 | // local function |
---|
| 1302 | // |
---|
[69] | 1303 | Function/S ListFromDash(item) |
---|
| 1304 | String item |
---|
| 1305 | |
---|
| 1306 | String numList="",loStr="",hiStr="" |
---|
| 1307 | Variable lo,hi,ii |
---|
| 1308 | |
---|
| 1309 | loStr=StringFromList(0,item,"-") //treat the range as a list |
---|
| 1310 | hiStr=StringFromList(1,item,"-") |
---|
| 1311 | lo=str2num(loStr) |
---|
| 1312 | hi=str2num(hiStr) |
---|
| 1313 | if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) ) |
---|
| 1314 | numList="" |
---|
| 1315 | return numList |
---|
| 1316 | endif |
---|
| 1317 | for(ii=lo;ii<=hi;ii+=1) |
---|
| 1318 | numList += num2str(ii) + "," |
---|
| 1319 | endfor |
---|
| 1320 | |
---|
| 1321 | Return numList |
---|
| 1322 | End |
---|
| 1323 | |
---|
| 1324 | |
---|
| 1325 | ////////Transmission |
---|
| 1326 | //****************** |
---|
| 1327 | //lookup tables for attenuator transmissions |
---|
| 1328 | //NG3 and NG7 attenuators are physically different, so the transmissions are slightly different |
---|
| 1329 | //NG1 - (8m SANS) is not supported |
---|
[79] | 1330 | // |
---|
[121] | 1331 | // new calibration done June 2007, John Barker |
---|
[79] | 1332 | // |
---|
[69] | 1333 | Proc MakeNG3AttenTable() |
---|
| 1334 | |
---|
| 1335 | NewDataFolder/O root:myGlobals:Attenuators |
---|
| 1336 | //do explicitly to avoid data folder problems, redundant, but it must work without fail |
---|
[121] | 1337 | Variable num=10 //10 needed for tables after June 2007 |
---|
| 1338 | |
---|
| 1339 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att0 |
---|
| 1340 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att1 |
---|
| 1341 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att2 |
---|
| 1342 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att3 |
---|
| 1343 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att4 |
---|
| 1344 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att5 |
---|
| 1345 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att6 |
---|
| 1346 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att7 |
---|
| 1347 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att8 |
---|
| 1348 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att9 |
---|
| 1349 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att10 |
---|
[69] | 1350 | |
---|
[794] | 1351 | // and a wave for the errors at each attenuation factor |
---|
| 1352 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att0_err |
---|
| 1353 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att1_err |
---|
| 1354 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att2_err |
---|
| 1355 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att3_err |
---|
| 1356 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att4_err |
---|
| 1357 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att5_err |
---|
| 1358 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att6_err |
---|
| 1359 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att7_err |
---|
| 1360 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att8_err |
---|
| 1361 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att9_err |
---|
| 1362 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att10_err |
---|
| 1363 | |
---|
| 1364 | |
---|
[121] | 1365 | //each wave has 10 elements, the transmission of att# at the wavelengths |
---|
| 1366 | //lambda = 4,5,6,7,8,10,12,14,17,20 (4 A and 20 A are extrapolated values) |
---|
| 1367 | Make/O/N=(num) root:myGlobals:Attenuators:ng3lambda={4,5,6,7,8,10,12,14,17,20} |
---|
| 1368 | |
---|
| 1369 | // new calibration done June 2007, John Barker |
---|
| 1370 | root:myGlobals:Attenuators:ng3att0 = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } |
---|
| 1371 | root:myGlobals:Attenuators:ng3att1 = {0.444784,0.419,0.3935,0.3682,0.3492,0.3132,0.2936,0.2767,0.2477,0.22404} |
---|
| 1372 | root:myGlobals:Attenuators:ng3att2 = {0.207506,0.1848,0.1629,0.1447,0.1292,0.1056,0.09263,0.08171,0.06656,0.0546552} |
---|
| 1373 | root:myGlobals:Attenuators:ng3att3 = {0.092412,0.07746,0.06422,0.05379,0.04512,0.03321,0.02707,0.02237,0.01643,0.0121969} |
---|
| 1374 | root:myGlobals:Attenuators:ng3att4 = {0.0417722,0.03302,0.02567,0.02036,0.01604,0.01067,0.00812,0.006316,0.00419,0.00282411} |
---|
| 1375 | root:myGlobals:Attenuators:ng3att5 = {0.0187129,0.01397,0.01017,0.007591,0.005668,0.003377,0.002423,0.001771,0.001064,0.000651257} |
---|
| 1376 | root:myGlobals:Attenuators:ng3att6 = {0.00851048,0.005984,0.004104,0.002888,0.002029,0.001098,0.0007419,0.0005141,0.000272833,0.000150624} |
---|
| 1377 | root:myGlobals:Attenuators:ng3att7 = {0.00170757,0.001084,0.0006469,0.0004142,0.0002607,0.0001201,7.664e-05,4.06624e-05,1.77379e-05,7.30624e-06} |
---|
| 1378 | root:myGlobals:Attenuators:ng3att8 = {0.000320057,0.0001918,0.0001025,6.085e-05,3.681e-05,1.835e-05,6.74002e-06,3.25288e-06,1.15321e-06,3.98173e-07} |
---|
| 1379 | root:myGlobals:Attenuators:ng3att9 = {6.27682e-05,3.69e-05,1.908e-05,1.196e-05,8.738e-06,6.996e-06,6.2901e-07,2.60221e-07,7.49748e-08,2.08029e-08} |
---|
| 1380 | root:myGlobals:Attenuators:ng3att10 = {1.40323e-05,8.51e-06,5.161e-06,4.4e-06,4.273e-06,1.88799e-07,5.87021e-08,2.08169e-08,4.8744e-09,1.08687e-09} |
---|
| 1381 | |
---|
[794] | 1382 | // percent errors as measured, May 2007 values |
---|
| 1383 | // zero error for zero attenuators, appropriate average values put in for unknown values |
---|
| 1384 | root:myGlobals:Attenuators:ng3att0_err = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
---|
| 1385 | root:myGlobals:Attenuators:ng3att1_err = {0.15,0.142,0.154,0.183,0.221,0.328,0.136,0.13,0.163,0.15} |
---|
| 1386 | root:myGlobals:Attenuators:ng3att2_err = {0.25,0.257,0.285,0.223,0.271,0.405,0.212,0.223,0.227,0.25} |
---|
| 1387 | root:myGlobals:Attenuators:ng3att3_err = {0.3,0.295,0.329,0.263,0.323,0.495,0.307,0.28,0.277,0.3} |
---|
| 1388 | root:myGlobals:Attenuators:ng3att4_err = {0.35,0.331,0.374,0.303,0.379,0.598,0.367,0.322,0.33,0.35} |
---|
| 1389 | root:myGlobals:Attenuators:ng3att5_err = {0.4,0.365,0.418,0.355,0.454,0.745,0.411,0.367,0.485,0.4} |
---|
| 1390 | root:myGlobals:Attenuators:ng3att6_err = {0.45,0.406,0.473,0.385,0.498,0.838,0.454,0.49,0.5,0.5} |
---|
| 1391 | root:myGlobals:Attenuators:ng3att7_err = {0.6,0.554,0.692,0.425,0.562,0.991,0.715,0.8,0.8,0.8} |
---|
| 1392 | root:myGlobals:Attenuators:ng3att8_err = {0.7,0.705,0.927,0.503,0.691,1.27,1,1,1,1} |
---|
| 1393 | root:myGlobals:Attenuators:ng3att9_err = {1,0.862,1.172,0.799,1.104,1.891,1.5,1.5,1.5,1.5} |
---|
| 1394 | root:myGlobals:Attenuators:ng3att10_err = {1.5,1.054,1.435,1.354,1.742,2,2,2,2,2} |
---|
| 1395 | |
---|
| 1396 | |
---|
[121] | 1397 | //old tables, pre-June 2007 |
---|
| 1398 | // Make/O/N=9 root:myGlobals:Attenuators:ng3lambda={5,6,7,8,10,12,14,17,20} |
---|
| 1399 | // root:myGlobals:Attenuators:ng3att0 = {1, 1, 1, 1, 1, 1, 1, 1,1 } |
---|
| 1400 | // root:myGlobals:Attenuators:ng3att1 = {0.421, 0.394, 0.371, 0.349, 0.316, 0.293, 0.274, 0.245,0.220} |
---|
| 1401 | // root:myGlobals:Attenuators:ng3att2 = {0.187, 0.164, 0.145, 0.130, 0.106, 0.0916, 0.0808, 0.0651,0.0531} |
---|
| 1402 | // root:myGlobals:Attenuators:ng3att3 = {0.0777, 0.0636, 0.0534, 0.0446, 0.0330, 0.0262, 0.0217, 0.0157 ,0.0116} |
---|
| 1403 | // root:myGlobals:Attenuators:ng3att4 = {0.0328, 0.0252, 0.0195, 0.0156, 0.0104, 7.68e-3, 5.98e-3, 3.91e-3,0.00262} |
---|
| 1404 | // root:myGlobals:Attenuators:ng3att5 = {0.0139, 9.94e-3, 7.34e-3, 5.44e-3, 3.29e-3, 2.25e-3, 1.66e-3, 9.95e-4, 6.12e-4} |
---|
| 1405 | // root:myGlobals:Attenuators:ng3att6 = {5.95e-3, 3.97e-3, 2.77e-3, 1.95e-3, 1.06e-3, 6.81e-4, 4.71e-4, 2.59e-4 , 1.45e-4} |
---|
| 1406 | // root:myGlobals:Attenuators:ng3att7 = {1.07e-3, 6.24e-4, 3.90e-4, 2.44e-4, 1.14e-4, 6.55e-5, 4.10e-5, 1.64e-5 , 7.26e-6} |
---|
| 1407 | // root:myGlobals:Attenuators:ng3att8 = {1.90e-4, 9.84e-5, 5.60e-5, 3.25e-5, 1.55e-5, 6.60e-6, 3.42e-6, 1.04e-6 , 3.48e-7} |
---|
| 1408 | // root:myGlobals:Attenuators:ng3att9 = {3.61e-5, 1.74e-5, 9.90e-6, 6.45e-6, 2.35e-6, 6.35e-7, 2.86e-7, 6.61e-8 , 1.73e-8} |
---|
| 1409 | // root:myGlobals:Attenuators:ng3att10 = {7.60e-6, 3.99e-6, 2.96e-6, 2.03e-6, 3.34e-7, 6.11e-8, 2.39e-8, 4.19e-9 , 8.60e-10} |
---|
[69] | 1410 | |
---|
| 1411 | End |
---|
| 1412 | |
---|
[121] | 1413 | // new calibration done June 2007, John Barker |
---|
[69] | 1414 | Proc MakeNG7AttenTable() |
---|
| 1415 | |
---|
| 1416 | NewDataFolder/O root:myGlobals:Attenuators |
---|
[121] | 1417 | |
---|
| 1418 | Variable num=10 //10 needed for tables after June 2007 |
---|
| 1419 | |
---|
[118] | 1420 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att0 |
---|
| 1421 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att1 |
---|
| 1422 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att2 |
---|
| 1423 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att3 |
---|
| 1424 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att4 |
---|
| 1425 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att5 |
---|
| 1426 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att6 |
---|
| 1427 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att7 |
---|
| 1428 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att8 |
---|
| 1429 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att9 |
---|
| 1430 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att10 |
---|
[69] | 1431 | |
---|
[794] | 1432 | // and a wave for the errors at each attenuation factor |
---|
| 1433 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att0_err |
---|
| 1434 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att1_err |
---|
| 1435 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att2_err |
---|
| 1436 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att3_err |
---|
| 1437 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att4_err |
---|
| 1438 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att5_err |
---|
| 1439 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att6_err |
---|
| 1440 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att7_err |
---|
| 1441 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att8_err |
---|
| 1442 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att9_err |
---|
| 1443 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att10_err |
---|
| 1444 | |
---|
[118] | 1445 | //NG7 wave has 10 elements, the transmission of att# at the wavelengths |
---|
[121] | 1446 | //lambda =4, 5,6,7,8,10,12,14,17,20 |
---|
| 1447 | // note that some of the higher attenuations and ALL of the 4 A and 20A data is interpolated |
---|
[118] | 1448 | // none of these values are expected to be used in reality since the flux would be too low in practice |
---|
| 1449 | Make/O/N=(num) root:myGlobals:Attenuators:ng7lambda={4,5,6,7,8,10,12,14,17,20} |
---|
| 1450 | |
---|
| 1451 | // New calibration, June 2007, John Barker |
---|
| 1452 | root:myGlobals:Attenuators:ng7att0 = {1, 1, 1, 1, 1, 1, 1, 1 ,1,1} |
---|
| 1453 | root:myGlobals:Attenuators:ng7att1 = {0.448656,0.4192,0.3925,0.3661,0.3458,0.3098,0.2922,0.2738,0.2544,0.251352} |
---|
| 1454 | root:myGlobals:Attenuators:ng7att2 = {0.217193,0.1898,0.1682,0.148,0.1321,0.1076,0.0957,0.08485,0.07479,0.0735965} |
---|
| 1455 | root:myGlobals:Attenuators:ng7att3 = {0.098019,0.07877,0.06611,0.05429,0.04548,0.03318,0.02798,0.0234,0.02004,0.0202492} |
---|
| 1456 | root:myGlobals:Attenuators:ng7att4 = {0.0426904,0.03302,0.02617,0.02026,0.0158,0.01052,0.008327,0.006665,0.005745,0.00524807} |
---|
| 1457 | root:myGlobals:Attenuators:ng7att5 = {0.0194353,0.01398,0.01037,0.0075496,0.005542,0.003339,0.002505,0.001936,0.001765,0.00165959} |
---|
| 1458 | root:myGlobals:Attenuators:ng7att6 = {0.00971666,0.005979,0.004136,0.002848,0.001946,0.001079,0.0007717,0.000588,0.000487337,0.000447713} |
---|
| 1459 | root:myGlobals:Attenuators:ng7att7 = {0.00207332,0.001054,0.0006462,0.0003957,0.0002368,0.0001111,7.642e-05,4.83076e-05,3.99401e-05,3.54814e-05} |
---|
| 1460 | root:myGlobals:Attenuators:ng7att8 = {0.000397173,0.0001911,0.0001044,5.844e-05,3.236e-05,1.471e-05,6.88523e-06,4.06541e-06,3.27333e-06,2.81838e-06} |
---|
| 1461 | root:myGlobals:Attenuators:ng7att9 = {9.43625e-05,3.557e-05,1.833e-05,1.014e-05,6.153e-06,1.64816e-06,6.42353e-07,3.42132e-07,2.68269e-07,2.2182e-07} |
---|
| 1462 | root:myGlobals:Attenuators:ng7att10 = {2.1607e-05,7.521e-06,2.91221e-06,1.45252e-06,7.93451e-07,1.92309e-07,5.99279e-08,2.87928e-08,2.19862e-08,1.7559e-08} |
---|
| 1463 | |
---|
[794] | 1464 | // percent errors as measured, May 2007 values |
---|
| 1465 | // zero error for zero attenuators, appropriate average values put in for unknown values |
---|
| 1466 | root:myGlobals:Attenuators:ng7att0_err = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
---|
| 1467 | root:myGlobals:Attenuators:ng7att1_err = {0.2,0.169,0.1932,0.253,0.298,0.4871,0.238,0.245,0.332,0.3} |
---|
| 1468 | root:myGlobals:Attenuators:ng7att2_err = {0.3,0.305,0.3551,0.306,0.37,0.6113,0.368,0.413,0.45,0.4} |
---|
| 1469 | root:myGlobals:Attenuators:ng7att3_err = {0.4,0.355,0.4158,0.36,0.4461,0.7643,0.532,0.514,0.535,0.5} |
---|
| 1470 | root:myGlobals:Attenuators:ng7att4_err = {0.45,0.402,0.4767,0.415,0.5292,0.9304,0.635,0.588,0.623,0.6} |
---|
| 1471 | root:myGlobals:Attenuators:ng7att5_err = {0.5,0.447,0.5376,0.487,0.6391,1.169,0.708,0.665,0.851,0.8} |
---|
| 1472 | root:myGlobals:Attenuators:ng7att6_err = {0.6,0.501,0.6136,0.528,0.8796,1.708,0.782,0.874,1,1} |
---|
| 1473 | root:myGlobals:Attenuators:ng7att7_err = {0.8,0.697,0.9149,0.583,1.173,2.427,1.242,2,2,2} |
---|
| 1474 | root:myGlobals:Attenuators:ng7att8_err = {1,0.898,1.24,0.696,1.577,3.412,3,3,3,3} |
---|
| 1475 | root:myGlobals:Attenuators:ng7att9_err = {1.5,1.113,1.599,1.154,2.324,4.721,5,5,5,5} |
---|
| 1476 | root:myGlobals:Attenuators:ng7att10_err = {1.5,1.493,5,5,5,5,5,5,5,5} |
---|
| 1477 | |
---|
| 1478 | |
---|
[118] | 1479 | // Pre-June 2007 calibration values - do not use these anymore |
---|
| 1480 | //// root:myGlobals:Attenuators:ng7att0 = {1, 1, 1, 1, 1, 1, 1, 1 ,1} |
---|
| 1481 | //// root:myGlobals:Attenuators:ng7att1 = {0.418, 0.393, 0.369, 0.347, 0.313, 0.291, 0.271, 0.244, 0.219 } |
---|
| 1482 | //// root:myGlobals:Attenuators:ng7att2 = {0.189, 0.167, 0.148, 0.132, 0.109, 0.0945, 0.0830, 0.0681, 0.0560} |
---|
| 1483 | //// root:myGlobals:Attenuators:ng7att3 = {0.0784, 0.0651, 0.0541, 0.0456, 0.0340, 0.0273, 0.0223, 0.0164 , 0.0121} |
---|
| 1484 | //// root:myGlobals:Attenuators:ng7att4 = {0.0328, 0.0256, 0.0200, 0.0159, 0.0107, 7.98e-3, 6.14e-3, 4.09e-3 , 0.00274} |
---|
| 1485 | //// root:myGlobals:Attenuators:ng7att5 = {0.0139, 0.0101, 7.43e-3, 5.58e-3, 3.42e-3, 2.36e-3, 1.70e-3, 1.03e-3 , 6.27e-4} |
---|
| 1486 | //// root:myGlobals:Attenuators:ng7att6 = {5.90e-3, 4.07e-3, 2.79e-3, 1.99e-3, 1.11e-3, 7.13e-4, 4.91e-4, 2.59e-4 , 1.42e-4} |
---|
| 1487 | //// root:myGlobals:Attenuators:ng7att7 = {1.04e-3, 6.37e-4, 3.85e-4, 2.46e-4, 1.16e-4, 6.86e-5, 4.10e-5, 1.64e-5 ,7.02e-6} |
---|
| 1488 | //// root:myGlobals:Attenuators:ng7att8 = {1.90e-4, 1.03e-4, 5.71e-5, 3.44e-5, 1.65e-5, 6.60e-6, 3.42e-6, 1.04e-6 , 3.48e-7} |
---|
| 1489 | //// root:myGlobals:Attenuators:ng7att9 = {3.58e-5, 1.87e-5, 1.05e-5, 7.00e-6, 2.35e-6, 6.35e-7, 2.86e-7, 6.61e-8 , 1.73e-8} |
---|
| 1490 | //// root:myGlobals:Attenuators:ng7att10 = {7.76e-6, 4.56e-6, 3.25e-6, 2.03e-6, 3.34e-7, 6.11e-8, 2.39e-8, 4.19e-9, 8.60e-10} |
---|
[69] | 1491 | End |
---|
| 1492 | |
---|
| 1493 | //returns the transmission of the attenuator (at NG3) given the attenuator number |
---|
| 1494 | //which must be an integer(to select the wave) and given the wavelength. |
---|
[121] | 1495 | //the wavelength may be any value between 4 and 20 (A), and is interpolated |
---|
[69] | 1496 | //between calibrated wavelengths for a given attenuator |
---|
[79] | 1497 | // |
---|
[644] | 1498 | // Mar 2010 - abs() added to attStr to account for ICE reporting -0.0001 as an attenuator position, which truncates to "-0" |
---|
[794] | 1499 | Function LookupAttenNG3(lambda,attenNo,atten_err) |
---|
| 1500 | Variable lambda, attenNo, &atten_err |
---|
[69] | 1501 | |
---|
| 1502 | Variable trans |
---|
[644] | 1503 | String attStr="root:myGlobals:Attenuators:ng3att"+num2str(trunc(abs(attenNo))) |
---|
[794] | 1504 | String attErrWStr="root:myGlobals:Attenuators:ng3att"+num2str(trunc(abs(attenNo)))+"_err" |
---|
[69] | 1505 | String lamStr = "root:myGlobals:Attenuators:ng3lambda" |
---|
| 1506 | |
---|
| 1507 | if(attenNo == 0) |
---|
| 1508 | return (1) //no attenuation, return trans == 1 |
---|
| 1509 | endif |
---|
| 1510 | |
---|
[121] | 1511 | if( (lambda < 4) || (lambda > 20 ) ) |
---|
| 1512 | Abort "Wavelength out of calibration range (4,20). You must manually enter the absolute parameters" |
---|
[69] | 1513 | Endif |
---|
| 1514 | |
---|
[794] | 1515 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) || !(WaveExists($attErrWStr))) |
---|
[69] | 1516 | Execute "MakeNG3AttenTable()" |
---|
| 1517 | Endif |
---|
| 1518 | //just in case creating the tables fails.... |
---|
| 1519 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) ) |
---|
| 1520 | Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters" |
---|
| 1521 | Endif |
---|
| 1522 | |
---|
| 1523 | //lookup the value by interpolating the wavelength |
---|
| 1524 | //the attenuator must always be an integer |
---|
| 1525 | Wave att = $attStr |
---|
[794] | 1526 | Wave attErrW = $attErrWStr |
---|
[69] | 1527 | Wave lam = $lamstr |
---|
| 1528 | trans = interp(lambda,lam,att) |
---|
[794] | 1529 | atten_err = interp(lambda,lam,attErrW) |
---|
| 1530 | |
---|
| 1531 | // the error in the tables is % error. return the standard deviation instead |
---|
| 1532 | atten_err = trans*atten_err/100 |
---|
| 1533 | |
---|
[69] | 1534 | // Print "trans = ",trans |
---|
[794] | 1535 | // Print "trans err = ",atten_err |
---|
[69] | 1536 | |
---|
| 1537 | return trans |
---|
| 1538 | End |
---|
| 1539 | |
---|
| 1540 | //returns the transmission of the attenuator (at NG7) given the attenuator number |
---|
| 1541 | //which must be an integer(to select the wave) and given the wavelength. |
---|
[121] | 1542 | //the wavelength may be any value between 4 and 20 (A), and is interpolated |
---|
[69] | 1543 | //between calibrated wavelengths for a given attenuator |
---|
| 1544 | // |
---|
[121] | 1545 | // this set of tables is also used for NG5 (NG1) SANS instrument - as the attenuator has never been calibrated |
---|
[79] | 1546 | // |
---|
| 1547 | // local function |
---|
| 1548 | // |
---|
[644] | 1549 | // Mar 2010 - abs() added to attStr to account for ICE reporting -0.0001 as an attenuator position, which truncates to "-0" |
---|
[794] | 1550 | Function LookupAttenNG7(lambda,attenNo,atten_err) |
---|
| 1551 | Variable lambda, attenNo, &atten_err |
---|
[69] | 1552 | |
---|
| 1553 | Variable trans |
---|
[644] | 1554 | String attStr="root:myGlobals:Attenuators:ng7att"+num2str(trunc(abs(attenNo))) |
---|
[794] | 1555 | String attErrWStr="root:myGlobals:Attenuators:ng7att"+num2str(trunc(abs(attenNo)))+"_err" |
---|
[69] | 1556 | String lamStr = "root:myGlobals:Attenuators:ng7lambda" |
---|
| 1557 | |
---|
| 1558 | if(attenNo == 0) |
---|
| 1559 | return (1) //no attenuation, return trans == 1 |
---|
| 1560 | endif |
---|
| 1561 | |
---|
[121] | 1562 | if( (lambda < 4) || (lambda > 20 ) ) |
---|
| 1563 | Abort "Wavelength out of calibration range (4,20). You must manually enter the absolute parameters" |
---|
[69] | 1564 | Endif |
---|
| 1565 | |
---|
[794] | 1566 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) || !(WaveExists($attErrWStr))) |
---|
[69] | 1567 | Execute "MakeNG7AttenTable()" |
---|
| 1568 | Endif |
---|
| 1569 | //just in case creating the tables fails.... |
---|
| 1570 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) ) |
---|
| 1571 | Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters" |
---|
| 1572 | Endif |
---|
| 1573 | |
---|
| 1574 | //lookup the value by interpolating the wavelength |
---|
| 1575 | //the attenuator must always be an integer |
---|
| 1576 | Wave att = $attStr |
---|
[794] | 1577 | Wave attErrW = $attErrWStr |
---|
[69] | 1578 | Wave lam = $lamstr |
---|
| 1579 | trans = interp(lambda,lam,att) |
---|
[794] | 1580 | atten_err = interp(lambda,lam,attErrW) |
---|
| 1581 | |
---|
| 1582 | // the error in the tables is % error. return the standard deviation instead |
---|
| 1583 | atten_err = trans*atten_err/100 |
---|
[69] | 1584 | |
---|
[794] | 1585 | // Print "trans = ",trans |
---|
| 1586 | // Print "trans err = ",atten_err |
---|
[69] | 1587 | |
---|
| 1588 | return trans |
---|
| 1589 | |
---|
| 1590 | End |
---|
| 1591 | |
---|
[801] | 1592 | // a utility function so that I can get the values from the command line |
---|
| 1593 | // since the atten_err is PBR |
---|
| 1594 | // |
---|
| 1595 | Function PrintAttenuation(instr,lam,attenNo) |
---|
| 1596 | String instr |
---|
| 1597 | Variable lam,attenNo |
---|
| 1598 | |
---|
| 1599 | Variable atten_err, attenFactor |
---|
| 1600 | |
---|
| 1601 | strswitch(instr) |
---|
| 1602 | case "NG3": |
---|
| 1603 | attenFactor = LookupAttenNG3(lam,attenNo,atten_err) |
---|
| 1604 | break |
---|
| 1605 | case "NG5": |
---|
| 1606 | //using NG7 lookup Table |
---|
| 1607 | attenFactor = LookupAttenNG7(lam,attenNo,atten_err) |
---|
| 1608 | break |
---|
| 1609 | case "NG7": |
---|
| 1610 | attenFactor = LookupAttenNG7(lam,attenNo,atten_err) |
---|
| 1611 | break |
---|
| 1612 | default: |
---|
| 1613 | //return error? |
---|
| 1614 | attenFactor=1 |
---|
| 1615 | endswitch |
---|
| 1616 | |
---|
| 1617 | Print "atten, err = ", attenFactor, atten_err |
---|
| 1618 | |
---|
| 1619 | return(0) |
---|
| 1620 | End |
---|
| 1621 | |
---|
| 1622 | |
---|
| 1623 | |
---|
[69] | 1624 | //returns the proper attenuation factor based on the instrument (NG3, NG5, or NG7) |
---|
| 1625 | //NG5 values are taken from the NG7 tables (there is very little difference in the |
---|
| 1626 | //values, and NG5 attenuators have not been calibrated (as of 8/01) |
---|
[79] | 1627 | // |
---|
[82] | 1628 | // filestr is passed from TextRead[3] = the default directory |
---|
| 1629 | // lam is passed from RealsRead[26] |
---|
| 1630 | // AttenNo is passed from ReaslRead[3] |
---|
| 1631 | // |
---|
[79] | 1632 | // Attenuation factor as defined here is <= 1 |
---|
[82] | 1633 | // |
---|
[81] | 1634 | // ORNL can pass ("",1,attenuationFactor) and have this function simply |
---|
| 1635 | // spit back the attenuationFactor (that was read into rw[3]) |
---|
[79] | 1636 | // |
---|
| 1637 | // called by Correct.ipf, ProtocolAsPanel.ipf, Transmission.ipf |
---|
| 1638 | // |
---|
[794] | 1639 | // |
---|
| 1640 | // as of March 2011, returns the error (one standard deviation) in the attenuation factor as the last parameter, by reference |
---|
| 1641 | Function AttenuationFactor(fileStr,lam,attenNo,atten_err) |
---|
[69] | 1642 | String fileStr |
---|
[794] | 1643 | Variable lam,attenNo, &atten_err |
---|
[69] | 1644 | |
---|
| 1645 | Variable attenFactor=1,loc |
---|
| 1646 | String instr=fileStr[1,3] //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total) |
---|
| 1647 | |
---|
| 1648 | strswitch(instr) |
---|
| 1649 | case "NG3": |
---|
[794] | 1650 | attenFactor = LookupAttenNG3(lam,attenNo,atten_err) |
---|
[69] | 1651 | break |
---|
| 1652 | case "NG5": |
---|
| 1653 | //using NG7 lookup Table |
---|
[794] | 1654 | attenFactor = LookupAttenNG7(lam,attenNo,atten_err) |
---|
[69] | 1655 | break |
---|
| 1656 | case "NG7": |
---|
[794] | 1657 | attenFactor = LookupAttenNG7(lam,attenNo,atten_err) |
---|
[69] | 1658 | break |
---|
| 1659 | default: |
---|
| 1660 | //return error? |
---|
| 1661 | attenFactor=1 |
---|
| 1662 | endswitch |
---|
| 1663 | // print "instr, lambda, attenNo,attenFactor = ",instr,lam,attenNo,attenFactor |
---|
| 1664 | return(attenFactor) |
---|
| 1665 | End |
---|
| 1666 | |
---|
[79] | 1667 | //function called by the popups to get a file list of data that can be sorted |
---|
[70] | 1668 | // this procedure simply removes the raw data files from the string - there |
---|
| 1669 | //can be lots of other junk present, but this is very fast... |
---|
| 1670 | // |
---|
| 1671 | // could also use the alternate procedure of keeping only file with the proper extension |
---|
| 1672 | // |
---|
| 1673 | // another possibility is to get a listing of the text files, but is unreliable on |
---|
| 1674 | // Windows, where the data file must be .txt (and possibly OSX) |
---|
| 1675 | // |
---|
[79] | 1676 | // called by FIT_Ops.ipf, NSORT.ipf, PlotUtils.ipf |
---|
| 1677 | // |
---|
[70] | 1678 | Function/S ReducedDataFileList(ctrlName) |
---|
| 1679 | String ctrlName |
---|
| 1680 | |
---|
| 1681 | String list="",newList="",item="" |
---|
| 1682 | Variable num,ii |
---|
| 1683 | |
---|
| 1684 | //check for the path |
---|
| 1685 | PathInfo catPathName |
---|
| 1686 | if(V_Flag==0) |
---|
| 1687 | DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel" |
---|
| 1688 | Return("") |
---|
| 1689 | Endif |
---|
| 1690 | |
---|
| 1691 | list = IndexedFile(catpathName,-1,"????") |
---|
[670] | 1692 | |
---|
| 1693 | list = RemoveFromList(ListMatch(list,"*.SA1*",";"), list, ";", 0) |
---|
| 1694 | list = RemoveFromList(ListMatch(list,"*.SA2*",";"), list, ";", 0) |
---|
| 1695 | list = RemoveFromList(ListMatch(list,"*.SA3*",";"), list, ";", 0) |
---|
| 1696 | list = RemoveFromList(ListMatch(list,".*",";"), list, ";", 0) |
---|
| 1697 | list = RemoveFromList(ListMatch(list,"*.pxp",";"), list, ";", 0) |
---|
| 1698 | list = RemoveFromList(ListMatch(list,"*.DIV",";"), list, ";", 0) |
---|
| 1699 | list = RemoveFromList(ListMatch(list,"*.GSP",";"), list, ";", 0) |
---|
| 1700 | list = RemoveFromList(ListMatch(list,"*.MASK",";"), list, ";", 0) |
---|
| 1701 | |
---|
[70] | 1702 | //remove VAX version numbers |
---|
[670] | 1703 | list = RemoveVersNumsFromList(List) |
---|
[70] | 1704 | //sort |
---|
[670] | 1705 | newList = SortList(List,";",0) |
---|
[70] | 1706 | |
---|
| 1707 | return newlist |
---|
[76] | 1708 | End |
---|
| 1709 | |
---|
| 1710 | // returns a list of raw data files in the catPathName directory on disk |
---|
| 1711 | // - list is SEMICOLON-delimited |
---|
| 1712 | // |
---|
| 1713 | // does it the "cheap" way, simply finding the ".SAn" in the file name |
---|
| 1714 | // = does not check for proper byte length. |
---|
[79] | 1715 | // |
---|
| 1716 | // called by PatchFiles.ipf, Tile_2D.ipf |
---|
| 1717 | // |
---|
[76] | 1718 | Function/S GetRawDataFileList() |
---|
| 1719 | |
---|
| 1720 | //make sure that path exists |
---|
| 1721 | PathInfo catPathName |
---|
| 1722 | if (V_flag == 0) |
---|
| 1723 | Abort "Folder path does not exist - use Pick Path button on Main Panel" |
---|
| 1724 | Endif |
---|
| 1725 | |
---|
| 1726 | String list=IndexedFile(catPathName,-1,"????") |
---|
| 1727 | String newList="",item="" |
---|
| 1728 | Variable num=ItemsInList(list,";"),ii |
---|
| 1729 | for(ii=0;ii<num;ii+=1) |
---|
| 1730 | item = StringFromList(ii, list ,";") |
---|
| 1731 | if( stringmatch(item,"*.sa1*") ) |
---|
| 1732 | newlist += item + ";" |
---|
| 1733 | endif |
---|
| 1734 | if( stringmatch(item,"*.sa2*") ) |
---|
| 1735 | newlist += item + ";" |
---|
| 1736 | endif |
---|
| 1737 | if( stringmatch(item,"*.sa3*") ) |
---|
| 1738 | newlist += item + ";" |
---|
| 1739 | endif |
---|
| 1740 | //print "ii=",ii |
---|
| 1741 | endfor |
---|
| 1742 | newList = SortList(newList,";",0) |
---|
| 1743 | return(newList) |
---|
[680] | 1744 | End |
---|
| 1745 | |
---|
| 1746 | // Return the filename that represents the previous or next file. |
---|
| 1747 | // Input is current filename and increment. |
---|
| 1748 | // Increment should be -1 or 1 |
---|
| 1749 | // -1 => previous file |
---|
| 1750 | // 1 => next file |
---|
| 1751 | Function/S GetPrevNextRawFile(curfilename, prevnext) |
---|
| 1752 | String curfilename |
---|
| 1753 | Variable prevnext |
---|
| 1754 | |
---|
| 1755 | String filename |
---|
| 1756 | |
---|
| 1757 | //get the run number |
---|
| 1758 | Variable num = GetRunNumFromFile(curfilename) |
---|
| 1759 | |
---|
| 1760 | //find the next specified file by number |
---|
| 1761 | fileName = FindFileFromRunNumber(num+prevnext) |
---|
| 1762 | |
---|
| 1763 | if(cmpstr(fileName,"")==0) |
---|
| 1764 | //null return, do nothing |
---|
| 1765 | fileName = FindFileFromRunNumber(num) |
---|
| 1766 | Endif |
---|
| 1767 | |
---|
[683] | 1768 | // print "in FU "+filename |
---|
[680] | 1769 | |
---|
| 1770 | Return filename |
---|
[708] | 1771 | End |
---|
| 1772 | |
---|
| 1773 | |
---|