source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/QKK_NSORT.ipf @ 908

Last change on this file since 908 was 908, checked in by davidm, 10 years ago

Added ANSTO specific files (QKK stands for our SANS Instrument "Quokka")

File size: 63.5 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 = "%15g %15g %15g\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 = "%15g %15g %15g %15g %15g %15g\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 NCNR_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(WinType("NSORT_Graph")==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
498        SetDataFolder root:HighQSet:
499        AppendToGraph/W=NSORT_Graph $"HighQSet_i" vs $"HighQSet_q"
500        ModifyGraph/W=NSORT_Graph log=1,mode=3,marker($"HighQSet_i")=8,msize=2,rgb($"HighQSet_i")=(0,0,65535),opaque($"HighQSet_i")=1
501        ErrorBars/W=NSORT_Graph $"HighQSet_i" Y,wave=($"HighQSet_s",$"HighQSet_s")
502        AppendToGraph/W=NSORT_Graph $"TrimHighQSet_i" vs $"TrimHighQSet_q"
503        ModifyGraph/W=NSORT_Graph mode($"TrimHighQSet_i")=3,marker($"TrimHighQSet_i")=19,msize=2,rgb($"TrimHighQSet_i")=(0,0,65535)
504        SetDataFolder root:
505End
506
507//adds both med-q sets (full and trimmed) to the graph, which is
508//assumed to exist along with the med-q waves
509//
510Function DisplayMedSet()
511        //function assumes that the window "NSORT_Graph" already exists
512//      DoWindow/F NSORT_Graph
513       
514        SetDataFolder root:MedQSet:
515        AppendToGraph/W=NSORT_Graph $"MedQSet_i" vs $"MedQSet_q"
516        ModifyGraph/W=NSORT_Graph log=1,mode=3,marker($"MedQSet_i")=8,msize=2,rgb($"MedQSet_i")=(65535,0,0),opaque($"MedQSet_i")=1
517        ErrorBars/W=NSORT_Graph $"MedQSet_i" Y,wave=($"MedQSet_s",$"MedQSet_s")
518        AppendToGraph/W=NSORT_Graph $"TrimMedQSet_i" vs $"TrimMedQSet_q"
519        ModifyGraph/W=NSORT_Graph mode($"TrimMedQSet_i")=3,marker($"TrimMedQSet_i")=19,msize=2,rgb($"TrimMedQSet_i")=(65535,0,0)
520        SetDataFolder root:
521End
522
523//adds both low-q sets (full and trimmed) to the graph, which is
524//assumed to exist along with the low-q waves
525//
526Function DisplayLowSet()
527        //function assumes that the window "NSORT_Graph" already exists
528//      DoWindow/F NSORT_Graph
529
530        SetDataFolder root:LowQSet:
531        AppendToGraph/W=NSORT_Graph $"LowQSet_i" vs $"LowQSet_q"
532        ModifyGraph/W=NSORT_Graph log=1,mode=3,marker($"LowQSet_i")=8,msize=2,rgb($"LowQSet_i")=(2,39321,1),opaque($"LowQSet_i")=1
533        ErrorBars/W=NSORT_Graph $"LowQSet_i" Y,wave=($"LowQSet_s",$"LowQSet_s")
534        AppendToGraph/W=NSORT_Graph $"TrimLowQSet_i" vs $"TrimLowQSet_q"
535        ModifyGraph/W=NSORT_Graph mode($"TrimLowQSet_i")=3,marker($"TrimLowQSet_i")=19,msize=2,rgb($"TrimLowQSet_i")=(2,39321,1)
536        SetDataFolder root:
537End
538
539//button action procedure to set both the main global of the catPath string
540//and also the duplicate global string used in the NSORT folder
541//after path selected, the popup menus are updated
542//
543Function NSORTPickPathButton(ctrlName) : ButtonControl
544        String ctrlName
545
546        Variable err = PickPath()               //sets global path value
547        SVAR pathStr = root:myGlobals:gCatPathStr
548       
549        //set the global string for NSORT to the selected pathname
550        String/G root:myGlobals:NSORT:gPathStr = pathStr
551       
552        //call each of the popup menu proc's to re-set the menu choices
553        //setting the checkboxes to force update
554//      CheckBox check_0,win=NSORT_Panel,value=1
555//      CheckBox check_1,win=NSORT_Panel,value=1
556//      CheckBox check_2,win=NSORT_Panel,value=1
557        LowQPopMenuProc("popup_1",1,"")
558        MedQPopMenuProc("popup_2",1,"")
559        HighQPopMenuProc("popup_3",1,"")
560       
561End
562
563
564//action procedure associated with the setvar box
565//when a value is entered, the global value is set, and the corresponding dataset
566//is updated on the plot, showing the new result of removing this number of points
567//
568//      SetVar boxes are named beg_N and end_N (so 4th element is the number)
569//
570// 1 == LowQ
571// 2 == MedQ
572// 3 == HighQ
573//
574//"Plot_1" is the low-q button name
575//"Plot_2" is the med-q button name
576//"Plot_3" is the high-q button name
577//
578//calling plot_0_Button() responds as if that named button were pressed
579// and gets the proper number to trim directly from the SetVar
580//
581Function SetBegOrEnd(ctrlName,varNum,varStr,varName) : SetVariableControl
582        String ctrlName
583        Variable varNum
584        String varStr
585        String varName
586       
587//  global is automatically updated as the value is entered
588        String numStr= num2Str( str2num(ctrlName[4]) )
589        Plot_0_Button("Plot_"+numStr)
590        DoWindow/F NSORT_Panel
591End
592
593//this will---
594//re-load the data sets (since they may not have been loaded if they were not plotted)
595// apply the scaling to the datasets (so that they will show up in the graph)
596//and actually write the file
597//
598// then "pop" the  lists to get the new file lists with the new name in the list
599//
600Function WriteNSORTFileButton(ctrlName) : ButtonControl
601        String ctrlName
602               
603        // Put here the dialog that says if ANY of the datasets had 3-column data, the results will all have only three columns
604        // Set the number of output columns
605        Variable isAThree = 0, isASix = 0,err
606        String fileStr="",tempName
607
608        NVAR Columns1 = root:myGlobals:NSORT:gColumns1
609        NVAR Columns2 = root:myGlobals:NSORT:gColumns2
610        NVAR Columns3 = root:myGlobals:NSORT:gColumns3
611        if( (Columns1 == 3) || (Columns2 == 3) || (Columns3 == 3) )
612                isAThree = 1
613        endif
614        if( (Columns1 == 6) || (Columns2 == 6) || (Columns3 == 6) )
615                isASix = 1
616        endif
617        if( (isAThree == 1) && (isASix == 1))
618                DoAlert 0, "These files contained a mixture of 3-column and 6-column data.  Only 3 columns were output."
619        endif
620       
621        //is there just one data set? if so, then dispatch to a simpler routine, since no normalization is needed
622        ControlInfo/W=NSORT_Panel popup_2               //if MedQSet is "none", then so is HighQSet
623        fileStr = S_Value
624        if(cmpstr(fileStr,"none") == 0)
625                // just like in the rescaling routines, always RELOAD the data  !!!
626                //load file1
627                ControlInfo/W=NSORT_Panel popup_1
628                fileStr = S_Value
629                //get a valid file based on this partialName and catPathName
630                tempName = FindValidFilename(fileStr)
631               
632                //prepend path to tempName for read routine
633                PathInfo catPathName
634                tempName = S_path + tempName
635                err = LoadDataForNSORT(tempName,1)
636                //////end load file1
637       
638                //send just the trimmed (LowQ) set to be written out
639                WAVE lowq = $"root:LowQSet:TrimLowQSet_q"
640                WAVE lowi = $"root:LowQSet:TrimLowQSet_i"
641                WAVE lows = $"root:LowQSet:TrimLowQSet_s"
642//              WAVE/Z lowsq = $"root:LowQSet:TrimLowQSet_sq"           //these may not exist
643//              WAVE/Z lowqb = $"root:LowQSet:TrimLowQSet_qb"
644//              WAVE/Z lowfs = $"root:LowQSet:TrimLowQSet_fs"
645                WAVE/Z lowres = $"root:LowQSet:TrimLowQSet_res"
646                NVAR scaleFactor= root:myGlobals:NSORT:gScale1_2
647               
648                //
649                lowi *= scaleFactor
650                lows *= scaleFactor
651               
652                ControlInfo/W=NSORT_Panel PreviewCheck
653                if( V_Value==1 )                //if ==1, just preview and exit
654                        return(0)
655                endif
656                       
657                ControlInfo/W=NSORT_Panel popup_1
658                if(isAThree)
659                        WriteNSORTedFile(lowq,lowi,lows,S_Value,"none","none",S_Value,scaleFactor,1)
660                else
661                        WriteNSORTedFile(lowq,lowi,lows,S_Value,"none","none",S_Value,scaleFactor,1,res=lowres)
662                endif
663                //  just get the new list and return - don't actually "pop" the menu, or the selected item will change
664                SVAR popList = root:myGlobals:NSORT:gDataPopList
665                SVAR popList_3 = root:myGlobals:NSORT:gDataPopList_3
666                popList  = ReducedDataFileList("")
667                popList_3 = "none;" +  ReducedDataFileList("")
668                return(0)
669        endif
670               
671               
672        //two or more datasets, combine them
673        //have they been manually or auto-normalized?
674        ControlInfo AutoCheck
675        Variable checked = V_Value
676       
677        //do the normalization and update the global scale factors displayed in the Panel
678        err = DoAutoScaleFromPanel(checked)                     // DoAutoScaleFromPanel writes out the datafile
679
680        //  just get the new list - don't actually "pop" the menu, or the selected item will change
681        SVAR popList = root:myGlobals:NSORT:gDataPopList
682        SVAR popList_3 = root:myGlobals:NSORT:gDataPopList_3
683        popList  = ReducedDataFileList("")
684        popList_3 = "none;" +  ReducedDataFileList("")
685       
686        return(0)
687End
688
689//window recreation macro for NSORT Panel
690//
691Window NSORT_Panel()
692        PauseUpdate; Silent 1           // building window...
693        NewPanel /W=(569,69,944,485)/K=2
694        ModifyPanel cbRGB=(49151,53155,65535)
695        ModifyPanel fixedSize=1
696        SetDrawLayer UserBack
697        SetDrawEnv fstyle= 5
698        DrawText 35,20,"NSORT - Rescale and combine 1-D files"
699        DrawLine 0,55,346,55
700        DrawLine 0,128,346,128
701        DrawLine 0,214,346,214
702        DrawLine 0,295,346,295
703        SetDrawEnv fstyle= 5
704        DrawText 5,74,"Low Q:"
705        SetDrawEnv fstyle= 5
706        DrawText 5,148,"Medium Q:"
707        SetDrawEnv fstyle= 5
708        DrawText 8,234,"High Q: (or none)"
709        SetDrawEnv fstyle= 4
710        DrawText 178,75,"Delete Points?"
711        SetDrawEnv fstyle= 4
712        DrawText 178,146,"Delete Points?"
713        SetDrawEnv fstyle= 4
714        DrawText 184,236,"Delete Points?"
715        DrawLine 0,363,346,363
716        DrawText 31,357,"To Manually scale data, enter scale factors above"
717        Button NSORT_Done,pos={274,387},size={50,20},proc=NSORT_DoneButton,title="Done"
718        Button NSORT_Done,help={"closes the panel"}
719        Button Plot_1,pos={279,63},size={50,20},proc=Plot_0_Button,title="Plot"
720        Button Plot_1,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
721        Button Plot_2,pos={283,144},size={50,20},proc=Plot_0_Button,title="Plot"
722        Button Plot_2,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
723        Button Plot_3,pos={284,223},size={50,20},proc=Plot_0_Button,title="Plot"
724        Button Plot_3,help={"Plots the dataset from the popup, showing the full set as open circles and the trimmed set as solid circles"}
725        Button PathButton,pos={6,26},size={80,20},proc=NSORTPickPathButton,title="Pick Path"
726        Button PathButton,help={"Select the local path to the folder containing your SANS data"}
727        Button helpButton,pos={340,26},size={25,20},proc=ShowNSORTHelp,title="?"
728        Button helpButton,help={"Show the help file for sorting and internormalizing 1-D data sets"}
729        SetVariable setPath,pos={95,29},size={240,14},title="Path:",fSize=10
730        SetVariable setPath,limits={0,0,0},value= root:myGlobals:NSORT:gPathStr
731        SetVariable setPath,help={"The current path to the local folder with SANS data"}
732        SetVariable end_1,pos={182,101},size={80,14},proc=SetBegOrEnd,title="End Pts"
733        SetVariable end_1,fSize=10,help={"How many points to remove from the high-q end of this dataset"}
734        SetVariable end_1,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsEnd1
735        SetVariable end_2,pos={182,176},size={80,14},proc=SetBegOrEnd,title="End Pts"
736        SetVariable end_2,fSize=10,help={"How many points to remove from the high-q end of this dataset"}
737        SetVariable end_2,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsEnd2
738        SetVariable end_3,pos={182,269},size={80,14},proc=SetBegOrEnd,title="End Pts"
739        SetVariable end_3,fSize=10,help={"How many points to remove from the high-q end of this dataset"}
740        SetVariable end_3,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsEnd3
741        SetVariable beg_1,pos={182,79},size={80,14},proc=SetBegOrEnd,title="Beg Pts"
742        SetVariable beg_1,fSize=10,help={"How many points to remove from the low-q end of this dataset"}
743        SetVariable beg_1,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsBeg1
744        SetVariable beg_2,pos={182,155},size={80,14},proc=SetBegOrEnd,title="Beg Pts"
745        SetVariable beg_2,fSize=10,help={"How many points to remove from the low-q end of this dataset"}
746        SetVariable beg_2,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsBeg2
747        SetVariable beg_3,pos={182,246},size={80,14},proc=SetBegOrEnd,title="Beg Pts"
748        SetVariable beg_3,fSize=10,help={"How many points to remove from the low-q end of this dataset"}
749        SetVariable beg_3,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gPtsBeg3
750        Button DoCombine,pos={13,387},size={160,20},proc=WriteNSORTFileButton,title="Write Combined File"
751        Button DoCombine,help={"Combine and normalize the selected files as specifed"}
752        SetVariable scale_12,pos={159,305},size={160,14},proc=SetScale_12,title="Mult factor 1-2"
753        SetVariable scale_12,fSize=10,help={"Factor that will multiply medium-q set to scale to low-q set"}
754        SetVariable scale_12,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gScale1_2
755        SetVariable scale_23,pos={159,325},size={160,14},proc=SetScale_23,title="Mult factor 2-3"
756        SetVariable scale_23,fSize=10,help={"Factor that will multiply high-q set to scale to medium-q set"}
757        SetVariable scale_23,limits={-Inf,Inf,0},value= root:myGlobals:NSORT:gScale2_3
758        CheckBox check1,pos={5,105},size={160,20},proc=CheckProc,title="Normalize to this file",value=1
759        CheckBox check1,help={"If checked, the combined dataset will be normalized to this dataset"}
760        CheckBox check2,pos={5,185},size={160,20},proc=CheckProc,title="Normalize to this file",value=0
761        CheckBox check2,help={"If checked, the combined dataset will be normalized to this dataset"}
762        CheckBox check3,pos={4,270},size={160,20},proc=CheckProc,title="Normalize to this file",value=0
763        CheckBox check3,help={"If checked, the combined dataset will be normalized to this dataset"}
764        PopupMenu popup_1,pos={6,77},size={99,19},proc=LowQPopMenuProc
765        PopupMenu popup_1,mode=1,value= #"root:myGlobals:NSORT:gDataPopList"
766        PopupMenu popup_1,help={"Choose the dataset with the lowest overall q-value (longest detector distance)"}
767        PopupMenu popup_2,pos={6,153},size={99,19},proc=MedQPopMenuProc
768        PopupMenu popup_2,mode=1,value= #"root:myGlobals:NSORT:gDataPopList_3"
769        PopupMenu popup_2,help={"Choose the dataset with the intermediate q-values (\"medium\" detector distance)"}
770        PopupMenu popup_3,pos={6,239},size={99,19},proc=HighQPopMenuProc
771        PopupMenu popup_3,mode=1,value= #"root:myGlobals:NSORT:gDataPopList_3"
772        PopupMenu popup_3,help={"Choose the dataset with the highest overall q-value (shortest detector distance), or NONE if no third set desired"}
773        CheckBox AutoCheck,pos={14,310},size={100,20},title="Auto Scale",value=0
774        CheckBox AutoCheck,help={"If checked, the scale factor will be automatically determined, if not checked, the current values in the fields will be used"}
775        CheckBox PreviewCheck,pos={15,369},size={74,14},title="Preview Only",value= 0
776        CheckBox WarningCheck,pos={111,369},size={93,14},title="Overlap warning?",value= 1
777EndMacro
778
779//sets the scale factor (multiplicative) between sets 1 and 2
780//re-sets the global variable
781//
782Function SetScale_12(ctrlName,varNum,varStr,varName) : SetVariableControl
783        String ctrlName
784        Variable varNum
785        String varStr
786        String varName
787
788        Variable/G root:myGlobals:NSORT:gScale1_2 = varNum
789       
790End
791
792//sets the scale factor (multiplicative) between sets 2 and 3
793//re-sets the global variable
794//
795Function SetScale_23(ctrlName,varNum,varStr,varName) : SetVariableControl
796        String ctrlName
797        Variable varNum
798        String varStr
799        String varName
800
801        Variable/G root:myGlobals:NSORT:gScale2_3 = varNum
802End
803
804//control procedures for the checkboxes to specify which file is to be
805//held fixed (so all other files are normalized to the checked file
806//the three checkboxes behave as "radio buttons" - only one can be checked
807//
808Function CheckProc(ctrlName,checked) : CheckBoxControl
809        String ctrlName
810        Variable checked
811       
812        //controls the three checkboxes to act as "radio buttons" to have only one file to
813        //normalize to.
814        //all three boxes should call this routine
815       
816        //do the "radio button control"
817        do
818                if(cmpstr(ctrlName,"check2") == 0)
819                        CheckBox check1 value=0
820                        CheckBox check2 value=1
821                        CheckBox check3 value=0
822                        Variable/G root:myGlobals:NSORT:gNormToNum = 2
823                        break
824                Endif
825                if(cmpstr(ctrlName,"check3") == 0)
826                        CheckBox check1 value=0
827                        CheckBox check2 value=0
828                        CheckBox check3 value=1
829                        Variable/G root:myGlobals:NSORT:gNormToNum = 3
830                        break
831                Endif
832                //default case is normalize to file1
833                CheckBox check1 value=1
834                CheckBox check2 value=0
835                CheckBox check3 value=0
836                Variable/G root:myGlobals:NSORT:gNormToNum = 1
837        While(0)
838        ControlUpdate/A/W=NSORT_Panel
839                DoUpdate
840               
841End
842
843//when menu is popped, it gets a valid list to display and updates the control
844//
845// 2002- always refreshes, as new (fast) filter is used
846Function LowQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
847        String ctrlName
848        Variable popNum
849        String popStr
850
851        String/G root:myGlobals:NSORT:gDataPopList = ReducedDataFileList("")
852        ControlUpdate popup_1
853
854        return(0)
855End
856
857//when menu is popped, it gets a valid list to display and updates the control
858//
859Function MedQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
860        String ctrlName
861        Variable popNum
862        String popStr
863               
864        String/G root:myGlobals:NSORT:gDataPopList_3 = "none;" +  ReducedDataFileList("")
865        ControlUpdate popup_2
866        if(cmpstr(popStr,"none")==0)
867                PopupMenu popup_3,mode=1        //force "none" (item #1) to be the selection
868                CheckBox AutoCheck,value=0      //un-check the auto-scale checkbox
869                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
870                RemoveFromGraph/Z MedQSet_i,TrimMedQSet_i,HighQSet_i,TrimHighQSet_i             //remove the data from the graph
871        Endif   
872        return(0)
873End
874
875//when menu is popped, it gets a valid list to display and updates the control
876// - will be different, since set 3 can also be "none" if only 2 sets
877//are to be NSORTed
878//
879Function HighQPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
880        String ctrlName
881        Variable popNum
882        String popStr
883
884        //add the option "none" to the file list (which should already end with a semicolon)
885        String/G root:myGlobals:NSORT:gDataPopList_3 = "none;" +  ReducedDataFileList("")
886
887        ControlUpdate/W=NSORT_Panel popup_3
888        if(cmpstr(popStr,"none")==0)
889                RemoveFromGraph/Z HighQSet_i,TrimHighQSet_i             //remove the data from the graph
890        Endif   
891        ControlInfo/W=NSORT_Panel popup_2
892        if(cmpstr(S_Value,"none")==0)
893                PopupMenu popup_3,win=NSORT_Panel,mode=1        //force "none" (item #1) to be the selection if medium is none
894        endif
895        return(0)       
896End
897
898
899//be sure to use the "Trim.." datasets that have had the bad points removed
900//and then do the scaling based on the choices in the panel
901//input (auto) is a switch
902//
903Function DoAutoScaleFromPanel(auto)
904        Variable auto           //if auto == 1, do the scaling, if 0, use manual scale values
905
906        NVAR normTo = root:myGlobals:NSORT:gNormToNum
907        Variable err=0,setNum,norm12,norm23
908        String fileStr="",tempName="",name1="",name2="",name3="",normToStr=""
909       
910//Set the number of output columns
911        Variable numOutputColumns = 0
912
913        NVAR Columns1 = root:myGlobals:NSORT:gColumns1
914        NVAR Columns2 = root:myGlobals:NSORT:gColumns2
915        NVAR Columns3 = root:myGlobals:NSORT:gColumns3
916        if( (Columns1 == 3) || (Columns2 == 3) || (Columns3 == 3) )
917                numOutputColumns = 3
918        else
919                if( (Columns1 == 6) && (Columns2 == 6) && ((Columns3 == 0) || (Columns3 == 6)) )
920                        numOutputColumns = 6
921                endif
922        endif
923
924        //rescale 1-2
925       
926        //load file1
927        ControlInfo $"popup_1"
928        fileStr = S_Value
929        name1 = fileStr
930        setNum = 1
931        //get a valid file based on this partialName and catPathName
932        tempName = FindValidFilename(fileStr)
933       
934        //prepend path to tempName for read routine
935        PathInfo catPathName
936        tempName = S_path + tempName
937        err = LoadDataForNSORT(tempName,setNum)
938        //////end load file1
939       
940        //load file2
941        ControlInfo $"popup_2"
942        fileStr = S_Value
943        name2 = fileStr
944        setNum = 2
945        //get a valid file based on this partialName and catPathName
946        tempName = FindValidFilename(fileStr)
947       
948        //prepend path to tempName for read routine
949        PathInfo catPathName
950        tempName = S_path + tempName
951        err = LoadDataForNSORT(tempName,setNum)
952        //////end load file2
953       
954        //load file3 , if necessary
955        ControlInfo $"popup_3"
956        fileStr = S_Value
957        name3 = fileStr
958        setNum = 3
959        if(cmpstr(fileStr,"none") == 0)
960                //do nothing
961        else
962                //get a valid file based on this partialName and catPathName
963                tempName = FindValidFilename(fileStr)
964       
965                //prepend path to tempName for read routine
966                PathInfo catPathName
967                tempName = S_path + tempName
968                err = LoadDataForNSORT(tempName,setNum)
969        Endif
970        //////end load file3
971       
972        //assign filename of file to normalize to
973        if(normTo == 1)
974                normToStr = name1
975        else
976                if(normTo == 2)
977                        normToStr = name2
978                else
979                        normToStr = name3
980                Endif
981        Endif
982
983        Variable n1,n2,n12,num2
984        Variable n3,n123
985       
986   if(numOutputColumns == 3) //Start the 3-column specific stuff here.
987                //order points in sets 1-2, indexing overlap region
988                //put result in temporary waves
989                WaveStats/Q $"root:LowQSet:TrimLowQSet_q"
990                n1 = V_npnts
991                WaveStats/Q $"root:LowQSet:TrimMedQSet_q"
992                n2 = V_npnts
993                n12 = n1+ n2
994               
995                Make/O/N=(n12) q12,i12,sig12
996                WAVE lowq = $"root:LowQSet:TrimLowQSet_q"
997                WAVE medq = $"root:MedQSet:TrimMedQSet_q"
998                WAVE lowi = $"root:LowQSet:TrimLowQSet_i"
999                WAVE medi =  $"root:MedQSet:TrimMedQSet_i"
1000                WAVE lows = $"root:LowQSet:TrimLowQSet_s"
1001                WAVE meds = $"root:MedQSet:TrimMedQSet_s"
1002                q12[0,n1-1] = lowq[p]
1003                q12[n1,n1+n2-1]= medq[p-n1]
1004                i12[0,n1-1] = lowi[p]
1005                i12[n1,n1+n2-1]= medi[p-n1]
1006                sig12[0,n1-1] = lows[p]
1007                sig12[n1,n1+n2-1]= meds[p-n1]
1008               
1009                Sort q12, q12,i12,sig12
1010                /////////////////
1011               
1012                //find the maximum point number of set 2  in the overlap region
1013                FindLevel/P/Q medq,(lowq[n1-1])
1014                num2 = trunc(V_levelX)
1015                //Print "num2 = ",num2
1016               
1017                if (auto)
1018                        //there must be overlap points to use auto-scaling
1019                        if(numtype(num2) != 0)
1020                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1021                        endif
1022                        //do auto-scaling of data
1023                        norm12 = NCNR_GetScalingInOverlap(num2,lowq,lowi,medq,medi)
1024                        //Set the global variable for the 1-2 scale factor
1025                        Variable/G root:myGlobals:NSORT:gScale1_2 = norm12
1026                else
1027                        //use the value from the panel ( which is the global)
1028                        NVAR temp12 = root:myGlobals:NSORT:gScale1_2
1029                        norm12 = temp12
1030                Endif
1031               
1032                If(normTo== 2)
1033                        //normalize to second file, so multiply 1st by 1/norm
1034                        norm12 = 1/norm12
1035                        lowi *= norm12
1036                        lows *= norm12
1037                else
1038                        //normalize to first file, OR THIRD FILE so multiply 2nd by norm
1039                        medi *= norm12
1040                        meds *= norm12
1041                Endif
1042               
1043                //Print "NSORT-ed ",name1," + ", name2
1044                //Print "normalized to ",normTo
1045                //Print "multiplicative factor = ",norm12
1046               
1047               
1048                //Make the combined, scaled dataset by overwriting the old sets
1049                Make/O/N=(n12) q12,i12,sig12
1050                q12[0,n1-1] = lowq[p]
1051                q12[n1,n1+n2-1]= medq[p-n1]
1052                i12[0,n1-1] = lowi[p]
1053                i12[n1,n1+n2-1]= medi[p-n1]
1054                sig12[0,n1-1] = lows[p]
1055                sig12[n1,n1+n2-1]= meds[p-n1]
1056               
1057                Sort q12, q12,i12,sig12
1058                //at this point 1-2 are combined
1059               
1060                ControlUpdate/A/W=NSORT_Panel
1061                DoUpdate
1062               
1063                //do we need to continue, or write out the set here and stop?
1064                if(cmpstr(name3,"none") == 0)
1065                        //stop here
1066                        norm23 = 1              //norm23 was not used
1067                        Variable/G root:myGlobals:NSORT:gScale2_3 = 1
1068                        //If any of them have three columns write three column data
1069                       
1070                        ControlInfo/W=NSORT_Panel PreviewCheck
1071                        if( V_Value==0 )                //if zero skip the preview and write out the file
1072                                err=WriteNSORTedFile(q12,i12,sig12,name1,name2,name3,normToStr,norm12,norm23)
1073                        endif
1074                        //cleanup waves before exiting
1075                        KillWaves/Z q12,i12,sig12
1076                        return err
1077                Endif
1078               
1079                //need to add the third file... which was already loaded at the top of the function
1080                /////
1081                //order points in sets 12-3, indexing overlap region
1082                //put result in temporary waves
1083                WaveStats/Q q12
1084                n12 = V_npnts
1085                WaveStats/Q $"root:HighQSet:TrimHighQSet_q"
1086                n3 = V_npnts
1087                n123 = n12+ n3
1088               
1089                Make/O/N=(n123) q123,i123,sig123
1090                WAVE highq = $"root:HighQSet:TrimHighQSet_q"
1091                WAVE highi = $"root:HighQSet:TrimHighQSet_i"
1092                WAVE highs = $"root:HighQSet:TrimHighQSet_s"
1093       
1094                q123[0,n12-1] = q12[p]
1095                q123[n1,n12+n3-1]= highq[p-n12]
1096                i123[0,n12-1] = i12[p]
1097                i123[n1,n12+n3-1]= highi[p-n12]
1098                sig123[0,n12-1] = sig12[p]
1099                sig123[n1,n12+n3-1]= highs[p-n12]
1100               
1101                Sort q123, q123,i123,sig123
1102                /////////////////
1103               
1104                //find the maximum point number of set 2  in the overlap region
1105                FindLevel/P/Q highq,(q12[n12-1])
1106                num2 = trunc(V_levelX)
1107                //Print "num2 = ",num2
1108               
1109                if (auto)
1110                        //there must be overlap points to use auto-scaling
1111                        if(numtype(num2) != 0)
1112                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1113                        endif
1114                        //do auto-scaling of data
1115                        norm23 = NCNR_GetScalingInOverlap(num2,q12,i12,highq,highi)
1116                        //Set the global variable for the 12 - 3 scale factor
1117                        Variable/G root:myGlobals:NSORT:gScale2_3 = norm23
1118                else
1119                        //use the value from the panel ( which is the global)
1120                        NVAR temp23 = root:myGlobals:NSORT:gScale2_3
1121                        norm23 = temp23
1122                Endif
1123               
1124                If( (normTo== 1) || (normTo ==2) )
1125                        //normalize to first or second file, so multiply third by norm23
1126                        highi *= norm23
1127                        highs *= norm23
1128                else
1129                        //normalize to THIRD file, 1-2 by 1/norm23
1130                        norm23 = 1/norm23
1131                        i12 *= norm23
1132                        sig12 *= norm23
1133                        // for the display, scale the trimmed sets 1 and 2
1134                        lowi *= norm23
1135                        lows *= norm23
1136                        medi *= norm23
1137                        meds *= norm23
1138                Endif
1139               
1140                ControlUpdate/A/W=NSORT_Panel
1141                DoUpdate
1142
1143                //Print "NSORT-ed ",name1," + ", name2, " + ", name3
1144                //Print "normalized to ",normTo
1145                //Print "multiplicative factor 1-2 = ",norm12," multiplicative factor 12 - 3 = ",norm23
1146               
1147               
1148                Make/O/N=(n123) q123,i123,sig123
1149                q123[0,n12-1] = q12[p]
1150                q123[n12,n12+n3-1]= highq[p-n12]
1151                i123[0,n12-1] = i12[p]
1152                i123[n12,n12+n3-1]= highi[p-n12]
1153                sig123[0,n12-1] = sig12[p]
1154                sig123[n12,n12+n3-1]= highs[p-n12]
1155               
1156                Sort q123, q123,i123,sig123
1157                //at this point 12 - 3 are combined
1158                //write out the set here and stop
1159       
1160                ControlInfo/W=NSORT_Panel PreviewCheck
1161                if( V_Value==0 )                //if zero skip the preview and write out the file
1162                        err=WriteNSORTedFile(q123,i123,sig123,name1,name2,name3,normToStr,norm12,norm23)
1163                endif
1164                //cleanup waves before exiting
1165                KillWaves/Z q12,i12,sig12,q123,i123,sig123
1166                //combined dataset will already be displayed if the NSORT_Graph is open
1167       
1168                ////////////////
1169                return err
1170   endif // End the 3-column specific stuff here
1171
1172   if(numOutputColumns == 6) // Start the 6-column specific stuff here
1173                //order points in sets 1-2, indexing overlap region
1174                //put result in temporary waves
1175                WaveStats/Q $"root:LowQSet:TrimLowQSet_q"
1176                n1 = V_npnts
1177                WaveStats/Q $"root:MedQSet:TrimMedQSet_q"
1178                n2 = V_npnts
1179                n12 = n1+ n2
1180               
1181                Make/O/N=(n12) q12,i12,sig12,sq12,qb12,fs12
1182                Make/O/N=(n12,3) res12
1183                WAVE lowq = $"root:LowQSet:TrimLowQSet_q"
1184                WAVE medq = $"root:MedQSet:TrimMedQSet_q"
1185                WAVE lowi = $"root:LowQSet:TrimLowQSet_i"
1186                WAVE medi =  $"root:MedQSet:TrimMedQSet_i"
1187                WAVE lows = $"root:LowQSet:TrimLowQSet_s"
1188                WAVE meds = $"root:MedQSet:TrimMedQSet_s"
1189//              WAVE lowsq = $"root:LowQSet:TrimLowQSet_sq"
1190//              WAVE medsq = $"root:MedQSet:TrimMedQSet_sq"
1191//              WAVE lowqb = $"root:LowQSet:TrimLowQSet_qb"
1192//              WAVE medqb =  $"root:MedQSet:TrimMedQSet_qb"
1193//              WAVE lowfs = $"root:LowQSet:TrimLowQSet_fs"
1194//              WAVE medfs = $"root:MedQSet:TrimMedQSet_fs"
1195                WAVE lowres = $"root:LowQSet:TrimLowQSet_res"
1196                WAVE medres = $"root:MedQSet:TrimMedQSet_res"
1197               
1198                q12[0,n1-1] = lowq[p]
1199                q12[n1,n1+n2-1]= medq[p-n1]
1200                i12[0,n1-1] = lowi[p]
1201                i12[n1,n1+n2-1]= medi[p-n1]
1202                sig12[0,n1-1] = lows[p]
1203                sig12[n1,n1+n2-1]= meds[p-n1]
1204                sq12[0,n1-1] = lowres[p][0]
1205                sq12[n1,n1+n2-1]= medres[p-n1][0]
1206                qb12[0,n1-1] = lowres[p][1]
1207                qb12[n1,n1+n2-1]= medres[p-n1][1]
1208                fs12[0,n1-1] = lowres[p][2]
1209                fs12[n1,n1+n2-1]= medres[p-n1][2]
1210//              res12[0,n1-1][0]=lowres[p][0]
1211//              res12[n1,n1+n2-1][0]=medres[p-n1][0]
1212//              res12[0,n1-1][1]=lowres[p][1]
1213//              res12[n1,n1+n2-1][1]=medres[p-n1][1]
1214//              res12[0,n1-1][2]=lowres[p][2]
1215//              res12[n1,n1+n2-1][2]=medres[p-n1][2]
1216
1217               
1218                Sort q12, q12,i12,sig12,sq12,qb12,fs12
1219                /////////////////
1220               
1221                //find the maximum point number of set 2  in the overlap region
1222                FindLevel/P/Q medq,(lowq[n1-1])
1223                num2 = trunc(V_levelX)
1224                //Print "num2 = ",num2
1225               
1226                if (auto)
1227                        //there must be overlap points to use auto-scaling
1228                        if(numtype(num2) != 0)
1229                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1230                        endif
1231                        //do auto-scaling of data
1232                        norm12 = NCNR_GetScalingInOverlap(num2,lowq,lowi,medq,medi)
1233                        //Set the global variable for the 1-2 scale factor
1234                        Variable/G root:myGlobals:NSORT:gScale1_2 = norm12
1235                else
1236                        //use the value from the panel ( which is the global)
1237                        NVAR temp12 = root:myGlobals:NSORT:gScale1_2
1238                        norm12 = temp12
1239                Endif
1240               
1241                If(normTo== 2)
1242                        //normalize to second file, so multiply 1st by 1/norm
1243                        norm12 = 1/norm12
1244                        lowi *= norm12
1245                        lows *= norm12
1246                else
1247                        //normalize to first file, OR THIRD FILE so multiply 2nd by norm
1248                        medi *= norm12
1249                        meds *= norm12
1250                Endif
1251               
1252                //Print "NSORT-ed ",name1," + ", name2
1253                //Print "normalized to ",normTo
1254                //Print "multiplicative factor = ",norm12
1255                ControlUpdate/A/W=NSORT_Panel
1256                DoUpdate
1257
1258               
1259                //Make the combined, scaled dataset by overwriting the old sets
1260                Make/O/N=(n12) q12,i12,sig12,sq12,qb12,fs12
1261                Make/O/N=(n12,3) res12
1262                q12[0,n1-1] = lowq[p]
1263                q12[n1,n1+n2-1]= medq[p-n1]
1264                i12[0,n1-1] = lowi[p]
1265                i12[n1,n1+n2-1]= medi[p-n1]
1266                sig12[0,n1-1] = lows[p]
1267                sig12[n1,n1+n2-1]= meds[p-n1]
1268                sq12[0,n1-1] = lowres[p][0]
1269                sq12[n1,n1+n2-1]= medres[p-n1][0]
1270                qb12[0,n1-1] = lowres[p][1]
1271                qb12[n1,n1+n2-1]= medres[p-n1][1]
1272                fs12[0,n1-1] = lowres[p][2]
1273                fs12[n1,n1+n2-1]= medres[p-n1][2]
1274//              res12[0,n1-1][0]=lowres[p][0]
1275//              res12[n1,n1+n2-1][0]=medres[p-n1][0]
1276//              res12[0,n1-1][1]=lowres[p][1]
1277//              res12[n1,n1+n2-1][1]=medres[p-n1][1]
1278//              res12[0,n1-1][2]=lowres[p][2]
1279//              res12[n1,n1+n2-1][2]=medres[p-n1][2]
1280
1281               
1282                Sort q12, q12,i12,sig12,sq12,qb12,fs12
1283                //at this point 1-2 are combined
1284                //do we need to continue, or write out the set here and stop?
1285                if(cmpstr(name3,"none") == 0)
1286                        //stop here
1287                        norm23 = 1              //norm23 was not used
1288                        Variable/G root:myGlobals:NSORT:gScale2_3 = 1
1289                       
1290                        ControlInfo/W=NSORT_Panel PreviewCheck
1291                        if( V_Value==0 )                //if zero skip the preview and write out the file
1292                                res12[][0] = sq12[p]
1293                                res12[][1] = qb12[p]
1294                                res12[][2] = fs12[p]
1295                                err=WriteNSORTedFile(q12,i12,sig12,name1,name2,name3,normToStr,norm12,norm23,res=res12)
1296                        endif
1297                        // always clean up waves before exiting
1298                        KillWaves/Z q12,i12,sig12,sq12,qb12,fs12
1299                        return err
1300                Endif
1301               
1302                //need to add the third file... which was already loaded at the top of the function
1303                /////
1304                //order points in sets 12-3, indexing overlap region
1305                //put result in temporary waves
1306                WaveStats/Q q12
1307                n12 = V_npnts
1308                WaveStats/Q $"root:HighQSet:TrimHighQSet_q"
1309                n3 = V_npnts
1310                n123 = n12+ n3
1311               
1312                Make/O/N=(n123) q123,i123,sig123,sq123,qb123,fs123
1313                Make/O/N=(n123,3) res123
1314                WAVE highq = $"root:HighQSet:TrimHighQSet_q"
1315                WAVE highi = $"root:HighQSet:TrimHighQSet_i"
1316                WAVE highs = $"root:HighQSet:TrimHighQSet_s"
1317//              WAVE highsq = $"root:HighQSet:TrimHighQSet_sq"
1318//              WAVE highqb = $"root:HighQSet:TrimHighQSet_qb"
1319//              WAVE highfs = $"root:HighQSet:TrimHighQSet_fs"
1320                WAVE highres = $"root:HighQSet:TrimHighQSet_res"
1321       
1322       
1323                q123[0,n12-1] = q12[p]
1324                q123[n1,n12+n3-1]= highq[p-n12]
1325                i123[0,n12-1] = i12[p]
1326                i123[n1,n12+n3-1]= highi[p-n12]
1327                sig123[0,n12-1] = sig12[p]
1328                sig123[n1,n12+n3-1]= highs[p-n12]
1329                sq123[0,n12-1] = sq12[p]
1330                sq123[n1,n12+n3-1]= highres[p-n12][0]
1331                qb123[0,n12-1] = qb12[p]
1332                qb123[n1,n12+n3-1]= highres[p-n12][1]
1333                fs123[0,n12-1] = fs12[p]
1334                fs123[n1,n12+n3-1]= highres[p-n12][2]
1335//              res123[0,n12-1][0] = highres[p][0]
1336//              res123[n1,n12+n3-1][0] = highres[p-n12][0]
1337//              res123[0,n12-1][1] = highres[p][1]
1338//              res123[n1,n12+n3-1][1] = highres[p-n12][1]
1339//              res123[0,n12-1][2] = highres[p][2]
1340//              res123[n1,n12+n3-1][2] = highres[p-n12][2]
1341
1342               
1343                Sort q123, q123,i123,sig123,sq123,qb123,fs123
1344                /////////////////
1345               
1346                //find the maximum point number of set 2  in the overlap region
1347                FindLevel/P/Q highq,(q12[n12-1])
1348                num2 = trunc(V_levelX)
1349                //Print "num2 = ",num2
1350               
1351                if (auto)
1352                        //there must be overlap points to use auto-scaling
1353                        if(numtype(num2) != 0)
1354                                Abort "There are no data points in the overlap region. Either reduce the number of deleted points or use manual scaling."
1355                        endif
1356                        //do auto-scaling of data
1357                        norm23 = NCNR_GetScalingInOverlap(num2,q12,i12,highq,highi)
1358                        //Set the global variable for the 12 - 3 scale factor
1359                        Variable/G root:myGlobals:NSORT:gScale2_3 = norm23
1360                else
1361                        //use the value from the panel ( which is the global)
1362                        NVAR temp23 = root:myGlobals:NSORT:gScale2_3
1363                        norm23 = temp23
1364                Endif
1365               
1366                If( (normTo== 1) || (normTo ==2) )
1367                        //normalize to first or second file, so multiply third by norm23
1368                        highi *= norm23
1369                        highs *= norm23
1370                else
1371                        //normalize to THIRD file, 1-2 by 1/norm23
1372                        norm23 = 1/norm23
1373                        i12 *= norm23
1374                        sig12 *= norm23
1375                        // for the display, scale the trimmed sets 1 and 2
1376                        lowi *= norm23
1377                        lows *= norm23
1378                        medi *= norm23
1379                        meds *= norm23
1380                Endif
1381               
1382                //Print "NSORT-ed ",name1," + ", name2, " + ", name3
1383                //Print "normalized to ",normTo
1384                //Print "multiplicative factor 1-2 = ",norm12," multiplicative factor 12 - 3 = ",norm23
1385                ControlUpdate/A/W=NSORT_Panel
1386                DoUpdate
1387               
1388                Make/O/N=(n123) q123,i123,sig123
1389                Make/O/N=(n123,3) res123
1390                q123[0,n12-1] = q12[p]
1391                q123[n12,n12+n3-1]= highq[p-n12]
1392                i123[0,n12-1] = i12[p]
1393                i123[n12,n12+n3-1]= highi[p-n12]
1394                sig123[0,n12-1] = sig12[p]
1395                sig123[n12,n12+n3-1]= highs[p-n12]
1396                sq123[0,n12-1] = sq12[p]
1397                sq123[n12,n12+n3-1]= highres[p-n12][0]
1398                qb123[0,n12-1] = qb12[p]
1399                qb123[n12,n12+n3-1]= highres[p-n12][1]
1400                fs123[0,n12-1] = fs12[p]
1401                fs123[n12,n12+n3-1]= highres[p-n12][2]
1402//              res123[0,n12-1][0] = highres[p][0]
1403//              res123[n1,n12+n3-1][0] = highres[p-n12][0]
1404//              res123[0,n12-1][1] = highres[p][1]
1405//              res123[n1,n12+n3-1][1] = highres[p-n12][1]
1406//              res123[0,n12-1][2] = highres[p][2]
1407//              res123[n1,n12+n3-1][2] = highres[p-n12][2]
1408               
1409                Sort q123, q123,i123,sig123,sq123,qb123,fs123
1410                //at this point 12 - 3 are combined
1411                //write out the set here and stop
1412       
1413                ControlInfo/W=NSORT_Panel PreviewCheck
1414                if( V_Value==0 )                //if zero skip the preview and write out the file
1415                        res123[][0] = sq123[p]
1416                        res123[][1] = qb123[p]
1417                        res123[][2] = fs123[p]
1418                        err=WriteNSORTedFile(q123,i123,sig123,name1,name2,name3,normToStr,norm12,norm23,res=res123)
1419                endif
1420                //cleanup waves before exiting
1421                KillWaves/Z q12,i12,sig12,q123,i123,sig123,sq123,qb123,fs123 //,res123
1422                //combined dataset will already be displayed if the NSORT_Graph is open
1423       
1424                ////////////////
1425                return err
1426   endif // End the 6-column specific stuff here
1427       
1428End
1429
1430
1431
1432/////////////////////////////////////////////////////////////
1433// testing, may speed up NSORT, NCNR-specific naming scheme of
1434// run numbers and a run prefix
1435//
1436// it is assumed that you are combining data from the current reduction session,
1437// so that the XML y/n hasn't changed.
1438//
1439Function Set3NSORTFiles(low,med,hi,pref)
1440        Variable low,med,hi
1441        String pref
1442       
1443        //make strings from the numbers
1444        String absStr="",ext
1445        Variable popNum
1446        DoWindow/F NSORT_Panel
1447       
1448        SVAR lowQPopStr = root:myGlobals:NSORT:gDataPopList
1449        SVAR medHiQPopStr = root:myGlobals:NSORT:gDataPopList_3
1450       
1451        NVAR useXMLOutput = root:Packages:NIST:gXML_Write
1452        if(useXMLOutput)
1453                ext = ".ABSx"
1454        else
1455                ext = ".ABS"
1456        endif
1457       
1458        //lowQ menu
1459        absStr = pref+RunDigitString(low)+ext
1460        popNum = WhichListItem(absStr,lowQPopStr,";",0)
1461        if(popNum == -1)
1462                Abort "Could not find file: " + absStr +" aborting...  Be sure that your output format is the same as the input"
1463        endif
1464        popNum += 1             // add 1 to get the item number
1465        PopupMenu popup_1,win=NSORT_Panel,mode=(popNum)
1466       
1467        //medQ (a different list for the popup)
1468        absStr = pref+RunDigitString(med)+ext
1469        popNum = WhichListItem(absStr,medHiQPopStr,";",0)
1470        if(popNum == -1)
1471                Abort "Could not find file: "+absStr+" aborting...  Be sure that your output format is the same as the input"
1472        endif
1473        popNum += 1             // add 1 to get the item number
1474        PopupMenu popup_2,win=NSORT_Panel,mode=(popNum)
1475       
1476       
1477        //highQ (same pop list as medQ)
1478        if(hi != 0)
1479                absStr = pref+RunDigitString(hi)+ext
1480                popNum = WhichListItem(absStr,medHiQPopStr,";",0)
1481                if(popNum == -1)
1482                        Abort "Could not find file: "+absStr+" aborting...  Be sure that your output format is the same as the input"
1483                endif
1484                popNum += 1             // add 1 to get the item number
1485                PopupMenu popup_3,win=NSORT_Panel,mode=(popNum)
1486        else
1487                PopupMenu popup_3,win=NSORT_Panel,mode=(1)
1488        endif
1489End
1490
1491//more beta procedures - to create a table of scattering runs to combine with NSORT
1492Proc CreateTableToCombine(ctrlName)
1493        String ctrlName
1494       
1495        NewDataFolder/O root:myGlobals:CombineTable
1496//      DoWindow/F CombineTable
1497       
1498        Make/O/T/N=0 $"root:myGlobals:CombineTable:Filenames"
1499        Make/O/T/N=0 $"root:myGlobals:CombineTable:Suffix"
1500        Make/O/T/N=0 $"root:myGlobals:CombineTable:Labels"
1501        Make/O/D/N=0 $"root:myGlobals:CombineTable:SDD"
1502        Make/O/D/N=0 $"root:myGlobals:CombineTable:RunNumber"
1503        Make/O/D/N=0 $"root:myGlobals:CombineTable:IsTrans"
1504
1505
1506        AppendToTable/W=CombinePanel#GroupedFiles root:myGlobals:CombineTable:Labels, root:myGlobals:CombineTable:SDD, root:myGlobals:CombineTable:RunNumber
1507
1508        ModifyTable/W=CombinePanel#GroupedFiles width(:myGlobals:CombineTable:SDD)=40
1509        ModifyTable/W=CombinePanel#GroupedFiles width(:myGlobals:CombineTable:Labels)=180
1510        ModifyTable/W=CombinePanel#GroupedFiles width(Point)=0          //JUN04, remove point numbers - confuses users since point != run
1511
1512
1513        //get a list of all files in the folder, some will be junk version numbers that don't exist     
1514        String list,partialName,tempName,temp=""
1515        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
1516        Variable numitems,ii,ok
1517       
1518        //remove version numbers from semicolon-delimited list
1519        list =  RemoveVersNumsFromList(list)
1520        numitems = ItemsInList(list,";")
1521       
1522        //loop through all of the files in the list, reading CAT/SHORT information if the file is RAW SANS
1523        //***version numbers have been removed***
1524        String str,fullName
1525        Variable lastPoint
1526        ii=0
1527       
1528        Make/T/O/N=0 notRAWlist
1529        do
1530                //get current item in the list
1531                partialName = StringFromList(ii, list, ";")
1532                //get a valid file based on this partialName and catPathName
1533                tempName = FindValidFilename(partialName)
1534                If(cmpstr(tempName,"")==0)              //a null string was returned
1535                        //write to notebook that file was not found
1536                        //if string is not a number, report the error
1537                        //if(str2num(partialName) == NaN) // will always be false [davidm]
1538                        if(numtype(str2num(partialName)) == 2)
1539                                str = "this file was not found: "+partialName+"\r\r"
1540                                //Notebook CatWin,font="Times",fsize=12,text=str
1541                        Endif
1542                else
1543                        //prepend path to tempName for read routine
1544                        PathInfo catPathName
1545                        FullName = S_path + tempName
1546                        //make sure the file is really a RAW data file
1547                        ok = CheckIfRawData(fullName)
1548                        if (!ok)
1549                                //write to notebook that file was not a RAW SANS file
1550                                lastPoint = numpnts(notRAWlist)
1551                                InsertPoints lastPoint,1,notRAWlist
1552                                notRAWlist[lastPoint]=tempname
1553                        else
1554                                //go write the header information to the Notebook
1555                                GetHeaderInfoToCombineWave(fullName,tempName)
1556                        Endif
1557                Endif
1558                ii+=1
1559        while(ii<numitems)
1560//Now sort them all based on the suffix data (orders them as collected)
1561//      SortCombineWaves()
1562// sort by label
1563        SortCombineByLabel()
1564// remove the transmission waves
1565//
1566        RemoveTransFilesFromCombine()
1567//
1568        SetDataFolder root:
1569       
1570        Killwaves/Z notRAWlist
1571End
1572
1573
1574Function RemoveTransFilesFromCombine()
1575        Wave/T filenames = $"root:myGlobals:CombineTable:Filenames"
1576        Wave/T suffix = $"root:myGlobals:CombineTable:Suffix"
1577        Wave/T labels = $"root:myGlobals:CombineTable:Labels"
1578        Wave sdd = $"root:myGlobals:CombineTable:SDD"
1579        Wave runnum = $"root:myGlobals:CombineTable:RunNumber"
1580        Wave isTrans = $"root:myGlobals:CombineTable:IsTrans"
1581       
1582        Variable num=numpnts(isTrans),ii
1583        ii=num-1
1584        do
1585                if(isTrans[ii] != 0)
1586                        DeletePoints ii, 1, filenames,suffix,labels,sdd,runnum,isTrans
1587                endif
1588                ii-=1
1589        while(ii>=0)
1590        return(0)
1591End
1592
1593//reads header information and puts it in the appropriate waves for display in the table.
1594//fname is the full path for opening (and reading) information from the file
1595//which alreay was found to exist. sname is the file;vers to be written out,
1596//avoiding the need to re-extract it from fname.
1597Function GetHeaderInfoToCombineWave(fname,sname)
1598        String fname,sname
1599       
1600        String textstr,temp,lbl,date_time,suffix
1601        Variable ctime,lambda,sdd,detcnt,cntrate,refNum,trans,thick,xcenter,ycenter,numatten
1602        Variable lastPoint, beamstop
1603
1604        Wave/T GFilenames = $"root:myGlobals:CombineTable:Filenames"
1605        Wave/T GSuffix = $"root:myGlobals:CombineTable:Suffix"
1606        Wave/T GLabels = $"root:myGlobals:CombineTable:Labels"
1607        Wave GSDD = $"root:myGlobals:CombineTable:SDD"
1608        Wave GRunNumber = $"root:myGlobals:CombineTable:RunNumber"
1609        Wave GIsTrans = $"root:myGlobals:CombineTable:IsTrans"
1610       
1611        lastPoint = numpnts(GLambda)
1612               
1613        InsertPoints lastPoint,1,GFilenames
1614        GFilenames[lastPoint]=sname
1615       
1616        //read the file suffix
1617        InsertPoints lastPoint,1,GSuffix
1618        GSuffix[lastPoint]=getSuffix(fname)
1619
1620        // read the sample.label text field
1621        InsertPoints lastPoint,1,GLabels
1622        GLabels[lastPoint]=getSampleLabel(fname)
1623       
1624        //read in the SDD
1625        InsertPoints lastPoint,1,GSDD
1626        GSDD[lastPoint]= getSDD(fname)
1627
1628        //the run number (not displayed in the table, but carried along)
1629        InsertPoints lastPoint,1,GRunNumber
1630        GRunNumber[lastPoint] = GetRunNumFromFile(sname)
1631
1632        // 0 if the file is a scattering  file, 1 (truth) if the file is a transmission file
1633        InsertPoints lastPoint,1,GIsTrans
1634        GIsTrans[lastPoint]  = isTransFile(fname)               //returns one if beamstop is "out"
1635       
1636        KillWaves/Z w
1637        return(0)
1638End
1639
1640//sorts all of the waves of header information using the suffix (A123)
1641//the result is that all of the data is in the order that it was collected,
1642// regardless of how the prefix or run numbers were changed by the user
1643Function SortCombineWaves()
1644        Wave/T GFilenames = $"root:myGlobals:CombineTable:Filenames"
1645        Wave/T GSuffix = $"root:myGlobals:CombineTable:Suffix"
1646        Wave/T GLabels = $"root:myGlobals:CombineTable:Labels"
1647        Wave GSDD = $"root:myGlobals:CombineTable:SDD"
1648        Wave GRunNumber = $"root:myGlobals:CombineTable:RunNumber"
1649        Wave GIsTrans = $"root:myGlobals:CombineTable:IsTrans"
1650
1651//      Sort GSuffix, GSuffix, GFilenames, GLabels, GDateTime, GSDD, GLambda, GCntTime, GTotCnts, GCntRate, GTransmission, GThickness, GXCenter, GYCenter, GNumAttens,GRunNumber,GIsTrans
1652        Sort GSuffix, GSuffix, GFilenames, GLabels, GSDD, GRunNumber, GIsTrans
1653        return(0)
1654End
1655
1656//sorts all of the waves of header information using the suffix (A123)
1657//the result is that all of the data is in the order that it was collected,
1658// regardless of how the prefix or run numbers were changed by the user
1659Function SortCombineByLabel()
1660        Wave/T GFilenames = $"root:myGlobals:CombineTable:Filenames"
1661        Wave/T GSuffix = $"root:myGlobals:CombineTable:Suffix"
1662        Wave/T GLabels = $"root:myGlobals:CombineTable:Labels"
1663        Wave GSDD = $"root:myGlobals:CombineTable:SDD"
1664        Wave GRunNumber = $"root:myGlobals:CombineTable:RunNumber"
1665        Wave GIsTrans = $"root:myGlobals:CombineTable:IsTrans"
1666
1667        Sort GLabels, GSuffix, GFilenames, GLabels, GSDD, GRunNumber, GIsTrans
1668//      Sort {GLabels, GSDD}, GSuffix, GFilenames, GLabels, GSDD, GRunNumber, GIsTrans          //sort on GLabels, GSDD breaks the tie
1669        return(0)
1670End
1671
1672//main procedure, called from the menu
1673// sets a flag (temporarily) to use the names from the table
1674// during the procedure that writes the data files.
1675//
1676//
1677Function DoCombineFiles(ctrlName)
1678        String ctrlName
1679       
1680       
1681        if(WinType("NSORT_Panel") == 0)
1682                DoAlert 0, "The SORT Panel must be open to combine the files"
1683                return(0)
1684        endif
1685       
1686        DoAlert 1,"Do you have all the assignments set in the bottom table? If not, < No > will exit."
1687        if(V_flag == 2)
1688                return(0)               //no, get out
1689        endif
1690        // pop all of the menus to make sure that they are properly populated
1691        LowQPopMenuProc("",1,"")
1692        MedQPopMenuProc("",1,"")
1693        HighQPopMenuProc("",1,"")
1694       
1695//      String savedDataFolder = GetDataFolder(1)               // save
1696        Wave LowRun = root:myGlobals:CombineTable:LowRun
1697        Wave MediumRun = root:myGlobals:CombineTable:MediumRun
1698        Wave HighRun = root:myGlobals:CombineTable:HighRun
1699        Wave/T prefix = root:myGlobals:CombineTable:Prefix
1700        Wave/T saveName = root:myGlobals:CombineTable:saveName
1701
1702        Variable/G root:myGlobals:CombineTable:useTable=1
1703       
1704        Variable num=numpnts(lowRun),ii,lowFile,medFile,hiFile
1705        String prefixStr = ""
1706        Pathinfo catPathName
1707        String path=S_Path
1708       
1709        ii=0
1710        do
1711                lowFile = LowRun[ii]
1712                medFile = MediumRun[ii]
1713                hiFile = highRun[ii]
1714                prefixStr = prefix[ii]
1715               
1716                Set3NSORTFiles(lowFile,medFile,hiFile,prefixStr)                //set the files and pop the NSORT popups
1717               
1718                //pass the new file name in as a global (ugh!)
1719                String/G root:myGlobals:CombineTable:SaveNameStr = path+saveName[ii]
1720                //combine the files and write the data
1721                WriteNSORTFileButton("")
1722               
1723                Print "wrote file : ",path+saveName[ii]
1724                ii+=1
1725        while(ii<num)
1726
1727        Variable/G root:myGlobals:CombineTable:useTable=0               //turn this off immediately
1728       
1729        return(0)
1730End
1731
1732
1733// only respond to clicks in the subwindow (table) rather than everywhere. Hooks can't be set for subwindows
1734//
1735//// Window hook example:
1736//  WINDOW:CombinePanel;HCSPEC:CombinePanel#GroupedFiles;EVENT:mouseup;MOUSEX:152;MOUSEY:143;TICKS:7722029;MODIFIERS:0;
1737//
1738Function CombineTableHook(infoStr)
1739        String infoStr
1740        String event= StringByKey("EVENT",infoStr)
1741        String subwin = StringByKey("HCSPEC",infoStr)
1742//      Print subwin
1743//      Print infoStr
1744//      Print "EVENT= ",event
1745        if(cmpstr(subwin,"CombinePanel#GroupedFiles")==0)
1746                strswitch(event)
1747                        case "mousedown":
1748                                Variable xpix= NumberByKey("MOUSEX",infoStr)
1749                                Variable ypix= NumberByKey("MOUSEY",infoStr)
1750                                Variable modif= NumberByKey("MODIFIERS",infoStr)
1751                                //print modif
1752                                if(modif & 2^1)         //bit 1 set, shift key is down
1753                                        PopupContextualMenu/C=(xpix, ypix) "combine;"
1754                                        strswitch(S_selection)
1755                                                case "combine":
1756                                                        //Print "combine the files"
1757                                                        SendSelectionToTable()
1758                                                        break
1759                                        endswitch               //on selection
1760                                endif
1761                endswitch       // on event
1762        endif
1763        return 0
1764End
1765
1766//ASSUMES 3 FILES!!!!
1767Function SendSelectionToTable()
1768
1769        DoWindow/F CombinePanel
1770        if(V_flag==0)
1771//              Make/O/N=0 $"root:myGlobals:CombineTable:Low"
1772//              Make/O/N=0 $"root:myGlobals:CombineTable:Medium"
1773//              Make/O/N=0 $"root:myGlobals:CombineTable:High"
1774//              Make/O/T/N=0 $"root:myGlobals:CombineTable:Prefix"
1775//              Make/O/T/N=0 $"root:myGlobals:CombineTable:SaveName"
1776//              edit Low,Medium,High,Prefix,SaveName as "Run Numbers to Combine"
1777//              DoWindow/C ToCombine
1778
1779                return(0)
1780               
1781        else
1782                Wave low = $"root:myGlobals:CombineTable:LowRun"
1783                Wave medium = $"root:myGlobals:CombineTable:MediumRun"
1784                Wave high = $"root:myGlobals:CombineTable:HighRun"
1785                Wave/T prefix = $"root:myGlobals:CombineTable:Prefix"
1786                Wave/T saveName = $"root:myGlobals:CombineTable:SaveName"
1787               
1788                Wave/T gLabels = $"root:myGlobals:CombineTable:Labels"
1789                Wave gSDD = $"root:myGlobals:CombineTable:SDD"
1790                Wave gRunNumber = $"root:myGlobals:CombineTable:RunNumber"
1791                Wave/T filenames = $"root:myGlobals:CombineTable:FileNames"
1792        endif
1793       
1794        GetSelection table,CombinePanel#GroupedFiles,3
1795//      Print V_startRow, V_endRow
1796       
1797        //prompt for combined name, give the user a chance to cancel
1798        Variable num=V_endRow-V_startRow+1
1799        Variable ii
1800        String saveStr=""
1801        Prompt saveStr,"saved file name for "+ gLabels[V_StartRow]      //+tmpLbl[1]
1802        DoPrompt "Enter the combined file name",saveStr
1803        if(V_flag==1)
1804                return(1)               //user cancel, get out before anything is set
1805        endif
1806
1807
1808        if( !(num==2 || num==3) )
1809                Abort "invalid table selection - must select either 2 or 3 files to combine"
1810        endif
1811        Make/O/T/N=(3) tmpLbl
1812        Make/O/N=(3) tmpSDD,tmpRun
1813        for(ii=V_startRow;ii<=V_endRow;ii+=1)
1814                tmpLbl[ii-V_startRow] = gLabels[ii]
1815                tmpSDD[ii-V_startRow] = gSDD[ii]
1816                tmpRun[ii-V_startRow] = gRunNumber[ii]
1817        endfor
1818        if(num==2)      // then "highest" q run needs to be forced to zero
1819                ii=2
1820                tmpLbl[ii] = ""
1821                tmpSDD[ii] = 0.01               //fake sdd in meters to always be the "highest" Q
1822                tmpRun[ii] = 0                  //pass a run number of zero to be later interpreted as "none"
1823        endif
1824        Sort tmpSDD, tmpSDD,tmpLbl,tmpRun
1825       
1826//      Print tmpSDD
1827       
1828        num=numpnts(low)
1829        InsertPoints num, 1, low,medium,high,prefix,SaveName
1830        low[num] = tmpRun[2]
1831        medium[num] = tmpRun[1]
1832        high[num] = tmpRun[0]
1833        prefix[num] = GetPrefixStrFromFile(filenames[ii])
1834        saveName[num] = saveStr
1835
1836        KillWaves/Z tmpLbl,tmpRun,tmpSDD
1837        return(0)
1838end
1839
1840
1841////////////////////////
1842// replaces the beta menu items
1843//
1844
1845Proc ShowCombinePanel()
1846        DoWindow/F CombinePanel
1847        if(V_flag==0)
1848                CombinePanel()
1849                CreateTableToCombine("")
1850                DoAlert 1,"Do you want to clear the list of runs and file names to combine?"
1851                TableToCombineAndSave(V_flag==1)                // clear and initialize, if desired
1852        endif
1853end
1854
1855Proc CombinePanel()
1856        PauseUpdate; Silent 1           // building window...
1857        NewPanel /W=(546,442,1197,915) /K=1 as "Sort and Combine Data Files"
1858        ModifyPanel cbRGB=(49151,53155,65535)
1859        DoWindow/C CombinePanel
1860        Button button0_0,pos={20,20},size={160,20},proc=CreateTableToCombine,title="List Files to Combine"
1861        Button button0_1,pos={206,20},size={140,20},proc=DoCombineFiles,title="Combine Files"
1862        Button button0_2,pos={509,40},size={60,20},proc=CombinePanelDone,title="Done"
1863        Button button0_3,pos={522,14},size={30,20},proc=ShowCombineHelp,title="?"
1864        Button button0_4,pos={500,220},size={120,20},proc=ClearCombineTable,title="Clear Table?"
1865        Edit/W=(20,54,368,249)/HOST=#
1866        ModifyTable format=1,width=0
1867        RenameWindow #,GroupedFiles
1868        SetActiveSubwindow ##
1869        Edit/W=(20,263,634,455)/HOST=#
1870        ModifyTable format=1
1871        RenameWindow #,RunNumbersToCombine
1872        SetActiveSubwindow ##
1873        SetWindow kwTopWin hook=CombineTableHook, hookevents=1  // mouse down events
1874EndMacro
1875
1876Proc ShowCombineHelp(ctrlName): ButtonControl
1877        String ctrlName
1878        DisplayHelpTopic/K=1/Z "SANS Data Reduction Tutorial[Batch Combine Data Files]"
1879        if(V_flag !=0)
1880                DoAlert 0,"The SANS Data Reduction Tutorial Help file could not be found"
1881        endif
1882end
1883
1884Function CombinePanelDone(ctrlName)
1885        String ctrlName
1886       
1887        DoWindow/K CombinePanel
1888        return(0)
1889end
1890
1891Function ClearCombineTable(ctrlName)
1892        String ctrlName
1893       
1894        DoAlert 1,"Do you want to clear the list of runs and file names to combine?"
1895        TableToCombineAndSave(V_flag==1)                // clear and initialize, if desired
1896        return(0)
1897end
1898
1899Function TableToCombineAndSave(clear)
1900        Variable clear
1901       
1902        if(clear)
1903                // make the waves and table for the sets to combine
1904                Make/O/N=0 $"root:myGlobals:CombineTable:LowRun"
1905                Make/O/N=0 $"root:myGlobals:CombineTable:MediumRun"
1906                Make/O/N=0 $"root:myGlobals:CombineTable:HighRun"
1907                Make/O/T/N=0 $"root:myGlobals:CombineTable:Prefix"
1908                Make/O/T/N=0 $"root:myGlobals:CombineTable:SaveName"
1909        endif
1910        SetDataFolder root:myGlobals:CombineTable
1911       
1912        // make the second table
1913        AppendToTable/W=CombinePanel#RunNumbersToCombine LowRun,MediumRun,HighRun,Prefix,SaveName
1914       
1915        SetDataFolder root:
1916End
Note: See TracBrowser for help on using the repository browser.