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

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

switched the 2d resolution calculation back to using the latest gravity correction terms. Still not sure if these are final, but I think it's close.

File size: 55.9 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/(2*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// dd-mon-yyyy hh:mm:ss -> seconds
527// the VAX uses 24 hr time for hh
528//
529Function ConvertVAXDateTime2secs(dateAndTime)
530        string dateAndTime
531       
532        Variable day,yr,mon,hh,mm,ss,time_secs
533        string str,monStr
534       
535        str=dateandtime
536        sscanf str,"%d-%3s-%4d %d:%d:%d",day,monStr,yr,hh,mm,ss
537        mon = monStr2num(monStr)
538//      print yr,mon,day,hh,mm,ss
539        time_secs = date2secs(yr,mon,day)
540        time_secs += hh*3600 + mm*60 + ss
541
542
543        return(time_secs)
544end
545
546// takes a month string and returns the corresponding number
547//
548Function monStr2num(monStr)
549        String monStr
550       
551        String list=";JAN;FEB;MAR;APR;MAY;JUN;JUL;AUG;SEP;OCT;NOV;DEC;"
552        return(WhichListItem(monStr, list ,";"))
553end
554
555
556//make a three character string of the run number
557//Moved to facility utils
558Function/S RunDigitString(num)
559        Variable num
560       
561        String numStr=""
562        if(num<10)
563                numStr = "00"+num2str(num)
564        else
565                if(num<100)
566                        numStr = "0"+num2str(num)
567                else
568                        numStr = num2str(num)
569                Endif
570        Endif
571        //Print "numstr = ",numstr
572        return(numstr)
573End
574
575//given a filename of a SANS data filename of the form
576//TTTTTnnn.SAn_TTT_Txxx
577//returns the prefix "TTTTT" as some number of characters
578//returns "" as an invalid file prefix
579//
580// NCNR-specifc, does not really belong here - but it's a beta procedure used for the
581// Combine Files Panel
582//
583Function/S GetPrefixStrFromFile(item)
584        String item
585        String invalid = ""     //"" is not a valid run prefix, since it's text
586        Variable num=-1
587       
588        //find the "dot"
589        String runStr=""
590        Variable pos = strsearch(item,".",0)
591        if(pos == -1)
592                //"dot" not found
593                return (invalid)
594        else
595                //found, skip the three characters preceeding it
596                if (pos <=3)
597                        //not enough characters
598                        return (invalid)
599                else
600                        runStr = item[0,pos-4]
601                        return (runStr)
602                Endif
603        Endif
604End
605
606
607
608
609/////VAX filename/Run number parsing utilities
610//
611// a collection of uilities for processing vax filenames
612//and processing lists (especially for display in popup menus)
613//
614//required to correctly account for VAX supplied version numbers, which
615//may or may not be removed by the ftp utility
616//
617// - parses lists of run numbers into real filenames
618// - selects proper detector constants
619//
620//**************************
621//
622//given a filename of a SANS data filename of the form
623//TTTTTnnn.SAn_TTT_Txxx
624//returns the run number "nnn" as a number
625//returns -1 as an invalid file number
626//
627// called by several ipfs
628//
629//
630Function GetRunNumFromFile(item)
631        String item
632        Variable invalid = -1   //negative numbers are invalid
633        Variable num=-1
634       
635        //find the "dot"
636        String runStr=""
637        Variable pos = strsearch(item,".",0)
638        if(pos == -1)
639                //"dot" not found
640                return (invalid)
641        else
642                //found, get the three characters preceeding it
643                if (pos <=2)
644                        //not enough characters
645                        return (invalid)
646                else
647                        runStr = item[pos-3,pos-1]
648                        //convert to a number
649                        num = str2num(runStr)
650                        //if valid, return it
651                        if (num == NaN)
652                                //3 characters were not a number
653                                return (invalid)
654                        else
655                                //run was OK
656                                return (num)
657                        Endif
658                Endif
659        Endif
660End
661
662//given a filename of a SANS data filename of the form
663//TTTTTnnn.SAn_TTT_Txxx
664//returns the run number "nnn" as a STRING of THREE characters
665//returns "ABC" as an invalid file number
666//
667// local function to aid in locating files by run number
668//
669Function/S GetRunNumStrFromFile(item)
670        String item
671        String invalid = "ABC"  //"ABC" is not a valid run number, since it's text
672        Variable num=-1
673       
674        //find the "dot"
675        String runStr=""
676        Variable pos = strsearch(item,".",0)
677        if(pos == -1)
678                //"dot" not found
679                return (invalid)
680        else
681                //found, get the three characters preceeding it
682                if (pos <=2)
683                        //not enough characters
684                        return (invalid)
685                else
686                        runStr = item[pos-3,pos-1]
687                        return (runStr)
688                Endif
689        Endif
690End
691
692//returns a string containing the full path to the file containing the
693//run number "num". The null string is returned if no valid file can be found
694//the path "catPathName" used and is hard-wired, will abort if this path does not exist
695//the file returned will be a RAW SANS data file, other types of files are
696//filtered out.
697//
698// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
699//
700Function/S FindFileFromRunNumber(num)
701        Variable num
702       
703        String fullName="",partialName="",item=""
704        //get list of raw data files in folder that match "num" (add leading zeros)
705        if( (num>999) || (num<=0) )
706                //Print "error in  FindFileFromRunNumber(num), file number too large or too small"
707                Return ("")
708        Endif
709        //make a three character string of the run number
710        String numStr=""
711        if(num<10)
712                numStr = "00"+num2str(num)
713        else
714                if(num<100)
715                        numStr = "0"+num2str(num)
716                else
717                        numStr = num2str(num)
718                Endif
719        Endif
720        //Print "numstr = ",numstr
721       
722        //make sure that path exists
723        PathInfo catPathName
724        String path = S_path
725        if (V_flag == 0)
726                Abort "folder path does not exist - use Pick Path button"
727        Endif
728        String list="",newList="",testStr=""
729       
730        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
731        //find (the) one with the number in the run # location in the name
732        Variable numItems,ii,runFound,isRAW
733        numItems = ItemsInList(list,";")                //get the new number of items in the list
734        ii=0
735        do
736                //parse through the list in this order:
737                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
738                // 2 - exclude by isRaw? (to minimize disk access)
739                item = StringFromList(ii, list  ,";" )
740                if(strlen(item) != 0)
741                        //find the run number, if it exists as a three character string
742                        testStr = GetRunNumStrFromFile(item)
743                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
744                        if(runFound == 0)
745                                //the run Number was found
746                                //build valid filename
747                                partialName = FindValidFileName(item)
748                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
749                                        fullName = path + partialName
750                                        //check if RAW, if so,this must be the file!
751                                        isRAW = CheckIfRawData(fullName)
752                                        if(isRaw)
753                                                //stop here
754                                                return(fullname)
755                                        Endif
756                                Endif
757                        Endif
758                Endif
759                ii+=1
760        while(ii<numItems)              //process all items in list
761        Return ("")     //null return if file not found in list
762End
763
764//function to test a binary file to see if it is a RAW binary SANS file
765//first checks the total bytes in the file (which for raw data is 33316 bytes)
766//**note that the "DIV" file will also show up as a raw file by the run field
767//should be listed in CAT/SHORT and in patch windows
768//
769//Function then checks the file fname (full path:file) for "RAW" run.type field
770//if not found, the data is not raw data and zero is returned
771//
772// called by many procedures (both external and local)
773//
774Function CheckIfRawData(fname)
775        String fname
776       
777        Variable refnum,totalBytes
778        String testStr=""
779       
780        Open/R/T="????TEXT" refNum as fname
781        if(strlen(s_filename) == 0)     //user cancel (/Z not used, so V_flag not set)
782                return(0)
783        endif
784       
785        //get the total number of bytes in the file
786        FStatus refNum
787        totalBytes = V_logEOF
788        //Print totalBytes
789        if(totalBytes < 100)
790                Close refNum
791                return(0)               //not a raw file
792        endif
793        FSetPos refNum,75
794        FReadLine/N=3 refNum,testStr
795        Close refNum
796       
797        if(totalBytes == 33316 && ( cmpstr(testStr,"RAW")==0 ||  cmpstr(testStr,"SIM")==0))
798                //true, is raw data file
799                Return(1)
800        else
801                //some other file
802                Return(0)
803        Endif
804End
805
806//function to check the header of a raw data file (full path specified by fname)
807//checks the field of the x-position of the beamstop during data collection
808//if the x-position is more negative (farther to the left) than xTol(input)
809//the the beamstop is "out" and the file is a transmission run and not a scattering run
810//xtol typically set at -5 (cm) - trans runs have bs(x) at -10 to -15 cm
811// function returns 1 if beamstop is out, 0 if beamstop is in
812//
813// tolerance is set as a global value "root:myGlobals:BeamstopXTol"
814//
815// called by Transmission.ipf, CatVSTable.ipf, NSORT.ipf
816//
817Function isTransFile(fName)
818        String fname
819       
820        Variable refnum,xpos
821        NVAR xTol = root:myGlobals:BeamstopXTol
822       
823        //pos = 369, read one real value
824       
825        SetDataFolder root:
826        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
827        String strToExecute=""
828        // 1 R*4 value
829        strToExecute = GBLoadStr + "/S=368/U=1" + "\"" + fname + "\""
830        Execute strToExecute
831        Wave w=$"root:tempGBWave0"
832        xPos = w[0]
833        KillWaves/Z w
834        //Print "xPos = ",xpos
835       
836        if(xpos<=xTol)
837                //xpos is farther left (more negative) than xtol (currently -5 cm)
838                Return(1)
839        else
840                //some other file
841                Return(0)
842        Endif
843End
844
845
846//function to remove all spaces from names when searching for filenames
847//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
848//but the text field in the header WILL, if less than 3 characters were used for the
849//user's initials, and can have leading spaces if prefix was less than 5 characters
850//
851//returns a string identical to the original string, except with the interior spaces removed
852//
853// local function for file name manipulation
854//
855Function/S RemoveAllSpaces(str)
856        String str
857       
858        String tempstr = str
859        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
860        ii=0
861        do
862                len = strlen(tempStr)
863                spc = strsearch(tempStr," ",0)          //is the last character a space?
864                if (spc == -1)
865                        break           //no more spaces found, get out
866                endif
867                str = tempstr
868                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
869        While(1)        //should never be more than 2 or 3
870       
871        If(strlen(tempStr) < 1)
872                tempStr = ""            //be sure to return a null string if problem found
873        Endif
874       
875        //Print strlen(tempstr)
876       
877        Return(tempStr)
878               
879End
880
881
882//Function attempts to find valid filename from partial name by checking for
883// the existence of the file on disk.
884// - checks as is
885// - adds ";vers" for possible VAX files
886// - strips spaces
887// - permutations of upper/lowercase
888//
889// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
890// since from marquee, the filename field (textread[0]) must be used, and can be a mix of
891// upper/lowercase letters, while the filename on the server (should) be all caps
892// now makes repeated calls to ValidFileString()
893//
894// returns a valid filename (No path prepended) or a null string
895//
896// called by any functions, both external and local
897//
898Function/S FindValidFilename(partialName)
899        String PartialName
900       
901        String retStr=""
902       
903        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
904        retStr = ValidFileString(partialName)
905        if(cmpstr(retStr,"") !=0)
906                //non-null return
907                return(retStr)
908        Endif
909       
910        //if the partial name is derived from the file header, there can be spaces at the beginning
911        //or in the middle of the filename - depending on the prefix and initials used
912        //
913        //remove any leading spaces from the name before starting
914        partialName = RemoveAllSpaces(partialName)
915       
916        //try name with no spaces
917        retStr = ValidFileString(partialName)
918        if(cmpstr(retStr,"") !=0)
919                //non-null return
920                return(retStr)
921        Endif
922       
923        //try all UPPERCASE
924        partialName = UpperStr(partialName)
925        retStr = ValidFileString(partialName)
926        if(cmpstr(retStr,"") !=0)
927                //non-null return
928                return(retStr)
929        Endif
930       
931        //try all lowercase (ret null if failure)
932        partialName = LowerStr(partialName)
933        retStr = ValidFileString(partialName)
934        if(cmpstr(retStr,"") !=0)
935                //non-null return
936                return(retStr)
937        else
938                return(retStr)
939        Endif
940End
941
942// Function checks for the existence of a file
943// partialName;vers (to account for VAX filenaming conventions)
944// The partial name is tried first with no version number
945//
946// *** the PATH is hard-wired to catPathName (which is assumed to exist)
947// version numers up to ;10 are tried
948// only the "name;vers" is returned if successful. The path is not prepended
949//
950// local function
951//
952Function/S ValidFileString(partialName)
953        String partialName
954       
955        String tempName = "",msg=""
956        Variable ii,refnum
957       
958        ii=0
959        do
960                if(ii==0)
961                        //first pass, try the partialName
962                        tempName = partialName
963                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
964                        if(V_flag == 0)
965                                //file exists
966                                Close refnum            //YES needed,
967                                break
968                        endif
969                else
970                        tempName = partialName + ";" + num2str(ii)
971                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
972                        if(V_flag == 0)
973                                //file exists
974                                Close refnum
975                                break
976                        endif
977                Endif
978                ii+=1
979                //print "ii=",ii
980        while(ii<11)
981        //go get the selected bits of information, using tempName, which exists
982        if(ii>=11)
983                //msg = partialName + " not found. is version number > 11?"
984                //DoAlert 0, msg
985                //PathInfo catPathName
986                //Print S_Path
987                Return ("")             //use null string as error condition
988        Endif
989       
990        Return (tempName)
991End
992
993//returns a string containing filename (WITHOUT the ;vers)
994//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
995//with the folders separated by colons
996//
997// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
998//
999Function/S GetFileNameFromPathNoSemi(fullPath)
1000        String fullPath
1001       
1002        Variable offset1,offset2
1003        String filename=""
1004        //String PartialPath
1005        offset1 = 0
1006        do
1007                offset2 = StrSearch(fullPath, ":", offset1)
1008                if (offset2 == -1)                              // no more colons ?
1009                        fileName = FullPath[offset1,strlen(FullPath) ]
1010                        //PartialPath = FullPath[0, offset1-1]
1011                        break
1012                endif
1013                offset1 = offset2+1
1014        while (1)
1015       
1016        //remove version number from name, if it's there - format should be: filename;N
1017        filename =  StringFromList(0,filename,";")              //returns null if error
1018       
1019        Return filename
1020End
1021
1022//returns a string containing filename (INCLUDING the ;vers)
1023//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
1024//with the folders separated by colons
1025//
1026// local, currently unused
1027//
1028Function/S GetFileNameFromPathKeepSemi(fullPath)
1029        String fullPath
1030       
1031        Variable offset1,offset2
1032        String filename
1033        //String PartialPath
1034        offset1 = 0
1035        do
1036                offset2 = StrSearch(fullPath, ":", offset1)
1037                if (offset2 == -1)                              // no more colons ?
1038                        fileName = FullPath[offset1,strlen(FullPath) ]
1039                        //PartialPath = FullPath[0, offset1-1]
1040                        break
1041                endif
1042                offset1 = offset2+1
1043        while (1)
1044       
1045        //keep version number from name, if it's there - format should be: filename;N
1046       
1047        Return filename
1048End
1049
1050//given the full path and filename (fullPath), strips the data path
1051//(Mac-style, separated by colons) and returns this path
1052//this partial path is the same string that would be returned from PathInfo, for example
1053//
1054// - allows the user to save to a different path than catPathName
1055//
1056// called by WriteQIS.ipf
1057//
1058Function/S GetPathStrFromfullName(fullPath)
1059        String fullPath
1060       
1061        Variable offset1,offset2
1062        //String filename
1063        String PartialPath
1064        offset1 = 0
1065        do
1066                offset2 = StrSearch(fullPath, ":", offset1)
1067                if (offset2 == -1)                              // no more colons ?
1068                        //fileName = FullPath[offset1,strlen(FullPath) ]
1069                        PartialPath = FullPath[0, offset1-1]
1070                        break
1071                endif
1072                offset1 = offset2+1
1073        while (1)
1074       
1075        Return PartialPath
1076End
1077
1078//given the VAX filename, pull off the first 8 characters to make a valid
1079//file string that can be used for naming averaged 1-d files
1080//
1081// called by ProtocolAsPanel.ipf and Tile_2D.ipf
1082//
1083Function/S GetNameFromHeader(fullName)
1084        String fullName
1085        String temp, newName = ""
1086        Variable spc,ii=0
1087       
1088        //filename is 20 characters NNNNNxxx.SAn_NNN_NNN
1089        //want the first 8 characters, NNNNNxxx, then strip off any spaces at the beginning
1090        //NNNNN was entered as less than 5 characters
1091        //returns a null string if no name can be found
1092        do
1093                temp = fullname[ii,7]           //characters ii,7 of the name
1094                spc = strsearch(temp," ",0)
1095                if (spc == -1)
1096                        break           //no more spaces found
1097                endif
1098                ii+=1
1099        While(ii<8)
1100       
1101        If(strlen(temp) < 1)
1102                newName = ""            //be sure to return a null string if problem found
1103        else
1104                newName = temp
1105        Endif
1106       
1107        Return(newName)
1108End
1109
1110//list (input) is a list, typically returned from IndexedFile()
1111//which is semicolon-delimited, and may contain filenames from the VAX
1112//that contain version numbers, where the version number appears as a separate list item
1113//(and also as a non-existent file)
1114//these numbers must be purged from the list, especially for display in a popup
1115//or list processing of filenames
1116//the function returns the list, cleaned of version numbers (up to 11)
1117//raw data files will typically never have a version number other than 1.
1118//
1119// if there are no version numbers in the list, the input list is returned
1120//
1121// called by CatVSTable.ipf, NSORT.ipf, Transmission.ipf, WorkFileUtils.ipf
1122//
1123Function/S RemoveVersNumsFromList(list)
1124        String list
1125       
1126        //get rid of version numbers first (up to 11)
1127        Variable ii,num
1128        String item
1129        num = ItemsInList(list,";")
1130        ii=1
1131        do
1132                item = num2str(ii)
1133                list = RemoveFromList(item, list ,";" )
1134                ii+=1
1135        while(ii<12)
1136       
1137        return (list)
1138End
1139
1140//input is a list of run numbers, and output is a list of filenames (not the full path)
1141//*** input list must be COMMA delimited***
1142//output is equivalent to selecting from the CAT table
1143//if some or all of the list items are valid filenames, keep them...
1144//if an error is encountered, notify of the offending element and return a null list
1145//
1146//output is COMMA delimited
1147//
1148// this routine is expecting that the "ask", "none" special cases are handled elsewhere
1149//and not passed here
1150//
1151// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
1152//
1153Function/S ParseRunNumberList(list)
1154        String list
1155       
1156        String newList="",item="",tempStr=""
1157        Variable num,ii,runNum
1158       
1159        //expand number ranges, if any
1160        list = ExpandNumRanges(list)
1161       
1162        num=itemsinlist(list,",")
1163       
1164        for(ii=0;ii<num;ii+=1)
1165                //get the item
1166                item = StringFromList(ii,list,",")
1167                //is it already a valid filename?
1168                tempStr=FindValidFilename(item) //returns filename if good, null if error
1169                if(strlen(tempstr)!=0)
1170                        //valid name, add to list
1171                        //Print "it's a file"
1172                        newList += tempStr + ","
1173                else
1174                        //not a valid name
1175                        //is it a number?
1176                        runNum=str2num(item)
1177                        //print runnum
1178                        if(numtype(runNum) != 0)
1179                                //not a number -  maybe an error                       
1180                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
1181                                return("")
1182                        else
1183                                //a run number or an error
1184                                tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) )
1185                                if(strlen(tempstr)==0)
1186                                        //file not found, error
1187                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
1188                                        return("")
1189                                else
1190                                        newList += tempStr + ","
1191                                endif
1192                        endif
1193                endif
1194        endfor          //loop over all items in list
1195       
1196        return(newList)
1197End
1198
1199//takes a comma delimited list that MAY contain number range, and
1200//expands any range of run numbers into a comma-delimited list...
1201//and returns the new list - if not a range, return unchanged
1202//
1203// local function
1204//
1205Function/S ExpandNumRanges(list)
1206        String list
1207       
1208        String newList="",dash="-",item,str
1209        Variable num,ii,hasDash
1210       
1211        num=itemsinlist(list,",")
1212//      print num
1213        for(ii=0;ii<num;ii+=1)
1214                //get the item
1215                item = StringFromList(ii,list,",")
1216                //does it contain a dash?
1217                hasDash = strsearch(item,dash,0)                //-1 if no dash found
1218                if(hasDash == -1)
1219                        //not a range, keep it in the list
1220                        newList += item + ","
1221                else
1222                        //has a dash (so it's a range), expand (or add null)
1223                        newList += ListFromDash(item)           
1224                endif
1225        endfor
1226       
1227        return newList
1228End
1229
1230//be sure to add a trailing comma to the return string...
1231//
1232// local function
1233//
1234Function/S ListFromDash(item)
1235        String item
1236       
1237        String numList="",loStr="",hiStr=""
1238        Variable lo,hi,ii
1239       
1240        loStr=StringFromList(0,item,"-")        //treat the range as a list
1241        hiStr=StringFromList(1,item,"-")
1242        lo=str2num(loStr)
1243        hi=str2num(hiStr)
1244        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
1245                numList=""
1246                return numList
1247        endif
1248        for(ii=lo;ii<=hi;ii+=1)
1249                numList += num2str(ii) + ","
1250        endfor
1251       
1252        Return numList
1253End
1254
1255
1256////////Transmission
1257//******************
1258//lookup tables for attenuator transmissions
1259//NG3 and NG7 attenuators are physically different, so the transmissions are slightly different
1260//NG1 - (8m SANS) is not supported
1261//
1262// new calibration done June 2007, John Barker
1263//
1264Proc MakeNG3AttenTable()
1265
1266        NewDataFolder/O root:myGlobals:Attenuators
1267        //do explicitly to avoid data folder problems, redundant, but it must work without fail
1268        Variable num=10         //10 needed for tables after June 2007
1269
1270        Make/O/N=(num) root:myGlobals:Attenuators:ng3att0
1271        Make/O/N=(num) root:myGlobals:Attenuators:ng3att1
1272        Make/O/N=(num) root:myGlobals:Attenuators:ng3att2
1273        Make/O/N=(num) root:myGlobals:Attenuators:ng3att3
1274        Make/O/N=(num) root:myGlobals:Attenuators:ng3att4
1275        Make/O/N=(num) root:myGlobals:Attenuators:ng3att5
1276        Make/O/N=(num) root:myGlobals:Attenuators:ng3att6
1277        Make/O/N=(num) root:myGlobals:Attenuators:ng3att7
1278        Make/O/N=(num) root:myGlobals:Attenuators:ng3att8
1279        Make/O/N=(num) root:myGlobals:Attenuators:ng3att9
1280        Make/O/N=(num) root:myGlobals:Attenuators:ng3att10
1281       
1282        // and a wave for the errors at each attenuation factor
1283        Make/O/N=(num) root:myGlobals:Attenuators:ng3att0_err
1284        Make/O/N=(num) root:myGlobals:Attenuators:ng3att1_err
1285        Make/O/N=(num) root:myGlobals:Attenuators:ng3att2_err
1286        Make/O/N=(num) root:myGlobals:Attenuators:ng3att3_err
1287        Make/O/N=(num) root:myGlobals:Attenuators:ng3att4_err
1288        Make/O/N=(num) root:myGlobals:Attenuators:ng3att5_err
1289        Make/O/N=(num) root:myGlobals:Attenuators:ng3att6_err
1290        Make/O/N=(num) root:myGlobals:Attenuators:ng3att7_err
1291        Make/O/N=(num) root:myGlobals:Attenuators:ng3att8_err
1292        Make/O/N=(num) root:myGlobals:Attenuators:ng3att9_err
1293        Make/O/N=(num) root:myGlobals:Attenuators:ng3att10_err
1294       
1295       
1296        //each wave has 10 elements, the transmission of att# at the wavelengths
1297        //lambda = 4,5,6,7,8,10,12,14,17,20 (4 A and 20 A are extrapolated values)
1298        Make/O/N=(num) root:myGlobals:Attenuators:ng3lambda={4,5,6,7,8,10,12,14,17,20}
1299       
1300        // new calibration done June 2007, John Barker
1301        root:myGlobals:Attenuators:ng3att0 = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
1302        root:myGlobals:Attenuators:ng3att1 = {0.444784,0.419,0.3935,0.3682,0.3492,0.3132,0.2936,0.2767,0.2477,0.22404}
1303        root:myGlobals:Attenuators:ng3att2 = {0.207506,0.1848,0.1629,0.1447,0.1292,0.1056,0.09263,0.08171,0.06656,0.0546552}
1304        root:myGlobals:Attenuators:ng3att3 = {0.092412,0.07746,0.06422,0.05379,0.04512,0.03321,0.02707,0.02237,0.01643,0.0121969}
1305        root:myGlobals:Attenuators:ng3att4 = {0.0417722,0.03302,0.02567,0.02036,0.01604,0.01067,0.00812,0.006316,0.00419,0.00282411}
1306        root:myGlobals:Attenuators:ng3att5 = {0.0187129,0.01397,0.01017,0.007591,0.005668,0.003377,0.002423,0.001771,0.001064,0.000651257}
1307        root:myGlobals:Attenuators:ng3att6 = {0.00851048,0.005984,0.004104,0.002888,0.002029,0.001098,0.0007419,0.0005141,0.000272833,0.000150624}
1308        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}
1309        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}
1310        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}
1311        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}
1312 
1313  // percent errors as measured, May 2007 values
1314  // zero error for zero attenuators, appropriate average values put in for unknown values
1315        root:myGlobals:Attenuators:ng3att0_err = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
1316        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}
1317        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}
1318        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}
1319        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}
1320        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}
1321        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}
1322        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}
1323        root:myGlobals:Attenuators:ng3att8_err = {0.7,0.705,0.927,0.503,0.691,1.27,1,1,1,1}
1324        root:myGlobals:Attenuators:ng3att9_err = {1,0.862,1.172,0.799,1.104,1.891,1.5,1.5,1.5,1.5}
1325        root:myGlobals:Attenuators:ng3att10_err = {1.5,1.054,1.435,1.354,1.742,2,2,2,2,2}
1326 
1327 
1328  //old tables, pre-June 2007
1329//      Make/O/N=9 root:myGlobals:Attenuators:ng3lambda={5,6,7,8,10,12,14,17,20}
1330//      root:myGlobals:Attenuators:ng3att0 = {1, 1, 1, 1, 1, 1, 1, 1,1 }
1331//      root:myGlobals:Attenuators:ng3att1 = {0.421, 0.394, 0.371, 0.349, 0.316, 0.293, 0.274, 0.245,0.220}
1332//      root:myGlobals:Attenuators:ng3att2 = {0.187, 0.164, 0.145, 0.130, 0.106, 0.0916, 0.0808, 0.0651,0.0531}
1333//      root:myGlobals:Attenuators:ng3att3 = {0.0777, 0.0636, 0.0534, 0.0446, 0.0330, 0.0262, 0.0217, 0.0157 ,0.0116}
1334//      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}
1335//      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}
1336//      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}
1337//      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}
1338//      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}
1339//      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}
1340//      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}
1341
1342End
1343
1344// new calibration done June 2007, John Barker
1345Proc MakeNG7AttenTable()
1346
1347        NewDataFolder/O root:myGlobals:Attenuators
1348       
1349        Variable num=10         //10 needed for tables after June 2007
1350       
1351        Make/O/N=(num) root:myGlobals:Attenuators:ng7att0
1352        Make/O/N=(num) root:myGlobals:Attenuators:ng7att1
1353        Make/O/N=(num) root:myGlobals:Attenuators:ng7att2
1354        Make/O/N=(num) root:myGlobals:Attenuators:ng7att3
1355        Make/O/N=(num) root:myGlobals:Attenuators:ng7att4
1356        Make/O/N=(num) root:myGlobals:Attenuators:ng7att5
1357        Make/O/N=(num) root:myGlobals:Attenuators:ng7att6
1358        Make/O/N=(num) root:myGlobals:Attenuators:ng7att7
1359        Make/O/N=(num) root:myGlobals:Attenuators:ng7att8
1360        Make/O/N=(num) root:myGlobals:Attenuators:ng7att9
1361        Make/O/N=(num) root:myGlobals:Attenuators:ng7att10
1362       
1363        // and a wave for the errors at each attenuation factor
1364        Make/O/N=(num) root:myGlobals:Attenuators:ng7att0_err
1365        Make/O/N=(num) root:myGlobals:Attenuators:ng7att1_err
1366        Make/O/N=(num) root:myGlobals:Attenuators:ng7att2_err
1367        Make/O/N=(num) root:myGlobals:Attenuators:ng7att3_err
1368        Make/O/N=(num) root:myGlobals:Attenuators:ng7att4_err
1369        Make/O/N=(num) root:myGlobals:Attenuators:ng7att5_err
1370        Make/O/N=(num) root:myGlobals:Attenuators:ng7att6_err
1371        Make/O/N=(num) root:myGlobals:Attenuators:ng7att7_err
1372        Make/O/N=(num) root:myGlobals:Attenuators:ng7att8_err
1373        Make/O/N=(num) root:myGlobals:Attenuators:ng7att9_err
1374        Make/O/N=(num) root:myGlobals:Attenuators:ng7att10_err 
1375       
1376        //NG7 wave has 10 elements, the transmission of att# at the wavelengths
1377        //lambda =4, 5,6,7,8,10,12,14,17,20
1378        // note that some of the higher attenuations and ALL of the 4 A and 20A data is interpolated
1379        // none of these values are expected to be used in reality since the flux would be too low in practice
1380        Make/O/N=(num) root:myGlobals:Attenuators:ng7lambda={4,5,6,7,8,10,12,14,17,20}
1381
1382// New calibration, June 2007, John Barker
1383        root:myGlobals:Attenuators:ng7att0 = {1, 1, 1, 1, 1, 1, 1, 1 ,1,1}     
1384        root:myGlobals:Attenuators:ng7att1 = {0.448656,0.4192,0.3925,0.3661,0.3458,0.3098,0.2922,0.2738,0.2544,0.251352}
1385        root:myGlobals:Attenuators:ng7att2 = {0.217193,0.1898,0.1682,0.148,0.1321,0.1076,0.0957,0.08485,0.07479,0.0735965}
1386        root:myGlobals:Attenuators:ng7att3 = {0.098019,0.07877,0.06611,0.05429,0.04548,0.03318,0.02798,0.0234,0.02004,0.0202492}
1387        root:myGlobals:Attenuators:ng7att4 = {0.0426904,0.03302,0.02617,0.02026,0.0158,0.01052,0.008327,0.006665,0.005745,0.00524807}
1388        root:myGlobals:Attenuators:ng7att5 = {0.0194353,0.01398,0.01037,0.0075496,0.005542,0.003339,0.002505,0.001936,0.001765,0.00165959}
1389        root:myGlobals:Attenuators:ng7att6 = {0.00971666,0.005979,0.004136,0.002848,0.001946,0.001079,0.0007717,0.000588,0.000487337,0.000447713}
1390        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}
1391        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}
1392        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}
1393        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}
1394
1395  // percent errors as measured, May 2007 values
1396  // zero error for zero attenuators, appropriate average values put in for unknown values
1397        root:myGlobals:Attenuators:ng7att0_err = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
1398        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}
1399        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}
1400        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}
1401        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}
1402        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}
1403        root:myGlobals:Attenuators:ng7att6_err = {0.6,0.501,0.6136,0.528,0.8796,1.708,0.782,0.874,1,1}
1404        root:myGlobals:Attenuators:ng7att7_err = {0.8,0.697,0.9149,0.583,1.173,2.427,1.242,2,2,2}
1405        root:myGlobals:Attenuators:ng7att8_err = {1,0.898,1.24,0.696,1.577,3.412,3,3,3,3}
1406        root:myGlobals:Attenuators:ng7att9_err = {1.5,1.113,1.599,1.154,2.324,4.721,5,5,5,5}
1407        root:myGlobals:Attenuators:ng7att10_err = {1.5,1.493,5,5,5,5,5,5,5,5} 
1408 
1409
1410// Pre-June 2007 calibration values - do not use these anymore 
1411////    root:myGlobals:Attenuators:ng7att0 = {1, 1, 1, 1, 1, 1, 1, 1 ,1}
1412////    root:myGlobals:Attenuators:ng7att1 = {0.418, 0.393, 0.369, 0.347, 0.313, 0.291, 0.271, 0.244, 0.219 }
1413////    root:myGlobals:Attenuators:ng7att2 = {0.189, 0.167, 0.148, 0.132, 0.109, 0.0945, 0.0830, 0.0681, 0.0560}
1414////    root:myGlobals:Attenuators:ng7att3 = {0.0784, 0.0651, 0.0541, 0.0456, 0.0340, 0.0273, 0.0223, 0.0164 , 0.0121}
1415////    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}
1416////    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}
1417////    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}
1418////    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}
1419////    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}
1420////    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}
1421////    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}
1422End
1423
1424//returns the transmission of the attenuator (at NG3) given the attenuator number
1425//which must be an integer(to select the wave) and given the wavelength.
1426//the wavelength may be any value between 4 and 20 (A), and is interpolated
1427//between calibrated wavelengths for a given attenuator
1428//
1429// Mar 2010 - abs() added to attStr to account for ICE reporting -0.0001 as an attenuator position, which truncates to "-0"
1430Function LookupAttenNG3(lambda,attenNo,atten_err)
1431        Variable lambda, attenNo, &atten_err
1432       
1433        Variable trans
1434        String attStr="root:myGlobals:Attenuators:ng3att"+num2str(trunc(abs(attenNo)))
1435        String attErrWStr="root:myGlobals:Attenuators:ng3att"+num2str(trunc(abs(attenNo)))+"_err"
1436        String lamStr = "root:myGlobals:Attenuators:ng3lambda"
1437       
1438        if(attenNo == 0)
1439                return (1)              //no attenuation, return trans == 1
1440        endif
1441       
1442        if( (lambda < 4) || (lambda > 20 ) )
1443                Abort "Wavelength out of calibration range (4,20). You must manually enter the absolute parameters"
1444        Endif
1445       
1446        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) || !(WaveExists($attErrWStr)))
1447                Execute "MakeNG3AttenTable()"
1448        Endif
1449        //just in case creating the tables fails....
1450        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
1451                Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters"
1452        Endif
1453       
1454        //lookup the value by interpolating the wavelength
1455        //the attenuator must always be an integer
1456        Wave att = $attStr
1457        Wave attErrW = $attErrWStr
1458        Wave lam = $lamstr
1459        trans = interp(lambda,lam,att)
1460        atten_err = interp(lambda,lam,attErrW)
1461
1462// the error in the tables is % error. return the standard deviation instead
1463        atten_err = trans*atten_err/100
1464               
1465//      Print "trans = ",trans
1466//      Print "trans err = ",atten_err
1467       
1468        return trans
1469End
1470
1471//returns the transmission of the attenuator (at NG7) given the attenuator number
1472//which must be an integer(to select the wave) and given the wavelength.
1473//the wavelength may be any value between 4 and 20 (A), and is interpolated
1474//between calibrated wavelengths for a given attenuator
1475//
1476// this set of tables is also used for NG5 (NG1) SANS instrument - as the attenuator has never been calibrated
1477//
1478// local function
1479//
1480// Mar 2010 - abs() added to attStr to account for ICE reporting -0.0001 as an attenuator position, which truncates to "-0"
1481Function LookupAttenNG7(lambda,attenNo,atten_err)
1482        Variable lambda, attenNo, &atten_err
1483       
1484        Variable trans
1485        String attStr="root:myGlobals:Attenuators:ng7att"+num2str(trunc(abs(attenNo)))
1486        String attErrWStr="root:myGlobals:Attenuators:ng7att"+num2str(trunc(abs(attenNo)))+"_err"
1487        String lamStr = "root:myGlobals:Attenuators:ng7lambda"
1488       
1489        if(attenNo == 0)
1490                return (1)              //no attenuation, return trans == 1
1491        endif
1492       
1493        if( (lambda < 4) || (lambda > 20 ) )
1494                Abort "Wavelength out of calibration range (4,20). You must manually enter the absolute parameters"
1495        Endif
1496       
1497        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) || !(WaveExists($attErrWStr)))
1498                Execute "MakeNG7AttenTable()"
1499        Endif
1500        //just in case creating the tables fails....
1501        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
1502                Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters"
1503        Endif
1504       
1505        //lookup the value by interpolating the wavelength
1506        //the attenuator must always be an integer
1507        Wave att = $attStr
1508        Wave attErrW = $attErrWStr
1509        Wave lam = $lamstr
1510        trans = interp(lambda,lam,att)
1511        atten_err = interp(lambda,lam,attErrW)
1512
1513// the error in the tables is % error. return the standard deviation instead
1514        atten_err = trans*atten_err/100
1515       
1516//      Print "trans = ",trans
1517//      Print "trans err = ",atten_err
1518       
1519        return trans
1520
1521End
1522
1523// a utility function so that I can get the values from the command line
1524// since the atten_err is PBR
1525//
1526Function PrintAttenuation(instr,lam,attenNo)
1527        String instr
1528        Variable lam,attenNo
1529       
1530        Variable atten_err, attenFactor
1531       
1532        strswitch(instr)
1533                case "NG3":
1534                        attenFactor = LookupAttenNG3(lam,attenNo,atten_err)
1535                        break
1536                case "NG5":
1537                        //using NG7 lookup Table
1538                        attenFactor = LookupAttenNG7(lam,attenNo,atten_err)
1539                        break
1540                case "NG7":
1541                        attenFactor = LookupAttenNG7(lam,attenNo,atten_err)
1542                        break
1543                default:                                                       
1544                        //return error?
1545                        attenFactor=1
1546        endswitch
1547
1548        Print "atten, err = ", attenFactor, atten_err
1549       
1550        return(0)
1551End
1552
1553
1554
1555//returns the proper attenuation factor based on the instrument (NG3, NG5, or NG7)
1556//NG5 values are taken from the NG7 tables (there is very little difference in the
1557//values, and NG5 attenuators have not been calibrated (as of 8/01)
1558//
1559// filestr is passed from TextRead[3] = the default directory
1560// lam is passed from RealsRead[26]
1561// AttenNo is passed from ReaslRead[3]
1562//
1563// Attenuation factor as defined here is <= 1
1564//
1565// ORNL can pass ("",1,attenuationFactor) and have this function simply
1566// spit back the attenuationFactor (that was read into rw[3])
1567//
1568// called by Correct.ipf, ProtocolAsPanel.ipf, Transmission.ipf
1569//
1570//
1571// as of March 2011, returns the error (one standard deviation) in the attenuation factor as the last parameter, by reference
1572Function AttenuationFactor(fileStr,lam,attenNo,atten_err)
1573        String fileStr
1574        Variable lam,attenNo, &atten_err
1575       
1576        Variable attenFactor=1,loc
1577        String instr=fileStr[1,3]       //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total)
1578       
1579        strswitch(instr)
1580                case "NG3":
1581                        attenFactor = LookupAttenNG3(lam,attenNo,atten_err)
1582                        break
1583                case "NG5":
1584                        //using NG7 lookup Table
1585                        attenFactor = LookupAttenNG7(lam,attenNo,atten_err)
1586                        break
1587                case "NG7":
1588                        attenFactor = LookupAttenNG7(lam,attenNo,atten_err)
1589                        break
1590                default:                                                       
1591                        //return error?
1592                        attenFactor=1
1593        endswitch
1594//      print "instr, lambda, attenNo,attenFactor = ",instr,lam,attenNo,attenFactor
1595        return(attenFactor)
1596End
1597
1598//function called by the popups to get a file list of data that can be sorted
1599// this procedure simply removes the raw data files from the string - there
1600//can be lots of other junk present, but this is very fast...
1601//
1602// could also use the alternate procedure of keeping only file with the proper extension
1603//
1604// another possibility is to get a listing of the text files, but is unreliable on
1605// Windows, where the data file must be .txt (and possibly OSX)
1606//
1607// called by FIT_Ops.ipf, NSORT.ipf, PlotUtils.ipf
1608//
1609Function/S ReducedDataFileList(ctrlName)
1610        String ctrlName
1611
1612        String list="",newList="",item=""
1613        Variable num,ii
1614       
1615        //check for the path
1616        PathInfo catPathName
1617        if(V_Flag==0)
1618                DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel"
1619                Return("")
1620        Endif
1621       
1622        list = IndexedFile(catpathName,-1,"????")
1623       
1624        list = RemoveFromList(ListMatch(list,"*.SA1*",";"), list, ";", 0)
1625        list = RemoveFromList(ListMatch(list,"*.SA2*",";"), list, ";", 0)
1626        list = RemoveFromList(ListMatch(list,"*.SA3*",";"), list, ";", 0)
1627        list = RemoveFromList(ListMatch(list,".*",";"), list, ";", 0)
1628        list = RemoveFromList(ListMatch(list,"*.pxp",";"), list, ";", 0)
1629        list = RemoveFromList(ListMatch(list,"*.DIV",";"), list, ";", 0)
1630        list = RemoveFromList(ListMatch(list,"*.GSP",";"), list, ";", 0)
1631        list = RemoveFromList(ListMatch(list,"*.MASK",";"), list, ";", 0)
1632
1633        //remove VAX version numbers
1634        list = RemoveVersNumsFromList(List)
1635        //sort
1636        newList = SortList(List,";",0)
1637
1638        return newlist
1639End
1640
1641// returns a list of raw data files in the catPathName directory on disk
1642// - list is SEMICOLON-delimited
1643//
1644// does it the "cheap" way, simply finding the ".SAn" in the file name
1645// = does not check for proper byte length.
1646//
1647// called by PatchFiles.ipf, Tile_2D.ipf
1648//
1649Function/S GetRawDataFileList()
1650       
1651        //make sure that path exists
1652        PathInfo catPathName
1653        if (V_flag == 0)
1654                Abort "Folder path does not exist - use Pick Path button on Main Panel"
1655        Endif
1656       
1657        String list=IndexedFile(catPathName,-1,"????")
1658        String newList="",item=""
1659        Variable num=ItemsInList(list,";"),ii
1660        for(ii=0;ii<num;ii+=1)
1661                item = StringFromList(ii, list  ,";")
1662                if( stringmatch(item,"*.sa1*") )
1663                        newlist += item + ";"
1664                endif
1665                if( stringmatch(item,"*.sa2*") )
1666                        newlist += item + ";"
1667                endif
1668                if( stringmatch(item,"*.sa3*") )
1669                        newlist += item + ";"
1670                endif
1671                //print "ii=",ii
1672        endfor
1673        newList = SortList(newList,";",0)
1674        return(newList)
1675End
1676
1677// Return the filename that represents the previous or next file.
1678// Input is current filename and increment.
1679// Increment should be -1 or 1
1680// -1 => previous file
1681// 1 => next file
1682Function/S GetPrevNextRawFile(curfilename, prevnext)
1683        String curfilename
1684        Variable prevnext
1685
1686        String filename
1687       
1688        //get the run number
1689        Variable num = GetRunNumFromFile(curfilename)
1690               
1691        //find the next specified file by number
1692        fileName = FindFileFromRunNumber(num+prevnext)
1693
1694        if(cmpstr(fileName,"")==0)
1695                //null return, do nothing
1696                fileName = FindFileFromRunNumber(num)
1697        Endif
1698
1699//      print "in FU "+filename
1700
1701        Return filename
1702End
1703
1704
Note: See TracBrowser for help on using the repository browser.