source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/NSORT.ipf @ 575

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

Change (1):
In preparation for release, updated pragma IgorVersion?=6.1 in all procedures

Change (2):
As a side benefit of requiring 6.1, we can use the MultiThread? keyword to thread any model function we like. The speed benefit is only noticeable on functions that require at least one integration and at least 100 points (resolution smearing is NOT threaded, too many threadSafe issues, too little benefit). I have chosen to use the MultiThread? only on the XOP assignment. In the Igor code there are too many functions that are not explicitly declared threadsafe, making for a mess.

File size: 62.8 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
4
5//****************************
6// Vers. 1.2 092101
7//
8// NSORT panel for combining and inter-normalizing 2 or 3 datasets
9// that have previously been averaged
10//
11// - handles 3 or 6-column datasets
12// allows manual scaling
13// allows user to interactively delete data points from either end of any datset
14//
15//*********************
16
17//main entry point for displaying the nsort panel
18//initializes folder/globals as needed
19//
20Proc ShowNSORTPanel()
21        DoWindow/F NSORT_Panel
22        if(V_flag==0)
23                InitNSORTPanel()
24                NSORT_Panel()
25        Endif
26        SetDataFolder root:
27        PathInfo/S catPathName
28        String junk = S_path
29        if (V_flag == 0)
30                //path does not exist - no folder selected
31                String/G root:myGlobals:NSORT:gPathStr = "no folder selected"
32        else
33                String/G root:myGlobals:NSORT:gPathStr = junk
34        endif
35        LowQPopMenuProc("",1,"")
36        MedQPopMenuProc("",1,"")
37        HighQPopMenuProc("",1,"")
38End
39
40//initializes globals/folder for the NSORT panel as needed
41//all of the globals are stored in root:myGlobals:NSORT folder
42//the globals are the values displayed in the panel
43//
44Proc InitNSORTPanel()
45
46        //set up the global variables needed for the NSORT panel
47        NewDataFolder/O root:myGlobals:NSORT
48        Variable/G root:myGlobals:NSORT:gScale1_2 = 1
49        Variable/G root:myGlobals:NSORT:gScale2_3 = 1
50        //
51        //save the number of points to trim from beginning/end of the data files
52        //
53        Variable/G root:myGlobals:NSORT:gPtsBeg1 = NumVarOrDefault("root:myGlobals:NSORT:gPtsBeg1", 0 )
54        Variable/G root:myGlobals:NSORT:gPtsEnd1 = NumVarOrDefault("root:myGlobals:NSORT:gPtsEnd1", 0 )
55        Variable/G root:myGlobals:NSORT:gPtsBeg2 = NumVarOrDefault("root:myGlobals:NSORT:gPtsBeg2", 0 )
56        Variable/G root:myGlobals:NSORT:gPtsEnd2 = NumVarOrDefault("root:myGlobals:NSORT:gPtsEnd2", 0 )
57        Variable/G root:myGlobals:NSORT:gPtsBeg3 = NumVarOrDefault("root:myGlobals:NSORT:gPtsBeg3", 0 )
58        Variable/G root:myGlobals:NSORT:gPtsEnd3 = NumVarOrDefault("root:myGlobals:NSORT:gPtsEnd3", 0 )
59       
60        Variable/G root:myGlobals:NSORT:gColumns1 = 0
61        Variable/G root:myGlobals:NSORT:gColumns2 = 0
62        Variable/G root:myGlobals:NSORT:gColumns3 = 0
63        Variable/G root:myGlobals:NSORT:gNormToNum = 1
64        String/G root:myGlobals:NSORT:gPathStr = ""
65        String/G root:myGlobals:NSORT:gDataPopList = "none"
66        String/G root:myGlobals:NSORT:gDataPopList_3 = "none"
67       
68        SetDataFolder root:             //(redundant)
69End
70
71
72//loads datasets (3-column or 6-column) for use in NSORTing
73//identical in function to normal file loading routine LoadQISData()
74//except that this routine builds custom names to keep track of
75//high-med-low q datasets (as defined by setNum input)
76//
77Function LoadDataForNSORT(fileStr,setNum)
78        String fileStr          //full path:name to a valid file
79        Variable setNum //number of set (used for naming) = 0, 1, or 2 (ONLY)
80       
81        Variable err=0
82       
83        LoadWave/G/D/A/Q fileStr                // (/Q) option suppresses printing to history
84        String nm0,nm1,nm2
85        String firstFileName = S_fileName
86        Variable pt=0,begPts,endPts
87
88        NVAR gColumns1 = root:myGlobals:NSORT:gColumns1
89        NVAR gColumns2 = root:myGlobals:NSORT:gColumns2
90        NVAR gColumns3 = root:myGlobals:NSORT:gColumns3
91        NVAR begPts1 = root:myGlobals:NSORT:gPtsBeg1
92        NVAR endPts1 = root:myGlobals:NSORT:gPtsEnd1
93        NVAR begPts2 = root:myGlobals:NSORT:gPtsBeg2
94        NVAR endPts2 = root:myGlobals:NSORT:gPtsEnd2
95        NVAR begPts3 = root:myGlobals:NSORT:gPtsBeg3
96        NVAR endPts3 = root:myGlobals:NSORT:gPtsEnd3
97       
98        String typStr="",trimStr=""
99       
100        do
101                if(V_flag == 3)  //Three waves loaded   
102                        // put the names of the three loaded waves into local names
103                        nm0 = StringFromList(0, S_waveNames ,";" )
104                        nm1 = StringFromList(1, S_waveNames ,";" )
105                        nm2 = StringFromList(2, S_waveNames ,";" )
106       
107                        //rename to give desired names - can't use rename if waves exist - it will generate an error
108                        if(setNum == 1)
109                                gColumns1 = 3
110                                typStr = "LowQSet"
111                                trimStr = "TrimLowQSet"
112                                begPts = begPts1
113                                endPts = endPts1
114                        else
115                                if(setNum == 2)
116                                        gColumns2 = 3
117                                        typStr = "MedQSet"
118                                        trimStr = "TrimMedQSet"
119                                        begPts = begPts2
120                                        endPts = endPts2
121                                else
122                                        gColumns3 = 3
123                                        typStr="HighQSet"
124                                        trimStr = "TrimHighQSet"
125                                        begPts = begPts3
126                                        endPts = endPts3
127                                Endif
128                        Endif
129                        Duplicate/O $nm0, $(typStr+"_q")
130                        Duplicate/O $nm1, $(typStr+"_i")
131                        Duplicate/O $nm2, $(typStr+"_s")
132                        KillWaves/Z $nm0,$nm1,$nm2
133                        //create the "trimmed" dataset too, start by duplicating the original sets
134                        Duplicate/O $(typStr+"_q"),$(trimStr+"_q")
135                        Duplicate/O $(typStr+"_i"),$(trimStr+"_i")
136                        Duplicate/O $(typStr+"_s"),$(trimStr+"_s")
137                        WaveStats/Q $(typStr+"_q")                      //get info about the original q-values read in
138                        pt = V_npnts-endPts
139                        DeletePoints pt,endPts,$(trimStr+"_q"),$(trimStr+"_i"),$(trimStr+"_s")  //delete end points first
140                        DeletePoints 0,begPts,$(trimStr+"_q"),$(trimStr+"_i"),$(trimStr+"_s")   //then delete points from beginning
141               
142                        Return err
143                        break
144                endif //End of what happens if 3 columns are loaded
145       
146                if(V_flag == 6)  //Six waves loaded
147                        String nm3,nm4,nm5
148                        // put the names of the three loaded waves into local names
149                        nm0 = StringFromList(0, S_waveNames ,";" )
150                        nm1 = StringFromList(1, S_waveNames ,";" )
151                        nm2 = StringFromList(2, S_waveNames ,";" )
152                        nm3 = StringFromList(3, S_waveNames ,";" )
153                        nm4 = StringFromList(4, S_waveNames ,";" )
154                        nm5 = StringFromList(5, S_waveNames ,";" )
155               
156                        if(setNum == 1)
157                                gColumns1 = 6
158                                typStr = "LowQSet"
159                                trimStr = "TrimLowQSet"
160                                begPts = begPts1
161                                endPts = endPts1
162                        else
163                                if(setNum == 2)
164                                        gColumns2 = 6
165                                        typStr = "MedQSet"
166                                        trimStr = "TrimMedQSet"
167                                        begPts = begPts2
168                                        endPts = endPts2
169                                else
170                                        gColumns3 = 6
171                                        typStr="HighQSet"
172                                        trimStr = "TrimHighQSet"
173                                        begPts = begPts3
174                                        endPts = endPts3
175                                Endif
176                        Endif
177                        Duplicate/O $nm0, $(typStr+"_q")
178                        Duplicate/O $nm1, $(typStr+"_i")
179                        Duplicate/O $nm2, $(typStr+"_s")
180                        Duplicate/O $nm3, $(typStr+"_sq")
181                        Duplicate/O $nm4, $(typStr+"_qb")
182                        Duplicate/O $nm5, $(typStr+"_fs")
183                        KillWaves/Z $nm0,$nm1,$nm2,$nm3,$nm4,$nm5
184                        //create the "trimmed" dataset too
185                        Duplicate/O $(typStr+"_q"),$(trimStr+"_q")
186                        Duplicate/O $(typStr+"_i"),$(trimStr+"_i")
187                        Duplicate/O $(typStr+"_s"),$(trimStr+"_s")
188                        Duplicate/O $(typStr+"_sq"),$(trimStr+"_sq")
189                        Duplicate/O $(typStr+"_qb"),$(trimStr+"_qb")
190                        Duplicate/O $(typStr+"_fs"),$(trimStr+"_fs")
191                        WaveStats/Q $(typStr+"_q")                      //get info about the original q-values read in
192                        pt = V_npnts-endPts
193                        DeletePoints pt,endPts,$(trimStr+"_q"),$(trimStr+"_i"),$(trimStr+"_s"),$(trimStr+"_sq"),$(trimStr+"_qb"),$(trimStr+"_fs")       //delete end points first
194                        DeletePoints 0,begPts,$(trimStr+"_q"),$(trimStr+"_i"),$(trimStr+"_s"),$(trimStr+"_sq"),$(trimStr+"_qb"),$(trimStr+"_fs")        //then delete points from beginning
195                               
196                        Return err
197                        break
198                endif //End of Six waves loaded
199       
200                //Next stuff gets executed if not 3 or 6 (example, if 0 )
201                err=1
202                return err
203        while(0)
204End
205
206//writes out the NSORTed file, includeing header information about how the file
207//was genereated - from which files, and how it was normalized
208//protocol info makes no sense here - go back to the original, separate files
209//if you want to know that information
210//
211// this is the 3-column version  - there's a separate function for 6-column data
212//will ALWAYS prompt for a filename
213//
214Function Write3ColNSORTedFile(q3,i3,sig3,firstFileName,secondFileName,thirdFileName,normTo,norm12,norm23)
215        Wave q3,i3,sig3
216        String firstFileName,secondFileName,thirdFileName,normTo
217        Variable norm12,norm23
218
219        Variable err=0,refNum
220        String fullPath=""
221        //check each wave - else REALLY FATAL error when writing file
222        If(!(WaveExists(q3)))
223                err = 1
224                return err
225        Endif
226        If(!(WaveExists(i3)))
227                err = 1
228                return err
229        Endif
230        If(!(WaveExists(sig3)))
231                err = 1
232                return err
233        Endif
234       
235        Variable dialog = 1
236        if(dialog)
237                PathInfo/S catPathName
238                fullPath = DoSaveFileDialog("Save data as")             //won't actually open the file
239                If(cmpstr(fullPath,"")==0)
240                        //user cancel, don't write out a file
241                        Close/A
242                        Abort "no data file was written"
243                Endif
244                //Print "dialog fullpath = ",fullpath
245        Endif
246       
247        // read in the header information from each of the combined files and put this information in the file header
248        String dum,hdr1="none\r\n",hdr2="none\r\n",hdr3="none\r\n"
249        PathInfo catPathName
250       
251        // the first file exists, check anyways
252        if(cmpstr(firstFileName,"none") !=0)
253                Open/R refNum as S_Path+firstFileName
254                FReadLine refNum, dum
255                FReadLine refNum, hdr1                  //just grab the second line
256                Close refNum
257        endif
258        //second file
259        if(cmpstr(secondFileName,"none") !=0)
260                Open/R refNum as S_Path+secondFileName
261                FReadLine refNum, dum
262                FReadLine refNum, hdr2                  //just grab the second line
263                Close refNum
264        endif
265        // third file
266        if(cmpstr(thirdFileName,"none") !=0)
267                Open/R refNum as S_Path+thirdFileName
268                FReadLine refNum, dum
269                FReadLine refNum, hdr3                  //just grab the second line
270                Close refNum
271        endif
272       
273        String formatStr = "%15.4g %15.4g %15.4g\r\n"
274        //actually open the file
275        Open refNum as fullpath
276       
277        fprintf refnum, "COMBINED FILE CREATED: %s \r\n",date()
278       
279        fprintf refnum, "FIRST File %s",hdr1            //new, Mar 2008
280        fprintf refnum, "SECOND File %s",hdr2           //new, Mar 2008
281        fprintf refnum, "THIRD File %s",hdr3            //new, Mar 2008
282       
283        fprintf refNum, "NSORT-ed   %s \t  +  %s\t  + %s\r\n",firstFileName, secondFileName,thirdFileName
284        fprintf refNum, "normalized to   %s\r\n",normTo
285        fprintf refNum, "multiplicative factor 1-2 = %12.8g\t multiplicative factor 2-3 = %12.8g\r\n",norm12,norm23
286        fprintf refnum, "The 3 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm) |\r\n"
287        wfprintf refnum, formatStr, q3,i3,sig3
288       
289        Close refnum
290       
291        Return err
292End
293
294//writes out the NSORTed file, includeing header information about how the file
295//was generated - from which files, and how it was normalized
296//protocol info makes no sense here - go back to the original, separate files
297//if you want to know that information
298//
299// this is the 6-column version  - there's a separate function for 3-column data
300//will ALWAYS prompt for a filename
301//
302Function Write6ColNSORTedFile(q3,i3,sig3,sq3,qb3,fs3,firstFileName,secondFileName,thirdFileName,normTo,norm12,norm23)
303        Wave q3,i3,sig3,sq3,qb3,fs3
304        String firstFileName,secondFileName,thirdFileName,normTo
305        Variable norm12,norm23
306
307        Variable err=0,refNum
308        String fullPath=""
309        //check each wave - else REALLY FATAL error when writing file   
310        If(!(WaveExists(q3)))
311                err = 1
312                return err
313        Endif
314        If(!(WaveExists(i3)))
315                err = 1
316                return err
317        Endif
318        If(!(WaveExists(sig3)))
319                err = 1
320                return err
321        Endif
322        If(!(WaveExists(sq3)))
323                err = 1
324                return err
325        Endif
326        If(!(WaveExists(qb3)))
327                err = 1
328                return err
329        Endif
330        If(!(WaveExists(fs3)))
331                err = 1
332                return err
333        Endif
334       
335        Variable dialog = 1
336        // 05SEP05 SRK -- added to automatically combine files from a table - see the end of NSORT.ipf for details
337        // - use the flag set in DoCombineFiles() to decide if the table entries should be used
338        //   root:myGlobals:CombineTable:useTable= (1) (0)
339        //if(exists("root:myGlobals:CombineTable:SaveName"))
340        NVAR/Z useTable = root:myGlobals:CombineTable:useTable
341        if(NVAR_Exists(useTable) && useTable==1)
342                SVAR str=$"root:myGlobals:CombineTable:SaveNameStr"             //messy, but pass in as a global
343                fullPath = str
344//              String str2 = "Is the file name "+str+" correct?"
345//              DoAlert 1,str2
346//              if(V_flag==1)
347                        dialog=0        //bypass the dialog if the name is good
348//              endif
349        endif
350       
351        if(dialog)
352                PathInfo/S catPathName
353                fullPath = DoSaveFileDialog("Save data as")             //won't actually open the file
354                If(cmpstr(fullPath,"")==0)
355                        //user cancel, don't write out a file
356                        Close/A
357                        Abort "no data file was written"
358                Endif
359                //Print "dialog fullpath = ",fullpath
360        Endif
361       
362        // read in the header information from each of the combined files and put this information in the file header
363        String dum,hdr1="none\r\n",hdr2="none\r\n",hdr3="none\r\n"
364        PathInfo catPathName
365       
366        // the first file exists, check anyways
367        if(cmpstr(firstFileName,"none") !=0)
368                Open/R refNum as S_Path+firstFileName
369                FReadLine refNum, dum
370                FReadLine refNum, hdr1                  //just grab the second line
371                Close refNum
372        endif
373        //second file
374        if(cmpstr(secondFileName,"none") !=0)
375                Open/R refNum as S_Path+secondFileName
376                FReadLine refNum, dum
377                FReadLine refNum, hdr2                  //just grab the second line
378                Close refNum
379        endif
380        // third file
381        if(cmpstr(thirdFileName,"none") !=0)
382                Open/R refNum as S_Path+thirdFileName
383                FReadLine refNum, dum
384                FReadLine refNum, hdr3                  //just grab the second line
385                Close refNum
386        endif
387       
388       
389        String formatStr = "%15.4g %15.4g %15.4g %15.4g %15.4g %15.4g\r\n"
390        //actually open the file
391        Open refNum as fullpath
392       
393        fprintf refnum, "COMBINED FILE CREATED: %s \r\n",date()
394       
395        fprintf refnum, "FIRST File %s",hdr1            //new, Mar 2008
396        fprintf refnum, "SECOND File %s",hdr2           //new, Mar 2008
397        fprintf refnum, "THIRD File %s",hdr3            //new, Mar 2008
398       
399        fprintf refNum, "NSORT-ed   %s \t  +  %s\t  + %s\r\n",firstFileName, secondFileName,thirdFileName
400        fprintf refNum, "normalized to   %s\r\n",normTo
401        fprintf refNum, "multiplicative factor 1-2 = %12.8g\t multiplicative factor 2-3 = %12.8g\r\n",norm12,norm23
402        fprintf refnum, "The 6 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm) | sigmaQ | meanQ | ShadowFactor|\r\n"
403        wfprintf refnum, formatStr, q3,i3,sig3,sq3,qb3,fs3
404       
405        Close refnum
406       
407        Return err
408End
409
410//gets the scaling constant to make (best) overlap of the specified datasets
411//the scaling value is an average value of the individual scaling values for
412//every data point (at the low q end) of set 2 that overlaps with set 1
413//(as if set 1 were held fixed)
414//num2 is the highest point number in set 2 that can overlap with set 1
415//(num2+1) individual scaling values are computed
416//wave2 must be multiplied by norm to rescale to wave1
417//the scale factor is the return value
418//
419Function GetScalingInOverlap(num2,wave1q,wave1i,wave2q,wave2i)
420        Variable num2           //largest point number of wave2 in overlap region
421        Wave wave1q,wave1i,wave2q,wave2i                //1 = first dataset, 2= second dataset
422
423        Variable ii,ival1,newi,ratio
424        ratio=0
425        ii=0
426        do
427                //get scaling factor at each point of wave 2 in the overlap region
428                newi = interp(wave2q[ii],wave1q,wave1i)         //get the intensity of wave1 at an overlap point
429                ratio += newi/wave2i[ii]                                        //get the scale factor
430                //Print "ratio = ",ratio
431                ii+=1
432        while(ii<=num2)
433        Variable val
434        val = ratio/(num2+1)            // +1 counts for point zero
435        //Print "val = ",val
436
437        Variable tol=1.05                       //5% is the preferred number (for Andrew and Lionel, at least)
438
439        ControlInfo/W=NSORT_Panel WarningCheck
440        if(( V_Value==1 ) && ( (val > tol) || (val < 1/tol) ) )
441                String str=""
442                sprintf str,"The scaling factor is more than a factor of %g from 1. Proceed with caution.\r",tol
443                DoAlert 0,str
444        endif
445       
446        Return val
447End
448
449Function ShowNSORTHelp(ctrlName) : ButtonControl
450        String ctrlName
451        DisplayHelpTopic/Z/K=1 "SANS Data Reduction Tutorial[Sort and Combine Averaged Datasets]"
452        if(V_flag !=0)
453                DoAlert 0,"The SANS Data Reduction Tutorial Help file could not be found"
454        endif
455End
456
457//button action procedure that simply closes the NSORT panel when done
458//and removes the NSORT-specific waves that were created
459// - the graph window must be killed first, so that the waves will not
460//be in use
461//
462Function NSORT_DoneButton(ctrlName) : ButtonControl
463        String ctrlName
464       
465        DoWindow/K NSORT_Panel
466       
467        DoWindow/K NSORT_Graph
468       
469        //clean up the temporary waves in the root: folder
470        SetDataFolder root:
471       
472        KillWaves/Z LowQSet_q,LowQSet_i,LowQSet_s,LowQSet_sq,LowQSet_qb,LowQSet_fs
473        KillWaves/Z TrimLowQSet_q,TrimLowQSet_i,TrimLowQSet_s,TrimLowQSet_sq,TrimLowQSet_qb,TrimLowQSet_fs
474        KillWaves/Z MedQSet_q,MedQSet_i,MedQSet_s,MedQSet_sq,MedQSet_qb,MedQSet_fs
475        KillWaves/Z TrimMedQSet_q,TrimMedQSet_i,TrimMedQSet_s,TrimMedQSet_sq,TrimMedQSet_qb,TrimMedQSet_fs
476        KillWaves/Z HighQSet_q,HighQSet_i,HighQSet_s,HighQSet_sq,HighQSet_qb,HighQSet_fs
477        KillWaves/Z TrimHighQSet_q,TrimHighQSet_i,TrimHighQSet_s,TrimHighQSet_sq,TrimHighQSet_qb,TrimHighQSet_fs
478
479End
480
481//button action procedure that plots dataset specified
482//on an NSORT graph window.
483//switch is on input controlName (low-med-high set)
484//parses partial filename from corresponding popup menu
485//builds a valid filename, loads the data (re-loads if already on graph)
486//and plots twice - once for the full datset (open symbols)
487//and once for the "trimmed" dataset (solid symbols, same color)
488//
489Function Plot_0_Button(ctrlName) : ButtonControl
490        String ctrlName
491
492        String tempName="",partialName=""
493        Variable setNum,err
494        //switch on ctrlName string - Plot_1, Plot_2, Plot_3
495        if(cmpstr(ctrlName,"Plot_1")==0)
496                //low-q
497                setNum = 1
498                ControlInfo $"popup_1"
499        else
500                if(cmpstr(ctrlName,"Plot_2")==0)
501                        //medium-q
502                        setNum = 2
503                        ControlInfo $"popup_2"
504                else
505                        //high-q
506                        setNum = 3
507                        ControlInfo $"popup_3"
508                Endif
509        Endif
510       
511        //find the file from the partial filename
512        If( (cmpstr(S_value,"")==0) || (cmpstr(S_value,"none")==0) )
513                //null selection, or "none" from any popup
514                Abort "no file selected in popup menu"
515        else
516                //selection not null
517                partialName = S_value
518                //Print partialName
519        Endif
520        //get a valid file based on this partialName and catPathName
521        tempName = FindValidFilename(partialName)
522       
523        //prepend path to tempName for read routine
524        PathInfo catPathName
525        tempName = S_path + tempName
526       
527        //load in the data (into the root directory)
528        err = LoadDataForNSORT(tempName,setNum)
529       
530        //bring the plot to the front, and put the new data on it
531        //and put cursors on the plotted dataset
532        //if the dataset is already on the graph, it will have been overwritten and updated by the load routine
533        //actually plot it twice, open(opaque) circles for the full dataset,
534        // then solid (filled) circles for the points actually kept
535        String list="",searchStr=""
536        Variable isOnPlot=0
537       
538        DoWindow/F NSORT_Graph
539        if(V_flag == 0)
540                //no window, create one
541                if(cmpstr(ctrlName,"Plot_1")==0)
542                        //low-q
543                        Display/K=1
544                        DoWindow/C NSORT_Graph
545                        DisplayLowSet()
546                else
547                        if(cmpstr(ctrlName,"Plot_2")==0)
548                                //medium-q
549                                Display/K=1
550                                DoWindow/C NSORT_Graph
551                                DisplayMedSet()
552                        else
553                                //high-q
554                                Display/K=1
555                                DoWindow/C NSORT_Graph
556                                DisplayHighSet()
557                        Endif
558                Endif
559                Legend
560        else
561                //plot already exists, waves have been updated
562                //make sure that the desired waves are actually on the graph, and add them if they aren't
563                list = TraceNameList("NSORT_Graph",";",1)
564       
565                if(cmpstr(ctrlName,"Plot_1")==0)
566                        //low-q
567                        isOnPlot = strsearch(list, "LowQSet_i", 0)              // isOnPlot == -1 if it is NOT found in the list
568                        if(isOnPlot == -1)
569                                DisplayLowSet()
570                        Endif
571                else
572                        if(cmpstr(ctrlName,"Plot_2")==0)
573                                //medium-q
574                                isOnPlot = strsearch(list, "MedQSet_i", 0)              // isOnPlot == -1 if it is NOT found in the list
575                                if(isOnPlot == -1)
576                                        DisplayMedSet()
577                                Endif
578                        else
579                                //high-q
580                                isOnPlot = strsearch(list, "HighQSet_i", 0)             // isOnPlot == -1 if it is NOT found in the list
581                                if(isOnPlot == -1)
582                                        DisplayHighSet()
583                                Endif
584                        Endif
585                Endif
586        Endif
587        //the stripPoints variable boxes should also update the graph, if necessary
588       
589End
590
591//adds both high-q sets (full and trimmed) to the graph, which is
592//assumed to exist along with the high-q waves
593//
594Function DisplayHighSet()
595        //function assumes that the window "NSORT_Graph" already exists
596        DoWindow/F NSORT_Graph
597        AppendToGraph $"HighQSet_i" vs $"HighQSet_q"
598        ModifyGraph log=1,mode=3,marker($"HighQSet_i")=8,msize=2,rgb($"HighQSet_i")=(0,0,65535),opaque($"HighQSet_i")=1
599        ErrorBars/T=0 $"HighQSet_i" Y,wave=($"HighQSet_s",$"HighQSet_s")
600        AppendToGraph $"TrimHighQSet_i" vs $"TrimHighQSet_q"
601        ModifyGraph mode($"TrimHighQSet_i")=3,marker($"TrimHighQSet_i")=19,msize=2,rgb($"TrimHighQSet_i")=(0,0,65535)
602End
603
604//adds both med-q sets (full and trimmed) to the graph, which is
605//assumed to exist along with the med-q waves
606//
607Function DisplayMedSet()
608        //function assumes that the window "NSORT_Graph" already exists
609        DoWindow/F NSORT_Graph
610        AppendToGraph $"MedQSet_i" vs $"MedQSet_q"
611        ModifyGraph log=1,mode=3,marker($"MedQSet_i")=8,msize=2,rgb($"MedQSet_i")=(65535,0,0),opaque($"MedQSet_i")=1
612        ErrorBars/T=0 $"MedQSet_i" Y,wave=($"MedQSet_s",$"MedQSet_s")
613        AppendToGraph $"TrimMedQSet_i" vs $"TrimMedQSet_q"
614        ModifyGraph mode($"TrimMedQSet_i")=3,marker($"TrimMedQSet_i")=19,msize=2,rgb($"TrimMedQSet_i")=(65535,0,0)
615End
616
617//adds both low-q sets (full and trimmed) to the graph, which is
618//assumed to exist along with the low-q waves
619//
620Function DisplayLowSet()
621        //function assumes that the window "NSORT_Graph" already exists
622        DoWindow/F NSORT_Graph
623        AppendToGraph $"LowQSet_i" vs $"LowQSet_q"
624        ModifyGraph log=1,mode=3,marker($"LowQSet_i")=8,msize=2,rgb($"LowQSet_i")=(2,39321,1),opaque($"LowQSet_i")=1
625        ErrorBars/T=0 $"LowQSet_i" Y,wave=($"LowQSet_s",$"LowQSet_s")
626        AppendToGraph $"TrimLowQSet_i" vs $"TrimLowQSet_q"
627        ModifyGraph mode($"TrimLowQSet_i")=3,marker($"TrimLowQSet_i")=19,msize=2,rgb($"TrimLowQSet_i")=(2,39321,1)
628End
629
630//button action procedure to set both the main global of the catPath string
631//and also the duplicate global string used in the NSORT folder
632//after path selected, the popup menus are updated
633//
634Function NSORTPickPathButton(ctrlName) : ButtonControl
635        String ctrlName
636
637        Variable err = PickPath()               //sets global path value
638        SVAR pathStr = root:myGlobals:gCatPathStr
639       
640        //set the global string for NSORT to the selected pathname
641        String/G root:myGlobals:NSORT:gPathStr = pathStr
642       
643        //call each of the popup menu proc's to re-set the menu choices
644        //setting the checkboxes to force update
645//      CheckBox check_0,win=NSORT_Panel,value=1
646//      CheckBox check_1,win=NSORT_Panel,value=1
647//      CheckBox check_2,win=NSORT_Panel,value=1
648        LowQPopMenuProc("popup_1",1,"")
649        MedQPopMenuProc("popup_2",1,"")
650        HighQPopMenuProc("popup_3",1,"")
651       
652End
653
654
655//action procedure associated with the setvar box
656//when a value is entered, the global value is set, and the corresponding dataset
657//is updated on the plot, showing the new result of removing this number of points
658//
659//      SetVar boxes are named beg_N and end_N (so 4th element is the number)
660//
661// 1 == LowQ
662// 2 == MedQ
663// 3 == HighQ
664//
665//"Plot_1" is the low-q button name
666//"Plot_2" is the med-q button name
667//"Plot_3" is the high-q button name
668//
669//calling plot_0_Button() responds as if that named button were pressed
670// and gets the proper number to trim directly from the SetVar
671//
672Function SetBegOrEnd(ctrlName,varNum,varStr,varName) : SetVariableControl
673        String ctrlName
674        Variable varNum
675        String varStr
676        String varName
677       
678//  global is automatically updated as the value is entered
679        String numStr= num2Str( str2num(ctrlName[4]) )
680        Plot_0_Button("Plot_"+numStr)
681        DoWindow/F NSORT_Panel
682End
683
684//this will---
685//re-load the data sets (since they may not have been loaded if they were not plotted)
686// apply the scaling to the datasets (so that they will show up in the graph)
687//and actually write the file
688//
689// then "pop" the  lists to get the new file lists with the new name in the list
690//
691Function WriteNSORTFileButton(ctrlName) : ButtonControl
692        String ctrlName
693               
694        // Put here the dialog that says if ANY of the datasets had 3-column data, the results will all have only three columns
695        // Set the number of output columns
696        Variable isAThree = 0, isASix = 0,err
697        String fileStr="",tempName
698
699        NVAR Columns1 = root:myGlobals:NSORT:gColumns1
700        NVAR Columns2 = root:myGlobals:NSORT:gColumns2
701        NVAR Columns3 = root:myGlobals:NSORT:gColumns3
702        if( (Columns1 == 3) || (Columns2 == 3) || (Columns3 == 3) )
703                isAThree = 1
704        endif
705        if( (Columns1 == 6) || (Columns2 == 6) || (Columns3 == 6) )
706                isASix = 1
707        endif
708        if( (isAThree == 1) && (isASix == 1))
709                DoAlert 0, "These files contained a mixture of 3-column and 6-column data.  Only 3 columns were output."
710        endif
711       
712        //is there just one data set? if so, then dispatch to a simpler routine, since no normalization is needed
713        ControlInfo/W=NSORT_Panel popup_2               //if MedQSet is "none", then so is HighQSet
714        fileStr = S_Value
715        if(cmpstr(fileStr,"none") == 0)
716                // just like in the rescaling routines, always RELOAD the data  !!!
717                //load file1
718                ControlInfo/W=NSORT_Panel popup_1
719                fileStr = S_Value
720                //get a valid file based on this partialName and catPathName
721                tempName = FindValidFilename(fileStr)
722               
723                //prepend path to tempName for read routine
724                PathInfo catPathName
725                tempName = S_path + tempName
726                err = LoadDataForNSORT(tempName,1)
727                //////end load file1
728       
729                //send just the trimmed (LowQ) set to be written out
730                WAVE lowq = $"TrimLowQSet_q"
731                WAVE lowi = $"TrimLowQSet_i"
732                WAVE lows = $"TrimLowQSet_s"
733                WAVE/Z lowsq = $"TrimLowQSet_sq"                //these may not exist
734                WAVE/Z lowqb = $"TrimLowQSet_qb"
735                WAVE/Z lowfs = $"TrimLowQSet_fs"
736                NVAR scaleFactor= root:myGlobals:NSORT:gScale1_2
737               
738                //
739                lowi *= scaleFactor
740                lows *= scaleFactor
741               
742                ControlInfo/W=NSORT_Panel PreviewCheck
743                if( V_Value==1 )                //if ==1, just preview and exit
744                        return(0)
745                endif
746                       
747                ControlInfo/W=NSORT_Panel popup_1
748                if(isAThree)
749                        Write3ColNSORTedFile(lowq,lowi,lows,S_Value,"none","none",S_Value,scaleFactor,1)
750                else
751                        Write6ColNSORTedFile(lowq,lowi,lows,lowsq,lowqb,lowfs,S_Value,"none","none",S_Value,scaleFactor,1)
752                endif
753                //  just get the new list and return - don't actually "pop" the menu, or the selected item will change
754                SVAR popList = root:myGlobals:NSORT:gDataPopList
755                SVAR popList_3 = root:myGlobals:NSORT:gDataPopList_3
756                popList  = ReducedDataFileList("")
757                popList_3 = "none;" +  ReducedDataFileList("")
758                return(0)
759        endif
760               
761               
762        //two or more datasets, combine them
763        //have they been manually or auto-normalized?
764        ControlInfo AutoCheck
765        Variable checked = V_Value
766       
767        //do the normalization and update the global scale factors displayed in the Panel
768        err = DoAutoScaleFromPanel(checked)                     // DoAutoScaleFromPanel writes out the datafile
769
770        //  just get the new list - don't actually "pop" the menu, or the selected item will change
771        SVAR popList = root:myGlobals:NSORT:gDataPopList
772        SVAR popList_3 = root:myGlobals:NSORT:gDataPopList_3
773        popList  = ReducedDataFileList("")
774        popList_3 = "none;" +  ReducedDataFileList("")
775       
776        return(0)
777End
778
779//window recreation macro for NSORT Panel
780//
781Window NSORT_Panel()
782        PauseUpdate; Silent 1           // building window...
783        NewPanel /W=(569,69,944,485)/K=2
784        ModifyPanel cbRGB=(49151,53155,65535)
785        ModifyPanel fixedSize=1
786        SetDrawLayer UserBack
787        SetDrawEnv fstyle= 5
788        DrawText 35,20,"NSORT - Rescale and combine 1-D files"
789        DrawLine 0,55,346,55
790        DrawLine 0,128,346,128
791        DrawLine 0,214,346,214
792        DrawLine 0,295,346,295
793        SetDrawEnv fstyle= 5
794        DrawText 5,74,"Low Q:"
795        SetDrawEnv fstyle= 5
796        DrawText 5,148,"Medium Q:"
797        SetDrawEnv fstyle= 5
798        DrawText 8,234,"High Q: (or none)"
799        SetDrawEnv fstyle= 4
800        DrawText 178,75,"Delete Points?"
801        SetDrawEnv fstyle= 4
802        DrawText 178,146,"Delete Points?"
803        SetDrawEnv fstyle= 4
804        DrawText 184,236,"Delete Points?"
805        DrawLine 0,363,346,363
806        DrawText 31,357,"To Manually scale data, enter scale factors above"
807        Button NSORT_Done,pos={274,387},size={50,20},proc=NSORT_DoneButton,title="Done"
808        Button NSORT_Done,help={"closes the panel"}
809        Button Plot_1,pos={279,63},size={50,20},proc=Plot_0_Button,title="Plot"
810        Button Plot_1,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
811        Button Plot_2,pos={283,144},size={50,20},proc=Plot_0_Button,title="Plot"
812        Button Plot_2,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
813        Button Plot_3,pos={284,223},size={50,20},proc=Plot_0_Button,title="Plot"
814        Button Plot_3,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
815        Button PathButton,pos={6,26},size={80,20},proc=NSORTPickPathButton,title="Pick Path"
816        Button PathButton,help={"Select the local path to the folder containing your SANS data"}
817        Button helpButton,pos={340,26},size={25,20},proc=ShowNSORTHelp,title="?"
818        Button helpButton,help={"Show the help file for sorting and internormalizing 1-D data sets"}
819        SetVariable setPath,pos={95,29},size={240,14},title="Path:",fSize=10
820        SetVariable setPath,limits={0,0,0},value= root:myGlobals:NSORT:gPathStr
821        SetVariable setPath,help={"The current path to the local folder with SANS data"}
822        SetVariable end_1,pos={182,101},size={80,14},proc=SetBegOrEnd,title="End Pts"
823        SetVariable end_1,fSize=10,help={"How many points to remove from the high-q end of this dataset"}
824        SetVariable end_1,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsEnd1
825        SetVariable end_2,pos={182,176},size={80,14},proc=SetBegOrEnd,title="End Pts"
826        SetVariable end_2,fSize=10,help={"How many points to remove from the high-q end of this dataset"}
827        SetVariable end_2,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsEnd2
828        SetVariable end_3,pos={182,269},size={80,14},proc=SetBegOrEnd,title="End Pts"
829        SetVariable end_3,fSize=10,help={"How many points to remove from the high-q end of this dataset"}
830        SetVariable end_3,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsEnd3
831        SetVariable beg_1,pos={182,79},size={80,14},proc=SetBegOrEnd,title="Beg Pts"
832        SetVariable beg_1,fSize=10,help={"How many points to remove from the low-q end of this dataset"}
833        SetVariable beg_1,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsBeg1
834        SetVariable beg_2,pos={182,155},size={80,14},proc=SetBegOrEnd,title="Beg Pts"
835        SetVariable beg_2,fSize=10,help={"How many points to remove from the low-q end of this dataset"}
836        SetVariable beg_2,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsBeg2
837        SetVariable beg_3,pos={182,246},size={80,14},proc=SetBegOrEnd,title="Beg Pts"
838        SetVariable beg_3,fSize=10,help={"How many points to remove from the low-q end of this dataset"}
839        SetVariable beg_3,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsBeg3
840        Button DoCombine,pos={13,387},size={160,20},proc=WriteNSORTFileButton,title="Write Combined File"
841        Button DoCombine,help={"Combine and normalize the selected files as specifed"}
842        SetVariable scale_12,pos={159,305},size={160,14},proc=SetScale_12,title="Mult factor 1-2"
843        SetVariable scale_12,fSize=10,help={"Factor that will multiply medium-q set to scale to low-q set"}
844        SetVariable scale_12,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gScale1_2
845        SetVariable scale_23,pos={159,325},size={160,14},proc=SetScale_23,title="Mult factor 2-3"
846        SetVariable scale_23,fSize=10,help={"Factor that will multiply high-q set to scale to medium-q set"}
847        SetVariable scale_23,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gScale2_3
848        CheckBox check1,pos={5,105},size={160,20},proc=CheckProc,title="Normalize to this file",value=1
849        CheckBox check1,help={"If checked, the combined dataset will be normalized to this dataset"}
850        CheckBox check2,pos={5,185},size={160,20},proc=CheckProc,title="Normalize to this file",value=0
851        CheckBox check2,help={"If checked, the combined dataset will be normalized to this dataset"}
852        CheckBox check3,pos={4,270},size={160,20},proc=CheckProc,title="Normalize to this file",value=0
853        CheckBox check3,help={"If checked, the combined dataset will be normalized to this dataset"}
854        PopupMenu popup_1,pos={6,77},size={99,19},proc=LowQPopMenuProc
855        PopupMenu popup_1,mode=1,value= #"root:myGlobals:NSORT:gDataPopList"
856        PopupMenu popup_1,help={"Choose the dataset with the lowest overall q-value (longest detector distance)"}
857        PopupMenu popup_2,pos={6,153},size={99,19},proc=MedQPopMenuProc
858        PopupMenu popup_2,mode=1,value= #"root:myGlobals:NSORT:gDataPopList_3"
859        PopupMenu popup_2,help={"Choose the dataset with the intermediate q-values (\"medium\" detector distance)"}
860        PopupMenu popup_3,pos={6,239},size={99,19},proc=HighQPopMenuProc
861        PopupMenu popup_3,mode=1,value= #"root:myGlobals:NSORT:gDataPopList_3"
862        PopupMenu popup_3,help={"Choose the dataset with the highest overall q-value (shortest detector distance), or NONE if no third set desired"}
863        CheckBox AutoCheck,pos={14,310},size={100,20},title="Auto Scale",value=0
864        CheckBox AutoCheck,help={"If checked, the scale factor will be automatically determined, if not checked, the current values in the fields will be used"}
865        CheckBox PreviewCheck,pos={15,369},size={74,14},title="Preview Only",value= 0
866        CheckBox WarningCheck,pos={111,369},size={93,14},title="Overlap warning?",value= 1
867EndMacro
868
869//sets the scale factor (multiplicative) between sets 1 and 2
870//re-sets the global variable
871//
872Function SetScale_12(ctrlName,varNum,varStr,varName) : SetVariableControl
873        String ctrlName
874        Variable varNum
875        String varStr
876        String varName
877
878        Variable/G root:myGlobals:NSORT:gScale1_2 = varNum
879       
880End
881
882//sets the scale factor (multiplicative) between sets 2 and 3
883//re-sets the global variable
884//
885Function SetScale_23(ctrlName,varNum,varStr,varName) : SetVariableControl
886        String ctrlName
887        Variable varNum
888        String varStr
889        String varName
890
891        Variable/G root:myGlobals:NSORT:gScale2_3 = varNum
892End
893
894//control procedures for the checkboxes to specify which file is to be
895//held fixed (so all other files are normalized to the checked file
896//the three checkboxes behave as "radio buttons" - only one can be checked
897//
898Function CheckProc(ctrlName,checked) : CheckBoxControl
899        String ctrlName
900        Variable checked
901       
902        //controls the three checkboxes to act as "radio buttons" to have only one file to
903        //normalize to.
904        //all three boxes should call this routine
905       
906        //do the "radio button control"
907        do
908                if(cmpstr(ctrlName,"check2") == 0)
909                        CheckBox check1 value=0
910                        CheckBox check2 value=1
911                        CheckBox check3 value=0
912                        Variable/G root:myGlobals:NSORT:gNormToNum = 2
913                        break
914                Endif
915                if(cmpstr(ctrlName,"check3") == 0)
916                        CheckBox check1 value=0
917                        CheckBox check2 value=0
918                        CheckBox check3 value=1
919                        Variable/G root:myGlobals:NSORT:gNormToNum = 3
920                        break
921                Endif
922                //default case is normalize to file1
923                CheckBox check1 value=1
924                CheckBox check2 value=0
925                CheckBox check3 value=0
926                Variable/G root:myGlobals:NSORT:gNormToNum = 1
927        While(0)
928        ControlUpdate/A/W=NSORT_Panel
929                DoUpdate
930               
931End
932
933//when menu is popped, it gets a valid list to display and updates the control
934//
935// 2002- always refreshes, as new (fast) filter is used
936Function LowQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
937        String ctrlName
938        Variable popNum
939        String popStr
940
941        String/G root:myGlobals:NSORT:gDataPopList = ReducedDataFileList("")
942        ControlUpdate popup_1
943
944        return(0)
945End
946
947//when menu is popped, it gets a valid list to display and updates the control
948//
949Function MedQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
950        String ctrlName
951        Variable popNum
952        String popStr
953               
954        String/G root:myGlobals:NSORT:gDataPopList_3 = "none;" +  ReducedDataFileList("")
955        ControlUpdate popup_2
956        if(cmpstr(popStr,"none")==0)
957                PopupMenu popup_3,mode=1        //force "none" (item #1) to be the selection
958                CheckBox AutoCheck,value=0      //un-check the auto-scale checkbox
959                DoAlert 0,"You have only one data set. Auto Scaling has been unchecked and Mult Factor 1-2 will be applied to your data. Remember to re-check this as needed"// remind the user of this fact
960                RemoveFromGraph/Z MedQSet_i,TrimMedQSet_i,HighQSet_i,TrimHighQSet_i             //remove the data from the graph
961        Endif   
962        return(0)
963End
964
965//when menu is popped, it gets a valid list to display and updates the control
966// - will be different, since set 3 can also be "none" if only 2 sets
967//are to be NSORTed
968//
969Function HighQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
970        String ctrlName
971        Variable popNum
972        String popStr
973
974        //add the option "none" to the file list (which should already end with a semicolon)
975        String/G root:myGlobals:NSORT:gDataPopList_3 = "none;" +  ReducedDataFileList("")
976
977        ControlUpdate/W=NSORT_Panel popup_3
978        if(cmpstr(popStr,"none")==0)
979                RemoveFromGraph/Z HighQSet_i,TrimHighQSet_i             //remove the data from the graph
980        Endif   
981        ControlInfo/W=NSORT_Panel popup_2
982        if(cmpstr(S_Value,"none")==0)
983                PopupMenu popup_3,win=NSORT_Panel,mode=1        //force "none" (item #1) to be the selection if medium is none
984        endif
985        return(0)       
986End
987
988
989//be sure to use the "Trim.." datasets that have had the bad points removed
990//and then do the scaling based on the choices in the panel
991//input (auto) is a switch
992//
993Function DoAutoScaleFromPanel(auto)
994        Variable auto           //if auto == 1, do the scaling, if 0, use manual scale values
995
996        NVAR normTo = root:myGlobals:NSORT:gNormToNum
997        Variable err=0,setNum,norm12,norm23
998        String fileStr="",tempName="",name1="",name2="",name3="",normToStr=""
999       
1000//Set the number of output columns
1001        Variable numOutputColumns = 0
1002
1003        NVAR Columns1 = root:myGlobals:NSORT:gColumns1
1004        NVAR Columns2 = root:myGlobals:NSORT:gColumns2
1005        NVAR Columns3 = root:myGlobals:NSORT:gColumns3
1006        if( (Columns1 == 3) || (Columns2 == 3) || (Columns3 == 3) )
1007                numOutputColumns = 3
1008        else
1009                if( (Columns1 == 6) && (Columns2 == 6) && ((Columns3 == 0) || (Columns3 == 6)) )
1010                        numOutputColumns = 6
1011                endif
1012        endif
1013
1014        //rescale 1-2
1015       
1016        //load file1
1017        ControlInfo $"popup_1"
1018        fileStr = S_Value
1019        name1 = fileStr
1020        setNum = 1
1021        //get a valid file based on this partialName and catPathName
1022        tempName = FindValidFilename(fileStr)
1023       
1024        //prepend path to tempName for read routine
1025        PathInfo catPathName
1026        tempName = S_path + tempName
1027        err = LoadDataForNSORT(tempName,setNum)
1028        //////end load file1
1029       
1030        //load file2
1031        ControlInfo $"popup_2"
1032        fileStr = S_Value
1033        name2 = fileStr
1034        setNum = 2
1035        //get a valid file based on this partialName and catPathName
1036        tempName = FindValidFilename(fileStr)
1037       
1038        //prepend path to tempName for read routine
1039        PathInfo catPathName
1040        tempName = S_path + tempName
1041        err = LoadDataForNSORT(tempName,setNum)
1042        //////end load file2
1043       
1044        //load file3 , if necessary
1045        ControlInfo $"popup_3"
1046        fileStr = S_Value
1047        name3 = fileStr
1048        setNum = 3
1049        if(cmpstr(fileStr,"none") == 0)
1050                //do nothing
1051        else
1052                //get a valid file based on this partialName and catPathName
1053                tempName = FindValidFilename(fileStr)
1054       
1055                //prepend path to tempName for read routine
1056                PathInfo catPathName
1057                tempName = S_path + tempName
1058                err = LoadDataForNSORT(tempName,setNum)
1059        Endif
1060        //////end load file3
1061       
1062        //assign filename of file to normalize to
1063        if(normTo == 1)
1064                normToStr = name1
1065        else
1066                if(normTo == 2)
1067                        normToStr = name2
1068                else
1069                        normToStr = name3
1070                Endif
1071        Endif
1072
1073        Variable n1,n2,n12,num2
1074        Variable n3,n123
1075       
1076   if(numOutputColumns == 3) //Start the 3-column specific stuff here.
1077                //order points in sets 1-2, indexing overlap region
1078                //put result in temporary waves
1079                WaveStats/Q $"TrimLowQSet_q"
1080                n1 = V_npnts
1081                WaveStats/Q $"TrimMedQSet_q"
1082                n2 = V_npnts
1083                n12 = n1+ n2
1084               
1085                Make/O/N=(n12) q12,i12,sig12
1086                WAVE lowq = $"TrimLowQSet_q"
1087                WAVE medq = $"TrimMedQSet_q"
1088                WAVE lowi = $"TrimLowQSet_i"
1089                WAVE medi =  $"TrimMedQSet_i"
1090                WAVE lows = $"TrimLowQSet_s"
1091                WAVE meds = $"TrimMedQSet_s"
1092                q12[0,n1-1] = lowq[p]
1093                q12[n1,n1+n2-1]= medq[p-n1]
1094                i12[0,n1-1] = lowi[p]
1095                i12[n1,n1+n2-1]= medi[p-n1]
1096                sig12[0,n1-1] = lows[p]
1097                sig12[n1,n1+n2-1]= meds[p-n1]
1098               
1099                Sort q12, q12,i12,sig12
1100                /////////////////
1101               
1102                //find the maximum point number of set 2  in the overlap region
1103                FindLevel/P/Q medq,(lowq[n1-1])
1104                num2 = trunc(V_levelX)
1105                //Print "num2 = ",num2
1106               
1107                if (auto)
1108                        //there must be overlap points to use auto-scaling
1109                        if(numtype(num2) != 0)
1110                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1111                        endif
1112                        //do auto-scaling of data
1113                        norm12 = GetScalingInOverlap(num2,lowq,lowi,medq,medi)
1114                        //Set the global variable for the 1-2 scale factor
1115                        Variable/G root:myGlobals:NSORT:gScale1_2 = norm12
1116                else
1117                        //use the value from the panel ( which is the global)
1118                        NVAR temp12 = root:myGlobals:NSORT:gScale1_2
1119                        norm12 = temp12
1120                Endif
1121               
1122                If(normTo== 2)
1123                        //normalize to second file, so multiply 1st by 1/norm
1124                        norm12 = 1/norm12
1125                        lowi *= norm12
1126                        lows *= norm12
1127                else
1128                        //normalize to first file, OR THIRD FILE so multiply 2nd by norm
1129                        medi *= norm12
1130                        meds *= norm12
1131                Endif
1132               
1133                //Print "NSORT-ed ",name1," + ", name2
1134                //Print "normalized to ",normTo
1135                //Print "multiplicative factor = ",norm12
1136               
1137               
1138                //Make the combined, scaled dataset by overwriting the old sets
1139                Make/O/N=(n12) q12,i12,sig12
1140                q12[0,n1-1] = lowq[p]
1141                q12[n1,n1+n2-1]= medq[p-n1]
1142                i12[0,n1-1] = lowi[p]
1143                i12[n1,n1+n2-1]= medi[p-n1]
1144                sig12[0,n1-1] = lows[p]
1145                sig12[n1,n1+n2-1]= meds[p-n1]
1146               
1147                Sort q12, q12,i12,sig12
1148                //at this point 1-2 are combined
1149               
1150                ControlUpdate/A/W=NSORT_Panel
1151                DoUpdate
1152               
1153                //do we need to continue, or write out the set here and stop?
1154                if(cmpstr(name3,"none") == 0)
1155                        //stop here
1156                        norm23 = 1              //norm23 was not used
1157                        Variable/G root:myGlobals:NSORT:gScale2_3 = 1
1158                        //If any of them have three columns write three column data
1159                       
1160                        ControlInfo/W=NSORT_Panel PreviewCheck
1161                        if( V_Value==0 )                //if zero skip the preview and write out the file
1162                                err=Write3ColNSORTedFile(q12,i12,sig12,name1,name2,name3,normToStr,norm12,norm23)
1163                        endif
1164                        //cleanup waves before exiting
1165                        KillWaves/Z q12,i12,sig12
1166                        return err
1167                Endif
1168               
1169                //need to add the third file... which was already loaded at the top of the function
1170                /////
1171                //order points in sets 12-3, indexing overlap region
1172                //put result in temporary waves
1173                WaveStats/Q q12
1174                n12 = V_npnts
1175                WaveStats/Q $"TrimHighQSet_q"
1176                n3 = V_npnts
1177                n123 = n12+ n3
1178               
1179                Make/O/N=(n123) q123,i123,sig123
1180                WAVE highq = $"TrimHighQSet_q"
1181                WAVE highi = $"TrimHighQSet_i"
1182                WAVE highs = $"TrimHighQSet_s"
1183       
1184                q123[0,n12-1] = q12[p]
1185                q123[n1,n12+n3-1]= highq[p-n12]
1186                i123[0,n12-1] = i12[p]
1187                i123[n1,n12+n3-1]= highi[p-n12]
1188                sig123[0,n12-1] = sig12[p]
1189                sig123[n1,n12+n3-1]= highs[p-n12]
1190               
1191                Sort q123, q123,i123,sig123
1192                /////////////////
1193               
1194                //find the maximum point number of set 2  in the overlap region
1195                FindLevel/P/Q highq,(q12[n12-1])
1196                num2 = trunc(V_levelX)
1197                //Print "num2 = ",num2
1198               
1199                if (auto)
1200                        //there must be overlap points to use auto-scaling
1201                        if(numtype(num2) != 0)
1202                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1203                        endif
1204                        //do auto-scaling of data
1205                        norm23 = GetScalingInOverlap(num2,q12,i12,highq,highi)
1206                        //Set the global variable for the 12 - 3 scale factor
1207                        Variable/G root:myGlobals:NSORT:gScale2_3 = norm23
1208                else
1209                        //use the value from the panel ( which is the global)
1210                        NVAR temp23 = root:myGlobals:NSORT:gScale2_3
1211                        norm23 = temp23
1212                Endif
1213               
1214                If( (normTo== 1) || (normTo ==2) )
1215                        //normalize to first or second file, so multiply third by norm23
1216                        highi *= norm23
1217                        highs *= norm23
1218                else
1219                        //normalize to THIRD file, 1-2 by 1/norm23
1220                        norm23 = 1/norm23
1221                        i12 *= norm23
1222                        sig12 *= norm23
1223                Endif
1224               
1225                ControlUpdate/A/W=NSORT_Panel
1226                DoUpdate
1227
1228                //Print "NSORT-ed ",name1," + ", name2, " + ", name3
1229                //Print "normalized to ",normTo
1230                //Print "multiplicative factor 1-2 = ",norm12," multiplicative factor 12 - 3 = ",norm23
1231               
1232               
1233                Make/O/N=(n123) q123,i123,sig123
1234                q123[0,n12-1] = q12[p]
1235                q123[n12,n12+n3-1]= highq[p-n12]
1236                i123[0,n12-1] = i12[p]
1237                i123[n12,n12+n3-1]= highi[p-n12]
1238                sig123[0,n12-1] = sig12[p]
1239                sig123[n12,n12+n3-1]= highs[p-n12]
1240               
1241                Sort q123, q123,i123,sig123
1242                //at this point 12 - 3 are combined
1243                //write out the set here and stop
1244       
1245                ControlInfo/W=NSORT_Panel PreviewCheck
1246                if( V_Value==0 )                //if zero skip the preview and write out the file
1247                        err=Write3ColNSORTedFile(q123,i123,sig123,name1,name2,name3,normToStr,norm12,norm23)
1248                endif
1249                //cleanup waves before exiting
1250                KillWaves/Z q12,i12,sig12,q123,i123,sig123
1251                //combined dataset will already be displayed if the NSORT_Graph is open
1252       
1253                ////////////////
1254                return err
1255   endif // End the 3-column specific stuff here
1256
1257   if(numOutputColumns == 6) // Start the 6-column specific stuff here
1258                //order points in sets 1-2, indexing overlap region
1259                //put result in temporary waves
1260                WaveStats/Q $"TrimLowQSet_q"
1261                n1 = V_npnts
1262                WaveStats/Q $"TrimMedQSet_q"
1263                n2 = V_npnts
1264                n12 = n1+ n2
1265               
1266                Make/O/N=(n12) q12,i12,sig12,sq12,qb12,fs12
1267                WAVE lowq = $"TrimLowQSet_q"
1268                WAVE medq = $"TrimMedQSet_q"
1269                WAVE lowi = $"TrimLowQSet_i"
1270                WAVE medi =  $"TrimMedQSet_i"
1271                WAVE lows = $"TrimLowQSet_s"
1272                WAVE meds = $"TrimMedQSet_s"
1273                WAVE lowsq = $"TrimLowQSet_sq"
1274                WAVE medsq = $"TrimMedQSet_sq"
1275                WAVE lowqb = $"TrimLowQSet_qb"
1276                WAVE medqb =  $"TrimMedQSet_qb"
1277                WAVE lowfs = $"TrimLowQSet_fs"
1278                WAVE medfs = $"TrimMedQSet_fs"
1279       
1280                q12[0,n1-1] = lowq[p]
1281                q12[n1,n1+n2-1]= medq[p-n1]
1282                i12[0,n1-1] = lowi[p]
1283                i12[n1,n1+n2-1]= medi[p-n1]
1284                sig12[0,n1-1] = lows[p]
1285                sig12[n1,n1+n2-1]= meds[p-n1]
1286                sq12[0,n1-1] = lowsq[p]
1287                sq12[n1,n1+n2-1]= medsq[p-n1]
1288                qb12[0,n1-1] = lowqb[p]
1289                qb12[n1,n1+n2-1]= medqb[p-n1]
1290                fs12[0,n1-1] = lowfs[p]
1291                fs12[n1,n1+n2-1]= medfs[p-n1]
1292               
1293                Sort q12, q12,i12,sig12,sq12,qb12,fs12
1294                /////////////////
1295               
1296                //find the maximum point number of set 2  in the overlap region
1297                FindLevel/P/Q medq,(lowq[n1-1])
1298                num2 = trunc(V_levelX)
1299                //Print "num2 = ",num2
1300               
1301                if (auto)
1302                        //there must be overlap points to use auto-scaling
1303                        if(numtype(num2) != 0)
1304                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1305                        endif
1306                        //do auto-scaling of data
1307                        norm12 = GetScalingInOverlap(num2,lowq,lowi,medq,medi)
1308                        //Set the global variable for the 1-2 scale factor
1309                        Variable/G root:myGlobals:NSORT:gScale1_2 = norm12
1310                else
1311                        //use the value from the panel ( which is the global)
1312                        NVAR temp12 = root:myGlobals:NSORT:gScale1_2
1313                        norm12 = temp12
1314                Endif
1315               
1316                If(normTo== 2)
1317                        //normalize to second file, so multiply 1st by 1/norm
1318                        norm12 = 1/norm12
1319                        lowi *= norm12
1320                        lows *= norm12
1321                else
1322                        //normalize to first file, OR THIRD FILE so multiply 2nd by norm
1323                        medi *= norm12
1324                        meds *= norm12
1325                Endif
1326               
1327                //Print "NSORT-ed ",name1," + ", name2
1328                //Print "normalized to ",normTo
1329                //Print "multiplicative factor = ",norm12
1330                ControlUpdate/A/W=NSORT_Panel
1331                DoUpdate
1332
1333               
1334                //Make the combined, scaled dataset by overwriting the old sets
1335                Make/O/N=(n12) q12,i12,sig12,sq12,qb12,fs12
1336                q12[0,n1-1] = lowq[p]
1337                q12[n1,n1+n2-1]= medq[p-n1]
1338                i12[0,n1-1] = lowi[p]
1339                i12[n1,n1+n2-1]= medi[p-n1]
1340                sig12[0,n1-1] = lows[p]
1341                sig12[n1,n1+n2-1]= meds[p-n1]
1342                sq12[0,n1-1] = lowsq[p]
1343                sq12[n1,n1+n2-1]= medsq[p-n1]
1344                qb12[0,n1-1] = lowqb[p]
1345                qb12[n1,n1+n2-1]= medqb[p-n1]
1346                fs12[0,n1-1] = lowfs[p]
1347                fs12[n1,n1+n2-1]= medfs[p-n1]
1348               
1349                Sort q12, q12,i12,sig12,sq12,qb12,fs12
1350                //at this point 1-2 are combined
1351                //do we need to continue, or write out the set here and stop?
1352                if(cmpstr(name3,"none") == 0)
1353                        //stop here
1354                        norm23 = 1              //norm23 was not used
1355                        Variable/G root:myGlobals:NSORT:gScale2_3 = 1
1356                       
1357                        ControlInfo/W=NSORT_Panel PreviewCheck
1358                        if( V_Value==0 )                //if zero skip the preview and write out the file
1359                                //If any of them have three columns write three column data
1360                                err=Write6ColNSORTedFile(q12,i12,sig12,sq12,qb12,fs12,name1,name2,name3,normToStr,norm12,norm23)
1361                        endif
1362                        // always clean up waves before exiting
1363                        KillWaves/Z q12,i12,sig12,sq12,qb12,fs12
1364                        return err
1365                Endif
1366               
1367                //need to add the third file... which was already loaded at the top of the function
1368                /////
1369                //order points in sets 12-3, indexing overlap region
1370                //put result in temporary waves
1371                WaveStats/Q q12
1372                n12 = V_npnts
1373                WaveStats/Q $"TrimHighQSet_q"
1374                n3 = V_npnts
1375                n123 = n12+ n3
1376               
1377                Make/O/N=(n123) q123,i123,sig123,sq123,qb123,fs123
1378                WAVE highq = $"TrimHighQSet_q"
1379                WAVE highi = $"TrimHighQSet_i"
1380                WAVE highs = $"TrimHighQSet_s"
1381                WAVE highsq = $"TrimHighQSet_sq"
1382                WAVE highqb = $"TrimHighQSet_qb"
1383                WAVE highfs = $"TrimHighQSet_fs"
1384       
1385                q123[0,n12-1] = q12[p]
1386                q123[n1,n12+n3-1]= highq[p-n12]
1387                i123[0,n12-1] = i12[p]
1388                i123[n1,n12+n3-1]= highi[p-n12]
1389                sig123[0,n12-1] = sig12[p]
1390                sig123[n1,n12+n3-1]= highs[p-n12]
1391                sq123[0,n12-1] = sq12[p]
1392                sq123[n1,n12+n3-1]= highsq[p-n12]
1393                qb123[0,n12-1] = qb12[p]
1394                qb123[n1,n12+n3-1]= highqb[p-n12]
1395                fs123[0,n12-1] = fs12[p]
1396                fs123[n1,n12+n3-1]= highfs[p-n12]
1397               
1398                Sort q123, q123,i123,sig123,sq123,qb123,fs123
1399                /////////////////
1400               
1401                //find the maximum point number of set 2  in the overlap region
1402                FindLevel/P/Q highq,(q12[n12-1])
1403                num2 = trunc(V_levelX)
1404                //Print "num2 = ",num2
1405               
1406                if (auto)
1407                        //there must be overlap points to use auto-scaling
1408                        if(numtype(num2) != 0)
1409                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1410                        endif
1411                        //do auto-scaling of data
1412                        norm23 = GetScalingInOverlap(num2,q12,i12,highq,highi)
1413                        //Set the global variable for the 12 - 3 scale factor
1414                        Variable/G root:myGlobals:NSORT:gScale2_3 = norm23
1415                else
1416                        //use the value from the panel ( which is the global)
1417                        NVAR temp23 = root:myGlobals:NSORT:gScale2_3
1418                        norm23 = temp23
1419                Endif
1420               
1421                If( (normTo== 1) || (normTo ==2) )
1422                        //normalize to first or second file, so multiply third by norm23
1423                        highi *= norm23
1424                        highs *= norm23
1425                else
1426                        //normalize to THIRD file, 1-2 by 1/norm23
1427                        norm23 = 1/norm23
1428                        i12 *= norm23
1429                        sig12 *= norm23
1430                Endif
1431               
1432                //Print "NSORT-ed ",name1," + ", name2, " + ", name3
1433                //Print "normalized to ",normTo
1434                //Print "multiplicative factor 1-2 = ",norm12," multiplicative factor 12 - 3 = ",norm23
1435                ControlUpdate/A/W=NSORT_Panel
1436                DoUpdate
1437               
1438                Make/O/N=(n123) q123,i123,sig123,sq123,qb123,fs123
1439                q123[0,n12-1] = q12[p]
1440                q123[n12,n12+n3-1]= highq[p-n12]
1441                i123[0,n12-1] = i12[p]
1442                i123[n12,n12+n3-1]= highi[p-n12]
1443                sig123[0,n12-1] = sig12[p]
1444                sig123[n12,n12+n3-1]= highs[p-n12]
1445                sq123[0,n12-1] = sq12[p]
1446                sq123[n12,n12+n3-1]= highsq[p-n12]
1447                qb123[0,n12-1] = qb12[p]
1448                qb123[n12,n12+n3-1]= highqb[p-n12]
1449                fs123[0,n12-1] = fs12[p]
1450                fs123[n12,n12+n3-1]= highfs[p-n12]
1451               
1452                Sort q123, q123,i123,sig123,sq123,qb123,fs123
1453                //at this point 12 - 3 are combined
1454                //write out the set here and stop
1455       
1456                ControlInfo/W=NSORT_Panel PreviewCheck
1457                if( V_Value==0 )                //if zero skip the preview and write out the file
1458                        err=Write6ColNSORTedFile(q123,i123,sig123,sq123,qb123,fs123,name1,name2,name3,normToStr,norm12,norm23)
1459                endif
1460                //cleanup waves before exiting
1461                KillWaves/Z q12,i12,sig12,sq12,qb12,fs12,q123,i123,sig123,sq123,qb123,fs123
1462                //combined dataset will already be displayed if the NSORT_Graph is open
1463       
1464                ////////////////
1465                return err
1466   endif // End the 6-column specific stuff here
1467       
1468End
1469
1470
1471
1472/////////////////////////////////////////////////////////////
1473// testing, may speed up NSORT, NCNR-specific naming scheme of
1474// run numbers and a run prefix
1475Proc Set3NSORTFiles(low,med,hi,pref)
1476        Variable low=1,med=2,hi=3
1477        String pref="LIPID"
1478       
1479        //make strings from the numbers
1480        String absStr=""
1481        Variable popNum
1482        DoWindow/F NSORT_Panel
1483       
1484        //lowQ menu
1485        absStr = pref+ThreeDigitString(low)+".ABS"
1486        popNum = 1+WhichListItem(absStr,root:myGlobals:NSORT:gDataPopList,";",0)
1487        PopupMenu popup_1,win=NSORT_Panel,mode=(popNum)
1488        //medQ (a different list for the popup)
1489        absStr = pref+ThreeDigitString(med)+".ABS"
1490        popNum = 1+WhichListItem(absStr,root:myGlobals:NSORT:gDataPopList_3,";",0)
1491        PopupMenu popup_2,win=NSORT_Panel,mode=(popNum)
1492        //highQ (same pop list as medQ)
1493        if(hi != 0)
1494                absStr = pref+ThreeDigitString(hi)+".ABS"
1495                popNum = 1+WhichListItem(absStr,root:myGlobals:NSORT:gDataPopList_3,";",0)
1496                PopupMenu popup_3,win=NSORT_Panel,mode=(popNum)
1497        else
1498                PopupMenu popup_3,win=NSORT_Panel,mode=(1)
1499        endif
1500End
1501
1502//make a three character string of the run number
1503Function/S ThreeDigitString(num)
1504        Variable num
1505       
1506        String numStr=""
1507        if(num<10)
1508                numStr = "00"+num2str(num)
1509        else
1510                if(num<100)
1511                        numStr = "0"+num2str(num)
1512                else
1513                        numStr = num2str(num)
1514                Endif
1515        Endif
1516        //Print "numstr = ",numstr
1517        return(numstr)
1518End
1519
1520//more beta procedures - to create a table of scattering runs to combine with NSORT
1521Proc CreateTableToCombine()
1522       
1523        NewDataFolder/O root:myGlobals:CombineTable
1524        DoWindow/F CombineTable
1525       
1526        Make/O/T/N=0 $"root:myGlobals:CombineTable:Filenames"
1527        Make/O/T/N=0 $"root:myGlobals:CombineTable:Suffix"
1528        Make/O/T/N=0 $"root:myGlobals:CombineTable:Labels"
1529        Make/O/D/N=0 $"root:myGlobals:CombineTable:SDD"
1530        Make/O/D/N=0 $"root:myGlobals:CombineTable:RunNumber"
1531        Make/O/D/N=0 $"root:myGlobals:CombineTable:IsTrans"
1532
1533        If(V_Flag==0)
1534                BuildCombineTableWindow()
1535                ModifyTable width(:myGlobals:CombineTable:SDD)=40
1536                ModifyTable width(:myGlobals:CombineTable:Labels)=180
1537               
1538                ModifyTable width(Point)=0              //JUN04, remove point numbers - confuses users since point != run
1539        Endif
1540
1541        //get a list of all files in the folder, some will be junk version numbers that don't exist     
1542        String list,partialName,tempName,temp=""
1543        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
1544        Variable numitems,ii,ok
1545       
1546        //remove version numbers from semicolon-delimited list
1547        list =  RemoveVersNumsFromList(list)
1548        numitems = ItemsInList(list,";")
1549       
1550        //loop through all of the files in the list, reading CAT/SHORT information if the file is RAW SANS
1551        //***version numbers have been removed***
1552        String str,fullName
1553        Variable lastPoint
1554        ii=0
1555       
1556        Make/T/O/N=0 notRAWlist
1557        do
1558                //get current item in the list
1559                partialName = StringFromList(ii, list, ";")
1560                //get a valid file based on this partialName and catPathName
1561                tempName = FindValidFilename(partialName)
1562                If(cmpstr(tempName,"")==0)              //a null string was returned
1563                        //write to notebook that file was not found
1564                        //if string is not a number, report the error
1565                        if(str2num(partialName) == NaN)
1566                                str = "this file was not found: "+partialName+"\r\r"
1567                                //Notebook CatWin,font="Times",fsize=12,text=str
1568                        Endif
1569                else
1570                        //prepend path to tempName for read routine
1571                        PathInfo catPathName
1572                        FullName = S_path + tempName
1573                        //make sure the file is really a RAW data file
1574                        ok = CheckIfRawData(fullName)
1575                        if (!ok)
1576                                //write to notebook that file was not a RAW SANS file
1577                                lastPoint = numpnts(notRAWlist)
1578                                InsertPoints lastPoint,1,notRAWlist
1579                                notRAWlist[lastPoint]=tempname
1580                        else
1581                                //go write the header information to the Notebook
1582                                GetHeaderInfoToCombineWave(fullName,tempName)
1583                        Endif
1584                Endif
1585                ii+=1
1586        while(ii<numitems)
1587//Now sort them all based on the suffix data (orders them as collected)
1588//      SortCombineWaves()
1589// sort by label
1590        SortCombineByLabel()
1591// remove the transmission waves
1592//
1593        RemoveTransFilesFromCombine()
1594//
1595// make the waves and table for the sets to combine
1596        Make/O/N=0 $"root:myGlobals:CombineTable:LowRun"
1597        Make/O/N=0 $"root:myGlobals:CombineTable:MediumRun"
1598        Make/O/N=0 $"root:myGlobals:CombineTable:HighRun"
1599        Make/O/T/N=0 $"root:myGlobals:CombineTable:Prefix"
1600        Make/O/T/N=0 $"root:myGlobals:CombineTable:SaveName"
1601        MakeTableToCombine()
1602
1603End
1604
1605
1606Function RemoveTransFilesFromCombine()
1607        Wave/T filenames = $"root:myGlobals:CombineTable:Filenames"
1608        Wave/T suffix = $"root:myGlobals:CombineTable:Suffix"
1609        Wave/T labels = $"root:myGlobals:CombineTable:Labels"
1610        Wave sdd = $"root:myGlobals:CombineTable:SDD"
1611        Wave runnum = $"root:myGlobals:CombineTable:RunNumber"
1612        Wave isTrans = $"root:myGlobals:CombineTable:IsTrans"
1613       
1614        Variable num=numpnts(isTrans),ii
1615        ii=num-1
1616        do
1617                if(isTrans[ii] != 0)
1618                        DeletePoints ii, 1, filenames,suffix,labels,sdd,runnum,isTrans
1619                endif
1620                ii-=1
1621        while(ii>=0)
1622        return(0)
1623End
1624
1625Function MakeTabletoCombine()
1626
1627        Wave low = $"root:myGlobals:CombineTable:LowRun"
1628        Wave medium = $"root:myGlobals:CombineTable:MediumRun"
1629        Wave high = $"root:myGlobals:CombineTable:HighRun"
1630        Wave/T prefix = $"root:myGlobals:CombineTable:Prefix"
1631        Wave/T saveName = $"root:myGlobals:CombineTable:SaveName"
1632
1633        DoWindow/F ToCombine
1634        if(V_flag==0)
1635                edit Low,Medium,High,Prefix,SaveName as "Run Numbers to Combine"
1636                DoWindow/C ToCombine
1637        endif
1638        AutoPositionWindow/M=1/R=CombineTable toCombine
1639       
1640       
1641        /////
1642//      SetWindow kwTopWin hook=CombineTableHook, hookevents=1  // mouse down events
1643       
1644end
1645
1646Function BuildCombineTableWindow()
1647        Wave/T Filenames = $"root:myGlobals:CombineTable:Filenames"
1648        Wave/T Labels = $"root:myGlobals:CombineTable:Labels"
1649        Wave SDD = $"root:myGlobals:CombineTable:SDD"
1650        Wave/T suffix = $"root:myGlobals:CombineTable:Suffix"
1651        Wave runnum = $"root:myGlobals:CombineTable:RunNumber"
1652        Wave isTrans = $"root:myGlobals:CombineTable:IsTrans"
1653       
1654//      Edit Filenames, Labels, DateAndTime, SDD, Lambda, CntTime, TotCnts, CntRate, Transmission, Thickness, XCenter, YCenter, NumAttens as "Files to Combine"
1655        Edit Labels, SDD, runNum as "Files to Combine"
1656        SetWindow kwTopWin hook=CombineTableHook, hookevents=1  // mouse down events
1657
1658        String name="CombineTable"
1659        DoWindow/C $name
1660        return(0)
1661End
1662
1663//reads header information and puts it in the appropriate waves for display in the table.
1664//fname is the full path for opening (and reading) information from the file
1665//which alreay was found to exist. sname is the file;vers to be written out,
1666//avoiding the need to re-extract it from fname.
1667Function GetHeaderInfoToCombineWave(fname,sname)
1668        String fname,sname
1669       
1670        String textstr,temp,lbl,date_time,suffix
1671        Variable ctime,lambda,sdd,detcnt,cntrate,refNum,trans,thick,xcenter,ycenter,numatten
1672        Variable lastPoint, beamstop
1673
1674        Wave/T GFilenames = $"root:myGlobals:CombineTable:Filenames"
1675        Wave/T GSuffix = $"root:myGlobals:CombineTable:Suffix"
1676        Wave/T GLabels = $"root:myGlobals:CombineTable:Labels"
1677        Wave GSDD = $"root:myGlobals:CombineTable:SDD"
1678        Wave GRunNumber = $"root:myGlobals:CombineTable:RunNumber"
1679        Wave GIsTrans = $"root:myGlobals:CombineTable:IsTrans"
1680       
1681        lastPoint = numpnts(GLambda)
1682               
1683        InsertPoints lastPoint,1,GFilenames
1684        GFilenames[lastPoint]=sname
1685       
1686        //read the file suffix
1687        InsertPoints lastPoint,1,GSuffix
1688        GSuffix[lastPoint]=getSuffix(fname)
1689
1690        // read the sample.label text field
1691        InsertPoints lastPoint,1,GLabels
1692        GLabels[lastPoint]=getSampleLabel(fname)
1693       
1694        //read in the SDD
1695        InsertPoints lastPoint,1,GSDD
1696        GSDD[lastPoint]= getSDD(fname)
1697
1698        //the run number (not displayed in the table, but carried along)
1699        InsertPoints lastPoint,1,GRunNumber
1700        GRunNumber[lastPoint] = GetRunNumFromFile(sname)
1701
1702        // 0 if the file is a scattering  file, 1 (truth) if the file is a transmission file
1703        InsertPoints lastPoint,1,GIsTrans
1704        GIsTrans[lastPoint]  = isTransFile(fname)               //returns one if beamstop is "out"
1705       
1706        KillWaves/Z w
1707        return(0)
1708End
1709
1710//sorts all of the waves of header information using the suffix (A123)
1711//the result is that all of the data is in the order that it was collected,
1712// regardless of how the prefix or run numbers were changed by the user
1713Function SortCombineWaves()
1714        Wave/T GFilenames = $"root:myGlobals:CombineTable:Filenames"
1715        Wave/T GSuffix = $"root:myGlobals:CombineTable:Suffix"
1716        Wave/T GLabels = $"root:myGlobals:CombineTable:Labels"
1717        Wave GSDD = $"root:myGlobals:CombineTable:SDD"
1718        Wave GRunNumber = $"root:myGlobals:CombineTable:RunNumber"
1719        Wave GIsTrans = $"root:myGlobals:CombineTable:IsTrans"
1720
1721//      Sort GSuffix, GSuffix, GFilenames, GLabels, GDateTime, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens,GRunNumber,GIsTrans
1722        Sort GSuffix, GSuffix, GFilenames, GLabels, GSDD, GRunNumber, GIsTrans
1723        return(0)
1724End
1725
1726//sorts all of the waves of header information using the suffix (A123)
1727//the result is that all of the data is in the order that it was collected,
1728// regardless of how the prefix or run numbers were changed by the user
1729Function SortCombineByLabel()
1730        Wave/T GFilenames = $"root:myGlobals:CombineTable:Filenames"
1731        Wave/T GSuffix = $"root:myGlobals:CombineTable:Suffix"
1732        Wave/T GLabels = $"root:myGlobals:CombineTable:Labels"
1733        Wave GSDD = $"root:myGlobals:CombineTable:SDD"
1734        Wave GRunNumber = $"root:myGlobals:CombineTable:RunNumber"
1735        Wave GIsTrans = $"root:myGlobals:CombineTable:IsTrans"
1736
1737        Sort GLabels, GSuffix, GFilenames, GLabels, GSDD, GRunNumber, GIsTrans
1738//      Sort {GLabels, GSDD}, GSuffix, GFilenames, GLabels, GSDD, GRunNumber, GIsTrans          //sort on GLabels, GSDD breaks the tie
1739        return(0)
1740End
1741
1742//main procedure, called from the menu
1743// sets a flag (temporarily) to use the names from the table
1744// during the procedure that writes the data files.
1745//
1746//
1747Proc  DoCombineFiles()
1748       
1749        // pop all of the menus to make sure that they are properly populated
1750        LowQPopMenuProc("",1,"")
1751        MedQPopMenuProc("",1,"")
1752        HighQPopMenuProc("",1,"")
1753       
1754        String savedDataFolder = GetDataFolder(1)               // save
1755        SetDataFolder root:myGlobals:CombineTable:
1756
1757        Variable/G useTable=1
1758       
1759        Variable num=numpnts(lowRun),ii,lowFile,medFile,hiFile
1760        String prefixStr = ""
1761        Pathinfo catPathName
1762        String path=S_Path
1763       
1764        ii=0
1765        do
1766                lowFile = LowRun[ii]
1767                medFile = MediumRun[ii]
1768                hiFile = highRun[ii]
1769                prefixStr = prefix[ii]
1770               
1771                Set3NSORTFiles(lowFile,medFile,hiFile,prefixStr)                //set the files and pop the NSORT popups
1772               
1773                //pass the new file name in as a global (ugh!)
1774                String/G root:myGlobals:CombineTable:SaveNameStr = path+saveName[ii]
1775                //combine the files and write the data
1776                WriteNSORTFileButton("")
1777               
1778                ii+=1
1779        while(ii<num)
1780
1781        Variable/G useTable=0
1782       
1783        SetDataFolder savedDataFolder
1784
1785End
1786
1787
1788// Commentized lines here are incomplete - and NON-FUNCTIONING
1789//
1790//// Window hook example:
1791//
1792Function CombineTableHook(infoStr)
1793        String infoStr
1794        String event= StringByKey("EVENT",infoStr)
1795//      Print "EVENT= ",event
1796        strswitch(event)
1797                case "mousedown":
1798                        Variable xpix= NumberByKey("MOUSEX",infoStr)
1799                        Variable ypix= NumberByKey("MOUSEY",infoStr)
1800                        Variable modif= NumberByKey("MODIFIERS",infoStr)
1801                        //print modif
1802                        if(modif & 2^1)         //bit 1 set, shift key is down
1803                                PopupContextualMenu/C=(xpix, ypix) "combine;"
1804                                strswitch(S_selection)
1805                                        case "combine":
1806                                                //Print "combine the files"
1807                                                SendSelectionToTable()
1808                                                break
1809        //                              case "no":
1810        //                                      break
1811        //                              case "maybe":
1812        //                                      // do something because "maybe" was chosen
1813        //                                      break
1814                                endswitch               //on selection
1815                        endif
1816        endswitch       // on event
1817       
1818        return 0
1819End
1820
1821//ASSUMES 3 FILES!!!!
1822Function SendSelectionToTable()
1823
1824        DoWindow/F CombineTable
1825        if(V_flag==0)
1826//              Make/O/N=0 $"root:myGlobals:CombineTable:Low"
1827//              Make/O/N=0 $"root:myGlobals:CombineTable:Medium"
1828//              Make/O/N=0 $"root:myGlobals:CombineTable:High"
1829//              Make/O/T/N=0 $"root:myGlobals:CombineTable:Prefix"
1830//              Make/O/T/N=0 $"root:myGlobals:CombineTable:SaveName"
1831//              edit Low,Medium,High,Prefix,SaveName as "Run Numbers to Combine"
1832//              DoWindow/C ToCombine
1833
1834                return(0)
1835               
1836        else
1837                Wave low = $"root:myGlobals:CombineTable:LowRun"
1838                Wave medium = $"root:myGlobals:CombineTable:MediumRun"
1839                Wave high = $"root:myGlobals:CombineTable:HighRun"
1840                Wave/T prefix = $"root:myGlobals:CombineTable:Prefix"
1841                Wave/T saveName = $"root:myGlobals:CombineTable:SaveName"
1842               
1843                Wave/T gLabels = $"root:myGlobals:CombineTable:Labels"
1844                Wave gSDD = $"root:myGlobals:CombineTable:SDD"
1845                Wave gRunNumber = $"root:myGlobals:CombineTable:RunNumber"
1846                Wave/T filenames = $"root:myGlobals:CombineTable:FileNames"
1847        endif
1848       
1849        GetSelection table,CombineTable,3
1850//      Print V_startRow, V_endRow
1851       
1852        //prompt for combined name, give the user a chance to cancel
1853        Variable num=V_endRow-V_startRow+1
1854        Variable ii
1855        String saveStr=""
1856        Prompt saveStr,"saved file name for "+ gLabels[V_StartRow]      //+tmpLbl[1]
1857        DoPrompt "Enter the combined file name",saveStr
1858        if(V_flag==1)
1859                return(1)               //user cancel, get out before anything is set
1860        endif
1861
1862
1863        if( !(num==2 || num==3) )
1864                Abort "invalid table selection - must select either 2 or 3 files to combine"
1865        endif
1866        Make/O/T/N=(3) tmpLbl
1867        Make/O/N=(3) tmpSDD,tmpRun
1868        for(ii=V_startRow;ii<=V_endRow;ii+=1)
1869                tmpLbl[ii-V_startRow] = gLabels[ii]
1870                tmpSDD[ii-V_startRow] = gSDD[ii]
1871                tmpRun[ii-V_startRow] = gRunNumber[ii]
1872        endfor
1873        if(num==2)      // then "highest" q run needs to be forced to zero
1874                ii=2
1875                tmpLbl[ii] = ""
1876                tmpSDD[ii] = 0.01               //fake sdd in meters to always be the "highest" Q
1877                tmpRun[ii] = 0                  //pass a run number of zero to be later interpreted as "none"
1878        endif
1879        Sort tmpSDD, tmpSDD,tmpLbl,tmpRun
1880       
1881//      Print tmpSDD
1882       
1883        num=numpnts(low)
1884        InsertPoints num, 1, low,medium,high,prefix,SaveName
1885        low[num] = tmpRun[2]
1886        medium[num] = tmpRun[1]
1887        high[num] = tmpRun[0]
1888        prefix[num] = GetPrefixStrFromFile(filenames[ii])
1889        saveName[num] = saveStr
1890
1891        return(0)
1892end
1893
1894//given a filename of a SANS data filename of the form
1895//TTTTTnnn.SAn_TTT_Txxx
1896//returns the prefix "TTTTT" as some number of characters
1897//returns "" as an invalid file prefix
1898//
1899// NCNR-specifc, does not really belong here - but it's a beta procedure anyhow...
1900//
1901Function/S GetPrefixStrFromFile(item)
1902        String item
1903        String invalid = ""     //"" is not a valid run prefix, since it's text
1904        Variable num=-1
1905       
1906        //find the "dot"
1907        String runStr=""
1908        Variable pos = strsearch(item,".",0)
1909        if(pos == -1)
1910                //"dot" not found
1911                return (invalid)
1912        else
1913                //found, skip the three characters preceeding it
1914                if (pos <=3)
1915                        //not enough characters
1916                        return (invalid)
1917                else
1918                        runStr = item[0,pos-4]
1919                        return (runStr)
1920                Endif
1921        Endif
1922End
Note: See TracBrowser for help on using the repository browser.