source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/HFIR_Utils.ipf @ 525

Last change on this file since 525 was 525, checked in by srkline, 14 years ago

first addition of HFIR reading utilities. not fully functional.

File size: 20.4 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.0
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
14
15
16
17// initializes globals that are specific to a particular facility
18// - number of XY pixels
19// - pixexl resolution [cm]
20// - detector deadtime constant [s]
21//
22// called by Initialize.ipf
23//
24Function InitFacilityGlobals()
25
26        //Detector -specific globals
27        Variable/G root:myGlobals:gNPixelsX=192                                 // number of detector X and Y pixels
28        Variable/G root:myGlobals:gNPixelsY=192
29       
30        // pixel dimensions are now read directly from the file header.
31        Variable/G root:myGlobals:PixelResDefault = 0.5                 //pixel resolution in cm
32       
33        Variable/G root:myGlobals:DeadtimeDefault = 3.4e-6              //deadtime in seconds
34
35        Variable/G root:myGlobals:apOff = 5.0           // (cm) distance from sample aperture to sample position
36
37End
38
39
40//**********************
41// Resolution calculation - used by the averaging routines
42// to calculate the resolution function at each q-value
43// - the return value is not used
44//
45// equivalent to John's routine on the VAX Q_SIGMA_AVE.FOR
46// Incorporates eqn. 3-15 from J. Appl. Cryst. (1995) v. 28 p105-114
47//
48// - 21 MAR 07 uses projected BS diameter on the detector
49// - APR 07 still need to add resolution with lenses. currently there is no flag in the
50//          raw data header to indicate the presence of lenses.
51//
52// - Aug 07 - added input to switch calculation based on lenses (==1 if in)
53//
54// - called by CircSectAvg.ipf and RectAnnulAvg.ipf
55//
56// passed values are read from RealsRead
57// except DDet and apOff, which are set from globals before passing
58//
59//
60Function/S getResolution(inQ,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,SigmaQ,QBar,fSubS)
61        Variable inQ, lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses
62        Variable &fSubS, &QBar, &SigmaQ         //these are the output quantities at the input Q value
63       
64        //lots of calculation variables
65        Variable a2, q_small, lp, v_lambda, v_b, v_d, vz, yg, v_g
66        Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r
67
68        //Constants
69        Variable vz_1 = 3.956e5         //velocity [cm/s] of 1 A neutron
70        Variable g = 981.0                              //gravity acceleration [cm/s^2]
71
72        String results
73        results ="Failure"
74
75        S1 *= 0.5*0.1                   //convert to radius and [cm]
76        S2 *= 0.5*0.1
77
78        L1 *= 100.0                     // [cm]
79        L1 -= apOff                             //correct the distance
80
81        L2 *= 100.0
82        L2 += apOff
83        del_r *= 0.1                            //width of annulus, convert mm to [cm]
84       
85        BS *= 0.5*0.1                   //nominal BS diameter passed in, convert to radius and [cm]
86        // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture
87        Variable LB
88        LB = 20.1 + 1.61*BS                     //distance in cm from beamstop to anode plane (empirical)
89        BS = bs + bs*lb/(l2-lb)         //adjusted diameter of shadow from parallax
90       
91        //Start resolution calculation
92        a2 = S1*L2/L1 + S2*(L1+L2)/L1
93        q_small = 2.0*Pi*(BS-a2)*(1.0-lambdaWidth)/(lambda*L2)
94        lp = 1.0/( 1.0/L1 + 1.0/L2)
95
96        v_lambda = lambdaWidth^2/6.0
97       
98//      if(usingLenses==1)                      //SRK 2007
99        if(usingLenses != 0)                    //SRK 2008 allows for the possibility of different numbers of lenses in header
100                v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2         //correction to 2nd term
101        else
102                v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2              //original form
103        endif
104       
105        v_d = (DDet/2.3548)^2 + del_r^2/12.0
106        vz = vz_1 / lambda
107        yg = 0.5*g*L2*(L1+L2)/vz^2
108        v_g = 2.0*(2.0*yg^2*v_lambda)                                   //factor of 2 correction, B. Hammouda, 2007
109
110        r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) ))
111        delta = 0.5*(BS - r0)^2/v_d
112
113        if (r0 < BS)
114                inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta))
115        else
116                inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta))
117        endif
118
119        fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) )
120        if (fSubS <= 0.0)
121                fSubS = 1.e-10
122        endif
123        fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi))
124        fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d
125
126        rmd = fr*r0
127        v_r1 = v_b + fv*v_d +v_g
128
129        rm = rmd + 0.5*v_r1/rmd
130        v_r = v_r1 - 0.5*(v_r1/rmd)^2
131        if (v_r < 0.0)
132                v_r = 0.0
133        endif
134        QBar = (4.0*Pi/lambda)*sin(0.5*atan(rm/L2))
135        SigmaQ = QBar*sqrt(v_r/rmd^2 +v_lambda)
136
137        results = "success"
138        Return results
139End
140
141//**********************
142// 2D resolution function calculation - in terms of X and Y
143//
144// see same-named function in NCNR_Utils
145//
146Function/S get2DResolution(inQ,phi,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,r_dist,SigmaQX,SigmaQY,fSubS)
147        Variable inQ, phi,lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses,r_dist
148        Variable &SigmaQX,&SigmaQY,&fSubS               //these are the output quantities at the input Q value
149
150
151        String results = "success"
152        Return results
153End
154
155
156//Utility function that returns the detector resolution (in cm)
157//Global values are set in the Initialize procedure
158//
159// - called by CircSectAvg.ipf, RectAnnulAvg.ipf, and ProtocolAsPanel.ipf
160//
161// fileStr is passed as TextRead[3] and is the filename
162// detStr is passed as TextRead[9] and is an identifier for the detector
163//
164// depricated - pixel dimensions are read directly from the file header
165Function xDetectorPixelResolution(fileStr,detStr)
166        String fileStr,detStr
167       
168        Variable DDet
169
170        //your code here
171       
172        return(DDet)
173End
174
175//Utility function that returns the detector deadtime (in seconds)
176//Global values are set in the Initialize procedure
177//
178// - called by WorkFileUtils.ipf
179//
180// fileStr is passed as TextRead[3] and is the filename
181// detStr is passed as TextRead[9] and is an identifier for the detector
182//
183Function DetectorDeadtime(fileStr,detStr)
184        String fileStr,detStr
185       
186        Variable deadtime
187       
188// your code here
189
190        return(deadtime)
191End
192
193
194
195// item is a filename
196//
197// this function extracts some sort of number from the file
198// presumably some sort of automatically incrementing run number set by the
199// acquisition system
200//
201// this run number should be a unique identifier for the file
202//
203Function GetRunNumFromFile(item)
204        String item
205
206        Variable num=-1         // an invalid return value
207       
208        //your code here
209       
210        return (num)
211End
212
213
214// item is a filename
215//
216// this function extracts some sort of number from the file
217// presumably some sort of automatically incrementing run number set by the
218// acquisition system
219//
220// this run number should be a unique identifier for the file
221//
222// same as GetRunNumFromFile(0), just with a string return
223//
224// "ABC" returned as an invalid result
225Function/S GetRunNumStrFromFile(item)
226        String item
227       
228        String invalid = "ABC"  //"ABC" is not a valid run number, since it's text
229        String retStr
230        retStr=invalid
231       
232        //your code here
233       
234        return(retStr)
235End
236
237//returns a string containing the full path to the file containing the
238//run number "num". The null string is returned if no valid file can be found.
239//
240//
241// search in the path "catPathName" (hard-wired), will abort if this path does not exist
242//the file returned will be a RAW SANS data file, other types of files are
243//filtered out.
244//
245// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
246//
247Function/S FindFileFromRunNumber(num)
248        Variable num
249       
250        String fullName="",partialName="",item=""
251       
252        //make sure that path exists
253        PathInfo catPathName
254        String path = S_path
255        if (V_flag == 0)
256                Abort "folder path does not exist - use Pick Path button"
257        Endif
258
259        //your code here       
260
261        return(fullname)
262       
263End
264
265//function to test a binary file to see if it is a RAW binary SANS file
266//first checks the total bytes in the file (which for raw data is 33316 bytes)
267//**note that the "DIV" file will also show up as a raw file by the run field
268//should be listed in CAT/SHORT and in patch windows
269//
270//Function then checks the file fname (full path:file) for "RAW" run.type field
271//if not found, the data is not raw data and zero is returned
272//
273// called by many procedures (both external and local)
274//
275Function CheckIfRawData(fname)
276        String fname
277             
278        String tempheadhfir                                           
279        Variable ind=0
280        Variable refNum
281       
282        //If not have .xml extension, return 0.
283        if (stringmatch(fname,"*.xml") <1)
284                print fname+": Failed. Not a *.xml file."
285                return 0                                //Not *.xml. Do nothing...
286        endif
287        //actually open the file
288        refNum = XmlOpenFile(fname)     
289        if (refNum < 0)
290                print "==> "+ fname+ "\r  ==> Failed to load: Not a standard xml file format or broken.. Please check the file if properly written..."
291                return 0                                //Not a xml file. Do nothing...
292        endif
293
294        //temp list of ns
295        MAKE/T/N=(1)/O nsList
296        nsList[0] = "1.1"
297       
298        // Check if  it is the SPICE version = 1.1
299        Variable  item,i
300        String thislocation,ns = ""
301        if (refNum >0)
302                for (item = 0; item < DimSize(nsList, 0); item += 1)            // loop over all possible namespaces
303                        XMLlistAttr(refNum, "/SPICErack", nsList[item])
304                        wave/T M_listAttr
305       
306                        for (i = 0; i < DimSize(M_listAttr,0); i+=1)                    // loop over all available attributes
307                                // Expect the required hfir XML header (will fail if "schemalocation" is not found)
308                                if ( CmpStr(  LowerStr(M_listAttr[i][1]),  LowerStr("SPICE_version") ) == 0 )
309                                        thisLocation = TrimWS(M_listAttr[i][2])
310                                        if ( StringMatch(thisLocation, nsList[item] ) )
311                                                ns = nsList[item]                       
312                                       
313                                                Break   // found it!
314                                        endif
315                                endif
316                        endfor
317                        if (strlen(ns))                 
318                                Break           
319                        endif
320                endfor
321        endif
322        XmlCloseFile(refNum,0)
323        KillWaves/Z M_listAttr, nsList
324        if (StringMatch(ns,"1.1") <1)
325                ns = "0"
326        else
327                ns = "1"
328        endif
329       
330        return str2num(ns)
331End
332
333// function returns 1 if file is a transmission file, 0 if not
334//
335// called by Transmission.ipf, CatVSTable.ipf, NSORT.ipf
336//
337Function isTransFile(fName)
338        String fname
339       
340//      if(your test here)
341//              //yes, its a transmisison file
342//              Return(1)
343//      else
344//              //some other file
345//              Return(0)
346//      Endif
347End
348
349
350
351//function to remove all spaces from names when searching for filenames
352//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
353//but the text field in the header WILL, if less than 3 characters were used for the
354//user's initials, and can have leading spaces if prefix was less than 5 characters
355//
356//returns a string identical to the original string, except with the interior spaces removed
357//
358// local function for file name manipulation
359//
360// NO CHANGE NEEDED
361//
362Function/S RemoveAllSpaces(str)
363        String str
364       
365        String tempstr = str
366        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
367        ii=0
368        do
369                len = strlen(tempStr)
370                spc = strsearch(tempStr," ",0)          //is the last character a space?
371                if (spc == -1)
372                        break           //no more spaces found, get out
373                endif
374                str = tempstr
375                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
376        While(1)        //should never be more than 2 or 3
377       
378        If(strlen(tempStr) < 1)
379                tempStr = ""            //be sure to return a null string if problem found
380        Endif
381       
382        //Print strlen(tempstr)
383       
384        Return(tempStr)
385               
386End
387
388
389
390//Function attempts to find valid filename from partial name by checking for
391// the existence of the file on disk
392//
393// returns a valid filename (No path prepended) or a null string
394//
395// called by any functions, both external and local
396//
397Function/S FindValidFilename(partialName)
398        String PartialName
399       
400        String retStr=partialName
401       
402        //your code here
403       
404        return(retStr)
405End
406
407
408//returns a string containing filename (WITHOUT the ;vers)
409//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
410//with the folders separated by colons
411//
412// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
413//
414// NO CHANGE NEEDED
415//
416
417Function/S GetFileNameFromPathNoSemi(fullPath)
418        String fullPath
419       
420        Variable offset1,offset2
421        String filename=""
422        //String PartialPath
423        offset1 = 0
424        do
425                offset2 = StrSearch(fullPath, ":", offset1)
426                if (offset2 == -1)                              // no more colons ?
427                        fileName = FullPath[offset1,strlen(FullPath) ]
428                        //PartialPath = FullPath[0, offset1-1]
429                        break
430                endif
431                offset1 = offset2+1
432        while (1)
433       
434        //remove version number from name, if it's there - format should be: filename;N
435        filename =  StringFromList(0,filename,";")              //returns null if error
436       
437        Return filename
438End
439
440//returns a string containing filename (INCLUDING the ;vers)
441//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
442//with the folders separated by colons
443//
444// local, currently unused
445//
446// NO CHANGE NEEDED
447//
448
449Function/S GetFileNameFromPathKeepSemi(fullPath)
450        String fullPath
451       
452        Variable offset1,offset2
453        String filename
454        //String PartialPath
455        offset1 = 0
456        do
457                offset2 = StrSearch(fullPath, ":", offset1)
458                if (offset2 == -1)                              // no more colons ?
459                        fileName = FullPath[offset1,strlen(FullPath) ]
460                        //PartialPath = FullPath[0, offset1-1]
461                        break
462                endif
463                offset1 = offset2+1
464        while (1)
465       
466        //keep version number from name, if it's there - format should be: filename;N
467       
468        Return filename
469End
470
471//given the full path and filename (fullPath), strips the data path
472//(Mac-style, separated by colons) and returns this path
473//this partial path is the same string that would be returned from PathInfo, for example
474//
475// - allows the user to save to a different path than catPathName
476//
477// called by WriteQIS.ipf
478//
479// NO CHANGE NEEDED
480//
481
482Function/S GetPathStrFromfullName(fullPath)
483        String fullPath
484       
485        Variable offset1,offset2
486        //String filename
487        String PartialPath
488        offset1 = 0
489        do
490                offset2 = StrSearch(fullPath, ":", offset1)
491                if (offset2 == -1)                              // no more colons ?
492                        //fileName = FullPath[offset1,strlen(FullPath) ]
493                        PartialPath = FullPath[0, offset1-1]
494                        break
495                endif
496                offset1 = offset2+1
497        while (1)
498       
499        Return PartialPath
500End
501
502//given the filename trim or modify the filename to get a new
503//file string that can be used for naming averaged 1-d files
504//
505// called by ProtocolAsPanel.ipf and Tile_2D.ipf
506//
507Function/S GetNameFromHeader(fullName)
508        String fullName
509        String newName = ""
510
511        //your code here
512       
513        Return(newName)
514End
515
516//list (input) is a list, typically returned from IndexedFile()
517//which is semicolon-delimited, and may contain filenames from the VAX
518//that contain version numbers, where the version number appears as a separate list item
519//(and also as a non-existent file)
520//these numbers must be purged from the list, especially for display in a popup
521//or list processing of filenames
522//the function returns the list, cleaned of version numbers (up to 11)
523//raw data files will typically never have a version number other than 1.
524//
525// if there are no version numbers in the list, the input list is returned
526//
527// called by CatVSTable.ipf, NSORT.ipf, Transmission.ipf, WorkFileUtils.ipf
528//
529// NO CHANGE NEEDED
530//
531
532Function/S RemoveVersNumsFromList(list)
533        String list
534       
535        //get rid of version numbers first (up to 11)
536        Variable ii,num
537        String item
538        num = ItemsInList(list,";")
539        ii=1
540        do
541                item = num2str(ii)
542                list = RemoveFromList(item, list ,";" )
543                ii+=1
544        while(ii<12)
545       
546        return (list)
547End
548
549//input is a list of run numbers, and output is a list of filenames (not the full path)
550//*** input list must be COMMA delimited***
551//output is equivalent to selecting from the CAT table
552//if some or all of the list items are valid filenames, keep them...
553//if an error is encountered, notify of the offending element and return a null list
554//
555//output is COMMA delimited
556//
557// this routine is expecting that the "ask", "none" special cases are handled elsewhere
558//and not passed here
559//
560// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
561//
562// NO CHANGE NEEDED
563//
564
565Function/S ParseRunNumberList(list)
566        String list
567       
568        String newList="",item="",tempStr=""
569        Variable num,ii,runNum
570       
571        //expand number ranges, if any
572        list = ExpandNumRanges(list)
573       
574        num=itemsinlist(list,",")
575       
576        for(ii=0;ii<num;ii+=1)
577                //get the item
578                item = StringFromList(ii,list,",")
579                //is it already a valid filename?
580                tempStr=FindValidFilename(item) //returns filename if good, null if error
581                if(strlen(tempstr)!=0)
582                        //valid name, add to list
583                        //Print "it's a file"
584                        newList += tempStr + ","
585                else
586                        //not a valid name
587                        //is it a number?
588                        runNum=str2num(item)
589                        //print runnum
590                        if(numtype(runNum) != 0)
591                                //not a number -  maybe an error                       
592                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
593                                return("")
594                        else
595                                //a run number or an error
596                                tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) )
597                                if(strlen(tempstr)==0)
598                                        //file not found, error
599                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
600                                        return("")
601                                else
602                                        newList += tempStr + ","
603                                endif
604                        endif
605                endif
606        endfor          //loop over all items in list
607       
608        return(newList)
609End
610
611//takes a comma delimited list that MAY contain number range, and
612//expands any range of run numbers into a comma-delimited list...
613//and returns the new list - if not a range, return unchanged
614//
615// local function
616//
617// NO CHANGE NEEDED
618//
619
620Function/S ExpandNumRanges(list)
621        String list
622       
623        String newList="",dash="-",item,str
624        Variable num,ii,hasDash
625       
626        num=itemsinlist(list,",")
627//      print num
628        for(ii=0;ii<num;ii+=1)
629                //get the item
630                item = StringFromList(ii,list,",")
631                //does it contain a dash?
632                hasDash = strsearch(item,dash,0)                //-1 if no dash found
633                if(hasDash == -1)
634                        //not a range, keep it in the list
635                        newList += item + ","
636                else
637                        //has a dash (so it's a range), expand (or add null)
638                        newList += ListFromDash(item)           
639                endif
640        endfor
641       
642        return newList
643End
644
645//be sure to add a trailing comma to the return string...
646//
647// local function
648//
649// NO CHANGE NEEDED
650//
651Function/S ListFromDash(item)
652        String item
653       
654        String numList="",loStr="",hiStr=""
655        Variable lo,hi,ii
656       
657        loStr=StringFromList(0,item,"-")        //treat the range as a list
658        hiStr=StringFromList(1,item,"-")
659        lo=str2num(loStr)
660        hi=str2num(hiStr)
661        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
662                numList=""
663                return numList
664        endif
665        for(ii=lo;ii<=hi;ii+=1)
666                numList += num2str(ii) + ","
667        endfor
668       
669        Return numList
670End
671
672
673//returns the proper attenuation factor based on the instrument
674//
675// filestr is passed from TextRead[3] = the default directory, used to identify the instrument
676// lam is passed from RealsRead[26]
677// AttenNo is passed from ReaslRead[3]
678//
679// Attenuation factor as defined here is <= 1
680//
681// Facilities can pass ("",1,attenuationFactor) and have this function simply
682// spit back the attenuationFactor (that was read into rw[3])
683//
684// called by Correct.ipf, ProtocolAsPanel.ipf, Transmission.ipf
685//
686Function AttenuationFactor(fileStr,lam,attenNo)
687        String fileStr
688        Variable lam,attenNo
689       
690        Variable attenFactor=1
691       
692        // your code here
693
694        return(attenFactor)
695End
696
697//function called by the popups to get a file list of data that can be sorted
698// this procedure simply removes the raw data files from the string - there
699//can be lots of other junk present, but this is very fast...
700//
701// could also use the alternate procedure of keeping only file with the proper extension
702//
703// another possibility is to get a listing of the text files, but is unreliable on
704// Windows, where the data file must be .txt (and possibly OSX)
705//
706// called by FIT_Ops.ipf, NSORT.ipf, PlotUtils.ipf
707//
708Function/S ReducedDataFileList(ctrlName)
709        String ctrlName
710
711        String list="",newList="",item=""
712        Variable num,ii
713       
714        //check for the path
715        PathInfo catPathName
716        if(V_Flag==0)
717                DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel"
718                Return("")
719        Endif
720       
721        list = IndexedFile(catpathName,-1,"????")
722        num=ItemsInList(list,";")
723        //print "num = ",num
724        for(ii=(num-1);ii>=0;ii-=1)
725                item = StringFromList(ii, list  ,";")
726                //simply remove all that are not raw data files (SA1 SA2 SA3)
727                if( !stringmatch(item,"*.xml") )
728                        if( !stringmatch(item,".*") && !stringmatch(item,"*.pxp") && !stringmatch(item,"*.DIV"))                //eliminate mac "hidden" files, pxp, and div files
729                                newlist += item + ";"
730                        endif
731                endif
732        endfor
733        //remove VAX version numbers
734        newList = RemoveVersNumsFromList(newList)
735        //sort
736        newList = SortList(newList,";",0)
737
738        return newlist
739End
740
741// returns a list of raw data files in the catPathName directory on disk
742// - list is SEMICOLON-delimited
743//
744// does it the "cheap" way, simply finding the ".SAn" in the file name
745// = does not check for proper byte length.
746//
747// called by PatchFiles.ipf, Tile_2D.ipf
748//
749Function/S GetRawDataFileList()
750       
751        //make sure that path exists
752        PathInfo catPathName
753        if (V_flag == 0)
754                Abort "Folder path does not exist - use Pick Path button on Main Panel"
755        Endif
756       
757        String list=IndexedFile(catPathName,-1,"????")
758        String newList="",item=""
759        Variable num=ItemsInList(list,";"),ii
760        for(ii=0;ii<num;ii+=1)
761                item = StringFromList(ii, list  ,";")
762                if( stringmatch(item,"*.xml") )
763                        if (CheckIfRawData(S_path+item) >0)
764                                newlist += item + ";"
765                        endif
766                endif
767        endfor
768        newList = SortList(newList,";",0)
769        return(newList)
770End
Note: See TracBrowser for help on using the repository browser.