source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/NCNR_Utils_HDF5.ipf @ 946

Last change on this file since 946 was 946, checked in by srkline, 9 years ago

Adding procedures that will allow read/write of raw data in HDF5 format. No Nexus file definition has been settled upon yet, so I made up my own for testing, simply converting what was present in the VAX file header. Simple read/write operations are functional, but no full scale testing.

Transmission calculation is partially broken as there are no file suffixes anymore.

Otherwise, a good starting point for the HDF5/Nexus of the future.

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