source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/NCNR_Utils.ipf @ 800

Last change on this file since 800 was 800, checked in by srkline, 11 years ago

Changed the 2D resolution calculation to include gravity. This seems to work, but will still require some testing. It requires no modifications to the smearing calculation, still using parallel and perpendicular directions.

Added a Fake Update feature to the RealTime? update. There are specific, separate instructions for how to set this up. Usef (possibly) for summer schools or demos.

Adjusted the 2D MonteCarlo? simulation to a corrected beam center. The Gauss Peak was not symmetric around the old beam center.

Corrected the AAO resolution smearing functions to work with cursors.

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