source: sans/Dev/trunk/NCNR_User_Procedures/Common/DataSetHandling.ipf @ 734

Last change on this file since 734 was 734, checked in by srkline, 12 years ago

Fixed bug in maunUSANS panel where clicking in white space in the file list threw up an open file dialog.

ticket #292: 1D arithmetic panel now properly writes out USANS data, switching to fill in the USANS fields if the USANS_dQv variable is found. Otherwise it is treated as SANS data.

File size: 50.0 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2
3
4///////// SRK - VERY SIMPLE batch converter has been added: see
5//
6//      Function batchXML26ColConvert()
7//
8// Function batchGrasp26ColConvert()
9//
10// these both need a real interface, and a way to better define the name of the
11// converted output file. And some retention of the header would be nice too...
12//
13
14
15// Functions and interfaces to manage datasets now that they are in data folders
16// Planned interface
17// - Panel to select/load data and then select operation
18// Planned functions:
19// - Rename a data set - AJJ Done Nov 2009
20// - Duplicate a data set - AJJ Done Nov 2009
21// - Subtract one data set from another
22// - Add one data set to another
23// - Divide data sets
24// - Multiply data sets
25// - Save a data folder to file
26
27/////////////////// Data Management Panel ///////////////////////////////////////////////////////
28
29//
30Proc MakeDMPanel()
31        DoWindow/F DataManagementPanel
32        if(V_flag==0)
33                fMakeDMPanel()
34        endif
35End
36
37Proc fMakeDMPanel()
38        PauseUpdate; Silent 1           // building window...
39        NewPanel /W=(459,44,959,410)/N=DataManagementPanel/K=2 as "Data Set Management"
40        ModifyPanel fixedSize=1,cbRGB=(30000,60000,60000)
41
42        //Main bit of panel
43        GroupBox grpBox_0,pos={20,10},size={460,100}
44        GroupBox grpBox_1,pos={20,130},size={460,70}
45        GroupBox grpBox_2,pos={20,220},size={460,40}
46
47        GroupBox grpBox_3,pos={20,280},size={460,40}
48
49        Button DS_button,title="Load 1D Data Set",pos={300,20},size={150,20}
50        Button DS_button,proc=DM_LoadDataSetProc
51        Button Unload_button,title="Unload 1D Data Set",pos={300,50},size={150,20}
52        Button Unload_button,proc=DM_UnloadProc
53        Button Save_button,title="Save 1D Data Set",pos={300,80},size={150,20}
54        Button Save_button,proc=DM_SaveProc
55        PopupMenu DS_popup,pos={30,40},size={318,20},title="Data Set ",proc=DM_PopupProc
56        PopupMenu DS_popup,mode=1,value= #"DM_DataSetPopupList()"
57
58        CheckBox XMLStateCtrl,pos={30,82},size={124,14},title="XML Output Enabled (change in Preferences)"
59        CheckBox XMLStateCtrl,help={"Default output format is canSAS XML rather than NIST 6 column"}
60        CheckBox XMLStateCtrl,value= root:Packages:NIST:gXML_Write,disable=2
61
62        Button Rename_button,title="Rename",pos={75,170},size={150,20}
63        Button Rename_button,proc=DM_RenameProc
64        Button  Duplicate_button,title="Duplicate",pos={275,170},size={150,20}
65        Button Duplicate_button,proc=DM_DuplicateProc
66
67        SetVariable NewName_setvar,title="New Name (max 25 characters)",pos={50,140},size={400,20}
68        SetVariable NewName_setvar,fsize=12,value=_STR:"",proc=DMNameSetvarproc,live=1
69               
70        Button SaveAsXML_button,title="Save as canSAS XML",pos={75,230},size={150,20}
71        Button SaveAsXML_button,proc=DMSaveAsXMLproc   
72
73        Button SaveAs6col_button,title="Save as NIST 6 column",pos={275,230},size={150,20}
74        Button SaveAs6col_button,proc=DMSaveAs6colproc 
75       
76        Button BatchConvertData_button,title="Convert Format of 1D Data Files",pos={75,290},size={350,20}
77        Button BatchConvertData_button,proc=DMBatchConvertProc
78                       
79        Button DMDone_button,title="Done",pos={360,330},size={60,20}
80        Button DMDone_button,proc=DMDoneButtonProc
81        Button DMHelp_button,title="?",pos={440,330},size={30,20}
82        Button DMHelp_button,proc=DMHelpButtonProc
83       
84       
85        ControlInfo/W=DataManagementPanel DS_popup
86        if (cmpstr(S_Value,"No data loaded") == 0)
87                SetVariable NewName_setvar,value=_STR:"dataset_copy"
88        else
89                //fake call to popup
90                STRUCT WMPopupAction pa
91                pa.win = "DataManagementPanel"
92                pa.ctrlName = "DS_popup"
93                pa.eventCode = 2
94                DM_PopupProc(pa)
95        endif
96
97End
98
99Function DMBatchConvertProc(ba) : ButtonControl
100        STRUCT WMButtonAction &ba
101       
102        switch( ba.eventCode)
103                case 2:
104                        Execute "MakeBatchConvertPanel()"
105                        break
106        endswitch
107       
108        return 0
109End
110
111
112Function DMNameSetvarproc(sva) : SetVariableControl
113        STRUCT WMSetVariableAction &sva
114               
115        switch( sva.eventCode )
116                case 1: // mouse up
117                case 2: // Enter key
118                case 3: // Live update
119                                String sv = sva.sval
120                                if( strlen(sv) > 25 )
121                                        sv= sv[0,24]
122                                        SetVariable  $(sva.ctrlName),win=$(sva.win),value=_STR:sv
123                                        ControlUpdate /W=$(sva.win) $(sva.ctrlName)
124                                        Beep
125                                endif
126                                break
127                endswitch
128        return 0
129End
130
131Function DM_RenameProc(ba) : ButtonControl
132        STRUCT WMButtonAction &ba
133       
134        String DS,NewName
135       
136        ControlInfo/W=$(ba.win) DS_popup
137        DS = S_Value
138       
139        ControlInfo/W=$(ba.win) NewName_setvar
140        NewName = CleanupName(S_Value, 0 )              //clean up any bad characters, and put the cleaned string back
141        SetVariable NewName_setvar,value=_STR:NewName
142       
143        switch (ba.eventcode)
144                case 2: // mouse up
145                        RenameDataSet(DS,NewName)
146                        ControlUpdate /W=$(ba.win) DS_Popup
147                        break
148        endswitch
149
150
151       
152        return 0
153end
154               
155Function DM_DuplicateProc(ba) : ButtonControl
156        STRUCT WMButtonAction &ba
157       
158        String DS,NewName
159       
160        ControlInfo/W=$(ba.win) DS_popup
161        DS = S_Value
162       
163        ControlInfo/W=$(ba.win) NewName_setvar
164        NewName = CleanupName(S_Value, 0 )              //clean up any bad characters, and put the cleaned string back
165        SetVariable NewName_setvar,value=_STR:NewName
166       
167        switch (ba.eventcode)
168                case 2: // mouse up
169                        DuplicateDataSet(DS,NewName,0)
170                        ControlUpdate /W=$(ba.win) DS_Popup
171                        break
172        endswitch
173       
174        return 0
175end
176
177Function DM_SaveProc(ba) : ButtonControl
178        STRUCT WMButtonAction &ba
179       
180        switch(ba.eventCode)
181                case 2:
182                        ControlInfo/W=$(ba.win) DS_popup
183                        SaveDataSetToFile(S_Value)
184                        break
185        endswitch
186       
187        return 0
188end
189
190Function DM_UnloadProc(ba) : ButtonControl
191        STRUCT WMButtonAction &ba
192
193        switch (ba.eventcode)
194                case 2: // mouse up
195                       
196                        String savDF=GetDataFolder(1)
197                        String DF
198                        ControlInfo /W=$(ba.win) DS_Popup
199                        DF = S_Value
200                       
201                        print DF
202                        //check for horrific null output from control
203                        if (cmpstr(DF,"") != 0)
204                       
205                                SetDataFolder DF
206                                KillVariables/A
207                                SetDataFolder savDF
208                       
209                                KillDataFolder/Z $DF
210                                ControlUpdate /W=$(ba.win) DS_Popup
211                       
212                                ControlInfo/W=DataManagementPanel DS_popup
213                                if (cmpstr(S_Value,"No data loaded") == 0)
214                                        SetVariable NewName_setvar,value=_STR:"dataset_copy"
215                                else
216                                        //fake call to popup
217                                        STRUCT WMPopupAction pa
218                                        pa.win = "DataManagementPanel"
219                                        pa.ctrlName = "DS_popup"
220                                        pa.eventCode = 2
221                                        DM_PopupProc(pa)
222                                endif
223                        endif
224                        break
225        endswitch
226       
227        return 0
228end
229               
230
231Function DM_PopupProc(pa) : PopupMenuControl
232        STRUCT WMPopupAction &pa
233       
234        String resultName
235       
236        switch( pa.eventCode)
237                case 2:
238                        //print "Called by "+pa.ctrlname+" with value "+pa.popStr
239                        ControlInfo/W=$(pa.win) $(pa.ctrlName)
240                        String popStr = S_Value
241                        if (stringmatch(pa.ctrlname,"*DS*") == 1)
242                                resultName = stringfromlist(0,popStr,"_")+"_copy"
243                               
244                                SetVariable NewName_setvar win=$(pa.win), value=_STR:resultName
245                        endif
246                break
247        endswitch
248       
249
250End
251
252
253//Must follow naming scheme to match buttons to popups
254//"Name_button" goes with "Name_popup"
255Function DM_LoadDataSetProc(ba) : ButtonControl
256        STRUCT WMButtonAction &ba
257
258
259        switch( ba.eventCode )
260                case 2: // mouse up
261                        // click code here
262                        String cmd = "A_LoadOneDDataWithName(\"\","+num2str(0)+")"
263                        Execute cmd
264               
265                        SVAR gLastFileName = root:packages:NIST:gLastFileName
266
267                        String windowName = ba.win
268                        String popupName = StringFromList(0,ba.ctrlName,"_")+"_popup"
269                       
270                        ControlUpdate/W=$(windowName) $(popupName)
271                        //instead of a simple controlUpdate, better to pop the menu to make sure that the other menus follow
272                        // convoluted method to find the right item and pop the menu.
273
274                        String list,folderStr
275                        Variable num
276                        folderStr = CleanupName(gLastFileName,0)
277                        list = DM_DataSetPopupList()
278                        num=WhichListItem(folderStr,list,";",0,0)
279                        if(num != -1)
280                                PopupMenu $(popupName),mode=num+1,win=$(windowName)
281                                ControlUpdate/W=$(windowName) $(popupName)
282                               
283                                if (cmpstr(popupName,"DS_popup") ==  0)
284                                        //send fake mouse action to popup to update old name if
285                                        Struct WMPopupAction pa
286                                        pa.eventCode = 2                //fake mouse up
287                                        pa.win = windowName
288                                        pa.ctrlName = "DS_popup"
289                                        DM_PopupProc(pa)
290                                endif                   
291                        endif
292                        break
293        endswitch
294       
295        return 0
296End
297
298
299Function/S DMGetDSName(dsNum)
300        Variable dsNum
301       
302        String ctrlName
303        if (dsNum == 1)
304                ctrlName = "DS1_popup"
305        elseif (dsNum == 2)
306                ctrlName = "DS2_popup"
307        endif
308       
309        ControlInfo/W=DataManagementPanel $(ctrlName)
310
311        Return S_Value
312
313End
314
315
316Function DMDoneButtonProc(ba) : ButtonControl
317        STRUCT WMButtonAction &ba
318       
319        String win = ba.win
320
321        switch (ba.eventCode)
322                case 2:
323                        DoWindow/K DataManagementPanel
324                        break
325        endswitch
326
327        return 0
328End
329
330Function DMHelpButtonProc(ba) : ButtonControl
331        STRUCT WMButtonAction &ba
332       
333        String win = ba.win
334
335        switch (ba.eventCode)
336                case 2:
337                        // click code here
338                        DisplayHelpTopic/Z/K=1 "Data Set Management"
339                        if(V_flag !=0)
340                                DoAlert 0,"The Data Set Management Help file could not be found"
341                        endif
342                        break
343        endswitch
344
345        return 0
346End
347
348/////////////////////// Batch Data Conversion Panel ////////////////////////////////////
349//
350//
351
352Proc MakeNCNRBatchConvertPanel()
353        NCNRInitBatchConvert()
354        DoWindow/F NCNRBatchConvertPanel
355        if(V_flag==0)
356                fMakeNCNRBatchConvertPanel()
357        endif
358End
359
360
361Function NCNRInitBatchConvert()
362        NewDataFolder/O/S root:Packages:NIST:BatchConvert
363        Make/O/T/N=1 filewave=""
364        Make/O/N=1 selWave=0
365        Variable/G ind=0,gRadioVal=1
366        SetDataFolder root:
367End
368
369Proc fMakeNCNRBatchConvertPanel()
370        PauseUpdate; Silent 1           // building window...
371        NewPanel /W=(658,347,1018,737)/N=NCNRBatchConvertPanel/K=2 as "Batch Convert 1D Data"
372//      NewPanel /W=(658,347,1018,737)/N=NCNRBatchConvertPanel as "Batch Convert 1D Data"
373        ModifyPanel cbRGB=(40000,50000,32896)
374        ModifyPanel fixedSize=1
375       
376        ListBox fileList,pos={13,11},size={206,179}
377        ListBox fileList,listWave=root:Packages:NIST:BatchConvert:fileWave
378        ListBox fileList,selWave=root:Packages:NIST:BatchConvert:selWave,mode= 4
379
380        Button button7,pos={238,20},size={100,20},proc=NCNRBatchConvertNewFolder,title="New Folder"
381        Button button7,help={"Select a new data folder"}
382        TitleBox msg0,pos={238,140},size={100,30},title="\JCShift-click to\rselect multiple files"
383        TitleBox msg0,frame=0,fixedSize=1
384       
385        GroupBox filterGroup,pos={13,200},size={206,60},title="Filter list by input file type"
386        CheckBox filterCheck_1,pos={24,220},size={36,14},title="XML",value= 1,mode=1, proc=BC_filterCheckProc
387        CheckBox filterCheck_2,pos={24,239},size={69,14},title="ABS or AVE",value= 0,mode=1, proc=BC_filterCheckProc
388        CheckBox filterCheck_3,pos={100,220},size={69,14},title="none",value= 0,mode=1, proc=BC_filterCheckProc
389       
390        Button button8,pos={238,76},size={100,20},proc=NCNRBatchConvertHelpProc,title="Help"
391        Button button9,pos={238,48},size={100,20},proc=NCNRBatchConvertRefresh,title="Refresh List"
392        Button button0,pos={238,106},size={100,20},proc=NCNRBatchConvertDone,title="Done"
393
394        GroupBox outputGroup,pos={13,270},size={206,60},title="Output File Type"
395        CheckBox outputCheck_1,pos={24,289},size={36,14},title="XML",value= 0,mode=1, proc=BC_outputCheckProc
396        CheckBox outputCheck_2,pos={24,309},size={69,14},title="ABS or AVE",value= 1,mode=1, proc=BC_outputCheckProc
397       
398        Button button6,pos={13,350},size={206,20},proc=NCNRBatchConvertFiles,title="Convert File(s)"
399        Button button6,help={"Converts the files to the format selected"}
400       
401
402       
403End
404
405Function BC_filterCheckProc(ctrlName,checked) : CheckBoxControl
406        String ctrlName
407        Variable checked
408
409        NVAR gRadioVal= root:Packages:NIST:BatchConvert:gRadioVal
410       
411        strswitch (ctrlName)
412                case "filterCheck_1":
413                        gRadioVal= 1
414                        break
415                case "filterCheck_2":
416                        gRadioVal= 2
417                        break
418                case "filterCheck_3":
419                        gRadioVal= 3
420                        break
421        endswitch
422        CheckBox filterCheck_1,value= gRadioVal==1
423        CheckBox filterCheck_2,value= gRadioVal==2
424        CheckBox filterCheck_3,value= gRadioVal==3
425       
426        NCNRBatchConvertGetList()
427         
428        return(0)
429End
430
431Function BC_outputCheckProc(ctrlName,checked) : CheckBoxControl
432        String ctrlName
433        Variable checked
434
435        if(cmpstr("outputCheck_1",ctrlName)==0)
436                CheckBox outputCheck_1,value=checked
437                CheckBox outputCheck_2,value=!checked
438        else
439                CheckBox outputCheck_1,value=!checked
440                CheckBox outputCheck_2,value=checked
441        endif
442       
443        return(0)
444End
445
446Function NCNRBatchConvertFiles(ba) : ButtonControl
447                STRUCT WMButtonAction &ba
448               
449               
450                switch (ba.eventCode)
451                        case 2:
452                       
453                                //check the input/output as best I can (none may be the input filter)
454                                Variable inputType,outputType=1
455                                NVAR gRadioVal= root:Packages:NIST:BatchConvert:gRadioVal
456                                inputType = gRadioVal
457                                ControlInfo outputCheck_1
458                                if(V_value==1)
459                                        outputType = 1          //xml
460                                else
461                                        outputType = 2          //6-col
462                                endif
463                               
464                                if(inputType==outputType)
465                                        DoAlert 0,"Input and output types are the same. Nothing will be converted"
466                                        return(0)
467                                endif
468                       
469                       
470                                        // input and output are different, proceed
471
472                                Wave/T fileWave=$"root:Packages:NIST:BatchConvert:fileWave"
473                                Wave sel=$"root:Packages:NIST:BatchConvert:selWave"
474                               
475                                String fname="",pathStr="",newFileName=""
476                                Variable ii,num
477                                PathInfo catPathName                    //this is where the files are
478                                pathStr=S_path
479                                                       
480                                // process the selected items
481                                num=numpnts(sel)
482                                ii=0
483                                do
484                                        if(sel[ii] == 1)
485                                                fname=pathStr + fileWave[ii]
486                                               
487                                                if(outputType == 1)
488                                                        convertNISTtoNISTXML(fname)
489                                                endif
490                                               
491                                                if(outputType == 2)
492                                                        convertNISTXMLtoNIST6Col(fname)
493                                                endif
494                                        endif
495                                        ii+=1
496                                while(ii<num)
497                               
498                                break
499                endswitch
500
501        return 0
502End
503
504
505Function NCNRBatchConvertNewFolder(ba) : ButtonControl
506        STRUCT WMButtonAction &ba
507       
508        switch (ba.eventcode)
509                case 2:
510                        A_PickPath()
511                        NCNRBatchConvertGetList()
512                        break
513        endswitch
514
515End
516
517
518// filter is a bit harsh - will need to soften this by presenting an option to enter the suffix
519//
520Function NCNRBatchConvertGetList()
521
522        //make sure that path exists
523        PathInfo catPathName
524        if (V_flag == 0)
525                Abort "Folder path does not exist - use \"New Folder\" button"
526        Endif
527       
528        String newList = A_ReducedDataFileList(""),tmpList=""
529        Variable num
530       
531        NVAR gRadioVal= root:Packages:NIST:BatchConvert:gRadioVal
532        ControlInfo filterCheck_1
533        if(gRadioVal == 1)
534                //keep XML data
535                tmpList = ListMatch(newList, "*.ABSx" ,";")
536                tmpList += ListMatch(newList, "*.AVEx" ,";")
537                tmpList += ListMatch(newList, "*.xml" ,";")
538        else
539                if(gRadioVal ==2)
540                        //keep ave, abs data
541                        tmpList = ListMatch(newList, "*.ABS" ,";")
542                        tmpList += ListMatch(newList, "*.AVE" ,";")
543                else
544                        //return everything
545                        tmpList = newList
546                endif
547        endif
548        newList = tmpList
549       
550        num=ItemsInList(newlist,";")
551        WAVE/T fileWave=$"root:Packages:NIST:BatchConvert:fileWave"
552        WAVE selWave=$"root:Packages:NIST:BatchConvert:selWave"
553        Redimension/N=(num) fileWave
554        Redimension/N=(num) selWave
555        fileWave = StringFromList(p,newlist,";")
556        Sort filewave,filewave
557       
558        return 0
559End
560
561Function NCNRBatchConvertRefresh(ba) : ButtonControl
562                STRUCT WMButtonAction &ba
563               
564                switch (ba.eventCode)
565                        case 2:
566                                NCNRBatchConvertGetList()
567                                break
568                endswitch
569               
570                return 0
571End
572       
573
574Function NCNRBatchConvertDone(ba) : ButtonControl
575                STRUCT WMButtonAction &ba
576
577                switch (ba.eventCode)
578                        case 2:
579                                DoWindow/K NCNRBatchConvertPanel
580                                break
581                endswitch
582               
583                return 0
584End
585
586Function NCNRBatchConvertHelpProc(ba) : ButtonControl
587        STRUCT WMButtonAction &ba
588       
589        String win = ba.win
590
591        switch (ba.eventCode)
592                case 2:
593                        // click code here
594                        DisplayHelpTopic/Z/K=1 "Batch Data Conversion"
595                        if(V_flag !=0)
596                                DoAlert 0,"The Batch Data Conversion Help file could not be found"
597                        endif
598                        break
599        endswitch
600
601        return 0
602End
603
604/////////////////////// Data Arithmetic Panel /////////////////////////////////////////
605
606//
607Function MakeDAPanel()
608        DoWindow/F DataArithmeticPanel
609        if(V_flag==0)
610                fMakeDAPanel()
611        else
612                DoWindow/F DAPlotPanel
613        endif
614       
615        return(0)
616End
617
618Function fMakeDAPanel()
619        PauseUpdate; Silent 1           // building window...
620        DoWindow/K DataArithmeticPanel
621        NewPanel /W=(459,44,959,404)/N=DataArithmeticPanel/K=2 as "Data Set Arithmetic"
622        ModifyPanel fixedSize=1
623
624        //Main bit of panel
625        GroupBox grpBox_0,pos={20,10},size={460,105}
626
627        Button DS1_button,pos={300,20},size={150,20},proc=DA_LoadDataSetProc,title="Load 1D Data Set 1"
628        Button DS1_button,valueColor=(65535,0,0),userdata="DS1"
629        PopupMenu DS1_popup,pos={30,21},size={318,20},title="Data Set 1"
630        PopupMenu DS1_popup,mode=1,value= #"DM_DataSetPopupList()"
631        PopupMenu DS1_popup,proc=DA_PopupProc
632        PopupMenu DS1_popup,fsize=12,fcolor=(65535,0,0),valueColor=(65535,0,0)
633
634        Button DS2_button,pos={300,50},size={150,20},proc=DA_LoadDataSetProc,title="Load 1D Data Set 2"
635        Button DS2_button,valueColor=(0,0,65535),userdata="DS2"
636        PopupMenu DS2_popup,pos={30,51},size={318,20},title="Data Set 2"
637        PopupMenu DS2_popup,mode=1,value= #"DM_DataSetPopupList()"
638        PopupMenu DS2_popup,proc=DA_PopupProc
639        PopupMenu DS2_popup,fsize=12,fcolor=(0,0,65535),valueColor=(0,0,65535)
640
641        Button DAPlot_button,title="Plot",pos={100,85},size={150,20}
642        Button DAPlot_button,proc=DAPlotButtonProc
643        Button DADone_button,title="Done",pos={360,85},size={60,20}
644        Button DADone_button,proc=DADoneButtonProc
645        Button DAHelp_button,title="?",pos={440,85},size={30,20}
646        Button DAHelp_button,proc=DAHelpButtonProc
647
648
649        //Tabs
650        TabControl DATabs,pos={20,120},size={460,220},tabLabel(0)="Subtract", proc=DATabsProc
651        TabControl DATabs,tablabel(1)="Add",tablabel(2)="Multiply",tablabel(3)="Divide"
652        TabControl DATabs,value=0
653
654        Button DACalculate_button,title="Calculate",pos={50,310},size={150,20}
655        Button DACalculate_button,proc=DACalculateProc
656        Button DASave_button,title="Save Result",pos={300,310},size={150,20}
657        Button DASave_button,proc=DASaveProc,disable=2
658        Button DACursors_button,title="Get Matching Range",pos={175,250},size={150,20}
659        Button DACursors_button,proc=DACursorButtonProc
660       
661        SetVariable DAResultName_sv,title="Result Name (max 25 characters)",pos={50,280},size={400,20}
662        SetVariable DAResultName_Sv,fsize=12,proc=DANameSetvarproc,live=1
663        //Update the result name
664        ControlInfo/W=DataArithmeticPanel DS1_popup
665        if (cmpstr(S_Value,"No data loaded") == 0)
666                SetVariable DAResultName_sv,value=_STR:"SubtractionResult"
667        else
668                //fake call to popup
669                STRUCT WMPopupAction pa
670                pa.win = "DataArithmeticPanel"
671                pa.ctrlName = "DS1_popup"
672                pa.eventCode = 2
673                DA_PopupProc(pa)
674        endif
675       
676        CheckBox DANoDS2_cb,title="Data Set 2 = 1?",pos={300,180}
677        CheckBox DANoDS2_cb,proc=DANoDS2Proc
678       
679        ValDisplay DARangeStar_vd,title="Start",pos={40,220},size={100,20},fsize=12,value=_NUM:0
680        ValDisplay DARangeEnd_vd,title="End  ",pos={160,220},size={100,20},fsize=12,value=_NUM:0
681       
682        SetVariable DAScale_sv,title="Scale Factor (f)",pos={280,220},size={180,20},fsize=12,value=_NUM:1
683
684        GroupBox grpBox_1,pos={30,210},size={440,70}
685       
686        NewPanel/HOST=DataArithmeticPanel/N=arithDisplay/W=(50,150,170,190)
687       
688        //Update the result name
689        ControlInfo/W=DataArithmeticPanel DS1_popup
690
691       
692       
693        arithDisplayProc(0)
694       
695End
696
697
698Function MakeDAPlotPanel()
699        PauseUpdate; Silent 1           // building window...
700        DoWindow/K DAPlotPanel
701        NewPanel /W=(14,44,454,484)/N=DAPlotPanel/K=1 as "Data Set Arithmetic"
702        ModifyPanel fixedSize=1
703
704        Display/HOST=DAPlotPanel/N=DAPlot/W=(0,0,440,400)
705        Legend
706        ShowInfo
707        SetActiveSubWindow DAPlotPanel
708        Checkbox DAPlot_log_cb, title="Log I(q)", pos={20,410},value=0
709        Checkbox DAPlot_log_cb, proc=DALogLinIProc
710        Checkbox DAPlot_lin_cb, title="High Q Linear", pos={100,410},value=0
711        Checkbox DAPlot_lin_cb, proc=DAHighQLinProc
712       
713End
714
715Function AddDAPlot(dataset)
716        Variable dataset
717       
718        String win = "DataArithmeticPanel"
719        String DS1name,DS2name,ResultName
720
721        switch(dataset)
722                case 1:
723                        ControlInfo/W=$(win) DS1_popup
724                        DS1name = S_Value
725                        Wave qWave = $("root:"+DS1name+":"+DS1name+"_q")
726                        Wave iWave = $("root:"+DS1name+":"+DS1name+"_i")
727                        Wave errWave = $("root:"+DS1name+":"+DS1name+"_s")
728                        AppendToGraph/W=DAPlotPanel#DAPlot iWave vs Qwave
729                        ErrorBars/W=DAPlotPanel#DAPlot /T=0 $(DS1name+"_i"), Y wave=(errWave,errWave)
730                        ModifyGraph/W=DAPlotPanel#DAPlot rgb($(DS1name+"_i"))=(65535,0,0)
731                        ControlInfo/W=$(win) DANoDS2_cb
732//                      if (V_Value == 1)
733//                                      Cursor/W=DAPlotPanel#DAPlot A, $(DS1name+"_i"), leftx(iWave)
734//                                      Cursor/W=DAPlotPanel#DAPlot/A=0 B, $(DS1name+"_i"),  rightx(iWave)
735//                      endif
736                        break
737                case 2:
738                        ControlInfo/W=$(win) DANoDS2_cb
739                        if (V_Value == 0)
740                                ControlInfo/W=$(win) DS2_popup
741                                DS2name = S_Value
742                                if(cmpstr(DS2name,"No data loaded")==0)
743                                        break                   //in case someone loads set 1, but not set two, then plots
744                                endif
745                                Wave qWave = $("root:"+DS2name+":"+DS2name+"_q")
746                                Wave iWave = $("root:"+DS2name+":"+DS2name+"_i")
747                                Wave errWave = $("root:"+DS2name+":"+DS2name+"_s")
748                                AppendToGraph/W=DAPlotPanel#DAPlot iWave vs Qwave
749                                ErrorBars/W=DAPlotPanel#DAPlot /T=0 $(DS2name+"_i"), Y wave=(errWave,errWave)                   
750                                ModifyGraph/W=DAPlotPanel#DAPlot rgb($(DS2name+"_i"))=(0,0,65535)
751                                Cursor/W=DAPlotPanel#DAPlot A, $(DS2name+"_i"), leftx(iWave)
752                                Cursor/W=DAPlotPanel#DAPlot/A=0 B, $(DS2name+"_i"),  rightx(iWave)
753                        else
754                                ControlInfo/W=$(win) DS1_popup
755                                DS1name = S_Value
756                                DuplicateDataSet("root:"+DS1name,"NullSolvent",1)
757                                Wave qWave =root:NullSolvent:NullSolvent_q
758                                Wave iWave = root:NullSolvent:NullSolvent_i
759                                Wave errWave = root:NullSolvent:NullSolvent_s
760                                Wave iWaveDS1 = $("root:"+DS1name+":"+DS1name+"_i")
761                                iWave = 1
762                                errWave = 0
763                                AppendToGraph/W=DAPlotPanel#DAPlot iWave vs Qwave
764                                ErrorBars/W=DAPlotPanel#DAPlot /T=0 NullSolvent_i, Y wave=(errWave,errWave)                     
765                                ModifyGraph/W=DAPlotPanel#DAPlot rgb(NullSolvent_i)=(0,0,65535)
766                                //Cursor/W=DAPlotPanel#DAPlot A, NullSolvent_i, leftx(iWave)
767                                //Cursor/W=DAPlotPanel#DAPlot/A=0 B, NullSolvent_i,  rightx(iWave)
768                                if(strlen(CsrInfo(A,"DAPlotPanel#DAPlot")) == 0)                //cursors not already on the graph             
769                                        Cursor/W=DAPlotPanel#DAPlot A, $(DS1Name+"_i"), leftx(iWaveDS1)
770                                        Cursor/W=DAPlotPanel#DAPlot/A=0 B, $(DS1Name+"_i"),  rightx(iWaveDS1)                   
771                                endif
772                        endif
773                        break
774                case 3:
775                        ControlInfo/W=$(win) DAResultName_sv
776                        ResultName = S_Value
777                        Wave qWave = $("root:"+ResultName+":"+ResultName+"_q")
778                        Wave iWave = $("root:"+ResultName+":"+ResultName+"_i")
779                        Wave errWave = $("root:"+ResultName+":"+ResultName+"_s")
780                        AppendToGraph/W=DAPlotPanel#DAPlot iWave vs Qwave
781                        ErrorBars/W=DAPlotPanel#DAPlot /T=0 $(ResultName+"_i"), Y wave=(errWave,errWave)
782                        ModifyGraph/W=DAPlotPanel#DAPlot rgb($(ResultName+"_i"))=(0,65535,0)
783                        break
784        endswitch
785
786        ControlInfo/W=DAPlotPanel DAPlot_log_cb
787        ModifyGraph/W=DAPlotPanel#DAPlot mode=3, msize=2, marker=19, mirror=1, tick=2, log(bottom)=1,log(left)=V_Value,tickUnit=1
788End
789
790Function arithDisplayProc(s)
791        Variable s
792
793        SetActiveSubWindow DataArithmeticPanel#arithDisplay
794
795        switch (s)
796                case 0:
797                        //Subtract
798                        DrawAction/L=progFront delete
799                        DrawRect 0,0,120,40
800                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,65535,0)
801                        DrawText 10,32,"I"
802                        SetDrawEnv fname="Times", fsize=22, fstyle= 1,textrgb= (0,0,0)
803                        DrawText 20,30,"="
804                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (65535,0,0)
805                        DrawText 35,32,"I"
806                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,65535)
807                        DrawText 95,32,"I"
808                        SetDrawEnv fname="Symbol", fsize=22, fstyle= 1,textrgb= (0,0,0)
809                        DrawText 52,32,"-"
810                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,0)
811                        DrawText 75,30,"f"
812                        SetDrawEnv fname="Times", fsize=22, fstyle= 1,textrgb= (0,0,0)
813                        DrawText 85,32,"*"
814                        break
815                case 1:
816                        //Add
817                        DrawAction/L=progFront delete
818                        DrawRect 0,0,120,40
819                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,65535,0)
820                        DrawText 10,32,"I"
821                        SetDrawEnv fname="Times", fsize=22, fstyle= 1,textrgb= (0,0,0)
822                        DrawText 20,30,"="
823                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (65535,0,0)
824                        DrawText 35,32,"I"
825                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,65535)
826                        DrawText 95,32,"I"
827                        SetDrawEnv fname="Symbol", fsize=22, fstyle= 1,textrgb= (0,0,0)
828                        DrawText 52,32,"+"
829                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,0)
830                        DrawText 75,30,"f"
831                        SetDrawEnv fname="Times", fsize=22, fstyle= 1,textrgb= (0,0,0)
832                        DrawText 85,32,"*"
833                        break
834                case 2:
835                        //Multiply
836                        DrawAction/L=progFront delete
837                        DrawRect 0,0,120,40
838                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,65535,0)
839                        DrawText 10,32,"I"
840                        SetDrawEnv fname="Times", fsize=22, fstyle= 1,textrgb= (0,0,0)
841                        DrawText 20,30,"="
842                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (65535,0,0)
843                        DrawText 35,32,"I"
844                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,65535)
845                        DrawText 95,32,"I"
846                        SetDrawEnv fname="Symbol", fsize=22, fstyle= 1,textrgb= (0,0,0)
847                        DrawText 52,32,"*"
848                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,0)
849                        DrawText 66,30,"("
850                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,0)
851                        DrawText 75,30,"f"
852                        SetDrawEnv fname="Times", fsize=22, fstyle= 1,textrgb= (0,0,0)
853                        DrawText 85,32,"*"
854                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,0)                                 
855                        DrawText 105,30,")"
856                        break
857                case 3:
858                        //Divide
859                        DrawAction/L=progFront delete
860                        DrawRect 0,0,120,40
861                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,65535,0)
862                        DrawText 10,32,"I"
863                        SetDrawEnv fname="Times", fsize=22, fstyle= 1,textrgb= (0,0,0)
864                        DrawText 20,30,"="
865                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (65535,0,0)
866                        DrawText 35,32,"I"
867                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,65535)
868                        DrawText 95,32,"I"
869                        SetDrawEnv fname="Symbol", fsize=22, fstyle= 1,textrgb= (0,0,0)
870                        DrawText 52,32,"/"
871                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,0)
872                        DrawText 66,30,"("
873                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,0)
874                        DrawText 75,30,"f"
875                        SetDrawEnv fname="Times", fsize=22, fstyle= 1,textrgb= (0,0,0)
876                        DrawText 85,32,"*"
877                        SetDrawEnv fname="Times", fsize=22, fstyle= 2,textrgb= (0,0,0)                                 
878                        DrawText 105,30,")"
879                        break           
880        endswitch
881
882        SetActiveSubWindow DataArithmeticPanel
883       
884        return 0
885End
886
887//Must follow naming scheme to match buttons to popups
888//"Name_button" goes with "Name_popup"
889Function DA_LoadDataSetProc(ba) : ButtonControl
890        STRUCT WMButtonAction &ba
891       
892        switch( ba.eventCode )
893                case 2: // mouse up
894                        // click code here
895                        String cmd = "A_LoadOneDDataWithName(\"\","+num2str(0)+")"
896                        Execute cmd
897               
898                        SVAR gLastFileName = root:packages:NIST:gLastFileName
899
900                        String windowName = ba.win
901                        String popupName = StringFromList(0,ba.ctrlName,"_")+"_popup"
902                       
903                        ControlUpdate/W=$(windowName) $(popupName)
904                        //instead of a simple controlUpdate, better to pop the menu to make sure that the other menus follow
905                        // convoluted method to find the right item and pop the menu.
906
907                        String list,folderStr
908                        Variable num
909                        folderStr = CleanupName(gLastFileName,0)
910                        list = DM_DataSetPopupList()
911                        num=WhichListItem(folderStr,list,";",0,0)
912                        if(num != -1)
913                                PopupMenu $(popupName),mode=num+1,win=$(windowName)
914                                ControlUpdate/W=$(windowName) $(popupName)
915               
916                        endif
917                        //fake call to popup
918                        STRUCT WMPopupAction pa
919                        pa.win = ba.win
920                        pa.ctrlName = "DS1_popup"
921                        pa.eventCode = 2
922                        DA_PopupProc(pa)
923                        break
924        endswitch
925       
926        return 0
927End
928
929Function DA_PopupProc(pa) : PopupMenuControl
930        STRUCT WMPopupAction &pa
931       
932        String resultName
933       
934        switch( pa.eventCode)
935                case 2:
936                        //print "Called by "+pa.ctrlname+" with value "+pa.popStr
937                        ControlInfo/W=$(pa.win) $(pa.ctrlName)
938                        String popStr = S_Value
939                        if (stringmatch(pa.ctrlname,"*DS1*") == 1)
940                                resultName = stringfromlist(0,popStr,"_")+"_mod"
941                               
942                                SetVariable DAResultName_sv win=$(pa.win), value=_STR:resultName
943                        endif
944                break
945        endswitch
946       
947
948End
949
950// function to control the drawing of buttons in the TabControl on the main panel
951// Naming scheme for the buttons MUST be strictly adhered to... else buttons will
952// appear in odd places...
953// all buttons are named MainButton_NA where N is the tab number and A is the letter denoting
954// the button's position on that particular tab.
955// in this way, buttons will always be drawn correctly..
956//
957Function DATabsProc(tca) : TabControl
958        STRUCT WMTabControlAction &tca
959               
960        switch (tca.eventCode)
961                case 2:
962                //      Print "name,number",name,tab
963                        String ctrlList = ControlNameList("",";"),item="",nameStr=""
964                        Variable num = ItemsinList(ctrlList,";"),ii,onTab
965                        for(ii=0;ii<num;ii+=1)
966                                //items all start w/"DSTabItem_"
967                                item=StringFromList(ii, ctrlList ,";")
968                                nameStr=item[0,9]
969                                if(cmpstr(nameStr,"DATabItem_")==0)
970                                        onTab = str2num(item[10])
971                                        ControlInfo $item
972                                        switch (V_flag)
973                                                case 1:
974                                                        Button $item,disable=(tca.tab!=onTab)
975                                                        break
976                                                case 2:
977                                                        CheckBox $item,disable=(tca.tab!=onTab)
978                                                        break
979                                                case 3:
980                                                        PopUpMenu       $item,disable=(tca.tab!=onTab)
981                                                        break
982                                                case 5:
983                                                        SetVariable     $item,disable=(tca.tab!=onTab)
984                                                        break
985                                        endswitch
986                                endif
987                        endfor
988                       
989                        arithDisplayProc(tca.tab)
990                        break
991        endswitch       
992End
993
994
995Function DACalculateProc(ba) : ButtonControl
996        STRUCT WMButtonAction &ba
997       
998        String DS1,DS2,Resultname
999       
1000        switch(ba.eventCode)
1001        case 2:
1002                //Which tab?
1003                ControlInfo/W=$(ba.win) DATabs
1004                Variable tabNum = V_value
1005                //Print "Tab number "+num2str(tabNum)
1006
1007                ControlInfo/W=$(ba.win) DS1_popup
1008                DS1 = S_Value
1009                ControlInfo/W=$(ba.win) DANoDS2_cb
1010                if (V_Value == 0)
1011                        ControlInfo/W=$(ba.win) DS2_popup
1012                        DS2 = S_Value
1013                else
1014                        DS2 = "NullSolvent"
1015                endif
1016                ControlInfo/W=$(ba.win) DAResultName_sv
1017                Resultname = CleanupName(S_Value, 0 )           //clean up any bad characters, and put the cleaned string back
1018                SetVariable DAResultName_sv,value=_STR:ResultName
1019               
1020                ControlInfo/W=$(ba.win) DAScale_sv
1021                Variable Scalefactor = V_Value
1022
1023                switch(tabNum)
1024                        case 0:
1025                                //do subtraction
1026                                //print "Subtraction of "+DS2+" from "+DS1+" with sf "+num2str(scalefactor)+ " into "+Resultname
1027                                SubtractDataSets(DS1,DS2,Scalefactor,Resultname)
1028                                break
1029                        case 1:
1030                                //do addition
1031                                AddDataSets(DS1,DS2,Scalefactor,Resultname)
1032                                break
1033                        case 2:
1034                                //do multiplication
1035                                MultiplyDataSets(DS1,DS2,Scalefactor,Resultname)
1036                                break
1037                        case 3:
1038                                //do division
1039                                DivideDataSets(DS1,DS2,Scalefactor,Resultname)
1040                                break
1041                endswitch
1042               
1043                //Sort out plot
1044                //Fake button press to DAPlotButtonProc
1045                STRUCT WMButtonAction ba2
1046                ba2.win = ba.win
1047                ba2.ctrlName = "DAPlot_button"
1048                ba2.eventCode = 2
1049               
1050                // I've commented this out - the cursors get reset to the ends since this removes all sets from the graph, and
1051                // then replots them. What is the real purpose of this call? To clear the old result off before adding the
1052                // new one?
1053//              DAPlotButtonProc(ba2)
1054                ba2.userData = ResultName
1055                DAPlotRemoveResult(ba2)
1056               
1057               
1058                AddDAPlot(3)
1059                DoWindow/F DataArithmeticPanel
1060               
1061                //Enable save button now that we have a result to save
1062                Button DASave_Button win=$(ba.win),disable=0
1063               
1064//              SetActiveSubWindow DAPlotPanel
1065        endswitch
1066       
1067End
1068
1069// remove what is not the
1070//
1071Function DAPlotRemoveResult(ba) : ButtonControl
1072        STRUCT WMButtonAction &ba
1073       
1074        String win = ba.win
1075        String ResultName = ba.userData
1076        String item="",traceList=""
1077        Variable ii=0,num
1078
1079        switch (ba.eventCode)
1080                case 2:         //mouse up
1081                        //data set 1
1082                        ControlInfo/W=$(win) DS1_popup
1083                        String DS1 = S_Value
1084                       
1085                        //Get folder for DS2
1086                        ControlInfo/W=$(win) DS2_popup
1087                        String DS2 = S_Value
1088                       
1089                        // state of the checkbox
1090                        ControlInfo/W=$(win) DANoDS2_cb
1091                        if(V_Value)
1092                                DS2 = "NullSolvent"
1093                        endif
1094                       
1095                        DoWindow DAPlotPanel
1096                        if (V_Flag == 0)
1097                                MakeDAPlotPanel()
1098                        else
1099                                DoWindow/HIDE=0/F DAPlotPanel
1100                                traceList = TraceNameList("DAPlotPanel#DAPlot",";",1)
1101                                num=ItemsInList(traceList)
1102                                ii=0
1103                                do
1104                                        item = StringFromList(ii,traceList,";")
1105                                        if (stringmatch(item,ResultName+"*")==1)                //it it's the specific trace I've asked to remove
1106                                                RemoveFromGraph/W=DAPlotPanel#DAPlot $item
1107                                        elseif (stringmatch(item,DS1+"*")==0 && stringmatch(item,DS2+"*")==0)           //if it's not set1 & not set2
1108                                                RemoveFromGraph/W=DAPlotPanel#DAPlot $item
1109                                        endif
1110                                       
1111                                        ii+=1
1112                                while(ii<num)                           
1113                        endif
1114                       
1115                        break
1116        endswitch
1117
1118        return 0
1119End
1120
1121
1122Function DAPlotButtonProc(ba) : ButtonControl
1123        STRUCT WMButtonAction &ba
1124       
1125        String win = ba.win
1126
1127        switch (ba.eventCode)
1128                case 2:
1129                        //mouse up
1130                        //Get folder for DS1
1131                        DoWindow DAPlotPanel
1132                        if (V_Flag == 0)
1133                                MakeDAPlotPanel()
1134                        else
1135                                DoWindow/HIDE=0/F DAPlotPanel
1136                                do
1137                                        String tracename = StringFromList(0,TraceNameList("DAPlotPanel#DAPlot",";",1),";")
1138                                        if (cmpstr(tracename,"")==0)
1139                                                break
1140                                        else
1141                                                RemoveFromGraph/W=DAPlotPanel#DAPlot $tracename
1142                                        endif                   
1143                                while(1)                               
1144                        endif
1145                       
1146                        ControlInfo/W=$(win) DS1_popup
1147                        String DS1 = S_Value
1148                        if (cmpstr(DS1,"") != 0 )
1149                                AddDAPlot(1)
1150                        endif
1151                        //Get folder for DS2
1152                        ControlInfo/W=$(win) DS2_popup
1153                        String DS2 = S_Value
1154                        if (cmpstr(DS2,"") != 0)
1155                                AddDAPlot(2)
1156                        endif
1157                        break
1158        endswitch
1159
1160        return 0
1161End
1162
1163Function DADoneButtonProc(ba) : ButtonControl
1164        STRUCT WMButtonAction &ba
1165       
1166        String win = ba.win
1167
1168        switch (ba.eventCode)
1169                case 2:
1170                        DoWindow/K DAPlotPanel
1171                        DoWindow/K DataArithmeticPanel
1172                        break
1173        endswitch
1174
1175        return 0
1176End
1177
1178Function DAHelpButtonProc(ba) : ButtonControl
1179        STRUCT WMButtonAction &ba
1180       
1181        String win = ba.win
1182
1183        switch (ba.eventCode)
1184                case 2:
1185                        // click code here
1186                        DisplayHelpTopic/Z/K=1 "Data Set Arithmetic"
1187                        if(V_flag !=0)
1188                                DoAlert 0,"The Data Set Arithmetic Help file could not be found"
1189                        endif
1190                        break
1191        endswitch
1192
1193        return 0
1194End
1195
1196Function DALogLinIProc(cba) : CheckBoxControl
1197        STRUCT WMCheckBoxAction &cba
1198
1199        switch(cba.eventcode)
1200                case 2:
1201                       
1202                        ModifyGraph/W=DAPlotPanel#DAPlot log(left)=cba.checked
1203                        ModifyGraph/W=DAPlotPanel#DAPlot log(bottom)=cba.checked
1204                        ModifyGraph/W=DAPlotPanel#DAPlot zero(left)=0
1205                        SetAxis/A/W=DAPlotPanel#DAPlot
1206                       
1207                        if(cba.checked)
1208                                Checkbox DAPlot_lin_cb,value=0          //uncheck lin
1209                        endif
1210        endswitch
1211
1212
1213End
1214
1215Function DAHighQLinProc(cba) : CheckBoxControl
1216        STRUCT WMCheckBoxAction &cba
1217
1218        switch(cba.eventcode)
1219                case 2:
1220                        if(cba.checked)
1221                                ModifyGraph/W=DAPlotPanel#DAPlot log=0,zero(left)=1
1222                                SetAxis/W=DAPlotPanel#DAPlot left -0.1,0.1
1223                                SetAxis/W=DAPlotPanel#DAPlot bottom 0.1,*
1224                                SetAxis/W=DAPlotPanel#DAPlot left -0.02,0.02
1225                               
1226                                Checkbox DAPlot_log_cb,value=0          //uncheck the log
1227                        endif
1228        endswitch
1229
1230
1231End
1232
1233
1234Function DACursorButtonProc(ba) : ButtonControl
1235        STRUCT WMButtonAction &ba
1236
1237        String DS1,DS2
1238       
1239        switch(ba.eventCode)
1240                case 2:
1241               
1242                        ControlInfo/W=$(ba.win) DS1_popup
1243                        DS1 = S_Value
1244                        ControlInfo/W=$(ba.win) DANoDS2_cb
1245                        Variable NoDS2 = V_Value
1246                        if (NoDS2 == 0)
1247                                ControlInfo/W=$(ba.win) DS2_popup
1248                                DS2 = S_Value
1249                        else
1250                                DS2 = "NullSolvent"
1251                        endif
1252               
1253                        //AJJ Nov 2009 - UGLY - Will have to revisit this when we deal with hierarchical folders
1254                        Wave set1_i = $("root:"+DS1+":"+DS1+"_i")
1255                        Wave set1_q = $("root:"+DS1+":"+DS1+"_q")
1256                        Wave set2_i = $("root:"+DS2+":"+DS2+"_i")
1257                        Wave set2_q = $("root:"+DS2+":"+DS2+"_q")
1258                        Duplicate/O set1_i tmp_i
1259                        Duplicate/O set1_q tmp_q
1260                        tmp_i = set1_i / interp(set1_q[p],set2_q,set2_i)       
1261                       
1262                        //Get cursors
1263                        Variable q1,q2
1264                       
1265                        DoWindow/F DAPlotPanel
1266                        SetActiveSubWindow DAPlotPanel#DAPlot
1267                       
1268                        q1 = CsrXWaveRef(A)[pcsr(A)]
1269                        q2 = CsrXWaveRef(B)[pcsr(B)]
1270
1271                        //Update value display
1272                        ValDisplay DARangeStar_vd,value=_NUM:q1, win=$(ba.win)
1273                        ValDisplay DARangeEnd_vd,value=_NUM:q2, win=$(ba.win)
1274                       
1275                        //Calculate scalefactor
1276                       
1277                        if (NoDS2 == 1)
1278                                Wave avgWave = set1_i
1279                        else
1280                                Wave avgWave = tmp_i
1281                        endif
1282
1283                        Variable p1 = BinarySearch(tmp_q,q1)                   
1284                        Variable p2 = BinarySearch(tmp_q,q2)                   
1285
1286                        //print avgWave
1287
1288                        WaveStats/Q/R=[p1,p2] avgWave
1289                        //print V_avg
1290                        //Update sv control
1291                        SetVariable DAScale_sv, value=_NUM:V_avg, win=$(ba.win)
1292                       
1293                        KillWaves/Z tmp_i,tmp_q
1294                        DoWindow/F DataArithmeticPanel
1295        endswitch
1296
1297End
1298
1299
1300Function DANoDS2Proc(cba) : CheckBoxControl
1301        STRUCT WMCheckBoxAction &cba
1302       
1303       
1304        switch(cba.eventCode)
1305                case 2:
1306                        if (cba.checked == 1)
1307                                //Disable DS2 popup etc
1308                                PopupMenu DS2_popup win=$(cba.win), disable=2
1309                                Button DS2_button win=$(cba.win), disable=2
1310                        else
1311                                //Enable DS2 popup etc
1312                                PopupMenu DS2_popup win=$(cba.win), disable=0
1313                                Button DS2_button win=$(cba.win), disable=0
1314                        endif
1315                        //Sort out plot
1316                        //Fake button press to DAPlotButtonProc
1317                        STRUCT WMButtonAction ba2
1318                        ba2.win = cba.win
1319                        ba2.ctrlName = "DAPlot_button"
1320                        ba2.eventCode = 2
1321                        DAPlotButtonProc(ba2)
1322                        SetActiveSubWindow DAPlotPanel
1323                        DoWindow/F DataArithmeticPanel
1324        endswitch
1325
1326End
1327
1328Function DASaveProc(ba) : ButtonControl
1329        STRUCT WMButtonAction &ba
1330       
1331        switch(ba.eventCode)
1332                case 2:
1333                        ControlInfo/W=$(ba.win) DAResultName_sv
1334                        SaveDataSetToFile(S_Value)
1335                        break
1336        endswitch
1337
1338
1339End
1340
1341/////////////////////// Common Panel Functions ///////////////////////////////////////
1342
1343
1344// is there a simpler way to do this? I don't think so.
1345Function/S DM_DataSetPopupList()
1346
1347        String str=GetAList(4)
1348
1349        if(strlen(str)==0)
1350                str = "No data loaded"
1351        endif
1352        str = SortList(str)
1353       
1354        return(str)
1355End
1356
1357
1358Function DANameSetvarproc(sva) : SetVariableControl
1359        STRUCT WMSetVariableAction &sva
1360               
1361        switch( sva.eventCode )
1362                case 1: // mouse up
1363                case 2: // Enter key
1364                case 3: // Live update
1365                                String sv = sva.sval
1366                                if( strlen(sv) > 25 )
1367                                        sv= sv[0,24]
1368                                        SetVariable  $(sva.ctrlName),win=$(sva.win),value=_STR:sv
1369                                        ControlUpdate /W=$(sva.win) $(sva.ctrlName)
1370                                        Beep
1371                                endif
1372                                Button DASave_Button win=$(sva.win), disable=2
1373                                break
1374                endswitch
1375        return 0
1376End
1377
1378
1379////////////////////// Functions to do manipulations ///////////////////////////////////
1380
1381Function RenameDataSet(dataSetFolder, newName)
1382        String dataSetFolder
1383        String newName
1384       
1385        String dataSetFolderParent,basestr,objName
1386        Variable index = 0
1387       
1388        //Abuse ParseFilePath to get path without folder name
1389        dataSetFolderParent = ParseFilePath(1,dataSetFolder,":",1,0)
1390        //Abuse ParseFilePath to get basestr
1391        basestr = ParseFilePath(0,dataSetFolder,":",1,0)
1392
1393//      try
1394                RenameDataFolder $(dataSetFolder) $(newName)//; AbortOnRTE
1395       
1396
1397                SetDataFolder $(dataSetFolderParent+newName)//; AbortOnRTE
1398                do
1399                        objName = GetIndexedObjName("",1,index)
1400                        if (strlen(objName) == 0)
1401                                break
1402                        endif
1403                        Rename $(objName) $(ReplaceString(basestr,objName,newName))
1404                        index+=1
1405                while(1)
1406                SetDataFolder root:
1407//      catch
1408//              Print "Aborted: " + num2str(V_AbortCode)
1409//              SetDataFolder root:
1410//      endtry
1411End
1412
1413
1414Function DuplicateDataSet(dataSetFolder, newName, forceoverwrite)
1415        String dataSetFolder
1416        String newName
1417        Variable forceoverwrite
1418
1419        String dataSetFolderParent,basestr,objName
1420        Variable index = 0
1421
1422        //Abuse ParseFilePath to get path without folder name
1423        dataSetFolderParent = ParseFilePath(1,dataSetFolder,":",1,0)
1424        //Abuse ParseFilePath to get basestr
1425        basestr = ParseFilePath(0,dataSetFolder,":",1,0)
1426       
1427        print "Duplicating "+dataSetFolder+" as "+newName
1428       
1429        SetDataFolder $(dataSetFolderParent)
1430       
1431        if (!DataFolderExists(newName))
1432                NewDataFolder $(newName)
1433        else
1434                if (!forceoverwrite)
1435                        DoAlert 1, "A dataset with the name "+newName+" already exists. Overwrite?"
1436                        if (V_flag == 2)
1437                                return 1
1438                        endif
1439                endif
1440        endif   
1441
1442        //If we are here, the folder (now) exists and the user has agreed to overwrite
1443        //either in the function call or from the alert.
1444       
1445        // here, GetIndexedObjectName copies all of the waves
1446        index = 0
1447        do
1448                objName = GetIndexedObjName(basestr,1,index)
1449                if (strlen(objName) == 0)
1450                        break
1451                endif
1452                objname = ":"+basestr+":"+objname
1453                        Duplicate/O $(objName) $(ReplaceString(basestr,objName,newName))
1454                index+=1
1455        while(1)
1456
1457// -- for USANS data, we need the slit height. copy all of the "USANS_*" variables
1458// may need to augment this for other situations
1459        index = 0
1460        do
1461                objName = GetIndexedObjName(basestr,2,index)
1462                if (strlen(objName) == 0)
1463                        break
1464                endif
1465                if(stringmatch(objName,"USANS*") == 1)
1466                        objname = ":"+basestr+":"+objname
1467                        NVAR tmp = $objName
1468                        Variable/G $(ReplaceString(basestr,objName,newName))= tmp
1469                endif
1470                index+=1
1471        while(1)
1472       
1473
1474        SetDataFolder root:
1475        return 0
1476End
1477
1478
1479// Subtract Set2 From Set1
1480// Use Result_I = Set1_I - f*Set2_I
1481Function SubtractDataSets(set1Name,set2Name,set2Scale,resultName)
1482        String set1Name
1483        String set2Name
1484        Variable set2Scale
1485        String resultName
1486
1487        String set1Path = "root:"+set1Name+":"
1488        String set2Path = "root:"+set2Name+":"
1489        String resultPath = "root:"+resultName+":"
1490       
1491        SetDataFolder root:
1492        //Create folder for result
1493        //UnloadDataSet(resultName)
1494        //Make the folder
1495        if (DuplicateDataSet(set1Path,resultName,0))
1496                return 1
1497        else
1498        //Do subtraction of I waves - including interpolation if necessary.
1499        Wave result_i = $(resultPath+resultName+"_i")
1500        Wave result_s = $(resultPath+resultName+"_s")
1501        Wave set1_i = $(set1Path+set1Name+"_i")
1502        Wave set1_q = $(set1Path+set1Name+"_q")
1503        Wave set1_s = $(set1Path+set1Name+"_s")
1504        Wave set2_i = $(set2Path+set2Name+"_i")
1505        Wave set2_q = $(set2Path+set2Name+"_q")
1506        Wave set2_s = $(set2Path+set2Name+"_s")
1507       
1508        result_i = set1_i - (set2Scale*interp(set1_q[p],set2_q,set2_i))
1509        result_s = sqrt(set1_s^2 + (set2Scale*interp(set1_q[p],set2_q,set2_s))^2 )
1510        //Calculate result error wave - can we produce corrected Q error?
1511       
1512        //Generate history string to record what was done?
1513        return 0
1514        endif
1515End
1516
1517// Add Set2 to Set1
1518// Use Result_I = Set1_I + f*Set2_I
1519Function AddDataSets(set1Name,set2Name,set2Scale,resultName)
1520        String set1Name
1521        String set2Name
1522        Variable set2Scale
1523        String resultName
1524
1525        String set1Path = "root:"+set1Name+":"
1526        String set2Path = "root:"+set2Name+":"
1527        String resultPath = "root:"+resultName+":"
1528       
1529        SetDataFolder root:
1530        //Create folder for result
1531        if(DuplicateDataSet(set1Path,resultName,0))
1532                //User said no overwrite
1533                return 1
1534        else
1535        //Do addition of I waves - including interpolation if necessary.
1536        Wave result_i = $(resultPath+resultName+"_i")
1537        Wave result_s = $(resultPath+resultName+"_s")
1538        Wave set1_i = $(set1Path+set1Name+"_i")
1539        Wave set1_q = $(set1Path+set1Name+"_q")
1540        Wave set1_s = $(set1Path+set1Name+"_s")
1541        Wave set2_i = $(set2Path+set2Name+"_i")
1542        Wave set2_q = $(set2Path+set2Name+"_q")
1543        Wave set2_s = $(set2Path+set2Name+"_s")
1544       
1545        result_i =  set1_i + set2Scale*interp(set1_q[p],set2_q,set2_i) 
1546        //Calculate result error wave (note that this is identical to subtraction)
1547        result_s = sqrt(set1_s^2 + (set2Scale*interp(set1_q[p],set2_q,set2_s))^2 )
1548
1549        //  - can we produce corrected Q error?
1550        //Generate history string to record what was done?
1551        return 0
1552        endif
1553End
1554
1555// Multiply Set1 by Set2
1556// Use Result_I  = Set1_I * (f*Set2_I)
1557Function MultiplyDataSets(set1Name, set2Name, set2Scale, resultName)
1558        String set1Name
1559        String set2Name
1560        Variable set2Scale
1561        String resultName
1562
1563        String set1Path = "root:"+set1Name+":"
1564        String set2Path = "root:"+set2Name+":"
1565        String resultPath = "root:"+resultName+":"
1566       
1567        SetDataFolder root:
1568        //Create folder for result
1569        //Make the folder
1570        if(DuplicateDataSet(set1Path,resultName,0))
1571                //User said no overwrite
1572                return 1
1573        else
1574        //Do multiplcation of I waves - including interpolation if necessary.
1575        Wave result_i = $(resultPath+resultName+"_i")
1576        Wave result_s = $(resultPath+resultName+"_s")
1577        Wave set1_i = $(set1Path+set1Name+"_i")
1578        Wave set1_q = $(set1Path+set1Name+"_q")
1579        Wave set1_s = $(set1Path+set1Name+"_s")
1580        Wave set2_i = $(set2Path+set2Name+"_i")
1581        Wave set2_q = $(set2Path+set2Name+"_q")
1582        Wave set2_s = $(set2Path+set2Name+"_s")
1583       
1584        result_i =  set1_i*set2Scale*interp(set1_q[p],set2_q,set2_i)
1585        //Calculate result error wave
1586        // sum each of the relative errors, interpolating set 2 intensity and error as needed
1587        // then sqrt
1588        result_s = (set2Scale*interp(set1_q[p],set2_q,set2_i)*set1_s)^2
1589        result_s += (set2Scale*set1_i*interp(set1_q[p],set2_q,set2_s))^2
1590        result_s = sqrt(result_s)
1591
1592        // - can we produce corrected Q error?
1593
1594        //Generate history string to record what was done?
1595        return 0
1596        endif
1597End
1598
1599// Divide Set1 by Set2
1600// Use Result_I  = Set1_I / (f*Set2_I)
1601Function DivideDataSets(set1Name, set2Name, set2Scale, resultName)
1602        String set1Name
1603        String set2Name
1604        Variable set2Scale
1605        String resultName
1606
1607        String set1Path = "root:"+set1Name+":"
1608        String set2Path = "root:"+set2Name+":"
1609        String resultPath = "root:"+resultName+":"
1610       
1611        SetDataFolder root:
1612        //Create folder for result
1613        //Make the folder
1614        if(DuplicateDataSet(set1Path,resultName,0))
1615                //User said no overwrite
1616                return 1
1617        else
1618        //Do division of I waves - including interpolation if necessary.
1619        Wave result_i = $(resultPath+resultName+"_i")
1620        Wave result_s = $(resultPath+resultName+"_s")
1621        Wave set1_i = $(set1Path+set1Name+"_i")
1622        Wave set1_q = $(set1Path+set1Name+"_q")
1623        Wave set1_s = $(set1Path+set1Name+"_s")
1624        Wave set2_i = $(set2Path+set2Name+"_i")
1625        Wave set2_q = $(set2Path+set2Name+"_q")
1626        Wave set2_s = $(set2Path+set2Name+"_s")
1627       
1628        result_i =  set1_i/(set2Scale*interp(set1_q[p],set2_q,set2_i)   )
1629        //Calculate result error wave
1630        // sum each of the relative errors, interpolating set 2 intensity and error as needed
1631        // then sqrt
1632        result_s = (set1_s/set2Scale/interp(set1_q[p],set2_q,set2_i))^2
1633        result_s += (interp(set1_q[p],set2_q,set2_s)*set1_i/set2Scale/interp(set1_q[p],set2_q,set2_i)^2)^2
1634        result_s = sqrt(result_s)
1635
1636        // - can we produce corrected Q error?
1637       
1638        //Generate history string to record what was done?
1639        return 0
1640        endif
1641End
1642
1643
1644///////////////////////////Other Utility functions ////////////////////////////
1645
1646Function SaveDataSetToFile(folderName)
1647        String folderName
1648
1649        String protoStr = ""
1650        //Check for history string in folder
1651        //If it doesn't exist then
1652
1653        //Do saving of data file.
1654       
1655        NVAR gXML_Write = root:Packages:NIST:gXML_Write
1656
1657        if (gXML_Write == 1)
1658                ReWrite1DXMLData(folderName)
1659        else
1660                fReWrite1DData(folderName,"tab","CRLF")
1661        endif
1662
1663//      NISTSave1DData(folderName,protoStr)
1664
1665        //Include history string to record what was done?
1666
1667End
1668
1669
1670
1671//////////////////// Write data functions ////////////////////////////////////
1672// AJJ Nov 2009 - should move towards unified writer
1673//
1674//////////////////////////////////////////////////////////////////////////
1675
1676//Function NISTSave1DData(folderPath,protoStr)
1677//      String folderPath, protoStr
1678//     
1679//      //protoStr is string that will be written to either
1680//     
1681//
1682//End
1683
1684
1685
1686
1687// still need to get the header information, and possibly the SASprocessnote from the XML load into the 6-column header
1688//
1689// start by looking in:
1690//      String xmlReaderFolder = "root:Packages:CS_XMLreader:"
1691// for Title and Title_folder strings -> then the metadata (but the processnote is still not there
1692//
1693// may need to get it directly using the filename
1694Function  convertNISTXMLtoNIST6Col(fname)
1695        String fname
1696
1697        String list, item,path
1698        Variable num,ii
1699       
1700        //load the XML
1701       
1702        LoadNISTXMLData(fname,"",0,0)           //no plot, no force overwrite
1703//      Execute "A_LoadOneDDataWithName(\""+fname+"\",0)"               //won't plot
1704
1705        // then rewrite what is in the data folder that was just loaded
1706        String basestr = ParseFilePath(0, fname, ":", 1, 0)
1707        baseStr = CleanupName(baseStr,0)
1708        print fname
1709        print basestr
1710
1711        fReWrite1DData_noPrompt(baseStr,"tab","CR")
1712
1713        return(0)
1714End
1715
1716
1717///////// SRK - VERY SIMPLE batch converter
1718// no header information is preserved
1719// file names are partially preserved
1720//
1721
1722/// to use this:
1723// -open the Plot Manager and set the path
1724// -run this function
1725//
1726// it doesn't matter if the XML ouput flag is set - this overrides.
1727Function batchXML26ColConvert()
1728
1729        String list, item,path,fname
1730        Variable num,ii
1731       
1732        PathInfo CatPathName
1733        path = S_Path
1734
1735        list = A_ReducedDataFileList("")
1736        num = itemsInList(list)
1737        Print num
1738        for(ii=0;ii<num;ii+=1)
1739                item = StringFromList(ii, list ,";")
1740                fname=path + item
1741                Execute "A_LoadOneDDataWithName(\""+fname+"\",0)"               //won't plot
1742//              easier to load all, then write out, since the name will be changed
1743        endfor
1744       
1745       
1746        list = DM_DataSetPopupList()
1747
1748        num = itemsInList(list)
1749        Print num
1750        for(ii=0;ii<num;ii+=1)
1751                item = StringFromList(ii, list ,";")
1752                fReWrite1DData_noPrompt(item,"tab","CR")
1753        endfor
1754       
1755End
1756
1757///////// SRK - VERY SIMPLE batch converter
1758// NO header information is preserved
1759// file names are partially preserved
1760//
1761
1762/// to use this:
1763// -open the Plot Manager and set the path
1764// -run this function
1765//
1766// it doesn't matter if the XML ouput flag is set - this overrides.
1767//
1768// The GRASP output data is 5-column Q-I-errI-sigQ-nCells
1769// which gets read in as q-i-s-ism-fit_ism (as if it was some wierd USANS data format)
1770// -- so fake the output...
1771//
1772Function batchGrasp26ColConvert()
1773
1774        String list, item,path,fname
1775        Variable num,ii,npt
1776       
1777        PathInfo CatPathName
1778        path = S_Path
1779
1780        list = A_ReducedDataFileList("")
1781        num = itemsInList(list)
1782        Print num
1783        for(ii=0;ii<num;ii+=1)
1784                item = StringFromList(ii, list ,";")
1785                fname=path + item
1786                Execute "A_LoadOneDDataWithName(\""+fname+"\",0)"               //won't plot
1787//              easier to load all, then write out, since the name will be changed
1788        endfor
1789       
1790       
1791        list = DM_DataSetPopupList()
1792
1793        num = itemsInList(list)
1794       
1795        Print num
1796        for(ii=0;ii<num;ii+=1)
1797                item = StringFromList(ii, list ,";")
1798               
1799                // fake the 6-column NIST data structure
1800                WAVE qw = $("root:"+item+":"+item+"_q")
1801                npt = numpnts(qw)
1802                Make/O/D/N=(npt,4) $("root:"+item+":"+item+"_res")
1803                WAVE res = $("root:"+item+":"+item+"_res")
1804                WAVE sigQ = $("root:"+item+":"+item+"_ism")
1805                res[][0] = sigQ[p]      // sigQ
1806                res[][1] = qw[p]                // qBar ~ q
1807                res[][2] = 1            //shadow
1808                res[][3] = qw[p]                // q
1809               
1810               
1811                fReWrite1DData_noPrompt(item,"tab","CR")
1812        endfor
1813       
1814End
1815
1816// quick version (copied from fReWrite1DData() that NEVER asks for a new fileName
1817// - and right now, always expect 6-column data, either SANS or USANS (re-writes -dQv)
1818// - AJJ Nov 2009 : better make sure we always fake 6 columns on reading then....
1819Function fReWrite1DData_noPrompt(folderStr,delim,term)
1820        String folderStr,delim,term
1821       
1822        String formatStr="",fullpath=""
1823        Variable refnum,dialog=1
1824       
1825        String dataSetFolderParent,basestr
1826       
1827        //setup delimeter and terminator choices
1828        If(cmpstr(delim,"tab")==0)
1829                //tab-delimeted
1830                formatStr="%15.8g\t%15.8g\t%15.8g\t%15.8g\t%15.8g\t%15.8g"
1831        else
1832                //use 3 spaces
1833                formatStr="%15.8g   %15.8g   %15.8g   %15.8g   %15.8g   %15.8g"
1834        Endif
1835        If(cmpstr(term,"CR")==0)
1836                formatStr += "\r"
1837        Endif
1838        If(cmpstr(term,"LF")==0)
1839                formatStr += "\n"
1840        Endif
1841        If(cmpstr(term,"CRLF")==0)
1842                formatStr += "\r\n"
1843        Endif
1844       
1845        //Abuse ParseFilePath to get path without folder name
1846        dataSetFolderParent = ParseFilePath(1,folderStr,":",1,0)
1847        //Abuse ParseFilePath to get basestr
1848        basestr = ParseFilePath(0,folderStr,":",1,0)
1849       
1850        //make sure the waves exist
1851        SetDataFolder $(dataSetFolderParent+basestr)
1852        WAVE/Z qw = $(baseStr+"_q")
1853        WAVE/Z iw = $(baseStr+"_i")
1854        WAVE/Z sw = $(baseStr+"_s")
1855        WAVE/Z resw = $(baseStr+"_res")
1856       
1857        if(WaveExists(qw) == 0)
1858                Abort "q is missing"
1859        endif
1860        if(WaveExists(iw) == 0)
1861                Abort "i is missing"
1862        endif
1863        if(WaveExists(sw) == 0)
1864                Abort "s is missing"
1865        endif
1866        if(WaveExists(resw) == 0)
1867                Abort "Resolution information is missing."
1868        endif
1869       
1870        Duplicate/O qw qbar,sigQ,fs
1871        if(dimsize(resW,1) > 4)
1872                //it's USANS put -dQv back in the last 3 columns
1873                NVAR/Z dQv = USANS_dQv
1874                if(NVAR_Exists(dQv) == 0)
1875                        Abort "It's USANS data, and I don't know what the slit height is."
1876                endif
1877                sigQ = -dQv
1878                qbar = -dQv
1879                fs = -dQv
1880        else
1881                //it's SANS
1882                sigQ = resw[p][0]
1883                qbar = resw[p][1]
1884                fs = resw[p][2]
1885        endif
1886       
1887        dialog=0
1888        if(dialog)
1889                PathInfo/S catPathName
1890//              fullPath = DoSaveFileDialog("Save data as",fname=baseStr+".txt")
1891                fullPath = DoSaveFileDialog("Save data as",fname=baseStr[0,strlen(BaseStr)-1])
1892                Print fullPath
1893                If(cmpstr(fullPath,"")==0)
1894                        //user cancel, don't write out a file
1895                        Close/A
1896                        Abort "no data file was written"
1897                Endif
1898                //Print "dialog fullpath = ",fullpath
1899        Endif
1900        PathInfo catPathName
1901        fullPath = S_Path + baseStr[0,strlen(BaseStr)-1]
1902
1903        Open refnum as fullpath
1904       
1905        fprintf refnum,"Modified data written from folder %s on %s\r\n",baseStr,(date()+" "+time())
1906        wfprintf refnum,formatStr,qw,iw,sw,sigQ,qbar,fs
1907        Close refnum
1908       
1909        KillWaves/Z sigQ,qbar,fs
1910       
1911        SetDataFolder root:
1912        return(0)
1913End
1914
1915///////////end SRK
Note: See TracBrowser for help on using the repository browser.