source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/QKK_ANSTO_Utils.ipf @ 986

Last change on this file since 986 was 986, checked in by srkline, 7 years ago

fixing issues with QUOKKA reduction procedures that generate errors in Igor 7

updated the QKK_NSORT file to match the new 4-file NSORT. this was a complete, direct copy of the file as there were no Ansto -specific bits.

File size: 36.6 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=192                                 // number of X and Y pixels
24        Variable/G root:myGlobals:gNPixelsY=192
25       
26        // pixel dimensions are now read directly from the file header.
27//      Variable/G root:myGlobals:PixelResDefault = 0.5                 //pixel resolution in cm
28       
29        Variable/G root:myGlobals:DeadtimeDefault = 2.14e-6 // 3.4e-6           //deadtime in seconds ???nha
30
31        Variable/G root:myGlobals:apOff = 5.0           // (cm) distance from sample aperture to sample position
32
33End
34
35
36//**********************
37// Resolution calculation - used by the averaging routines
38// to calculate the resolution function at each q-value
39// - the return value is not used
40//
41// equivalent to John's routine on the VAX Q_SIGMA_AVE.FOR
42// Incorporates eqn. 3-15 from J. Appl. Cryst. (1995) v. 28 p105-114
43//
44// - 21 MAR 07 uses projected BS diameter on the detector
45// - APR 07 still need to add resolution with lenses. currently there is no flag in the
46//          raw data header to indicate the presence of lenses.
47//
48// - Aug 07 - added input to switch calculation based on lenses (==1 if in)
49//
50// - called by CircSectAvg.ipf and RectAnnulAvg.ipf
51//
52// passed values are read from RealsRead
53// except DDet and apOff, which are set from globals before passing
54//
55//
56Function/S getResolution(inQ,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,SigmaQ,QBar,fSubS)
57        Variable inQ, lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses
58        Variable &fSubS, &QBar, &SigmaQ         //these are the output quantities at the input Q value
59       
60        //lots of calculation variables
61        Variable a2, q_small, lp, v_lambda, v_b, v_d, vz, yg, v_g
62        Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r
63
64        //Constants
65        Variable vz_1 = 3.956e5         //velocity [cm/s] of 1 A neutron
66        Variable g = 981.0                              //gravity acceleration [cm/s^2]
67
68        String results
69        results ="Failure"
70
71        S1 *= 0.5*0.1                   //convert to radius and [cm]
72        S2 *= 0.5*0.1
73
74        L1 *= 100.0                     // [cm]
75        L1 -= apOff                             //correct the distance
76
77        L2 *= 100.0
78        L2 += apOff
79        del_r *= 0.1                            //width of annulus, convert mm to [cm]
80       
81        BS *= 0.5*0.1                   //nominal BS diameter passed in, convert to radius and [cm]
82        // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture
83        Variable LB
84        LB = 20.1 + 1.61*BS                     //distance in cm from beamstop to anode plane (empirical)
85        BS = bs + bs*lb/(l2-lb)         //adjusted diameter of shadow from parallax
86       
87        //Start resolution calculation
88        a2 = S1*L2/L1 + S2*(L1+L2)/L1
89        q_small = 2.0*Pi*(BS-a2)*(1.0-lambdaWidth)/(lambda*L2)
90        lp = 1.0/( 1.0/L1 + 1.0/L2)
91
92        v_lambda = lambdaWidth^2/6.0
93       
94//      if(usingLenses==1)                      //SRK 2007
95        if(usingLenses != 0)                    //SRK 2008 allows for the possibility of different numbers of lenses in header
96                v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2         //correction to 2nd term
97        else
98                v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2              //original form
99        endif
100       
101        v_d = (DDet/2.3548)^2 + del_r^2/12.0
102        vz = vz_1 / lambda
103        yg = 0.5*g*L2*(L1+L2)/vz^2
104        v_g = 2.0*(2.0*yg^2*v_lambda)                                   //factor of 2 correction, B. Hammouda, 2007
105
106        r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) ))
107        delta = 0.5*(BS - r0)^2/v_d
108
109        if (r0 < BS)
110                inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta))
111        else
112                inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta))
113        endif
114
115        fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) )
116        if (fSubS <= 0.0)
117                fSubS = 1.e-10
118        endif
119        fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi))
120        fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d
121
122        rmd = fr*r0
123        v_r1 = v_b + fv*v_d +v_g
124
125        rm = rmd + 0.5*v_r1/rmd
126        v_r = v_r1 - 0.5*(v_r1/rmd)^2
127        if (v_r < 0.0)
128                v_r = 0.0
129        endif
130        QBar = (4.0*Pi/lambda)*sin(0.5*atan(rm/L2))
131        SigmaQ = QBar*sqrt(v_r/rmd^2 +v_lambda)
132
133        results = "success"
134        Return results
135End
136
137
138//Utility function that returns the detector resolution (in cm)
139//Global values are set in the Initialize procedure
140//
141// - called by CircSectAvg.ipf, RectAnnulAvg.ipf, and ProtocolAsPanel.ipf
142//
143// fileStr is passed as TextRead[3]
144// detStr is passed as TextRead[9]
145//
146// *** as of Jan 2008, depricated. Now detector pixel sizes are read from the file header
147// rw[10] = x size (mm); rw[13] = y size (mm)
148//
149// depricated - pixel dimensions are read directly from the file header
150Function xDetectorPixelResolution(fileStr,detStr)
151        String fileStr,detStr
152       
153        Variable DDet
154
155        //your code here
156       
157        return(DDet)
158End
159
160//Utility function that returns the detector deadtime (in seconds)
161//Global values are set in the Initialize procedure
162//
163// - called by WorkFileUtils.ipf
164//
165// fileStr is passed as TextRead[3] and is the filename
166// detStr is passed as TextRead[9] and is an identifier for the detector
167//
168Function DetectorDeadtime(fileStr,detStr)
169        String fileStr,detStr
170       
171        // [davidm]
172        nvar DeadtimeDefault = root:myGlobals:DeadtimeDefault
173
174        return DeadtimeDefault
175       
176End
177
178//given a filename of a SANS data filename of the form
179//QKKNNNNNNN.nx.hdf
180//returns the prefix
181Function/S GetPrefixStrFromFile(item)
182        String item
183        String invalid = ""     //"" is not a valid run prefix, since it's text
184        Variable num=-1
185       
186        //find the "dot"
187        String runStr=""
188       
189        Variable pos = strsearch(item,".",0)
190        if(pos == -1)
191                //"dot" not found
192                return (invalid)
193        else
194                //found, skip the three characters preceeding it
195                if (pos <=7)
196                        //not enough characters
197                        return (invalid)
198                else
199                        runStr = item[0,pos-8]
200                        return (runStr)
201                Endif
202        Endif
203End
204
205Function/S RunDigitString(num)
206        Variable num
207       
208        String numStr=""
209
210        //make 7 digit string from run number
211        sprintf numStr,"%07u",num
212       
213        //Print "numstr = ",numstr
214        return(numstr)
215End
216
217// item is a filename
218//
219// this function extracts some sort of number from the file
220// presumably some sort of automatically incrementing run number set by the
221// acquisition system
222//
223// this run number should be a unique identifier for the file
224//
225Function GetRunNumFromFile(item)
226        String item
227
228        Variable invalid = -1
229        Variable num=-1         // an invalid return value
230       
231        String runStr=""
232        Variable pos = strsearch(item,".",0)
233        if(pos == -1)
234                //"dot" not found
235                return (invalid)
236        else
237                //found, get the three characters preceeding it
238                if (pos <=6)
239                        //not enough characters
240                        return (invalid)
241                else
242                        runStr = item[pos-7,pos-1]
243                        //convert to a number
244                        num = str2num(runStr)
245                        //if valid, return it
246                        //if (num == NaN) // will always be false [davidm]
247                        if(numtype(num) == 2)
248                                //3 characters were not a number
249                                return (invalid)
250                        else
251                                //run was OK
252                                return (num)
253                        Endif
254                Endif
255        Endif   
256        return (num)
257End
258
259// item is a filename
260//
261// this function extracts some sort of number from the file
262// presumably some sort of automatically incrementing run number set by the
263// acquisition system
264//
265// this run number should be a unique identifier for the file
266//
267// same as GetRunNumFromFile(0), just with a string return
268//
269// "ABC" returned as an invalid result
270Function/S GetRunNumStrFromFile(item)
271        String item
272       
273        String invalid = "ABC"  //"ABC" is not a valid run number, since it's text
274        String retStr
275        retStr=invalid
276       
277        String runStr = ""
278        Variable pos = strsearch(item,".",0)
279        if(pos == -1)
280                //"dot" not found
281                return (invalid)
282        else
283                //found, get the three characters preceeding it
284                if (pos <=6)
285                        //not enough characters
286                        return (invalid)
287                else
288                        runStr = item[pos-7,pos-1]
289                        return (runStr)
290                Endif
291        Endif
292End
293
294//returns a string containing the full path to the file containing the
295//run number "num". The null string is returned if no valid file can be found.
296//
297//
298// search in the path "catPathName" (hard-wired), will abort if this path does not exist
299//the file returned will be a RAW SANS data file, other types of files are
300//filtered out.
301//
302// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
303//
304Function/S FindFileFromRunNumber(num)
305        Variable num
306       
307        String fullName="",partialName="",item="",numStr=""
308       
309        //make sure that path exists
310        PathInfo catPathName
311        String path = S_path
312        if (V_flag == 0)
313                Abort "folder path does not exist - use Pick Path button"
314        Endif
315
316        //make 7 digit string from run number
317        sprintf numStr,"%07u",num
318
319        //partialname = "QKK"+tmp_num+".nx.hdf"
320
321        String list="",newList="",testStr=""
322
323        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
324        //find (the) one with the number in the run # location in the name
325        Variable numItems,ii,runFound,isRAW
326        numItems = ItemsInList(list,";")                //get the new number of items in the list
327        ii=0
328        do
329                //parse through the list in this order:
330                // 1 - does item contain run number (as a string) "QKKXXXXXXX.nx.hdf"
331                // 2 - exclude by isRaw? (to minimize disk access)
332                item = StringFromList(ii, list  ,";" )
333                if(strlen(item) != 0)
334                        //find the run number, if it exists as a three character string
335                        testStr = GetRunNumStrFromFile(item)
336                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
337                        if(runFound == 0)
338                                //the run Number was found
339                                //build valid filename
340                                partialName = FindValidFileName(item)
341                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
342                                        fullName = path + partialName
343                                        //check if RAW, if so,this must be the file!
344                                        isRAW = CheckIfRawData(fullName)
345                                        if(isRaw)
346                                                //stop here
347                                                return(fullname)
348                                        Endif
349                                Endif
350                        Endif
351                Endif
352                ii+=1
353        while(ii<numItems)              //process all items in list
354        Return ("")     //null return if file not found in list
355End
356
357//function to test a file to see if it is a RAW SANS file
358//
359// returns truth 0/1
360//
361// called by many procedures (both external and local)
362//
363Function CheckIfRawData(fname)
364        String fname
365        Variable value = 0
366       
367        Variable hdfID,hdfgID
368        Variable isNXHDF = 0
369       
370        //nha. look for non-NeXus files
371        if (strsearch(fname, "nx.hdf", 0) >= 0)
372                isNXHDF = 1
373        endif
374
375        if(isNXHDF == 1)
376                //Need to actually determine if file is RAW data.
377                HDF5OpenFile/Z hdfID as fname
378                HDF5OpenGroup/Z hdfID, "/data", hdfgID
379                if (V_Flag == 0)
380                        //DIV file (with nx.hdf suffix)
381                        value = 0
382                else
383                        //Some other nx.hdf file
384                        value = 1
385                endif
386                HDF5CloseGroup/Z hdfgID
387                HDF5CloseFile/Z hdfID
388        else
389                value = 0
390        endif
391       
392        return(value)
393End
394
395Function CheckIfFileExists(fname)
396        String fname
397       
398        GetFileFolderInfo /Z/Q fname
399
400        return V_Flag == 0
401
402End
403
404Function isScatFile(fname)
405        String fname
406        Variable isTrans, isEmp
407        Variable value =1
408       
409        isTrans = isTransFile(fname)
410        isEmp = isEmpFile(fname)
411       
412        if(isTrans)
413                value = 0
414        endif
415        if(isEmp)
416                value = 0
417        endif
418        return(value)
419End
420
421Function isEmpFile(fName)
422        String fname
423
424        variable err
425        string dfName = ""
426        variable value = 0
427       
428        err = hdfRead(fname, dfName)
429        //err not handled here
430
431        Wave/T wSampleName = $(dfName+":sample:name")
432        String sampleName = wSampleName[0]
433       
434        if (cmpstr(sampleName,"MT beam")==0)
435                value = 1
436        endif
437       
438        return(value)
439End
440
441
442// function returns 1 if file is a transmission file, 0 if not
443//
444// called by Transmission.ipf, CatVSTable.ipf, NSORT.ipf
445//
446Function isTransFile(fName)
447        String fname
448
449// nha. TO DO. entry1 will have to change when the new naming convention for nxentry is implemented.
450
451        variable err
452        string dfName = ""
453        variable value = 0
454
455        // [davidm]
456        hdfReadSimulated(fname, dfName)
457        if (exists(dfName+":sample:TransmissionFlag") != 1)
458                err = hdfRead(fname, dfName)
459                //err not handled here
460        endif
461
462        Wave wTransmission_Flag = $(dfName+":sample:TransmissionFlag") //is only being set after 27/5/2009. ???
463       
464        if (WaveExists(wTransmission_Flag))
465                value = wTransmission_Flag[0]
466        else
467                print "Can't find Transmission Flag in " + fname
468        endif
469//     
470//   AJJ June 2nd 2010 - Unclear that this check is correct. Certainly BSPosXmm is not correct parameter in current data format...
471//      if (value == 0)
472//      //workaround - determine by bsx position
473//      Wave wBSX = $(dfName+":instrument:beam_stop:geometry:position:BSPosXmm")
474//      variable bsx = wBSX[0]
475//             
476//              if (bsx >= -10 )
477//                      value = 1
478//              endif
479//      endif
480
481        return(value)
482End
483
484
485//function to remove all spaces from names when searching for filenames
486//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
487//but the text field in the header may
488//
489//returns a string identical to the original string, except with the interior spaces removed
490//
491// local function for file name manipulation
492//
493// no change needed here
494Function/S RemoveAllSpaces(str)
495        String str
496       
497        String tempstr = str
498        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
499        ii=0
500        do
501                len = strlen(tempStr)
502                spc = strsearch(tempStr," ",0)          //is the last character a space?
503                if (spc == -1)
504                        break           //no more spaces found, get out
505                endif
506                str = tempstr
507                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
508        While(1)        //should never be more than 2 or 3
509       
510        If(strlen(tempStr) < 1)
511                tempStr = ""            //be sure to return a null string if problem found
512        Endif
513       
514        //Print strlen(tempstr)
515       
516        Return(tempStr)
517               
518End
519
520
521//Function attempts to find valid filename from partial name by checking for
522// the existence of the file on disk
523//
524// returns a valid filename (No path prepended) or a null string
525//
526// called by any functions, both external and local
527//
528Function/S FindValidFilename(partialName)
529        String PartialName
530
531        // [davidm] if partialName only contains a number, then the filename is generated
532        variable num = str2num(partialName)
533        Variable i, err = numtype(num) != 0
534       
535        if (!err)
536                for (i = 0; i != strlen(partialName); i = i + 1)
537                        if (numtype(str2num(partialName[i])) != 0)
538                                err = 1
539                                break
540                        endif
541                endfor
542        endif
543       
544        if (!err)
545                PartialName = "QKK" + RunDigitString(num) + ".nx.hdf"
546        endif
547       
548        return PartialName             
549End
550
551
552//returns a string containing filename (WITHOUT the ;vers)
553//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
554//with the folders separated by colons
555//
556// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
557//
558// NEEDS NO CHANGES
559//
560Function/S GetFileNameFromPathNoSemi(fullPath)
561        String fullPath
562       
563        Variable offset1,offset2
564        String filename=""
565        //String PartialPath
566        offset1 = 0
567        do
568                offset2 = StrSearch(fullPath, ":", offset1)
569                if (offset2 == -1)                              // no more colons ?
570                        fileName = FullPath[offset1,strlen(FullPath) ]
571                        //PartialPath = FullPath[0, offset1-1]
572                        break
573                endif
574                offset1 = offset2+1
575        while (1)
576       
577        //remove version number from name, if it's there - format should be: filename;N
578        filename =  StringFromList(0,filename,";")              //returns null if error
579       
580        Return filename
581End
582
583//returns a string containing filename (INCLUDING the ;vers)
584//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
585//with the folders separated by colons
586//
587// local, currently unused
588//
589// NEEDS NO CHANGES
590//
591Function/S GetFileNameFromPathKeepSemi(fullPath)
592        String fullPath
593       
594        Variable offset1,offset2
595        String filename
596        //String PartialPath
597        offset1 = 0
598        do
599                offset2 = StrSearch(fullPath, ":", offset1)
600                if (offset2 == -1)                              // no more colons ?
601                        fileName = FullPath[offset1,strlen(FullPath) ]
602                        //PartialPath = FullPath[0, offset1-1]
603                        break
604                endif
605                offset1 = offset2+1
606        while (1)
607       
608        //keep version number from name, if it's there - format should be: filename;N
609       
610        Return filename
611End
612
613//given the full path and filename (fullPath), strips the data path
614//(Mac-style, separated by colons) and returns this path
615//this partial path is the same string that would be returned from PathInfo, for example
616//
617// - allows the user to save to a different path than catPathName
618//
619// called by WriteQIS.ipf
620//
621// NEEDS NO CHANGES
622//
623Function/S GetPathStrFromfullName(fullPath)
624        String fullPath
625       
626        Variable offset1,offset2
627        //String filename
628        String PartialPath
629        offset1 = 0
630        do
631                offset2 = StrSearch(fullPath, ":", offset1)
632                if (offset2 == -1)                              // no more colons ?
633                        //fileName = FullPath[offset1,strlen(FullPath) ]
634                        PartialPath = FullPath[0, offset1-1]
635                        break
636                endif
637                offset1 = offset2+1
638        while (1)
639       
640        Return PartialPath
641End
642
643//given the filename trim or modify the filename to get a new
644//file string that can be used for naming averaged 1-d files
645//
646// called by ProtocolAsPanel.ipf and Tile_2D.ipf
647//
648Function/S GetNameFromHeader(fullName)
649// given the fully qualified path and filename ie. fullName, return just the filename
650        String fullName
651        String newName = ""
652
653        //your code here
654        newName = ParseFilePath(0, fullName, ":", 1, 0)
655
656        Return(newName)
657End
658
659//list (input) is a list, typically returned from IndexedFile()
660//which is semicolon-delimited, and may contain filenames from the VAX
661//that contain version numbers, where the version number appears as a separate list item
662//(and also as a non-existent file)
663//these numbers must be purged from the list, especially for display in a popup
664//or list processing of filenames
665//the function returns the list, cleaned of version numbers (up to 11)
666//raw data files will typically never have a version number other than 1.
667//
668// if there are no version numbers in the list, the input list is returned
669//
670// called by CatVSTable.ipf, NSORT.ipf, Transmission.ipf, WorkFileUtils.ipf
671//
672//
673// NO CHANGE NEEDED
674//
675Function/S RemoveVersNumsFromList(list)
676        String list
677       
678        //get rid of version numbers first (up to 11)
679        Variable ii,num
680        String item
681        num = ItemsInList(list,";")
682        ii=1
683        do
684                item = num2str(ii)
685                list = RemoveFromList(item, list ,";" )
686                ii+=1
687        while(ii<12)
688       
689        return (list)
690End
691
692//input is a list of run numbers, and output is a list of filenames (not the full path)
693//*** input list must be COMMA delimited***
694//output is equivalent to selecting from the CAT table
695//if some or all of the list items are valid filenames, keep them...
696//if an error is encountered, notify of the offending element and return a null list
697//
698//output is COMMA delimited
699//
700// this routine is expecting that the "ask", "none" special cases are handled elsewhere
701//and not passed here
702//
703// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
704//
705// NO CHANGE NEEDED
706//
707Function/S ParseRunNumberList(list)
708        String list
709       
710        String newList="",item="",tempStr=""
711        Variable num,ii,runNum
712       
713        //expand number ranges, if any
714        list = ExpandNumRanges(list)
715       
716        num=itemsinlist(list,",")
717       
718        for(ii=0;ii<num;ii+=1)
719                //get the item
720                item = StringFromList(ii,list,",")
721
722                tempStr=FindValidFilename(item) //returns filename if good, null if error
723               
724                if(strlen(tempstr)!=0)
725                        //valid name, add to list
726                        //Print "it's a file"
727                                if(strlen(newList)==0)
728                                        newList = tempStr
729                                else
730                                        newList += "," + tempStr
731                                endif           
732                        else
733                        //not a valid name
734                        //is it a number?
735                        runNum=str2num(item)
736                        //print runnum
737                        if(numtype(runNum) != 0)
738                                //not a number -  maybe an error                       
739                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
740                                return("")
741                        else
742                                //a run number or an error
743                                tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) )
744                                if(strlen(tempstr)==0)
745                                        //file not found, error
746                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
747                                        return("")
748                                else
749                                        newList += tempStr + ","
750                                endif
751                        endif
752                endif
753        endfor          //loop over all items in list
754       
755        return(newList)
756End
757
758//takes a comma delimited list that MAY contain number range, and
759//expands any range of run numbers into a comma-delimited list...
760//and returns the new list - if not a range, return unchanged
761//
762// local function
763//
764// NO CHANGE NEEDED
765//
766Function/S ExpandNumRanges(list)
767        String list
768       
769        String newList="",dash="-",item,str
770        Variable num,ii,hasDash
771       
772        num=itemsinlist(list,",")
773//      print num
774        for(ii=0;ii<num;ii+=1)
775                //get the item
776                item = StringFromList(ii,list,",")
777                //does it contain a dash?
778                hasDash = strsearch(item,dash,0)                //-1 if no dash found
779                if(hasDash == -1)
780                        //not a range, keep it in the list
781                        newList += item + ","
782                else
783                        //has a dash (so it's a range), expand (or add null)
784                        newList += ListFromDash(item)           
785                endif
786        endfor
787       
788        return newList
789End
790
791//be sure to add a trailing comma to the return string...
792//
793// local function
794//
795// NO CHANGE NEEDED
796//
797Function/S ListFromDash(item)
798        String item
799       
800        String numList="",loStr="",hiStr=""
801        Variable lo,hi,ii
802       
803        loStr=StringFromList(0,item,"-")        //treat the range as a list
804        hiStr=StringFromList(1,item,"-")
805        lo=str2num(loStr)
806        hi=str2num(hiStr)
807        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
808                numList=""
809                return numList
810        endif
811        for(ii=lo;ii<=hi;ii+=1)
812                numList += num2str(ii) + ","
813        endfor
814       
815        Return numList
816End
817
818
819//returns the proper attenuation factor based on the instrument
820//
821// filestr is passed from TextRead[3] = the default directory, used to identify the instrument
822// lam is passed from RealsRead[26]
823// AttenNo is passed from ReaslRead[3]
824//
825// Attenuation factor as defined here is <= 1
826//
827// Facilities can pass ("",1,attenuationFactor) and have this function simply
828// spit back the attenuationFactor (that was read into rw[3])
829//
830// called by Correct.ipf, ProtocolAsPanel.ipf, Transmission.ipf
831//
832Function AttenuationFactor(fileStr,lam,attenNo)
833       
834        //
835        String fileStr //
836        Variable lam,attenNo
837       
838        Variable attenFactor=1
839
840        // your code here       
841        attenFactor = LookupAtten(lam,attenNo)
842
843        return(attenFactor)
844End
845
846Function LookupAtten(lambda,attenNo)
847        Variable lambda, attenNo
848       
849        Variable trans
850        String attStr="root:myGlobals:Attenuators:att"+num2str(trunc(attenNo))
851        String lamStr = "root:myGlobals:Attenuators:lambda"
852       
853        if(attenNo == 0)
854                return (1)              //no attenuation, return trans == 1
855        endif
856       
857//      if( (lambda < 5) || (lambda > 5 ) )
858//              Abort "Wavelength out of calibration range (5A). You must manually enter the absolute parameters"
859//      Endif
860       
861        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
862                Execute "MakeAttenTable()"
863        Endif
864        //just in case creating the tables fails....
865        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
866                Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters"
867        Endif
868       
869        //lookup the value by interpolating the wavelength
870        //the attenuator must always be an integer
871       
872
873        Wave att = $attStr
874        Wave lam = $lamstr
875        //nha - commented below out until we have attenuation factors over multiple lambda values
876        //trans = interp(lambda,lam,att)
877       
878//      Print "trans = ",trans
879        //nha - delete this line when multiple lambda values
880        trans = att[0]
881       
882        return trans
883End
884
885Proc MakeAttenTable()
886
887        NewDataFolder/O root:myGlobals:Attenuators
888        //do explicitly to avoid data folder problems, redundant, but it must work without fail
889
890        //Quokka specific nha.
891        Variable num=12         
892       
893        Make/O/N=(num) root:myGlobals:Attenuators:att0
894        Make/O/N=(num) root:myGlobals:Attenuators:att1
895        Make/O/N=(num) root:myGlobals:Attenuators:att2
896        Make/O/N=(num) root:myGlobals:Attenuators:att3
897        Make/O/N=(num) root:myGlobals:Attenuators:att4
898        Make/O/N=(num) root:myGlobals:Attenuators:att5
899        Make/O/N=(num) root:myGlobals:Attenuators:att6
900        Make/O/N=(num) root:myGlobals:Attenuators:att7
901        Make/O/N=(num) root:myGlobals:Attenuators:att8
902        Make/O/N=(num) root:myGlobals:Attenuators:att9
903        Make/O/N=(num) root:myGlobals:Attenuators:att10
904        Make/O/N=(num) root:myGlobals:Attenuators:att11
905       
906        // epg
907        // note 5A only at this stage but other wavelengths as measured
908        // these values have to be re-determined as were measured on time and not monitor counts
909        //Make/O/N=(num) root:myGlobals:Attenuators:lambda={5}
910        Make/O/N=(num) root:myGlobals:Attenuators:lambda={4.94}
911
912        //Quokka attenuator factors. 19/1/09 nha
913        //20/3/09 nha updated to
914        //file://fianna/Sections/Bragg/Data_Analysis_Team/Project/P025 Quokka Commissioning DRV/3_Development/ATTest-timeseries.pdf
915        //updated by epg 13-02-2010 to reflect kwo measurements at g7
916       
917//      root:myGlobals:Attenuators:att0 = {1}
918//      root:myGlobals:Attenuators:att1 = {0.498782}
919//      root:myGlobals:Attenuators:att2 = {0.176433}
920//      root:myGlobals:Attenuators:att3 = {0.0761367}
921//      root:myGlobals:Attenuators:att4 = {0.0353985}
922//      root:myGlobals:Attenuators:att5 = {0.0137137}
923//      root:myGlobals:Attenuators:att6 = {0.00614167}
924//      root:myGlobals:Attenuators:att7 = {0.00264554}
925//      root:myGlobals:Attenuators:att8 = {0.000994504}
926//      root:myGlobals:Attenuators:att9 = {0.000358897}
927//      root:myGlobals:Attenuators:att10 = {7.2845e-05}
928//      root:myGlobals:Attenuators:att11 = {1.67827e-06}
929       
930        // [davidm] 19/12/2011 new attenuators
931        root:myGlobals:Attenuators:att0 = {1}
932        root:myGlobals:Attenuators:att1 = {0.493851474862975}
933        root:myGlobals:Attenuators:att2 = {0.172954232066555}
934        root:myGlobals:Attenuators:att3 = {0.0730333204657658}
935        root:myGlobals:Attenuators:att4 = {0.0338860321760628}
936        root:myGlobals:Attenuators:att5 = {0.0123806637881081}
937        root:myGlobals:Attenuators:att6 = {0.00547518298963546}
938        root:myGlobals:Attenuators:att7 = {0.00243389583698184}
939        root:myGlobals:Attenuators:att8 = {0.000833797438995085}
940        root:myGlobals:Attenuators:att9 = {0.000314495412044638}
941        root:myGlobals:Attenuators:att10 = {6.18092704241135e-05}
942        root:myGlobals:Attenuators:att11 = {1.1150347032482e-06}
943
944End
945
946//function called by the popups to get a file list of data that can be sorted
947// this procedure simply removes the raw data files from the string - there
948//can be lots of other junk present, but this is very fast...
949//
950// could also use the alternate procedure of keeping only file with the proper extension
951//
952// another possibility is to get a listing of the text files, but is unreliable on
953// Windows, where the data file must be .txt (and possibly OSX)
954//
955// called by FIT_Ops.ipf, NSORT.ipf, PlotUtils.ipf
956//
957// modify for specific facilities by changing the "*.SA1*","*.SA2*","*.SA3*" stringmatch
958// items which are specific to NCNR
959//
960Function/S ReducedDataFileList(ctrlName)
961        String ctrlName
962
963        String list="",newList="",item=""
964        Variable num,ii
965       
966        //check for the path
967        PathInfo catPathName
968        if(V_Flag==0)
969                DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel"
970                Return("")
971        Endif
972       
973        list = IndexedFile(catpathName,-1,"????")
974        num=ItemsInList(list,";")
975        //print "num = ",num
976        for(ii=(num-1);ii>=0;ii-=1)
977                item = StringFromList(ii, list  ,";")
978                //simply remove all that are not raw data files (SA1 SA2 SA3)
979                if( !stringmatch(item,"*.SA1*") && !stringmatch(item,"*.SA2*") && !stringmatch(item,"*.SA3*") )
980                        if( !stringmatch(item,".*") && !stringmatch(item,"*.pxp") && !stringmatch(item,"*.DIV"))                //eliminate mac "hidden" files, pxp, and div files
981                                newlist += item + ";"
982                        endif
983                endif
984        endfor
985        //remove VAX version numbers
986        newList = RemoveVersNumsFromList(newList)
987        //sort
988        newList = SortList(newList,";",0)
989
990        return newlist
991End
992
993// returns a list of raw data files in the catPathName directory on disk
994// - list is SEMICOLON-delimited
995//
996// called by PatchFiles.ipf, Tile_2D.ipf
997//
998Function/S GetRawDataFileList()
999       
1000        //nha. Reads Quokka file names 5/2/09
1001       
1002        //make sure that path exists
1003        PathInfo catPathName
1004        if (V_flag == 0)
1005                Abort "Folder path does not exist - use Pick Path button on Main Panel"
1006        Endif
1007
1008        String list=IndexedFile(catPathName,-1,"????")
1009        String newList="",item=""
1010        Variable num=ItemsInList(list,";"),ii
1011        for(ii=0;ii<num;ii+=1)
1012                item = StringFromList(ii, list  ,";")
1013                if( stringmatch(item,"*.nx.hdf") )
1014                        newlist += item + ";"
1015                endif
1016                //print "ii=",ii
1017        endfor
1018        newList = SortList(newList,";",0)
1019        return(newList)
1020       
1021        // your code here
1022       
1023        return(list)
1024End
1025
1026//**********************
1027// 2D resolution function calculation - in terms of X and Y
1028//
1029// based on notes from David Mildner, 2008
1030//
1031// the final NCNR version is located in NCNR_Utils.ipf
1032//
1033Function/S get2DResolution(inQ,phi,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,r_dist,SigmaQX,SigmaQY,fSubS)
1034        Variable inQ, phi,lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses,r_dist
1035        Variable &SigmaQX,&SigmaQY,&fSubS               //these are the output quantities at the input Q value
1036       
1037        return("Function Empty")
1038End
1039
1040// Return the filename that represents the previous or next file.
1041// Input is current filename and increment.
1042// Increment should be -1 or 1
1043// -1 => previous file
1044// 1 => next file
1045Function/S GetPrevNextRawFile(curfilename, prevnext)
1046        String curfilename
1047        Variable prevnext
1048
1049        String filename
1050       
1051        //get the run number
1052        Variable num = GetRunNumFromFile(curfilename)
1053               
1054        //find the next specified file by number
1055        fileName = FindFileFromRunNumber(num+prevnext)
1056
1057        if(cmpstr(fileName,"")==0)
1058                //null return, do nothing
1059                fileName = FindFileFromRunNumber(num)
1060        Endif
1061
1062//      print "in FU "+filename
1063
1064        Return filename
1065End
1066
1067//convert a comma delimited runNumberList
1068//e.g. 1234567,2345678
1069// to a comma delimited filename list
1070// e.g. QKK1234567.nx.hdf,QKK2345678.nx.hdf
1071Function/S RunNumberListToFilenameList(runNumberList)
1072        String runNumberList
1073        String filenameList, fileStr, numStr
1074        String item
1075        variable num,ii,runNumber
1076       
1077        filenameList = ""
1078       
1079        num = ItemsInList(runNumberList,",")
1080        ii=0
1081       do
1082                item = StringFromList(ii, runNumberList, ",")
1083                runNumber = str2num(item)
1084                                   
1085                 if (numtype(runNumber) != 0) // error
1086                        fileStr = item
1087                else
1088                        //make 7 digit string from run number
1089                        sprintf numStr ,"%07u", runNumber
1090                        fileStr = "QKK" +  numStr + ".nx.hdf"
1091                endif
1092
1093                //build FilenameList
1094                filenameList = filenameList + fileStr
1095                ii += 1
1096                if (ii<num)
1097                        filenameList = filenameList + ","
1098                endif
1099        while(ii<num)
1100
1101        return filenameList
1102End
1103
1104// [davidm] create CAT Sort-Dialog
1105function BuildCatSortDialog()
1106
1107        // check if CatVSTable exists
1108        DoWindow CatVSTable
1109        if (V_flag==0)
1110                DoAlert 0,"There is no File Catalog table. Use the File Catalog button to create one."
1111                return 0
1112        endif
1113       
1114        // bring CatSortDialog to front
1115        DoWindow/F CatSortDialog
1116        if (V_flag != 0)
1117                return 0
1118        endif
1119       
1120        print "Creating CAT Sort-Dialog..."
1121               
1122        //PauseUpdate
1123        NewPanel /W=(600,360,790,730)/K=1 as "CAT - Sort Dialog"
1124        DoWindow/C CatSortDialog
1125        ModifyPanel fixedSize=1, cbRGB = (42919, 53970, 60909)
1126       
1127        Button SortFilenamesButton,             pos={25, 8},            size={140,24},proc=CatVSTable_SortProc,title="Filenames"
1128        Button SortLabelsButton,                        pos={25,38},            size={140,24},proc=CatVSTable_SortProc,title="Labels"
1129        Button SortDateAndTimeButton,   pos={25,68},            size={140,24},proc=CatVSTable_SortProc,title="Date and Time"
1130        Button SortSSDButton,                   pos={25,98},            size={140,24},proc=CatVSTable_SortProc,title="SSD"
1131        Button SortSDDButton,                   pos={25,128},   size={140,24},proc=CatVSTable_SortProc,title="SDD"
1132        Button SortLambdaButton,                        pos={25,158},   size={140,24},proc=CatVSTable_SortProc,title="Lambda"
1133        Button SortCountTimButton,              pos={25,188},   size={140,24},proc=CatVSTable_SortProc,title="Count Time"
1134        Button SortTotalCountsButton,           pos={25,218},   size={140,24},proc=CatVSTable_SortProc,title="Total Counts"
1135        Button SortCountRateButton,             pos={25,248},   size={140,24},proc=CatVSTable_SortProc,title="Count Rate"
1136        Button SortMonitorCountsButton, pos={25,278},   size={140,24},proc=CatVSTable_SortProc,title="Monitor Counts"
1137        Button SortTransmissionButton,  pos={25,308},   size={140,24},proc=CatVSTable_SortProc,title="Transmission"
1138        Button SortThicknessButton,             pos={25,338},   size={140,24},proc=CatVSTable_SortProc,title="Thickness"
1139
1140end
1141
1142proc CatVSTable_SortProc(ctrlName) : ButtonControl // added by [davidm]
1143        String ctrlName
1144       
1145        // check if CatVSTable exists
1146        DoWindow CatVSTable
1147        if (V_flag==0)
1148                DoAlert 0,"There is no File Catalog table. Use the File Catalog button to create one."
1149                return
1150        endif
1151               
1152        // have to use function
1153        CatVSTable_SortFunction(ctrlName)
1154       
1155end
1156
1157function CatVSTable_SortFunction(ctrlName) // added by [davidm]
1158        String ctrlName
1159
1160        Wave/T GFilenames = $"root:myGlobals:CatVSHeaderInfo:Filenames"
1161        Wave/T GSuffix = $"root:myGlobals:CatVSHeaderInfo:Suffix"
1162        Wave/T GLabels = $"root:myGlobals:CatVSHeaderInfo:Labels"
1163        Wave/T GDateTime = $"root:myGlobals:CatVSHeaderInfo:DateAndTime"
1164        Wave GSDD = $"root:myGlobals:CatVSHeaderInfo:SDD"
1165        Wave GLambda = $"root:myGlobals:CatVSHeaderInfo:Lambda"
1166        Wave GCntTime = $"root:myGlobals:CatVSHeaderInfo:CntTime"
1167        Wave GTotCnts = $"root:myGlobals:CatVSHeaderInfo:TotCnts"
1168        Wave GCntRate = $"root:myGlobals:CatVSHeaderInfo:CntRate"
1169        Wave GMonCnts = $"root:myGlobals:CatVSHeaderInfo:MonCnts"
1170        Wave GTransmission = $"root:myGlobals:CatVSHeaderInfo:Transmission"
1171        Wave GThickness = $"root:myGlobals:CatVSHeaderInfo:Thickness"
1172        Wave GXCenter = $"root:myGlobals:CatVSHeaderInfo:XCenter"
1173        Wave GYCenter = $"root:myGlobals:CatVSHeaderInfo:YCenter"
1174        Wave/B GNumGuides = $"root:myGlobals:CatVSHeaderInfo:nGuides"
1175        Wave/B GNumAttens = $"root:myGlobals:CatVSHeaderInfo:NumAttens"
1176        Wave GRunNumber = $"root:myGlobals:CatVSHeaderInfo:RunNumber"
1177        Wave GIsTrans = $"root:myGlobals:CatVSHeaderInfo:IsTrans"
1178        Wave GRot = $"root:myGlobals:CatVSHeaderInfo:RotAngle"
1179        Wave GTemp = $"root:myGlobals:CatVSHeaderInfo:Temperature"
1180        Wave GField = $"root:myGlobals:CatVSHeaderInfo:Field"
1181        Wave GMCR = $"root:myGlobals:CatVSHeaderInfo:MCR"
1182        Wave GPos = $"root:myGlobals:CatVSHeaderInfo:Pos"
1183        Wave/Z GReactPow = $"root:myGlobals:CatVSHeaderInfo:ReactorPower"
1184        //For ANSTO
1185        Wave GSSD = $"root:myGlobals:CatVSHeaderInfo:SSD"
1186        Wave/T GSICS = $"root:myGlobals:CatVSHeaderInfo:SICS"
1187        Wave/T GHDF = $"root:myGlobals:CatVSHeaderInfo:HDF"
1188       
1189        // take out the "not-RAW-Files"
1190        Variable fileCount = numpnts(GFilenames)
1191        Variable rawCount = numpnts(GLabels)
1192        Variable notRAWcount = fileCount - rawCount
1193       
1194        if (notRAWcount > 0)
1195                Make/T/O/N=(notRAWcount) notRAWlist
1196                notRAWlist[0, notRAWcount-1] = GFilenames[p+rawCount]
1197                DeletePoints rawCount, notRAWcount, GFilenames
1198        endif
1199       
1200        strswitch (ctrlName)
1201       
1202                case "SortFilenamesButton":
1203                        Sort GFilenames, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1204                        break
1205                       
1206                case "SortLabelsButton":
1207                        Sort GLabels, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1208                        break
1209                       
1210                case "SortDateAndTimeButton":
1211                        Sort GDateTime, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1212                        break
1213                       
1214                case "SortSSDButton":
1215                        Sort GSSD, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1216                        break
1217                       
1218                case "SortSDDButton":
1219                        Sort GSDD, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1220                        break
1221                       
1222                case "SortLambdaButton":
1223                        Sort GLambda, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1224                        break
1225                       
1226                case "SortCountTimButton":
1227                        Sort GCntTime, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1228                        break
1229                       
1230                case "SortTotalCountsButton":
1231                        Sort GTotCnts, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1232                        break
1233                       
1234                case "SortCountRateButton":
1235                        Sort GCntRate, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1236                        break
1237                       
1238                case "SortMonitorCountsButton":
1239                        Sort GMonCnts, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1240                        break
1241                       
1242                case "SortTransmissionButton":
1243                        Sort GTransmission, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1244                        break
1245                       
1246                case "SortThicknessButton":
1247                        Sort GThickness, GSuffix, GFilenames, GLabels, GDateTime, GSSD, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GMonCnts, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens, GRunNumber, GIsTrans, GRot, GTemp, GField, GMCR, GSICS, GHDF
1248                        break
1249       
1250        endswitch
1251       
1252        // insert the "not-RAW-Files" again
1253        if (notRAWcount > 0)
1254                InsertPoints rawCount, notRAWcount, GFilenames
1255                GFilenames[rawCount, fileCount-1] = notRAWlist[p-rawCount]
1256        endif
1257end
Note: See TracBrowser for help on using the repository browser.