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

Last change on this file since 626 was 626, checked in by ajj, 13 years ago

XML output from NSORT

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