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

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

Made preferences a common panel (moved to PlotUtilsMacro?.ipf and globals to root:Packages:NIST:) and added menu items for all packages. Many files had to be modified so that the preferences could be properly accessed

File Open dialog now is set to "All files" so that XML can be selected. I think that all open access that doesn't already have the full path go through this common function.

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