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

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

Added pixel number and size to 2D output
resolved #247

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