source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/FACILITY_Utils.ipf @ 572

Last change on this file since 572 was 572, checked in by srkline, 13 years ago

Merging changes:

NCNR_Utils -> merging these into FACILITY, HFIR, and ILL_Utils

HFIR files merged by hand to reflect JaeHie?'s 29JUL09 version

Changed MainPanel? to look for TISANE or RealTime? functions to prevent button procedures from being called when the procedures aren't there. Seemed easier than separate versions without the buttons. #define at the begining of TISANE.ipf -> #ifdef in MainPanel? didn't work for some reason?

File size: 18.2 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                                 // number of X and Y pixels
24        Variable/G root:myGlobals:gNPixelsY=128
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 = 3.4e-6              //deadtime in seconds
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                v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2         //correction to 2nd term
96        else
97                v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2              //original form
98        endif
99       
100        v_d = (DDet/2.3548)^2 + del_r^2/12.0
101        vz = vz_1 / lambda
102        yg = 0.5*g*L2*(L1+L2)/vz^2
103        v_g = 2.0*(2.0*yg^2*v_lambda)                                   //factor of 2 correction, B. Hammouda, 2007
104
105        r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) ))
106        delta = 0.5*(BS - r0)^2/v_d
107
108        if (r0 < BS)
109                inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta))
110        else
111                inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta))
112        endif
113
114        fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) )
115        if (fSubS <= 0.0)
116                fSubS = 1.e-10
117        endif
118        fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi))
119        fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d
120
121        rmd = fr*r0
122        v_r1 = v_b + fv*v_d +v_g
123
124        rm = rmd + 0.5*v_r1/rmd
125        v_r = v_r1 - 0.5*(v_r1/rmd)^2
126        if (v_r < 0.0)
127                v_r = 0.0
128        endif
129        QBar = (4.0*Pi/lambda)*sin(0.5*atan(rm/L2))
130        SigmaQ = QBar*sqrt(v_r/rmd^2 +v_lambda)
131
132        results = "success"
133        Return results
134End
135
136
137//Utility function that returns the detector resolution (in cm)
138//Global values are set in the Initialize procedure
139//
140// - called by CircSectAvg.ipf, RectAnnulAvg.ipf, and ProtocolAsPanel.ipf
141//
142// fileStr is passed as TextRead[3] and is the filename
143// detStr is passed as TextRead[9] and is an identifier for the detector
144//
145// depricated - pixel dimensions are read directly from the file header
146Function xDetectorPixelResolution(fileStr,detStr)
147        String fileStr,detStr
148       
149        Variable DDet
150
151        //your code here
152       
153        return(DDet)
154End
155
156//Utility function that returns the detector deadtime (in seconds)
157//Global values are set in the Initialize procedure
158//
159// - called by WorkFileUtils.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//
164Function DetectorDeadtime(fileStr,detStr)
165        String fileStr,detStr
166       
167        Variable deadtime
168       
169// your code here
170
171        return(deadtime)
172End
173
174
175// item is a filename
176//
177// this function extracts some sort of number from the file
178// presumably some sort of automatically incrementing run number set by the
179// acquisition system
180//
181// this run number should be a unique identifier for the file
182//
183Function GetRunNumFromFile(item)
184        String item
185
186        Variable num=-1         // an invalid return value
187       
188        //your code here
189       
190        return (num)
191End
192
193// item is a filename
194//
195// this function extracts some sort of number from the file
196// presumably some sort of automatically incrementing run number set by the
197// acquisition system
198//
199// this run number should be a unique identifier for the file
200//
201// same as GetRunNumFromFile(0), just with a string return
202//
203// "ABC" returned as an invalid result
204Function/S GetRunNumStrFromFile(item)
205        String item
206       
207        String invalid = "ABC"  //"ABC" is not a valid run number, since it's text
208        String retStr
209        retStr=invalid
210       
211        //your code here
212       
213        return(retStr)
214End
215
216//returns a string containing the full path to the file containing the
217//run number "num". The null string is returned if no valid file can be found.
218//
219//
220// search in the path "catPathName" (hard-wired), will abort if this path does not exist
221//the file returned will be a RAW SANS data file, other types of files are
222//filtered out.
223//
224// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
225//
226Function/S FindFileFromRunNumber(num)
227        Variable num
228       
229        String fullName="",partialName="",item=""
230       
231        //make sure that path exists
232        PathInfo catPathName
233        String path = S_path
234        if (V_flag == 0)
235                Abort "folder path does not exist - use Pick Path button"
236        Endif
237
238        //your code here       
239
240        return(fullname)
241       
242End
243
244//function to test a file to see if it is a RAW SANS file
245//
246// returns truth 0/1
247//
248// called by many procedures (both external and local)
249//
250Function CheckIfRawData(fname)
251        String fname
252       
253
254//      if(your test here)
255//              //true, is raw data file
256//              Return(1)
257//      else
258//              //some other file
259//              Return(0)
260//      Endif
261
262End
263
264
265// function returns 1 if file is a transmission file, 0 if not
266//
267// called by Transmission.ipf, CatVSTable.ipf, NSORT.ipf
268//
269Function isTransFile(fName)
270        String fname
271       
272//      if(your test here)
273//              //yes, its a transmisison file
274//              Return(1)
275//      else
276//              //some other file
277//              Return(0)
278//      Endif
279End
280
281
282//function to remove all spaces from names when searching for filenames
283//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
284//but the text field in the header may
285//
286//returns a string identical to the original string, except with the interior spaces removed
287//
288// local function for file name manipulation
289//
290// no change needed here
291Function/S RemoveAllSpaces(str)
292        String str
293       
294        String tempstr = str
295        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
296        ii=0
297        do
298                len = strlen(tempStr)
299                spc = strsearch(tempStr," ",0)          //is the last character a space?
300                if (spc == -1)
301                        break           //no more spaces found, get out
302                endif
303                str = tempstr
304                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
305        While(1)        //should never be more than 2 or 3
306       
307        If(strlen(tempStr) < 1)
308                tempStr = ""            //be sure to return a null string if problem found
309        Endif
310       
311        //Print strlen(tempstr)
312       
313        Return(tempStr)
314               
315End
316
317
318//Function attempts to find valid filename from partial name by checking for
319// the existence of the file on disk
320//
321// returns a valid filename (No path prepended) or a null string
322//
323// called by any functions, both external and local
324//
325Function/S FindValidFilename(partialName)
326        String PartialName
327       
328        String retStr=""
329       
330        //your code here
331       
332        return(retStr)
333End
334
335
336//returns a string containing filename (WITHOUT the ;vers)
337//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
338//with the folders separated by colons
339//
340// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
341//
342// NEEDS NO CHANGES
343//
344Function/S GetFileNameFromPathNoSemi(fullPath)
345        String fullPath
346       
347        Variable offset1,offset2
348        String filename=""
349        //String PartialPath
350        offset1 = 0
351        do
352                offset2 = StrSearch(fullPath, ":", offset1)
353                if (offset2 == -1)                              // no more colons ?
354                        fileName = FullPath[offset1,strlen(FullPath) ]
355                        //PartialPath = FullPath[0, offset1-1]
356                        break
357                endif
358                offset1 = offset2+1
359        while (1)
360       
361        //remove version number from name, if it's there - format should be: filename;N
362        filename =  StringFromList(0,filename,";")              //returns null if error
363       
364        Return filename
365End
366
367//returns a string containing filename (INCLUDING the ;vers)
368//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
369//with the folders separated by colons
370//
371// local, currently unused
372//
373// NEEDS NO CHANGES
374//
375Function/S GetFileNameFromPathKeepSemi(fullPath)
376        String fullPath
377       
378        Variable offset1,offset2
379        String filename
380        //String PartialPath
381        offset1 = 0
382        do
383                offset2 = StrSearch(fullPath, ":", offset1)
384                if (offset2 == -1)                              // no more colons ?
385                        fileName = FullPath[offset1,strlen(FullPath) ]
386                        //PartialPath = FullPath[0, offset1-1]
387                        break
388                endif
389                offset1 = offset2+1
390        while (1)
391       
392        //keep version number from name, if it's there - format should be: filename;N
393       
394        Return filename
395End
396
397//given the full path and filename (fullPath), strips the data path
398//(Mac-style, separated by colons) and returns this path
399//this partial path is the same string that would be returned from PathInfo, for example
400//
401// - allows the user to save to a different path than catPathName
402//
403// called by WriteQIS.ipf
404//
405// NEEDS NO CHANGES
406//
407Function/S GetPathStrFromfullName(fullPath)
408        String fullPath
409       
410        Variable offset1,offset2
411        //String filename
412        String PartialPath
413        offset1 = 0
414        do
415                offset2 = StrSearch(fullPath, ":", offset1)
416                if (offset2 == -1)                              // no more colons ?
417                        //fileName = FullPath[offset1,strlen(FullPath) ]
418                        PartialPath = FullPath[0, offset1-1]
419                        break
420                endif
421                offset1 = offset2+1
422        while (1)
423       
424        Return PartialPath
425End
426
427//given the filename trim or modify the filename to get a new
428//file string that can be used for naming averaged 1-d files
429//
430// called by ProtocolAsPanel.ipf and Tile_2D.ipf
431//
432Function/S GetNameFromHeader(fullName)
433        String fullName
434        String newName = ""
435
436        //your code here
437       
438        Return(newName)
439End
440
441//list (input) is a list, typically returned from IndexedFile()
442//which is semicolon-delimited, and may contain filenames from the VAX
443//that contain version numbers, where the version number appears as a separate list item
444//(and also as a non-existent file)
445//these numbers must be purged from the list, especially for display in a popup
446//or list processing of filenames
447//the function returns the list, cleaned of version numbers (up to 11)
448//raw data files will typically never have a version number other than 1.
449//
450// if there are no version numbers in the list, the input list is returned
451//
452// called by CatVSTable.ipf, NSORT.ipf, Transmission.ipf, WorkFileUtils.ipf
453//
454//
455// NO CHANGE NEEDED
456//
457Function/S RemoveVersNumsFromList(list)
458        String list
459       
460        //get rid of version numbers first (up to 11)
461        Variable ii,num
462        String item
463        num = ItemsInList(list,";")
464        ii=1
465        do
466                item = num2str(ii)
467                list = RemoveFromList(item, list ,";" )
468                ii+=1
469        while(ii<12)
470       
471        return (list)
472End
473
474//input is a list of run numbers, and output is a list of filenames (not the full path)
475//*** input list must be COMMA delimited***
476//output is equivalent to selecting from the CAT table
477//if some or all of the list items are valid filenames, keep them...
478//if an error is encountered, notify of the offending element and return a null list
479//
480//output is COMMA delimited
481//
482// this routine is expecting that the "ask", "none" special cases are handled elsewhere
483//and not passed here
484//
485// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
486//
487// NO CHANGE NEEDED
488//
489Function/S ParseRunNumberList(list)
490        String list
491       
492        String newList="",item="",tempStr=""
493        Variable num,ii,runNum
494       
495        //expand number ranges, if any
496        list = ExpandNumRanges(list)
497       
498        num=itemsinlist(list,",")
499       
500        for(ii=0;ii<num;ii+=1)
501                //get the item
502                item = StringFromList(ii,list,",")
503                //is it already a valid filename?
504                tempStr=FindValidFilename(item) //returns filename if good, null if error
505                if(strlen(tempstr)!=0)
506                        //valid name, add to list
507                        //Print "it's a file"
508                        newList += tempStr + ","
509                else
510                        //not a valid name
511                        //is it a number?
512                        runNum=str2num(item)
513                        //print runnum
514                        if(numtype(runNum) != 0)
515                                //not a number -  maybe an error                       
516                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
517                                return("")
518                        else
519                                //a run number or an error
520                                tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) )
521                                if(strlen(tempstr)==0)
522                                        //file not found, error
523                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
524                                        return("")
525                                else
526                                        newList += tempStr + ","
527                                endif
528                        endif
529                endif
530        endfor          //loop over all items in list
531       
532        return(newList)
533End
534
535//takes a comma delimited list that MAY contain number range, and
536//expands any range of run numbers into a comma-delimited list...
537//and returns the new list - if not a range, return unchanged
538//
539// local function
540//
541// NO CHANGE NEEDED
542//
543Function/S ExpandNumRanges(list)
544        String list
545       
546        String newList="",dash="-",item,str
547        Variable num,ii,hasDash
548       
549        num=itemsinlist(list,",")
550//      print num
551        for(ii=0;ii<num;ii+=1)
552                //get the item
553                item = StringFromList(ii,list,",")
554                //does it contain a dash?
555                hasDash = strsearch(item,dash,0)                //-1 if no dash found
556                if(hasDash == -1)
557                        //not a range, keep it in the list
558                        newList += item + ","
559                else
560                        //has a dash (so it's a range), expand (or add null)
561                        newList += ListFromDash(item)           
562                endif
563        endfor
564       
565        return newList
566End
567
568//be sure to add a trailing comma to the return string...
569//
570// local function
571//
572// NO CHANGE NEEDED
573//
574Function/S ListFromDash(item)
575        String item
576       
577        String numList="",loStr="",hiStr=""
578        Variable lo,hi,ii
579       
580        loStr=StringFromList(0,item,"-")        //treat the range as a list
581        hiStr=StringFromList(1,item,"-")
582        lo=str2num(loStr)
583        hi=str2num(hiStr)
584        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
585                numList=""
586                return numList
587        endif
588        for(ii=lo;ii<=hi;ii+=1)
589                numList += num2str(ii) + ","
590        endfor
591       
592        Return numList
593End
594
595
596//returns the proper attenuation factor based on the instrument
597//
598// filestr is passed from TextRead[3] = the default directory, used to identify the instrument
599// lam is passed from RealsRead[26]
600// AttenNo is passed from ReaslRead[3]
601//
602// Attenuation factor as defined here is <= 1
603//
604// Facilities can pass ("",1,attenuationFactor) and have this function simply
605// spit back the attenuationFactor (that was read into rw[3])
606//
607// called by Correct.ipf, ProtocolAsPanel.ipf, Transmission.ipf
608//
609Function AttenuationFactor(fileStr,lam,attenNo)
610        String fileStr
611        Variable lam,attenNo
612       
613        Variable attenFactor=1
614       
615        // your code here
616
617        return(attenFactor)
618End
619
620//function called by the popups to get a file list of data that can be sorted
621// this procedure simply removes the raw data files from the string - there
622//can be lots of other junk present, but this is very fast...
623//
624// could also use the alternate procedure of keeping only file with the proper extension
625//
626// another possibility is to get a listing of the text files, but is unreliable on
627// Windows, where the data file must be .txt (and possibly OSX)
628//
629// called by FIT_Ops.ipf, NSORT.ipf, PlotUtils.ipf
630//
631// modify for specific facilities by changing the "*.SA1*","*.SA2*","*.SA3*" stringmatch
632// items which are specific to NCNR
633//
634Function/S ReducedDataFileList(ctrlName)
635        String ctrlName
636
637        String list="",newList="",item=""
638        Variable num,ii
639       
640        //check for the path
641        PathInfo catPathName
642        if(V_Flag==0)
643                DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel"
644                Return("")
645        Endif
646       
647        list = IndexedFile(catpathName,-1,"????")
648        num=ItemsInList(list,";")
649        //print "num = ",num
650        for(ii=(num-1);ii>=0;ii-=1)
651                item = StringFromList(ii, list  ,";")
652                //simply remove all that are not raw data files (SA1 SA2 SA3)
653                if( !stringmatch(item,"*.SA1*") && !stringmatch(item,"*.SA2*") && !stringmatch(item,"*.SA3*") )
654                        if( !stringmatch(item,".*") && !stringmatch(item,"*.pxp") && !stringmatch(item,"*.DIV"))                //eliminate mac "hidden" files, pxp, and div files
655                                newlist += item + ";"
656                        endif
657                endif
658        endfor
659        //remove VAX version numbers
660        newList = RemoveVersNumsFromList(newList)
661        //sort
662        newList = SortList(newList,";",0)
663
664        return newlist
665End
666
667// returns a list of raw data files in the catPathName directory on disk
668// - list is SEMICOLON-delimited
669//
670// called by PatchFiles.ipf, Tile_2D.ipf
671//
672Function/S GetRawDataFileList()
673       
674        //make sure that path exists
675        PathInfo catPathName
676        if (V_flag == 0)
677                Abort "Folder path does not exist - use Pick Path button on Main Panel"
678        Endif
679       
680        String list=""
681       
682        // your code here
683       
684        return(list)
685End
686
687//**********************
688// 2D resolution function calculation - in terms of X and Y
689//
690// based on notes from David Mildner, 2008
691//
692// the final NCNR version is located in NCNR_Utils.ipf
693//
694Function/S get2DResolution(inQ,phi,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,r_dist,SigmaQX,SigmaQY,fSubS)
695        Variable inQ, phi,lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses,r_dist
696        Variable &SigmaQX,&SigmaQY,&fSubS               //these are the output quantities at the input Q value
697       
698        return("Function Empty")
699End
Note: See TracBrowser for help on using the repository browser.