source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/Automated_SANS_Reduction.ipf @ 1249

Last change on this file since 1249 was 1222, checked in by srkline, 3 years ago

Updated help file for VSANS. Graphics were not PNG.

Removed HFIR SANS package since if requires XML XOP - no longer supported.

Improved quality of graphics export for Analysis reports.

Added more support for super_white_beam mode on VSANS

Corrected printf bug (Igor 8) when printing out % sign

Added utilities for patching wavelength and monochromator type on VSANS since the type is still not written out correctly by NICE, and super_white_beam is not yet defined in NICE

Adjusted panel dimensions for the temperature sensor display on VSANS (needed onWindows)

File size: 36.2 KB
Line 
1#pragma rtGlobals=3             // Use modern global access method and strict wave access.
2
3
4//// a bunch of test functions to try to automate data reduction
5//
6// OCT 2014
7//
8//
9//
10//
11//
12// 1) start with gathering some basic information
13//              AskForConfigurations()
14//
15// 2) then sort the configurations from low Q to high Q
16//              SortConfigs()
17//
18//
19// 3) fill in the other files for the configuration. Currently a manual operation
20//
21//
22// 4) from the matrix of file numbers and some default choices,
23// save (n) configurations as config_n, to match row (n) of the matrix
24//
25// -- panel must be open
26//              ReductionProtocolPanel()
27//              FillInProtocol(index) -- need to set the ABS parameters before saving
28//              --save the protocol (I pick the name)   
29//              Auto_SaveProtocol(index)
30//
31//      ---- Run as:
32//              Auto_FillSaveProtocols()
33//
34// 5) calculate all of the transmissions
35// -- start by opening the Transmission panel
36// -- list all of the files
37// then:
38// - for each empty beam file:
39//              setXYBox (writes out box and counts to the file)
40//              check if there are transmission measurements at this config (SDD && lam)
41//                      if so, this is the empty beam
42//                              so try to guess the scattering files and calc transmission
43//
44//                      go get another transmission at this configuration
45//
46//              go get another empty beam file
47//
48//      - at the end, search through all of the scattering files. look at
49// the S_Transmission wave for: T=1 (be sure these are blocked beam) and search for
50//  T > 1, as these are wrong.
51//
52//      -- may need user intervention if things go wrong.
53//
54//      ---- to Run:
55//              Auto_Transmission()
56// then
57//              ListFiles_TransUnity()
58//              ListFiles_TransTooLarge()
59//
60//
61//
62// 6) reduce all of the data at each configuration
63//
64// - open the MRED panel
65// - for each configuration
66// - pick the configuration
67// - get the SDD, and the list of scattering files
68// - set the list and reduce all files
69// - when saving the files, can I enforce a prefix C0_, C1_etc. on the files?
70//
71// ---- Run As:
72//    Auto_MRED()
73//
74//
75// 7) figure out how to combine the data
76//
77// -- get listings of what I think I should be combining - this is saved from the transmission assignment
78// (default trim of data points for overlap, no rescaling)
79//
80//
81// -- look for the beamstop shadow at the beginning of the file
82// -- trim a default 5? 10? from the high Q end
83//
84// -- then just concatentate and sort.
85//
86//      ---- Run As:
87//                      Auto_NSORT(tableOnly=1)          to allow editing of the list of files and names
88//                      Auto_NSORT(tableOnly=0)         does the combination
89//
90//
91///////////////////////////////////
92//
93// TODO
94//
95//
96//              --properly generate the help file (reformat), link it to the help button, and get it into the SANS reduction
97//                              help file.
98//              -- make a better entry point from the Macros menu, and the SANS menu
99//
100//              -- may want to allow for some user feedback in NSORT in selecting the exact points to keep
101//       this is still a step where human judgement is rather useful.
102//     --  make it easier to edit the NSORT table. may be helpful to see the sample labels. This was
103//      clearly the case with 4 configs (one lens) since they fell in different piles during transmission
104//      calculation, so they did not appear together for combining files.
105//
106//
107
108
109
110
111///////// A simple panel so I don't have to run the commands
112//
113// --there is nothing to initialize
114//
115
116
117Proc Auto_Reduce_Panel() : Panel
118        PauseUpdate; Silent 1           // building window...
119        NewPanel /W=(1323,334,1574,663) /K=1
120        DoWindow/C AutoReduce
121        ModifyPanel cbRGB=(26205,52428,1)
122        SetDrawLayer UserBack
123        SetDrawEnv fname= "Monaco",fstyle= 1
124        DrawText 7,28,"(1)"
125        SetDrawEnv fname= "Monaco",fstyle= 1
126        DrawText 7,68,"(2)"
127        SetDrawEnv fname= "Monaco",fstyle= 1
128        DrawText 7,108,"(3)"
129        SetDrawEnv fname= "Monaco",fstyle= 1
130        DrawText 7,148,"(4)"
131        SetDrawEnv fname= "Monaco",fstyle= 1
132        DrawText 27,174,"(4.1)"
133        SetDrawEnv fname= "Monaco",fstyle= 1
134        DrawText 27,193,"(4.2)"
135        SetDrawEnv fname= "Monaco",fstyle= 1
136        DrawText 7,228,"(5)"
137        SetDrawEnv fname= "Monaco",fstyle= 1
138        DrawText 7,269,"(6)"
139        SetDrawEnv fname= "Monaco",fstyle= 1
140        DrawText 27,295,"(6.1)"
141        SetDrawEnv fstyle= 1
142        SetDrawEnv save
143
144        Button button0,pos={35,10},size={150,20},proc=AutoAskForConfigButton,title="Ask for Config"
145        Button button1,pos={35,50},size={150,20},proc=AutoSortConfigButton,title="Fill Config"
146        Button button2,pos={35,90},size={150,20},proc=AutoFillProtocolButton,title="Fill Protocols"
147        Button button3,pos={35,130},size={150,20},proc=AutoCalcTransButton,title="Calc Transmission"
148        Button button4,pos={70,155},size={150,20},proc=AutoFindUnityTransButton,title="Unity Transm"
149        Button button5,pos={70,175},size={150,20},proc=AutoFindLargeTransButton,title="Large Transm"
150        Button button6,pos={35,210},size={150,20},proc=AutoReduceEverythingButton,title="Reduce Everything"
151        Button button7,pos={35,250},size={150,20},proc=AutoNSORTTableButton,title="NSORT Table"
152        Button button8,pos={70,275},size={150,20},proc=AutoNSORTEverythingButton,title="NSORT Everything"
153
154        Button button9,pos={220,5},size={20,20},proc=AutoReduceHelpButton,title="?"
155       
156EndMacro
157
158// make the matrix a numeric wave.
159// assume that the DIV file can be found from the file list as ".DIV"
160// and the MASK file can be found as ".MASK" (if not, ask for help)
161//
162//
163Function AskForConfigurations()
164
165        Variable num
166        Prompt num,"How many configurations were used?"
167        DoPrompt "Enter the number of configs",num
168       
169        Make/O/D/N=(num,5) Configs
170        WAVE w = Configs
171        // set the column labels
172        SetDimLabel 1,0,'SDD',w
173        SetDimLabel 1,1,'Wavelength',w
174        SetDimLabel 1,2,'BKG',w
175        SetDimLabel 1,3,'EMP',w
176        SetDimLabel 1,4,'Empty Beam',w
177
178        Edit w.ld
179        ModifyTable width(Configs.l)=20
180       
181        DoAlert 0, "Fill in the SDD and wavelength for each configuration"
182
183        return(0)
184end
185
186//
187//
188Function SortConfigs()
189
190        WAVE w = Configs
191         
192        Variable num = DimSize(w, 0 )
193
194        Make/O/D/N=(num) wave0,wave1
195        wave0 = w[p][%'SDD']
196        wave1 = w[p][%'Wavelength']
197       
198        Sort/R {wave0,wave1},wave0,wave1
199
200        w[][%'SDD'] = wave0[p]
201        w[][%'Wavelength'] = wave1[p]
202       
203        KillWaves wave0,wave1
204
205// now try to find the configurations as best as I can
206        // loop over the rows
207        Variable ii
208        for(ii=0;ii<num;ii+=1)
209                FindConfigurationFiles(ii)
210        endfor
211
212        DoAlert 0, "I've sorted Low Q to High Q -- And while at it, filled in the run numbers for BKG, EMP and empty beam for each configuration"
213
214        return(0)
215End
216
217
218//
219// find the other files for each configuration as best possible
220//
221//
222Function FindConfigurationFiles(row)
223        Variable row
224       
225        WAVE w = Configs
226
227        // for the SDD and wavelength, find the BKG and EMP and Empty beam
228        Variable sdd, lam
229        sdd = w[row][%'SDD']
230        lam = w[row][%'Wavelength']
231
232        //(see MRED and Patch for help on this)
233        // find files with a reasonable string in the header somewhere -- returns a short list
234        // filter out the wrong SDD
235        // filter out the wrong wavelength
236        // filter out (is Trans) if needed
237
238        string newList="",item,matchStr,list="",pathStr
239        Variable num,ii,runNum
240
241        PathInfo catPathName
242        pathStr = S_Path
243       
244// blocked beam
245        matchStr = "block"
246        list = FindFileContainingString(matchStr)
247
248//      print list
249        newList = ""
250        num = ItemsinList(list)
251        for(ii=0;ii<num;ii+=1)
252                item = StringFromList(ii, list)
253                if(SameSDD_byName(pathStr+item,sdd) && SameWavelength_byName(pathStr+item,lam) && !isTransFile(pathStr+item))
254                        newList += item
255                        break           //only keep the first instance
256                endif   
257        endfor
258       
259        runNum = GetRunNumFromFile(newList)
260        w[row][%'BKG'] = runNum
261       
262        Printf "Config %d BKG: %s = %s\r",row,newList,getSampleLabel(pathStr+newList)
263       
264        // and the empty cell scattering
265        matchStr = "empty"
266        list = FindFileContainingString(matchStr)
267
268//      print list
269        newList = ""
270        num = ItemsinList(list)
271        for(ii=0;ii<num;ii+=1)
272                item = StringFromList(ii, list)
273                if(SameSDD_byName(pathStr+item,sdd) && SameWavelength_byName(pathStr+item,lam) && !isTransFile(pathStr+item))
274                        newList += item
275                        break           //only keep the first instance
276                endif   
277        endfor
278       
279        runNum = GetRunNumFromFile(newList)
280        w[row][%'EMP'] = runNum
281       
282       
283        Printf "Config %d EMP: %s = %s\r",row,newList,getSampleLabel(pathStr+newList)
284
285        //and the empty beam transmission
286        matchStr = "empty"
287        list = FindFileContainingString(matchStr)
288
289//      print list
290        newList = ""
291        num = ItemsinList(list)
292        for(ii=0;ii<num;ii+=1)
293                item = StringFromList(ii, list)
294                if(SameSDD_byName(pathStr+item,sdd) && SameWavelength_byName(pathStr+item,lam) && isTransFile(pathStr+item))
295                        newList += item
296                        break           //only keep the first instance
297                endif   
298        endfor
299       
300        runNum = GetRunNumFromFile(newList)
301        w[row][%'Empty Beam'] = runNum
302
303        Printf "Config %d Empty beam: %s = %s\r\r",row,newList,getSampleLabel(pathStr+newList)
304       
305
306        return(0)
307End
308
309Function/S FindFileContainingString(matchStr)
310        string matchStr
311       
312
313        string newList,item,list=""
314        Variable num,ii
315
316       
317        newList = GetRawDataFileList()
318        num=ItemsInList(newList)
319
320        for(ii=0;ii<num;ii+=1)
321                item=StringFromList(ii, newList , ";")
322//              Grep/P=catPathName/Q/E=("(?i)\\b"+matchStr+"\\b") item
323                Grep/P=catPathName/Q/E=("(?i)"+matchStr) item
324                if( V_value )   // at least one instance was found
325                        list += item + ";"
326                endif
327        endfor
328
329        newList = list
330
331       
332        return(newList)
333end
334
335
336
337
338Function/S FindDIVFile()
339       
340        String list,fileStr=""
341       
342        list = IndexedFile(catPathName, -1, ".DIV")
343//      Print list
344//      if(itemsinlist(list) == 1)
345                fileStr = StringFromList(0, list)               // just return the first one
346//      endif
347       
348        return(fileStr)
349
350End
351
352Function/S FindMASKFile()
353
354        String list,fileStr=""
355       
356        list = IndexedFile(catPathName, -1, ".MASK")
357//      Print list
358//      if(itemsinlist(list) == 1)
359                fileStr = StringFromList(0, list)               // just return the first one
360//      endif
361       
362        return(fileStr)
363End
364
365// returns true (1) if the run number has the same SDD as input
366Function SameSDD_byRun(runNum,sdd)
367        Variable runNum,sdd
368
369        String fname
370        Variable good
371       
372        good = 0
373        fname = ""
374        //generate a name
375        fname = FindFileFromRunNumber(runNum)
376        // test
377        good = SameSDD_byName(fname,sdd)
378       
379        return(good)
380End
381
382
383// returns true (1) if the file (fullPath) has the same SDD as input
384// -- fuzzy test, within 1% is a match
385//
386Function SameSDD_byName(fname,sdd)
387        String fname
388        Variable sdd
389
390        Variable good,tmp,tolerance
391       
392        tolerance = 0.01
393        good = 0
394        tmp = getSDD(fname)
395       
396        if(abs(tmp - sdd) < tolerance)          //need a fuzzy test here, just like for the wavelength
397                return(1)
398        else
399                return(0)
400        endif
401       
402End
403
404// returns true (1) if the run number has the same wavelength as input
405Function SameWavelength_byRun(runNum,lambda)
406        Variable runNum,lambda
407
408        String fname
409        Variable good
410       
411        good = 0
412        fname = ""
413        //generate a name
414        fname = FindFileFromRunNumber(runNum)
415        // test
416        good = SameWavelength_byName(fname,lambda)
417       
418        return(good)
419End
420
421
422// returns true (1) if the file (fullPath) has the same wavelength as input
423// -- fuzzy test, within 1% is a match
424//
425Function SameWavelength_byName(fname,lambda)
426        String fname
427        Variable lambda
428
429        Variable good,tmp,tolerance
430       
431        tolerance = 0.01
432        good = 0
433        tmp = getWavelength(fname)
434       
435        if(abs(tmp - lambda) < tolerance)               //need a fuzzy test here
436                return(1)
437        else
438                return(0)
439        endif
440       
441End
442
443
444// simple loop to automate the generation/saving of protocols from the configuration matrix
445//
446Function Auto_FillSaveProtocols()
447
448        WAVE w = root:Configs
449         
450        Variable num,ii
451        num = DimSize(w,0)
452       
453        for(ii=0;ii<num;ii+=1)
454                FillInProtocol(ii)
455                Auto_SaveProtocol(ii)
456        endfor
457       
458        return(0)
459End
460
461//
462// I could possibly just fill in the protocol on my own, or
463// fill in the panel and go through the parsing.
464//
465// be sure the panel is open before starting this.
466//
467Function FillInProtocol(index)
468        variable index
469       
470        // be sure it's open and on top (redundant, but do it anyways)
471        Execute "ReductionProtocolPanel()"
472       
473        SVAR bgd = root:myGlobals:Protocols:gBGD
474        SVAR emp = root:myGlobals:Protocols:gEMP
475        SVAR div = root:myGlobals:Protocols:gDIV
476        SVAR mask = root:myGlobals:Protocols:gMASK
477        SVAR gABS = root:myGlobals:Protocols:gAbsStr
478
479        WAVE configs=root:configs
480        bgd = num2str(configs[index][%'BKG'])
481        emp = num2str(configs[index][%'EMP'])
482
483        div = FindDIVFile()
484        mask = FindMASKFile()
485       
486        // now do the absolute scaling
487        // be sure to load in the DIV file
488        String pathStr
489        PathInfo catPathName
490        pathStr = S_path
491       
492        ReadHeaderAndWork("DIV",pathStr+div)
493       
494        // be sure that the beam center is properly set
495        Auto_FindWriteBeamCenter(configs[index][%'Empty Beam'])
496       
497        // then I can calculate Kappa
498        gABS = Auto_CalcKappa(configs[index][%'Empty Beam'])
499       
500        return(0)
501end
502
503
504Function Auto_SaveProtocol(index)
505        variable index
506       
507        String newProtocol
508       
509        newProtocol = "config_"+num2str(index)
510        Make/O/T/N=8 $("root:myGlobals:Protocols:" + newProtocol)
511        MakeProtocolFromPanel( $("root:myGlobals:Protocols:" + newProtocol) )
512       
513        return(0)
514End
515
516
517
518//
519// parallels the functionality of AskForAbsoluteParams_Quest()
520//
521Function/S Auto_CalcKappa(runNum)
522        Variable runNum
523       
524        String filename,pathStr
525       
526        filename = FindFileFromRunNumber(runNum)
527       
528        ReadHeaderAndData(filename)     //this is the full Path+file
529        UpdateDisplayInformation("RAW")                 //display the new type of data that was loaded
530       
531        Wave/T tw=$"root:Packages:NIST:RAW:TextRead"
532        Wave rw=$"root:Packages:NIST:RAW:RealsRead"
533        Wave iw=$"root:Packages:NIST:RAW:IntegersRead"
534        Wave data = $"root:Packages:NIST:raw:linear_data"               //this will be the linear data
535        String acctStr = tw[3] 
536
537
538        //get the necessary variables for the calculation of kappa
539        Variable detCnt,countTime,attenTrans,monCnt,sdd,pixel,kappa
540        Variable kappa_err
541        String detStr=tw[9],junkStr,errStr
542
543        pixel = rw[10]/10                       // header value (X) is in mm, want cm here
544
545        countTime = iw[2]
546        //detCnt = rw[2]                //080802 -use sum of data, not scaler from header
547        monCnt = rw[0]
548        sdd = rw[18]
549        sdd *=100               //convert from meters to cm
550                               
551        //lookup table for transmission factor
552        //determine which instrument the measurement was done on from acctStr
553        Variable lambda = rw[26]
554        Variable attenNo = rw[3]
555        Variable atten_err
556        attenTrans = AttenuationFactor(acctStr,lambda,attenNo,atten_err)
557        //Print "attenTrans = ",attenTrans
558       
559        Variable x1,x2,y1,y2,ct_err
560        Variable xctr,yctr
561        // set the xy box to be the whole detector to find the beam center (may be wrong in the file)
562        // then +/- 20 pix (within bounds) to sum
563
564        xctr = rw[16]
565        yctr = rw[17]
566
567        x1 = xctr - 15
568        x2 = xctr + 15
569        y1 = yctr - 15
570        y2 = yctr + 15
571        KeepSelectionInBounds(x1,x2,y1,y2)
572
573        Printf "Using Box X(%d,%d),Y(%d,%d)\r",x1,x2,y1,y2
574       
575        //need the detector sensitivity file - make a guess, allow to override
576        // it must already be there, done by calling routine
577        //
578        Wave divData = $"root:Packages:NIST:div:Data"
579        // correct by detector sensitivity
580        data /= divData
581       
582        detCnt = SumCountsInBox(x1,x2,y1,y2,ct_err,"RAW")
583        if(cmpstr(tw[9],"ILL   ")==0)
584                detCnt /= 4             // for cerca detector, header is right, sum(data) is 4x too large this is usually corrected in the Add step
585                pixel *= 1.04                   // correction for true pixel size of the Cerca
586        endif
587        //             
588        kappa = detCnt/countTime/attenTrans*1.0e8/(monCnt/countTime)*(pixel/sdd)^2
589       
590        kappa_err = (ct_err/detCnt)^2 + (atten_err/attenTrans)^2
591        kappa_err = sqrt(kappa_err) * kappa
592               
593        junkStr = num2str(kappa)
594        errStr = num2Str(kappa_err)
595               
596        // set the parameters in the global string
597        Execute "AskForAbsoluteParams(1,1,"+junkStr+",1,"+errStr+")"            //no missing parameters, no dialog
598               
599        DoWindow/K SANS_Data
600
601        Printf "Kappa was successfully calculated as = %g +/- %g (%g %%)\r",kappa,kappa_err,(kappa_err/kappa)*100
602       
603        SVAR kapStr = root:myGlobals:Protocols:gAbsStr 
604       
605        return(kapStr)
606end
607
608
609// given a run number:
610// -- load it to RAW
611// -- find the beam center
612// -- write this out to the file
613//
614Function Auto_FindWriteBeamCenter(runNum)
615        Variable runNum
616       
617        String filename,pathStr
618       
619        filename = FindFileFromRunNumber(runNum)
620       
621        ReadHeaderAndData(filename)     //this is the full Path+file
622        UpdateDisplayInformation("RAW")                 //display the new type of data that was loaded
623
624        Wave data = $"root:Packages:NIST:raw:linear_data"               //this will be the linear data
625
626        Variable xzsum,yzsum,zsum,ii,jj,top,bottom,left,right
627        Variable counts,xctr,yctr
628        xzsum = 0
629        yzsum = 0
630        zsum = 0
631       
632        left = 0
633        right = 127
634        bottom = 0
635        top = 127
636        // count over rectangular selection, doing each row, L-R, bottom to top
637        ii = bottom -1
638        do
639                ii +=1
640                jj = left-1
641                do
642                        jj += 1
643                        counts = data[jj][ii]
644                        xzsum += jj*counts
645                        yzsum += ii*counts
646                        zsum += counts
647                while(jj<right)
648        while(ii<top)
649       
650        xctr = xzsum/zsum
651        yctr = yzsum/zsum
652       
653        // add 1 to each to get to detector coordinates (1,128)
654        // rather than the data array which is [0,127]
655        xctr+=1
656        yctr+=1
657       
658        Print "Automatic Beam X-center (in detector coordinates) = ",xctr
659        Print "Automatic Beam Y-center (in detector coordinates) = ",yctr
660
661        //write the center to the header, so I don't need to find it again
662        WriteBeamCenterXToHeader(filename,xctr)
663        WriteBeamCenterYToHeader(filename,yctr)
664       
665        return(0)
666       
667End
668
669
670// load the file
671// - convert to SAM
672// - find the box and write out the counts
673//
674//  parallels SetXYBoxCoords()
675//
676Function Auto_SetXYBox(runNum)
677        Variable runNum
678
679        String filename,pathStr
680        Variable err,xctr,yctr,x1,x2,y1,y2
681        filename = FindFileFromRunNumber(runNum)
682
683// load the data        and convert to SAM
684        ReadHeaderAndData(filename)     //this is the full Path+file
685        UpdateDisplayInformation("RAW")                 //display the new type of data that was loaded
686        err = Raw_to_work("SAM")
687        String/G root:myGlobals:gDataDisplayType="SAM"
688        UpdateDisplayInformation("SAM")                 //display the new type of data that was loaded
689//      fRawWindowHook()
690
691// set the XYBox
692        xctr = getBeamXPos(filename)
693        yctr = getBeamYPos(filename)
694
695        x1 = xctr - 15
696        x2 = xctr + 15
697        y1 = yctr - 15
698        y2 = yctr + 15
699        KeepSelectionInBounds(x1,x2,y1,y2)
700        //write string as keyword-packed string, to use IGOR parsing functions
701        String msgStr = "X1="+num2str(x1)+";"
702        msgStr += "X2="+num2str(x2)+";"
703        msgStr += "Y1="+num2str(y1)+";"
704        msgStr += "Y2="+num2str(y2)+";"
705        String/G root:myGlobals:Patch:gPS3 = msgStr
706        String/G root:myGlobals:Patch:gEmpBox = msgStr
707        //changing this global wil update the display variable on the TransPanel
708        String/G root:myGlobals:TransHeaderInfo:gBox = msgStr
709
710// get the counts and write everything to the header
711        Variable counts,ct_err
712        counts = SumCountsInBox(x1,x2,y1,y2,ct_err,"SAM")
713       
714        WriteXYBoxToHeader(filename,x1,x2,y1,y2)
715       
716        Print counts, " counts in XY box"
717        WriteBoxCountsToHeader(filename,counts)
718       
719        WriteBoxCountsErrorToHeader(filename,ct_err)
720       
721       
722        return(0)
723End
724
725//// calculating the transmissions
726// 5) calculate all of the transmissions
727// -- start by opening the Transmission panel
728// -- list all of the files
729// then:
730// - for each empty beam file:
731//              setXYBox (write out box and counts to the file)
732//              check if there are transmission measurements at this config (SDD && lam)
733//                      if so, this is the empty beam
734//                              so try to guess the scattering files and calc transmission
735//
736//                      go get another transmission at this configuration
737//
738//              go get another empty beam file
739//
740//      - at the end, search through all of the scattering files. look at
741// the S_Transmission wave for: T=1 (be sure these are blocked beam) and search for
742//  T > 1, as these are wrong.
743//
744//      -- may need user intervention if things go wrong.
745//
746Function Auto_Transmission()
747
748        //open the panel
749        Execute "CalcTrans()"
750        //list the files - this is equivalent to pressing the button
751        Execute "BuildFileTables()"
752       
753        // get all of the empty beam files (from the initial setup)
754        WAVE configs = root:configs
755       
756        // declare all of the necessary TransTable files so that I can check, and do assignments
757        WAVE/T TransFiles = $"root:myGlobals:TransHeaderInfo:T_Filenames"
758        WAVE/T EmpAssignments = $"root:myGlobals:TransHeaderInfo:T_EMP_Filenames"
759       
760        Variable nEmpFiles,nTransFiles,ii,jj,empNum,empLam,empSDD,testNum,numChars
761        String empName="",pathStr,testName
762       
763        PathInfo catPathName
764        pathStr = S_path
765       
766        numChars = 8            //for the trans guess
767       
768        nEmpFiles = DimSize(configs, 0)
769        nTransFiles = numpnts(TransFiles)
770
771
772// this is only to save the "matches" for use later in combining the reduced data
773        SVAR gMatchSamStr = root:myGlobals:TransHeaderInfo:gMatchingSampleFiles
774        Make/O/T/N=(nTransFiles) savedMatches
775        savedMatches = ""
776
777        for(ii=0;ii<nEmpFiles;ii+=1)            //loop over the empty beam files (from Configs)
778                empNum = configs[ii][%'Empty Beam']
779                empName = GetFileNameFromPathNoSemi(FindFileFromRunNumber(empNum))
780                // auto_find the beam center
781                Auto_FindWriteBeamCenter(empNum)
782                // set the XY box for the file, and the counts in the box
783                Auto_SetXYBox(empNum)
784               
785                // get the wavelength and SDD (from the config) for comparison
786                empLam = configs[ii][%'Wavelength']
787                empSDD = configs[ii][%'SDD']
788               
789               
790                // loop through the trans files in the table (skip the empNum file)
791                // and see if any match the configuration
792                // -- if so do something
793               
794                for(jj=0;jj<nTransFiles;jj+=1)
795//              for(jj=0;jj<10;jj+=1)
796               
797                        // if it's the same file, skip it
798                        testNum = GetRunNumFromFile(TransFiles[jj])
799                        testName = TransFiles[jj]
800                        if(testNum != empNum)           
801                                // do the configurations match?
802                                if(SameWavelength_byName(pathStr+testName,empLam) && SameSDD_byName(pathStr+testName,empSDD))
803                                        // if yes:
804                                        // assign this empty beam as the reference empty beam
805                                        EmpAssignments[jj] = empName
806                                       
807                                        // try to find matching scattering runs
808                                        // set the selection on the table
809                                        ModifyTable/W=TransFileTable selection=(jj,1,jj,1,jj,1)
810                                       
811                                        // pick the number of characters to use
812                                        fGuessTransToScattFiles(numChars)
813                                       
814                                        // ** if "correct" runs are found, calculate the transmissions *** this is the tough step
815                                        // at this point, I'm still asking for user intervention, since I have no way of knowing
816                                        // how to tell if I have the right files, or even the right number of files.
817                                       
818                                        // this is a ; delimited list of the raw data files that have the same transmission assignment
819                                        // - that may be the ones to combine together.
820                                        savedMatches[jj] = gMatchSamStr                 
821                                       
822                                endif
823                        endif
824                endfor
825               
826        endfor          //loop over all empty beam files
827
828        DoAlert 0,"Transmissions are done"
829
830        return(0)
831End
832
833
834// spit out a list of scattering files with T=1
835// ask the user if these are OK
836Function ListFiles_TransUnity()
837
838        WAVE/T S_FileNames = $"root:myGlobals:TransHeaderInfo:S_FileNames"
839        WAVE/T S_Labels = $"root:myGlobals:TransHeaderInfo:S_Labels"
840        WAVE S_Transmission = $"root:myGlobals:TransHeaderInfo:S_Transmission"
841
842        Variable num,ii
843        num = numpnts(S_Transmission)
844       
845        for(ii=0;ii<num;ii+=1)
846                if(S_transmission[ii] == 1)
847                        printf "File %s = %s has T=1. Is this OK?\r",S_FileNames[ii],S_Labels[ii]
848                endif
849        endfor
850       
851        return(0)
852End
853
854
855// spit out a list of scattering files with T>1
856// let the user know that these are incorrect and need to be repaired
857
858Function ListFiles_TransTooLarge()
859
860        WAVE/T S_FileNames = $"root:myGlobals:TransHeaderInfo:S_FileNames"
861        WAVE/T S_Labels = $"root:myGlobals:TransHeaderInfo:S_Labels"
862        WAVE S_Transmission = $"root:myGlobals:TransHeaderInfo:S_Transmission"
863
864        Variable num,ii
865        num = numpnts(S_Transmission)
866       
867        for(ii=0;ii<num;ii+=1)
868                if(S_transmission[ii] > 1)
869                        printf "File %s = %s has T=1. This is NOT OK!\r",S_FileNames[ii],S_Labels[ii]
870                endif
871        endfor
872       
873        return(0)
874End
875
876
877
878
879// TOO -- rewrite this correctly, using a proper "fuzzy" match for the wavelength,
880// adding items that do not match to a growing list of "different" wavelengths to check against
881// -- use 1% tol, not 5%
882//
883// use the function "CloseEnough()"
884//
885Function HowManyWavelengths()
886       
887        Variable num
888        WAVE lam = root:myGlobals:CatVSHeaderInfo:Lambda
889       
890        Variable ii,npt,tol
891        npt = numpnts(lam)
892        tol = 1.01              // 1%
893       
894        Duplicate/O lam,tmp
895        sort tmp,tmp
896       
897        num = 1
898        Make/O/D/N=1 numLam
899        numLam[0] = tmp[0]
900       
901       
902        for(ii=1;ii<npt;ii+=1)
903                if(tmp[ii] > tol*numLam[num-1])
904                        InsertPoints num, 1, numLam
905                        numLam[num] = tmp[ii]
906                        num += 1
907                endif
908       
909        endfor
910       
911        Printf "Found %d different wavelengths\r",num
912       
913        return(num)
914End
915
916
917// somewhat tricky -- look for combinations of different
918// SDD and wavelength. -- if lenses are used, often they are both at the
919// same SDD, but at different wavelengths -- for lenses
920Function HowManyConfigurations()
921
922        Variable num
923        WAVE SDD = root:myGlobals:CatVSHeaderInfo:SDD
924        WAVE lam = root:myGlobals:CatVSHeaderInfo:Lambda
925       
926
927       
928        return(num)
929End
930
931
932/////
933//
934//
935Function Auto_MRED()
936
937        // open the panel
938        Execute "ReduceMultipleFiles()"
939       
940        WAVE w = root:Configs
941        SVAR protoList = root:myGlobals:MRED:gMRProtoList
942       
943        Variable num,ii,sdd,item
944        String str
945        num = DimSize(w,0)
946       
947        // protocols are named "config_n"
948        for(ii=0;ii<num;ii+=1)
949       
950                // pick the configuration (ii)
951                // set the protocol - find which list item
952                str = "config_"+num2str(ii)
953                item = WhichListItem(str, protoList)
954                PopupMenu MRProto_pop,win=Multiple_Reduce_Panel,mode=(item+1)           //popup counts from one
955
956                // get the SDD
957                SDD = w[ii][%'SDD']
958               
959                // get the scattering files at the SDD
960                Execute "CreateScatteringAtSDDTable("+num2str(SDD)+")"
961               
962                RemoveWrongLamFromSDDList(w[ii][%'Wavelength'])
963               
964                // set the list
965                AcceptMREDList("")
966               
967                // reduce them all
968                ReduceAllPopupFiles("")
969        endfor
970       
971        return(0)
972End
973
974// need fuzzy comparison
975//
976// Only wavelengths matching testLam are kept
977//
978Function RemoveWrongLamFromSDDList(testLam)
979        Variable testLam
980       
981        Wave/T filenames = $"root:myGlobals:MRED:Filenames"
982        Wave/T suffix = $"root:myGlobals:MRED:Suffix"
983        Wave/T labels = $"root:myGlobals:MRED:Labels"
984        Wave sdd = $"root:myGlobals:MRED:SDD"
985        Wave runnum = $"root:myGlobals:MRED:RunNumber"
986        Wave isTrans = $"root:myGlobals:MRED:IsTrans"
987       
988        String path
989        PathInfo catPathName
990        path = S_Path
991       
992        Variable num=numpnts(sdd),ii,tol = 0.1,lam
993       
994        ii=num-1
995        do
996                lam = getWavelength(path+filenames[ii])
997                if(trunc(abs(lam - testLam)) > tol)             //just get the integer portion of the difference - very coarse comparison
998                        DeletePoints ii, 1, filenames,suffix,labels,sdd,runnum,isTrans
999                endif
1000                ii-=1
1001        while(ii>=0)
1002       
1003        // now sort
1004        Sort RunNum,    filenames,suffix,labels,sdd,runnum,isTrans
1005        return(0)
1006End
1007
1008// does no scaling, only the basic (default) trim of the ends, concatenate, sort, and save
1009//
1010//
1011Function Auto_NSORT(tableOnly)
1012        variable tableOnly
1013
1014        Wave/T SavedMatches = root:savedMatches
1015
1016        if(tableOnly)
1017                Duplicate/T/O savedMatches saveName
1018                saveName = ""
1019        Endif
1020       
1021       
1022        DoWindow/F Auto_NSORT_Table
1023        if(V_flag == 0)
1024                Edit/N=Auto_NSORT_Table savedMatches,saveName
1025        endif
1026       
1027        Variable num,ii,numitems,numChars,jj,nEnd
1028        String item,path,tmpStr,cmd,folderStr
1029       
1030        // number of characters in the file label to keep for the file name
1031        numChars = 16
1032        // number of points to trim from end
1033        nEnd = 10
1034       
1035       
1036        PathInfo catPathName
1037        path = S_Path
1038       
1039        if(tableOnly)   
1040                num=numpnts(savedMatches)
1041        // guess at the file names
1042                for(ii=0;ii<num;ii+=1)
1043                        item = StringFromList(0, savedMatches[ii])
1044                        if(cmpstr(item,"") != 0)
1045                                tmpStr = RemoveAllSpaces(getSampleLabel(path+item))
1046                                tmpStr = CleanupName(tmpStr, 0 )
1047                                saveName[ii] = tmpStr[0,numChars-1]+".abs"
1048                        endif
1049                endfor
1050               
1051                DoAlert 0,"Edit the table to combine the correct files, and names that you like"
1052               
1053                return(0)
1054        endif
1055
1056
1057        // now, the table may have been edited
1058        num=numpnts(savedMatches)
1059
1060// now loop over the files:
1061        for(ii=0;ii<num;ii+=1)
1062                numItems = ItemsInList(savedMatches[ii])
1063                if(numItems != 0)
1064                        for(jj=0;jj<numItems;jj+=1)
1065                                // load
1066                                item = StringFromList(jj, savedMatches[ii])
1067                                folderStr = GetPrefixAndNumStrFromFile(item)            //this is where the data will be loaded to
1068                               
1069                                // check for existence first - this bypasses cases like the empty cell, which have transmission but are not reduced
1070                                if(cmpstr("",ValidFileString(folderStr+".ABS")) !=0)
1071       
1072                                        sprintf cmd , "A_LoadOneDDataToName(\"%s\",\"%s\",%d,%d)",path+folderStr+".ABS","",0,1
1073                                        Execute cmd             //no plot, force overwrite
1074                                       
1075                                        // trim
1076                                        Auto_TrimData(folderStr+"_ABS",nEnd)
1077                                        SetDataFolder root:
1078                                       
1079                                        // if first file, duplicate for a placeholder for the combined data, force overwrite
1080                                        if(jj==0)
1081                                                DuplicateDataSet(folderStr+"_ABS", CleanupName(saveName[ii],0), 1)
1082                                        else
1083                                                Auto_Concatenate(folderStr+"_ABS", CleanupName(saveName[ii],0))
1084                                        endif
1085                                       
1086                                endif
1087                        endfor
1088                       
1089                        // sort
1090                        Auto_Sort(CleanupName(saveName[ii],0))
1091                       
1092                        // save
1093                        if(DataFolderExists("root:"+CleanupName(saveName[ii],0)))
1094                                Auto_Write1DData(CleanupName(saveName[ii],0),"tab","CRLF")
1095                        endif
1096                endif
1097        endfor
1098
1099        // kill the loaded data sets (since they have been modified!)
1100        Execute "A_PlotManager_KillAll(\"\")"
1101
1102        return(0)
1103End
1104
1105
1106// this will bypass save dialogs
1107// -- AND WILL OVERWITE DATA WITH THE SAME NAME
1108//
1109Function Auto_Write1DData(folderStr,delim,term)
1110        String folderStr,delim,term
1111       
1112        String formatStr="",fullpath=""
1113        Variable refnum,dialog=1
1114       
1115        String dataSetFolderParent,basestr
1116       
1117        //Abuse ParseFilePath to get path without folder name
1118        dataSetFolderParent = ParseFilePath(1,folderStr,":",1,0)
1119        //Abuse ParseFilePath to get basestr
1120        basestr = ParseFilePath(0,folderStr,":",1,0)
1121       
1122        //make sure the waves exist
1123        SetDataFolder $(dataSetFolderParent+basestr)
1124        WAVE/Z qw = $(baseStr+"_q")
1125        WAVE/Z iw = $(baseStr+"_i")
1126        WAVE/Z sw = $(baseStr+"_s")
1127        WAVE/Z resw = $(baseStr+"_res")
1128       
1129        if(WaveExists(qw) == 0)
1130                Abort "q is missing"
1131        endif
1132        if(WaveExists(iw) == 0)
1133                Abort "i is missing"
1134        endif
1135        if(WaveExists(sw) == 0)
1136                Abort "s is missing"
1137        endif
1138        if(WaveExists(resw) == 0)
1139                Abort "Resolution information is missing."
1140        endif
1141       
1142        Duplicate/O qw qbar,sigQ,fs
1143        if(dimsize(resW,1) > 4)
1144                //it's USANS put -dQv back in the last 3 columns
1145                NVAR/Z dQv = USANS_dQv
1146                if(NVAR_Exists(dQv) == 0)
1147                        SetDataFolder root:
1148                        Abort "It's USANS data, and I don't know what the slit height is."
1149                endif
1150                sigQ = -dQv
1151                qbar = -dQv
1152                fs = -dQv
1153        else
1154                //it's SANS
1155                sigQ = resw[p][0]
1156                qbar = resw[p][1]
1157                fs = resw[p][2]
1158        endif
1159       
1160        PathInfo catPathName
1161        fullPath = S_Path + folderStr
1162
1163        Open refnum as fullpath
1164
1165        fprintf refnum,"Combined data written from folder %s on %s\r\n",folderStr,(date()+" "+time())
1166        formatStr = "%15.4g %15.4g %15.4g %15.4g %15.4g %15.4g\r\n"     
1167        fprintf refnum, "The 6 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm) | sigmaQ | meanQ | ShadowFactor|\r\n"       
1168
1169        wfprintf refnum,formatStr,qw,iw,sw,sigQ,qbar,fs
1170        Close refnum
1171       
1172        KillWaves/Z sigQ,qbar,fs
1173       
1174        SetDataFolder root:
1175        return(0)
1176End
1177
1178
1179// concatentate folder1 to the end of folder2
1180//
1181// this seems like a lot of extra work to do something so simple...
1182//
1183Function Auto_Concatenate(folder1,folder2)
1184        String folder1,folder2
1185       
1186       
1187        Concatenate/NP {$("root:"+folder1+":"+folder1+"_q"),$("root:"+folder2+":"+folder2+"_q")},tmp_q
1188        Concatenate/NP {$("root:"+folder1+":"+folder1+"_i"),$("root:"+folder2+":"+folder2+"_i")},tmp_i
1189        Concatenate/NP {$("root:"+folder1+":"+folder1+"_s"),$("root:"+folder2+":"+folder2+"_s")},tmp_s
1190        Concatenate/NP {$("root:"+folder1+":res0"),$("root:"+folder2+":res0")},tmp_res0
1191        Concatenate/NP {$("root:"+folder1+":res1"),$("root:"+folder2+":res1")},tmp_res1
1192        Concatenate/NP {$("root:"+folder1+":res2"),$("root:"+folder2+":res2")},tmp_res2
1193        Concatenate/NP {$("root:"+folder1+":res3"),$("root:"+folder2+":res3")},tmp_res3
1194       
1195// move the concatenated result into the destination folder (killing the old stuff first)
1196        KillWaves/Z $("root:"+folder2+":"+folder2+"_q")
1197        KillWaves/Z $("root:"+folder2+":"+folder2+"_i")
1198        KillWaves/Z $("root:"+folder2+":"+folder2+"_s")
1199        KillWaves/Z $("root:"+folder2+":res0")
1200        KillWaves/Z $("root:"+folder2+":res1")
1201        KillWaves/Z $("root:"+folder2+":res2")
1202        KillWaves/Z $("root:"+folder2+":res3")
1203       
1204        Duplicate/O tmp_q $("root:"+folder2+":"+folder2+"_q")
1205        Duplicate/O tmp_i $("root:"+folder2+":"+folder2+"_i")
1206        Duplicate/O tmp_s $("root:"+folder2+":"+folder2+"_s")
1207        Duplicate/O tmp_res0 $("root:"+folder2+":res0")
1208        Duplicate/O tmp_res1 $("root:"+folder2+":res1")
1209        Duplicate/O tmp_res2 $("root:"+folder2+":res2")
1210        Duplicate/O tmp_res3 $("root:"+folder2+":res3")
1211
1212        KillWaves/Z tmp_q,tmp_i,tmp_s,tmp_res0,tmp_res1,tmp_res2,tmp_res3       
1213       
1214       
1215        return(0)               
1216End
1217                       
1218Function Auto_Sort(folderStr)
1219        String folderStr
1220
1221        if(DataFolderExists("root:"+folderStr)  == 0)
1222                return(0)
1223        endif
1224       
1225        SetDataFolder $("root:"+folderStr)
1226       
1227        Wave qw = $(folderStr + "_q")
1228        Wave iw = $(folderStr + "_i")
1229        Wave sw = $(folderStr + "_s")
1230       
1231        Wave res0 = res0
1232        Wave res1 = res1
1233        Wave res2 = res2
1234        Wave res3 = res3
1235        // sort the waves
1236       
1237        Sort qw, qw,iw,sw,res0,res1,res2,res3
1238       
1239        // restore the res wave
1240        KillWaves/Z $(folderStr+"_res")
1241        Make/O/D/N=(numpnts(qw),4) $(folderStr+"_res")
1242        WAVE resWave = $(folderStr+"_res")
1243       
1244        //Put resolution contents back
1245        reswave[][0] = res0[p]
1246        reswave[][1] = res1[p]
1247        reswave[][2] = res2[p]
1248        reswave[][3] = res3[p]
1249       
1250        SetDataFolder root:
1251        return(0)
1252End
1253                       
1254// trims the beamstop out (based on shadow)
1255// trims num from the highQ end
1256// splits the res wave into individual waves in anticipation of concatenation
1257//
1258Function Auto_TrimData(folderStr,nEnd)
1259        String folderStr
1260        Variable nEnd
1261
1262        if(DataFolderExists("root:"+folderStr)  == 0)
1263                return(0)
1264        endif
1265               
1266        SetDataFolder $("root:"+folderStr)
1267       
1268        Wave qw = $(folderStr + "_q")
1269        Wave iw = $(folderStr + "_i")
1270        Wave sw = $(folderStr + "_s")
1271        Wave res = $(folderStr + "_res")
1272       
1273        variable num,ii
1274       
1275        num=numpnts(qw)
1276        //Break out resolution wave into separate waves
1277        Make/O/D/N=(num) res0 = res[p][0]               // sigQ
1278        Make/O/D/N=(num) res1 = res[p][1]               // qBar
1279        Make/O/D/N=(num) res2 = res[p][2]               // fshad
1280        Make/O/D/N=(num) res3 = res[p][3]               // qvals
1281       
1282        // trim off the last nEnd points from everything
1283        DeletePoints num-nEnd,nEnd, qw,iw,sw,res0,res1,res2,res3
1284       
1285        // delete all points where the shadow is < 0.98
1286        num=numpnts(qw)
1287        for(ii=0;ii<num;ii+=1)
1288                if(res2[ii] < 0.98)
1289                        DeletePoints ii,1, qw,iw,sw,res0,res1,res2,res3
1290                        num -= 1
1291                        ii -= 1
1292                endif
1293        endfor
1294       
1295////Put resolution contents back???
1296//              reswave[][0] = res0[p]
1297//              reswave[][1] = res1[p]
1298//              reswave[][2] = res2[p]
1299//              reswave[][3] = res3[p]
1300//             
1301                       
1302        SetDataFolder root:
1303        return(0)
1304end
1305
1306
1307//given a filename of a SANS data filename of the form
1308//TTTTTnnn.SAn_TTT_Txxx
1309//returns the prefix "TTTTTnnn" as some number of characters
1310//returns "" as an invalid file prefix
1311//
1312// NCNR-specifc, does not really belong here - but it's a beta procedure used for automation
1313//
1314Function/S GetPrefixAndNumStrFromFile(item)
1315        String item
1316        String invalid = ""     //"" is not a valid run prefix, since it's text
1317        Variable num=-1
1318       
1319        //find the "dot"
1320        String runStr=""
1321        Variable pos = strsearch(item,".",0)
1322        if(pos == -1)
1323                //"dot" not found
1324                return (invalid)
1325        else
1326                runStr = item[0,pos-1]
1327                return (runStr)
1328        Endif
1329End
1330
1331
1332//             
1333Function AutoReduceHelpButton(ba) : ButtonControl
1334        STRUCT WMButtonAction &ba
1335
1336        switch( ba.eventCode )
1337                case 2: // mouse up
1338                        // click code here
1339                        DisplayHelpTopic/Z/K=1 "Automated SANS Data Reduction"
1340                        if(V_flag !=0)
1341                                DoAlert 0,"The SANS Reduction Automation Help file could not be found"
1342                        endif
1343                        break
1344                case -1: // control being killed
1345                        break
1346        endswitch
1347
1348        return 0
1349End
1350
1351//             
1352Function AutoAskForConfigButton(ba) : ButtonControl
1353        STRUCT WMButtonAction &ba
1354
1355        switch( ba.eventCode )
1356                case 2: // mouse up
1357                        // click code here
1358                        AskForConfigurations()
1359                        break
1360                case -1: // control being killed
1361                        break
1362        endswitch
1363
1364        return 0
1365End
1366
1367
1368Function AutoSortConfigButton(ba) : ButtonControl
1369        STRUCT WMButtonAction &ba
1370
1371        switch( ba.eventCode )
1372                case 2: // mouse up
1373                        // click code here
1374                        SortConfigs()
1375                        break
1376                case -1: // control being killed
1377                        break
1378        endswitch
1379
1380        return 0
1381End
1382
1383
1384Function AutoFillProtocolButton(ba) : ButtonControl
1385        STRUCT WMButtonAction &ba
1386
1387        switch( ba.eventCode )
1388                case 2: // mouse up
1389                        // click code here
1390                        Auto_FillSaveProtocols()
1391                        break
1392                case -1: // control being killed
1393                        break
1394        endswitch
1395
1396        return 0
1397End
1398
1399
1400Function AutoCalcTransButton(ba) : ButtonControl
1401        STRUCT WMButtonAction &ba
1402
1403        switch( ba.eventCode )
1404                case 2: // mouse up
1405                        // click code here
1406                        Auto_Transmission()
1407                        break
1408                case -1: // control being killed
1409                        break
1410        endswitch
1411
1412        return 0
1413End
1414
1415
1416Function AutoFindUnityTransButton(ba) : ButtonControl
1417        STRUCT WMButtonAction &ba
1418
1419        switch( ba.eventCode )
1420                case 2: // mouse up
1421                        // click code here
1422                        ListFiles_TransUnity()
1423                        break
1424                case -1: // control being killed
1425                        break
1426        endswitch
1427
1428        return 0
1429End
1430
1431
1432Function AutoFindLargeTransButton(ba) : ButtonControl
1433        STRUCT WMButtonAction &ba
1434
1435        switch( ba.eventCode )
1436                case 2: // mouse up
1437                        // click code here
1438                        ListFiles_TransTooLarge()
1439                        break
1440                case -1: // control being killed
1441                        break
1442        endswitch
1443
1444        return 0
1445End
1446
1447
1448Function AutoReduceEverythingButton(ba) : ButtonControl
1449        STRUCT WMButtonAction &ba
1450
1451        switch( ba.eventCode )
1452                case 2: // mouse up
1453                        // click code here
1454                        Auto_MRED()
1455                        break
1456                case -1: // control being killed
1457                        break
1458        endswitch
1459
1460        return 0
1461End
1462
1463
1464Function AutoNSORTTableButton(ba) : ButtonControl
1465        STRUCT WMButtonAction &ba
1466
1467        switch( ba.eventCode )
1468                case 2: // mouse up
1469                        // click code here
1470                        Variable tableOnly = 1
1471                        Auto_NSORT(tableOnly)
1472                        break
1473                case -1: // control being killed
1474                        break
1475        endswitch
1476
1477        return 0
1478End
1479
1480Function AutoNSORTEverythingButton(ba) : ButtonControl
1481        STRUCT WMButtonAction &ba
1482
1483        switch( ba.eventCode )
1484                case 2: // mouse up
1485                        // click code here
1486                        Variable tableOnly = 0
1487                        Auto_NSORT(tableOnly)
1488                        DoAlert 0,"Sorting and Saving Done"
1489                        break
1490                case -1: // control being killed
1491                        break
1492        endswitch
1493
1494        return 0
1495End
1496
1497
1498
1499
Note: See TracBrowser for help on using the repository browser.