source: sans/Dev/branches/nxcansas_writer/NCNR_User_Procedures/Reduction/SANS/NSORT.ipf @ 1190

Last change on this file since 1190 was 1190, checked in by krzywon, 3 years ago

Update loader for multidata and multientry items. TODO: differentiate 1D and 2D data, load in multiple detectors (VSANS), and create an NSORT method that outputs in the NXcanSAS format.

File size: 82.0 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// MAR 2016 SRK added functionality to combine 4 datasets
12//
13// - handles 3 or 6-column datasets
14// allows manual scaling
15// allows user to interactively delete data points from either end of any datset
16//
17//*********************
18
19//main entry point for displaying the nsort panel
20//initializes folder/globals as needed
21//
22Proc ShowNSORTPanel()
23        DoWindow/F NSORT_Panel
24        if(V_flag==0)
25                InitNSORTPanel()
26                NSORT_Panel()
27        Endif
28        SetDataFolder root:
29        PathInfo/S catPathName
30        String junk = S_path
31        if (V_flag == 0)
32                //path does not exist - no folder selected
33                String/G root:myGlobals:NSORT:gPathStr = "no folder selected"
34        else
35                String/G root:myGlobals:NSORT:gPathStr = junk
36        endif
37        LowQPopMenuProc("",1,"")
38        MedQPopMenuProc("",1,"")
39        HighQPopMenuProc("",1,"")
40        HighestQPopMenuProc("",1,"")
41End
42
43//initializes globals/folder for the NSORT panel as needed
44//all of the globals are stored in root:myGlobals:NSORT folder
45//the globals are the values displayed in the panel
46//
47Proc InitNSORTPanel()
48
49        //set up the global variables needed for the NSORT panel
50        NewDataFolder/O root:myGlobals:NSORT
51        Variable/G root:myGlobals:NSORT:gScale1_2 = 1
52        Variable/G root:myGlobals:NSORT:gScale2_3 = 1
53        Variable/G root:myGlobals:NSORT:gScale3_4 = 1
54        //
55        //save the number of points to trim from beginning/end of the data files
56        //
57        Variable/G root:myGlobals:NSORT:gPtsBeg1 = NumVarOrDefault("root:myGlobals:NSORT:gPtsBeg1", 0 )
58        Variable/G root:myGlobals:NSORT:gPtsEnd1 = NumVarOrDefault("root:myGlobals:NSORT:gPtsEnd1", 0 )
59        Variable/G root:myGlobals:NSORT:gPtsBeg2 = NumVarOrDefault("root:myGlobals:NSORT:gPtsBeg2", 0 )
60        Variable/G root:myGlobals:NSORT:gPtsEnd2 = NumVarOrDefault("root:myGlobals:NSORT:gPtsEnd2", 0 )
61        Variable/G root:myGlobals:NSORT:gPtsBeg3 = NumVarOrDefault("root:myGlobals:NSORT:gPtsBeg3", 0 )
62        Variable/G root:myGlobals:NSORT:gPtsEnd3 = NumVarOrDefault("root:myGlobals:NSORT:gPtsEnd3", 0 )
63        Variable/G root:myGlobals:NSORT:gPtsBeg4 = NumVarOrDefault("root:myGlobals:NSORT:gPtsBeg4", 0 )
64        Variable/G root:myGlobals:NSORT:gPtsEnd4 = NumVarOrDefault("root:myGlobals:NSORT:gPtsEnd4", 0 )
65       
66        Variable/G root:myGlobals:NSORT:gColumns1 = 0
67        Variable/G root:myGlobals:NSORT:gColumns2 = 0
68        Variable/G root:myGlobals:NSORT:gColumns3 = 0
69        Variable/G root:myGlobals:NSORT:gColumns4 = 0
70        Variable/G root:myGlobals:NSORT:gNormToNum = 1
71        String/G root:myGlobals:NSORT:gPathStr = ""
72        String/G root:myGlobals:NSORT:gDataPopList = "none"
73        String/G root:myGlobals:NSORT:gDataPopList_3 = "none"
74       
75        SetDataFolder root:             //(redundant)
76End
77
78//New loader that uses data folders etc...
79//AJJ Jan 2010
80Function LoadDataForNSORT(fileStr,setNum)
81        String fileStr          //full path:name to a valid file
82        Variable setNum //number of set (used for naming) = 0, 1, or 2 (ONLY), (2016) 3 is now valid for 4th data set
83       
84        Variable err=0
85
86        String nm0,nm1,nm2
87        //String firstFileName = S_fileName
88        Variable pt=0,begPts,endPts,numCols
89       
90        NVAR gColumns1 = root:myGlobals:NSORT:gColumns1
91        NVAR gColumns2 = root:myGlobals:NSORT:gColumns2
92        NVAR gColumns3 = root:myGlobals:NSORT:gColumns3
93        NVAR gColumns4 = root:myGlobals:NSORT:gColumns4
94        NVAR begPts1 = root:myGlobals:NSORT:gPtsBeg1
95        NVAR endPts1 = root:myGlobals:NSORT:gPtsEnd1
96        NVAR begPts2 = root:myGlobals:NSORT:gPtsBeg2
97        NVAR endPts2 = root:myGlobals:NSORT:gPtsEnd2
98        NVAR begPts3 = root:myGlobals:NSORT:gPtsBeg3
99        NVAR endPts3 = root:myGlobals:NSORT:gPtsEnd3
100        NVAR begPts4 = root:myGlobals:NSORT:gPtsBeg4
101        NVAR endPts4 = root:myGlobals:NSORT:gPtsEnd4
102       
103        String cmd
104        String typStr= "", trimStr=""
105       
106        switch (setNum)
107                case 1:
108                        sprintf cmd , "A_LoadOneDDataToName(\"%s\",\"%s\",%d,%d)",fileStr,"LowQSet",0,1
109                        Execute cmd
110                        typStr = "LowQSet"
111                        trimStr = "TrimLowQSet"
112                        begPts = begPts1
113                        endPts = endPts1
114                        break
115                case 2:
116                        sprintf cmd , "A_LoadOneDDataToName(\"%s\",\"%s\",%d,%d)",fileStr,"MedQSet",0,1
117                        Execute cmd             
118                        typStr = "MedQSet"
119                        trimStr = "TrimMedQSet"
120                        begPts = begPts2
121                        endPts = endPts2
122                        break
123                case 3:
124                        sprintf cmd , "A_LoadOneDDataToName(\"%s\",\"%s\",%d,%d)",fileStr,"HighQSet",0,1
125                        Execute cmd
126                        typStr = "HighQSet"
127                        trimStr = "TrimHighQSet"
128                        begPts = begPts3
129                        endPts = endPts3
130                        break
131                case 4:
132                        sprintf cmd , "A_LoadOneDDataToName(\"%s\",\"%s\",%d,%d)",fileStr,"HighestQSet",0,1
133                        Execute cmd
134                        typStr = "HighestQSet"
135                        trimStr = "TrimHighestQSet"
136                        begPts = begPts4
137                        endPts = endPts4
138                        break
139        endswitch
140               
141        String typPrefix = "root:"+typStr+":"+typStr
142        String trimPrefix = "root:"+typStr+":"+trimStr
143       
144        if (WaveExists($(typPrefix+"_res")))
145                //6 col data loaded
146//              print "6 col data loaded"
147                numCols = 6
148                Duplicate/O $(typPrefix+"_q") $(trimPrefix+"_q")
149                Duplicate/O $(typPrefix+"_i") $(trimPrefix+"_i")
150                Duplicate/O $(typPrefix+"_s") $(trimPrefix+"_s")
151                Duplicate/O $(typPrefix+"_res") $(trimPrefix+"_res")
152                //Trimmed data set
153//              Duplicate/O $(typPrefix+"_q"),$(trimPrefix+"_q")
154//              Duplicate/O $(typPrefix+"_i"),$(trimPrefix+"_i")
155//              Duplicate/O $(typPrefix+"_s"),$(trimPrefix+"_s")
156                WaveStats/Q $(typPrefix+"_q")                   //get info about the original q-values read in
157                pt = V_npnts-endPts
158                DeletePoints pt,endPts,$(trimPrefix+"_q"),$(trimPrefix+"_i"),$(trimPrefix+"_s"),$(trimPrefix+"_res")    //delete end points first
159                DeletePoints 0,begPts,$(trimPrefix+"_q"),$(trimPrefix+"_i"),$(trimPrefix+"_s"),$(trimPrefix+"_res")     //then delete points from beginning                     
160        else
161                //Assume
162                //3 col data loaded
163//              print "Assuming 3 col data loaded"
164                numcols = 3
165                Duplicate/O $(typPrefix+"_q") $(trimPrefix+"_q")
166                Duplicate/O $(typPrefix+"_i") $(trimPrefix+"_i")
167                Duplicate/O $(typPrefix+"_s") $(trimPrefix+"_s")               
168                //Trimmed data set
169//              Duplicate/O $(typPrefix+"_q"),$(trimPrefix+"_q")
170//              Duplicate/O $(typPrefix+"_i"),$(trimPrefix+"_i")
171//              Duplicate/O $(typPrefix+"_s"),$(trimPrefix+"_s")
172                WaveStats/Q $(typPrefix+"_q")                   //get info about the original q-values read in
173                pt = V_npnts-endPts
174                DeletePoints pt,endPts,$(trimPrefix+"_q"),$(trimPrefix+"_i"),$(trimPrefix+"_s") //delete end points first
175                DeletePoints 0,begPts,$(trimPrefix+"_q"),$(trimPrefix+"_i"),$(trimPrefix+"_s")  //then delete points from beginning                                                     
176        endif
177
178        switch (setNum)
179                case 1:
180                        gColumns1 = numCols
181                        break
182                case 2:
183                        gColumns2 = numCols
184                        break
185                case 3:
186                        gColumns3 = numCols
187                        break
188                case 4:
189                        gColumns4 = numCols
190                        break
191        endswitch
192       
193        return(0)
194       
195End
196
197Function WriteNSORTedFile(q3,i3,sig3,firstFileName,secondFileName,thirdFileName,fourthFileName,normTo,norm12,norm23,norm34,[res])
198        Wave q3,i3,sig3,res
199        String firstFileName,secondFileName,thirdFileName,fourthfileName,normTo
200        Variable norm12,norm23,norm34
201
202        NVAR useXMLOutput = root:Packages:NIST:gXML_Write
203        NVAR useNXcanSASOutput = root:Packages:NIST:gNXcanSAS_Write
204       
205        //
206        // TODO: create WriteNSORTedNXcanSASFile
207        //
208
209        if (useXMLOutput == 1)
210                if(WaveExists(res))
211                        WriteNSORTedXMLFile(q3,i3,sig3,firstFileName,secondFileName,thirdFileName,fourthFileName,normTo,norm12,norm23,norm34,res=res)
212                else
213                        WriteNSORTedXMLFile(q3,i3,sig3,firstFileName,secondFileName,thirdFileName,fourthFileName,normTo,norm12,norm23,norm34)
214                endif
215        else
216                if(WaveExists(res))
217                        WriteOLDNSORTedFile(q3,i3,sig3,firstFileName,secondFileName,thirdFileName,fourthFileName,normTo,norm12,norm23,norm34,res=res)
218                else
219                        WriteOLDNSORTedFile(q3,i3,sig3,firstFileName,secondFileName,thirdFileName,fourthFileName,normTo,norm12,norm23,norm34)
220                endif           
221        endif
222
223End
224
225
226Function WriteOLDNSORTedFile(q3,i3,sig3,firstFileName,secondFileName,thirdFileName,fourthFileName,normTo,norm12,norm23,norm34,[res])
227        Wave q3,i3,sig3,res
228        String firstFileName,secondFileName,thirdFileName,fourthFileName,normTo
229        Variable norm12,norm23,norm34
230
231        Variable err=0,refNum,numCols,dialog=1
232        String fullPath="",formatStr="",str2
233        //check each wave - else REALLY FATAL error when writing file
234        If(!(WaveExists(q3)))
235                err = 1
236                return err
237        Endif
238        If(!(WaveExists(i3)))
239                err = 1
240                return err
241        Endif
242        If(!(WaveExists(sig3)))
243                err = 1
244                return err
245        Endif
246       
247        if(WaveExists(res))
248                numCols = 6
249        else
250                numCols = 3
251        endif
252       
253// 05SEP05 SRK -- added to automatically combine files from a table - see the end of NSORT.ipf for details
254// - use the flag set in DoCombineFiles() to decide if the table entries should be used
255//Ê Êroot:myGlobals:CombineTable:useTable= (1) (0)
256//if(exists("root:myGlobals:CombineTable:SaveName"))
257        NVAR/Z useTable = root:myGlobals:CombineTable:useTable
258        if(NVAR_Exists(useTable) && useTable==1)
259                SVAR str=root:myGlobals:CombineTable:SaveNameStr        //messy, but pass in as a global
260                fullPath = str
261//              str2 = "Is the file name "+str+" correct?"
262//              DoAlert 1,str2
263//              if(V_flag==1)
264                        dialog=0                //bypass the dialog if the name is good (assumed, since DoAlert is bypassed)
265//              endif
266        endif
267       
268        if(dialog)
269                PathInfo/S catPathName
270                fullPath = DoSaveFileDialog("Save data as",fname="",suffix=".ABS")              //won't actually open the file
271                If(cmpstr(fullPath,"")==0)
272                        //user cancel, don't write out a file
273                        Close/A
274                        Abort "no data file was written"
275                Endif
276                //Print "dialog fullpath = ",fullpath
277        Endif
278       
279//      // read in the header information from each of the combined files and put this information in the file header
280//      String dum,hdr1="none\r\n",hdr2="none\r\n",hdr3="none\r\n"
281//      PathInfo catPathName
282//     
283//      // the first file exists, check anyways
284//      if(cmpstr(firstFileName,"none") !=0)
285//              Open/R refNum as S_Path+firstFileName
286//              FReadLine refNum, dum
287//              FReadLine refNum, hdr1                  //just grab the second line
288//              Close refNum
289//      endif
290//      //second file
291//      if(cmpstr(secondFileName,"none") !=0)
292//              Open/R refNum as S_Path+secondFileName
293//              FReadLine refNum, dum
294//              FReadLine refNum, hdr2                  //just grab the second line
295//              Close refNum
296//      endif
297//      // third file
298//      if(cmpstr(thirdFileName,"none") !=0)
299//              Open/R refNum as S_Path+thirdFileName
300//              FReadLine refNum, dum
301//              FReadLine refNum, hdr3                  //just grab the second line
302//              Close refNum
303//      endif
304
305       
306        //actually open the file
307        Open refNum as fullpath
308       
309        fprintf refnum, "COMBINED FILE CREATED: %s \r\n",date()
310       
311//      fprintf refnum, "FIRST File %s",hdr1            //new, Mar 2008
312//      fprintf refnum, "SECOND File %s",hdr2           //new, Mar 2008
313//      fprintf refnum, "THIRD File %s",hdr3            //new, Mar 2008
314       
315        fprintf refNum, "NSORT-ed   %s\t  +  %s\t  +  %s\t + %s\r\n",firstFileName, secondFileName,thirdFileName,fourthFileName
316        fprintf refNum, "normalized to   %s\r\n",normTo
317        fprintf refNum, "multiplicative factor 1-2 = %12.8g\t multiplicative factor 2-3 = %12.8g\t multiplicative factor 3-4 = %12.8g\r\n",norm12,norm23,norm34
318
319        if (numCols == 3)
320                formatStr = "%15.4g %15.4g %15.4g\r\n"
321                fprintf refnum, "The 3 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm) |\r\n"
322                wfprintf refnum, formatStr, q3,i3,sig3
323        elseif (numCols == 6)
324                Make/O/N=(dimsize(res,0)) sigq3 = res[p][0]
325                Make/O/N=(dimsize(res,0)) qbar3 = res[p][1]
326                Make/O/N=(dimsize(res,0)) fs3 = res[p][2]
327       
328                formatStr = "%15.4g %15.4g %15.4g %15.4g %15.4g %15.4g\r\n"     
329                fprintf refnum, "The 6 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm) | sigmaQ | meanQ | ShadowFactor|\r\n"
330                wfprintf refnum, formatStr, q3,i3,sig3,sigq3,qbar3,fs3
331        endif
332       
333        Close refnum
334       
335        Return err
336End
337
338
339//gets the scaling constant to make (best) overlap of the specified datasets
340//the scaling value is an average value of the individual scaling values for
341//every data point (at the low q end) of set 2 that overlaps with set 1
342//(as if set 1 were held fixed)
343//num2 is the highest point number in set 2 that can overlap with set 1
344//(num2+1) individual scaling values are computed
345//wave2 must be multiplied by norm to rescale to wave1
346//the scale factor is the return value
347//
348Function NCNR_GetScalingInOverlap(num2,wave1q,wave1i,wave2q,wave2i)
349        Variable num2           //largest point number of wave2 in overlap region
350        Wave wave1q,wave1i,wave2q,wave2i                //1 = first dataset, 2= second dataset
351
352        Variable ii,ival1,newi,ratio
353        ratio=0
354        ii=0
355        do
356                //get scaling factor at each point of wave 2 in the overlap region
357                newi = interp(wave2q[ii],wave1q,wave1i)         //get the intensity of wave1 at an overlap point
358                ratio += newi/wave2i[ii]                                        //get the scale factor
359                //Print "ratio = ",ratio
360                ii+=1
361        while(ii<=num2)
362        Variable val
363        val = ratio/(num2+1)            // +1 counts for point zero
364        //Print "val = ",val
365
366        Variable tol=1.05                       //5% is the preferred number (for Andrew and Lionel, at least)
367
368        ControlInfo/W=NSORT_Panel WarningCheck
369        if(( V_Value==1 ) && ( (val > tol) || (val < 1/tol) ) )
370                String str=""
371                sprintf str,"The scaling factor is more than a factor of %g from 1. Proceed with caution.\r",tol
372                DoAlert 0,str
373        endif
374       
375        Return val
376End
377
378Function ShowNSORTHelp(ctrlName) : ButtonControl
379        String ctrlName
380        DisplayHelpTopic/Z/K=1 "SANS Data Reduction Tutorial[Sort and Combine Averaged Datasets]"
381        if(V_flag !=0)
382                DoAlert 0,"The SANS Data Reduction Tutorial Help file could not be found"
383        endif
384End
385
386//button action procedure that simply closes the NSORT panel when done
387//and removes the NSORT-specific waves that were created
388// - the graph window must be killed first, so that the waves will not
389//be in use
390//
391Function NSORT_DoneButton(ctrlName) : ButtonControl
392        String ctrlName
393       
394        DoWindow/K NSORT_Panel
395       
396        DoWindow/K NSORT_Graph
397       
398        //clean up the temporary waves in the root: folder
399        SetDataFolder root:
400
401        KillDataFolder/Z LowQSet
402        KillDataFolder/Z MedQSet
403        KillDataFolder/Z HighQSet
404        KillDataFolder/Z HighestQSet
405
406End
407
408//button action procedure that plots dataset specified
409//on an NSORT graph window.
410//switch is on input controlName (low-med-high set)
411//parses partial filename from corresponding popup menu
412//builds a valid filename, loads the data (re-loads if already on graph)
413//and plots twice - once for the full datset (open symbols)
414//and once for the "trimmed" dataset (solid symbols, same color)
415//
416Function Plot_0_Button(ctrlName) : ButtonControl
417        String ctrlName
418
419        String tempName="",partialName=""
420        Variable setNum,err
421        //switch on ctrlName string - Plot_1, Plot_2, Plot_3
422       
423        strswitch(ctrlName)     // string switch
424                case "Plot_1":         
425                        //low-q
426                        setNum = 1
427                        ControlInfo/W=NSORT_Panel popup_1
428                        break
429                case "Plot_2":         
430                        //medium-q
431                        setNum = 2
432                        ControlInfo/W=NSORT_Panel popup_2
433                        break
434                case "Plot_3":         
435                        //high-q
436                        setNum = 3
437                        ControlInfo/W=NSORT_Panel popup_3
438                        break
439                case "Plot_4":         
440                        //highest-q
441                        setNum = 4
442                        ControlInfo/W=NSORT_Panel popup_4
443                        break
444        endswitch
445       
446
447        //find the file from the partial filename
448        If( (cmpstr(S_value,"")==0) || (cmpstr(S_value,"none")==0) )
449                //null selection, or "none" from any popup
450                Abort "no file selected in popup menu"
451        else
452                //selection not null
453                partialName = S_value
454                //Print partialName
455        Endif
456        //get a valid file based on this partialName and catPathName
457        tempName = FindValidFilename(partialName)
458       
459        //prepend path to tempName for read routine
460        PathInfo catPathName
461        tempName = S_path + tempName
462       
463        //load in the data (into the root directory)
464        err = LoadDataForNSORT(tempName,setNum)
465       
466        //bring the plot to the front, and put the new data on it
467        //and put cursors on the plotted dataset
468        //if the dataset is already on the graph, it will have been overwritten and updated by the load routine
469        //actually plot it twice, open(opaque) circles for the full dataset,
470        // then solid (filled) circles for the points actually kept
471        String list="",searchStr=""
472        Variable isOnPlot=0
473       
474//      DoWindow/F NSORT_Graph
475        if(WinType("NSORT_Graph")==0)
476                //no window, create one
477                strswitch(ctrlName)     // string switch
478                        case "Plot_1":         
479                                //low-q
480                                Display/K=1
481                                DoWindow/C NSORT_Graph
482                                DisplayLowSet()
483                                break
484                        case "Plot_2":         
485                                //medium-q
486                                Display/K=1
487                                DoWindow/C NSORT_Graph
488                                DisplayMedSet()
489                                break
490                        case "Plot_3":         
491                                //high-q
492                                Display/K=1
493                                DoWindow/C NSORT_Graph
494                                DisplayHighSet()
495                                break
496                        case "Plot_4":         
497                                //highest-q
498                                Display/K=1
499                                DoWindow/C NSORT_Graph
500                                DisplayHighestSet()
501                                break
502                endswitch
503                Legend
504        else
505                //plot already exists, waves have been updated
506                //make sure that the desired waves are actually on the graph, and add them if they aren't
507                list = TraceNameList("NSORT_Graph",";",1)
508       
509                strswitch(ctrlName)     // string switch
510                        case "Plot_1":         
511                                //low-q
512                                isOnPlot = strsearch(list, "LowQSet_i", 0)              // isOnPlot == -1 if it is NOT found in the list
513                                if(isOnPlot == -1)
514                                        DisplayLowSet()
515                                Endif
516                                break
517                        case "Plot_2":         
518                                //medium-q
519                                isOnPlot = strsearch(list, "MedQSet_i", 0)              // isOnPlot == -1 if it is NOT found in the list
520                                if(isOnPlot == -1)
521                                        DisplayMedSet()
522                                Endif
523                                break
524                        case "Plot_3":         
525                                //high-q
526                                isOnPlot = strsearch(list, "HighQSet_i", 0)             // isOnPlot == -1 if it is NOT found in the list
527                                if(isOnPlot == -1)
528                                        DisplayHighSet()
529                                Endif
530                                break
531                        case "Plot_4":         
532                                //highest-q
533                                isOnPlot = strsearch(list, "HighestQSet_i", 0)          // isOnPlot == -1 if it is NOT found in the list
534                                if(isOnPlot == -1)
535                                        DisplayHighestSet()
536                                Endif
537                                break
538                endswitch       
539       
540        Endif
541       
542       
543        //the stripPoints variable boxes should also update the graph, if necessary
544        return(0)
545End
546
547//adds both highest-q sets (full and trimmed) to the graph, which is
548//assumed to exist along with the high-q waves
549//
550Function DisplayHighestSet()
551        //function assumes that the window "NSORT_Graph" already exists
552//      DoWindow/F NSORT_Graph
553
554        SetDataFolder root:HighestQSet:
555        AppendToGraph/W=NSORT_Graph $"HighestQSet_i" vs $"HighestQSet_q"
556        ModifyGraph/W=NSORT_Graph log=1,mode=3,marker($"HighestQSet_i")=8,msize=2,rgb($"HighestQSet_i")=(65535,32896,0),opaque($"HighestQSet_i")=1
557        ErrorBars/W=NSORT_Graph/T=0 $"HighestQSet_i" Y,wave=($"HighestQSet_s",$"HighestQSet_s")
558        AppendToGraph/W=NSORT_Graph $"TrimHighestQSet_i" vs $"TrimHighestQSet_q"
559        ModifyGraph/W=NSORT_Graph mode($"TrimHighestQSet_i")=3,marker($"TrimHighestQSet_i")=19,msize=2,rgb($"TrimHighestQSet_i")=(65535,32896,0)
560        SetDataFolder root:
561End
562
563//adds both high-q sets (full and trimmed) to the graph, which is
564//assumed to exist along with the high-q waves
565//
566Function DisplayHighSet()
567        //function assumes that the window "NSORT_Graph" already exists
568//      DoWindow/F NSORT_Graph
569
570        SetDataFolder root:HighQSet:
571        AppendToGraph/W=NSORT_Graph $"HighQSet_i" vs $"HighQSet_q"
572        ModifyGraph/W=NSORT_Graph log=1,mode=3,marker($"HighQSet_i")=8,msize=2,rgb($"HighQSet_i")=(0,0,65535),opaque($"HighQSet_i")=1
573        ErrorBars/W=NSORT_Graph/T=0 $"HighQSet_i" Y,wave=($"HighQSet_s",$"HighQSet_s")
574        AppendToGraph/W=NSORT_Graph $"TrimHighQSet_i" vs $"TrimHighQSet_q"
575        ModifyGraph/W=NSORT_Graph mode($"TrimHighQSet_i")=3,marker($"TrimHighQSet_i")=19,msize=2,rgb($"TrimHighQSet_i")=(0,0,65535)
576        SetDataFolder root:
577End
578
579//adds both med-q sets (full and trimmed) to the graph, which is
580//assumed to exist along with the med-q waves
581//
582Function DisplayMedSet()
583        //function assumes that the window "NSORT_Graph" already exists
584//      DoWindow/F NSORT_Graph
585       
586        SetDataFolder root:MedQSet:
587        AppendToGraph/W=NSORT_Graph $"MedQSet_i" vs $"MedQSet_q"
588        ModifyGraph/W=NSORT_Graph log=1,mode=3,marker($"MedQSet_i")=8,msize=2,rgb($"MedQSet_i")=(65535,0,0),opaque($"MedQSet_i")=1
589        ErrorBars/W=NSORT_Graph/T=0 $"MedQSet_i" Y,wave=($"MedQSet_s",$"MedQSet_s")
590        AppendToGraph/W=NSORT_Graph $"TrimMedQSet_i" vs $"TrimMedQSet_q"
591        ModifyGraph/W=NSORT_Graph mode($"TrimMedQSet_i")=3,marker($"TrimMedQSet_i")=19,msize=2,rgb($"TrimMedQSet_i")=(65535,0,0)
592        SetDataFolder root:
593End
594
595//adds both low-q sets (full and trimmed) to the graph, which is
596//assumed to exist along with the low-q waves
597//
598Function DisplayLowSet()
599        //function assumes that the window "NSORT_Graph" already exists
600//      DoWindow/F NSORT_Graph
601
602        SetDataFolder root:LowQSet:
603        AppendToGraph/W=NSORT_Graph $"LowQSet_i" vs $"LowQSet_q"
604        ModifyGraph/W=NSORT_Graph log=1,mode=3,marker($"LowQSet_i")=8,msize=2,rgb($"LowQSet_i")=(2,39321,1),opaque($"LowQSet_i")=1
605        ErrorBars/W=NSORT_Graph/T=0 $"LowQSet_i" Y,wave=($"LowQSet_s",$"LowQSet_s")
606        AppendToGraph/W=NSORT_Graph $"TrimLowQSet_i" vs $"TrimLowQSet_q"
607        ModifyGraph/W=NSORT_Graph mode($"TrimLowQSet_i")=3,marker($"TrimLowQSet_i")=19,msize=2,rgb($"TrimLowQSet_i")=(2,39321,1)
608        ModifyGraph tickUnit(left)=1
609        SetDataFolder root:
610End
611
612//button action procedure to set both the main global of the catPath string
613//and also the duplicate global string used in the NSORT folder
614//after path selected, the popup menus are updated
615//
616Function NSORTPickPathButton(ctrlName) : ButtonControl
617        String ctrlName
618
619        Variable err = PickPath()               //sets global path value
620        SVAR pathStr = root:myGlobals:gCatPathStr
621       
622        //set the global string for NSORT to the selected pathname
623        String/G root:myGlobals:NSORT:gPathStr = pathStr
624       
625        //call each of the popup menu proc's to re-set the menu choices
626        //setting the checkboxes to force update
627//      CheckBox check_0,win=NSORT_Panel,value=1
628//      CheckBox check_1,win=NSORT_Panel,value=1
629//      CheckBox check_2,win=NSORT_Panel,value=1
630        LowQPopMenuProc("popup_1",1,"")
631        MedQPopMenuProc("popup_2",1,"")
632        HighQPopMenuProc("popup_3",1,"")
633        HighestQPopMenuProc("popup_4",1,"")
634       
635End
636
637
638//action procedure associated with the setvar box
639//when a value is entered, the global value is set, and the corresponding dataset
640//is updated on the plot, showing the new result of removing this number of points
641//
642//      SetVar boxes are named beg_N and end_N (so 4th element is the number)
643//
644// 1 == LowQ
645// 2 == MedQ
646// 3 == HighQ
647// 4 == HighestQ
648//
649//"Plot_1" is the low-q button name
650//"Plot_2" is the med-q button name
651//"Plot_3" is the high-q button name
652//"Plot_4" is the high-q button name
653//
654//calling plot_0_Button() responds as if that named button were pressed
655// and gets the proper number to trim directly from the SetVar
656//
657Function SetBegOrEnd(ctrlName,varNum,varStr,varName) : SetVariableControl
658        String ctrlName
659        Variable varNum
660        String varStr
661        String varName
662       
663//  global is automatically updated as the value is entered
664        String numStr= num2Str( str2num(ctrlName[4]) )
665        Plot_0_Button("Plot_"+numStr)
666        DoWindow/F NSORT_Panel
667End
668
669//this will---
670//re-load the data sets (since they may not have been loaded if they were not plotted)
671// apply the scaling to the datasets (so that they will show up in the graph)
672//and actually write the file
673//
674// then "pop" the  lists to get the new file lists with the new name in the list
675//
676Function WriteNSORTFileButton(ctrlName) : ButtonControl
677        String ctrlName
678               
679        // Put here the dialog that says if ANY of the datasets had 3-column data, the results will all have only three columns
680        // Set the number of output columns
681        Variable isAThree = 0, isASix = 0,err
682        String fileStr="",tempName
683
684        NVAR Columns1 = root:myGlobals:NSORT:gColumns1
685        NVAR Columns2 = root:myGlobals:NSORT:gColumns2
686        NVAR Columns3 = root:myGlobals:NSORT:gColumns3
687        NVAR Columns4 = root:myGlobals:NSORT:gColumns4
688        if( (Columns1 == 3) || (Columns2 == 3) || (Columns3 == 3) || (Columns4 == 3))
689                isAThree = 1
690        endif
691        if( (Columns1 == 6) || (Columns2 == 6) || (Columns3 == 6) || (Columns4 == 6))
692                isASix = 1
693        endif
694        if( (isAThree == 1) && (isASix == 1))
695                DoAlert 0, "These files contained a mixture of 3-column and 6-column data.  Only 3 columns were output."
696        endif
697       
698        //is there just one data set? if so, then dispatch to a simpler routine, since no normalization is needed
699        ControlInfo/W=NSORT_Panel popup_2               //if MedQSet is "none", then so is HighQSet and HighestQSet
700        fileStr = S_Value
701        if(cmpstr(fileStr,"none") == 0)
702                // just like in the rescaling routines, always RELOAD the data  !!!
703                //load file1
704                ControlInfo/W=NSORT_Panel popup_1
705                fileStr = S_Value
706                //get a valid file based on this partialName and catPathName
707                tempName = FindValidFilename(fileStr)
708               
709                //prepend path to tempName for read routine
710                PathInfo catPathName
711                tempName = S_path + tempName
712                err = LoadDataForNSORT(tempName,1)
713                //////end load file1
714       
715                //send just the trimmed (LowQ) set to be written out
716                WAVE lowq = $"root:LowQSet:TrimLowQSet_q"
717                WAVE lowi = $"root:LowQSet:TrimLowQSet_i"
718                WAVE lows = $"root:LowQSet:TrimLowQSet_s"
719//              WAVE/Z lowsq = $"root:LowQSet:TrimLowQSet_sq"           //these may not exist
720//              WAVE/Z lowqb = $"root:LowQSet:TrimLowQSet_qb"
721//              WAVE/Z lowfs = $"root:LowQSet:TrimLowQSet_fs"
722                WAVE/Z lowres = $"root:LowQSet:TrimLowQSet_res"
723                NVAR scaleFactor= root:myGlobals:NSORT:gScale1_2
724               
725                //
726                lowi *= scaleFactor
727                lows *= scaleFactor
728               
729                ControlInfo/W=NSORT_Panel PreviewCheck
730                if( V_Value==1 )                //if ==1, just preview and exit
731                        return(0)
732                endif
733                       
734                ControlInfo/W=NSORT_Panel popup_1
735                if(isAThree)
736                        WriteNSORTedFile(lowq,lowi,lows,S_Value,"none","none","none",S_Value,scaleFactor,1,1)
737                else
738                        WriteNSORTedFile(lowq,lowi,lows,S_Value,"none","none","none",S_Value,scaleFactor,1,1,res=lowres)
739                endif
740                //  just get the new list and return - don't actually "pop" the menu, or the selected item will change
741                SVAR popList = root:myGlobals:NSORT:gDataPopList
742                SVAR popList_3 = root:myGlobals:NSORT:gDataPopList_3
743                popList  = ReducedDataFileList("")
744                popList_3 = "none;" +  ReducedDataFileList("")
745                return(0)
746        endif
747               
748               
749        //two or more datasets, combine them
750        //have they been manually or auto-normalized?
751        ControlInfo/W=NSORT_Panel AutoCheck
752        Variable checked = V_Value
753       
754        //do the normalization and update the global scale factors displayed in the Panel
755        err = DoAutoScaleFromPanel(checked)                     // DoAutoScaleFromPanel writes out the datafile
756
757        //  just get the new list - don't actually "pop" the menu, or the selected item will change
758        SVAR popList = root:myGlobals:NSORT:gDataPopList
759        SVAR popList_3 = root:myGlobals:NSORT:gDataPopList_3
760        popList  = ReducedDataFileList("")
761        popList_3 = "none;" +  ReducedDataFileList("")
762       
763        return(0)
764End
765
766//window recreation macro for NSORT Panel
767//
768Window NSORT_Panel()
769        PauseUpdate; Silent 1           // building window...
770        NewPanel /W=(569,69,944,584)//K=2
771        ModifyPanel cbRGB=(49151,53155,65535)
772        ModifyPanel fixedSize=1
773        SetDrawLayer UserBack
774        SetDrawEnv fstyle= 5
775        DrawText 35,20,"NSORT - Rescale and combine 1-D files"
776        DrawLine 0,55,346,55
777        DrawLine 0,128,346,128
778        DrawLine 0,214,346,214
779        DrawLine 0,295,346,295
780        DrawLine 0,372,347,372
781        DrawLine 0,460,346,460
782       
783        SetDrawEnv fstyle= 5
784        DrawText 5,74,"Low Q:"
785        SetDrawEnv fstyle= 5
786        DrawText 5,148,"Medium Q:"
787        SetDrawEnv fstyle= 5
788        DrawText 8,234,"High Q: (or none)"
789        SetDrawEnv fstyle= 5
790        DrawText 8,314,"Highest Q: (or none)"
791        SetDrawEnv fstyle= 4
792        DrawText 178,75,"Delete Points?"
793        SetDrawEnv fstyle= 4
794        DrawText 178,146,"Delete Points?"
795        SetDrawEnv fstyle= 4
796        DrawText 184,236,"Delete Points?"
797        SetDrawEnv fstyle= 4
798        DrawText 184,316,"Delete Points?"
799        DrawText 31,456,"To Manually scale data, enter scale factors above"
800       
801        Button NSORT_Done,pos={274,483},size={50,20},proc=NSORT_DoneButton,title="Done"
802        Button NSORT_Done,help={"closes the panel"}
803        Button Plot_1,pos={279,63},size={50,20},proc=Plot_0_Button,title="Plot"
804        Button Plot_1,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
805        Button Plot_2,pos={283,144},size={50,20},proc=Plot_0_Button,title="Plot"
806        Button Plot_2,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
807        Button Plot_3,pos={284,223},size={50,20},proc=Plot_0_Button,title="Plot"
808        Button Plot_3,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
809        Button Plot_4,pos={284.00,303.00},size={50.00,20.00},proc=Plot_0_Button,title="Plot"
810        Button Plot_4,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
811
812        Button PathButton,pos={6,26},size={80,20},proc=NSORTPickPathButton,title="Pick Path"
813        Button PathButton,help={"Select the local path to the folder containing your SANS data"}
814        Button helpButton,pos={340,26},size={25,20},proc=ShowNSORTHelp,title="?"
815        Button helpButton,help={"Show the help file for sorting and internormalizing 1-D data sets"}
816        SetVariable setPath,pos={95,29},size={240,14},title="Path:",fSize=10
817        SetVariable setPath,limits={0,0,0},value= root:myGlobals:NSORT:gPathStr
818        SetVariable setPath,help={"The current path to the local folder with SANS data"}
819        SetVariable end_1,pos={182,101},size={80,14},proc=SetBegOrEnd,title="End Pts"
820        SetVariable end_1,fSize=10,help={"How many points to remove from the high-q end of this dataset"}
821        SetVariable end_1,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsEnd1
822        SetVariable end_2,pos={182,176},size={80,14},proc=SetBegOrEnd,title="End Pts"
823        SetVariable end_2,fSize=10,help={"How many points to remove from the high-q end of this dataset"}
824        SetVariable end_2,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsEnd2
825        SetVariable end_3,pos={182,269},size={80,14},proc=SetBegOrEnd,title="End Pts"
826        SetVariable end_3,fSize=10,help={"How many points to remove from the high-q end of this dataset"}
827        SetVariable end_3,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsEnd3
828        SetVariable end_4,pos={182.00,349.00},size={80.00,16.00},proc=SetBegOrEnd,title="End Pts"
829        SetVariable end_4,help={"How many points to remove from the high-q end of this dataset"}
830        SetVariable end_4,fSize=10
831        SetVariable end_4,limits={-inf,inf,0},value= root:myGlobals:NSORT:gPtsEnd4
832        SetVariable beg_1,pos={182,79},size={80,14},proc=SetBegOrEnd,title="Beg Pts"
833        SetVariable beg_1,fSize=10,help={"How many points to remove from the low-q end of this dataset"}
834        SetVariable beg_1,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsBeg1
835        SetVariable beg_2,pos={182,155},size={80,14},proc=SetBegOrEnd,title="Beg Pts"
836        SetVariable beg_2,fSize=10,help={"How many points to remove from the low-q end of this dataset"}
837        SetVariable beg_2,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsBeg2
838        SetVariable beg_3,pos={182,246},size={80,14},proc=SetBegOrEnd,title="Beg Pts"
839        SetVariable beg_3,fSize=10,help={"How many points to remove from the low-q end of this dataset"}
840        SetVariable beg_3,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsBeg3
841        SetVariable beg_4,pos={182.00,326.00},size={80.00,16.00},proc=SetBegOrEnd,title="Beg Pts"
842        SetVariable beg_4,help={"How many points to remove from the low-q end of this dataset"}
843        SetVariable beg_4,fSize=10
844        SetVariable beg_4,limits={-inf,inf,0},value= root:myGlobals:NSORT:gPtsBeg4
845        Button DoCombine,pos={13,483},size={160,20},proc=WriteNSORTFileButton,title="Write Combined File"
846        Button DoCombine,help={"Combine and normalize the selected files as specifed"}
847        SetVariable scale_12,pos={159,381},size={160,14},proc=SetScale_12,title="Mult factor 1-2"
848        SetVariable scale_12,fSize=10,help={"Factor that will multiply medium-q set to scale to low-q set"}
849        SetVariable scale_12,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gScale1_2
850        SetVariable scale_23,pos={159,401},size={160,14},proc=SetScale_23,title="Mult factor 2-3"
851        SetVariable scale_23,fSize=10,help={"Factor that will multiply high-q set to scale to medium-q set"}
852        SetVariable scale_23,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gScale2_3
853        SetVariable scale_34,pos={159.00,421.00},size={160.00,16.00},proc=SetScale_34,title="Mult factor 3-4"
854        SetVariable scale_34,help={"Factor that will multiply highest-q set to scale to high-q set"}
855        SetVariable scale_34,fSize=10
856        SetVariable scale_34,limits={-inf,inf,0},value= root:myGlobals:NSORT:gScale3_4
857        CheckBox check1,pos={5,105},size={160,20},proc=CheckProc,title="Normalize to this file",value=1
858        CheckBox check1,help={"If checked, the combined dataset will be normalized to this dataset"}
859        CheckBox check2,pos={5,185},size={160,20},proc=CheckProc,title="Normalize to this file",value=0
860        CheckBox check2,help={"If checked, the combined dataset will be normalized to this dataset"}
861        CheckBox check3,pos={4,270},size={160,20},proc=CheckProc,title="Normalize to this file",value=0
862        CheckBox check3,help={"If checked, the combined dataset will be normalized to this dataset"}
863        CheckBox check4,pos={4.00,350.00},size={107.00,16.00},proc=CheckProc,title="Normalize to this file"
864        CheckBox check4,help={"If checked, the combined dataset will be normalized to this dataset"}
865        CheckBox check4,value= 0
866        PopupMenu popup_1,pos={6,77},size={99,19},proc=LowQPopMenuProc
867        PopupMenu popup_1,mode=1,value= #"root:myGlobals:NSORT:gDataPopList"
868        PopupMenu popup_1,help={"Choose the dataset with the lowest overall q-value (longest detector distance)"}
869        PopupMenu popup_2,pos={6,153},size={99,19},proc=MedQPopMenuProc
870        PopupMenu popup_2,mode=1,value= #"root:myGlobals:NSORT:gDataPopList_3"
871        PopupMenu popup_2,help={"Choose the dataset with the intermediate q-values (\"medium\" detector distance)"}
872        PopupMenu popup_3,pos={6,239},size={99,19},proc=HighQPopMenuProc
873        PopupMenu popup_3,mode=1,value= #"root:myGlobals:NSORT:gDataPopList_3"
874        PopupMenu popup_3,help={"Choose the dataset with the highest overall q-value (shortest detector distance), or NONE if no third set desired"}
875        PopupMenu popup_4,pos={6.00,319.00},size={58.00,23.00},proc=HighestQPopMenuProc
876        PopupMenu popup_4,help={"Choose the dataset with the highest overall q-value (shortest detector distance), or NONE if no fourth set desired"}
877        PopupMenu popup_4,mode=1,popvalue="none",value= #"root:myGlobals:NSORT:gDataPopList_3"
878        CheckBox AutoCheck,pos={14,386},size={100,20},title="Auto Scale",value=0
879        CheckBox AutoCheck,help={"If checked, the scale factor will be automatically determined, if not checked, the current values in the fields will be used"}
880        CheckBox PreviewCheck,pos={15,465},size={74,14},title="Preview Only",value= 0
881        CheckBox WarningCheck,pos={111,465},size={93,14},title="Overlap warning?",value= 1
882EndMacro
883
884//sets the scale factor (multiplicative) between sets 1 and 2
885//re-sets the global variable
886//
887Function SetScale_12(ctrlName,varNum,varStr,varName) : SetVariableControl
888        String ctrlName
889        Variable varNum
890        String varStr
891        String varName
892
893        Variable/G root:myGlobals:NSORT:gScale1_2 = varNum
894       
895End
896
897//sets the scale factor (multiplicative) between sets 2 and 3
898//re-sets the global variable
899//
900Function SetScale_23(ctrlName,varNum,varStr,varName) : SetVariableControl
901        String ctrlName
902        Variable varNum
903        String varStr
904        String varName
905
906        Variable/G root:myGlobals:NSORT:gScale2_3 = varNum
907End
908
909//sets the scale factor (multiplicative) between sets 3 and 4
910//re-sets the global variable
911//
912Function SetScale_34(ctrlName,varNum,varStr,varName) : SetVariableControl
913        String ctrlName
914        Variable varNum
915        String varStr
916        String varName
917
918        Variable/G root:myGlobals:NSORT:gScale3_4 = varNum
919End
920
921//control procedures for the checkboxes to specify which file is to be
922//held fixed (so all other files are normalized to the checked file
923//the three checkboxes behave as "radio buttons" - only one can be checked
924//
925Function CheckProc(ctrlName,checked) : CheckBoxControl
926        String ctrlName
927        Variable checked
928       
929        //controls the three checkboxes to act as "radio buttons" to have only one file to
930        //normalize to.
931        //all three boxes should call this routine
932       
933        //do the "radio button control"
934        do
935                if(cmpstr(ctrlName,"check2") == 0)
936                        CheckBox check1 value=0
937                        CheckBox check2 value=1
938                        CheckBox check3 value=0
939                        CheckBox check4 value=0
940                        Variable/G root:myGlobals:NSORT:gNormToNum = 2
941                        break
942                Endif
943                if(cmpstr(ctrlName,"check3") == 0)
944                        CheckBox check1 value=0
945                        CheckBox check2 value=0
946                        CheckBox check3 value=1
947                        CheckBox check4 value=0
948                        Variable/G root:myGlobals:NSORT:gNormToNum = 3
949                        break
950                Endif
951                if(cmpstr(ctrlName,"check4") == 0)
952                        CheckBox check1 value=0
953                        CheckBox check2 value=0
954                        CheckBox check3 value=0
955                        CheckBox check4 value=1
956                        Variable/G root:myGlobals:NSORT:gNormToNum = 4
957                        break
958                Endif
959                //default case is normalize to file1
960                CheckBox check1 value=1
961                CheckBox check2 value=0
962                CheckBox check3 value=0
963                        CheckBox check4 value=0
964                Variable/G root:myGlobals:NSORT:gNormToNum = 1
965        While(0)
966       
967        ControlUpdate/A/W=NSORT_Panel
968        DoUpdate
969               
970End
971
972//when menu is popped, it gets a valid list to display and updates the control
973//
974// 2002- always refreshes, as new (fast) filter is used
975Function LowQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
976        String ctrlName
977        Variable popNum
978        String popStr
979
980        String/G root:myGlobals:NSORT:gDataPopList = ReducedDataFileList("")
981        ControlUpdate popup_1
982
983        return(0)
984End
985
986//when menu is popped, it gets a valid list to display and updates the control
987//
988Function MedQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
989        String ctrlName
990        Variable popNum
991        String popStr
992               
993        String/G root:myGlobals:NSORT:gDataPopList_3 = "none;" +  ReducedDataFileList("")
994        ControlUpdate popup_2
995        if(cmpstr(popStr,"none")==0)
996                PopupMenu popup_3,mode=1        //force "none" (item #1) to be the selection
997                CheckBox AutoCheck,value=0      //un-check the auto-scale checkbox
998                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
999                RemoveFromGraph/Z MedQSet_i,TrimMedQSet_i,HighQSet_i,TrimHighQSet_i             //remove the data from the graph
1000        Endif   
1001        return(0)
1002End
1003
1004//when menu is popped, it gets a valid list to display and updates the control
1005// - will be different, since set 3 can also be "none" if only 2 sets
1006//are to be NSORTed
1007//
1008Function HighQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
1009        String ctrlName
1010        Variable popNum
1011        String popStr
1012
1013        //add the option "none" to the file list (which should already end with a semicolon)
1014        String/G root:myGlobals:NSORT:gDataPopList_3 = "none;" +  ReducedDataFileList("")
1015
1016        ControlUpdate/W=NSORT_Panel popup_3
1017        if(cmpstr(popStr,"none")==0)
1018                RemoveFromGraph/Z HighQSet_i,TrimHighQSet_i             //remove the data from the graph
1019        Endif   
1020        ControlInfo/W=NSORT_Panel popup_2
1021        if(cmpstr(S_Value,"none")==0)
1022                PopupMenu popup_3,win=NSORT_Panel,mode=1        //force "none" (item #1) to be the selection if medium is none
1023        endif
1024        return(0)       
1025End
1026
1027
1028//when menu is popped, it gets a valid list to display and updates the control
1029// - will be different, since set 3 can also be "none" if only 2 sets
1030//are to be NSORTed
1031//
1032Function HighestQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
1033        String ctrlName
1034        Variable popNum
1035        String popStr
1036
1037        //add the option "none" to the file list (which should already end with a semicolon)
1038        String/G root:myGlobals:NSORT:gDataPopList_3 = "none;" +  ReducedDataFileList("")
1039
1040        ControlUpdate/W=NSORT_Panel popup_4
1041        if(cmpstr(popStr,"none")==0)
1042                RemoveFromGraph/Z HighestQSet_i,TrimHighestQSet_i               //remove the data from the graph
1043        Endif   
1044        ControlInfo/W=NSORT_Panel popup_2
1045        if(cmpstr(S_Value,"none")==0)
1046                PopupMenu popup_3,win=NSORT_Panel,mode=1        //force "none" (item #1) to be the selection if medium is none
1047                PopupMenu popup_4,win=NSORT_Panel,mode=1        //force "none" (item #1) to be the selection if medium is none
1048        endif
1049        ControlInfo/W=NSORT_Panel popup_3
1050        if(cmpstr(S_Value,"none")==0)
1051                PopupMenu popup_4,win=NSORT_Panel,mode=1        //force "none" (item #1) to be the selection if medium is none
1052        endif
1053        return(0)       
1054End
1055
1056//be sure to use the "Trim.." datasets that have had the bad points removed
1057//and then do the scaling based on the choices in the panel
1058//input (auto) is a switch
1059//
1060Function DoAutoScaleFromPanel(auto)
1061        Variable auto           //if auto == 1, do the scaling, if 0, use manual scale values
1062
1063        NVAR normTo = root:myGlobals:NSORT:gNormToNum
1064        Variable err=0,setNum,norm12,norm23,norm34
1065        String fileStr="",tempName="",name1="",name2="",name3="",normToStr="",name4=""
1066       
1067//Set the number of output columns
1068        Variable numOutputColumns = 0
1069
1070        NVAR Columns1 = root:myGlobals:NSORT:gColumns1
1071        NVAR Columns2 = root:myGlobals:NSORT:gColumns2
1072        NVAR Columns3 = root:myGlobals:NSORT:gColumns3
1073        NVAR Columns4 = root:myGlobals:NSORT:gColumns4
1074        if( (Columns1 == 3) || (Columns2 == 3) || (Columns3 == 3) || (Columns4 == 3) )
1075                numOutputColumns = 3
1076        else
1077                if( (Columns1 == 6) && (Columns2 == 6) && ((Columns3 == 0) || (Columns3 == 6)) || (Columns4 == 6) )
1078                        numOutputColumns = 6
1079                endif
1080        endif
1081
1082        //rescale 1-2
1083       
1084        //load file1
1085        ControlInfo/W=NSORT_Panel popup_1
1086        fileStr = S_Value
1087        name1 = fileStr
1088        setNum = 1
1089        //get a valid file based on this partialName and catPathName
1090        tempName = FindValidFilename(fileStr)
1091       
1092        //prepend path to tempName for read routine
1093        PathInfo catPathName
1094        tempName = S_path + tempName
1095        err = LoadDataForNSORT(tempName,setNum)
1096        //////end load file1
1097       
1098        //load file2
1099        ControlInfo/W=NSORT_Panel popup_2
1100        fileStr = S_Value
1101        name2 = fileStr
1102        setNum = 2
1103        //get a valid file based on this partialName and catPathName
1104        tempName = FindValidFilename(fileStr)
1105       
1106        //prepend path to tempName for read routine
1107        PathInfo catPathName
1108        tempName = S_path + tempName
1109        err = LoadDataForNSORT(tempName,setNum)
1110        //////end load file2
1111       
1112        //load file3 , if necessary
1113        ControlInfo/W=NSORT_Panel popup_3
1114        fileStr = S_Value
1115        name3 = fileStr
1116        setNum = 3
1117        if(cmpstr(fileStr,"none") == 0)
1118                //do nothing
1119        else
1120                //get a valid file based on this partialName and catPathName
1121                tempName = FindValidFilename(fileStr)
1122       
1123                //prepend path to tempName for read routine
1124                PathInfo catPathName
1125                tempName = S_path + tempName
1126                err = LoadDataForNSORT(tempName,setNum)
1127        Endif
1128        //////end load file3
1129       
1130        //load file4 , if necessary
1131        ControlInfo/W=NSORT_Panel popup_4
1132        fileStr = S_Value
1133        name4 = fileStr
1134        setNum = 4
1135        if(cmpstr(fileStr,"none") == 0)
1136                //do nothing
1137        else
1138                //get a valid file based on this partialName and catPathName
1139                tempName = FindValidFilename(fileStr)
1140       
1141                //prepend path to tempName for read routine
1142                PathInfo catPathName
1143                tempName = S_path + tempName
1144                err = LoadDataForNSORT(tempName,setNum)
1145        Endif
1146        //////end load file4
1147       
1148       
1149        //assign filename of file to normalize to
1150        switch(normTo)
1151                case 1:
1152                        normToStr = name1
1153                        break
1154                case 2:
1155                        normToStr = name2
1156                        break
1157                case 3:
1158                        normToStr = name3
1159                        break
1160                case 4:
1161                        normToStr = name4
1162                        break
1163        endswitch
1164
1165
1166        Variable n1,n2,n12,num2
1167        Variable n3,n123
1168        Variable n4,n1234
1169       
1170   if(numOutputColumns == 3) //Start the 3-column specific stuff here.
1171                //order points in sets 1-2, indexing overlap region
1172                //put result in temporary waves
1173                WaveStats/Q $"root:LowQSet:TrimLowQSet_q"
1174                n1 = V_npnts
1175                WaveStats/Q $"root:LowQSet:TrimMedQSet_q"
1176                n2 = V_npnts
1177                n12 = n1+ n2
1178               
1179                Make/O/N=(n12) q12,i12,sig12
1180                WAVE lowq = $"root:LowQSet:TrimLowQSet_q"
1181                WAVE medq = $"root:MedQSet:TrimMedQSet_q"
1182                WAVE lowi = $"root:LowQSet:TrimLowQSet_i"
1183                WAVE medi =  $"root:MedQSet:TrimMedQSet_i"
1184                WAVE lows = $"root:LowQSet:TrimLowQSet_s"
1185                WAVE meds = $"root:MedQSet:TrimMedQSet_s"
1186                q12[0,n1-1] = lowq[p]
1187                q12[n1,n1+n2-1]= medq[p-n1]
1188                i12[0,n1-1] = lowi[p]
1189                i12[n1,n1+n2-1]= medi[p-n1]
1190                sig12[0,n1-1] = lows[p]
1191                sig12[n1,n1+n2-1]= meds[p-n1]
1192               
1193                Sort q12, q12,i12,sig12
1194                /////////////////
1195               
1196                //find the maximum point number of set 2  in the overlap region
1197                FindLevel/P/Q medq,(lowq[n1-1])
1198                num2 = trunc(V_levelX)
1199                //Print "num2 = ",num2
1200               
1201                if (auto)
1202                        //there must be overlap points to use auto-scaling
1203                        if(numtype(num2) != 0)
1204                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1205                        endif
1206                        //do auto-scaling of data
1207                        norm12 = NCNR_GetScalingInOverlap(num2,lowq,lowi,medq,medi)
1208                        //Set the global variable for the 1-2 scale factor
1209                        Variable/G root:myGlobals:NSORT:gScale1_2 = norm12
1210                else
1211                        //use the value from the panel ( which is the global)
1212                        NVAR temp12 = root:myGlobals:NSORT:gScale1_2
1213                        norm12 = temp12
1214                Endif
1215               
1216                If(normTo== 2)
1217                        //normalize to second file, so multiply 1st by 1/norm
1218                        norm12 = 1/norm12
1219                        lowi *= norm12
1220                        lows *= norm12
1221                else
1222                        //normalize to first file, OR THIRD FILE so multiply 2nd by norm
1223                        medi *= norm12
1224                        meds *= norm12
1225                Endif
1226               
1227                //Print "NSORT-ed ",name1," + ", name2
1228                //Print "normalized to ",normTo
1229                //Print "multiplicative factor = ",norm12
1230               
1231               
1232                //Make the combined, scaled dataset by overwriting the old sets
1233                Make/O/N=(n12) q12,i12,sig12
1234                q12[0,n1-1] = lowq[p]
1235                q12[n1,n1+n2-1]= medq[p-n1]
1236                i12[0,n1-1] = lowi[p]
1237                i12[n1,n1+n2-1]= medi[p-n1]
1238                sig12[0,n1-1] = lows[p]
1239                sig12[n1,n1+n2-1]= meds[p-n1]
1240               
1241                Sort q12, q12,i12,sig12
1242                //at this point 1-2 are combined
1243               
1244                ControlUpdate/A/W=NSORT_Panel
1245                DoUpdate
1246               
1247                //do we need to continue, or write out the set here and stop?
1248                if(cmpstr(name3,"none") == 0)
1249                        //stop here
1250                        norm23 = 1              //norm23 was not used
1251                        Variable/G root:myGlobals:NSORT:gScale2_3 = 1
1252                        //If any of them have three columns write three column data
1253                       
1254                        ControlInfo/W=NSORT_Panel PreviewCheck
1255                        if( V_Value==0 )                //if zero skip the preview and write out the file
1256                                err=WriteNSORTedFile(q12,i12,sig12,name1,name2,name3,name4,normToStr,norm12,norm23,norm34)
1257                        endif
1258                        //cleanup waves before exiting
1259                        KillWaves/Z q12,i12,sig12
1260                        return err
1261                Endif
1262               
1263                //need to add the third file... which was already loaded at the top of the function
1264                /////
1265                //order points in sets 12-3, indexing overlap region
1266                //put result in temporary waves
1267                WaveStats/Q q12
1268                n12 = V_npnts
1269                WaveStats/Q $"root:HighQSet:TrimHighQSet_q"
1270                n3 = V_npnts
1271                n123 = n12+ n3
1272               
1273                Make/O/N=(n123) q123,i123,sig123
1274                WAVE highq = $"root:HighQSet:TrimHighQSet_q"
1275                WAVE highi = $"root:HighQSet:TrimHighQSet_i"
1276                WAVE highs = $"root:HighQSet:TrimHighQSet_s"
1277       
1278                q123[0,n12-1] = q12[p]
1279                q123[n1,n12+n3-1]= highq[p-n12]
1280                i123[0,n12-1] = i12[p]
1281                i123[n1,n12+n3-1]= highi[p-n12]
1282                sig123[0,n12-1] = sig12[p]
1283                sig123[n1,n12+n3-1]= highs[p-n12]
1284               
1285                Sort q123, q123,i123,sig123
1286                /////////////////
1287               
1288                //find the maximum point number of set 2  in the overlap region
1289                FindLevel/P/Q highq,(q12[n12-1])
1290                num2 = trunc(V_levelX)
1291                //Print "num2 = ",num2
1292               
1293                if (auto)
1294                        //there must be overlap points to use auto-scaling
1295                        if(numtype(num2) != 0)
1296                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1297                        endif
1298                        //do auto-scaling of data
1299                        norm23 = NCNR_GetScalingInOverlap(num2,q12,i12,highq,highi)
1300                        //Set the global variable for the 12 - 3 scale factor
1301                        Variable/G root:myGlobals:NSORT:gScale2_3 = norm23
1302                else
1303                        //use the value from the panel ( which is the global)
1304                        NVAR temp23 = root:myGlobals:NSORT:gScale2_3
1305                        norm23 = temp23
1306                Endif
1307               
1308                If( (normTo== 1) || (normTo ==2) )
1309                        //normalize to first or second file, so multiply third by norm23
1310                        highi *= norm23
1311                        highs *= norm23
1312                else
1313                        //normalize to THIRD file, 1-2 by 1/norm23
1314                        norm23 = 1/norm23
1315                        i12 *= norm23
1316                        sig12 *= norm23
1317                        // for the display, scale the trimmed sets 1 and 2
1318                        lowi *= norm23
1319                        lows *= norm23
1320                        medi *= norm23
1321                        meds *= norm23
1322                Endif
1323               
1324                ControlUpdate/A/W=NSORT_Panel
1325                DoUpdate
1326
1327                //Print "NSORT-ed ",name1," + ", name2, " + ", name3
1328                //Print "normalized to ",normTo
1329                //Print "multiplicative factor 1-2 = ",norm12," multiplicative factor 12 - 3 = ",norm23
1330               
1331               
1332                Make/O/N=(n123) q123,i123,sig123
1333                q123[0,n12-1] = q12[p]
1334                q123[n12,n12+n3-1]= highq[p-n12]
1335                i123[0,n12-1] = i12[p]
1336                i123[n12,n12+n3-1]= highi[p-n12]
1337                sig123[0,n12-1] = sig12[p]
1338                sig123[n12,n12+n3-1]= highs[p-n12]
1339               
1340                Sort q123, q123,i123,sig123
1341                //at this point 12 - 3 are combined
1342                //write out the set here and stop
1343       
1344                ControlInfo/W=NSORT_Panel PreviewCheck
1345                if( V_Value==0 )                //if zero skip the preview and write out the file
1346                        err=WriteNSORTedFile(q123,i123,sig123,name1,name2,name3,name4,normToStr,norm12,norm23,norm34)
1347                endif
1348                //cleanup waves before exiting
1349                KillWaves/Z q12,i12,sig12,q123,i123,sig123
1350               
1351               
1352                //do we need to continue, or write out the set here and stop?
1353                if(cmpstr(name4,"none") == 0)
1354                        //stop here
1355                        norm34 = 1              //norm34 was not used
1356                        Variable/G root:myGlobals:NSORT:gScale3_4 = 1
1357                        //If any of them have three columns write three column data
1358                       
1359                        ControlInfo/W=NSORT_Panel PreviewCheck
1360                        if( V_Value==0 )                //if zero skip the preview and write out the file
1361                                err=WriteNSORTedFile(q123,i123,sig123,name1,name2,name3,name4,normToStr,norm12,norm23,norm34)
1362                        endif
1363                        //cleanup waves before exiting
1364                        KillWaves/Z q123,i123,sig123
1365                        return err
1366                Endif
1367               
1368                //need to add the fourth file... which was already loaded at the top of the function
1369                /////
1370                //order points in sets 123-4, indexing overlap region
1371                //put result in temporary waves
1372                WaveStats/Q q123
1373                n123 = V_npnts
1374                WaveStats/Q $"root:HighestQSet:TrimHighestQSet_q"
1375                n4 = V_npnts
1376                n1234 = n123 + n4
1377               
1378                Make/O/N=(n1234) q1234,i1234,sig1234
1379                WAVE highestq = $"root:HighestQSet:TrimHighestQSet_q"
1380                WAVE highesti = $"root:HighestQSet:TrimHighestQSet_i"
1381                WAVE highests = $"root:HighestQSet:TrimHighestQSet_s"
1382       
1383                q1234[0,n123-1] = q123[p]
1384                q1234[n12,n123+n4-1]= highestq[p-n123]
1385                i1234[0,n123-1] = i123[p]
1386                i1234[n12,n123+n4-1]= highesti[p-n123]
1387                sig1234[0,n123-1] = sig123[p]
1388                sig1234[n12,n123+n4-1]= highests[p-n123]
1389               
1390                Sort q1234, q1234,i1234,sig1234
1391                /////////////////
1392               
1393                //find the maximum point number of set 2  in the overlap region
1394                FindLevel/P/Q highestq,(q123[n123-1])
1395                num2 = trunc(V_levelX)
1396                //Print "num2 = ",num2
1397               
1398                if (auto)
1399                        //there must be overlap points to use auto-scaling
1400                        if(numtype(num2) != 0)
1401                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1402                        endif
1403                        //do auto-scaling of data
1404                        norm34 = NCNR_GetScalingInOverlap(num2,q123,i123,highestq,highesti)
1405                        //Set the global variable for the 123 - 4 scale factor
1406                        Variable/G root:myGlobals:NSORT:gScale3_4 = norm34
1407                else
1408                        //use the value from the panel ( which is the global)
1409                        NVAR temp34 = root:myGlobals:NSORT:gScale3_4
1410                        norm34 = temp34
1411                Endif
1412               
1413// normalization
1414                switch (normTo)
1415                        case 1:
1416                        case 2:
1417                        case 3:
1418                                //normalize to first or second or third file, so multiply fourth by norm34
1419                                highesti *= norm34
1420                                highests *= norm34
1421                                break
1422                        case 4:
1423                                //normalize to FOURTH file, 123 by multiplicative factor 1/norm34
1424                                norm34 = 1/norm34
1425                                i123 *= norm34
1426                                sig123 *= norm34
1427                                // for the display, scale the trimmed sets 1 and 2 and 3
1428                                lowi *= norm34
1429                                lows *= norm34
1430                                medi *= norm34
1431                                meds *= norm34
1432                                highi *= norm34
1433                                highs *= norm34
1434                                break
1435                endswitch
1436                               
1437                ControlUpdate/A/W=NSORT_Panel
1438                DoUpdate
1439
1440                //Print "NSORT-ed ",name1," + ", name2, " + ", name3
1441                //Print "normalized to ",normTo
1442                //Print "multiplicative factor 1-2 = ",norm12," multiplicative factor 12 - 3 = ",norm23
1443               
1444               
1445                Make/O/N=(n1234) q1234,i1234,sig1234
1446                q1234[0,n123-1] = q123[p]
1447                q1234[n123,n123+n4-1]= highestq[p-n123]
1448                i1234[0,n123-1] = i123[p]
1449                i1234[n123,n123+n4-1]= highesti[p-n123]
1450                sig1234[0,n123-1] = sig123[p]
1451                sig1234[n123,n123+n4-1]= highests[p-n123]
1452               
1453                Sort q123, q123,i123,sig123
1454                //at this point 12 - 3 are combined
1455                //write out the set here and stop
1456       
1457                ControlInfo/W=NSORT_Panel PreviewCheck
1458                if( V_Value==0 )                //if zero skip the preview and write out the file
1459                        err=WriteNSORTedFile(q123,i123,sig123,name1,name2,name3,name4,normToStr,norm12,norm23,norm34)
1460                endif
1461                //cleanup waves before exiting
1462                KillWaves/Z q12,i12,sig12,q123,i123,sig123
1463               
1464               
1465               
1466               
1467                //combined dataset will already be displayed if the NSORT_Graph is open
1468       
1469                ////////////////
1470                return err
1471   endif // End the 3-column specific stuff here
1472
1473   if(numOutputColumns == 6) // Start the 6-column specific stuff here
1474                //order points in sets 1-2, indexing overlap region
1475                //put result in temporary waves
1476                WaveStats/Q $"root:LowQSet:TrimLowQSet_q"
1477                n1 = V_npnts
1478                WaveStats/Q $"root:MedQSet:TrimMedQSet_q"
1479                n2 = V_npnts
1480                n12 = n1+ n2
1481               
1482                Make/O/N=(n12) q12,i12,sig12,sq12,qb12,fs12
1483                Make/O/N=(n12,3) res12
1484                WAVE lowq = $"root:LowQSet:TrimLowQSet_q"
1485                WAVE medq = $"root:MedQSet:TrimMedQSet_q"
1486                WAVE lowi = $"root:LowQSet:TrimLowQSet_i"
1487                WAVE medi =  $"root:MedQSet:TrimMedQSet_i"
1488                WAVE lows = $"root:LowQSet:TrimLowQSet_s"
1489                WAVE meds = $"root:MedQSet:TrimMedQSet_s"
1490                WAVE lowres = $"root:LowQSet:TrimLowQSet_res"
1491                WAVE medres = $"root:MedQSet:TrimMedQSet_res"
1492               
1493                q12[0,n1-1] = lowq[p]
1494                q12[n1,n1+n2-1]= medq[p-n1]
1495                i12[0,n1-1] = lowi[p]
1496                i12[n1,n1+n2-1]= medi[p-n1]
1497                sig12[0,n1-1] = lows[p]
1498                sig12[n1,n1+n2-1]= meds[p-n1]
1499                sq12[0,n1-1] = lowres[p][0]
1500                sq12[n1,n1+n2-1]= medres[p-n1][0]
1501                qb12[0,n1-1] = lowres[p][1]
1502                qb12[n1,n1+n2-1]= medres[p-n1][1]
1503                fs12[0,n1-1] = lowres[p][2]
1504                fs12[n1,n1+n2-1]= medres[p-n1][2]
1505
1506               
1507                Sort q12, q12,i12,sig12,sq12,qb12,fs12
1508                /////////////////
1509               
1510                //find the maximum point number of set 2  in the overlap region
1511                FindLevel/P/Q medq,(lowq[n1-1])
1512                num2 = trunc(V_levelX)
1513                //Print "num2 = ",num2
1514               
1515                if (auto)
1516                        //there must be overlap points to use auto-scaling
1517                        if(numtype(num2) != 0)
1518                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1519                        endif
1520                        //do auto-scaling of data
1521                        norm12 = NCNR_GetScalingInOverlap(num2,lowq,lowi,medq,medi)
1522                        //Set the global variable for the 1-2 scale factor
1523                        Variable/G root:myGlobals:NSORT:gScale1_2 = norm12
1524                else
1525                        //use the value from the panel ( which is the global)
1526                        NVAR temp12 = root:myGlobals:NSORT:gScale1_2
1527                        norm12 = temp12
1528                Endif
1529               
1530                If(normTo== 2)
1531                        //normalize to second file, so multiply 1st by 1/norm
1532                        norm12 = 1/norm12
1533                        lowi *= norm12
1534                        lows *= norm12
1535                else
1536                        //normalize to first file, OR THIRD FILE so multiply 2nd by norm
1537                        medi *= norm12
1538                        meds *= norm12
1539                Endif
1540               
1541                //Print "NSORT-ed ",name1," + ", name2
1542                //Print "normalized to ",normTo
1543                //Print "multiplicative factor = ",norm12
1544                ControlUpdate/A/W=NSORT_Panel
1545                DoUpdate
1546
1547               
1548                //Make the combined, scaled dataset by overwriting the old sets
1549                Make/O/N=(n12) q12,i12,sig12,sq12,qb12,fs12
1550                Make/O/N=(n12,3) res12
1551                q12[0,n1-1] = lowq[p]
1552                q12[n1,n1+n2-1]= medq[p-n1]
1553                i12[0,n1-1] = lowi[p]
1554                i12[n1,n1+n2-1]= medi[p-n1]
1555                sig12[0,n1-1] = lows[p]
1556                sig12[n1,n1+n2-1]= meds[p-n1]
1557                sq12[0,n1-1] = lowres[p][0]
1558                sq12[n1,n1+n2-1]= medres[p-n1][0]
1559                qb12[0,n1-1] = lowres[p][1]
1560                qb12[n1,n1+n2-1]= medres[p-n1][1]
1561                fs12[0,n1-1] = lowres[p][2]
1562                fs12[n1,n1+n2-1]= medres[p-n1][2]
1563
1564               
1565                Sort q12, q12,i12,sig12,sq12,qb12,fs12
1566                //at this point 1-2 are combined
1567                //do we need to continue, or write out the set here and stop?
1568                if(cmpstr(name3,"none") == 0)
1569                        //stop here
1570                        norm23 = 1              //norm23 was not used
1571                        Variable/G root:myGlobals:NSORT:gScale2_3 = 1
1572                       
1573                        ControlInfo/W=NSORT_Panel PreviewCheck
1574                        if( V_Value==0 )                //if zero skip the preview and write out the file
1575                                res12[][0] = sq12[p]
1576                                res12[][1] = qb12[p]
1577                                res12[][2] = fs12[p]
1578                                err=WriteNSORTedFile(q12,i12,sig12,name1,name2,name3,name4,normToStr,norm12,norm23,norm34,res=res12)
1579                        endif
1580                        // always clean up waves before exiting
1581                        KillWaves/Z q12,i12,sig12,sq12,qb12,fs12
1582                        return err
1583                Endif
1584               
1585                //need to add the third file... which was already loaded at the top of the function
1586                /////
1587                //order points in sets 12-3, indexing overlap region
1588                //put result in temporary waves
1589                WaveStats/Q q12
1590                n12 = V_npnts
1591                WaveStats/Q $"root:HighQSet:TrimHighQSet_q"
1592                n3 = V_npnts
1593                n123 = n12+ n3
1594               
1595                Make/O/N=(n123) q123,i123,sig123,sq123,qb123,fs123
1596                Make/O/N=(n123,3) res123
1597                WAVE highq = $"root:HighQSet:TrimHighQSet_q"
1598                WAVE highi = $"root:HighQSet:TrimHighQSet_i"
1599                WAVE highs = $"root:HighQSet:TrimHighQSet_s"
1600                WAVE highres = $"root:HighQSet:TrimHighQSet_res"
1601       
1602       
1603                q123[0,n12-1] = q12[p]
1604                q123[n12,n12+n3-1]= highq[p-n12]
1605                i123[0,n12-1] = i12[p]
1606                i123[n12,n12+n3-1]= highi[p-n12]
1607                sig123[0,n12-1] = sig12[p]
1608                sig123[n12,n12+n3-1]= highs[p-n12]
1609                sq123[0,n12-1] = sq12[p]
1610                sq123[n12,n12+n3-1]= highres[p-n12][0]
1611                qb123[0,n12-1] = qb12[p]
1612                qb123[n12,n12+n3-1]= highres[p-n12][1]
1613                fs123[0,n12-1] = fs12[p]
1614                fs123[n12,n12+n3-1]= highres[p-n12][2]
1615
1616               
1617                Sort q123, q123,i123,sig123,sq123,qb123,fs123
1618                /////////////////
1619               
1620                //find the maximum point number of set 2  in the overlap region
1621                FindLevel/P/Q highq,(q12[n12-1])
1622                num2 = trunc(V_levelX)
1623                //Print "num2 = ",num2
1624               
1625                if (auto)
1626                        //there must be overlap points to use auto-scaling
1627                        if(numtype(num2) != 0)
1628                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1629                        endif
1630                        //do auto-scaling of data
1631                        norm23 = NCNR_GetScalingInOverlap(num2,q12,i12,highq,highi)
1632                        //Set the global variable for the 12 - 3 scale factor
1633                        Variable/G root:myGlobals:NSORT:gScale2_3 = norm23
1634                else
1635                        //use the value from the panel ( which is the global)
1636                        NVAR temp23 = root:myGlobals:NSORT:gScale2_3
1637                        norm23 = temp23
1638                Endif
1639               
1640                If( (normTo== 1) || (normTo ==2) )
1641                        //normalize to first or second file, so multiply third by norm23
1642                        highi *= norm23
1643                        highs *= norm23
1644                else
1645                        //normalize to THIRD file, 1-2 by 1/norm23
1646                        norm23 = 1/norm23
1647                        i12 *= norm23
1648                        sig12 *= norm23
1649                        // for the display, scale the trimmed sets 1 and 2
1650                        lowi *= norm23
1651                        lows *= norm23
1652                        medi *= norm23
1653                        meds *= norm23
1654                Endif
1655               
1656                //Print "NSORT-ed ",name1," + ", name2, " + ", name3
1657                //Print "normalized to ",normTo
1658                //Print "multiplicative factor 1-2 = ",norm12," multiplicative factor 12 - 3 = ",norm23
1659                ControlUpdate/A/W=NSORT_Panel
1660                DoUpdate
1661               
1662                Make/O/N=(n123) q123,i123,sig123
1663                Make/O/N=(n123,3) res123
1664                q123[0,n12-1] = q12[p]
1665                q123[n12,n12+n3-1]= highq[p-n12]
1666                i123[0,n12-1] = i12[p]
1667                i123[n12,n12+n3-1]= highi[p-n12]
1668                sig123[0,n12-1] = sig12[p]
1669                sig123[n12,n12+n3-1]= highs[p-n12]
1670                sq123[0,n12-1] = sq12[p]
1671                sq123[n12,n12+n3-1]= highres[p-n12][0]
1672                qb123[0,n12-1] = qb12[p]
1673                qb123[n12,n12+n3-1]= highres[p-n12][1]
1674                fs123[0,n12-1] = fs12[p]
1675                fs123[n12,n12+n3-1]= highres[p-n12][2]
1676
1677               
1678                Sort q123, q123,i123,sig123,sq123,qb123,fs123
1679                //at this point 12 - 3 are combined
1680               
1681                //do we need to continue, or write out the set here and stop?
1682                if(cmpstr(name4,"none") == 0)
1683                        //stop here
1684               
1685                        ControlInfo/W=NSORT_Panel PreviewCheck
1686                        if( V_Value==0 )                //if zero skip the preview and write out the file
1687                                res123[][0] = sq123[p]
1688                                res123[][1] = qb123[p]
1689                                res123[][2] = fs123[p]
1690                                err=WriteNSORTedFile(q123,i123,sig123,name1,name2,name3,name4,normToStr,norm12,norm23,norm34,res=res123)
1691                        endif
1692                        // always clean up waves before exiting
1693                        KillWaves/Z q12,i12,sig12,q123,i123,sig123,sq123,qb123,fs123 //,res123
1694                        return err
1695                Endif
1696               
1697                // new 2016 - combine the 4th data set
1698
1699                //need to add the fourth file... which was already loaded at the top of the function
1700                /////
1701                //order points in sets 123-4, indexing overlap region
1702                //put result in temporary waves
1703                WaveStats/Q q123
1704                n123 = V_npnts
1705                WaveStats/Q $"root:HighestQSet:TrimHighestQSet_q"
1706                n4 = V_npnts
1707                n1234 = n123 + n4
1708               
1709                Make/O/N=(n1234) q1234,i1234,sig1234,sq1234,qb1234,fs1234
1710                Make/O/N=(n1234,3) res1234
1711                WAVE highestq = $"root:HighestQSet:TrimHighestQSet_q"
1712                WAVE highesti = $"root:HighestQSet:TrimHighestQSet_i"
1713                WAVE highests = $"root:HighestQSet:TrimHighestQSet_s"
1714                WAVE highestres = $"root:HighestQSet:TrimHighestQSet_res"
1715       
1716       
1717                q1234[0,n123-1] = q123[p]
1718                q1234[n123,n123+n4-1]= highestq[p-n123]
1719                i1234[0,n123-1] = i123[p]
1720                i1234[n123,n123+n4-1]= highesti[p-n123]
1721                sig1234[0,n123-1] = sig123[p]
1722                sig1234[n123,n123+n4-1]= highests[p-n123]
1723                sq1234[0,n123-1] = sq123[p]
1724                sq1234[n123,n123+n4-1]= highestres[p-n123][0]
1725                qb1234[0,n123-1] = qb123[p]
1726                qb1234[n123,n123+n4-1]= highestres[p-n123][1]
1727                fs1234[0,n123-1] = fs123[p]
1728                fs1234[n123,n123+n4-1]= highestres[p-n123][2]
1729
1730               
1731                Sort q1234, q1234,i1234,sig1234,sq1234,qb1234,fs1234
1732                /////////////////
1733               
1734                //find the maximum point number of set 2  in the overlap region
1735                FindLevel/P/Q highestq,(q123[n123-1])
1736                num2 = trunc(V_levelX)
1737                //Print "num2 = ",num2
1738               
1739                if (auto)
1740                        //there must be overlap points to use auto-scaling
1741                        if(numtype(num2) != 0)
1742                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1743                        endif
1744                        //do auto-scaling of data
1745                        norm34 = NCNR_GetScalingInOverlap(num2,q123,i123,highestq,highesti)
1746                        //Set the global variable for the 12 - 3 scale factor
1747                        Variable/G root:myGlobals:NSORT:gScale3_4 = norm34
1748                else
1749                        //use the value from the panel ( which is the global)
1750                        NVAR temp34 = root:myGlobals:NSORT:gScale3_4
1751                        norm34 = temp34
1752                Endif
1753
1754// normalization
1755                switch (normTo)
1756                        case 1:
1757                        case 2:
1758                        case 3:
1759                                //normalize to first or second or third file, so multiply fourth by norm34
1760                                highesti *= norm34
1761                                highests *= norm34
1762                                break
1763                        case 4:
1764                                //normalize to FOURTH file, 123 by multiplicative factor 1/norm34
1765                                norm34 = 1/norm34
1766                                i123 *= norm34
1767                                sig123 *= norm34
1768                                // for the display, scale the trimmed sets 1 and 2 and 3
1769                                lowi *= norm34
1770                                lows *= norm34
1771                                medi *= norm34
1772                                meds *= norm34
1773                                highi *= norm34
1774                                highs *= norm34
1775                                break
1776                endswitch
1777               
1778       
1779                //Print "NSORT-ed ",name1," + ", name2, " + ", name3
1780                //Print "normalized to ",normTo
1781                //Print "multiplicative factor 1-2 = ",norm12," multiplicative factor 12 - 3 = ",norm23
1782                ControlUpdate/A/W=NSORT_Panel
1783                DoUpdate
1784               
1785                Make/O/N=(n1234) q1234,i1234,sig1234
1786                Make/O/N=(n1234,3) res1234
1787                q1234[0,n123-1] = q123[p]
1788                q1234[n123,n123+n4-1]= highestq[p-n123]
1789                i1234[0,n123-1] = i123[p]
1790                i1234[n123,n123+n4-1]= highesti[p-n123]
1791                sig1234[0,n123-1] = sig123[p]
1792                sig1234[n123,n123+n4-1]= highests[p-n123]
1793                sq1234[0,n123-1] = sq123[p]
1794                sq1234[n123,n123+n4-1]= highestres[p-n123][0]
1795                qb1234[0,n123-1] = qb123[p]
1796                qb1234[n123,n123+n4-1]= highestres[p-n123][1]
1797                fs1234[0,n123-1] = fs123[p]
1798                fs1234[n123,n123+n4-1]= highestres[p-n123][2]
1799               
1800                Sort q1234, q1234,i1234,sig1234,sq1234,qb1234,fs1234
1801                //at this point 123 - 4 are combined
1802               
1803//write out the set here and stop
1804                        //stop here
1805       
1806                ControlInfo/W=NSORT_Panel PreviewCheck
1807                if( V_Value==0 )                //if zero skip the preview and write out the file
1808                        res1234[][0] = sq1234[p]
1809                        res1234[][1] = qb1234[p]
1810                        res1234[][2] = fs1234[p]
1811                        err=WriteNSORTedFile(q1234,i1234,sig1234,name1,name2,name3,name4,normToStr,norm12,norm23,norm34,res=res1234)
1812                endif
1813                // always clean up waves before exiting
1814                KillWaves/Z q123,i123,sig123,q1234,i1234,sig1234,sq1234,qb1234,fs1234 //,res1234
1815                return err
1816
1817                //combined dataset will already be displayed if the NSORT_Graph is open
1818       
1819                ////////////////
1820                return err
1821   endif // End the if(6-column) specific stuff here
1822       
1823       
1824End
1825
1826
1827
1828
1829
1830
1831/////////////////////////////////////////////////////////////
1832// testing, may speed up NSORT, NCNR-specific naming scheme of
1833// run numbers and a run prefix
1834//
1835// it is assumed that you are combining data from the current reduction session,
1836// so that the XML y/n hasn't changed.
1837//
1838Function Set3NSORTFiles(low,med,hi,pref)
1839        Variable low,med,hi
1840        String pref
1841       
1842        //make strings from the numbers
1843        String absStr="",ext
1844        Variable popNum
1845        DoWindow/F NSORT_Panel
1846       
1847        SVAR lowQPopStr = root:myGlobals:NSORT:gDataPopList
1848        SVAR medHiQPopStr = root:myGlobals:NSORT:gDataPopList_3
1849       
1850        NVAR useXMLOutput = root:Packages:NIST:gXML_Write
1851        if(useXMLOutput)
1852                ext = ".ABSx"
1853        else
1854                ext = ".ABS"
1855        endif
1856       
1857        //lowQ menu
1858        absStr = pref+RunDigitString(low)+ext
1859        popNum = WhichListItem(absStr,lowQPopStr,";",0)
1860        if(popNum == -1)
1861                Abort "Could not find file: " + absStr +" aborting...  Be sure that your output format is the same as the input"
1862        endif
1863        popNum += 1             // add 1 to get the item number
1864        PopupMenu popup_1,win=NSORT_Panel,mode=(popNum)
1865       
1866        //medQ (a different list for the popup)
1867        absStr = pref+RunDigitString(med)+ext
1868        popNum = WhichListItem(absStr,medHiQPopStr,";",0)
1869        if(popNum == -1)
1870                Abort "Could not find file: "+absStr+" aborting...  Be sure that your output format is the same as the input"
1871        endif
1872        popNum += 1             // add 1 to get the item number
1873        PopupMenu popup_2,win=NSORT_Panel,mode=(popNum)
1874       
1875       
1876        //highQ (same pop list as medQ)
1877        if(hi != 0)
1878                absStr = pref+RunDigitString(hi)+ext
1879                popNum = WhichListItem(absStr,medHiQPopStr,";",0)
1880                if(popNum == -1)
1881                        Abort "Could not find file: "+absStr+" aborting...  Be sure that your output format is the same as the input"
1882                endif
1883                popNum += 1             // add 1 to get the item number
1884                PopupMenu popup_3,win=NSORT_Panel,mode=(popNum)
1885        else
1886                PopupMenu popup_3,win=NSORT_Panel,mode=(1)
1887        endif
1888End
1889
1890/////////////////////////////////////////////////////////////
1891// testing, may speed up NSORT, NCNR-specific naming scheme of
1892// run numbers and a run prefix
1893//
1894// it is assumed that you are combining data from the current reduction session,
1895// so that the XML y/n hasn't changed.
1896//
1897// updated to use 4 files
1898//
1899// TODO:
1900// -- still assuming ABS
1901//
1902Function Set4NSORTFiles(low,med,hi,highest,pref)
1903        Variable low,med,hi,highest
1904        String pref
1905       
1906        //make strings from the numbers
1907        String absStr="",ext
1908        Variable popNum
1909        DoWindow/F NSORT_Panel
1910       
1911        SVAR lowQPopStr = root:myGlobals:NSORT:gDataPopList
1912        SVAR medHiQPopStr = root:myGlobals:NSORT:gDataPopList_3
1913       
1914        NVAR useXMLOutput = root:Packages:NIST:gXML_Write
1915        if(useXMLOutput)
1916                ext = ".ABSx"
1917        else
1918                ext = ".ABS"
1919        endif
1920       
1921        //lowQ menu
1922        absStr = pref+RunDigitString(low)+ext
1923        popNum = WhichListItem(absStr,lowQPopStr,";",0)
1924        if(popNum == -1)
1925                Abort "Could not find file: " + absStr +" aborting...  Be sure that your output format is the same as the input"
1926        endif
1927        popNum += 1             // add 1 to get the item number
1928        PopupMenu popup_1,win=NSORT_Panel,mode=(popNum)
1929       
1930        //medQ (a different list for the popup)
1931        absStr = pref+RunDigitString(med)+ext
1932        popNum = WhichListItem(absStr,medHiQPopStr,";",0)
1933        if(popNum == -1)
1934                Abort "Could not find file: "+absStr+" aborting...  Be sure that your output format is the same as the input"
1935        endif
1936        popNum += 1             // add 1 to get the item number
1937        PopupMenu popup_2,win=NSORT_Panel,mode=(popNum)
1938       
1939       
1940        //highQ (same pop list as medQ)
1941        if(hi != 0)
1942                absStr = pref+RunDigitString(hi)+ext
1943                popNum = WhichListItem(absStr,medHiQPopStr,";",0)
1944                if(popNum == -1)
1945                        Abort "Could not find file: "+absStr+" aborting...  Be sure that your output format is the same as the input"
1946                endif
1947                popNum += 1             // add 1 to get the item number
1948                PopupMenu popup_3,win=NSORT_Panel,mode=(popNum)
1949        else
1950                PopupMenu popup_3,win=NSORT_Panel,mode=(1)
1951        endif
1952       
1953        //highestQ (same pop list as medQ)
1954        if(highest != 0)
1955                absStr = pref+RunDigitString(highest)+ext
1956                popNum = WhichListItem(absStr,medHiQPopStr,";",0)
1957                if(popNum == -1)
1958                        Abort "Could not find file: "+absStr+" aborting...  Be sure that your output format is the same as the input"
1959                endif
1960                popNum += 1             // add 1 to get the item number
1961                PopupMenu popup_4,win=NSORT_Panel,mode=(popNum)
1962        else
1963                PopupMenu popup_4,win=NSORT_Panel,mode=(1)
1964        endif
1965       
1966        return(0)
1967End
1968
1969//more beta procedures - to create a table of scattering runs to combine with NSORT
1970Proc CreateTableToCombine(ctrlName)
1971        String ctrlName
1972       
1973        NewDataFolder/O root:myGlobals:CombineTable
1974//      DoWindow/F CombineTable
1975       
1976        Make/O/T/N=0 $"root:myGlobals:CombineTable:Filenames"
1977        Make/O/T/N=0 $"root:myGlobals:CombineTable:Suffix"
1978        Make/O/T/N=0 $"root:myGlobals:CombineTable:Labels"
1979        Make/O/D/N=0 $"root:myGlobals:CombineTable:SDD"
1980        Make/O/D/N=0 $"root:myGlobals:CombineTable:RunNumber"
1981        Make/O/D/N=0 $"root:myGlobals:CombineTable:IsTrans"
1982
1983
1984        AppendToTable/W=CombinePanel#GroupedFiles root:myGlobals:CombineTable:Labels, root:myGlobals:CombineTable:SDD, root:myGlobals:CombineTable:RunNumber
1985
1986        ModifyTable/W=CombinePanel#GroupedFiles width(:myGlobals:CombineTable:SDD)=40
1987        ModifyTable/W=CombinePanel#GroupedFiles width(:myGlobals:CombineTable:Labels)=180
1988        ModifyTable/W=CombinePanel#GroupedFiles width(Point)=0          //JUN04, remove point numbers - confuses users since point != run
1989
1990
1991        //get a list of all files in the folder, some will be junk version numbers that don't exist     
1992        String list,partialName,tempName,temp=""
1993        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
1994        Variable numitems,ii,ok
1995       
1996        //remove version numbers from semicolon-delimited list
1997        list =  RemoveVersNumsFromList(list)
1998        numitems = ItemsInList(list,";")
1999       
2000        //loop through all of the files in the list, reading CAT/SHORT information if the file is RAW SANS
2001        //***version numbers have been removed***
2002        String str,fullName
2003        Variable lastPoint
2004        ii=0
2005       
2006        Make/T/O/N=0 notRAWlist
2007        do
2008                //get current item in the list
2009                partialName = StringFromList(ii, list, ";")
2010                //get a valid file based on this partialName and catPathName
2011                tempName = FindValidFilename(partialName)
2012                If(cmpstr(tempName,"")==0)              //a null string was returned
2013                        //write to notebook that file was not found
2014                        //if string is not a number, report the error
2015                        if(numtype(str2num(partialName)) == 2)
2016                                str = "this file was not found: "+partialName+"\r\r"
2017                                //Notebook CatWin,font="Times",fsize=12,text=str
2018                        Endif
2019                else
2020                        //prepend path to tempName for read routine
2021                        PathInfo catPathName
2022                        FullName = S_path + tempName
2023                        //make sure the file is really a RAW data file
2024                        ok = CheckIfRawData(fullName)
2025                        if (!ok)
2026                                //write to notebook that file was not a RAW SANS file
2027                                lastPoint = numpnts(notRAWlist)
2028                                InsertPoints lastPoint,1,notRAWlist
2029                                notRAWlist[lastPoint]=tempname
2030                        else
2031                                //go write the header information to the Notebook
2032                                GetHeaderInfoToCombineWave(fullName,tempName)
2033                        Endif
2034                Endif
2035                ii+=1
2036        while(ii<numitems)
2037//Now sort them all based on the suffix data (orders them as collected)
2038//      SortCombineWaves()
2039// sort by label
2040        SortCombineByLabel()
2041// remove the transmission waves
2042//
2043        RemoveTransFilesFromCombine()
2044//
2045        SetDataFolder root:
2046       
2047        Killwaves/Z notRAWlist
2048End
2049
2050
2051Function RemoveTransFilesFromCombine()
2052        Wave/T filenames = $"root:myGlobals:CombineTable:Filenames"
2053        Wave/T suffix = $"root:myGlobals:CombineTable:Suffix"
2054        Wave/T labels = $"root:myGlobals:CombineTable:Labels"
2055        Wave sdd = $"root:myGlobals:CombineTable:SDD"
2056        Wave runnum = $"root:myGlobals:CombineTable:RunNumber"
2057        Wave isTrans = $"root:myGlobals:CombineTable:IsTrans"
2058       
2059        Variable num=numpnts(isTrans),ii
2060        ii=num-1
2061        do
2062                if(isTrans[ii] != 0)
2063                        DeletePoints ii, 1, filenames,suffix,labels,sdd,runnum,isTrans
2064                endif
2065                ii-=1
2066        while(ii>=0)
2067        return(0)
2068End
2069
2070//reads header information and puts it in the appropriate waves for display in the table.
2071//fname is the full path for opening (and reading) information from the file
2072//which alreay was found to exist. sname is the file;vers to be written out,
2073//avoiding the need to re-extract it from fname.
2074Function GetHeaderInfoToCombineWave(fname,sname)
2075        String fname,sname
2076       
2077        String textstr,temp,lbl,date_time,suffix
2078        Variable ctime,lambda,sdd,detcnt,cntrate,refNum,trans,thick,xcenter,ycenter,numatten
2079        Variable lastPoint, beamstop
2080
2081        Wave/T GFilenames = $"root:myGlobals:CombineTable:Filenames"
2082        Wave/T GSuffix = $"root:myGlobals:CombineTable:Suffix"
2083        Wave/T GLabels = $"root:myGlobals:CombineTable:Labels"
2084        Wave GSDD = $"root:myGlobals:CombineTable:SDD"
2085        Wave GRunNumber = $"root:myGlobals:CombineTable:RunNumber"
2086        Wave GIsTrans = $"root:myGlobals:CombineTable:IsTrans"
2087       
2088        lastPoint = numpnts(GLambda)
2089               
2090        InsertPoints lastPoint,1,GFilenames
2091        GFilenames[lastPoint]=sname
2092       
2093        //read the file suffix
2094        InsertPoints lastPoint,1,GSuffix
2095        GSuffix[lastPoint]=getSuffix(fname)
2096
2097        // read the sample.label text field
2098        InsertPoints lastPoint,1,GLabels
2099        GLabels[lastPoint]=getSampleLabel(fname)
2100       
2101        //read in the SDD
2102        InsertPoints lastPoint,1,GSDD
2103        GSDD[lastPoint]= getSDD(fname)
2104
2105        //the run number (not displayed in the table, but carried along)
2106        InsertPoints lastPoint,1,GRunNumber
2107        GRunNumber[lastPoint] = GetRunNumFromFile(sname)
2108
2109        // 0 if the file is a scattering  file, 1 (truth) if the file is a transmission file
2110        InsertPoints lastPoint,1,GIsTrans
2111        GIsTrans[lastPoint]  = isTransFile(fname)               //returns one if beamstop is "out"
2112       
2113        KillWaves/Z w
2114        return(0)
2115End
2116
2117//sorts all of the waves of header information using the suffix (A123)
2118//the result is that all of the data is in the order that it was collected,
2119// regardless of how the prefix or run numbers were changed by the user
2120Function SortCombineWaves()
2121        Wave/T GFilenames = $"root:myGlobals:CombineTable:Filenames"
2122        Wave/T GSuffix = $"root:myGlobals:CombineTable:Suffix"
2123        Wave/T GLabels = $"root:myGlobals:CombineTable:Labels"
2124        Wave GSDD = $"root:myGlobals:CombineTable:SDD"
2125        Wave GRunNumber = $"root:myGlobals:CombineTable:RunNumber"
2126        Wave GIsTrans = $"root:myGlobals:CombineTable:IsTrans"
2127
2128//      Sort GSuffix, GSuffix, GFilenames, GLabels, GDateTime, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens,GRunNumber,GIsTrans
2129        Sort GSuffix, GSuffix, GFilenames, GLabels, GSDD, GRunNumber, GIsTrans
2130        return(0)
2131End
2132
2133//sorts all of the waves of header information using the suffix (A123)
2134//the result is that all of the data is in the order that it was collected,
2135// regardless of how the prefix or run numbers were changed by the user
2136Function SortCombineByLabel()
2137        Wave/T GFilenames = $"root:myGlobals:CombineTable:Filenames"
2138        Wave/T GSuffix = $"root:myGlobals:CombineTable:Suffix"
2139        Wave/T GLabels = $"root:myGlobals:CombineTable:Labels"
2140        Wave GSDD = $"root:myGlobals:CombineTable:SDD"
2141        Wave GRunNumber = $"root:myGlobals:CombineTable:RunNumber"
2142        Wave GIsTrans = $"root:myGlobals:CombineTable:IsTrans"
2143
2144        Sort GLabels, GSuffix, GFilenames, GLabels, GSDD, GRunNumber, GIsTrans
2145//      Sort {GLabels, GSDD}, GSuffix, GFilenames, GLabels, GSDD, GRunNumber, GIsTrans          //sort on GLabels, GSDD breaks the tie
2146        return(0)
2147End
2148
2149//main procedure, called from the menu
2150// sets a flag (temporarily) to use the names from the table
2151// during the procedure that writes the data files.
2152//
2153//
2154Function DoCombineFiles(ctrlName)
2155        String ctrlName
2156       
2157       
2158        if(WinType("NSORT_Panel") == 0)
2159                DoAlert 0, "The SORT Panel must be open to combine the files"
2160                return(0)
2161        endif
2162       
2163        DoAlert 1,"Do you have all the assignments set in the bottom table? If not, < No > will exit."
2164        if(V_flag == 2)
2165                return(0)               //no, get out
2166        endif
2167        // pop all of the menus to make sure that they are properly populated
2168        LowQPopMenuProc("",1,"")
2169        MedQPopMenuProc("",1,"")
2170        HighQPopMenuProc("",1,"")
2171        HighestQPopMenuProc("",1,"")
2172       
2173//      String savedDataFolder = GetDataFolder(1)               // save
2174        Wave LowRun = root:myGlobals:CombineTable:LowRun
2175        Wave MediumRun = root:myGlobals:CombineTable:MediumRun
2176        Wave HighRun = root:myGlobals:CombineTable:HighRun
2177        Wave HighestRun = root:myGlobals:CombineTable:HighestRun
2178        Wave/T prefix = root:myGlobals:CombineTable:Prefix
2179        Wave/T saveName = root:myGlobals:CombineTable:saveName
2180
2181        Variable/G root:myGlobals:CombineTable:useTable=1
2182       
2183        Variable num=numpnts(lowRun),ii,lowFile,medFile,hiFile,highestFile
2184        String prefixStr = ""
2185        Pathinfo catPathName
2186        String path=S_Path
2187       
2188        ii=0
2189        do
2190                lowFile = LowRun[ii]
2191                medFile = MediumRun[ii]
2192                hiFile = highRun[ii]
2193                highestFile = highestRun[ii]
2194                prefixStr = prefix[ii]
2195               
2196                Set4NSORTFiles(lowFile,medFile,hiFile,highestFile,prefixStr)            //set the files and pop the NSORT popups
2197               
2198                //pass the new file name in as a global (ugh!)
2199                String/G root:myGlobals:CombineTable:SaveNameStr = path+saveName[ii]
2200                //combine the files and write the data
2201                WriteNSORTFileButton("")
2202               
2203                Print "wrote file : ",path+saveName[ii]
2204                ii+=1
2205        while(ii<num)
2206
2207        Variable/G root:myGlobals:CombineTable:useTable=0               //turn this off immediately
2208       
2209        return(0)
2210End
2211
2212
2213// only respond to clicks in the subwindow (table) rather than everywhere. Hooks can't be set for subwindows
2214//
2215//// Window hook example:
2216//  WINDOW:CombinePanel;HCSPEC:CombinePanel#GroupedFiles;EVENT:mouseup;MOUSEX:152;MOUSEY:143;TICKS:7722029;MODIFIERS:0;
2217//
2218Function CombineTableHook(infoStr)
2219        String infoStr
2220        String event= StringByKey("EVENT",infoStr)
2221        String subwin = StringByKey("HCSPEC",infoStr)
2222//      Print subwin
2223//      Print infoStr
2224//      Print "EVENT= ",event
2225        if(cmpstr(subwin,"CombinePanel#GroupedFiles")==0)
2226                strswitch(event)
2227                        case "mousedown":
2228                                Variable xpix= NumberByKey("MOUSEX",infoStr)
2229                                Variable ypix= NumberByKey("MOUSEY",infoStr)
2230                                Variable modif= NumberByKey("MODIFIERS",infoStr)
2231                                //print modif
2232                                if(modif & 2^1)         //bit 1 set, shift key is down
2233                                        PopupContextualMenu/C=(xpix, ypix) "combine;"
2234                                        strswitch(S_selection)
2235                                                case "combine":
2236                                                        //Print "combine the files"
2237                                                        SendSelectionToTable()
2238                                                        break
2239                                        endswitch               //on selection
2240                                endif
2241                endswitch       // on event
2242        endif
2243        return 0
2244End
2245
2246//ASSUMES 3 FILES!!!!
2247Function SendSelectionToTable()
2248
2249        DoWindow/F CombinePanel
2250        if(V_flag==0)
2251//              Make/O/N=0 $"root:myGlobals:CombineTable:Low"
2252//              Make/O/N=0 $"root:myGlobals:CombineTable:Medium"
2253//              Make/O/N=0 $"root:myGlobals:CombineTable:High"
2254//              Make/O/T/N=0 $"root:myGlobals:CombineTable:Prefix"
2255//              Make/O/T/N=0 $"root:myGlobals:CombineTable:SaveName"
2256//              edit Low,Medium,High,Prefix,SaveName as "Run Numbers to Combine"
2257//              DoWindow/C ToCombine
2258
2259                return(0)
2260               
2261        else
2262                Wave low = $"root:myGlobals:CombineTable:LowRun"
2263                Wave medium = $"root:myGlobals:CombineTable:MediumRun"
2264                Wave high = $"root:myGlobals:CombineTable:HighRun"
2265                Wave highest = $"root:myGlobals:CombineTable:HighestRun"
2266                Wave/T prefix = $"root:myGlobals:CombineTable:Prefix"
2267                Wave/T saveName = $"root:myGlobals:CombineTable:SaveName"
2268               
2269                Wave/T gLabels = $"root:myGlobals:CombineTable:Labels"
2270                Wave gSDD = $"root:myGlobals:CombineTable:SDD"
2271                Wave gRunNumber = $"root:myGlobals:CombineTable:RunNumber"
2272                Wave/T filenames = $"root:myGlobals:CombineTable:FileNames"
2273        endif
2274       
2275        GetSelection table,CombinePanel#GroupedFiles,3
2276//      Print V_startRow, V_endRow
2277       
2278        //prompt for combined name, give the user a chance to cancel
2279        Variable num=V_endRow-V_startRow+1
2280        Variable ii
2281        String saveStr=""
2282        Prompt saveStr,"saved file name for "+ gLabels[V_StartRow]      //+tmpLbl[1]
2283        DoPrompt "Enter the combined file name",saveStr
2284        if(V_flag==1)
2285                return(1)               //user cancel, get out before anything is set
2286        endif
2287
2288        if( !(num==2 || num==3 || num==4) )
2289                Abort "invalid table selection - must select either 2 or 3 or 4 files to combine"
2290        endif
2291        Make/O/T/N=(4) tmpLbl
2292        Make/O/N=(4) tmpSDD,tmpRun
2293       
2294        //initialize with fake values in case 2 or 3 files are combined
2295        tmpLbl = ""
2296        tmpSDD = 0.01           //fake sdd in meters to always be the "highest" Q
2297        tmpRun = 0                      //pass a run number of zero to be later interpreted as "none"
2298       
2299        //fill in the real values from the selection
2300        for(ii=V_startRow;ii<=V_endRow;ii+=1)
2301                tmpLbl[ii-V_startRow] = gLabels[ii]
2302                tmpSDD[ii-V_startRow] = gSDD[ii]
2303                tmpRun[ii-V_startRow] = gRunNumber[ii]
2304        endfor
2305//      if(num==2)      // then "highest" q run needs to be forced to zero
2306//              ii=2
2307//              tmpLbl[ii] = ""
2308//              tmpSDD[ii] = 0.01               //fake sdd in meters to always be the "highest" Q
2309//              tmpRun[ii] = 0                  //pass a run number of zero to be later interpreted as "none"
2310//      endif
2311        Sort tmpSDD, tmpSDD,tmpLbl,tmpRun
2312       
2313//      Print tmpSDD
2314       
2315        num=numpnts(low)
2316        InsertPoints num, 1, low,medium,high,highest,prefix,SaveName
2317        low[num] = tmpRun[3]
2318        medium[num] = tmpRun[2]
2319        high[num] = tmpRun[1]
2320        highest[num] = tmpRun[0]
2321        prefix[num] = GetPrefixStrFromFile(filenames[ii])
2322        saveName[num] = saveStr
2323
2324        KillWaves/Z tmpLbl,tmpRun,tmpSDD
2325        return(0)
2326end
2327
2328
2329////////////////////////
2330// replaces the beta menu items
2331//
2332
2333Proc ShowCombinePanel()
2334        DoWindow/F CombinePanel
2335        if(V_flag==0)
2336                CombinePanel()
2337                CreateTableToCombine("")
2338                DoAlert 1,"Do you want to clear the list of runs and file names to combine?"
2339                TableToCombineAndSave(V_flag==1)                // clear and initialize, if desired
2340        endif
2341end
2342
2343Proc CombinePanel()
2344        PauseUpdate; Silent 1           // building window...
2345        NewPanel /W=(546,442,1197,915) /K=1 as "Sort and Combine Data Files"
2346        ModifyPanel cbRGB=(49151,53155,65535)
2347        DoWindow/C CombinePanel
2348        Button button0_0,pos={20,20},size={160,20},proc=CreateTableToCombine,title="List Files to Combine"
2349        Button button0_1,pos={206,20},size={140,20},proc=DoCombineFiles,title="Combine Files"
2350        Button button0_2,pos={509,40},size={60,20},proc=CombinePanelDone,title="Done"
2351        Button button0_3,pos={522,14},size={30,20},proc=ShowCombineHelp,title="?"
2352        Button button0_4,pos={500,220},size={120,20},proc=ClearCombineTable,title="Clear Table?"
2353        Edit/W=(20,54,368,249)/HOST=#
2354        ModifyTable format=1,width=0
2355        RenameWindow #,GroupedFiles
2356        SetActiveSubwindow ##
2357        Edit/W=(20,263,634,455)/HOST=#
2358        ModifyTable format=1
2359        RenameWindow #,RunNumbersToCombine
2360        SetActiveSubwindow ##
2361        SetWindow kwTopWin hook=CombineTableHook, hookevents=1  // mouse down events
2362EndMacro
2363
2364Proc ShowCombineHelp(ctrlName): ButtonControl
2365        String ctrlName
2366        DisplayHelpTopic/K=1/Z "SANS Data Reduction Tutorial[Batch Combine Data Files]"
2367        if(V_flag !=0)
2368                DoAlert 0,"The SANS Data Reduction Tutorial Help file could not be found"
2369        endif
2370end
2371
2372Function CombinePanelDone(ctrlName)
2373        String ctrlName
2374       
2375        DoWindow/K CombinePanel
2376        return(0)
2377end
2378
2379Function ClearCombineTable(ctrlName)
2380        String ctrlName
2381       
2382        DoAlert 1,"Do you want to clear the list of runs and file names to combine?"
2383        TableToCombineAndSave(V_flag==1)                // clear and initialize, if desired
2384        return(0)
2385end
2386
2387Function TableToCombineAndSave(clear)
2388        Variable clear
2389       
2390        if(clear)
2391                // make the waves and table for the sets to combine
2392                Make/O/N=0 $"root:myGlobals:CombineTable:LowRun"
2393                Make/O/N=0 $"root:myGlobals:CombineTable:MediumRun"
2394                Make/O/N=0 $"root:myGlobals:CombineTable:HighRun"
2395                Make/O/N=0 $"root:myGlobals:CombineTable:HighestRun"
2396                Make/O/T/N=0 $"root:myGlobals:CombineTable:Prefix"
2397                Make/O/T/N=0 $"root:myGlobals:CombineTable:SaveName"
2398        endif
2399        SetDataFolder root:myGlobals:CombineTable
2400       
2401        // make the second table
2402        AppendToTable/W=CombinePanel#RunNumbersToCombine LowRun,MediumRun,HighRun,HighestRun,Prefix,SaveName
2403       
2404        SetDataFolder root:
2405End
2406
2407
2408
2409/////////////////////////////////
2410// currently unused
2411//
2412Proc MakeCombineTable_byName()
2413        NewDataFolder/O root:myGlobals:CombineTable                     //in case it doesn't exist yet
2414        Make/O/T/N=1 lowQfile,medQfile,hiQfile,saveName
2415        Edit/W=(330,148,973,360) lowQfile,medQfile,hiQfile,saveName
2416        ModifyTable format(Point)=1,width(lowQfile)=120,width(medQfile)=120,width(hiQfile)=120
2417        ModifyTable width(saveName)=120
2418End
2419
2420//
2421// currently unused
2422//
2423// Another beta procedure, to allow files to be combined quickly
2424// - make 4 waves (text) with the low, med, hi, and wave names
2425// (if there is no hiQ, then pass a wave with "" for all entries)
2426// - then pass the waves, and the save will work like in the DoCombineFiles
2427//
2428// - the named files must be there - there is no error checking
2429// - the NSORT panel must be open with the proper selections of beg,end and autoscale, etc.
2430//
2431// - could write a little proc to generate a table to fill in and a button to call this
2432// - and then think of quick ways to populate the table with file names (and minimize typos)
2433//
2434Function DoCombineFiles_byName(lowW,medW,hiW,saveW)
2435        Wave/T lowW,medW,hiW,saveW
2436               
2437        if(WinType("NSORT_Panel") == 0)
2438                DoAlert 0, "The SORT Panel must be open to combine the files"
2439                return(0)
2440        endif
2441       
2442        // pop all of the menus to make sure that they are properly populated
2443        LowQPopMenuProc("",1,"")
2444        MedQPopMenuProc("",1,"")
2445        HighQPopMenuProc("",1,"")
2446       
2447        Variable num=numpnts(lowW),ii
2448        String lowFile,medFile,hiFile
2449       
2450        Pathinfo catPathName
2451        String path=S_Path
2452       
2453////////        Make/O/D/N=(numpnts(lowW)) scale_4m
2454        NVAR scale12 = root:myGlobals:NSORT:gScale1_2
2455
2456       
2457// this variable must exist and be set to 1 to be able to automatically name files
2458// and use the global saveNameStr that is passed in
2459// -- turn this off when done   
2460        Variable/G root:myGlobals:CombineTable:useTable=1               
2461
2462        ii=0
2463        do
2464                lowFile = lowW[ii]
2465                medFile = medW[ii]
2466                hiFile = hiW[ii]
2467               
2468                //Set3NSORTFiles(lowFile,medFile,hiFile,prefixStr)              //set the files and pop the NSORT popups
2469                //lowQ menu
2470                PopupMenu popup_1 win=NSORT_Panel,popmatch=lowFile
2471               
2472                // mediumQ menu
2473                if(strlen(medFile)!=0)
2474                        PopupMenu popup_2 win=NSORT_Panel,popmatch=medFile
2475                else
2476                        PopupMenu popup_2,win=NSORT_Panel,popmatch="none"       //set to "none"
2477                endif
2478       
2479                //highQ (same pop list as medQ)
2480                if(strlen(hiFile)!=0)
2481                        PopupMenu popup_3 win=NSORT_Panel,popmatch=hiFile
2482                else
2483                        PopupMenu popup_3,win=NSORT_Panel,popmatch="none"       //set to "none"
2484                endif
2485               
2486               
2487                //pass the new file name in as a global (ugh!)
2488                String/G root:myGlobals:CombineTable:SaveNameStr = path+saveW[ii]
2489                //combine the files and write the data
2490                WriteNSORTFileButton("")
2491               
2492//////          scale_4m[ii] = scale12
2493               
2494                Print "wrote file : ",path+saveW[ii]
2495                ii+=1
2496        while(ii<num)
2497
2498        Variable/G root:myGlobals:CombineTable:useTable=0               //turn this off immediately
2499       
2500        return(0)
2501End
Note: See TracBrowser for help on using the repository browser.