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

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

Modifications to NSORT to use data folder methods for dataset handling

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