[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 |
---|
[899] | 27 | // be set correctly in instr.cfg - these values are not used, but declared to avoid errors |
---|
[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 |
---|
[899] | 34 | Variable/G root:myGlobals:PixelResNGB_ORNL = 0.5 |
---|
| 35 | // Variable/G root:myGlobals:PixelResCGB_ORNL = 0.5 // fiction |
---|
[886] | 36 | |
---|
[69] | 37 | Variable/G root:myGlobals:PixelResDefault = 0.5 |
---|
[1003] | 38 | |
---|
| 39 | //Very old - ILL/Cerca-style detectors |
---|
[69] | 40 | Variable/G root:myGlobals:DeadtimeNG3_ILL = 3.0e-6 //deadtime in seconds |
---|
| 41 | Variable/G root:myGlobals:DeadtimeNG5_ILL = 3.0e-6 |
---|
| 42 | Variable/G root:myGlobals:DeadtimeNG7_ILL = 3.0e-6 |
---|
[899] | 43 | Variable/G root:myGlobals:DeadtimeNGB_ILL = 4.0e-6 // fictional |
---|
[1003] | 44 | // retired NG5 (NG1) 8m-sans instrument |
---|
| 45 | Variable/G root:myGlobals:DeadtimeNG5_ORNL = 0.6e-6 //as of 9 MAY 2002 |
---|
| 46 | |
---|
| 47 | // NG3 SANS, moved to NGB (currently named as CGB) |
---|
[788] | 48 | Variable/G root:myGlobals:DeadtimeNG3_ORNL_VAX = 3.4e-6 //pre - 23-JUL-2009 used VAX |
---|
| 49 | Variable/G root:myGlobals:DeadtimeNG3_ORNL_ICE = 1.5e-6 //post - 23-JUL-2009 used ICE |
---|
[1003] | 50 | Variable/G root:myGlobals:DeadtimeNG3_ORNL_NISTO = 1.0e-6 //post - 22-JUN-2016 using new NISTO |
---|
| 51 | |
---|
| 52 | // NG7 SANS |
---|
[788] | 53 | Variable/G root:myGlobals:DeadtimeNG7_ORNL_VAX = 3.4e-6 //pre 25-FEB-2010 used VAX |
---|
| 54 | Variable/G root:myGlobals:DeadtimeNG7_ORNL_ICE = 2.3e-6 //post 25-FEB-2010 used ICE |
---|
[1003] | 55 | Variable/G root:myGlobals:DeadtimeNG7_ORNL_NISTO = 1.0e-6 //--post 22-JUN-2016 using new NISTO |
---|
| 56 | |
---|
| 57 | // 10m sans @ NGB |
---|
[899] | 58 | Variable/G root:myGlobals:DeadtimeNGB_ORNL_ICE = 4.0e-6 //per JGB 16-JAN-2013, best value we have for the oscillating data |
---|
[1003] | 59 | Variable/G root:myGlobals:DeadtimeNGB_ORNL_NISTO = 1.0e-6 // (not a measured value!) per JGB June 2016, using NISTO, match value to NG7 and CGB 30m as of 27-APR-2016 |
---|
[899] | 60 | |
---|
[1003] | 61 | |
---|
[899] | 62 | // Variable/G root:myGlobals:DeadtimeCGB_ORNL_ICE = 1.5e-6 // fiction |
---|
| 63 | |
---|
[69] | 64 | Variable/G root:myGlobals:DeadtimeDefault = 3.4e-6 |
---|
[899] | 65 | |
---|
[82] | 66 | //new 11APR07 |
---|
[206] | 67 | Variable/G root:myGlobals:BeamstopXTol = -8 // (cm) is BS Xpos is -5 cm or less, it's a trans measurement |
---|
[82] | 68 | // sample aperture offset is NOT stored in the VAX header, but it should be |
---|
| 69 | // - when it is, remove the global and write an accessor AND make a place for |
---|
| 70 | // it in the RealsRead |
---|
[85] | 71 | Variable/G root:myGlobals:apOff = 5.0 // (cm) distance from sample aperture to sample position |
---|
[82] | 72 | |
---|
[69] | 73 | End |
---|
| 74 | |
---|
| 75 | |
---|
| 76 | //********************** |
---|
| 77 | // Resolution calculation - used by the averaging routines |
---|
| 78 | // to calculate the resolution function at each q-value |
---|
| 79 | // - the return value is not used |
---|
| 80 | // |
---|
| 81 | // equivalent to John's routine on the VAX Q_SIGMA_AVE.FOR |
---|
| 82 | // Incorporates eqn. 3-15 from J. Appl. Cryst. (1995) v. 28 p105-114 |
---|
| 83 | // |
---|
| 84 | // - 21 MAR 07 uses projected BS diameter on the detector |
---|
[79] | 85 | // - APR 07 still need to add resolution with lenses. currently there is no flag in the |
---|
| 86 | // raw data header to indicate the presence of lenses. |
---|
[69] | 87 | // |
---|
[143] | 88 | // - Aug 07 - added input to switch calculation based on lenses (==1 if in) |
---|
| 89 | // |
---|
[79] | 90 | // - called by CircSectAvg.ipf and RectAnnulAvg.ipf |
---|
| 91 | // |
---|
[82] | 92 | // passed values are read from RealsRead |
---|
| 93 | // except DDet and apOff, which are set from globals before passing |
---|
| 94 | // |
---|
[143] | 95 | // |
---|
| 96 | Function/S getResolution(inQ,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,SigmaQ,QBar,fSubS) |
---|
| 97 | Variable inQ, lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses |
---|
[1081] | 98 | Variable &SigmaQ, &QBar, &fSubS //these are the output quantities at the input Q value |
---|
[69] | 99 | |
---|
| 100 | //lots of calculation variables |
---|
| 101 | Variable a2, q_small, lp, v_lambda, v_b, v_d, vz, yg, v_g |
---|
| 102 | Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r |
---|
| 103 | |
---|
| 104 | //Constants |
---|
| 105 | Variable vz_1 = 3.956e5 //velocity [cm/s] of 1 A neutron |
---|
| 106 | Variable g = 981.0 //gravity acceleration [cm/s^2] |
---|
| 107 | |
---|
| 108 | String results |
---|
| 109 | results ="Failure" |
---|
| 110 | |
---|
| 111 | S1 *= 0.5*0.1 //convert to radius and [cm] |
---|
| 112 | S2 *= 0.5*0.1 |
---|
| 113 | |
---|
| 114 | L1 *= 100.0 // [cm] |
---|
| 115 | L1 -= apOff //correct the distance |
---|
| 116 | |
---|
| 117 | L2 *= 100.0 |
---|
| 118 | L2 += apOff |
---|
| 119 | del_r *= 0.1 //width of annulus, convert mm to [cm] |
---|
| 120 | |
---|
| 121 | BS *= 0.5*0.1 //nominal BS diameter passed in, convert to radius and [cm] |
---|
| 122 | // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture |
---|
| 123 | Variable LB |
---|
| 124 | LB = 20.1 + 1.61*BS //distance in cm from beamstop to anode plane (empirical) |
---|
| 125 | BS = bs + bs*lb/(l2-lb) //adjusted diameter of shadow from parallax |
---|
| 126 | |
---|
| 127 | //Start resolution calculation |
---|
| 128 | a2 = S1*L2/L1 + S2*(L1+L2)/L1 |
---|
| 129 | q_small = 2.0*Pi*(BS-a2)*(1.0-lambdaWidth)/(lambda*L2) |
---|
| 130 | lp = 1.0/( 1.0/L1 + 1.0/L2) |
---|
| 131 | |
---|
| 132 | v_lambda = lambdaWidth^2/6.0 |
---|
[143] | 133 | |
---|
[248] | 134 | // if(usingLenses==1) //SRK 2007 |
---|
| 135 | if(usingLenses != 0) //SRK 2008 allows for the possibility of different numbers of lenses in header |
---|
[143] | 136 | v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2 //correction to 2nd term |
---|
| 137 | else |
---|
| 138 | v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2 //original form |
---|
| 139 | endif |
---|
| 140 | |
---|
[925] | 141 | v_d = (DDet/2.3548)^2 + del_r^2/12.0 //the 2.3548 is a conversion from FWHM->Gauss, see http://mathworld.wolfram.com/GaussianFunction.html |
---|
[69] | 142 | vz = vz_1 / lambda |
---|
| 143 | yg = 0.5*g*L2*(L1+L2)/vz^2 |
---|
[143] | 144 | v_g = 2.0*(2.0*yg^2*v_lambda) //factor of 2 correction, B. Hammouda, 2007 |
---|
[69] | 145 | |
---|
| 146 | r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) )) |
---|
| 147 | delta = 0.5*(BS - r0)^2/v_d |
---|
| 148 | |
---|
| 149 | if (r0 < BS) |
---|
| 150 | inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta)) |
---|
| 151 | else |
---|
| 152 | inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta)) |
---|
| 153 | endif |
---|
| 154 | |
---|
| 155 | fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) ) |
---|
| 156 | if (fSubS <= 0.0) |
---|
| 157 | fSubS = 1.e-10 |
---|
| 158 | endif |
---|
| 159 | fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi)) |
---|
| 160 | fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d |
---|
| 161 | |
---|
| 162 | rmd = fr*r0 |
---|
| 163 | v_r1 = v_b + fv*v_d +v_g |
---|
| 164 | |
---|
| 165 | rm = rmd + 0.5*v_r1/rmd |
---|
| 166 | v_r = v_r1 - 0.5*(v_r1/rmd)^2 |
---|
| 167 | if (v_r < 0.0) |
---|
| 168 | v_r = 0.0 |
---|
| 169 | endif |
---|
| 170 | QBar = (4.0*Pi/lambda)*sin(0.5*atan(rm/L2)) |
---|
| 171 | SigmaQ = QBar*sqrt(v_r/rmd^2 +v_lambda) |
---|
| 172 | |
---|
[794] | 173 | |
---|
| 174 | // more readable method for calculating the variance in Q |
---|
| 175 | // EXCEPT - this is calculated for Qo, NOT qBar |
---|
| 176 | // (otherwise, they are nearly equivalent, except for close to the beam stop) |
---|
| 177 | // Variable kap,a_val,a_val_l2,m_h |
---|
| 178 | // g = 981.0 //gravity acceleration [cm/s^2] |
---|
| 179 | // m_h = 252.8 // m/h [=] s/cm^2 |
---|
| 180 | // |
---|
| 181 | // kap = 2*pi/lambda |
---|
| 182 | // a_val = L2*(L1+L2)*g/2*(m_h)^2 |
---|
| 183 | // a_val_L2 = a_val/L2*1e-16 //convert 1/cm^2 to 1/A^2 |
---|
| 184 | // |
---|
| 185 | // sigmaQ = 0 |
---|
| 186 | // sigmaQ = 3*(S1/L1)^2 |
---|
| 187 | // |
---|
| 188 | // if(usingLenses != 0) |
---|
| 189 | // sigmaQ += 2*(S2/lp)^2*(lambdaWidth)^2 //2nd term w/ lenses |
---|
| 190 | // else |
---|
| 191 | // sigmaQ += 2*(S2/lp)^2 //2nd term w/ no lenses |
---|
| 192 | // endif |
---|
| 193 | // |
---|
| 194 | // sigmaQ += (del_r/L2)^2 |
---|
| 195 | // sigmaQ += 2*(r0/L2)^2*(lambdaWidth)^2 |
---|
| 196 | // sigmaQ += 4*(a_val_l2)^2*lambda^4*(lambdaWidth)^2 |
---|
| 197 | // |
---|
| 198 | // sigmaQ *= kap^2/12 |
---|
| 199 | // sigmaQ = sqrt(sigmaQ) |
---|
| 200 | |
---|
| 201 | |
---|
[69] | 202 | results = "success" |
---|
| 203 | Return results |
---|
| 204 | End |
---|
| 205 | |
---|
[708] | 206 | |
---|
[509] | 207 | // |
---|
[708] | 208 | //********************** |
---|
| 209 | // 2D resolution function calculation - ***NOT*** in terms of X and Y |
---|
| 210 | // but written in terms of Parallel and perpendicular to the Q vector at each point |
---|
[509] | 211 | // |
---|
[838] | 212 | // -- it is more naturally written this way since the 2D function is an ellipse with its major |
---|
[708] | 213 | // axis pointing in the direction of Q_parallel. Hence there is no way to properly define the |
---|
| 214 | // elliptical gaussian in terms of sigmaX and sigmaY |
---|
[509] | 215 | // |
---|
[838] | 216 | // For a full description of the gravity effect on the resolution, see: |
---|
[509] | 217 | // |
---|
[838] | 218 | // "The effect of gravity on the resolution of small-angle neutron diffraction peaks" |
---|
| 219 | // D.F.R Mildner, J.G. Barker & S.R. Kline J. Appl. Cryst. (2011). 44, 1127-1129. |
---|
| 220 | // [ doi:10.1107/S0021889811033322 ] |
---|
[509] | 221 | // |
---|
[838] | 222 | // 2/17/12 SRK |
---|
| 223 | // NOTE: the first 2/3 of this code is the 1D code, copied here just to have the beam stop |
---|
| 224 | // calculation here, if I decide to implement it. The real calculation is all at the |
---|
| 225 | // bottom and is quite compact |
---|
| 226 | // |
---|
| 227 | // |
---|
| 228 | // |
---|
| 229 | // |
---|
[509] | 230 | // - 21 MAR 07 uses projected BS diameter on the detector |
---|
| 231 | // - APR 07 still need to add resolution with lenses. currently there is no flag in the |
---|
| 232 | // raw data header to indicate the presence of lenses. |
---|
| 233 | // |
---|
| 234 | // - Aug 07 - added input to switch calculation based on lenses (==1 if in) |
---|
| 235 | // |
---|
| 236 | // passed values are read from RealsRead |
---|
| 237 | // except DDet and apOff, which are set from globals before passing |
---|
| 238 | // |
---|
| 239 | // phi is the azimuthal angle, CCW from +x axis |
---|
| 240 | // r_dist is the real-space distance from ctr of detector to QxQy pixel location |
---|
| 241 | // |
---|
[794] | 242 | // MAR 2011 - removed the del_r terms, they don't apply since no bining is done to the 2D data |
---|
| 243 | // |
---|
[509] | 244 | Function/S get2DResolution(inQ,phi,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,r_dist,SigmaQX,SigmaQY,fSubS) |
---|
| 245 | Variable inQ, phi,lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses,r_dist |
---|
| 246 | Variable &SigmaQX,&SigmaQY,&fSubS //these are the output quantities at the input Q value |
---|
| 247 | |
---|
| 248 | //lots of calculation variables |
---|
| 249 | Variable a2, lp, v_lambda, v_b, v_d, vz, yg, v_g |
---|
| 250 | Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r |
---|
[69] | 251 | |
---|
[509] | 252 | //Constants |
---|
| 253 | Variable vz_1 = 3.956e5 //velocity [cm/s] of 1 A neutron |
---|
| 254 | Variable g = 981.0 //gravity acceleration [cm/s^2] |
---|
[708] | 255 | Variable m_h = 252.8 // m/h [=] s/cm^2 |
---|
[509] | 256 | |
---|
| 257 | String results |
---|
| 258 | results ="Failure" |
---|
| 259 | |
---|
| 260 | S1 *= 0.5*0.1 //convert to radius and [cm] |
---|
| 261 | S2 *= 0.5*0.1 |
---|
| 262 | |
---|
| 263 | L1 *= 100.0 // [cm] |
---|
| 264 | L1 -= apOff //correct the distance |
---|
| 265 | |
---|
| 266 | L2 *= 100.0 |
---|
| 267 | L2 += apOff |
---|
| 268 | del_r *= 0.1 //width of annulus, convert mm to [cm] |
---|
| 269 | |
---|
| 270 | BS *= 0.5*0.1 //nominal BS diameter passed in, convert to radius and [cm] |
---|
| 271 | // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture |
---|
| 272 | Variable LB |
---|
| 273 | LB = 20.1 + 1.61*BS //distance in cm from beamstop to anode plane (empirical) |
---|
| 274 | BS = bs + bs*lb/(l2-lb) //adjusted diameter of shadow from parallax |
---|
| 275 | |
---|
| 276 | //Start resolution calculation |
---|
| 277 | a2 = S1*L2/L1 + S2*(L1+L2)/L1 |
---|
| 278 | lp = 1.0/( 1.0/L1 + 1.0/L2) |
---|
| 279 | |
---|
| 280 | v_lambda = lambdaWidth^2/6.0 |
---|
| 281 | |
---|
| 282 | // if(usingLenses==1) //SRK 2007 |
---|
| 283 | if(usingLenses != 0) //SRK 2008 allows for the possibility of different numbers of lenses in header |
---|
| 284 | v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2 //correction to 2nd term |
---|
| 285 | else |
---|
| 286 | v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2 //original form |
---|
| 287 | endif |
---|
| 288 | |
---|
| 289 | v_d = (DDet/2.3548)^2 + del_r^2/12.0 |
---|
| 290 | vz = vz_1 / lambda |
---|
| 291 | yg = 0.5*g*L2*(L1+L2)/vz^2 |
---|
| 292 | v_g = 2.0*(2.0*yg^2*v_lambda) //factor of 2 correction, B. Hammouda, 2007 |
---|
| 293 | |
---|
| 294 | r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) )) |
---|
| 295 | delta = 0.5*(BS - r0)^2/v_d |
---|
| 296 | |
---|
| 297 | if (r0 < BS) |
---|
| 298 | inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta)) |
---|
| 299 | else |
---|
| 300 | inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta)) |
---|
| 301 | endif |
---|
| 302 | |
---|
| 303 | fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) ) |
---|
| 304 | if (fSubS <= 0.0) |
---|
| 305 | fSubS = 1.e-10 |
---|
| 306 | endif |
---|
| 307 | // fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi)) |
---|
| 308 | // fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d |
---|
| 309 | // |
---|
| 310 | // rmd = fr*r0 |
---|
| 311 | // v_r1 = v_b + fv*v_d +v_g |
---|
| 312 | // |
---|
| 313 | // rm = rmd + 0.5*v_r1/rmd |
---|
| 314 | // v_r = v_r1 - 0.5*(v_r1/rmd)^2 |
---|
| 315 | // if (v_r < 0.0) |
---|
| 316 | // v_r = 0.0 |
---|
| 317 | // endif |
---|
| 318 | |
---|
[794] | 319 | Variable kap,a_val,a_val_L2,proj_DDet |
---|
[509] | 320 | |
---|
| 321 | kap = 2*pi/lambda |
---|
[708] | 322 | a_val = L2*(L1+L2)*g/2*(m_h)^2 |
---|
| 323 | a_val_L2 = a_val/L2*1e-16 //convert 1/cm^2 to 1/A^2 |
---|
[515] | 324 | |
---|
[509] | 325 | |
---|
[827] | 326 | // the detector pixel is square, so correct for phi |
---|
| 327 | proj_DDet = DDet*cos(phi) + DDet*sin(phi) |
---|
[509] | 328 | |
---|
| 329 | |
---|
[827] | 330 | ///////// OLD - don't use --- |
---|
| 331 | //in terms of Q_parallel ("x") and Q_perp ("y") - this works, since parallel is in the direction of Q and I |
---|
| 332 | // can calculate that from the QxQy (I just need the projection) |
---|
[813] | 333 | //// for test case with no gravity, set a_val = 0 |
---|
| 334 | //// note that gravity has no wavelength dependence. the lambda^4 cancels out. |
---|
| 335 | //// |
---|
| 336 | //// a_val = 0 |
---|
| 337 | //// a_val_l2 = 0 |
---|
[708] | 338 | // |
---|
[813] | 339 | // |
---|
| 340 | // // this is really sigma_Q_parallel |
---|
| 341 | // 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) |
---|
| 342 | // SigmaQX += inQ*inQ*v_lambda |
---|
| 343 | // |
---|
| 344 | // //this is really sigma_Q_perpendicular |
---|
| 345 | // proj_DDet = DDet*sin(phi) + DDet*cos(phi) //not necessary, since DDet is the same in both X and Y directions |
---|
| 346 | // |
---|
| 347 | // 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) |
---|
| 348 | // |
---|
| 349 | // SigmaQX = sqrt(SigmaQX) |
---|
| 350 | // SigmaQy = sqrt(SigmaQY) |
---|
| 351 | // |
---|
[708] | 352 | |
---|
[800] | 353 | ///////////////////////////////////////////////// |
---|
[811] | 354 | ///// |
---|
[827] | 355 | // ////// this is all new, inclusion of gravity effect into the parallel component |
---|
| 356 | // perpendicular component is purely geometric, no gravity component |
---|
[838] | 357 | // |
---|
| 358 | // the shadow factor is calculated as above -so keep the above calculations, even though |
---|
| 359 | // most of them are redundant. |
---|
| 360 | // |
---|
| 361 | |
---|
[811] | 362 | //// // |
---|
[813] | 363 | Variable yg_d,acc,sdd,ssd,lambda0,DL_L,sig_l |
---|
[827] | 364 | Variable var_qlx,var_qly,var_ql,qx,qy,sig_perp,sig_para, sig_para_new |
---|
[838] | 365 | |
---|
[813] | 366 | G = 981. //! ACCELERATION OF GRAVITY, CM/SEC^2 |
---|
| 367 | acc = vz_1 // 3.956E5 //! CONVERT WAVELENGTH TO VELOCITY CM/SEC |
---|
| 368 | SDD = L2 //1317 |
---|
| 369 | SSD = L1 //1627 //cm |
---|
| 370 | lambda0 = lambda // 15 |
---|
| 371 | DL_L = lambdaWidth //0.236 |
---|
| 372 | SIG_L = DL_L/sqrt(6) |
---|
| 373 | YG_d = -0.5*G*SDD*(SSD+SDD)*(LAMBDA0/acc)^2 |
---|
| 374 | ///// Print "DISTANCE BEAM FALLS DUE TO GRAVITY (CM) = ",YG |
---|
[838] | 375 | // Print "Gravity q* = ",-2*pi/lambda0*2*yg_d/sdd |
---|
[800] | 376 | |
---|
[813] | 377 | sig_perp = kap*kap/12 * (3*(S1/L1)^2 + 3*(S2/LP)^2 + (proj_DDet/L2)^2) |
---|
| 378 | sig_perp = sqrt(sig_perp) |
---|
| 379 | |
---|
| 380 | |
---|
| 381 | FindQxQy(inQ,phi,qx,qy) |
---|
[827] | 382 | |
---|
| 383 | // missing a factor of 2 here, and the form is different than the paper, so re-write |
---|
| 384 | // VAR_QLY = SIG_L^2 * (QY+4*PI*YG_d/(2*SDD*LAMBDA0))^2 |
---|
| 385 | // VAR_QLX = (SIG_L*QX)^2 |
---|
| 386 | // VAR_QL = VAR_QLY + VAR_QLX //! WAVELENGTH CONTRIBUTION TO VARIANCE |
---|
| 387 | // sig_para = (sig_perp^2 + VAR_QL)^0.5 |
---|
[813] | 388 | |
---|
[827] | 389 | // r_dist is passed in, [=]cm |
---|
| 390 | // from the paper |
---|
| 391 | a_val = 0.5*G*SDD*(SSD+SDD)*m_h^2 * 1e-16 //units now are cm /(A^2) |
---|
[813] | 392 | |
---|
[827] | 393 | 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) |
---|
| 394 | sig_para_new = (sig_perp^2 + VAR_QL)^0.5 |
---|
| 395 | |
---|
| 396 | |
---|
[813] | 397 | ///// return values PBR |
---|
[827] | 398 | SigmaQX = sig_para_new |
---|
[813] | 399 | SigmaQy = sig_perp |
---|
| 400 | |
---|
| 401 | //// |
---|
| 402 | |
---|
[509] | 403 | results = "success" |
---|
| 404 | Return results |
---|
| 405 | End |
---|
| 406 | |
---|
| 407 | |
---|
| 408 | |
---|
| 409 | |
---|
[82] | 410 | //Utility function that returns the detector resolution (in cm) |
---|
[69] | 411 | //Global values are set in the Initialize procedure |
---|
[79] | 412 | // |
---|
| 413 | // |
---|
| 414 | // - called by CircSectAvg.ipf, RectAnnulAvg.ipf, and ProtocolAsPanel.ipf |
---|
| 415 | // |
---|
[82] | 416 | // fileStr is passed as TextRead[3] |
---|
| 417 | // detStr is passed as TextRead[9] |
---|
| 418 | // |
---|
[247] | 419 | // *** as of Jan 2008, depricated. Now detector pixel sizes are read from the file header |
---|
| 420 | // rw[10] = x size (mm); rw[13] = y size (mm) |
---|
| 421 | // |
---|
| 422 | Function xDetectorPixelResolution(fileStr,detStr) |
---|
[69] | 423 | String fileStr,detStr |
---|
| 424 | |
---|
| 425 | Variable DDet |
---|
| 426 | String instr=fileStr[1,3] //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total) |
---|
| 427 | |
---|
| 428 | NVAR PixelResNG3_ILL = root:myGlobals:PixelResNG3_ILL //pixel resolution in cm |
---|
| 429 | NVAR PixelResNG5_ILL = root:myGlobals:PixelResNG5_ILL |
---|
| 430 | NVAR PixelResNG7_ILL = root:myGlobals:PixelResNG7_ILL |
---|
[899] | 431 | NVAR PixelResNGB_ILL = root:myGlobals:PixelResNGB_ILL |
---|
[69] | 432 | NVAR PixelResNG3_ORNL = root:myGlobals:PixelResNG3_ORNL |
---|
| 433 | NVAR PixelResNG5_ORNL = root:myGlobals:PixelResNG5_ORNL |
---|
| 434 | NVAR PixelResNG7_ORNL = root:myGlobals:PixelResNG7_ORNL |
---|
[899] | 435 | NVAR PixelResNGB_ORNL = root:myGlobals:PixelResNGB_ORNL |
---|
| 436 | // NVAR PixelResCGB_ORNL = root:myGlobals:PixelResCGB_ORNL |
---|
[69] | 437 | NVAR PixelResDefault = root:myGlobals:PixelResDefault |
---|
| 438 | |
---|
| 439 | strswitch(instr) |
---|
[899] | 440 | case "CGB": |
---|
[69] | 441 | case "NG3": |
---|
| 442 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 443 | DDet= PixelResNG3_ILL |
---|
| 444 | else |
---|
| 445 | DDet = PixelResNG3_ORNL //detector is ordella-type |
---|
| 446 | endif |
---|
| 447 | break |
---|
| 448 | case "NG5": |
---|
| 449 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 450 | DDet= PixelResNG5_ILL |
---|
| 451 | else |
---|
| 452 | DDet = PixelResNG5_ORNL //detector is ordella-type |
---|
| 453 | endif |
---|
| 454 | break |
---|
| 455 | case "NG7": |
---|
| 456 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 457 | DDet= PixelResNG7_ILL |
---|
| 458 | else |
---|
| 459 | DDet = PixelResNG7_ORNL //detector is ordella-type |
---|
| 460 | endif |
---|
| 461 | break |
---|
[886] | 462 | case "NGA": |
---|
[899] | 463 | case "NGB": |
---|
[886] | 464 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
[899] | 465 | DDet= PixelResNGB_ILL |
---|
[886] | 466 | else |
---|
[899] | 467 | DDet = PixelResNGB_ORNL //detector is ordella-type |
---|
[886] | 468 | endif |
---|
| 469 | break |
---|
[69] | 470 | default: |
---|
| 471 | //return error? |
---|
[886] | 472 | DoAlert 0, "No matching instrument xDetectorPixelResolution-- Using default resolution" |
---|
[82] | 473 | DDet = PixelResDefault //0.5 cm, typical for new ORNL detectors |
---|
[69] | 474 | endswitch |
---|
| 475 | |
---|
| 476 | return(DDet) |
---|
| 477 | End |
---|
| 478 | |
---|
[82] | 479 | //Utility function that returns the detector deadtime (in seconds) |
---|
[69] | 480 | //Global values are set in the Initialize procedure |
---|
[79] | 481 | // |
---|
| 482 | // - called by WorkFileUtils.ipf |
---|
| 483 | // |
---|
[82] | 484 | // fileStr is passed as TextRead[3] |
---|
| 485 | // detStr is passed as TextRead[9] |
---|
[788] | 486 | // dateAndTimeStr is passed as TextRead[1] |
---|
| 487 | // --- if no date/time string is passed, ICE values are the default |
---|
[79] | 488 | // |
---|
[788] | 489 | // Due to the switch from VAX -> ICE, there were some hardware changes that led to |
---|
| 490 | // a change in the effective detector dead time. The dead time was re-measured by J. Barker |
---|
| 491 | // as follows: |
---|
| 492 | // Instrument Date measured deadtime constant |
---|
| 493 | // NG3 DECEMBER 2009 1.5 microseconds |
---|
[940] | 494 | // NG7 APRIL 2010 2.3 microseconds |
---|
[899] | 495 | // NGB JAN 2013 4 microseconds |
---|
[788] | 496 | // |
---|
[886] | 497 | // |
---|
[1003] | 498 | // |
---|
[788] | 499 | // The day of the switch to ICE on NG7 was 25-FEB-2010 (per J. Krzywon) |
---|
| 500 | // The day of the switch to ICE on NG3 was 23-JUL-2009 (per C. Gagnon) |
---|
| 501 | // |
---|
| 502 | // so any data after these dates is to use the new dead time constant. The switch is made on the |
---|
| 503 | // data collection date. |
---|
| 504 | // |
---|
[940] | 505 | // May 2014 SRK -- optional parameter dtime is the dead time as read in from the file |
---|
| 506 | // -- if if is non-zero, use it. If it's zero, go through tree and pick from the global constants |
---|
[788] | 507 | // |
---|
[940] | 508 | // MAY 2014 -- if the beam is CGB (now that the NG3 SANS has been moved to NGB), the logic |
---|
| 509 | // drops to select the values from NG3, since nothing has changed. When it does, I'll add in specifics for CGB |
---|
| 510 | // |
---|
[1003] | 511 | // |
---|
| 512 | // *** JUNE 2016 *** |
---|
| 513 | // instruments are now using new version of NISTO (all using the same hardware now) |
---|
| 514 | // ** the day of the switch is 22-JUN-2016 ** |
---|
| 515 | // CGB 30m (former NG3) 0.96 us == 1.0 us |
---|
| 516 | // NG7 SANS (measured as 1.02 us == 1.0 us) |
---|
| 517 | // 10m, yet unmeasured (use 1.0 us) starting 27-APR-2016 |
---|
| 518 | // ************** |
---|
| 519 | // |
---|
| 520 | // |
---|
[940] | 521 | Function DetectorDeadtime(fileStr,detStr,[dateAndTimeStr,dtime]) |
---|
[788] | 522 | String fileStr,detStr,dateAndTimeStr |
---|
[940] | 523 | Variable dtime |
---|
[69] | 524 | |
---|
| 525 | Variable deadtime |
---|
| 526 | String instr=fileStr[1,3] //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total) |
---|
| 527 | |
---|
| 528 | NVAR DeadtimeNG3_ILL = root:myGlobals:DeadtimeNG3_ILL //pixel resolution in cm |
---|
| 529 | NVAR DeadtimeNG5_ILL = root:myGlobals:DeadtimeNG5_ILL |
---|
| 530 | NVAR DeadtimeNG7_ILL = root:myGlobals:DeadtimeNG7_ILL |
---|
[899] | 531 | NVAR DeadtimeNGB_ILL = root:myGlobals:DeadtimeNGB_ILL |
---|
[1003] | 532 | |
---|
[788] | 533 | NVAR DeadtimeNG3_ORNL_VAX = root:myGlobals:DeadtimeNG3_ORNL_VAX |
---|
| 534 | NVAR DeadtimeNG3_ORNL_ICE = root:myGlobals:DeadtimeNG3_ORNL_ICE |
---|
[1003] | 535 | NVAR DeadtimeNG3_ORNL_NISTO = root:myGlobals:DeadtimeNG3_ORNL_NISTO |
---|
[899] | 536 | // NVAR DeadtimeCGB_ORNL_ICE = root:myGlobals:DeadtimeCGB_ORNL_ICE |
---|
[69] | 537 | NVAR DeadtimeNG5_ORNL = root:myGlobals:DeadtimeNG5_ORNL |
---|
[788] | 538 | NVAR DeadtimeNG7_ORNL_VAX = root:myGlobals:DeadtimeNG7_ORNL_VAX |
---|
| 539 | NVAR DeadtimeNG7_ORNL_ICE = root:myGlobals:DeadtimeNG7_ORNL_ICE |
---|
[1003] | 540 | NVAR DeadtimeNG7_ORNL_NISTO = root:myGlobals:DeadtimeNG7_ORNL_NISTO |
---|
[899] | 541 | NVAR DeadtimeNGB_ORNL_ICE = root:myGlobals:DeadtimeNGB_ORNL_ICE |
---|
[1003] | 542 | NVAR DeadtimeNGB_ORNL_NISTO = root:myGlobals:DeadtimeNGB_ORNL_NISTO |
---|
[69] | 543 | NVAR DeadtimeDefault = root:myGlobals:DeadtimeDefault |
---|
| 544 | |
---|
[940] | 545 | // if the deadtime passed in is good, return it and get out. MAY 2014 |
---|
| 546 | if(dtime > 0) |
---|
| 547 | Print "Deadtime from the file = ",dtime |
---|
| 548 | return(dtime) |
---|
| 549 | endif |
---|
| 550 | |
---|
| 551 | |
---|
[788] | 552 | // if no date string is passed, default to the ICE values |
---|
| 553 | if(strlen(dateAndTimeStr)==0) |
---|
| 554 | dateAndTimeStr = "01-JAN-2011" //dummy date to force to ICE values |
---|
| 555 | endif |
---|
| 556 | |
---|
[1003] | 557 | // the switch from VAX to ICE |
---|
[788] | 558 | Variable NG3_to_ICE = ConvertVAXDay2secs("23-JUL-2009") |
---|
| 559 | Variable NG7_to_ICE = ConvertVAXDay2secs("25-FEB-2010") |
---|
[1003] | 560 | |
---|
| 561 | // dates for the new NISTO hardware |
---|
| 562 | Variable NG3_to_NISTO = ConvertVAXDay2secs("22-JUN-2016") |
---|
| 563 | Variable NGB_to_NISTO = ConvertVAXDay2secs("22-JUN-2016") |
---|
| 564 | Variable NG7_to_NISTO = ConvertVAXDay2secs("27-APR-2016") //one cycle earlier on 10m |
---|
| 565 | |
---|
| 566 | |
---|
[788] | 567 | Variable fileTime = ConvertVAXDay2secs(dateAndTimeStr) |
---|
| 568 | |
---|
| 569 | |
---|
[69] | 570 | strswitch(instr) |
---|
[899] | 571 | case "CGB": |
---|
[69] | 572 | case "NG3": |
---|
| 573 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 574 | deadtime= DeadtimeNG3_ILL |
---|
| 575 | else |
---|
[1003] | 576 | if(fileTime > NG3_to_NISTO) |
---|
| 577 | deadtime = DeadtimeNG3_ORNL_NISTO //detector is ordella-type, using NISTO hardware |
---|
| 578 | endif |
---|
| 579 | if(fileTime > NG3_to_ICE && fileTime <= NG3_to_NISTO) |
---|
[788] | 580 | deadtime = DeadtimeNG3_ORNL_ICE //detector is ordella-type, using ICE hardware |
---|
| 581 | endif |
---|
[1003] | 582 | if(fileTime <= NG3_to_ICE) |
---|
| 583 | deadtime = DeadtimeNG3_ORNL_VAX //detector is ordella-type, VAX hardware |
---|
| 584 | endif |
---|
[69] | 585 | endif |
---|
| 586 | break |
---|
| 587 | case "NG5": |
---|
| 588 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 589 | deadtime= DeadtimeNG5_ILL |
---|
| 590 | else |
---|
| 591 | deadtime = DeadtimeNG5_ORNL //detector is ordella-type |
---|
| 592 | endif |
---|
| 593 | break |
---|
| 594 | case "NG7": |
---|
| 595 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
| 596 | deadtime= DeadtimeNG7_ILL |
---|
| 597 | else |
---|
[1003] | 598 | if(fileTime > NG7_to_NISTO) |
---|
| 599 | deadtime = DeadtimeNG7_ORNL_NISTO //detector is ordella-type, using NISTO hardware |
---|
| 600 | endif |
---|
| 601 | if(fileTime > NG7_to_ICE && fileTime <= NG7_to_NISTO) |
---|
[788] | 602 | deadtime = DeadtimeNG7_ORNL_ICE //detector is ordella-type, using ICE hardware |
---|
| 603 | endif |
---|
[1003] | 604 | if(fileTime <= NG7_to_ICE) |
---|
| 605 | deadtime = DeadtimeNG7_ORNL_VAX //detector is ordella-type, VAX hardware |
---|
| 606 | endif |
---|
| 607 | |
---|
[69] | 608 | endif |
---|
| 609 | break |
---|
[886] | 610 | case "NGA": |
---|
[899] | 611 | case "NGB": |
---|
[886] | 612 | if(cmpstr(detStr, "ILL ") == 0 ) |
---|
[899] | 613 | deadtime= DeadtimeNGB_ILL |
---|
[886] | 614 | else |
---|
[1003] | 615 | if(fileTime > NGB_to_NISTO) |
---|
| 616 | deadtime = DeadtimeNGB_ORNL_NISTO //detector is ordella-type, using NISTO hardware |
---|
| 617 | else |
---|
| 618 | deadtime = DeadtimeNGB_ORNL_ICE //detector is ordella-type, using ICE hardware |
---|
| 619 | endif |
---|
[886] | 620 | endif |
---|
[899] | 621 | // Print "Using fictional values for NGB dead time" |
---|
[886] | 622 | break |
---|
[69] | 623 | default: |
---|
| 624 | //return error? |
---|
[886] | 625 | DoAlert 0, "no matching instrument DetectorDeadtime, using default" |
---|
[69] | 626 | deadtime = DeadtimeDefault //1e-6 seconds, typical for new ORNL detectors |
---|
| 627 | endswitch |
---|
| 628 | |
---|
| 629 | return(deadtime) |
---|
| 630 | End |
---|
| 631 | |
---|
[788] | 632 | // converts ONLY DD-MON-YYYY portion of the data collection time |
---|
| 633 | // to a number of seconds from midnight on 1/1/1904, as Igor likes to do |
---|
| 634 | // |
---|
| 635 | // dateAndTime is the full string of "dd-mon-yyyy hh:mm:ss" as returned by the function |
---|
| 636 | // getFileCreationDate(file) |
---|
| 637 | // |
---|
| 638 | Function ConvertVAXDay2secs(dateAndTime) |
---|
| 639 | string dateAndTime |
---|
| 640 | |
---|
| 641 | Variable day,yr,mon,time_secs |
---|
| 642 | string monStr |
---|
| 643 | |
---|
| 644 | sscanf dateandtime,"%d-%3s-%4d",day,monStr,yr |
---|
| 645 | mon = monStr2num(monStr) |
---|
| 646 | // print yr,mon,day |
---|
| 647 | time_secs = date2secs(yr,mon,day) |
---|
| 648 | |
---|
| 649 | return(time_secs) |
---|
| 650 | end |
---|
| 651 | |
---|
[801] | 652 | // dd-mon-yyyy hh:mm:ss -> seconds |
---|
| 653 | // the VAX uses 24 hr time for hh |
---|
| 654 | // |
---|
| 655 | Function ConvertVAXDateTime2secs(dateAndTime) |
---|
| 656 | string dateAndTime |
---|
| 657 | |
---|
| 658 | Variable day,yr,mon,hh,mm,ss,time_secs |
---|
| 659 | string str,monStr |
---|
| 660 | |
---|
| 661 | str=dateandtime |
---|
| 662 | sscanf str,"%d-%3s-%4d %d:%d:%d",day,monStr,yr,hh,mm,ss |
---|
| 663 | mon = monStr2num(monStr) |
---|
| 664 | // print yr,mon,day,hh,mm,ss |
---|
| 665 | time_secs = date2secs(yr,mon,day) |
---|
| 666 | time_secs += hh*3600 + mm*60 + ss |
---|
| 667 | |
---|
| 668 | |
---|
| 669 | return(time_secs) |
---|
| 670 | end |
---|
| 671 | |
---|
[788] | 672 | // takes a month string and returns the corresponding number |
---|
| 673 | // |
---|
| 674 | Function monStr2num(monStr) |
---|
| 675 | String monStr |
---|
| 676 | |
---|
| 677 | String list=";JAN;FEB;MAR;APR;MAY;JUN;JUL;AUG;SEP;OCT;NOV;DEC;" |
---|
| 678 | return(WhichListItem(monStr, list ,";")) |
---|
| 679 | end |
---|
| 680 | |
---|
| 681 | |
---|
[715] | 682 | //make a three character string of the run number |
---|
| 683 | //Moved to facility utils |
---|
| 684 | Function/S RunDigitString(num) |
---|
| 685 | Variable num |
---|
| 686 | |
---|
| 687 | String numStr="" |
---|
| 688 | if(num<10) |
---|
| 689 | numStr = "00"+num2str(num) |
---|
| 690 | else |
---|
| 691 | if(num<100) |
---|
| 692 | numStr = "0"+num2str(num) |
---|
| 693 | else |
---|
| 694 | numStr = num2str(num) |
---|
| 695 | Endif |
---|
| 696 | Endif |
---|
| 697 | //Print "numstr = ",numstr |
---|
| 698 | return(numstr) |
---|
| 699 | End |
---|
[69] | 700 | |
---|
[715] | 701 | //given a filename of a SANS data filename of the form |
---|
| 702 | //TTTTTnnn.SAn_TTT_Txxx |
---|
| 703 | //returns the prefix "TTTTT" as some number of characters |
---|
| 704 | //returns "" as an invalid file prefix |
---|
| 705 | // |
---|
[750] | 706 | // NCNR-specifc, does not really belong here - but it's a beta procedure used for the |
---|
| 707 | // Combine Files Panel |
---|
[715] | 708 | // |
---|
| 709 | Function/S GetPrefixStrFromFile(item) |
---|
| 710 | String item |
---|
| 711 | String invalid = "" //"" is not a valid run prefix, since it's text |
---|
| 712 | Variable num=-1 |
---|
| 713 | |
---|
| 714 | //find the "dot" |
---|
| 715 | String runStr="" |
---|
| 716 | Variable pos = strsearch(item,".",0) |
---|
| 717 | if(pos == -1) |
---|
| 718 | //"dot" not found |
---|
| 719 | return (invalid) |
---|
| 720 | else |
---|
| 721 | //found, skip the three characters preceeding it |
---|
| 722 | if (pos <=3) |
---|
| 723 | //not enough characters |
---|
| 724 | return (invalid) |
---|
| 725 | else |
---|
| 726 | runStr = item[0,pos-4] |
---|
| 727 | return (runStr) |
---|
| 728 | Endif |
---|
| 729 | Endif |
---|
| 730 | End |
---|
| 731 | |
---|
| 732 | |
---|
| 733 | |
---|
| 734 | |
---|
[69] | 735 | /////VAX filename/Run number parsing utilities |
---|
| 736 | // |
---|
[79] | 737 | // a collection of uilities for processing vax filenames |
---|
[69] | 738 | //and processing lists (especially for display in popup menus) |
---|
| 739 | // |
---|
| 740 | //required to correctly account for VAX supplied version numbers, which |
---|
| 741 | //may or may not be removed by the ftp utility |
---|
| 742 | // |
---|
| 743 | // - parses lists of run numbers into real filenames |
---|
| 744 | // - selects proper detector constants |
---|
| 745 | // |
---|
| 746 | //************************** |
---|
[79] | 747 | // |
---|
[69] | 748 | //given a filename of a SANS data filename of the form |
---|
| 749 | //TTTTTnnn.SAn_TTT_Txxx |
---|
| 750 | //returns the run number "nnn" as a number |
---|
| 751 | //returns -1 as an invalid file number |
---|
[79] | 752 | // |
---|
| 753 | // called by several ipfs |
---|
| 754 | // |
---|
| 755 | // |
---|
[69] | 756 | Function GetRunNumFromFile(item) |
---|
| 757 | String item |
---|
| 758 | Variable invalid = -1 //negative numbers are invalid |
---|
| 759 | Variable num=-1 |
---|
| 760 | |
---|
| 761 | //find the "dot" |
---|
| 762 | String runStr="" |
---|
| 763 | Variable pos = strsearch(item,".",0) |
---|
| 764 | if(pos == -1) |
---|
| 765 | //"dot" not found |
---|
| 766 | return (invalid) |
---|
| 767 | else |
---|
| 768 | //found, get the three characters preceeding it |
---|
| 769 | if (pos <=2) |
---|
| 770 | //not enough characters |
---|
| 771 | return (invalid) |
---|
| 772 | else |
---|
| 773 | runStr = item[pos-3,pos-1] |
---|
| 774 | //convert to a number |
---|
| 775 | num = str2num(runStr) |
---|
| 776 | //if valid, return it |
---|
| 777 | if (num == NaN) |
---|
| 778 | //3 characters were not a number |
---|
| 779 | return (invalid) |
---|
| 780 | else |
---|
| 781 | //run was OK |
---|
| 782 | return (num) |
---|
| 783 | Endif |
---|
| 784 | Endif |
---|
| 785 | Endif |
---|
| 786 | End |
---|
| 787 | |
---|
| 788 | //given a filename of a SANS data filename of the form |
---|
| 789 | //TTTTTnnn.SAn_TTT_Txxx |
---|
| 790 | //returns the run number "nnn" as a STRING of THREE characters |
---|
| 791 | //returns "ABC" as an invalid file number |
---|
[79] | 792 | // |
---|
| 793 | // local function to aid in locating files by run number |
---|
| 794 | // |
---|
[69] | 795 | Function/S GetRunNumStrFromFile(item) |
---|
| 796 | String item |
---|
| 797 | String invalid = "ABC" //"ABC" is not a valid run number, since it's text |
---|
| 798 | Variable num=-1 |
---|
| 799 | |
---|
| 800 | //find the "dot" |
---|
| 801 | String runStr="" |
---|
| 802 | Variable pos = strsearch(item,".",0) |
---|
| 803 | if(pos == -1) |
---|
| 804 | //"dot" not found |
---|
| 805 | return (invalid) |
---|
| 806 | else |
---|
| 807 | //found, get the three characters preceeding it |
---|
| 808 | if (pos <=2) |
---|
| 809 | //not enough characters |
---|
| 810 | return (invalid) |
---|
| 811 | else |
---|
| 812 | runStr = item[pos-3,pos-1] |
---|
| 813 | return (runStr) |
---|
| 814 | Endif |
---|
| 815 | Endif |
---|
| 816 | End |
---|
| 817 | |
---|
[79] | 818 | //returns a string containing the full path to the file containing the |
---|
[69] | 819 | //run number "num". The null string is returned if no valid file can be found |
---|
| 820 | //the path "catPathName" used and is hard-wired, will abort if this path does not exist |
---|
| 821 | //the file returned will be a RAW SANS data file, other types of files are |
---|
| 822 | //filtered out. |
---|
[79] | 823 | // |
---|
| 824 | // called by Buttons.ipf and Transmission.ipf, and locally by parsing routines |
---|
| 825 | // |
---|
[69] | 826 | Function/S FindFileFromRunNumber(num) |
---|
| 827 | Variable num |
---|
| 828 | |
---|
| 829 | String fullName="",partialName="",item="" |
---|
| 830 | //get list of raw data files in folder that match "num" (add leading zeros) |
---|
| 831 | if( (num>999) || (num<=0) ) |
---|
| 832 | //Print "error in FindFileFromRunNumber(num), file number too large or too small" |
---|
| 833 | Return ("") |
---|
| 834 | Endif |
---|
| 835 | //make a three character string of the run number |
---|
| 836 | String numStr="" |
---|
| 837 | if(num<10) |
---|
| 838 | numStr = "00"+num2str(num) |
---|
| 839 | else |
---|
| 840 | if(num<100) |
---|
| 841 | numStr = "0"+num2str(num) |
---|
| 842 | else |
---|
| 843 | numStr = num2str(num) |
---|
| 844 | Endif |
---|
| 845 | Endif |
---|
| 846 | //Print "numstr = ",numstr |
---|
| 847 | |
---|
| 848 | //make sure that path exists |
---|
| 849 | PathInfo catPathName |
---|
| 850 | String path = S_path |
---|
| 851 | if (V_flag == 0) |
---|
| 852 | Abort "folder path does not exist - use Pick Path button" |
---|
| 853 | Endif |
---|
| 854 | String list="",newList="",testStr="" |
---|
| 855 | |
---|
| 856 | list = IndexedFile(catPathName,-1,"????") //get all files in folder |
---|
| 857 | //find (the) one with the number in the run # location in the name |
---|
| 858 | Variable numItems,ii,runFound,isRAW |
---|
| 859 | numItems = ItemsInList(list,";") //get the new number of items in the list |
---|
| 860 | ii=0 |
---|
| 861 | do |
---|
| 862 | //parse through the list in this order: |
---|
| 863 | // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy" |
---|
| 864 | // 2 - exclude by isRaw? (to minimize disk access) |
---|
| 865 | item = StringFromList(ii, list ,";" ) |
---|
| 866 | if(strlen(item) != 0) |
---|
| 867 | //find the run number, if it exists as a three character string |
---|
| 868 | testStr = GetRunNumStrFromFile(item) |
---|
| 869 | runFound= cmpstr(numStr,testStr) //compare the three character strings, 0 if equal |
---|
| 870 | if(runFound == 0) |
---|
| 871 | //the run Number was found |
---|
| 872 | //build valid filename |
---|
| 873 | partialName = FindValidFileName(item) |
---|
| 874 | if(strlen(partialName) != 0) //non-null return from FindValidFileName() |
---|
| 875 | fullName = path + partialName |
---|
| 876 | //check if RAW, if so,this must be the file! |
---|
| 877 | isRAW = CheckIfRawData(fullName) |
---|
| 878 | if(isRaw) |
---|
| 879 | //stop here |
---|
| 880 | return(fullname) |
---|
| 881 | Endif |
---|
| 882 | Endif |
---|
| 883 | Endif |
---|
| 884 | Endif |
---|
| 885 | ii+=1 |
---|
| 886 | while(ii<numItems) //process all items in list |
---|
| 887 | Return ("") //null return if file not found in list |
---|
| 888 | End |
---|
| 889 | |
---|
| 890 | //function to test a binary file to see if it is a RAW binary SANS file |
---|
| 891 | //first checks the total bytes in the file (which for raw data is 33316 bytes) |
---|
| 892 | //**note that the "DIV" file will also show up as a raw file by the run field |
---|
| 893 | //should be listed in CAT/SHORT and in patch windows |
---|
| 894 | // |
---|
| 895 | //Function then checks the file fname (full path:file) for "RAW" run.type field |
---|
| 896 | //if not found, the data is not raw data and zero is returned |
---|
[79] | 897 | // |
---|
| 898 | // called by many procedures (both external and local) |
---|
| 899 | // |
---|
[69] | 900 | Function CheckIfRawData(fname) |
---|
| 901 | String fname |
---|
| 902 | |
---|
| 903 | Variable refnum,totalBytes |
---|
| 904 | String testStr="" |
---|
| 905 | |
---|
| 906 | Open/R/T="????TEXT" refNum as fname |
---|
[541] | 907 | if(strlen(s_filename) == 0) //user cancel (/Z not used, so V_flag not set) |
---|
| 908 | return(0) |
---|
| 909 | endif |
---|
| 910 | |
---|
[79] | 911 | //get the total number of bytes in the file |
---|
[69] | 912 | FStatus refNum |
---|
| 913 | totalBytes = V_logEOF |
---|
| 914 | //Print totalBytes |
---|
[377] | 915 | if(totalBytes < 100) |
---|
| 916 | Close refNum |
---|
| 917 | return(0) //not a raw file |
---|
| 918 | endif |
---|
[69] | 919 | FSetPos refNum,75 |
---|
| 920 | FReadLine/N=3 refNum,testStr |
---|
| 921 | Close refNum |
---|
| 922 | |
---|
[577] | 923 | if(totalBytes == 33316 && ( cmpstr(testStr,"RAW")==0 || cmpstr(testStr,"SIM")==0)) |
---|
[69] | 924 | //true, is raw data file |
---|
| 925 | Return(1) |
---|
| 926 | else |
---|
| 927 | //some other file |
---|
| 928 | Return(0) |
---|
| 929 | Endif |
---|
| 930 | End |
---|
| 931 | |
---|
[857] | 932 | //function to test a file to see if it is a DIV file |
---|
| 933 | // |
---|
| 934 | // returns truth 0/1 |
---|
| 935 | // |
---|
| 936 | // called by many procedures (both external and local) |
---|
| 937 | // |
---|
| 938 | Function CheckIfDIVData(fname) |
---|
| 939 | String fname |
---|
| 940 | |
---|
| 941 | |
---|
| 942 | Variable refnum,totalBytes |
---|
| 943 | // String testStr="" |
---|
| 944 | |
---|
| 945 | Open/R/T="????TEXT" refNum as fname |
---|
| 946 | if(strlen(s_filename) == 0) //user cancel (/Z not used, so V_flag not set) |
---|
| 947 | return(0) |
---|
| 948 | endif |
---|
| 949 | |
---|
| 950 | //get the total number of bytes in the file |
---|
| 951 | FStatus refNum |
---|
| 952 | totalBytes = V_logEOF |
---|
| 953 | //Print totalBytes |
---|
| 954 | if(totalBytes < 100) |
---|
| 955 | Close refNum |
---|
| 956 | return(0) //not a raw file |
---|
| 957 | endif |
---|
| 958 | // FSetPos refNum,75 |
---|
| 959 | // FReadLine/N=3 refNum,testStr |
---|
| 960 | Close refNum |
---|
| 961 | |
---|
| 962 | if(totalBytes == 66116) // && ( cmpstr(testStr,"RAW")==0 || cmpstr(testStr,"SIM")==0)) |
---|
| 963 | //true, is raw data file |
---|
| 964 | Return(1) |
---|
| 965 | else |
---|
| 966 | //some other file |
---|
| 967 | Return(0) |
---|
| 968 | Endif |
---|
| 969 | |
---|
| 970 | End |
---|
| 971 | |
---|
[74] | 972 | //function to check the header of a raw data file (full path specified by fname) |
---|
| 973 | //checks the field of the x-position of the beamstop during data collection |
---|
| 974 | //if the x-position is more negative (farther to the left) than xTol(input) |
---|
| 975 | //the the beamstop is "out" and the file is a transmission run and not a scattering run |
---|
| 976 | //xtol typically set at -5 (cm) - trans runs have bs(x) at -10 to -15 cm |
---|
| 977 | // function returns 1 if beamstop is out, 0 if beamstop is in |
---|
| 978 | // |
---|
[82] | 979 | // tolerance is set as a global value "root:myGlobals:BeamstopXTol" |
---|
[79] | 980 | // |
---|
| 981 | // called by Transmission.ipf, CatVSTable.ipf, NSORT.ipf |
---|
| 982 | // |
---|
[82] | 983 | Function isTransFile(fName) |
---|
[74] | 984 | String fname |
---|
| 985 | |
---|
| 986 | Variable refnum,xpos |
---|
[82] | 987 | NVAR xTol = root:myGlobals:BeamstopXTol |
---|
| 988 | |
---|
[74] | 989 | //pos = 369, read one real value |
---|
| 990 | |
---|
| 991 | SetDataFolder root: |
---|
[1017] | 992 | String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q" |
---|
| 993 | |
---|
| 994 | if(cmpstr("\\\\",fname[0,1])==0) //Windows user going through network neighborhood |
---|
| 995 | PathInfo catPathName |
---|
| 996 | if(V_flag==1) |
---|
| 997 | //catPathName exists, use it |
---|
| 998 | GBLoadStr += "/S=368/U=1/P=catPathName " + "\"" + ParseFilePath(0, fname, ":", 1, 0) + "\"" |
---|
| 999 | else |
---|
| 1000 | // need to create a temporary path |
---|
| 1001 | String tmpPathStr = ParseFilePath(1, fname, ":", 1, 0) |
---|
| 1002 | NewPath/O/Q tmpUNCPath tmpPathStr |
---|
| 1003 | GBLoadStr += "/S=368/U=1/P=tmpUNCPath " + "\"" + ParseFilePath(0, fname, ":", 1, 0) + "\"" |
---|
| 1004 | endif |
---|
| 1005 | else |
---|
| 1006 | // original case, fname is the full path:name and is Mac (or a mapped drive) |
---|
| 1007 | GBLoadStr += "/S=368/U=1" + "\"" + fname + "\"" |
---|
| 1008 | endif |
---|
| 1009 | |
---|
| 1010 | Execute GBLoadStr |
---|
[74] | 1011 | Wave w=$"root:tempGBWave0" |
---|
| 1012 | xPos = w[0] |
---|
| 1013 | KillWaves/Z w |
---|
| 1014 | //Print "xPos = ",xpos |
---|
| 1015 | |
---|
| 1016 | if(xpos<=xTol) |
---|
| 1017 | //xpos is farther left (more negative) than xtol (currently -5 cm) |
---|
| 1018 | Return(1) |
---|
| 1019 | else |
---|
| 1020 | //some other file |
---|
| 1021 | Return(0) |
---|
| 1022 | Endif |
---|
| 1023 | End |
---|
| 1024 | |
---|
| 1025 | |
---|
[69] | 1026 | //function to remove all spaces from names when searching for filenames |
---|
| 1027 | //the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn) |
---|
| 1028 | //but the text field in the header WILL, if less than 3 characters were used for the |
---|
| 1029 | //user's initials, and can have leading spaces if prefix was less than 5 characters |
---|
| 1030 | // |
---|
| 1031 | //returns a string identical to the original string, except with the interior spaces removed |
---|
| 1032 | // |
---|
[79] | 1033 | // local function for file name manipulation |
---|
| 1034 | // |
---|
[69] | 1035 | Function/S RemoveAllSpaces(str) |
---|
| 1036 | String str |
---|
| 1037 | |
---|
| 1038 | String tempstr = str |
---|
| 1039 | Variable ii,spc,len //should never be more than 2 or 3 trailing spaces in a filename |
---|
| 1040 | ii=0 |
---|
| 1041 | do |
---|
| 1042 | len = strlen(tempStr) |
---|
| 1043 | spc = strsearch(tempStr," ",0) //is the last character a space? |
---|
| 1044 | if (spc == -1) |
---|
| 1045 | break //no more spaces found, get out |
---|
| 1046 | endif |
---|
| 1047 | str = tempstr |
---|
| 1048 | tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string |
---|
| 1049 | While(1) //should never be more than 2 or 3 |
---|
| 1050 | |
---|
| 1051 | If(strlen(tempStr) < 1) |
---|
| 1052 | tempStr = "" //be sure to return a null string if problem found |
---|
| 1053 | Endif |
---|
| 1054 | |
---|
| 1055 | //Print strlen(tempstr) |
---|
| 1056 | |
---|
| 1057 | Return(tempStr) |
---|
| 1058 | |
---|
| 1059 | End |
---|
| 1060 | |
---|
| 1061 | |
---|
[79] | 1062 | //Function attempts to find valid filename from partial name by checking for |
---|
| 1063 | // the existence of the file on disk. |
---|
| 1064 | // - checks as is |
---|
| 1065 | // - adds ";vers" for possible VAX files |
---|
| 1066 | // - strips spaces |
---|
| 1067 | // - permutations of upper/lowercase |
---|
[69] | 1068 | // |
---|
| 1069 | // added 11/99 - uppercase and lowercase versions of the file are tried, if necessary |
---|
[916] | 1070 | // since from marquee, the filename field (textread[0]) must be used, and can be a mix of //02JUL13 |
---|
[69] | 1071 | // upper/lowercase letters, while the filename on the server (should) be all caps |
---|
| 1072 | // now makes repeated calls to ValidFileString() |
---|
| 1073 | // |
---|
[79] | 1074 | // returns a valid filename (No path prepended) or a null string |
---|
| 1075 | // |
---|
| 1076 | // called by any functions, both external and local |
---|
| 1077 | // |
---|
[69] | 1078 | Function/S FindValidFilename(partialName) |
---|
| 1079 | String PartialName |
---|
| 1080 | |
---|
| 1081 | String retStr="" |
---|
| 1082 | |
---|
| 1083 | //try name with no changes - to allow for ABS files that have spaces in the names 12APR04 |
---|
| 1084 | retStr = ValidFileString(partialName) |
---|
| 1085 | if(cmpstr(retStr,"") !=0) |
---|
| 1086 | //non-null return |
---|
| 1087 | return(retStr) |
---|
| 1088 | Endif |
---|
| 1089 | |
---|
| 1090 | //if the partial name is derived from the file header, there can be spaces at the beginning |
---|
| 1091 | //or in the middle of the filename - depending on the prefix and initials used |
---|
| 1092 | // |
---|
| 1093 | //remove any leading spaces from the name before starting |
---|
| 1094 | partialName = RemoveAllSpaces(partialName) |
---|
| 1095 | |
---|
| 1096 | //try name with no spaces |
---|
| 1097 | retStr = ValidFileString(partialName) |
---|
| 1098 | if(cmpstr(retStr,"") !=0) |
---|
| 1099 | //non-null return |
---|
| 1100 | return(retStr) |
---|
| 1101 | Endif |
---|
| 1102 | |
---|
| 1103 | //try all UPPERCASE |
---|
| 1104 | partialName = UpperStr(partialName) |
---|
| 1105 | retStr = ValidFileString(partialName) |
---|
| 1106 | if(cmpstr(retStr,"") !=0) |
---|
| 1107 | //non-null return |
---|
| 1108 | return(retStr) |
---|
| 1109 | Endif |
---|
| 1110 | |
---|
| 1111 | //try all lowercase (ret null if failure) |
---|
| 1112 | partialName = LowerStr(partialName) |
---|
| 1113 | retStr = ValidFileString(partialName) |
---|
| 1114 | if(cmpstr(retStr,"") !=0) |
---|
| 1115 | //non-null return |
---|
| 1116 | return(retStr) |
---|
| 1117 | else |
---|
| 1118 | return(retStr) |
---|
| 1119 | Endif |
---|
| 1120 | End |
---|
| 1121 | |
---|
[79] | 1122 | // Function checks for the existence of a file |
---|
| 1123 | // partialName;vers (to account for VAX filenaming conventions) |
---|
| 1124 | // The partial name is tried first with no version number |
---|
[69] | 1125 | // |
---|
[79] | 1126 | // *** the PATH is hard-wired to catPathName (which is assumed to exist) |
---|
| 1127 | // version numers up to ;10 are tried |
---|
| 1128 | // only the "name;vers" is returned if successful. The path is not prepended |
---|
| 1129 | // |
---|
| 1130 | // local function |
---|
| 1131 | // |
---|
[69] | 1132 | Function/S ValidFileString(partialName) |
---|
| 1133 | String partialName |
---|
| 1134 | |
---|
| 1135 | String tempName = "",msg="" |
---|
| 1136 | Variable ii,refnum |
---|
| 1137 | |
---|
| 1138 | ii=0 |
---|
| 1139 | do |
---|
| 1140 | if(ii==0) |
---|
| 1141 | //first pass, try the partialName |
---|
| 1142 | tempName = partialName |
---|
| 1143 | Open/Z/R/T="????TEXT"/P=catPathName refnum tempName //Does open file (/Z flag) |
---|
| 1144 | if(V_flag == 0) |
---|
| 1145 | //file exists |
---|
| 1146 | Close refnum //YES needed, |
---|
| 1147 | break |
---|
| 1148 | endif |
---|
| 1149 | else |
---|
| 1150 | tempName = partialName + ";" + num2str(ii) |
---|
| 1151 | Open/Z/R/T="????TEXT"/P=catPathName refnum tempName |
---|
| 1152 | if(V_flag == 0) |
---|
| 1153 | //file exists |
---|
| 1154 | Close refnum |
---|
| 1155 | break |
---|
| 1156 | endif |
---|
| 1157 | Endif |
---|
| 1158 | ii+=1 |
---|
| 1159 | //print "ii=",ii |
---|
| 1160 | while(ii<11) |
---|
| 1161 | //go get the selected bits of information, using tempName, which exists |
---|
| 1162 | if(ii>=11) |
---|
| 1163 | //msg = partialName + " not found. is version number > 11?" |
---|
| 1164 | //DoAlert 0, msg |
---|
| 1165 | //PathInfo catPathName |
---|
| 1166 | //Print S_Path |
---|
| 1167 | Return ("") //use null string as error condition |
---|
| 1168 | Endif |
---|
| 1169 | |
---|
| 1170 | Return (tempName) |
---|
| 1171 | End |
---|
| 1172 | |
---|
| 1173 | //returns a string containing filename (WITHOUT the ;vers) |
---|
| 1174 | //the input string is a full path to the file (Mac-style, still works on Win in IGOR) |
---|
| 1175 | //with the folders separated by colons |
---|
[79] | 1176 | // |
---|
| 1177 | // called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf |
---|
| 1178 | // |
---|
[69] | 1179 | Function/S GetFileNameFromPathNoSemi(fullPath) |
---|
| 1180 | String fullPath |
---|
| 1181 | |
---|
| 1182 | Variable offset1,offset2 |
---|
| 1183 | String filename="" |
---|
| 1184 | //String PartialPath |
---|
| 1185 | offset1 = 0 |
---|
| 1186 | do |
---|
| 1187 | offset2 = StrSearch(fullPath, ":", offset1) |
---|
| 1188 | if (offset2 == -1) // no more colons ? |
---|
| 1189 | fileName = FullPath[offset1,strlen(FullPath) ] |
---|
| 1190 | //PartialPath = FullPath[0, offset1-1] |
---|
| 1191 | break |
---|
| 1192 | endif |
---|
| 1193 | offset1 = offset2+1 |
---|
| 1194 | while (1) |
---|
| 1195 | |
---|
| 1196 | //remove version number from name, if it's there - format should be: filename;N |
---|
| 1197 | filename = StringFromList(0,filename,";") //returns null if error |
---|
| 1198 | |
---|
| 1199 | Return filename |
---|
| 1200 | End |
---|
| 1201 | |
---|
| 1202 | //returns a string containing filename (INCLUDING the ;vers) |
---|
| 1203 | //the input string is a full path to the file (Mac-style, still works on Win in IGOR) |
---|
| 1204 | //with the folders separated by colons |
---|
[79] | 1205 | // |
---|
| 1206 | // local, currently unused |
---|
| 1207 | // |
---|
[69] | 1208 | Function/S GetFileNameFromPathKeepSemi(fullPath) |
---|
| 1209 | String fullPath |
---|
| 1210 | |
---|
| 1211 | Variable offset1,offset2 |
---|
| 1212 | String filename |
---|
| 1213 | //String PartialPath |
---|
| 1214 | offset1 = 0 |
---|
| 1215 | do |
---|
| 1216 | offset2 = StrSearch(fullPath, ":", offset1) |
---|
| 1217 | if (offset2 == -1) // no more colons ? |
---|
| 1218 | fileName = FullPath[offset1,strlen(FullPath) ] |
---|
| 1219 | //PartialPath = FullPath[0, offset1-1] |
---|
| 1220 | break |
---|
| 1221 | endif |
---|
| 1222 | offset1 = offset2+1 |
---|
| 1223 | while (1) |
---|
| 1224 | |
---|
| 1225 | //keep version number from name, if it's there - format should be: filename;N |
---|
| 1226 | |
---|
| 1227 | Return filename |
---|
| 1228 | End |
---|
| 1229 | |
---|
| 1230 | //given the full path and filename (fullPath), strips the data path |
---|
| 1231 | //(Mac-style, separated by colons) and returns this path |
---|
| 1232 | //this partial path is the same string that would be returned from PathInfo, for example |
---|
[79] | 1233 | // |
---|
| 1234 | // - allows the user to save to a different path than catPathName |
---|
| 1235 | // |
---|
| 1236 | // called by WriteQIS.ipf |
---|
| 1237 | // |
---|
[69] | 1238 | Function/S GetPathStrFromfullName(fullPath) |
---|
| 1239 | String fullPath |
---|
| 1240 | |
---|
| 1241 | Variable offset1,offset2 |
---|
| 1242 | //String filename |
---|
| 1243 | String PartialPath |
---|
| 1244 | offset1 = 0 |
---|
| 1245 | do |
---|
| 1246 | offset2 = StrSearch(fullPath, ":", offset1) |
---|
| 1247 | if (offset2 == -1) // no more colons ? |
---|
| 1248 | //fileName = FullPath[offset1,strlen(FullPath) ] |
---|
| 1249 | PartialPath = FullPath[0, offset1-1] |
---|
| 1250 | break |
---|
| 1251 | endif |
---|
| 1252 | offset1 = offset2+1 |
---|
| 1253 | while (1) |
---|
| 1254 | |
---|
| 1255 | Return PartialPath |
---|
| 1256 | End |
---|
| 1257 | |
---|
| 1258 | //given the VAX filename, pull off the first 8 characters to make a valid |
---|
| 1259 | //file string that can be used for naming averaged 1-d files |
---|
[79] | 1260 | // |
---|
| 1261 | // called by ProtocolAsPanel.ipf and Tile_2D.ipf |
---|
| 1262 | // |
---|
[69] | 1263 | Function/S GetNameFromHeader(fullName) |
---|
| 1264 | String fullName |
---|
| 1265 | String temp, newName = "" |
---|
| 1266 | Variable spc,ii=0 |
---|
| 1267 | |
---|
| 1268 | //filename is 20 characters NNNNNxxx.SAn_NNN_NNN |
---|
| 1269 | //want the first 8 characters, NNNNNxxx, then strip off any spaces at the beginning |
---|
| 1270 | //NNNNN was entered as less than 5 characters |
---|
| 1271 | //returns a null string if no name can be found |
---|
| 1272 | do |
---|
| 1273 | temp = fullname[ii,7] //characters ii,7 of the name |
---|
| 1274 | spc = strsearch(temp," ",0) |
---|
| 1275 | if (spc == -1) |
---|
| 1276 | break //no more spaces found |
---|
| 1277 | endif |
---|
| 1278 | ii+=1 |
---|
| 1279 | While(ii<8) |
---|
| 1280 | |
---|
| 1281 | If(strlen(temp) < 1) |
---|
| 1282 | newName = "" //be sure to return a null string if problem found |
---|
| 1283 | else |
---|
| 1284 | newName = temp |
---|
| 1285 | Endif |
---|
| 1286 | |
---|
| 1287 | Return(newName) |
---|
| 1288 | End |
---|
| 1289 | |
---|
| 1290 | //list (input) is a list, typically returned from IndexedFile() |
---|
[79] | 1291 | //which is semicolon-delimited, and may contain filenames from the VAX |
---|
[69] | 1292 | //that contain version numbers, where the version number appears as a separate list item |
---|
| 1293 | //(and also as a non-existent file) |
---|
| 1294 | //these numbers must be purged from the list, especially for display in a popup |
---|
| 1295 | //or list processing of filenames |
---|
| 1296 | //the function returns the list, cleaned of version numbers (up to 11) |
---|
| 1297 | //raw data files will typically never have a version number other than 1. |
---|
[79] | 1298 | // |
---|
| 1299 | // if there are no version numbers in the list, the input list is returned |
---|
| 1300 | // |
---|
| 1301 | // called by CatVSTable.ipf, NSORT.ipf, Transmission.ipf, WorkFileUtils.ipf |
---|
| 1302 | // |
---|
[69] | 1303 | Function/S RemoveVersNumsFromList(list) |
---|
| 1304 | String list |
---|
| 1305 | |
---|
| 1306 | //get rid of version numbers first (up to 11) |
---|
| 1307 | Variable ii,num |
---|
| 1308 | String item |
---|
| 1309 | num = ItemsInList(list,";") |
---|
| 1310 | ii=1 |
---|
| 1311 | do |
---|
| 1312 | item = num2str(ii) |
---|
| 1313 | list = RemoveFromList(item, list ,";" ) |
---|
| 1314 | ii+=1 |
---|
| 1315 | while(ii<12) |
---|
| 1316 | |
---|
| 1317 | return (list) |
---|
| 1318 | End |
---|
| 1319 | |
---|
| 1320 | //input is a list of run numbers, and output is a list of filenames (not the full path) |
---|
| 1321 | //*** input list must be COMMA delimited*** |
---|
| 1322 | //output is equivalent to selecting from the CAT table |
---|
| 1323 | //if some or all of the list items are valid filenames, keep them... |
---|
[79] | 1324 | //if an error is encountered, notify of the offending element and return a null list |
---|
[69] | 1325 | // |
---|
| 1326 | //output is COMMA delimited |
---|
| 1327 | // |
---|
| 1328 | // this routine is expecting that the "ask", "none" special cases are handled elsewhere |
---|
| 1329 | //and not passed here |
---|
[79] | 1330 | // |
---|
| 1331 | // called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf |
---|
| 1332 | // |
---|
[69] | 1333 | Function/S ParseRunNumberList(list) |
---|
| 1334 | String list |
---|
| 1335 | |
---|
| 1336 | String newList="",item="",tempStr="" |
---|
| 1337 | Variable num,ii,runNum |
---|
| 1338 | |
---|
| 1339 | //expand number ranges, if any |
---|
| 1340 | list = ExpandNumRanges(list) |
---|
| 1341 | |
---|
| 1342 | num=itemsinlist(list,",") |
---|
| 1343 | |
---|
| 1344 | for(ii=0;ii<num;ii+=1) |
---|
| 1345 | //get the item |
---|
| 1346 | item = StringFromList(ii,list,",") |
---|
| 1347 | //is it already a valid filename? |
---|
| 1348 | tempStr=FindValidFilename(item) //returns filename if good, null if error |
---|
| 1349 | if(strlen(tempstr)!=0) |
---|
| 1350 | //valid name, add to list |
---|
| 1351 | //Print "it's a file" |
---|
| 1352 | newList += tempStr + "," |
---|
| 1353 | else |
---|
| 1354 | //not a valid name |
---|
| 1355 | //is it a number? |
---|
| 1356 | runNum=str2num(item) |
---|
| 1357 | //print runnum |
---|
| 1358 | if(numtype(runNum) != 0) |
---|
| 1359 | //not a number - maybe an error |
---|
| 1360 | DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename." |
---|
| 1361 | return("") |
---|
| 1362 | else |
---|
| 1363 | //a run number or an error |
---|
| 1364 | tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) ) |
---|
| 1365 | if(strlen(tempstr)==0) |
---|
| 1366 | //file not found, error |
---|
| 1367 | DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number." |
---|
| 1368 | return("") |
---|
| 1369 | else |
---|
| 1370 | newList += tempStr + "," |
---|
| 1371 | endif |
---|
| 1372 | endif |
---|
| 1373 | endif |
---|
| 1374 | endfor //loop over all items in list |
---|
| 1375 | |
---|
| 1376 | return(newList) |
---|
| 1377 | End |
---|
| 1378 | |
---|
| 1379 | //takes a comma delimited list that MAY contain number range, and |
---|
| 1380 | //expands any range of run numbers into a comma-delimited list... |
---|
| 1381 | //and returns the new list - if not a range, return unchanged |
---|
[79] | 1382 | // |
---|
| 1383 | // local function |
---|
| 1384 | // |
---|
[69] | 1385 | Function/S ExpandNumRanges(list) |
---|
| 1386 | String list |
---|
| 1387 | |
---|
| 1388 | String newList="",dash="-",item,str |
---|
| 1389 | Variable num,ii,hasDash |
---|
| 1390 | |
---|
| 1391 | num=itemsinlist(list,",") |
---|
| 1392 | // print num |
---|
| 1393 | for(ii=0;ii<num;ii+=1) |
---|
| 1394 | //get the item |
---|
| 1395 | item = StringFromList(ii,list,",") |
---|
| 1396 | //does it contain a dash? |
---|
| 1397 | hasDash = strsearch(item,dash,0) //-1 if no dash found |
---|
| 1398 | if(hasDash == -1) |
---|
| 1399 | //not a range, keep it in the list |
---|
| 1400 | newList += item + "," |
---|
| 1401 | else |
---|
| 1402 | //has a dash (so it's a range), expand (or add null) |
---|
| 1403 | newList += ListFromDash(item) |
---|
| 1404 | endif |
---|
| 1405 | endfor |
---|
| 1406 | |
---|
| 1407 | return newList |
---|
| 1408 | End |
---|
| 1409 | |
---|
| 1410 | //be sure to add a trailing comma to the return string... |
---|
[79] | 1411 | // |
---|
| 1412 | // local function |
---|
| 1413 | // |
---|
[69] | 1414 | Function/S ListFromDash(item) |
---|
| 1415 | String item |
---|
| 1416 | |
---|
| 1417 | String numList="",loStr="",hiStr="" |
---|
| 1418 | Variable lo,hi,ii |
---|
| 1419 | |
---|
| 1420 | loStr=StringFromList(0,item,"-") //treat the range as a list |
---|
| 1421 | hiStr=StringFromList(1,item,"-") |
---|
| 1422 | lo=str2num(loStr) |
---|
| 1423 | hi=str2num(hiStr) |
---|
| 1424 | if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) ) |
---|
| 1425 | numList="" |
---|
| 1426 | return numList |
---|
| 1427 | endif |
---|
| 1428 | for(ii=lo;ii<=hi;ii+=1) |
---|
| 1429 | numList += num2str(ii) + "," |
---|
| 1430 | endfor |
---|
| 1431 | |
---|
| 1432 | Return numList |
---|
| 1433 | End |
---|
| 1434 | |
---|
| 1435 | |
---|
| 1436 | ////////Transmission |
---|
| 1437 | //****************** |
---|
| 1438 | //lookup tables for attenuator transmissions |
---|
| 1439 | //NG3 and NG7 attenuators are physically different, so the transmissions are slightly different |
---|
| 1440 | //NG1 - (8m SANS) is not supported |
---|
[79] | 1441 | // |
---|
[121] | 1442 | // new calibration done June 2007, John Barker |
---|
[1209] | 1443 | // new calibration for 3A only -- September 2019, John Barker |
---|
[1219] | 1444 | // -- corrected values for att #9 and att #10 27SEP2019 |
---|
[79] | 1445 | // |
---|
[69] | 1446 | Proc MakeNG3AttenTable() |
---|
| 1447 | |
---|
| 1448 | NewDataFolder/O root:myGlobals:Attenuators |
---|
| 1449 | //do explicitly to avoid data folder problems, redundant, but it must work without fail |
---|
[1217] | 1450 | // Variable num=10 //10 needed for tables after June 2007 |
---|
| 1451 | Variable num=11 //11 needed for tables after Sep 2019 |
---|
[121] | 1452 | |
---|
| 1453 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att0 |
---|
| 1454 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att1 |
---|
| 1455 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att2 |
---|
| 1456 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att3 |
---|
| 1457 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att4 |
---|
| 1458 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att5 |
---|
| 1459 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att6 |
---|
| 1460 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att7 |
---|
| 1461 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att8 |
---|
| 1462 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att9 |
---|
| 1463 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att10 |
---|
[69] | 1464 | |
---|
[794] | 1465 | // and a wave for the errors at each attenuation factor |
---|
| 1466 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att0_err |
---|
| 1467 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att1_err |
---|
| 1468 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att2_err |
---|
| 1469 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att3_err |
---|
| 1470 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att4_err |
---|
| 1471 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att5_err |
---|
| 1472 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att6_err |
---|
| 1473 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att7_err |
---|
| 1474 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att8_err |
---|
| 1475 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att9_err |
---|
| 1476 | Make/O/N=(num) root:myGlobals:Attenuators:ng3att10_err |
---|
| 1477 | |
---|
| 1478 | |
---|
[1219] | 1479 | //each wave has 11 elements, the transmission of att# at the wavelengths |
---|
[121] | 1480 | //lambda = 4,5,6,7,8,10,12,14,17,20 (4 A and 20 A are extrapolated values) |
---|
[1209] | 1481 | Make/O/N=(num) root:myGlobals:Attenuators:ng3lambda={3,4,5,6,7,8,10,12,14,17,20} |
---|
[121] | 1482 | |
---|
| 1483 | // new calibration done June 2007, John Barker |
---|
[1209] | 1484 | // new calibration for 3A only -- September 2019, John Barker |
---|
| 1485 | root:myGlobals:Attenuators:ng3att0 = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } |
---|
| 1486 | root:myGlobals:Attenuators:ng3att1 = {0.49769,0.444784,0.419,0.3935,0.3682,0.3492,0.3132,0.2936,0.2767,0.2477,0.22404} |
---|
| 1487 | root:myGlobals:Attenuators:ng3att2 = {0.25729,0.207506,0.1848,0.1629,0.1447,0.1292,0.1056,0.09263,0.08171,0.06656,0.0546552} |
---|
| 1488 | root:myGlobals:Attenuators:ng3att3 = {0.12823,0.092412,0.07746,0.06422,0.05379,0.04512,0.03321,0.02707,0.02237,0.01643,0.0121969} |
---|
| 1489 | root:myGlobals:Attenuators:ng3att4 = {0.064491,0.0417722,0.03302,0.02567,0.02036,0.01604,0.01067,0.00812,0.006316,0.00419,0.00282411} |
---|
| 1490 | root:myGlobals:Attenuators:ng3att5 = {0.032216,0.0187129,0.01397,0.01017,0.007591,0.005668,0.003377,0.002423,0.001771,0.001064,0.000651257} |
---|
| 1491 | root:myGlobals:Attenuators:ng3att6 = {0.016244,0.00851048,0.005984,0.004104,0.002888,0.002029,0.001098,0.0007419,0.0005141,0.000272833,0.000150624} |
---|
| 1492 | root:myGlobals:Attenuators:ng3att7 = {0.0041106,0.00170757,0.001084,0.0006469,0.0004142,0.0002607,0.0001201,7.664e-05,4.06624e-05,1.77379e-05,7.30624e-06} |
---|
| 1493 | root:myGlobals:Attenuators:ng3att8 = {0.001029,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} |
---|
[1219] | 1494 | root:myGlobals:Attenuators:ng3att9 = {0.00026462,5.999e-05,3.3937e-05,1.6241e-05,8.9395e-06,5.1975e-06,2.0337e-06,5.9274e-07,2.6022e-07,7.4975e-08,2.1699e-08} |
---|
| 1495 | root:myGlobals:Attenuators:ng3att10 = {6.9169e-05,1.1244e-05,6.0046e-06,2.5733e-06,1.3133e-06,7.3386e-07,2.3137e-07,5.2128e-08,2.0817e-08,4.8744e-09,1.1826e-09} |
---|
[121] | 1496 | |
---|
[794] | 1497 | // percent errors as measured, May 2007 values |
---|
[1209] | 1498 | // new calibration for 3A only -- September 2019, John Barker |
---|
[794] | 1499 | // zero error for zero attenuators, appropriate average values put in for unknown values |
---|
[1209] | 1500 | root:myGlobals:Attenuators:ng3att0_err = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
---|
| 1501 | root:myGlobals:Attenuators:ng3att1_err = {0.655,0.15,0.142,0.154,0.183,0.221,0.328,0.136,0.13,0.163,0.15} |
---|
| 1502 | root:myGlobals:Attenuators:ng3att2_err = {1.0725,0.25,0.257,0.285,0.223,0.271,0.405,0.212,0.223,0.227,0.25} |
---|
| 1503 | root:myGlobals:Attenuators:ng3att3_err = {1.6862,0.3,0.295,0.329,0.263,0.323,0.495,0.307,0.28,0.277,0.3} |
---|
| 1504 | root:myGlobals:Attenuators:ng3att4_err = {1.86,0.35,0.331,0.374,0.303,0.379,0.598,0.367,0.322,0.33,0.35} |
---|
| 1505 | root:myGlobals:Attenuators:ng3att5_err = {1.9755,0.4,0.365,0.418,0.355,0.454,0.745,0.411,0.367,0.485,0.4} |
---|
| 1506 | root:myGlobals:Attenuators:ng3att6_err = {2.0725,0.45,0.406,0.473,0.385,0.498,0.838,0.454,0.49,0.5,0.5} |
---|
| 1507 | root:myGlobals:Attenuators:ng3att7_err = {4.0576,0.6,0.554,0.692,0.425,0.562,0.991,0.715,0.8,0.8,0.8} |
---|
| 1508 | root:myGlobals:Attenuators:ng3att8_err = {8.1442,0.7,0.705,0.927,0.503,0.691,1.27,1,1,1,1} |
---|
| 1509 | root:myGlobals:Attenuators:ng3att9_err = {10.361,1,0.862,1.172,0.799,1.104,1.891,1.5,1.5,1.5,1.5} |
---|
| 1510 | root:myGlobals:Attenuators:ng3att10_err = {10.53,1.5,1.054,1.435,1.354,1.742,2,2,2,2,2} |
---|
[794] | 1511 | |
---|
| 1512 | |
---|
[121] | 1513 | //old tables, pre-June 2007 |
---|
| 1514 | // Make/O/N=9 root:myGlobals:Attenuators:ng3lambda={5,6,7,8,10,12,14,17,20} |
---|
| 1515 | // root:myGlobals:Attenuators:ng3att0 = {1, 1, 1, 1, 1, 1, 1, 1,1 } |
---|
| 1516 | // root:myGlobals:Attenuators:ng3att1 = {0.421, 0.394, 0.371, 0.349, 0.316, 0.293, 0.274, 0.245,0.220} |
---|
| 1517 | // root:myGlobals:Attenuators:ng3att2 = {0.187, 0.164, 0.145, 0.130, 0.106, 0.0916, 0.0808, 0.0651,0.0531} |
---|
| 1518 | // root:myGlobals:Attenuators:ng3att3 = {0.0777, 0.0636, 0.0534, 0.0446, 0.0330, 0.0262, 0.0217, 0.0157 ,0.0116} |
---|
| 1519 | // 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} |
---|
| 1520 | // 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} |
---|
| 1521 | // 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} |
---|
| 1522 | // 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} |
---|
| 1523 | // 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} |
---|
| 1524 | // 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} |
---|
| 1525 | // 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] | 1526 | |
---|
| 1527 | End |
---|
| 1528 | |
---|
[121] | 1529 | // new calibration done June 2007, John Barker |
---|
[69] | 1530 | Proc MakeNG7AttenTable() |
---|
| 1531 | |
---|
| 1532 | NewDataFolder/O root:myGlobals:Attenuators |
---|
[121] | 1533 | |
---|
| 1534 | Variable num=10 //10 needed for tables after June 2007 |
---|
| 1535 | |
---|
[118] | 1536 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att0 |
---|
| 1537 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att1 |
---|
| 1538 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att2 |
---|
| 1539 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att3 |
---|
| 1540 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att4 |
---|
| 1541 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att5 |
---|
| 1542 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att6 |
---|
| 1543 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att7 |
---|
| 1544 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att8 |
---|
| 1545 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att9 |
---|
| 1546 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att10 |
---|
[69] | 1547 | |
---|
[794] | 1548 | // and a wave for the errors at each attenuation factor |
---|
| 1549 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att0_err |
---|
| 1550 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att1_err |
---|
| 1551 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att2_err |
---|
| 1552 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att3_err |
---|
| 1553 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att4_err |
---|
| 1554 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att5_err |
---|
| 1555 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att6_err |
---|
| 1556 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att7_err |
---|
| 1557 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att8_err |
---|
| 1558 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att9_err |
---|
| 1559 | Make/O/N=(num) root:myGlobals:Attenuators:ng7att10_err |
---|
| 1560 | |
---|
[118] | 1561 | //NG7 wave has 10 elements, the transmission of att# at the wavelengths |
---|
[121] | 1562 | //lambda =4, 5,6,7,8,10,12,14,17,20 |
---|
| 1563 | // note that some of the higher attenuations and ALL of the 4 A and 20A data is interpolated |
---|
[118] | 1564 | // none of these values are expected to be used in reality since the flux would be too low in practice |
---|
| 1565 | Make/O/N=(num) root:myGlobals:Attenuators:ng7lambda={4,5,6,7,8,10,12,14,17,20} |
---|
| 1566 | |
---|
| 1567 | // New calibration, June 2007, John Barker |
---|
| 1568 | root:myGlobals:Attenuators:ng7att0 = {1, 1, 1, 1, 1, 1, 1, 1 ,1,1} |
---|
| 1569 | root:myGlobals:Attenuators:ng7att1 = {0.448656,0.4192,0.3925,0.3661,0.3458,0.3098,0.2922,0.2738,0.2544,0.251352} |
---|
| 1570 | root:myGlobals:Attenuators:ng7att2 = {0.217193,0.1898,0.1682,0.148,0.1321,0.1076,0.0957,0.08485,0.07479,0.0735965} |
---|
| 1571 | root:myGlobals:Attenuators:ng7att3 = {0.098019,0.07877,0.06611,0.05429,0.04548,0.03318,0.02798,0.0234,0.02004,0.0202492} |
---|
| 1572 | root:myGlobals:Attenuators:ng7att4 = {0.0426904,0.03302,0.02617,0.02026,0.0158,0.01052,0.008327,0.006665,0.005745,0.00524807} |
---|
| 1573 | root:myGlobals:Attenuators:ng7att5 = {0.0194353,0.01398,0.01037,0.0075496,0.005542,0.003339,0.002505,0.001936,0.001765,0.00165959} |
---|
| 1574 | root:myGlobals:Attenuators:ng7att6 = {0.00971666,0.005979,0.004136,0.002848,0.001946,0.001079,0.0007717,0.000588,0.000487337,0.000447713} |
---|
| 1575 | 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} |
---|
| 1576 | 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} |
---|
| 1577 | 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} |
---|
| 1578 | 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} |
---|
| 1579 | |
---|
[794] | 1580 | // percent errors as measured, May 2007 values |
---|
| 1581 | // zero error for zero attenuators, appropriate average values put in for unknown values |
---|
| 1582 | root:myGlobals:Attenuators:ng7att0_err = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
---|
| 1583 | 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} |
---|
| 1584 | 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} |
---|
| 1585 | 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} |
---|
| 1586 | 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} |
---|
| 1587 | 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} |
---|
| 1588 | root:myGlobals:Attenuators:ng7att6_err = {0.6,0.501,0.6136,0.528,0.8796,1.708,0.782,0.874,1,1} |
---|
| 1589 | root:myGlobals:Attenuators:ng7att7_err = {0.8,0.697,0.9149,0.583,1.173,2.427,1.242,2,2,2} |
---|
| 1590 | root:myGlobals:Attenuators:ng7att8_err = {1,0.898,1.24,0.696,1.577,3.412,3,3,3,3} |
---|
| 1591 | root:myGlobals:Attenuators:ng7att9_err = {1.5,1.113,1.599,1.154,2.324,4.721,5,5,5,5} |
---|
| 1592 | root:myGlobals:Attenuators:ng7att10_err = {1.5,1.493,5,5,5,5,5,5,5,5} |
---|
| 1593 | |
---|
| 1594 | |
---|
[118] | 1595 | // Pre-June 2007 calibration values - do not use these anymore |
---|
| 1596 | //// root:myGlobals:Attenuators:ng7att0 = {1, 1, 1, 1, 1, 1, 1, 1 ,1} |
---|
| 1597 | //// root:myGlobals:Attenuators:ng7att1 = {0.418, 0.393, 0.369, 0.347, 0.313, 0.291, 0.271, 0.244, 0.219 } |
---|
| 1598 | //// root:myGlobals:Attenuators:ng7att2 = {0.189, 0.167, 0.148, 0.132, 0.109, 0.0945, 0.0830, 0.0681, 0.0560} |
---|
| 1599 | //// root:myGlobals:Attenuators:ng7att3 = {0.0784, 0.0651, 0.0541, 0.0456, 0.0340, 0.0273, 0.0223, 0.0164 , 0.0121} |
---|
| 1600 | //// 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} |
---|
| 1601 | //// 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} |
---|
| 1602 | //// 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} |
---|
| 1603 | //// 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} |
---|
| 1604 | //// 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} |
---|
| 1605 | //// 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} |
---|
| 1606 | //// 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] | 1607 | End |
---|
| 1608 | |
---|
[886] | 1609 | |
---|
[911] | 1610 | // xxxx JAN 2013 -- Using John's measured values from 23 JAN 2013 |
---|
[886] | 1611 | // |
---|
[887] | 1612 | // |
---|
[911] | 1613 | // -- updated MAY 2013 -- |
---|
| 1614 | // K. Weigandt's calibration |
---|
| 1615 | // 12 discrete wavelengths |
---|
| 1616 | // 10 attenuators |
---|
| 1617 | // |
---|
[899] | 1618 | Proc MakeNGBAttenTable() |
---|
[886] | 1619 | |
---|
| 1620 | NewDataFolder/O root:myGlobals:Attenuators |
---|
| 1621 | |
---|
[911] | 1622 | Variable num=12 //12 needed for tables to cover 3A - 30A |
---|
[886] | 1623 | |
---|
[899] | 1624 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt0 |
---|
| 1625 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt1 |
---|
| 1626 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt2 |
---|
| 1627 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt3 |
---|
| 1628 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt4 |
---|
| 1629 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt5 |
---|
| 1630 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt6 |
---|
| 1631 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt7 |
---|
| 1632 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt8 |
---|
| 1633 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt9 |
---|
[911] | 1634 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt10 |
---|
[886] | 1635 | |
---|
| 1636 | // and a wave for the errors at each attenuation factor |
---|
[899] | 1637 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt0_err |
---|
| 1638 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt1_err |
---|
| 1639 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt2_err |
---|
| 1640 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt3_err |
---|
| 1641 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt4_err |
---|
| 1642 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt5_err |
---|
| 1643 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt6_err |
---|
| 1644 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt7_err |
---|
| 1645 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt8_err |
---|
| 1646 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt9_err |
---|
[911] | 1647 | Make/O/N=(num) root:myGlobals:Attenuators:NGBatt10_err |
---|
[886] | 1648 | |
---|
[1217] | 1649 | //NGB wave has 12 elements, the transmission of att# at the wavelengths |
---|
[889] | 1650 | //lambda = 3A to 30A |
---|
| 1651 | // note that some of the higher attenuations and ALL of the 30A data is interpolated |
---|
[886] | 1652 | // none of these values are expected to be used in reality since the flux would be too low in practice |
---|
[911] | 1653 | // Make/O/N=(num) root:myGlobals:Attenuators:NGBlambda={3,4,5,6,7,8,10,12,14,17,20,25,30} //this is for 13 wavelengths |
---|
| 1654 | Make/O/N=(num) root:myGlobals:Attenuators:NGBlambda={3,4,5,6,8,10,12,14,16,20,25,30} // 12 wavelengths, MAY 2013 |
---|
[886] | 1655 | |
---|
[911] | 1656 | |
---|
| 1657 | // new calibrations MAY 2013 |
---|
[1217] | 1658 | root:myGlobals:Attenuators:NGBatt0 = {1,1,1,1,1,1,1,1,1,1,1,1} |
---|
[911] | 1659 | root:myGlobals:Attenuators:NGBatt1 = {0.512,0.474,0.418,0.392,0.354,0.325,0.294,0.27,0.255,0.222,0.185,0.155} |
---|
| 1660 | root:myGlobals:Attenuators:NGBatt2 = {0.268,0.227,0.184,0.16,0.129,0.108,0.0904,0.0777,0.0689,0.0526,0.0372,0.0263} |
---|
| 1661 | root:myGlobals:Attenuators:NGBatt3 = {0.135,0.105,0.0769,0.0629,0.0455,0.0342,0.0266,0.0212,0.0178,0.0117,0.007,0.00429} |
---|
| 1662 | root:myGlobals:Attenuators:NGBatt4 = {0.0689,0.0483,0.0324,0.0249,0.016,0.0109,0.00782,0.00583,0.0046,0.00267,0.00135,0.000752} |
---|
| 1663 | root:myGlobals:Attenuators:NGBatt5 = {0.0348,0.0224,0.0136,0.00979,0.0056,0.00347,0.0023,0.0016,0.0012,0.000617,0.000282,0.000155} |
---|
| 1664 | root:myGlobals:Attenuators:NGBatt6 = {0.018,0.0105,0.00586,0.00398,0.00205,0.00115,0.000709,0.000467,0.000335,0.000157,7.08e-05,4e-05} |
---|
| 1665 | root:myGlobals:Attenuators:NGBatt7 = {0.00466,0.00226,0.00104,0.000632,0.00026,0.000123,6.8e-05,4.26e-05,3e-05,1.5e-05,8e-06,4e-06} |
---|
| 1666 | root:myGlobals:Attenuators:NGBatt8 = {0.00121,0.000488,0.000187,0.000101,3.52e-05,1.61e-05,9.79e-06,7.68e-06,4.4e-06,2e-06,1e-06,5e-07} |
---|
| 1667 | root:myGlobals:Attenuators:NGBatt9 = {0.000312,0.000108,3.53e-05,1.78e-05,6.6e-06,4.25e-06,2e-06,1.2e-06,9e-07,4e-07,1.6e-07,9e-08} |
---|
| 1668 | root:myGlobals:Attenuators:NGBatt10 = {8.5e-05,2.61e-05,8.24e-06,4.47e-06,2.53e-06,9e-07,5e-07,3e-07,2e-07,1e-07,4e-08,2e-08} |
---|
[886] | 1669 | |
---|
[911] | 1670 | // percent errors as measured, MAY 2013 values |
---|
[889] | 1671 | // zero error for zero attenuators, large values put in for unknown values (either 2% or 5%) |
---|
[1217] | 1672 | root:myGlobals:Attenuators:NGBatt0_err = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
---|
[911] | 1673 | root:myGlobals:Attenuators:NGBatt1_err = {0.174,0.256,0.21,0.219,0.323,0.613,0.28,0.135,0.195,0.216,0.214,19.8} |
---|
| 1674 | root:myGlobals:Attenuators:NGBatt2_err = {0.261,0.458,0.388,0.419,0.354,0.668,0.321,0.206,0.302,0.305,0.315,31.1} |
---|
| 1675 | root:myGlobals:Attenuators:NGBatt3_err = {0.319,0.576,0.416,0.448,0.431,0.688,0.37,0.247,0.368,0.375,0.41,50.6} |
---|
| 1676 | root:myGlobals:Attenuators:NGBatt4_err = {0.41,0.611,0.479,0.515,0.461,0.715,0.404,0.277,0.416,0.436,0.576,111} |
---|
| 1677 | root:myGlobals:Attenuators:NGBatt5_err = {0.549,0.684,0.503,0.542,0.497,0.735,0.428,0.3,0.456,0.538,1.08,274} |
---|
| 1678 | root:myGlobals:Attenuators:NGBatt6_err = {0.61,0.712,0.528,0.571,0.52,0.749,0.446,0.333,0.515,0.836,2.28,5} |
---|
| 1679 | root:myGlobals:Attenuators:NGBatt7_err = {0.693,0.76,0.556,0.607,0.554,0.774,0.516,0.56,0.924,5,5,5} |
---|
| 1680 | root:myGlobals:Attenuators:NGBatt8_err = {0.771,0.813,0.59,0.657,0.612,0.867,0.892,1.3,5,5,5,5} |
---|
| 1681 | root:myGlobals:Attenuators:NGBatt9_err = {0.837,0.867,0.632,0.722,0.751,1.21,5,5,5,5,5,5} |
---|
| 1682 | root:myGlobals:Attenuators:NGBatt10_err = {0.892,0.921,0.715,0.845,1.09,5,5,5,5,5,5,5} |
---|
| 1683 | |
---|
| 1684 | |
---|
[1217] | 1685 | //// (old) calibration, Jan 2013 John Barker |
---|
[911] | 1686 | // root:myGlobals:Attenuators:NGBatt0 = {1,1,1,1,1,1,1,1,1,1,1,1,1} |
---|
| 1687 | // root:myGlobals:Attenuators:NGBatt1 = {0.522,0.476,0.42007,0.39298,0.36996,0.35462,0.31637,0.29422,0.27617,0.24904,0.22263,0.18525,0.15} |
---|
| 1688 | // root:myGlobals:Attenuators:NGBatt2 = {0.27046,0.21783,0.17405,0.15566,0.13955,0.1272,0.10114,0.087289,0.077363,0.063607,0.051098,0.0357,0.023} |
---|
| 1689 | // root:myGlobals:Attenuators:NGBatt3 = {0.12601,0.090906,0.064869,0.054644,0.046916,0.041169,0.028926,0.023074,0.019276,0.014244,0.01021,0.006029,0.0033} |
---|
| 1690 | // root:myGlobals:Attenuators:NGBatt4 = {0.057782,0.037886,0.024727,0.019499,0.015719,0.013041,0.0080739,0.0059418,0.0046688,0.0031064,0.0020001,0.0010049,0.0005} |
---|
| 1691 | // root:myGlobals:Attenuators:NGBatt5 = {0.026627,0.016169,0.0096679,0.0071309,0.0052982,0.0040951,0.0021809,0.001479,0.001096,0.00066564,0.00039384,0.0002,9e-05} |
---|
| 1692 | // root:myGlobals:Attenuators:NGBatt6 = {0.0091671,0.0053041,0.0029358,0.0019376,0.0013125,0.00096946,0.00042126,0.0002713,0.00019566,0.00011443,5e-05,3e-05,1.2e-05} |
---|
| 1693 | // root:myGlobals:Attenuators:NGBatt7 = {0.0017971,0.00089679,0.00040572,0.0002255,0.00013669,8.7739e-05,3.3373e-05,2.0759e-05,1.5624e-05,1e-05,8e-06,4e-06,2.1e-06} |
---|
| 1694 | // root:myGlobals:Attenuators:NGBatt8 = {0.00033646,0.00012902,4.6033e-05,2.414e-05,1.4461e-05,9.4644e-06,4.8121e-06,4e-06,3e-06,2e-06,1e-06,7e-07,3.3e-07} |
---|
| 1695 | // root:myGlobals:Attenuators:NGBatt9 = {7e-05,2e-05,8.2796e-06,4.5619e-06,3.1543e-06,2.6216e-06,8e-07,6e-07,4e-07,3e-07,2e-07,1e-07,5e-08} |
---|
| 1696 | //// root:myGlobals:Attenuators:NGBatt10 = {} |
---|
| 1697 | // |
---|
| 1698 | // // percent errors as measured, Jan 2013 values |
---|
| 1699 | // // zero error for zero attenuators, large values put in for unknown values (either 2% or 5%) |
---|
| 1700 | // root:myGlobals:Attenuators:NGBatt0_err = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
---|
| 1701 | // root:myGlobals:Attenuators:NGBatt1_err = {0.12116,0.111059,0.150188,0.15168,0.174434,0.218745,0.0938678,0.144216,0.2145,0.141995,0.153655,0.157188,5} |
---|
| 1702 | // root:myGlobals:Attenuators:NGBatt2_err = {0.183583,0.19981,0.278392,0.286518,0.336599,0.240429,0.190996,0.178529,0.266807,0.23608,0.221334,0.245336,5} |
---|
| 1703 | // root:myGlobals:Attenuators:NGBatt3_err = {0.271054,0.326341,0.30164,0.31008,0.364188,0.296638,0.1914,0.22433,0.340313,0.307021,0.279339,0.319965,5} |
---|
| 1704 | // root:myGlobals:Attenuators:NGBatt4_err = {0.333888,0.361023,0.356208,0.368968,0.437084,0.322955,0.248284,0.260956,0.402069,0.368168,0.337252,0.454958,5} |
---|
| 1705 | // root:myGlobals:Attenuators:NGBatt5_err = {0.365745,0.433845,0.379735,0.394999,0.470603,0.357534,0.290938,0.291193,0.455465,0.426855,0.434639,2,5} |
---|
| 1706 | // root:myGlobals:Attenuators:NGBatt6_err = {0.402066,0.470239,0.410136,0.432342,0.523241,0.389247,0.333352,0.325301,0.517036,0.539386,2,2,5} |
---|
| 1707 | // root:myGlobals:Attenuators:NGBatt7_err = {0.542334,0.549954,0.45554,0.497426,0.624473,0.454971,0.432225,0.464043,0.752858,2,5,5,5} |
---|
| 1708 | // root:myGlobals:Attenuators:NGBatt8_err = {0.704775,0.673556,0.537178,0.62027,0.814375,0.582449,0.662811,2,2,5,5,5,5} |
---|
| 1709 | // root:myGlobals:Attenuators:NGBatt9_err = {2,2,0.583513,0.685477,0.901413,0.767115,2,5,5,5,5,5,5} |
---|
| 1710 | //// root:myGlobals:Attenuators:NGBatt10_err = {} |
---|
[886] | 1711 | |
---|
| 1712 | End |
---|
| 1713 | |
---|
[69] | 1714 | //returns the transmission of the attenuator (at NG3) given the attenuator number |
---|
| 1715 | //which must be an integer(to select the wave) and given the wavelength. |
---|
[121] | 1716 | //the wavelength may be any value between 4 and 20 (A), and is interpolated |
---|
[69] | 1717 | //between calibrated wavelengths for a given attenuator |
---|
[79] | 1718 | // |
---|
[644] | 1719 | // Mar 2010 - abs() added to attStr to account for ICE reporting -0.0001 as an attenuator position, which truncates to "-0" |
---|
[794] | 1720 | Function LookupAttenNG3(lambda,attenNo,atten_err) |
---|
| 1721 | Variable lambda, attenNo, &atten_err |
---|
[69] | 1722 | |
---|
| 1723 | Variable trans |
---|
[644] | 1724 | String attStr="root:myGlobals:Attenuators:ng3att"+num2str(trunc(abs(attenNo))) |
---|
[794] | 1725 | String attErrWStr="root:myGlobals:Attenuators:ng3att"+num2str(trunc(abs(attenNo)))+"_err" |
---|
[69] | 1726 | String lamStr = "root:myGlobals:Attenuators:ng3lambda" |
---|
| 1727 | |
---|
| 1728 | if(attenNo == 0) |
---|
| 1729 | return (1) //no attenuation, return trans == 1 |
---|
| 1730 | endif |
---|
| 1731 | |
---|
[1209] | 1732 | if( (lambda < 3) || (lambda > 20 ) ) |
---|
| 1733 | Abort "Wavelength out of calibration range (3,20). You must manually enter the absolute parameters" |
---|
[69] | 1734 | Endif |
---|
| 1735 | |
---|
[794] | 1736 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) || !(WaveExists($attErrWStr))) |
---|
[69] | 1737 | Execute "MakeNG3AttenTable()" |
---|
| 1738 | Endif |
---|
| 1739 | //just in case creating the tables fails.... |
---|
| 1740 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) ) |
---|
| 1741 | Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters" |
---|
| 1742 | Endif |
---|
| 1743 | |
---|
| 1744 | //lookup the value by interpolating the wavelength |
---|
| 1745 | //the attenuator must always be an integer |
---|
| 1746 | Wave att = $attStr |
---|
[794] | 1747 | Wave attErrW = $attErrWStr |
---|
[69] | 1748 | Wave lam = $lamstr |
---|
| 1749 | trans = interp(lambda,lam,att) |
---|
[794] | 1750 | atten_err = interp(lambda,lam,attErrW) |
---|
| 1751 | |
---|
| 1752 | // the error in the tables is % error. return the standard deviation instead |
---|
| 1753 | atten_err = trans*atten_err/100 |
---|
| 1754 | |
---|
[69] | 1755 | // Print "trans = ",trans |
---|
[794] | 1756 | // Print "trans err = ",atten_err |
---|
[69] | 1757 | |
---|
| 1758 | return trans |
---|
| 1759 | End |
---|
| 1760 | |
---|
| 1761 | //returns the transmission of the attenuator (at NG7) given the attenuator number |
---|
| 1762 | //which must be an integer(to select the wave) and given the wavelength. |
---|
[121] | 1763 | //the wavelength may be any value between 4 and 20 (A), and is interpolated |
---|
[69] | 1764 | //between calibrated wavelengths for a given attenuator |
---|
| 1765 | // |
---|
[121] | 1766 | // this set of tables is also used for NG5 (NG1) SANS instrument - as the attenuator has never been calibrated |
---|
[79] | 1767 | // |
---|
| 1768 | // local function |
---|
| 1769 | // |
---|
[644] | 1770 | // Mar 2010 - abs() added to attStr to account for ICE reporting -0.0001 as an attenuator position, which truncates to "-0" |
---|
[794] | 1771 | Function LookupAttenNG7(lambda,attenNo,atten_err) |
---|
| 1772 | Variable lambda, attenNo, &atten_err |
---|
[69] | 1773 | |
---|
| 1774 | Variable trans |
---|
[644] | 1775 | String attStr="root:myGlobals:Attenuators:ng7att"+num2str(trunc(abs(attenNo))) |
---|
[794] | 1776 | String attErrWStr="root:myGlobals:Attenuators:ng7att"+num2str(trunc(abs(attenNo)))+"_err" |
---|
[69] | 1777 | String lamStr = "root:myGlobals:Attenuators:ng7lambda" |
---|
| 1778 | |
---|
| 1779 | if(attenNo == 0) |
---|
| 1780 | return (1) //no attenuation, return trans == 1 |
---|
| 1781 | endif |
---|
| 1782 | |
---|
[121] | 1783 | if( (lambda < 4) || (lambda > 20 ) ) |
---|
| 1784 | Abort "Wavelength out of calibration range (4,20). You must manually enter the absolute parameters" |
---|
[69] | 1785 | Endif |
---|
| 1786 | |
---|
[794] | 1787 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) || !(WaveExists($attErrWStr))) |
---|
[69] | 1788 | Execute "MakeNG7AttenTable()" |
---|
| 1789 | Endif |
---|
| 1790 | //just in case creating the tables fails.... |
---|
| 1791 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) ) |
---|
| 1792 | Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters" |
---|
| 1793 | Endif |
---|
| 1794 | |
---|
| 1795 | //lookup the value by interpolating the wavelength |
---|
| 1796 | //the attenuator must always be an integer |
---|
| 1797 | Wave att = $attStr |
---|
[794] | 1798 | Wave attErrW = $attErrWStr |
---|
[69] | 1799 | Wave lam = $lamstr |
---|
| 1800 | trans = interp(lambda,lam,att) |
---|
[794] | 1801 | atten_err = interp(lambda,lam,attErrW) |
---|
| 1802 | |
---|
| 1803 | // the error in the tables is % error. return the standard deviation instead |
---|
| 1804 | atten_err = trans*atten_err/100 |
---|
[69] | 1805 | |
---|
[794] | 1806 | // Print "trans = ",trans |
---|
| 1807 | // Print "trans err = ",atten_err |
---|
[69] | 1808 | |
---|
| 1809 | return trans |
---|
| 1810 | |
---|
| 1811 | End |
---|
| 1812 | |
---|
[899] | 1813 | //returns the transmission of the attenuator (at NGB) given the attenuator number |
---|
[886] | 1814 | //which must be an integer(to select the wave) and given the wavelength. |
---|
[887] | 1815 | //the wavelength may be any value between 3 and 30 (A), and is interpolated |
---|
[886] | 1816 | //between calibrated wavelengths for a given attenuator |
---|
| 1817 | // |
---|
| 1818 | // local function |
---|
| 1819 | // |
---|
| 1820 | // Mar 2010 - abs() added to attStr to account for ICE reporting -0.0001 as an attenuator position, which truncates to "-0" |
---|
| 1821 | // |
---|
[899] | 1822 | // JAN 2013 -- now correct, NGB table has been added, allowing for 3A to 30A |
---|
[886] | 1823 | // |
---|
[899] | 1824 | Function LookupAttenNGB(lambda,attenNo,atten_err) |
---|
[886] | 1825 | Variable lambda, attenNo, &atten_err |
---|
| 1826 | |
---|
| 1827 | Variable trans |
---|
[899] | 1828 | String attStr="root:myGlobals:Attenuators:NGBatt"+num2str(trunc(abs(attenNo))) |
---|
| 1829 | String attErrWStr="root:myGlobals:Attenuators:NGBatt"+num2str(trunc(abs(attenNo)))+"_err" |
---|
| 1830 | String lamStr = "root:myGlobals:Attenuators:NGBlambda" |
---|
[886] | 1831 | |
---|
| 1832 | if(attenNo == 0) |
---|
| 1833 | return (1) //no attenuation, return trans == 1 |
---|
| 1834 | endif |
---|
| 1835 | |
---|
[887] | 1836 | if( (lambda < 3) || (lambda > 30 ) ) |
---|
| 1837 | Abort "Wavelength out of calibration range (3,30). You must manually enter the absolute parameters" |
---|
[886] | 1838 | Endif |
---|
| 1839 | |
---|
| 1840 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) || !(WaveExists($attErrWStr))) |
---|
[899] | 1841 | Execute "MakeNGBAttenTable()" |
---|
[886] | 1842 | Endif |
---|
| 1843 | //just in case creating the tables fails.... |
---|
| 1844 | if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) ) |
---|
| 1845 | Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters" |
---|
| 1846 | Endif |
---|
| 1847 | |
---|
| 1848 | //lookup the value by interpolating the wavelength |
---|
| 1849 | //the attenuator must always be an integer |
---|
| 1850 | Wave att = $attStr |
---|
| 1851 | Wave attErrW = $attErrWStr |
---|
| 1852 | Wave lam = $lamstr |
---|
| 1853 | trans = interp(lambda,lam,att) |
---|
| 1854 | atten_err = interp(lambda,lam,attErrW) |
---|
| 1855 | |
---|
| 1856 | // the error in the tables is % error. return the standard deviation instead |
---|
| 1857 | atten_err = trans*atten_err/100 |
---|
| 1858 | |
---|
| 1859 | // Print "trans = ",trans |
---|
| 1860 | // Print "trans err = ",atten_err |
---|
| 1861 | |
---|
| 1862 | return trans |
---|
| 1863 | |
---|
| 1864 | End |
---|
| 1865 | |
---|
[801] | 1866 | // a utility function so that I can get the values from the command line |
---|
| 1867 | // since the atten_err is PBR |
---|
| 1868 | // |
---|
| 1869 | Function PrintAttenuation(instr,lam,attenNo) |
---|
| 1870 | String instr |
---|
| 1871 | Variable lam,attenNo |
---|
| 1872 | |
---|
| 1873 | Variable atten_err, attenFactor |
---|
| 1874 | |
---|
[901] | 1875 | // 22 FEB 2013 - not sure what changed with the writeout of ICE data files... but .... |
---|
| 1876 | // to account for ICE occasionally writing out "3" as 2.9998, make sure I can construct |
---|
| 1877 | // a single digit -> string "3" to identify the proper wave in the lookup table |
---|
| 1878 | |
---|
| 1879 | attenNo = round(attenNo) |
---|
| 1880 | |
---|
[801] | 1881 | strswitch(instr) |
---|
[899] | 1882 | case "CGB": |
---|
[801] | 1883 | case "NG3": |
---|
| 1884 | attenFactor = LookupAttenNG3(lam,attenNo,atten_err) |
---|
| 1885 | break |
---|
| 1886 | case "NG5": |
---|
| 1887 | //using NG7 lookup Table |
---|
| 1888 | attenFactor = LookupAttenNG7(lam,attenNo,atten_err) |
---|
| 1889 | break |
---|
| 1890 | case "NG7": |
---|
| 1891 | attenFactor = LookupAttenNG7(lam,attenNo,atten_err) |
---|
| 1892 | break |
---|
[886] | 1893 | case "NGA": |
---|
[899] | 1894 | case "NGB": |
---|
| 1895 | attenFactor = LookupAttenNGB(lam,attenNo,atten_err) |
---|
[886] | 1896 | break |
---|
[801] | 1897 | default: |
---|
| 1898 | //return error? |
---|
[886] | 1899 | DoAlert 0, "No matching instrument -- PrintAttenuation" |
---|
[801] | 1900 | attenFactor=1 |
---|
| 1901 | endswitch |
---|
| 1902 | |
---|
| 1903 | Print "atten, err = ", attenFactor, atten_err |
---|
| 1904 | |
---|
| 1905 | return(0) |
---|
| 1906 | End |
---|
| 1907 | |
---|
| 1908 | |
---|
| 1909 | |
---|
[69] | 1910 | //returns the proper attenuation factor based on the instrument (NG3, NG5, or NG7) |
---|
| 1911 | //NG5 values are taken from the NG7 tables (there is very little difference in the |
---|
| 1912 | //values, and NG5 attenuators have not been calibrated (as of 8/01) |
---|
[79] | 1913 | // |
---|
[82] | 1914 | // filestr is passed from TextRead[3] = the default directory |
---|
| 1915 | // lam is passed from RealsRead[26] |
---|
| 1916 | // AttenNo is passed from ReaslRead[3] |
---|
| 1917 | // |
---|
[79] | 1918 | // Attenuation factor as defined here is <= 1 |
---|
[82] | 1919 | // |
---|
[886] | 1920 | // HFIR can pass ("",1,attenuationFactor) and have this function simply |
---|
[81] | 1921 | // spit back the attenuationFactor (that was read into rw[3]) |
---|
[79] | 1922 | // |
---|
| 1923 | // called by Correct.ipf, ProtocolAsPanel.ipf, Transmission.ipf |
---|
| 1924 | // |
---|
[794] | 1925 | // |
---|
| 1926 | // as of March 2011, returns the error (one standard deviation) in the attenuation factor as the last parameter, by reference |
---|
| 1927 | Function AttenuationFactor(fileStr,lam,attenNo,atten_err) |
---|
[69] | 1928 | String fileStr |
---|
[794] | 1929 | Variable lam,attenNo, &atten_err |
---|
[69] | 1930 | |
---|
| 1931 | Variable attenFactor=1,loc |
---|
| 1932 | String instr=fileStr[1,3] //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total) |
---|
[901] | 1933 | |
---|
| 1934 | |
---|
| 1935 | // 22 FEB 2013 - not sure what changed with the writeout of ICE data files... but .... |
---|
| 1936 | // to account for ICE occasionally writing out "3" as 2.9998, make sure I can construct |
---|
| 1937 | // a single digit -> string "3" to identify the proper wave in the lookup table |
---|
[69] | 1938 | |
---|
[1192] | 1939 | // CGB is the three character identifier for the NGB30 SANS instrument |
---|
| 1940 | // NGB is the 10m SANS instrument at NGB |
---|
| 1941 | // NGA does not exist |
---|
| 1942 | // NG5 hasn't existed for years |
---|
| 1943 | // NG3 is used when old NG3SANS data is processed (pre-instrument move) |
---|
| 1944 | |
---|
[901] | 1945 | attenNo = round(attenNo) |
---|
| 1946 | |
---|
| 1947 | |
---|
[69] | 1948 | strswitch(instr) |
---|
[899] | 1949 | case "CGB": |
---|
[69] | 1950 | case "NG3": |
---|
[794] | 1951 | attenFactor = LookupAttenNG3(lam,attenNo,atten_err) |
---|
[69] | 1952 | break |
---|
| 1953 | case "NG5": |
---|
| 1954 | //using NG7 lookup Table |
---|
[794] | 1955 | attenFactor = LookupAttenNG7(lam,attenNo,atten_err) |
---|
[69] | 1956 | break |
---|
| 1957 | case "NG7": |
---|
[794] | 1958 | attenFactor = LookupAttenNG7(lam,attenNo,atten_err) |
---|
[69] | 1959 | break |
---|
[886] | 1960 | case "NGA": |
---|
[899] | 1961 | case "NGB": |
---|
| 1962 | attenFactor = LookupAttenNGB(lam,attenNo,atten_err) |
---|
[886] | 1963 | break |
---|
[69] | 1964 | default: |
---|
| 1965 | //return error? |
---|
[886] | 1966 | DoAlert 0, "No matching instrument -- PrintAttenuation" |
---|
[69] | 1967 | attenFactor=1 |
---|
| 1968 | endswitch |
---|
| 1969 | // print "instr, lambda, attenNo,attenFactor = ",instr,lam,attenNo,attenFactor |
---|
| 1970 | return(attenFactor) |
---|
| 1971 | End |
---|
| 1972 | |
---|
[79] | 1973 | //function called by the popups to get a file list of data that can be sorted |
---|
[70] | 1974 | // this procedure simply removes the raw data files from the string - there |
---|
| 1975 | //can be lots of other junk present, but this is very fast... |
---|
| 1976 | // |
---|
| 1977 | // could also use the alternate procedure of keeping only file with the proper extension |
---|
| 1978 | // |
---|
| 1979 | // another possibility is to get a listing of the text files, but is unreliable on |
---|
| 1980 | // Windows, where the data file must be .txt (and possibly OSX) |
---|
| 1981 | // |
---|
[79] | 1982 | // called by FIT_Ops.ipf, NSORT.ipf, PlotUtils.ipf |
---|
| 1983 | // |
---|
[70] | 1984 | Function/S ReducedDataFileList(ctrlName) |
---|
| 1985 | String ctrlName |
---|
| 1986 | |
---|
| 1987 | String list="",newList="",item="" |
---|
| 1988 | Variable num,ii |
---|
| 1989 | |
---|
| 1990 | //check for the path |
---|
| 1991 | PathInfo catPathName |
---|
| 1992 | if(V_Flag==0) |
---|
| 1993 | DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel" |
---|
| 1994 | Return("") |
---|
| 1995 | Endif |
---|
| 1996 | |
---|
| 1997 | list = IndexedFile(catpathName,-1,"????") |
---|
[670] | 1998 | |
---|
| 1999 | list = RemoveFromList(ListMatch(list,"*.SA1*",";"), list, ";", 0) |
---|
| 2000 | list = RemoveFromList(ListMatch(list,"*.SA2*",";"), list, ";", 0) |
---|
| 2001 | list = RemoveFromList(ListMatch(list,"*.SA3*",";"), list, ";", 0) |
---|
[888] | 2002 | list = RemoveFromList(ListMatch(list,"*.SA4*",";"), list, ";", 0) // added JAN 2013 for new guide hall |
---|
| 2003 | list = RemoveFromList(ListMatch(list,"*.SA5*",";"), list, ";", 0) |
---|
[670] | 2004 | list = RemoveFromList(ListMatch(list,".*",";"), list, ";", 0) |
---|
| 2005 | list = RemoveFromList(ListMatch(list,"*.pxp",";"), list, ";", 0) |
---|
| 2006 | list = RemoveFromList(ListMatch(list,"*.DIV",";"), list, ";", 0) |
---|
| 2007 | list = RemoveFromList(ListMatch(list,"*.GSP",";"), list, ";", 0) |
---|
| 2008 | list = RemoveFromList(ListMatch(list,"*.MASK",";"), list, ";", 0) |
---|
| 2009 | |
---|
[70] | 2010 | //remove VAX version numbers |
---|
[670] | 2011 | list = RemoveVersNumsFromList(List) |
---|
[70] | 2012 | //sort |
---|
[670] | 2013 | newList = SortList(List,";",0) |
---|
[70] | 2014 | |
---|
| 2015 | return newlist |
---|
[76] | 2016 | End |
---|
| 2017 | |
---|
| 2018 | // returns a list of raw data files in the catPathName directory on disk |
---|
| 2019 | // - list is SEMICOLON-delimited |
---|
| 2020 | // |
---|
| 2021 | // does it the "cheap" way, simply finding the ".SAn" in the file name |
---|
| 2022 | // = does not check for proper byte length. |
---|
[79] | 2023 | // |
---|
| 2024 | // called by PatchFiles.ipf, Tile_2D.ipf |
---|
| 2025 | // |
---|
[76] | 2026 | Function/S GetRawDataFileList() |
---|
| 2027 | |
---|
| 2028 | //make sure that path exists |
---|
| 2029 | PathInfo catPathName |
---|
| 2030 | if (V_flag == 0) |
---|
| 2031 | Abort "Folder path does not exist - use Pick Path button on Main Panel" |
---|
| 2032 | Endif |
---|
| 2033 | |
---|
| 2034 | String list=IndexedFile(catPathName,-1,"????") |
---|
| 2035 | String newList="",item="" |
---|
| 2036 | Variable num=ItemsInList(list,";"),ii |
---|
| 2037 | for(ii=0;ii<num;ii+=1) |
---|
| 2038 | item = StringFromList(ii, list ,";") |
---|
| 2039 | if( stringmatch(item,"*.sa1*") ) |
---|
| 2040 | newlist += item + ";" |
---|
| 2041 | endif |
---|
| 2042 | if( stringmatch(item,"*.sa2*") ) |
---|
| 2043 | newlist += item + ";" |
---|
| 2044 | endif |
---|
| 2045 | if( stringmatch(item,"*.sa3*") ) |
---|
| 2046 | newlist += item + ";" |
---|
| 2047 | endif |
---|
[888] | 2048 | if( stringmatch(item,"*.sa4*") ) // added JAN 2013 for new guide hall |
---|
| 2049 | newlist += item + ";" |
---|
| 2050 | endif |
---|
| 2051 | if( stringmatch(item,"*.sa5*") ) |
---|
| 2052 | newlist += item + ";" |
---|
| 2053 | endif |
---|
[76] | 2054 | //print "ii=",ii |
---|
| 2055 | endfor |
---|
| 2056 | newList = SortList(newList,";",0) |
---|
| 2057 | return(newList) |
---|
[680] | 2058 | End |
---|
| 2059 | |
---|
[945] | 2060 | Function/S GetASCDataFileList() |
---|
| 2061 | |
---|
| 2062 | //make sure that path exists |
---|
| 2063 | PathInfo catPathName |
---|
| 2064 | if (V_flag == 0) |
---|
| 2065 | Abort "Folder path does not exist - use Pick Path button on Main Panel" |
---|
| 2066 | Endif |
---|
| 2067 | |
---|
| 2068 | String list=IndexedFile(catPathName,-1,"????") |
---|
| 2069 | String newList="",item="" |
---|
| 2070 | Variable num=ItemsInList(list,";"),ii |
---|
| 2071 | for(ii=0;ii<num;ii+=1) |
---|
| 2072 | item = StringFromList(ii, list ,";") |
---|
| 2073 | if(stringmatch(item,"*.ASC") ) |
---|
| 2074 | newlist += item + ";" |
---|
| 2075 | endif |
---|
| 2076 | endfor |
---|
| 2077 | |
---|
| 2078 | newList = SortList(newList,";",0) |
---|
| 2079 | return(newList) |
---|
| 2080 | End |
---|
| 2081 | |
---|
| 2082 | |
---|
| 2083 | |
---|
[680] | 2084 | // Return the filename that represents the previous or next file. |
---|
| 2085 | // Input is current filename and increment. |
---|
| 2086 | // Increment should be -1 or 1 |
---|
| 2087 | // -1 => previous file |
---|
| 2088 | // 1 => next file |
---|
| 2089 | Function/S GetPrevNextRawFile(curfilename, prevnext) |
---|
| 2090 | String curfilename |
---|
| 2091 | Variable prevnext |
---|
| 2092 | |
---|
| 2093 | String filename |
---|
| 2094 | |
---|
| 2095 | //get the run number |
---|
| 2096 | Variable num = GetRunNumFromFile(curfilename) |
---|
| 2097 | |
---|
| 2098 | //find the next specified file by number |
---|
| 2099 | fileName = FindFileFromRunNumber(num+prevnext) |
---|
| 2100 | |
---|
| 2101 | if(cmpstr(fileName,"")==0) |
---|
| 2102 | //null return, do nothing |
---|
| 2103 | fileName = FindFileFromRunNumber(num) |
---|
| 2104 | Endif |
---|
| 2105 | |
---|
[683] | 2106 | // print "in FU "+filename |
---|
[680] | 2107 | |
---|
| 2108 | Return filename |
---|
[708] | 2109 | End |
---|
| 2110 | |
---|
| 2111 | |
---|